removed ticketsystem; lots of work on cron stuff
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -46,7 +46,7 @@ return array(
|
||||
'type' => 'option',
|
||||
'default' => 'bind',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array('bind' => 'Bind9', 'pdns' => 'PowerDNS'),
|
||||
'option_options' => array('Bind' => 'Bind9', 'PowerDNS' => 'PowerDNS'),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_bindconf_directory' => array(
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Settings
|
||||
*
|
||||
*/
|
||||
|
||||
return array(
|
||||
'groups' => array(
|
||||
'ticket' => array(
|
||||
'title' => $lng['admin']['ticketsettings'],
|
||||
'fields' => array(
|
||||
'ticket_enabled' => array(
|
||||
'label' => $lng['serversettings']['ticket']['enable'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'enabled',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'cronmodule' => 'froxlor/ticket',
|
||||
'save_method' => 'storeSettingField',
|
||||
'overview_option' => true
|
||||
),
|
||||
'ticket_noreply_email' => array(
|
||||
'label' => $lng['serversettings']['ticket']['noreply_email'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'noreply_email',
|
||||
'type' => 'string',
|
||||
'string_type' => 'mail',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_noreply_name' => array(
|
||||
'label' => $lng['serversettings']['ticket']['noreply_name'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'noreply_name',
|
||||
'type' => 'string',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_reset_cycle' => array(
|
||||
'label' => $lng['serversettings']['ticket']['reset_cycle'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'reset_cycle',
|
||||
'type' => 'option',
|
||||
'default' => 1,
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(0 => html_entity_decode($lng['admin']['tickets']['daily']), 1 => html_entity_decode($lng['admin']['tickets']['weekly']), 2 => html_entity_decode($lng['admin']['tickets']['monthly']), 3 => html_entity_decode($lng['admin']['tickets']['yearly'])),
|
||||
'save_method' => 'storeSettingField',
|
||||
'plausibility_check_method' => 'setCycleOfCronjob',
|
||||
),
|
||||
'ticket_concurrently_open' => array(
|
||||
'label' => $lng['serversettings']['ticket']['concurrentlyopen'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'concurrently_open',
|
||||
'type' => 'int',
|
||||
'default' => 5,
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_archiving_days' => array(
|
||||
'label' => $lng['serversettings']['ticket']['archiving_days'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'archiving_days',
|
||||
'type' => 'int',
|
||||
'int_min' => 1,
|
||||
'int_max' => 99,
|
||||
'default' => 5,
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_worktime_all' => array(
|
||||
'label' => $lng['serversettings']['ticket']['worktime_all'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'worktime_all',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_worktime_begin' => array(
|
||||
'label' => $lng['serversettings']['ticket']['worktime_begin'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'worktime_begin',
|
||||
'type' => 'string',
|
||||
'string_regexp' => '/^[012][0-9]:[0-6][0-9]$/',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_worktime_end' => array(
|
||||
'label' => $lng['serversettings']['ticket']['worktime_end'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'worktime_end',
|
||||
'type' => 'string',
|
||||
'string_regexp' => '/^[012][0-9]:[0-6][0-9]$/',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_worktime_sat' => array(
|
||||
'label' => $lng['serversettings']['ticket']['worktime_sat'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'worktime_sat',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'ticket_worktime_sun' => array(
|
||||
'label' => $lng['serversettings']['ticket']['worktime_sun'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'worktime_sun',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'system_last_archive_run' => array(
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'last_archive_run',
|
||||
'type' => 'hidden',
|
||||
'default' => '',
|
||||
),
|
||||
'ticket_default_priority' => array(
|
||||
'label' => $lng['serversettings']['ticket']['default_priority'],
|
||||
'settinggroup' => 'ticket',
|
||||
'varname' => 'default_priority',
|
||||
'type' => 'option',
|
||||
'default' => 2,
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(1 => $lng['ticket']['high'], 2 => $lng['ticket']['normal'], 3 => $lng['ticket']['low']),
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
@@ -1,912 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Panel
|
||||
*
|
||||
*/
|
||||
|
||||
define('AREA', 'admin');
|
||||
require './lib/init.php';
|
||||
|
||||
use Froxlor\Database as Database;
|
||||
use Froxlor\Settings as Settings;
|
||||
|
||||
if (isset($_POST['id'])) {
|
||||
$id = intval($_POST['id']);
|
||||
|
||||
} elseif(isset($_GET['id'])) {
|
||||
|
||||
$id = intval($_GET['id']);
|
||||
|
||||
// only check if this is not a category-id
|
||||
if (!isset($_GET['page']) || (isset($_GET['page']) && $_GET['page'] != 'categories')) {
|
||||
if (!$userinfo['customers_see_all']) {
|
||||
/*
|
||||
* Check if the current user is allowed to see the current ticket.
|
||||
*/
|
||||
$stmt = Database::prepare("
|
||||
SELECT `id` FROM `panel_tickets`
|
||||
WHERE `id` = :id AND `adminid` = :adminid
|
||||
");
|
||||
$result = Database::pexecute_first($stmt, array('id' => $id, 'adminid' => $userinfo['adminid']));
|
||||
|
||||
if ($result == null) {
|
||||
// no rights to see the requested ticket
|
||||
standard_error(array('ticketnotaccessible'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($page == 'tickets'
|
||||
&& $userinfo['customers'] != '0'
|
||||
) {
|
||||
// Let's see how many customers we have
|
||||
$countcustomers_stmt = Database::prepare("
|
||||
SELECT COUNT(`customerid`) as `countcustomers`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` " .
|
||||
($userinfo['customers_see_all'] ? '' : "WHERE `adminid` = :adminid")
|
||||
);
|
||||
$countcustomers = Database::pexecute_first($countcustomers_stmt, array('adminid' => $userinfo['adminid']));
|
||||
$countcustomers = (int)$countcustomers['countcustomers'];
|
||||
|
||||
if ($action == '') {
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_tickets");
|
||||
$fields = array(
|
||||
'status' => $lng['ticket']['status'],
|
||||
'lastchange' => $lng['ticket']['lastchange'],
|
||||
'subject' => $lng['ticket']['subject'],
|
||||
'lastreplier' => $lng['ticket']['lastreplier']
|
||||
);
|
||||
$paging = new paging($userinfo, TABLE_PANEL_TICKETS, $fields, null, null, 1, 'desc');
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `main`.`id`, `main`.`customerid`, (
|
||||
SELECT COUNT(`sub`.`id`)
|
||||
FROM `" . TABLE_PANEL_TICKETS . "` `sub`
|
||||
WHERE `sub`.`answerto` = `main`.`id`) as `ticket_answers`,
|
||||
`main`.`lastchange`, `main`.`subject`, `main`.`status`, `main`.`lastreplier`, `main`.`priority`
|
||||
FROM `" . TABLE_PANEL_TICKETS . "` as `main`
|
||||
WHERE `main`.`answerto` = '0' AND `archived` = '0' " .
|
||||
($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") .
|
||||
$paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()
|
||||
);
|
||||
Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid']));
|
||||
$num_rows = Database::num_rows();
|
||||
$paging->setEntries($num_rows);
|
||||
$sortcode = $paging->getHtmlSortCode($lng);
|
||||
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$searchcode = $paging->getHtmlSearchCode($lng);
|
||||
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$ctickets = array();
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
if (!isset($ctickets[$row['customerid']])
|
||||
|| !is_array($ctickets[$row['customerid']])
|
||||
) {
|
||||
$ctickets[$row['customerid']] = array();
|
||||
}
|
||||
$ctickets[$row['customerid']][$row['id']] = $row;
|
||||
}
|
||||
|
||||
if ($paging->sortfield == 'customerid'
|
||||
&& $paging->sortorder == 'desc'
|
||||
) {
|
||||
krsort($ctickets);
|
||||
} else {
|
||||
ksort($ctickets);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$count = 0;
|
||||
$tickets_count = 0;
|
||||
$tickets = '';
|
||||
foreach ($ctickets as $cid => $ticketrows) {
|
||||
$_cid = 0;
|
||||
foreach ($ticketrows as $row) {
|
||||
if ($paging->checkDisplay($i)) {
|
||||
|
||||
$row = htmlentities_array($row);
|
||||
$row['lastchange'] = date("d.m.y H:i", $row['lastchange']);
|
||||
|
||||
if ($_cid != $row['customerid']) {
|
||||
$cid = $row['customerid'];
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :cid'
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array('cid' => $cid));
|
||||
|
||||
if (isset($usr['loginname'])) {
|
||||
$customer = getCorrectFullUserDetails($usr);
|
||||
$customerloginname = $usr['loginname'];
|
||||
$customerid = $usr['customerid'];
|
||||
} else {
|
||||
$customer = $lng['ticket']['nonexistingcustomer'];
|
||||
}
|
||||
eval("\$tickets.=\"" . getTemplate("tickets/tickets_customer") . "\";");
|
||||
}
|
||||
|
||||
$tickets_count++;
|
||||
|
||||
if ($row['status'] >= 0
|
||||
&& $row['status'] <= 2
|
||||
) {
|
||||
$reopen = 0;
|
||||
} else {
|
||||
$reopen = 1;
|
||||
}
|
||||
|
||||
$row['status'] = ticket::getStatusText($lng, $row['status']);
|
||||
$row['priority'] = ticket::getPriorityText($lng, $row['priority']);
|
||||
|
||||
if ($row['lastreplier'] == '1') {
|
||||
$row['lastreplier'] = $lng['ticket']['staff'];
|
||||
$cananswer = 0;
|
||||
} else {
|
||||
$row['lastreplier'] = $lng['ticket']['customer'];
|
||||
$cananswer = 1;
|
||||
}
|
||||
|
||||
$row['subject'] = html_entity_decode($row['subject']);
|
||||
if (strlen($row['subject']) > 30) {
|
||||
$ts = wordwrap($row['subject'], 30, "|");
|
||||
$ts = explode("|", $ts);
|
||||
$row['subject'] = $ts[0]. '...';
|
||||
}
|
||||
|
||||
eval("\$tickets.=\"" . getTemplate("tickets/tickets_tickets") . "\";");
|
||||
$count++;
|
||||
$_cid = $row['customerid'];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
eval("echo \"" . getTemplate("tickets/tickets") . "\";");
|
||||
|
||||
} elseif($action == 'new') {
|
||||
|
||||
if ($userinfo['tickets_used'] < $userinfo['tickets']
|
||||
|| $userinfo['tickets'] == '-1'
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
$newticket = ticket::getInstanceOf($userinfo, -1);
|
||||
$newticket->Set('subject', validate($_POST['subject'], 'subject'), true, false);
|
||||
$newticket->Set('priority', validate($_POST['priority'], 'priority'), true, false);
|
||||
$newticket->Set('category', validate($_POST['category'], 'category'), true, false);
|
||||
$newticket->Set('customer', (int)$_POST['customer'], true, false);
|
||||
$newticket->Set('message', validate(htmlentities(str_replace("\r\n", "\n", $_POST['message'])), 'message', '/^[^\0]*$/'), true, false);
|
||||
|
||||
if ($newticket->Get('subject') == null) {
|
||||
standard_error(array('stringisempty', 'mysubject'));
|
||||
} elseif($newticket->Get('message') == null) {
|
||||
standard_error(array('stringisempty', 'mymessage'));
|
||||
} else {
|
||||
$now = time();
|
||||
$newticket->Set('admin', $userinfo['adminid'], true, true);
|
||||
$newticket->Set('dt', $now, true, true);
|
||||
$newticket->Set('lastchange', $now, true, true);
|
||||
$newticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true);
|
||||
$newticket->Set('status', '0', true, true);
|
||||
$newticket->Set('lastreplier', '1', true, true);
|
||||
$newticket->Set('by', '1', true, true);
|
||||
$newticket->Insert();
|
||||
$newticket->sendMail((int)$newticket->Get('customer'), 'new_ticket_by_staff_subject', $lng['mails']['new_ticket_by_staff']['subject'], 'new_ticket_by_staff_mailbody', $lng['mails']['new_ticket_by_staff']['mailbody']);
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "opened a new ticket for customer #" . $newticket->Get('customer') . " - '" . $newticket->Get('subject') . "'");
|
||||
redirectTo($filename, Array('page' => $page, 's' => $s));
|
||||
}
|
||||
} else {
|
||||
$categories = '';
|
||||
$where = '';
|
||||
if ($userinfo['tickets_see_all'] != '1') {
|
||||
$where = 'WHERE `adminid` = :adminid';
|
||||
}
|
||||
$result_stmt = Database::prepare('
|
||||
SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '`
|
||||
'.$where.' ORDER BY `logicalorder`, `name` ASC'
|
||||
);
|
||||
$result = Database::pexecute_first($result_stmt, array('adminid' => $userinfo['adminid']));
|
||||
|
||||
if (isset($result['name'])
|
||||
&& $result['name'] != ''
|
||||
) {
|
||||
$result2_stmt = Database::prepare('
|
||||
SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '`
|
||||
'.$where.' ORDER BY `logicalorder`, `name` ASC'
|
||||
);
|
||||
Database::pexecute($result2_stmt, array('adminid' => $userinfo['adminid']));
|
||||
|
||||
while ($row = $result2_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$categories.= makeoption($row['name'], $row['id']);
|
||||
}
|
||||
|
||||
} else {
|
||||
$categories = makeoption($lng['ticket']['no_cat'], '0');
|
||||
}
|
||||
|
||||
$customers = '';
|
||||
$result_customers_stmt = Database::prepare("
|
||||
SELECT `customerid`, `loginname`, `name`, `firstname`, `company`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` " .
|
||||
($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid")."
|
||||
ORDER BY `name` ASC"
|
||||
);
|
||||
Database::pexecute($result_customers_stmt, array('adminid' => $userinfo['adminid']));
|
||||
|
||||
while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$customers.= makeoption(getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']);
|
||||
}
|
||||
|
||||
$def_prio = Settings::Get('ticket.default_priority');
|
||||
$priorities = makeoption($lng['ticket']['high'], '1', $def_prio);
|
||||
$priorities.= makeoption($lng['ticket']['normal'], '2', $def_prio);
|
||||
$priorities.= makeoption($lng['ticket']['low'], '3', $def_prio);
|
||||
|
||||
$ticket_new_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.ticket_new.php';
|
||||
$ticket_new_form = htmlform::genHTMLForm($ticket_new_data);
|
||||
|
||||
$title = $ticket_new_data['ticket_new']['title'];
|
||||
$image = $ticket_new_data['ticket_new']['image'];
|
||||
|
||||
eval("echo \"" . getTemplate("tickets/tickets_new") . "\";");
|
||||
}
|
||||
|
||||
} else {
|
||||
standard_error('nomoreticketsavailable');
|
||||
}
|
||||
|
||||
} elseif($action == 'answer'
|
||||
&& $id != 0
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
$replyticket = ticket::getInstanceOf($userinfo, -1);
|
||||
$replyticket->Set('subject', validate($_POST['subject'], 'subject'), true, false);
|
||||
$replyticket->Set('priority', validate($_POST['priority'], 'priority'), true, false);
|
||||
$replyticket->Set('message', validate(htmlentities(str_replace("\r\n", "\n", $_POST['message'])), 'message', '/^[^\0]*$/'), true, false);
|
||||
|
||||
if ($replyticket->Get('message') == null) {
|
||||
standard_error(array('stringisempty', 'mymessage'));
|
||||
} else {
|
||||
$now = time();
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$replyticket->Set('customer', $mainticket->Get('customer'), true, true);
|
||||
$replyticket->Set('lastchange', $now, true, true);
|
||||
$replyticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true);
|
||||
$replyticket->Set('status', '1', true, true);
|
||||
$replyticket->Set('answerto', (int)$id, true, false);
|
||||
$replyticket->Set('by', '1', true, true);
|
||||
$replyticket->Insert();
|
||||
|
||||
// Update priority if changed
|
||||
if ($replyticket->Get('priority') != $mainticket->Get('priority')) {
|
||||
$mainticket->Set('priority', $replyticket->Get('priority'), true);
|
||||
}
|
||||
|
||||
$mainticket->Set('lastchange', $now);
|
||||
$mainticket->Set('lastreplier', '1');
|
||||
$mainticket->Set('status', '2');
|
||||
$mainticket->Update();
|
||||
$mainticket->sendMail((int)$mainticket->Get('customer'), 'new_reply_ticket_by_staff_subject', $lng['mails']['new_reply_ticket_by_staff']['subject'], 'new_reply_ticket_by_staff_mailbody', $lng['mails']['new_reply_ticket_by_staff']['mailbody']);
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "answered ticket '" . $mainticket->Get('subject') . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$ticket_replies = '';
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$dt = date("d.m.Y H:i\h", $mainticket->Get('dt'));
|
||||
$status = ticket::getStatusText($lng, $mainticket->Get('status'));
|
||||
|
||||
if ($mainticket->Get('status') >= 0
|
||||
&& $mainticket->Get('status') <= 2
|
||||
) {
|
||||
$isclosed = 0;
|
||||
} else {
|
||||
$isclosed = 1;
|
||||
}
|
||||
|
||||
if ($mainticket->Get('by') == '1') {
|
||||
$by = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$cid = $mainticket->Get('customer');
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :cid'
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array('cid' => $cid));
|
||||
$by = '<a href="'.$linker->getLink(array('section' => 'customers', 'page' => 'customers', 'action' => 'su', 'id' => $cid)).'" rel="external">';
|
||||
$by .= getCorrectFullUserDetails($usr).'</a>';
|
||||
}
|
||||
|
||||
$subject = $mainticket->Get('subject');
|
||||
$message = $mainticket->Get('message');
|
||||
eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_main") . "\";");
|
||||
|
||||
$result_stmt = Database::prepare('
|
||||
SELECT `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` WHERE `id` = :cid'
|
||||
);
|
||||
$row = Database::pexecute_first($result_stmt, array('cid' => $mainticket->Get('category')));
|
||||
|
||||
$andere_stmt = Database::prepare('
|
||||
SELECT * FROM `' . TABLE_PANEL_TICKETS . '`
|
||||
WHERE `answerto` = :id ORDER BY `lastchange` ASC'
|
||||
);
|
||||
Database::pexecute($andere_stmt, array('id' => $id));
|
||||
$numrows_andere = Database::num_rows();
|
||||
|
||||
while ($row2 = $andere_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$subticket = ticket::getInstanceOf($userinfo, (int)$row2['id']);
|
||||
$lastchange = date("d.m.Y H:i\h", $subticket->Get('lastchange'));
|
||||
|
||||
if ($subticket->Get('by') == '1') {
|
||||
$by = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$cid = $subticket->Get('customer');
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :cid'
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array('cid' => $cid));
|
||||
$by = '<a href="'.$linker->getLink(array('section' => 'customers', 'page' => 'customers', 'action' => 'su', 'id' => $cid)).'" rel="external">';
|
||||
$by .= getCorrectFullUserDetails($usr).'</a>';
|
||||
}
|
||||
|
||||
$subject = $subticket->Get('subject');
|
||||
$message = $subticket->Get('message');
|
||||
|
||||
$row2 = htmlentities_array($row2);
|
||||
eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_list") . "\";");
|
||||
}
|
||||
|
||||
$priorities = makeoption($lng['ticket']['high'], '1', $mainticket->Get('priority'), true, true);
|
||||
$priorities.= makeoption($lng['ticket']['normal'], '2', $mainticket->Get('priority'), true, true);
|
||||
$priorities.= makeoption($lng['ticket']['low'], '3', $mainticket->Get('priority'), true, true);
|
||||
$subject = htmlentities($mainticket->Get('subject'));
|
||||
$ticket_replies_count = $numrows_andere + 1;
|
||||
|
||||
// don't forget the main-ticket!
|
||||
$ticket_reply_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.ticket_reply.php';
|
||||
$ticket_reply_form = htmlform::genHTMLForm($ticket_reply_data);
|
||||
|
||||
$title = $ticket_reply_data['ticket_reply']['title'];
|
||||
$image = $ticket_reply_data['ticket_reply']['image'];
|
||||
|
||||
eval("echo \"" . getTemplate("tickets/tickets_reply") . "\";");
|
||||
}
|
||||
|
||||
} elseif($action == 'close'
|
||||
&& $id != 0
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
$now = time();
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '1', true, true);
|
||||
$mainticket->Set('status', '3', true, true);
|
||||
$mainticket->Update();
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "closed ticket '" . $mainticket->Get('subject') . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
} else {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
ask_yesno('ticket_reallyclose', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject'));
|
||||
}
|
||||
|
||||
} elseif($action == 'reopen'
|
||||
&& $id != 0
|
||||
) {
|
||||
$now = time();
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '1', true, true);
|
||||
$mainticket->Set('status', '0', true, true);
|
||||
$mainticket->Update();
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "reopened ticket '" . $mainticket->Get('subject') . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
|
||||
} elseif($action == 'archive'
|
||||
&& $id != 0
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
$now = time();
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '1', true, true);
|
||||
$mainticket->Set('status', '3', true, true);
|
||||
$mainticket->Update();
|
||||
$mainticket->Archive();
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "archived ticket '" . $mainticket->Get('subject') . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
} else {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
ask_yesno('ticket_reallyarchive', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject'));
|
||||
}
|
||||
|
||||
} elseif($action == 'delete'
|
||||
&& $id != 0
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$log->logAction(ADM_ACTION, LOG_INFO, "deleted ticket '" . $mainticket->Get('subject') . "'");
|
||||
$mainticket->Delete();
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
} else {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
ask_yesno('ticket_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject'));
|
||||
}
|
||||
}
|
||||
|
||||
} elseif($page == 'categories'
|
||||
&& $userinfo['customers'] != '0'
|
||||
) {
|
||||
if ($action == '') {
|
||||
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_tickets::categories");
|
||||
$fields = array(
|
||||
'name' => $lng['ticket']['category'],
|
||||
'logicalorder' => $lng['ticket']['logicalorder']
|
||||
);
|
||||
|
||||
$where = '1'; // WHERE 1 is like no 'where-clause'
|
||||
if ($userinfo['tickets_see_all'] != '1') {
|
||||
$where = " `main`.`adminid` = :adminid";
|
||||
}
|
||||
$paging = new paging($userinfo, TABLE_PANEL_TICKET_CATS, $fields);
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `main`.`id`, `main`.`name`, `main`.`logicalorder`, (
|
||||
SELECT COUNT(`sub`.`id`) FROM `" . TABLE_PANEL_TICKETS . "` `sub`
|
||||
WHERE `sub`.`category` = `main`.`id`
|
||||
AND `sub`.`answerto` = '0'
|
||||
AND `sub`.`adminid` = :adminid
|
||||
) as `ticketcount`, (
|
||||
SELECT COUNT(`sub2`.`id`) FROM `" . TABLE_PANEL_TICKETS . "` `sub2`
|
||||
WHERE `sub2`.`category` = `main`.`id`
|
||||
AND `sub2`.`answerto` = '0'
|
||||
AND (`sub2`.`status` = '0' OR `sub2`.`status` = '1' OR `sub2`.`status` = '2')
|
||||
AND `sub2`.`adminid` = :adminid
|
||||
) as `ticketcountnotclosed`
|
||||
FROM `" . TABLE_PANEL_TICKET_CATS . "` `main`
|
||||
WHERE " . $where . $paging->getSqlWhere(true) . " " .
|
||||
$paging->getSqlOrderBy() . " " . $paging->getSqlLimit()
|
||||
);
|
||||
Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid']));
|
||||
$numrows = Database::num_rows();
|
||||
$paging->setEntries($numrows);
|
||||
$sortcode = $paging->getHtmlSortCode($lng);
|
||||
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$searchcode = $paging->getHtmlSearchCode($lng);
|
||||
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$i = 0;
|
||||
$count = 0;
|
||||
$ticketcategories = '';
|
||||
$categories_count = $numrows;
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if ($paging->checkDisplay($i)) {
|
||||
$row = htmlentities_array($row);
|
||||
$closedtickets_count = ($row['ticketcount'] - $row['ticketcountnotclosed']);
|
||||
eval("\$ticketcategories.=\"" . getTemplate("tickets/tickets_categories") . "\";");
|
||||
$count++;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
eval("echo \"" . getTemplate("tickets/categories") . "\";");
|
||||
|
||||
} elseif($action == 'addcategory') {
|
||||
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
|
||||
$category = validate($_POST['category'], 'category');
|
||||
$order = validate($_POST['logicalorder'], 'logicalorder');
|
||||
|
||||
if ($order < 1 || $order >= 1000) {
|
||||
// use the latest available
|
||||
$order = ticket::getHighestOrderNumber($userinfo['adminid']) + 1;
|
||||
}
|
||||
|
||||
if ($category == '') {
|
||||
standard_error(array('stringisempty', 'mycategory'));
|
||||
} else {
|
||||
ticket::addCategory($category, $userinfo['adminid'], $order);
|
||||
$log->logAction(ADM_ACTION, LOG_INFO, "added ticket-category '" . $category . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
}
|
||||
} else {
|
||||
$order = ticket::getHighestOrderNumber($userinfo['adminid']) + 1;
|
||||
|
||||
$category_new_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.category_new.php';
|
||||
$category_new_form = htmlform::genHTMLForm($category_new_data);
|
||||
|
||||
$title = $category_new_data['category_new']['title'];
|
||||
$image = $category_new_data['category_new']['image'];
|
||||
|
||||
eval("echo \"" . getTemplate("tickets/tickets_newcategory") . "\";");
|
||||
}
|
||||
|
||||
} elseif($action == 'editcategory'
|
||||
&& $id != 0
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
|
||||
$category = validate($_POST['category'], 'category');
|
||||
$order = validate($_POST['logicalorder'], 'logicalorder');
|
||||
|
||||
if ($order < 1 || $order >= 1000) {
|
||||
$order = 1;
|
||||
}
|
||||
|
||||
if ($category == '') {
|
||||
standard_error(array('stringisempty', 'mycategory'));
|
||||
} else {
|
||||
ticket::editCategory($category, $id, $order);
|
||||
$log->logAction(ADM_ACTION, LOG_INFO, "edited ticket-category '" . $category . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
}
|
||||
} else {
|
||||
$row_stmt = Database::prepare('
|
||||
SELECT * FROM `' . TABLE_PANEL_TICKET_CATS . '` WHERE `id` = :id'
|
||||
);
|
||||
$row = Database::pexecute_first($row_stmt, array('id' => $id));
|
||||
$row = htmlentities_array($row);
|
||||
$category_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.category_edit.php';
|
||||
$category_edit_form = htmlform::genHTMLForm($category_edit_data);
|
||||
|
||||
$title = $category_edit_data['category_edit']['title'];
|
||||
$image = $category_edit_data['category_edit']['image'];
|
||||
|
||||
eval("echo \"" . getTemplate("tickets/tickets_editcategory") . "\";");
|
||||
}
|
||||
|
||||
} elseif($action == 'deletecategory'
|
||||
&& $id != 0
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
if (ticket::deleteCategory($id) == false) {
|
||||
standard_error('categoryhastickets');
|
||||
}
|
||||
|
||||
$log->logAction(ADM_ACTION, LOG_INFO, "deleted ticket-category #" . $id);
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
|
||||
} else {
|
||||
$name = ticket::getCategoryName($id);
|
||||
ask_yesno('ticket_reallydeletecat', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $name);
|
||||
}
|
||||
}
|
||||
|
||||
} elseif($page == 'archive'
|
||||
&& $userinfo['customers'] != '0'
|
||||
) {
|
||||
if ($action == '') {
|
||||
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_tickets::archive");
|
||||
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
$priority = array();
|
||||
$categories = array();
|
||||
$subject = validate($_POST['subject'], 'subject');
|
||||
$priority[0] = isset($_POST['priority1']) ? $_POST['priority1'] : '';
|
||||
$priority[1] = isset($_POST['priority2']) ? $_POST['priority2'] : '';
|
||||
$priority[2] = isset($_POST['priority3']) ? $_POST['priority3'] : '';
|
||||
$fromdate = validate($_POST['fromdate'], 'fromdate');
|
||||
$todate = validate($_POST['todate'], 'todate');
|
||||
$message = validate($_POST['message'], 'message');
|
||||
$customer = validate($_POST['customer'], 'customer');
|
||||
|
||||
$cat_stmt = Database::query('SELECT COUNT(`id`) as `ccount` FROM `' . TABLE_PANEL_TICKET_CATS . '`');
|
||||
$cat = $cat_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
for ($x = 0;$x < $cat['ccount'];$x++) {
|
||||
$categories[$x] = isset($_POST['category' . $x]) ? $_POST['category' . $x] : '';
|
||||
}
|
||||
|
||||
$archive_search = ticket::getArchiveSearchStatement($subject, $priority, $fromdate, $todate, $message, $customer, $userinfo['adminid'], $categories);
|
||||
|
||||
$query = $archive_search[0];
|
||||
$archive_params = $archive_search[1];
|
||||
|
||||
$fields = array(
|
||||
'lastchange' => $lng['ticket']['lastchange'],
|
||||
'subject' => $lng['ticket']['subject'],
|
||||
'lastreplier' => $lng['ticket']['lastreplier']
|
||||
);
|
||||
$paging = new paging($userinfo, TABLE_PANEL_TICKETS, $fields);
|
||||
$result_stmt = Database::prepare($query . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
|
||||
Database::pexecute($result_stmt, $archive_params);
|
||||
$sortcode = $paging->getHtmlSortCode($lng);
|
||||
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$searchcode = $paging->getHtmlSearchCode($lng);
|
||||
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$ctickets = array();
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
if (!isset($ctickets[$row['customerid']])
|
||||
|| !is_array($ctickets[$row['customerid']])
|
||||
) {
|
||||
$ctickets[$row['customerid']] = array();
|
||||
}
|
||||
$ctickets[$row['customerid']][$row['id']] = $row;
|
||||
}
|
||||
|
||||
if ($paging->sortfield == 'customerid'
|
||||
&& $paging->sortorder == 'desc'
|
||||
) {
|
||||
krsort($ctickets);
|
||||
} else {
|
||||
ksort($ctickets);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$count = 0;
|
||||
$tickets_count = 0;
|
||||
$tickets = '';
|
||||
foreach ($ctickets as $cid => $ticketrows) {
|
||||
if ($paging->sortfield == 'lastchange'
|
||||
&& $paging->sortorder == 'desc'
|
||||
) {
|
||||
krsort($ticketrows);
|
||||
} else {
|
||||
ksort($ticketrows);
|
||||
}
|
||||
|
||||
$_cid = -1;
|
||||
foreach ($ticketrows as $ticket) {
|
||||
if ($paging->checkDisplay($i)) {
|
||||
$ticket['lastchange'] = date("d.m.y H:i", $ticket['lastchange']);
|
||||
if ($_cid != $ticket['customerid']) {
|
||||
$cid = $ticket['customerid'];
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :cid'
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array('cid' => $cid));
|
||||
|
||||
if (isset($usr['loginname'])) {
|
||||
$customer = getCorrectFullUserDetails($usr);
|
||||
$customerloginname = $usr['loginname'];
|
||||
$customerid = $usr['customerid'];
|
||||
} else {
|
||||
$customer = $lng['ticket']['nonexistingcustomer'];
|
||||
$customerid = 0;
|
||||
$customerloginname = '';
|
||||
}
|
||||
eval("\$tickets.=\"" . getTemplate("tickets/tickets_customer") . "\";");
|
||||
}
|
||||
|
||||
$tickets_count++;
|
||||
switch ($ticket['priority'])
|
||||
{
|
||||
case 1: $ticket['display'] = 'high';
|
||||
break;
|
||||
case 2: $ticket['display'] = 'normal';
|
||||
break;
|
||||
case 3: $ticket['display'] = 'low';
|
||||
break;
|
||||
default: $ticket['display'] = 'unknown';
|
||||
}
|
||||
$ticket['priority'] = ticket::getPriorityText($lng, $ticket['priority']);
|
||||
|
||||
if ($ticket['lastreplier'] == '1') {
|
||||
$ticket['lastreplier'] = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$ticket['lastreplier'] = $lng['ticket']['customer'];
|
||||
}
|
||||
|
||||
if (strlen($ticket['subject']) > 20) {
|
||||
$ticket['subject'] = substr($ticket['subject'], 0, 17) . '...';
|
||||
}
|
||||
$ticket = htmlentities_array($ticket);
|
||||
eval("\$tickets.=\"" . getTemplate("tickets/archived_tickets") . "\";");
|
||||
$count++;
|
||||
$_cid = $ticket['customerid'];
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
eval("echo \"" . getTemplate("tickets/archivesearch") . "\";");
|
||||
|
||||
} else {
|
||||
|
||||
$archived = array();
|
||||
$archived = ticket::getLastArchived(6, $userinfo['adminid']);
|
||||
$tickets = '';
|
||||
|
||||
if ($archived !== false) {
|
||||
|
||||
foreach ($archived as $id => $ticket) {
|
||||
|
||||
$ticket['lastchange'] = date("d.m.y H:i", $ticket['lastchange']);
|
||||
$ticket['priority'] = ticket::getPriorityText($lng, $ticket['priority']);
|
||||
|
||||
if ($ticket['lastreplier'] == '1') {
|
||||
$ticket['lastreplier'] = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$ticket['lastreplier'] = $lng['ticket']['customer'];
|
||||
}
|
||||
|
||||
if (strlen($ticket['subject']) > 20) {
|
||||
$ticket['subject'] = substr($ticket['subject'], 0, 17) . '...';
|
||||
}
|
||||
eval("\$tickets.=\"" . getTemplate("tickets/archived_tickets") . "\";");
|
||||
}
|
||||
}
|
||||
|
||||
$priorities_options = makecheckbox('priority1', $lng['ticket']['high'], '1');
|
||||
$priorities_options.= makecheckbox('priority2', $lng['ticket']['normal'], '2');
|
||||
$priorities_options.= makecheckbox('priority3', $lng['ticket']['low'], '3');
|
||||
$category_options = '';
|
||||
$ccount = 0;
|
||||
$result = Database::query('SELECT * FROM `' . TABLE_PANEL_TICKET_CATS . '` ORDER BY `name` ASC');
|
||||
|
||||
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
|
||||
$category_options.= makecheckbox('category' . $ccount, $row['name'], $row['id'], true);
|
||||
$ccount++;
|
||||
}
|
||||
|
||||
$customers = makeoption($lng['ticket']['nocustomer'], '-1', '-1');
|
||||
$result_customers_stmt = Database::prepare("
|
||||
SELECT `customerid`, `loginname`, `name`, `firstname`, `company`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` " .
|
||||
($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid")."
|
||||
ORDER BY `name` ASC"
|
||||
);
|
||||
Database::pexecute($result_customers_stmt, array('adminid' => $userinfo['adminid']));
|
||||
|
||||
while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$customers.= makeoption(getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']);
|
||||
}
|
||||
eval("echo \"" . getTemplate("tickets/archive") . "\";");
|
||||
}
|
||||
|
||||
} elseif($action == 'view'
|
||||
&& $id != 0
|
||||
) {
|
||||
$log->logAction(ADM_ACTION, LOG_NOTICE, "viewed archived-ticket #" . $id);
|
||||
$ticket_replies = '';
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$lastchange = date("d.m.Y H:i\h", $mainticket->Get('lastchange'));
|
||||
$dt = date("d.m.Y H:i\h", $mainticket->Get('dt'));
|
||||
$status = ticket::getStatusText($lng, $mainticket->Get('status'));
|
||||
$isclosed = 1;
|
||||
|
||||
if ($mainticket->Get('by') == '1') {
|
||||
$by = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$cid = $mainticket->Get('customer');
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :cid'
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array('cid' => $cid));
|
||||
|
||||
if (isset($usr['loginname'])) {
|
||||
$customer = getCorrectFullUserDetails($usr);
|
||||
$customerloginname = ' ('.$usr['loginname'].')';
|
||||
$customerid = $usr['customerid'];
|
||||
} else {
|
||||
$customer = $lng['ticket']['nonexistingcustomer'];
|
||||
$customerid = 0;
|
||||
$customerloginname = '';
|
||||
}
|
||||
if ($customerid != 0) {
|
||||
$by = '<a href="'.$linker->getLink(array('section' => 'customers', 'page' => 'customers', 'action' => 'su', 'id' => $customerid)).'" rel="external">';
|
||||
$by .= $customer.$customerloginname.'</a>';
|
||||
} else {
|
||||
$by = $customer;
|
||||
}
|
||||
}
|
||||
|
||||
$subject = $mainticket->Get('subject');
|
||||
$message = $mainticket->Get('message');
|
||||
eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_main") . "\";");
|
||||
|
||||
$result_stmt = Database::prepare('
|
||||
SELECT `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` WHERE `id` = :cid'
|
||||
);
|
||||
$row = Database::pexecute_first($result_stmt, array('cid' => $mainticket->Get('category')));
|
||||
|
||||
$andere_stmt = Database::prepare('
|
||||
SELECT * FROM `' . TABLE_PANEL_TICKETS . '` WHERE `answerto` = :id'
|
||||
);
|
||||
Database::pexecute($andere_stmt, array('id' => $id));
|
||||
$numrows_andere = Database::num_rows();
|
||||
|
||||
while ($row2 = $andere_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$subticket = ticket::getInstanceOf($userinfo, (int)$row2['id']);
|
||||
$lastchange = date("d.m.Y H:i\h", $subticket->Get('lastchange'));
|
||||
|
||||
if ($subticket->Get('by') == '1') {
|
||||
$by = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$cid = $subticket->Get('customer');
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :cid'
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array('cid' => $cid));
|
||||
|
||||
if (isset($usr['loginname'])) {
|
||||
$customer = getCorrectFullUserDetails($usr);
|
||||
$customerloginname = ' ('.$usr['loginname'].')';
|
||||
$customerid = $usr['customerid'];
|
||||
} else {
|
||||
$customer = $lng['ticket']['nonexistingcustomer'];
|
||||
$customerid = 0;
|
||||
$customerloginname = '';
|
||||
}
|
||||
if ($customerid != 0) {
|
||||
$by = '<a href="'.$linker->getLink(array('section' => 'customers', 'page' => 'customers', 'action' => 'su', 'id' => $customerid)).'" rel="external">';
|
||||
$by .= $customer.$customerloginname.'</a>';
|
||||
} else {
|
||||
$by = $customer;
|
||||
}
|
||||
}
|
||||
|
||||
$subject = $subticket->Get('subject');
|
||||
$message = $subticket->Get('message');
|
||||
eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_list") . "\";");
|
||||
}
|
||||
|
||||
$priorities = makeoption($lng['ticket']['high'], '1', htmlentities($mainticket->Get('priority')), true, true);
|
||||
$priorities.= makeoption($lng['ticket']['normal'], '2', htmlentities($mainticket->Get('priority')), true, true);
|
||||
$priorities.= makeoption($lng['ticket']['low'], '3', htmlentities($mainticket->Get('priority')), true, true);
|
||||
$subject = $mainticket->Get('subject');
|
||||
$ticket_replies_count = $numrows_andere + 1;
|
||||
|
||||
// don't forget the main-ticket!
|
||||
eval("echo \"" . getTemplate("tickets/tickets_view") . "\";");
|
||||
|
||||
} elseif($action == 'delete'
|
||||
&& $id != 0
|
||||
) {
|
||||
if (isset($_POST['send'])
|
||||
&& $_POST['send'] == 'send'
|
||||
) {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
$log->logAction(ADM_ACTION, LOG_INFO, "deleted archived ticket '" . $mainticket->Get('subject') . "'");
|
||||
$mainticket->Delete();
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
} else {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
ask_yesno('ticket_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
standard_error('nocustomerforticket');
|
||||
}
|
||||
@@ -1,413 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Panel
|
||||
*
|
||||
*/
|
||||
|
||||
define('AREA', 'customer');
|
||||
require './lib/init.php';
|
||||
|
||||
use Froxlor\Database as Database;
|
||||
use Froxlor\Settings as Settings;
|
||||
|
||||
if (isset($_POST['id'])) {
|
||||
|
||||
$id = intval($_POST['id']);
|
||||
|
||||
//Check if the current user is allowed to see the current ticket.
|
||||
$stmt = Database::prepare("SELECT `id` FROM `panel_tickets` WHERE `id` = :id AND `customerid` = :customerid");
|
||||
$result = Database::pexecute_first($stmt, array("id" => $id, "customerid" => $userinfo['customerid']));
|
||||
|
||||
if ($result == null) {
|
||||
// no rights to see the requested ticket
|
||||
standard_error(array('ticketnotaccessible'));
|
||||
}
|
||||
} elseif (isset($_GET['id'])) {
|
||||
$id = intval($_GET['id']);
|
||||
}
|
||||
|
||||
if ($page == 'overview') {
|
||||
$log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_tickets");
|
||||
eval("echo \"" . getTemplate("tickets/ticket") . "\";");
|
||||
} elseif ($page == 'tickets') {
|
||||
if ($action == '') {
|
||||
$log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_tickets::tickets");
|
||||
$fields = array(
|
||||
'status' => $lng['ticket']['status'],
|
||||
'lastchange' => $lng['ticket']['lastchange'],
|
||||
'subject' => $lng['ticket']['subject'],
|
||||
'lastreplier' => $lng['ticket']['lastreplier']
|
||||
);
|
||||
$paging = new paging($userinfo, TABLE_PANEL_TICKETS, $fields);
|
||||
$stmt = Database::prepare('SELECT `main`.`id`, (SELECT COUNT(`sub`.`id`) FROM `' . TABLE_PANEL_TICKETS . '` `sub`
|
||||
WHERE `sub`.`answerto` = `main`.`id`) AS `ticket_answers`, `main`.`lastchange`, `main`.`subject`, `main`.`status`, `main`.`lastreplier`, `main`.`priority`
|
||||
FROM `' . TABLE_PANEL_TICKETS . '` as `main`
|
||||
WHERE `main`.`answerto` = "0"
|
||||
AND `archived` = "0"
|
||||
AND `customerid`= :customerid ' . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()
|
||||
);
|
||||
Database::pexecute($stmt, array("customerid" => $userinfo['customerid']));
|
||||
|
||||
$paging->setEntries(Database::num_rows());
|
||||
$sortcode = $paging->getHtmlSortCode($lng);
|
||||
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$searchcode = $paging->getHtmlSearchCode($lng);
|
||||
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
|
||||
$i = 0;
|
||||
$count = 0;
|
||||
$tickets = '';
|
||||
$tickets_count = 0;
|
||||
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($paging->checkDisplay($i)) {
|
||||
$tickets_count++;
|
||||
$row = htmlentities_array($row);
|
||||
$row['lastchange'] = date("d.m.y H:i", $row['lastchange']);
|
||||
|
||||
if ($row['status'] >= 0 && $row['status'] <= 2) {
|
||||
$reopen = 0;
|
||||
} else {
|
||||
$reopen = 1;
|
||||
}
|
||||
|
||||
$row['status'] = ticket::getStatusText($lng, $row['status']);
|
||||
$row['priority'] = ticket::getPriorityText($lng, $row['priority']);
|
||||
|
||||
if ($row['lastreplier'] == '1') {
|
||||
$row['lastreplier'] = $lng['ticket']['staff'];
|
||||
$cananswer = 1;
|
||||
} else {
|
||||
$row['lastreplier'] = $lng['ticket']['customer'];
|
||||
$cananswer = 0;
|
||||
}
|
||||
|
||||
$row['subject'] = html_entity_decode($row['subject']);
|
||||
if (strlen($row['subject']) > 30) {
|
||||
$ts = wordwrap($row['subject'], 30, "|");
|
||||
$ts = explode("|", $ts);
|
||||
$row['subject'] = $ts[0]. '...';
|
||||
}
|
||||
|
||||
eval("\$tickets.=\"" . getTemplate("tickets/tickets_tickets") . "\";");
|
||||
$count++;
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
$supportavailable = 0;
|
||||
$time = date("Hi", time());
|
||||
$day = date("w", time());
|
||||
$start = substr(Settings::Get('ticket.worktime_begin'), 0, 2) . substr(Settings::Get('ticket.worktime_begin'), 3, 2);
|
||||
$end = substr(Settings::Get('ticket.worktime_end'), 0, 2) . substr(Settings::Get('ticket.worktime_end'), 3, 2);
|
||||
|
||||
if ($time >= $start && $time <= $end) {
|
||||
$supportavailable = 1;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.worktime_sat') == "0" && $day == "6") {
|
||||
$supportavailable = 0;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.worktime_sun') == "0" && $day == "0") {
|
||||
$supportavailable = 0;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.worktime_all') == "1") {
|
||||
$supportavailable = 1;
|
||||
}
|
||||
|
||||
$ticketsopen = 0;
|
||||
$stmt = Database::prepare('SELECT COUNT(`id`) as `count` FROM `' . TABLE_PANEL_TICKETS . '`
|
||||
WHERE `customerid` = :customerid
|
||||
AND `answerto` = "0"
|
||||
AND (`status` = "0" OR `status` = "1" OR `status` = "2")'
|
||||
);
|
||||
$opentickets = Database::pexecute_first($stmt, array("customerid" => $userinfo['customerid']));
|
||||
|
||||
if (Settings::Get('ticket.concurrently_open') != - 1 && Settings::Get('ticket.concurrently_open') != '') {
|
||||
$notmorethanxopentickets = strtr($lng['ticket']['notmorethanxopentickets'], array('%s' => Settings::Get('ticket.concurrently_open')));
|
||||
} else {
|
||||
$notmorethanxopentickets = '';
|
||||
}
|
||||
|
||||
$ticketsopen = (int)$opentickets['count'];
|
||||
eval("echo \"" . getTemplate("tickets/tickets") . "\";");
|
||||
|
||||
} elseif ($action == 'new') {
|
||||
if ($userinfo['tickets_used'] < $userinfo['tickets'] || $userinfo['tickets'] == '-1') {
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
$newticket = ticket::getInstanceOf($userinfo, -1);
|
||||
$newticket->Set('subject', validate($_POST['subject'], 'subject'), true, false);
|
||||
$newticket->Set('priority', validate($_POST['priority'], 'priority'), true, false);
|
||||
$newticket->Set('category', validate($_POST['category'], 'category'), true, false);
|
||||
$newticket->Set('customer', (int)$userinfo['customerid'], true, false);
|
||||
$newticket->Set('admin', (int)$userinfo['adminid'], true, false);
|
||||
$newticket->Set('message', validate(str_replace("\r\n", "\n", $_POST['message']), 'message', '/^[^\0]*$/'), true, false);
|
||||
|
||||
if ($newticket->Get('subject') == null) {
|
||||
standard_error(array('stringisempty', 'mysubject'));
|
||||
} elseif ($newticket->Get('message') == null) {
|
||||
standard_error(array('stringisempty', 'mymessage'));
|
||||
} else {
|
||||
$now = time();
|
||||
$newticket->Set('dt', $now, true, true);
|
||||
$newticket->Set('lastchange', $now, true, true);
|
||||
$newticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true);
|
||||
$newticket->Set('status', '0', true, true);
|
||||
$newticket->Set('lastreplier', '0', true, true);
|
||||
$newticket->Set('by', '0', true, true);
|
||||
$newticket->Insert();
|
||||
$log->logAction(USR_ACTION, LOG_NOTICE, "opened support-ticket '" . $newticket->Get('subject') . "'");
|
||||
|
||||
$stmt = Database::prepare('UPDATE `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
SET `tickets_used`=`tickets_used` + 1
|
||||
WHERE `customerid`= :customerid'
|
||||
);
|
||||
Database::pexecute($stmt, array("customerid" => $userinfo['customerid']));
|
||||
|
||||
// Customer mail
|
||||
$newticket->sendMail((int)$userinfo['customerid'], 'new_ticket_for_customer_subject', $lng['mails']['new_ticket_for_customer']['subject'], 'new_ticket_for_customer_mailbody', $lng['mails']['new_ticket_for_customer']['mailbody']);
|
||||
|
||||
// Admin mail
|
||||
$newticket->sendMail(-1, 'new_ticket_by_customer_subject', $lng['mails']['new_ticket_by_customer']['subject'], 'new_ticket_by_customer_mailbody', $lng['mails']['new_ticket_by_customer']['mailbody']);
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
}
|
||||
} else {
|
||||
$categories = '';
|
||||
$result_stmt = Database::prepare('SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '`
|
||||
WHERE `adminid` = :adminid
|
||||
ORDER BY `logicalorder`, `name` ASC'
|
||||
);
|
||||
$result = Database::pexecute_first($result_stmt, array("adminid" => $userinfo['adminid']));
|
||||
|
||||
if (isset($result['name']) && $result['name'] != '') {
|
||||
$result2_stmt = Database::prepare('SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '`
|
||||
WHERE `adminid` = :adminid
|
||||
ORDER BY `logicalorder`, `name` ASC'
|
||||
);
|
||||
Database::pexecute($result2_stmt, array("adminid" => $userinfo['adminid']));
|
||||
|
||||
while ($row = $result2_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$categories.= makeoption($row['name'], $row['id']);
|
||||
}
|
||||
} else {
|
||||
$categories = makeoption($lng['ticket']['no_cat'], '0');
|
||||
}
|
||||
|
||||
$priorities = makeoption($lng['ticket']['high'], '1');
|
||||
$priorities.= makeoption($lng['ticket']['normal'], '2');
|
||||
$priorities.= makeoption($lng['ticket']['low'], '3');
|
||||
$ticketsopen = 0;
|
||||
$opentickets_stmt = Database::prepare('SELECT COUNT(`id`) as `count` FROM `' . TABLE_PANEL_TICKETS . '`
|
||||
WHERE `customerid` = :customerid
|
||||
AND `answerto` = "0"
|
||||
AND (`status` = "0" OR `status` = "1" OR `status` = "2")'
|
||||
);
|
||||
$opentickets = Database::pexecute_first($opentickets_stmt, array("customerid" => $userinfo['customerid']));
|
||||
|
||||
if (Settings::Get('ticket.concurrently_open') != -1 && Settings::Get('ticket.concurrently_open') != '') {
|
||||
$notmorethanxopentickets = strtr($lng['ticket']['notmorethanxopentickets'], array('%s' => Settings::Get('ticket.concurrently_open')));
|
||||
} else {
|
||||
$notmorethanxopentickets = '';
|
||||
}
|
||||
|
||||
$ticketsopen = (int)$opentickets['count'];
|
||||
|
||||
$ticket_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/tickets/formfield.ticket_add.php';
|
||||
$ticket_add_form = htmlform::genHTMLForm($ticket_add_data);
|
||||
|
||||
$title = $ticket_add_data['ticket_add']['title'];
|
||||
$image = $ticket_add_data['ticket_add']['image'];
|
||||
|
||||
eval("echo \"" . getTemplate("tickets/tickets_new") . "\";");
|
||||
}
|
||||
} else {
|
||||
standard_error('nomoreticketsavailable');
|
||||
}
|
||||
} elseif ($action == 'answer' && $id != 0) {
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
try {
|
||||
$replyticket = ticket::getInstanceOf($userinfo, -1);
|
||||
} catch(Exception $e) {
|
||||
standard_error($e->getMessage());
|
||||
}
|
||||
$replyticket->Set('subject', validate($_POST['subject'], 'subject'), true, false);
|
||||
$replyticket->Set('priority', validate($_POST['priority'], 'priority'), true, false);
|
||||
$replyticket->Set('message', validate(str_replace("\r\n", "\n", $_POST['message']), 'message', '/^[^\0]*$/'), true, false);
|
||||
|
||||
if ($replyticket->Get('message') == null) {
|
||||
standard_error(array('stringisempty', 'mymessage'));
|
||||
} else {
|
||||
try {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
} catch(Exception $e) {
|
||||
standard_error($e->getMessage());
|
||||
}
|
||||
$now = time();
|
||||
$replyticket->Set('customer', (int)$userinfo['customerid'], true, true);
|
||||
$replyticket->Set('lastchange', $now, true, true);
|
||||
$replyticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true);
|
||||
$replyticket->Set('status', '1', true, true);
|
||||
$replyticket->Set('answerto', (int)$id, true, false);
|
||||
$replyticket->Set('by', '0', true, true);
|
||||
$replyticket->Insert();
|
||||
|
||||
// Update priority if changed
|
||||
if ($replyticket->Get('priority') != $mainticket->Get('priority')) {
|
||||
$mainticket->Set('priority', $replyticket->Get('priority'), true);
|
||||
}
|
||||
|
||||
$mainticket->Set('lastchange', $now);
|
||||
$mainticket->Set('lastreplier', '0');
|
||||
$mainticket->Set('status', '1');
|
||||
$mainticket->Update();
|
||||
$log->logAction(USR_ACTION, LOG_NOTICE, "answered support-ticket '" . $mainticket->Get('subject') . "'");
|
||||
$mainticket->sendMail(-1, 'new_reply_ticket_by_customer_subject', $lng['mails']['new_reply_ticket_by_customer']['subject'], 'new_reply_ticket_by_customer_mailbody', $lng['mails']['new_reply_ticket_by_customer']['mailbody']);
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
}
|
||||
} else {
|
||||
$ticket_replies = '';
|
||||
try {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
} catch(Exception $e) {
|
||||
standard_error($e->getMessage());
|
||||
}
|
||||
$dt = date("d.m.Y H:i\h", $mainticket->Get('dt'));
|
||||
$status = ticket::getStatusText($lng, $mainticket->Get('status'));
|
||||
|
||||
if ($mainticket->Get('status') >= 0 && $mainticket->Get('status') <= 2) {
|
||||
$isclosed = 0;
|
||||
} else {
|
||||
$isclosed = 1;
|
||||
}
|
||||
|
||||
if ($mainticket->Get('by') == '1') {
|
||||
$by = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$cid = $mainticket->Get('customer');
|
||||
$usr_stmt = Database::prepare('SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :customerid '
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array("customerid" => $cid));
|
||||
$by = getCorrectFullUserDetails($usr);
|
||||
}
|
||||
|
||||
$subject = $mainticket->Get('subject');
|
||||
$message = $mainticket->Get('message');
|
||||
eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_main") . "\";");
|
||||
$result_stmt = Database::prepare('SELECT `name` FROM `' . TABLE_PANEL_TICKET_CATS . '`
|
||||
WHERE `id`= :id '
|
||||
);
|
||||
$row = Database::pexecute_first($result_stmt, array("id" => $mainticket->Get('category')));
|
||||
|
||||
$andere_stmt = Database::prepare('SELECT * FROM `' . TABLE_PANEL_TICKETS . '`
|
||||
WHERE `answerto`= :answerto
|
||||
ORDER BY `lastchange` ASC'
|
||||
);
|
||||
Database::pexecute($andere_stmt, array("answerto" => $id));
|
||||
$numrows_andere = Database::num_rows();
|
||||
|
||||
while ($row2 = $andere_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$subticket = ticket::getInstanceOf($userinfo, (int)$row2['id']);
|
||||
$lastchange = date("d.m.Y H:i\h", $subticket->Get('lastchange'));
|
||||
|
||||
if ($subticket->Get('by') == '1') {
|
||||
$by = $lng['ticket']['staff'];
|
||||
} else {
|
||||
$cid = $subticket->Get('customer');
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `customerid`, `firstname`, `name`, `company`, `loginname`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '`
|
||||
WHERE `customerid` = :customerid '
|
||||
);
|
||||
$usr = Database::pexecute_first($usr_stmt, array("customerid" => $cid));
|
||||
$by = getCorrectFullUserDetails($usr);
|
||||
}
|
||||
|
||||
$subject = $subticket->Get('subject');
|
||||
$message = $subticket->Get('message');
|
||||
|
||||
$row2 = htmlentities_array($row2);
|
||||
eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_list") . "\";");
|
||||
}
|
||||
|
||||
$priorities = makeoption($lng['ticket']['high'], '1', $mainticket->Get('priority'), true, true);
|
||||
$priorities.= makeoption($lng['ticket']['normal'], '2', $mainticket->Get('priority'), true, true);
|
||||
$priorities.= makeoption($lng['ticket']['low'], '3', $mainticket->Get('priority'), true, true);
|
||||
$subject = htmlentities($mainticket->Get('subject'));
|
||||
$ticket_replies_count = $numrows_andere + 1;
|
||||
|
||||
// don't forget the main-ticket!
|
||||
$ticket_reply_data = include_once dirname(__FILE__).'/lib/formfields/customer/tickets/formfield.ticket_reply.php';
|
||||
$ticket_reply_form = htmlform::genHTMLForm($ticket_reply_data);
|
||||
|
||||
$title = $ticket_reply_data['ticket_reply']['title'];
|
||||
$image = $ticket_reply_data['ticket_reply']['image'];
|
||||
|
||||
eval("echo \"" . getTemplate("tickets/tickets_reply") . "\";");
|
||||
}
|
||||
} elseif ($action == 'close' && $id != 0) {
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
$now = time();
|
||||
try {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
} catch(Exception $e) {
|
||||
standard_error($e->getMessage());
|
||||
}
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '0', true, true);
|
||||
$mainticket->Set('status', '3', true, true);
|
||||
$mainticket->Update();
|
||||
$log->logAction(USR_ACTION, LOG_NOTICE, "closed support-ticket '" . $mainticket->Get('subject') . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
} else {
|
||||
try {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
} catch(Exception $e) {
|
||||
standard_error($e->getMessage());
|
||||
}
|
||||
ask_yesno('ticket_reallyclose', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject'));
|
||||
}
|
||||
} elseif ($action == 'reopen' && $id != 0) {
|
||||
$ticketsopen = 0;
|
||||
$opentickets_stmt = Database::prepare('SELECT COUNT(`id`) as `count` FROM `' . TABLE_PANEL_TICKETS . '`
|
||||
WHERE `customerid` = :customerid
|
||||
AND `answerto` = "0"
|
||||
AND (`status` = "0" OR `status` = "1" OR `status` = "2")'
|
||||
);
|
||||
$opentickets = Database::pexecute_first($opentickets_stmt, array("customerid" => $userinfo['customerid']));
|
||||
$ticketsopen = (int)$opentickets['count'];
|
||||
|
||||
if ($ticketsopen > Settings::Get('ticket.concurrently_open') && Settings::Get('ticket.concurrently_open') != - 1 && Settings::Get('ticket.concurrently_open') != '') {
|
||||
standard_error('notmorethanxopentickets', Settings::Get('ticket.concurrently_open'));
|
||||
}
|
||||
|
||||
$now = time();
|
||||
try {
|
||||
$mainticket = ticket::getInstanceOf($userinfo, (int)$id);
|
||||
} catch(Exception $e) {
|
||||
standard_error($e->getMessage());
|
||||
}
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '0', true, true);
|
||||
$mainticket->Set('status', '0', true, true);
|
||||
$mainticket->Update();
|
||||
$log->logAction(USR_ACTION, LOG_NOTICE, "reopened support-ticket '" . $mainticket->Get('subject') . "'");
|
||||
redirectTo($filename, array('page' => $page, 's' => $s));
|
||||
}
|
||||
}
|
||||
@@ -118,9 +118,6 @@ CREATE TABLE `panel_admins` (
|
||||
`email_quota_used` bigint(13) NOT NULL default '0',
|
||||
`ftps` int(15) NOT NULL default '0',
|
||||
`ftps_used` int(15) NOT NULL default '0',
|
||||
`tickets` int(15) NOT NULL default '-1',
|
||||
`tickets_used` int(15) NOT NULL default '0',
|
||||
`tickets_see_all` tinyint(1) NOT NULL default '0',
|
||||
`subdomains` int(15) NOT NULL default '0',
|
||||
`subdomains_used` int(15) NOT NULL default '0',
|
||||
`traffic` bigint(30) NOT NULL default '0',
|
||||
@@ -173,8 +170,6 @@ CREATE TABLE `panel_customers` (
|
||||
`email_quota_used` bigint(13) NOT NULL default '0',
|
||||
`ftps` int(15) NOT NULL default '0',
|
||||
`ftps_used` int(15) NOT NULL default '0',
|
||||
`tickets` int(15) NOT NULL default '0',
|
||||
`tickets_used` int(15) NOT NULL default '0',
|
||||
`subdomains` int(15) NOT NULL default '0',
|
||||
`subdomains_used` int(15) NOT NULL default '0',
|
||||
`traffic` bigint(30) NOT NULL default '0',
|
||||
@@ -367,17 +362,6 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
|
||||
('customer', 'ftpatdomain', '0'),
|
||||
('customer', 'show_news_feed', '0'),
|
||||
('customer', 'news_feed_url', ''),
|
||||
('ticket', 'noreply_email', 'NO-REPLY@SERVERNAME'),
|
||||
('ticket', 'worktime_all', '1'),
|
||||
('ticket', 'worktime_begin', '00:00'),
|
||||
('ticket', 'worktime_end', '23:59'),
|
||||
('ticket', 'worktime_sat', '0'),
|
||||
('ticket', 'worktime_sun', '0'),
|
||||
('ticket', 'archiving_days', '5'),
|
||||
('ticket', 'enabled', '1'),
|
||||
('ticket', 'concurrently_open', '5'),
|
||||
('ticket', 'noreply_name', 'Hosting Support'),
|
||||
('ticket', 'reset_cycle', '2'),
|
||||
('logger', 'enabled', '1'),
|
||||
('logger', 'log_cron', '0'),
|
||||
('logger', 'logfile', ''),
|
||||
@@ -404,7 +388,6 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
|
||||
('defaultwebsrverrhandler', 'err403', ''),
|
||||
('defaultwebsrverrhandler', 'err404', ''),
|
||||
('defaultwebsrverrhandler', 'err500', ''),
|
||||
('ticket', 'default_priority', '2'),
|
||||
('customredirect', 'enabled', '1'),
|
||||
('customredirect', 'default', '1'),
|
||||
('perl', 'suexecworkaround', '0'),
|
||||
@@ -635,7 +618,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'leapiversion', '1'),
|
||||
('system', 'backupenabled', '0'),
|
||||
('system', 'dnsenabled', '0'),
|
||||
('system', 'dns_server', 'bind'),
|
||||
('system', 'dns_server', 'Bind'),
|
||||
('system', 'apacheglobaldiropt', ''),
|
||||
('system', 'allow_customer_shell', '0'),
|
||||
('system', 'available_shells', ''),
|
||||
@@ -697,7 +680,7 @@ opcache.interned_strings_buffer'),
|
||||
('panel', 'customer_hide_options', ''),
|
||||
('panel', 'is_configured', '0'),
|
||||
('panel', 'version', '0.10.0'),
|
||||
('panel', 'db_version', '201812180');
|
||||
('panel', 'db_version', '201812190');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_tasks`;
|
||||
@@ -816,41 +799,6 @@ INSERT INTO `panel_languages` (`id`, `language`, `iso`, `file`) VALUES
|
||||
(7, 'Svenska', 'sv', 'lng/swedish.lng.php');
|
||||
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_tickets`;
|
||||
CREATE TABLE `panel_tickets` (
|
||||
`id` int(11) unsigned NOT NULL auto_increment,
|
||||
`customerid` int(11) NOT NULL,
|
||||
`adminid` int(11) NOT NULL,
|
||||
`category` smallint(5) unsigned NOT NULL default '1',
|
||||
`priority` enum('1','2','3') NOT NULL default '3',
|
||||
`subject` varchar(70) NOT NULL,
|
||||
`message` text NOT NULL,
|
||||
`dt` int(15) NOT NULL,
|
||||
`lastchange` int(15) NOT NULL,
|
||||
`ip` varchar(39) NOT NULL default '',
|
||||
`status` enum('0','1','2','3') NOT NULL default '1',
|
||||
`lastreplier` enum('0','1') NOT NULL default '0',
|
||||
`answerto` int(11) unsigned NOT NULL,
|
||||
`by` enum('0','1') NOT NULL default '0',
|
||||
`archived` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `customerid` (`customerid`)
|
||||
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_ticket_categories`;
|
||||
CREATE TABLE `panel_ticket_categories` (
|
||||
`id` smallint(5) unsigned NOT NULL auto_increment,
|
||||
`name` varchar(60) NOT NULL,
|
||||
`adminid` int(11) NOT NULL,
|
||||
`logicalorder` int(3) NOT NULL default '1',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_syslog`;
|
||||
CREATE TABLE IF NOT EXISTS `panel_syslog` (
|
||||
`logid` bigint(20) NOT NULL auto_increment,
|
||||
@@ -930,6 +878,7 @@ CREATE TABLE IF NOT EXISTS `cronjobs_run` (
|
||||
`id` bigint(20) NOT NULL auto_increment,
|
||||
`module` varchar(250) NOT NULL,
|
||||
`cronfile` varchar(250) NOT NULL,
|
||||
`cronclass` varchar(500) NOT NULL,
|
||||
`lastrun` int(15) NOT NULL DEFAULT '0',
|
||||
`interval` varchar(100) NOT NULL DEFAULT '5 MINUTE',
|
||||
`isactive` tinyint(1) DEFAULT '1',
|
||||
@@ -938,15 +887,13 @@ CREATE TABLE IF NOT EXISTS `cronjobs_run` (
|
||||
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
|
||||
INSERT INTO `cronjobs_run` (`id`, `module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES
|
||||
(1, 'froxlor/core', 'tasks', '5 MINUTE', '1', 'cron_tasks'),
|
||||
(2, 'froxlor/core', 'traffic', '1 DAY', '1', 'cron_traffic'),
|
||||
(3, 'froxlor/ticket', 'used_tickets_reset', '1 DAY', '1', 'cron_ticketsreset'),
|
||||
(4, 'froxlor/ticket', 'ticketarchive', '1 MONTH', '1', 'cron_ticketarchive'),
|
||||
(5, 'froxlor/reports', 'usage_report', '1 DAY', '1', 'cron_usage_report'),
|
||||
(6, 'froxlor/core', 'mailboxsize', '6 HOUR', '1', 'cron_mailboxsize'),
|
||||
(7, 'froxlor/letsencrypt', 'letsencrypt', '5 MINUTE', '0', 'cron_letsencrypt'),
|
||||
(8, 'froxlor/backup', 'backup', '1 DAY', '1', 'cron_backup');
|
||||
INSERT INTO `cronjobs_run` (`id`, `module`, `cronfile`, `cronclass`, `interval`, `isactive`, `desc_lng_key`) VALUES
|
||||
(1, 'froxlor/core', 'tasks', '\\Froxlor\\Cron\\TasksCron', '5 MINUTE', '1', 'cron_tasks'),
|
||||
(2, 'froxlor/core', 'traffic', '\\Froxlor\\Cron\\Traffic\\TrafficCron', '1 DAY', '1', 'cron_traffic'),
|
||||
(3, 'froxlor/reports', 'usage_report', '\\Froxlor\\Cron\\Traffic\\ReportsCron', '1 DAY', '1', 'cron_usage_report'),
|
||||
(4, 'froxlor/core', 'mailboxsize', '\\Froxlor\\Cron\\System\\MailboxsizeCron', '6 HOUR', '1', 'cron_mailboxsize'),
|
||||
(5, 'froxlor/letsencrypt', 'letsencrypt', '\\Froxlor\\Cron\\LetsEncrypt\\LetsEncrypt', '5 MINUTE', '0', 'cron_letsencrypt'),
|
||||
(6, 'froxlor/backup', 'backup', '\\Froxlor\\Cron\\System\\BackupCron', '1 DAY', '1', 'cron_backup');
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?php
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
@@ -21,9 +24,9 @@ if (! defined('_CRON_UPDATE')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isFroxlorVersion('0.9.40.1')) {
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.9.40.1')) {
|
||||
showUpdateStep("Updating from 0.9.40.1 to 0.10.0", false);
|
||||
|
||||
|
||||
showUpdateStep("Adding new api keys table");
|
||||
Database::query("DROP TABLE IF EXISTS `api_keys`;");
|
||||
$sql = "CREATE TABLE `api_keys` (
|
||||
@@ -40,15 +43,15 @@ if (isFroxlorVersion('0.9.40.1')) {
|
||||
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;";
|
||||
Database::query($sql);
|
||||
lastStepStatus(0);
|
||||
|
||||
|
||||
showUpdateStep("Adding new api settings");
|
||||
Settings::AddNew('api.enabled', 0);
|
||||
lastStepStatus(0);
|
||||
|
||||
|
||||
showUpdateStep("Adding new default-ssl-ip setting");
|
||||
Settings::AddNew('system.defaultsslip', '');
|
||||
lastStepStatus(0);
|
||||
|
||||
|
||||
showUpdateStep("Altering admin ip's field to allow multiple ip addresses");
|
||||
// get all admins for updating the new field
|
||||
$sel_stmt = Database::prepare("SELECT adminid, ip FROM `panel_admins`");
|
||||
@@ -65,20 +68,20 @@ if (isFroxlorVersion('0.9.40.1')) {
|
||||
}
|
||||
}
|
||||
lastStepStatus(0);
|
||||
|
||||
updateToVersion('0.10.0');
|
||||
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.0');
|
||||
}
|
||||
|
||||
if (isDatabaseVersion('201809280')) {
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201809280')) {
|
||||
|
||||
showUpdateStep("Adding dhparams-file setting");
|
||||
Settings::AddNew("system.dhparams_file", '');
|
||||
Settings::AddNew("system.dhparams_file", '');
|
||||
lastStepStatus(0);
|
||||
|
||||
updateToDbVersion('201811180');
|
||||
\Froxlor\Froxlor::updateToDbVersion('201811180');
|
||||
}
|
||||
|
||||
if (isDatabaseVersion('201811180')) {
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201811180')) {
|
||||
|
||||
showUpdateStep("Adding new settings for 2FA");
|
||||
Settings::AddNew('2fa.enabled', '1', true);
|
||||
@@ -94,33 +97,74 @@ if (isDatabaseVersion('201811180')) {
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `data_2fa` varchar(500) NOT NULL default '' AFTER `type_2fa`;");
|
||||
lastStepStatus(0);
|
||||
|
||||
updateToDbVersion('201811300');
|
||||
\Froxlor\Froxlor::updateToDbVersion('201811300');
|
||||
}
|
||||
|
||||
if (isDatabaseVersion('201811300')) {
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201811300')) {
|
||||
|
||||
showUpdateStep("Adding new logview-flag to customers");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `logviewenabled` tinyint(1) NOT NULL default '0';");
|
||||
lastStepStatus(0);
|
||||
|
||||
updateToDbVersion('201812010');
|
||||
\Froxlor\Froxlor::updateToDbVersion('201812010');
|
||||
}
|
||||
|
||||
if (isDatabaseVersion('201812010')) {
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201812010')) {
|
||||
|
||||
showUpdateStep("Adding new is_configured-flag");
|
||||
// updated systems are already configured (most likely :P)
|
||||
Settings::AddNew('panel.is_configured', '1', true);
|
||||
lastStepStatus(0);
|
||||
|
||||
updateToDbVersion('201812100');
|
||||
\Froxlor\Froxlor::updateToDbVersion('201812100');
|
||||
}
|
||||
|
||||
if (isDatabaseVersion('201812100')) {
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201812100')) {
|
||||
|
||||
showUpdateStep("Adding fields writeaccesslog and writeerrorlog for domains");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `writeaccesslog` tinyint(1) NOT NULL default '1';");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `writeerrorlog` tinyint(1) NOT NULL default '1';");
|
||||
lastStepStatus(0);
|
||||
|
||||
updateToDbVersion('201812180');
|
||||
\Froxlor\Froxlor::updateToDbVersion('201812180');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201812180')) {
|
||||
|
||||
showUpdateStep("Updating cronjob table");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_CRONRUNS . "` ADD `cronclass` varchar(500) NOT NULL AFTER `cronfile`");
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `cronclass` = :cc WHERE `cronfile` = :cf");
|
||||
Database::pexecute($upd_stmt, array('cc' => '\\Froxlor\\Cron\\TasksCron', 'cf' => 'tasks'));
|
||||
Database::pexecute($upd_stmt, array('cc' => '\\Froxlor\\Cron\\Traffic\\TrafficCron', 'cf' => 'traffic'));
|
||||
Database::pexecute($upd_stmt, array('cc' => '\\Froxlor\\Cron\\Traffic\\ReportsCron', 'cf' => 'usage_report'));
|
||||
Database::pexecute($upd_stmt, array('cc' => '\\Froxlor\\Cron\\System\\MailboxsizeCron', 'cf' => 'mailboxsize'));
|
||||
Database::pexecute($upd_stmt, array('cc' => '\\Froxlor\\Cron\\LetsEncrypt\\LetsEncrypt', 'cf' => 'letsencrypt'));
|
||||
Database::pexecute($upd_stmt, array('cc' => '\\Froxlor\\Cron\\System\\BackupCron', 'cf' => 'backup'));
|
||||
Database::query("DELETE FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `module` = 'froxlor/ticket'");
|
||||
lastStepStatus(0);
|
||||
|
||||
showUpdateStep("Removing ticketsystem");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `tickets`");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `tickets_used`");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `tickets_see_all`");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `tickets`");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `tickets_used`");
|
||||
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'ticket'");
|
||||
|
||||
define('TABLE_PANEL_TICKETS', 'panel_tickets');
|
||||
define('TABLE_PANEL_TICKET_CATS', 'panel_ticket_categories');
|
||||
Database::query("DROP TABLE IF EXISTS `" . TABLE_PANEL_TICKETS . "`;");
|
||||
Database::query("DROP TABLE IF EXISTS `" . TABLE_PANEL_TICKET_CATS . "`;");
|
||||
lastStepStatus(0);
|
||||
|
||||
showUpdateStep("Updating nameserver settings");
|
||||
$dns_target = 'Bind';
|
||||
if (Settings::Get('system.dns_server') != 'bind') {
|
||||
$dns_target = 'PowerDNS';
|
||||
}
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :v WHERE `settinggroup` = 'system' AND `varname` = 'dns_server'");
|
||||
Database::pexecute($upd_stmt, array('v' => $dns_target));
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('201812190');
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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 Install
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('AREA')
|
||||
|| (defined('AREA') && AREA != 'admin')
|
||||
|| !isset($userinfo['loginname'])
|
||||
|| (isset($userinfo['loginname']) && $userinfo['loginname'] == '')
|
||||
) {
|
||||
header('Location: ../../../index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$updateto = '0.9-r0';
|
||||
$frontend = 'froxlor';
|
||||
|
||||
showUpdateStep("Upgrading SysCP ".Settings::Get('panel.version')." to Froxlor ". $updateto, false);
|
||||
updateToVersion($updateto);
|
||||
|
||||
// add field frontend
|
||||
Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET
|
||||
`settinggroup` = 'panel',
|
||||
`varname` = 'frontend',
|
||||
`value` = 'froxlor'"
|
||||
);
|
||||
Settings::Set('panel.frontend', $frontend);
|
||||
@@ -31,14 +31,14 @@ function getPreConfig($current_version, $current_db_version)
|
||||
$has_preconfig = false;
|
||||
$return = '<div class="preconfig"><h3 class="red">PLEASE NOTE - Important update notifications</h3>';
|
||||
|
||||
include_once makeCorrectFile(dirname(__FILE__).'/preconfig/0.9/preconfig_0.9.inc.php');
|
||||
include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.9/preconfig_0.9.inc.php');
|
||||
parseAndOutputPreconfig($has_preconfig, $return, $current_version, $current_db_version);
|
||||
|
||||
$return .= '<br /><br />'.makecheckbox('update_changesagreed', '<strong>I have read the update notifications above and I am aware of the changes made to my system.</strong>', '1', true, '0', true);
|
||||
$return .= '<br /><br />' . makecheckbox('update_changesagreed', '<strong>I have read the update notifications above and I am aware of the changes made to my system.</strong>', '1', true, '0', true);
|
||||
$return .= '</div>';
|
||||
$return .= '<input type="hidden" name="update_preconfig" value="1" />';
|
||||
|
||||
if($has_preconfig) {
|
||||
if ($has_preconfig) {
|
||||
return $return;
|
||||
} else {
|
||||
return '';
|
||||
@@ -47,9 +47,9 @@ function getPreConfig($current_version, $current_db_version)
|
||||
|
||||
function versionInUpdate($current_version, $version_to_check)
|
||||
{
|
||||
if (!isFroxlor()) {
|
||||
if (! isFroxlor()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (version_compare2($current_version, $version_to_check) == -1 ? true : false);
|
||||
return (version_compare2($current_version, $version_to_check) == - 1 ? true : false);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
* @package Language
|
||||
*
|
||||
*/
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
use PHPMailer\PHPMailer;
|
||||
|
||||
/**
|
||||
* checks if the new-version has some updating to do
|
||||
@@ -24,7 +27,7 @@
|
||||
* pointer to output string
|
||||
* @param string $current_version
|
||||
* current froxlor version
|
||||
*
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $current_db_version)
|
||||
@@ -130,7 +133,7 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
|
||||
$description = 'Resetting the open_basedir to customer - root';
|
||||
$question = '<strong>Due to a security - issue regarding open_basedir, Froxlor will set the open_basedir for the following domains to the customers root instead of the chosen documentroot:</strong><br /> ';
|
||||
$question .= '<ul>';
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
foreach ($wrongOpenBasedirDomain as $domain) {
|
||||
$question .= '<li>' . $idna_convert->decode($domain) . '</li>';
|
||||
}
|
||||
@@ -381,7 +384,7 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
|
||||
$question .= '<select name="update_default_theme">';
|
||||
$themes = getThemes();
|
||||
foreach ($themes as $cur_theme) // $theme is already in use
|
||||
{
|
||||
{
|
||||
$question .= makeoption($cur_theme, $cur_theme, 'Froxlor');
|
||||
}
|
||||
$question .= '</select>';
|
||||
|
||||
@@ -16,55 +16,39 @@
|
||||
* @package Install
|
||||
*
|
||||
*/
|
||||
use Froxlor\FroxlorLogger;
|
||||
|
||||
if (!defined('_CRON_UPDATE')) {
|
||||
if (!defined('AREA')
|
||||
|| (defined('AREA') && AREA != 'admin')
|
||||
|| !isset($userinfo['loginname'])
|
||||
|| (isset($userinfo['loginname']) && $userinfo['loginname'] == '')
|
||||
) {
|
||||
if (! defined('_CRON_UPDATE')) {
|
||||
if (! defined('AREA') || (defined('AREA') && AREA != 'admin') || ! isset($userinfo['loginname']) || (isset($userinfo['loginname']) && $userinfo['loginname'] == '')) {
|
||||
header('Location: ../index.php');
|
||||
exit;
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$updatelog = FroxlorLogger::getInstanceOf(array('loginname' => 'updater'));
|
||||
|
||||
$updatelogfile = validateUpdateLogFile(makeCorrectFile(dirname(__FILE__).'/update.log'));
|
||||
$filelog = FileLogger::getInstanceOf(array('loginname' => 'updater'));
|
||||
$filelog->setLogFile($updatelogfile);
|
||||
$filelog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'updater'
|
||||
));
|
||||
|
||||
// if first writing does not work we'll stop, tell the user to fix it
|
||||
// and then let him try again.
|
||||
try {
|
||||
$filelog->logAction(ADM_ACTION, LOG_WARNING, '-------------- START LOG --------------');
|
||||
} catch(Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
standard_error('exception', $e->getMessage());
|
||||
}
|
||||
|
||||
/*
|
||||
* since froxlor, we have to check if there's still someone
|
||||
* out there using syscp and needs to upgrade
|
||||
*/
|
||||
if(!isFroxlor()) {
|
||||
/**
|
||||
* Upgrading SysCP to Froxlor-0.9
|
||||
*/
|
||||
include_once (makeCorrectFile(dirname(__FILE__).'/updates/froxlor/upgrade_syscp.inc.php'));
|
||||
}
|
||||
|
||||
if (isFroxlor()) {
|
||||
include_once (makeCorrectFile(dirname(__FILE__).'/updates/froxlor/0.9/update_0.9.inc.php'));
|
||||
include_once (makeCorrectFile(dirname(__FILE__).'/updates/froxlor/0.10/update_0.10.inc.php'));
|
||||
if (\Froxlor\Froxlor::isFroxlor()) {
|
||||
include_once (\Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/updates/froxlor/0.9/update_0.9.inc.php'));
|
||||
include_once (\Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/updates/froxlor/0.10/update_0.10.inc.php'));
|
||||
|
||||
// Check Froxlor - database integrity (only happens after all updates are done, so we know the db-layout is okay)
|
||||
showUpdateStep("Checking database integrity");
|
||||
|
||||
$integrity = new IntegrityCheck();
|
||||
if (!$integrity->checkAll()) {
|
||||
if (! $integrity->checkAll()) {
|
||||
lastStepStatus(1, 'Monkeys ate the integrity');
|
||||
showUpdateStep("Trying to remove monkeys, feeding bananas");
|
||||
if(!$integrity->fixAll()) {
|
||||
if (! $integrity->fixAll()) {
|
||||
lastStepStatus(2, 'Some monkeys just would not move, you should contact team@froxlor.org');
|
||||
} else {
|
||||
lastStepStatus(0, 'Integrity restored');
|
||||
|
||||
@@ -43,7 +43,7 @@ abstract class ApiCommand extends ApiParameter
|
||||
/**
|
||||
* logger interface
|
||||
*
|
||||
* @var \FroxlorLogger
|
||||
* @var \Froxlor\FroxlorLogger
|
||||
*/
|
||||
private $logger = null;
|
||||
|
||||
@@ -111,7 +111,7 @@ abstract class ApiCommand extends ApiParameter
|
||||
} else {
|
||||
throw new \Exception("Invalid user data", 500);
|
||||
}
|
||||
$this->logger = \FroxlorLogger::getInstanceOf($this->user_data);
|
||||
$this->logger = \Froxlor\FroxlorLogger::getInstanceOf($this->user_data);
|
||||
|
||||
// check whether the user is deactivated
|
||||
if ($this->getUserDetail('deactivated') == 1) {
|
||||
@@ -269,7 +269,7 @@ abstract class ApiCommand extends ApiParameter
|
||||
/**
|
||||
* return logger instance
|
||||
*
|
||||
* @return \FroxlorLogger
|
||||
* @return \Froxlor\FroxlorLogger
|
||||
*/
|
||||
protected function logger()
|
||||
{
|
||||
|
||||
@@ -141,10 +141,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, default 0
|
||||
* @param bool $ftps_ul
|
||||
* optional, default false
|
||||
* @param int $tickets
|
||||
* optional, default 0
|
||||
* @param bool $tickets_ul
|
||||
* optional, default false
|
||||
* @param int $mysqls
|
||||
* optional, default 0
|
||||
* @param bool $mysqls_ul
|
||||
@@ -153,8 +149,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, default false
|
||||
* @param bool $domains_see_all
|
||||
* optional, default false
|
||||
* @param bool $tickets_see_all
|
||||
* optional, default false
|
||||
* @param bool $caneditphpsettings
|
||||
* optional, default false
|
||||
* @param bool $change_serversettings
|
||||
@@ -191,12 +185,10 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$email_forwarders = $this->getUlParam('email_forwarders', 'email_forwarders_ul', true, 0);
|
||||
$email_quota = $this->getUlParam('email_quota', 'email_quota_ul', true, 0);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, 0);
|
||||
$tickets = $this->getUlParam('tickets', 'tickets_ul', true, 0);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, 0);
|
||||
|
||||
$customers_see_all = $this->getBoolParam('customers_see_all', true, 0);
|
||||
$domains_see_all = $this->getBoolParam('domains_see_all', true, 0);
|
||||
$tickets_see_all = $this->getBoolParam('tickets_see_all', true, 0);
|
||||
$caneditphpsettings = $this->getBoolParam('caneditphpsettings', true, 0);
|
||||
$change_serversettings = $this->getBoolParam('change_serversettings', true, 0);
|
||||
$ipaddress = $this->getParam('ipaddress', true, - 1);
|
||||
@@ -212,10 +204,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$email_quota = - 1;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.enabled') != '1') {
|
||||
$tickets = - 1;
|
||||
}
|
||||
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
// only check if not empty,
|
||||
// cause empty == generate password automatically
|
||||
@@ -271,10 +259,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$change_serversettings = '0';
|
||||
}
|
||||
|
||||
if ($tickets_see_all != '1') {
|
||||
$tickets_see_all = '0';
|
||||
}
|
||||
|
||||
if ($password == '') {
|
||||
$password = generatePassword();
|
||||
}
|
||||
@@ -301,8 +285,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
'forwarders' => $email_forwarders,
|
||||
'quota' => $email_quota,
|
||||
'ftps' => $ftps,
|
||||
'tickets' => $tickets,
|
||||
'tickets_see_all' => $tickets_see_all,
|
||||
'mysqls' => $mysqls,
|
||||
'ip' => empty($ipaddress) ? "" : (is_array($ipaddress) && $ipaddress > 0 ? json_encode($ipaddress) : - 1),
|
||||
'theme' => $_theme,
|
||||
@@ -331,8 +313,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
`email_forwarders` = :forwarders,
|
||||
`email_quota` = :quota,
|
||||
`ftps` = :ftps,
|
||||
`tickets` = :tickets,
|
||||
`tickets_see_all` = :tickets_see_all,
|
||||
`mysqls` = :mysqls,
|
||||
`ip` = :ip,
|
||||
`theme` = :theme,
|
||||
@@ -418,10 +398,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, default 0
|
||||
* @param bool $ftps_ul
|
||||
* optional, default false
|
||||
* @param int $tickets
|
||||
* optional, default 0
|
||||
* @param bool $tickets_ul
|
||||
* optional, default false
|
||||
* @param int $mysqls
|
||||
* optional, default 0
|
||||
* @param bool $mysqls_ul
|
||||
@@ -430,8 +406,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, default false
|
||||
* @param bool $domains_see_all
|
||||
* optional, default false
|
||||
* @param bool $tickets_see_all
|
||||
* optional, default false
|
||||
* @param bool $caneditphpsettings
|
||||
* optional, default false
|
||||
* @param bool $change_serversettings
|
||||
@@ -479,9 +453,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$email_forwarders = $result['email_forwarders'];
|
||||
$email_quota = $result['email_quota'];
|
||||
$ftps = $result['ftps'];
|
||||
$tickets = $result['tickets'];
|
||||
$mysqls = $result['mysqls'];
|
||||
$tickets_see_all = $result['tickets_see_all'];
|
||||
$customers_see_all = $result['customers_see_all'];
|
||||
$domains_see_all = $result['domains_see_all'];
|
||||
$caneditphpsettings = $result['caneditphpsettings'];
|
||||
@@ -503,12 +475,10 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$email_forwarders = $this->getUlParam('email_forwarders', 'email_forwarders_ul', true, $result['email_forwarders']);
|
||||
$email_quota = $this->getUlParam('email_quota', 'email_quota_ul', true, $result['email_quota']);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
|
||||
$tickets = $this->getUlParam('tickets', 'tickets_ul', true, $result['tickets']);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']);
|
||||
|
||||
$customers_see_all = $this->getBoolParam('customers_see_all', true, $result['customers_see_all']);
|
||||
$domains_see_all = $this->getBoolParam('domains_see_all', true, $result['domains_see_all']);
|
||||
$tickets_see_all = $this->getBoolParam('tickets_see_all', true, $result['tickets_see_all']);
|
||||
$caneditphpsettings = $this->getBoolParam('caneditphpsettings', true, $result['caneditphpsettings']);
|
||||
$change_serversettings = $this->getBoolParam('change_serversettings', true, $result['change_serversettings']);
|
||||
$ipaddress = $this->getParam('ipaddress', true, ($result['ip'] != - 1 ? json_decode($result['ip'], true) : - 1));
|
||||
@@ -530,10 +500,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$email_quota = - 1;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.enabled') != '1') {
|
||||
$tickets = - 1;
|
||||
}
|
||||
|
||||
if (empty($theme)) {
|
||||
$theme = Settings::Get('panel.default_theme');
|
||||
}
|
||||
@@ -562,10 +528,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$change_serversettings = '0';
|
||||
}
|
||||
|
||||
if ($tickets_see_all != '1') {
|
||||
$tickets_see_all = '0';
|
||||
}
|
||||
|
||||
if ($password != '') {
|
||||
$password = validatePassword($password, true);
|
||||
$password = makeCryptPassword($password);
|
||||
@@ -603,9 +565,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
if ($ftps != $result['ftps'] && $ftps != - 1 && $ftps < $result['ftps_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'ftps');
|
||||
}
|
||||
if ($tickets != $result['tickets'] && $tickets != - 1 && $tickets < $result['tickets_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'tickets');
|
||||
}
|
||||
if ($mysqls != $result['mysqls'] && $mysqls != - 1 && $mysqls < $result['mysqls_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'mysqls');
|
||||
}
|
||||
@@ -633,8 +592,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
'forwarders' => $email_forwarders,
|
||||
'quota' => $email_quota,
|
||||
'ftps' => $ftps,
|
||||
'tickets' => $tickets,
|
||||
'tickets_see_all' => $tickets_see_all,
|
||||
'mysqls' => $mysqls,
|
||||
'ip' => empty($ipaddress) ? "" : (is_array($ipaddress) && $ipaddress > 0 ? json_encode($ipaddress) : - 1),
|
||||
'deactivated' => $deactivated,
|
||||
@@ -664,8 +621,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
`email_forwarders` = :forwarders,
|
||||
`email_quota` = :quota,
|
||||
`ftps` = :ftps,
|
||||
`tickets` = :tickets,
|
||||
`tickets_see_all` = :tickets_see_all,
|
||||
`mysqls` = :mysqls,
|
||||
`ip` = :ip,
|
||||
`deactivated` = :deactivated,
|
||||
|
||||
@@ -184,10 +184,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* optional amount of ftp-accounts available for customer, default 0
|
||||
* @param bool $ftps_ul
|
||||
* optional, whether customer should have unlimited ftp-accounts, default 0 (false)
|
||||
* @param int $tickets
|
||||
* optional amount of tickets available for customer if enabled, default 0
|
||||
* @param bool $tickets_ul
|
||||
* optional, whether customer should have unlimited tickets if enabled, default 0 (false)
|
||||
* @param int $mysqls
|
||||
* optional amount of mysql-databases available for customer, default 0
|
||||
* @param bool $mysqls_ul
|
||||
@@ -245,7 +241,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$email_imap = $this->getBoolParam('email_imap', true, 0);
|
||||
$email_pop3 = $this->getBoolParam('email_pop3', true, 0);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, 0);
|
||||
$tickets = $this->getUlParam('tickets', 'tickets_ul', true, 0);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
|
||||
$password = $this->getParam('new_customer_password', true, '');
|
||||
@@ -277,10 +272,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$email_quota = - 1;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.enabled') != '1') {
|
||||
$tickets = - 1;
|
||||
}
|
||||
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
// only check if not empty,
|
||||
// cause empty == generate password automatically
|
||||
@@ -305,7 +296,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$diskspace = $diskspace * 1024;
|
||||
$traffic = $traffic * 1024 * 1024;
|
||||
|
||||
if (((($this->getUserDetail('diskspace_used') + $diskspace) > $this->getUserDetail('diskspace')) && ($this->getUserDetail('diskspace') / 1024) != '-1') || ((($this->getUserDetail('mysqls_used') + $mysqls) > $this->getUserDetail('mysqls')) && $this->getUserDetail('mysqls') != '-1') || ((($this->getUserDetail('emails_used') + $emails) > $this->getUserDetail('emails')) && $this->getUserDetail('emails') != '-1') || ((($this->getUserDetail('email_accounts_used') + $email_accounts) > $this->getUserDetail('email_accounts')) && $this->getUserDetail('email_accounts') != '-1') || ((($this->getUserDetail('email_forwarders_used') + $email_forwarders) > $this->getUserDetail('email_forwarders')) && $this->getUserDetail('email_forwarders') != '-1') || ((($this->getUserDetail('email_quota_used') + $email_quota) > $this->getUserDetail('email_quota')) && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ((($this->getUserDetail('ftps_used') + $ftps) > $this->getUserDetail('ftps')) && $this->getUserDetail('ftps') != '-1') || ((($this->getUserDetail('tickets_used') + $tickets) > $this->getUserDetail('tickets')) && $this->getUserDetail('tickets') != '-1') || ((($this->getUserDetail('subdomains_used') + $subdomains) > $this->getUserDetail('subdomains')) && $this->getUserDetail('subdomains') != '-1') || (($diskspace / 1024) == '-1' && ($this->getUserDetail('diskspace') / 1024) != '-1') || ($mysqls == '-1' && $this->getUserDetail('mysqls') != '-1') || ($emails == '-1' && $this->getUserDetail('emails') != '-1') || ($email_accounts == '-1' && $this->getUserDetail('email_accounts') != '-1') || ($email_forwarders == '-1' && $this->getUserDetail('email_forwarders') != '-1') || ($email_quota == '-1' && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ($ftps == '-1' && $this->getUserDetail('ftps') != '-1') || ($tickets == '-1' && $this->getUserDetail('tickets') != '-1') || ($subdomains == '-1' && $this->getUserDetail('subdomains') != '-1')) {
|
||||
if (((($this->getUserDetail('diskspace_used') + $diskspace) > $this->getUserDetail('diskspace')) && ($this->getUserDetail('diskspace') / 1024) != '-1') || ((($this->getUserDetail('mysqls_used') + $mysqls) > $this->getUserDetail('mysqls')) && $this->getUserDetail('mysqls') != '-1') || ((($this->getUserDetail('emails_used') + $emails) > $this->getUserDetail('emails')) && $this->getUserDetail('emails') != '-1') || ((($this->getUserDetail('email_accounts_used') + $email_accounts) > $this->getUserDetail('email_accounts')) && $this->getUserDetail('email_accounts') != '-1') || ((($this->getUserDetail('email_forwarders_used') + $email_forwarders) > $this->getUserDetail('email_forwarders')) && $this->getUserDetail('email_forwarders') != '-1') || ((($this->getUserDetail('email_quota_used') + $email_quota) > $this->getUserDetail('email_quota')) && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ((($this->getUserDetail('ftps_used') + $ftps) > $this->getUserDetail('ftps')) && $this->getUserDetail('ftps') != '-1') || ((($this->getUserDetail('subdomains_used') + $subdomains) > $this->getUserDetail('subdomains')) && $this->getUserDetail('subdomains') != '-1') || (($diskspace / 1024) == '-1' && ($this->getUserDetail('diskspace') / 1024) != '-1') || ($mysqls == '-1' && $this->getUserDetail('mysqls') != '-1') || ($emails == '-1' && $this->getUserDetail('emails') != '-1') || ($email_accounts == '-1' && $this->getUserDetail('email_accounts') != '-1') || ($email_forwarders == '-1' && $this->getUserDetail('email_forwarders') != '-1') || ($email_quota == '-1' && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ($ftps == '-1' && $this->getUserDetail('ftps') != '-1') || ($subdomains == '-1' && $this->getUserDetail('subdomains') != '-1')) {
|
||||
standard_error('youcantallocatemorethanyouhave', '', true);
|
||||
}
|
||||
|
||||
@@ -418,7 +409,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'email_forwarders' => $email_forwarders,
|
||||
'email_quota' => $email_quota,
|
||||
'ftps' => $ftps,
|
||||
'tickets' => $tickets,
|
||||
'mysqls' => $mysqls,
|
||||
'phpenabled' => $phpenabled,
|
||||
'allowed_phpconfigs' => empty($allowed_phpconfigs) ? "" : json_encode($allowed_phpconfigs),
|
||||
@@ -459,7 +449,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
`email_forwarders` = :email_forwarders,
|
||||
`email_quota` = :email_quota,
|
||||
`ftps` = :ftps,
|
||||
`tickets` = :tickets,
|
||||
`mysqls` = :mysqls,
|
||||
`standardsubdomain` = '0',
|
||||
`phpenabled` = :phpenabled,
|
||||
@@ -509,10 +498,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$admin_update_query .= ", `ftps_used` = `ftps_used` + 0" . (int) $ftps;
|
||||
}
|
||||
|
||||
if ($tickets != '-1' && Settings::Get('ticket.enabled') == 1) {
|
||||
$admin_update_query .= ", `tickets_used` = `tickets_used` + 0" . (int) $tickets;
|
||||
}
|
||||
|
||||
if (($diskspace / 1024) != '-1') {
|
||||
$admin_update_query .= ", `diskspace_used` = `diskspace_used` + 0" . (int) $diskspace;
|
||||
}
|
||||
@@ -824,10 +809,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* optional amount of ftp-accounts available for customer, default 0
|
||||
* @param bool $ftps_ul
|
||||
* optional, whether customer should have unlimited ftp-accounts, default 0 (false)
|
||||
* @param int $tickets
|
||||
* optional amount of tickets available for customer if enabled, default 0
|
||||
* @param bool $tickets_ul
|
||||
* optional, whether customer should have unlimited tickets if enabled, default 0 (false)
|
||||
* @param int $mysqls
|
||||
* optional amount of mysql-databases available for customer, default 0
|
||||
* @param bool $mysqls_ul
|
||||
@@ -895,7 +876,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$email_imap = $this->getParam('email_imap', true, $result['imap']);
|
||||
$email_pop3 = $this->getParam('email_pop3', true, $result['pop3']);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
|
||||
$tickets = $this->getUlParam('tickets', 'tickets_ul', true, $result['tickets']);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
|
||||
$password = $this->getParam('new_customer_password', true, '');
|
||||
@@ -936,10 +916,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$email_quota = - 1;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.enabled') != '1') {
|
||||
$tickets = - 1;
|
||||
}
|
||||
|
||||
if (empty($theme)) {
|
||||
$theme = Settings::Get('panel.default_theme');
|
||||
}
|
||||
@@ -949,7 +925,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$diskspace = $diskspace * 1024;
|
||||
$traffic = $traffic * 1024 * 1024;
|
||||
|
||||
if (((($this->getUserDetail('diskspace_used') + $diskspace - $result['diskspace']) > $this->getUserDetail('diskspace')) && ($this->getUserDetail('diskspace') / 1024) != '-1') || ((($this->getUserDetail('mysqls_used') + $mysqls - $result['mysqls']) > $this->getUserDetail('mysqls')) && $this->getUserDetail('mysqls') != '-1') || ((($this->getUserDetail('emails_used') + $emails - $result['emails']) > $this->getUserDetail('emails')) && $this->getUserDetail('emails') != '-1') || ((($this->getUserDetail('email_accounts_used') + $email_accounts - $result['email_accounts']) > $this->getUserDetail('email_accounts')) && $this->getUserDetail('email_accounts') != '-1') || ((($this->getUserDetail('email_forwarders_used') + $email_forwarders - $result['email_forwarders']) > $this->getUserDetail('email_forwarders')) && $this->getUserDetail('email_forwarders') != '-1') || ((($this->getUserDetail('email_quota_used') + $email_quota - $result['email_quota']) > $this->getUserDetail('email_quota')) && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ((($this->getUserDetail('ftps_used') + $ftps - $result['ftps']) > $this->getUserDetail('ftps')) && $this->getUserDetail('ftps') != '-1') || ((($this->getUserDetail('tickets_used') + $tickets - $result['tickets']) > $this->getUserDetail('tickets')) && $this->getUserDetail('tickets') != '-1') || ((($this->getUserDetail('subdomains_used') + $subdomains - $result['subdomains']) > $this->getUserDetail('subdomains')) && $this->getUserDetail('subdomains') != '-1') || (($diskspace / 1024) == '-1' && ($this->getUserDetail('diskspace') / 1024) != '-1') || ($mysqls == '-1' && $this->getUserDetail('mysqls') != '-1') || ($emails == '-1' && $this->getUserDetail('emails') != '-1') || ($email_accounts == '-1' && $this->getUserDetail('email_accounts') != '-1') || ($email_forwarders == '-1' && $this->getUserDetail('email_forwarders') != '-1') || ($email_quota == '-1' && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ($ftps == '-1' && $this->getUserDetail('ftps') != '-1') || ($tickets == '-1' && $this->getUserDetail('tickets') != '-1') || ($subdomains == '-1' && $this->getUserDetail('subdomains') != '-1')) {
|
||||
if (((($this->getUserDetail('diskspace_used') + $diskspace - $result['diskspace']) > $this->getUserDetail('diskspace')) && ($this->getUserDetail('diskspace') / 1024) != '-1') || ((($this->getUserDetail('mysqls_used') + $mysqls - $result['mysqls']) > $this->getUserDetail('mysqls')) && $this->getUserDetail('mysqls') != '-1') || ((($this->getUserDetail('emails_used') + $emails - $result['emails']) > $this->getUserDetail('emails')) && $this->getUserDetail('emails') != '-1') || ((($this->getUserDetail('email_accounts_used') + $email_accounts - $result['email_accounts']) > $this->getUserDetail('email_accounts')) && $this->getUserDetail('email_accounts') != '-1') || ((($this->getUserDetail('email_forwarders_used') + $email_forwarders - $result['email_forwarders']) > $this->getUserDetail('email_forwarders')) && $this->getUserDetail('email_forwarders') != '-1') || ((($this->getUserDetail('email_quota_used') + $email_quota - $result['email_quota']) > $this->getUserDetail('email_quota')) && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ((($this->getUserDetail('ftps_used') + $ftps - $result['ftps']) > $this->getUserDetail('ftps')) && $this->getUserDetail('ftps') != '-1') || ((($this->getUserDetail('subdomains_used') + $subdomains - $result['subdomains']) > $this->getUserDetail('subdomains')) && $this->getUserDetail('subdomains') != '-1') || (($diskspace / 1024) == '-1' && ($this->getUserDetail('diskspace') / 1024) != '-1') || ($mysqls == '-1' && $this->getUserDetail('mysqls') != '-1') || ($emails == '-1' && $this->getUserDetail('emails') != '-1') || ($email_accounts == '-1' && $this->getUserDetail('email_accounts') != '-1') || ($email_forwarders == '-1' && $this->getUserDetail('email_forwarders') != '-1') || ($email_quota == '-1' && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ($ftps == '-1' && $this->getUserDetail('ftps') != '-1') || ($subdomains == '-1' && $this->getUserDetail('subdomains') != '-1')) {
|
||||
standard_error('youcantallocatemorethanyouhave', '', true);
|
||||
}
|
||||
|
||||
@@ -1178,7 +1154,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'email_forwarders' => $email_forwarders,
|
||||
'email_quota' => $email_quota,
|
||||
'ftps' => $ftps,
|
||||
'tickets' => $tickets,
|
||||
'mysqls' => $mysqls,
|
||||
'deactivated' => $deactivated,
|
||||
'phpenabled' => $phpenabled,
|
||||
@@ -1219,7 +1194,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
`email_accounts` = :email_accounts,
|
||||
`email_forwarders` = :email_forwarders,
|
||||
`ftps` = :ftps,
|
||||
`tickets` = :tickets,
|
||||
`mysqls` = :mysqls,
|
||||
`deactivated` = :deactivated,
|
||||
`phpenabled` = :phpenabled,
|
||||
@@ -1321,17 +1295,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
}
|
||||
}
|
||||
|
||||
if ($tickets != '-1' || $result['tickets'] != '-1') {
|
||||
$admin_update_query .= ", `tickets_used` = `tickets_used` ";
|
||||
|
||||
if ($tickets != '-1') {
|
||||
$admin_update_query .= " + 0" . (int) $tickets . " ";
|
||||
}
|
||||
if ($result['tickets'] != '-1') {
|
||||
$admin_update_query .= " - 0" . (int) $result['tickets'] . " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (($diskspace / 1024) != '-1' || ($result['diskspace'] / 1024) != '-1') {
|
||||
$admin_update_query .= ", `diskspace_used` = `diskspace_used` ";
|
||||
|
||||
@@ -1572,10 +1535,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$admin_update_query .= ", `ftps_used` = `ftps_used` - 0" . (int) $result['ftps'];
|
||||
}
|
||||
|
||||
if ($result['tickets'] != '-1') {
|
||||
$admin_update_query .= ", `tickets_used` = `tickets_used` - 0" . (int) $result['tickets'];
|
||||
}
|
||||
|
||||
if (($result['diskspace'] / 1024) != '-1') {
|
||||
$admin_update_query .= ", `diskspace_used` = `diskspace_used` - 0" . (int) $result['diskspace'];
|
||||
}
|
||||
@@ -1597,22 +1556,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
// Using filesystem - quota, insert a task which cleans the filesystem - quota
|
||||
inserttask('10');
|
||||
|
||||
// move old tickets to archive
|
||||
// @fixme ticket
|
||||
$tickets = \ticket::customerHasTickets($id);
|
||||
if ($tickets !== false && isset($tickets[0])) {
|
||||
foreach ($tickets as $ticket) {
|
||||
$now = time();
|
||||
$mainticket = \ticket::getInstanceOf($result, (int) $ticket);
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '1', true, true);
|
||||
$mainticket->Set('status', '3', true, true);
|
||||
$mainticket->Update();
|
||||
$mainticket->Archive();
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] archived ticket '" . $mainticket->Get('subject') . "'");
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] deleted customer '" . $result['loginname'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
@@ -1718,15 +1661,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'cid' => $id
|
||||
), true, true);
|
||||
|
||||
// Update customer-tickets
|
||||
$updTickets_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_TICKETS . "` SET `adminid` = :adminid WHERE `customerid` = :cid
|
||||
");
|
||||
Database::pexecute($updTickets_stmt, array(
|
||||
'adminid' => $adminid,
|
||||
'cid' => $id
|
||||
), true, true);
|
||||
|
||||
// now, recalculate the resource-usage for the old and the new admin
|
||||
updateCounters(false);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -14,9 +15,9 @@ if (! defined('MASTER_CRONJOB'))
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*
|
||||
*/
|
||||
class bind extends DnsBase
|
||||
class Bind extends DnsBase
|
||||
{
|
||||
|
||||
private $_bindconf_file = "";
|
||||
@@ -30,9 +31,9 @@ class bind extends DnsBase
|
||||
$this->_cleanZonefiles();
|
||||
|
||||
// check for subfolder in bind-config-directory
|
||||
if (! file_exists(makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/'))) {
|
||||
if (! file_exists(\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/'))) {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_NOTICE, 'mkdir ' . escapeshellarg(makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/')));
|
||||
}
|
||||
|
||||
$domains = $this->getDomainList();
|
||||
@@ -42,7 +43,7 @@ class bind extends DnsBase
|
||||
return;
|
||||
}
|
||||
|
||||
$bindconf_file = '# ' . Settings::Get('system.bindconf_directory') . 'froxlor_bind.conf' . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n";
|
||||
$this->_bindconf_file = '# ' . Settings::Get('system.bindconf_directory') . 'froxlor_bind.conf' . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n";
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
if ($domain['ismainbutsubto'] > 0) {
|
||||
@@ -52,7 +53,7 @@ class bind extends DnsBase
|
||||
$this->walkDomainList($domain, $domains);
|
||||
}
|
||||
|
||||
$bindconf_file_handler = fopen(makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
|
||||
$bindconf_file_handler = fopen(\Froxlor\FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
|
||||
fwrite($bindconf_file_handler, $this->_bindconf_file);
|
||||
fclose($bindconf_file_handler);
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'froxlor_bind.conf written');
|
||||
@@ -60,7 +61,6 @@ class bind extends DnsBase
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
}
|
||||
|
||||
|
||||
private function walkDomainList($domain, $domains)
|
||||
{
|
||||
$zoneContent = '';
|
||||
@@ -78,29 +78,19 @@ class bind extends DnsBase
|
||||
}
|
||||
|
||||
if ($domain['ismainbutsubto'] == 0) {
|
||||
$zoneContent = (string) createDomainZone(($domain['id'] == 'none') ?
|
||||
$domain :
|
||||
$domain['id'],
|
||||
$isFroxlorHostname);
|
||||
$zoneContent = (string) createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
|
||||
$domain['zonefile'] = 'domains/' . $domain['domain'] . '.zone';
|
||||
$zonefile_name = makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' .
|
||||
$domain['zonefile']);
|
||||
$zonefile_name = makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']);
|
||||
$zonefile_handler = fopen($zonefile_name, 'w');
|
||||
fwrite($zonefile_handler, $zoneContent . $subzones);
|
||||
fclose($zonefile_handler);
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, '`' . $zonefile_name . '` written');
|
||||
$this->_bindconf_file .= $this->_generateDomainConfig($domain);
|
||||
} else {
|
||||
return (string) createDomainZone(($domain['id'] == 'none') ?
|
||||
$domain :
|
||||
$domain['id'],
|
||||
$isFroxlorHostname,
|
||||
true);
|
||||
return (string) createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname, true);
|
||||
}
|
||||
} else {
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO,
|
||||
'Added zonefile ' . $domain['zonefile'] . ' for domain ' . $domain['domain'] .
|
||||
' - Note that you will also have to handle ALL records for ALL subdomains.');
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Added zonefile ' . $domain['zonefile'] . ' for domain ' . $domain['domain'] . ' - Note that you will also have to handle ALL records for ALL subdomains.');
|
||||
$this->_bindconf_file .= $this->_generateDomainConfig($domain);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +102,7 @@ class bind extends DnsBase
|
||||
$bindconf_file = '# Domain ID: ' . $domain['id'] . ' - CustomerID: ' . $domain['customerid'] . ' - CustomerLogin: ' . $domain['loginname'] . "\n";
|
||||
$bindconf_file .= 'zone "' . $domain['domain'] . '" in {' . "\n";
|
||||
$bindconf_file .= ' type master;' . "\n";
|
||||
$bindconf_file .= ' file "' . makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']) . '";' . "\n";
|
||||
$bindconf_file .= ' file "' . \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']) . '";' . "\n";
|
||||
$bindconf_file .= ' allow-query { any; };' . "\n";
|
||||
|
||||
if (count($this->_ns) > 0 || count($this->_axfr) > 0) {
|
||||
@@ -144,7 +134,7 @@ class bind extends DnsBase
|
||||
|
||||
private function _cleanZonefiles()
|
||||
{
|
||||
$config_dir = makeCorrectFile(Settings::Get('system.bindconf_directory') . '/domains/');
|
||||
$config_dir = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/domains/');
|
||||
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Cleaning dns zone files from ' . $config_dir);
|
||||
|
||||
@@ -152,13 +142,13 @@ class bind extends DnsBase
|
||||
if (@is_dir($config_dir)) {
|
||||
|
||||
// create directory iterator
|
||||
$its = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($config_dir));
|
||||
$its = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($config_dir));
|
||||
|
||||
// iterate through all subdirs, look for zone files and delete them
|
||||
foreach ($its as $it) {
|
||||
if ($it->isFile()) {
|
||||
// remove file
|
||||
safe_exec('rm -f ' . escapeshellarg(makeCorrectFile($its->getPathname())));
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg(makeCorrectFile($its->getPathname())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,11 +12,11 @@
|
||||
* 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> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -111,7 +115,7 @@ abstract class DnsBase
|
||||
$domains = array();
|
||||
// don't use fetchall() to be able to set the first column to the domain id and use it later on to set the rows'
|
||||
// array of direct children without having to search the outer array
|
||||
while ($domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$domains[$domain["id"]] = $domain;
|
||||
}
|
||||
|
||||
@@ -189,14 +193,14 @@ abstract class DnsBase
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `dkim` = '1' ORDER BY `id` ASC
|
||||
");
|
||||
|
||||
while ($domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
$privkey_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']);
|
||||
$pubkey_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id'] . '.public');
|
||||
|
||||
if ($domain['dkim_privkey'] == '' || $domain['dkim_pubkey'] == '') {
|
||||
$max_dkim_id_stmt = Database::query("SELECT MAX(`dkim_id`) as `max_dkim_id` FROM `" . TABLE_PANEL_DOMAINS . "`");
|
||||
$max_dkim_id = $max_dkim_id_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$max_dkim_id = $max_dkim_id_stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$domain['dkim_id'] = (int) $max_dkim_id['max_dkim_id'] + 1;
|
||||
$privkey_filename = makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']);
|
||||
safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength'));
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -16,7 +15,7 @@ if (! defined('MASTER_CRONJOB'))
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class pdns extends DnsBase
|
||||
class PowerDNS extends DnsBase
|
||||
{
|
||||
|
||||
public function writeConfigs()
|
||||
@@ -86,11 +85,11 @@ class pdns extends DnsBase
|
||||
{
|
||||
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Cleaning dns zone entries from database');
|
||||
|
||||
$pdns_domains_stmt = PowerDNS::getDB()->prepare("SELECT `id`, `name` FROM `domains` WHERE `name` = :domain");
|
||||
$pdns_domains_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("SELECT `id`, `name` FROM `domains` WHERE `name` = :domain");
|
||||
|
||||
$del_rec_stmt = PowerDNS::getDB()->prepare("DELETE FROM `records` WHERE `domain_id` = :did");
|
||||
$del_meta_stmt = PowerDNS::getDB()->prepare("DELETE FROM `domainmetadata` WHERE `domain_id` = :did");
|
||||
$del_dom_stmt = PowerDNS::getDB()->prepare("DELETE FROM `domains` WHERE `id` = :did");
|
||||
$del_rec_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `records` WHERE `domain_id` = :did");
|
||||
$del_meta_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `domainmetadata` WHERE `domain_id` = :did");
|
||||
$del_dom_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("DELETE FROM `domains` WHERE `id` = :did");
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$pdns_domains_stmt->execute(array(
|
||||
@@ -119,7 +118,7 @@ class pdns extends DnsBase
|
||||
'domainname' => $domainname,
|
||||
'serial' => $serial
|
||||
));
|
||||
$lastid = PowerDNS::getDB()->lastInsertId();
|
||||
$lastid = \Froxlor\Dns\PowerDNS::getDB()->lastInsertId();
|
||||
return $lastid;
|
||||
}
|
||||
|
||||
@@ -140,7 +139,7 @@ class pdns extends DnsBase
|
||||
");
|
||||
|
||||
foreach ($records as $record) {
|
||||
if ($record instanceof DnsZone) {
|
||||
if ($record instanceof \Froxlor\Dns\DnsZone) {
|
||||
$this->_insertRecords($domainid, $record->records, $record->origin);
|
||||
continue;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,9 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -17,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class apache_fcgid extends apache
|
||||
class ApacheFcgi extends Apache
|
||||
{
|
||||
protected function composePhpOptions($domain, $ssl_vhost = false)
|
||||
{
|
||||
@@ -25,7 +30,7 @@ class apache_fcgid extends apache
|
||||
|
||||
if($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1')
|
||||
{
|
||||
$php = new phpinterface($domain);
|
||||
$php = new PhpInterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
if((int)Settings::Get('phpfpm.enabled') == 1)
|
||||
@@ -56,12 +61,12 @@ class apache_fcgid extends apache
|
||||
$php_options_text.= ' SetHandler proxy:unix:' . $php->getInterface()->getSocketFile() . '|fcgi://localhost'. "\n";
|
||||
$php_options_text.= ' </FilesMatch>' . "\n";
|
||||
|
||||
$mypath_dir = new frxDirectory($domain['documentroot']);
|
||||
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
|
||||
|
||||
// only create the require all granted if there is not active directory-protection
|
||||
// for this path, as this would be the first require and therefore grant all access
|
||||
if ($mypath_dir->isUserProtected() == false) {
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text.= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
if ($phpconfig['pass_authorizationheader'] == '1') {
|
||||
$php_options_text.= ' CGIPassAuth On' . "\n";
|
||||
}
|
||||
@@ -70,7 +75,7 @@ class apache_fcgid extends apache
|
||||
$php_options_text.= ' </Directory>' . "\n";
|
||||
} elseif ($phpconfig['pass_authorizationheader'] == '1') {
|
||||
// allow Pass of Authorization header
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text.= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text.= ' CGIPassAuth On' . "\n";
|
||||
$php_options_text.= ' </Directory>' . "\n";
|
||||
}
|
||||
@@ -81,7 +86,7 @@ class apache_fcgid extends apache
|
||||
$addheader = " -pass-header Authorization";
|
||||
}
|
||||
$php_options_text.= ' FastCgiExternalServer ' . $php->getInterface()->getAliasConfigDir() . $srvName . ' -socket ' . $php->getInterface()->getSocketFile() . ' -idle-timeout ' . $phpconfig['fpm_settings']['idle_timeout'] . $addheader . "\n";
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text.= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
|
||||
$extensions = explode(" ", $filesmatch);
|
||||
$filesmatch = "";
|
||||
@@ -97,7 +102,7 @@ class apache_fcgid extends apache
|
||||
$php_options_text.= ' </FilesMatch>' . "\n";
|
||||
// >=apache-2.4 enabled?
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$mypath_dir = new frxDirectory($domain['documentroot']);
|
||||
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
|
||||
// only create the require all granted if there is not active directory-protection
|
||||
// for this path, as this would be the first require and therefore grant all access
|
||||
if ($mypath_dir->isUserProtected() == false) {
|
||||
@@ -123,7 +128,7 @@ class apache_fcgid extends apache
|
||||
else
|
||||
{
|
||||
$php_options_text.= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n";
|
||||
$php_options_text.= ' <Directory "' . makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$php_options_text.= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
|
||||
$file_extensions = explode(' ', $phpconfig['file_extensions']);
|
||||
$php_options_text.= ' <FilesMatch "\.(' . implode('|', $file_extensions) . ')$">' . "\n";
|
||||
$php_options_text.= ' SetHandler fcgid-script' . "\n";
|
||||
@@ -135,7 +140,7 @@ class apache_fcgid extends apache
|
||||
$php_options_text.= ' </FilesMatch>' . "\n";
|
||||
// >=apache-2.4 enabled?
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$mypath_dir = new frxDirectory($domain['documentroot']);
|
||||
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
|
||||
// only create the require all granted if there is not active directory-protection
|
||||
// for this path, as this would be the first require and therefore grant all access
|
||||
if ($mypath_dir->isUserProtected() == false) {
|
||||
@@ -171,7 +176,7 @@ class apache_fcgid extends apache
|
||||
|| (Settings::Get('phpfpm.enabled') == '1'
|
||||
&& Settings::Get('phpfpm.enabled_ownvhost') == '1')
|
||||
) {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__)))); // /var/www/froxlor, needed for chown
|
||||
$mypath = \Froxlor\Froxlor::getInstallDir();
|
||||
|
||||
if (Settings::Get('system.mod_fcgid_ownvhost') == '1')
|
||||
{
|
||||
@@ -212,10 +217,10 @@ class apache_fcgid extends apache
|
||||
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
|
||||
// get php.ini for our own vhost
|
||||
$php = new phpinterface($domain);
|
||||
$php = new PhpInterface($domain);
|
||||
|
||||
// get php-config
|
||||
if (Settings::Get('phpfpm.enabled') == '1') {
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,14 +11,14 @@
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.29
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.29
|
||||
*
|
||||
*/
|
||||
class ConfigIO
|
||||
{
|
||||
@@ -35,37 +38,37 @@ class ConfigIO
|
||||
*/
|
||||
public function cleanUp()
|
||||
{
|
||||
|
||||
|
||||
// old error logs
|
||||
$this->_cleanErrLogs();
|
||||
|
||||
|
||||
// awstats files
|
||||
$this->_cleanAwstatsFiles();
|
||||
|
||||
|
||||
// fcgid files
|
||||
$this->_cleanFcgidFiles();
|
||||
|
||||
|
||||
// php-fpm files
|
||||
$this->_cleanFpmFiles();
|
||||
|
||||
|
||||
// clean webserver-configs
|
||||
$this->_cleanWebserverConfigs();
|
||||
|
||||
|
||||
// old htpasswd files
|
||||
$this->_cleanHtpasswdFiles();
|
||||
|
||||
|
||||
// customer-specified ssl-certificates
|
||||
$this->_cleanCustomerSslCerts();
|
||||
}
|
||||
|
||||
private function _cleanErrLogs()
|
||||
{
|
||||
$err_dir = makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . "/logs/");
|
||||
$err_dir = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . "/logs/");
|
||||
if (@is_dir($err_dir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /*.log so we don't delete the directory)
|
||||
$err_dir .= '/*.log';
|
||||
safe_exec('rm -f ' . makeCorrectFile($err_dir));
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . \Froxlor\FileDir::makeCorrectFile($err_dir));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +80,7 @@ class ConfigIO
|
||||
*/
|
||||
private function _cleanCustomerSslCerts()
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
* only clean up if we're actually using SSL
|
||||
*/
|
||||
@@ -85,14 +88,14 @@ class ConfigIO
|
||||
// get correct directory
|
||||
$configdir = $this->_getFile('system', 'customer_ssl_path');
|
||||
if ($configdir !== false) {
|
||||
|
||||
$configdir = makeCorrectDir($configdir);
|
||||
|
||||
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
safe_exec('rm -f ' . makeCorrectFile($configdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . \Froxlor\FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,36 +108,36 @@ class ConfigIO
|
||||
*/
|
||||
private function _cleanWebserverConfigs()
|
||||
{
|
||||
|
||||
|
||||
// get directories
|
||||
$configdirs = array();
|
||||
$dir = $this->_getFile('system', 'apacheconf_vhost');
|
||||
if ($dir !== false)
|
||||
$configdirs[] = makeCorrectDir($dir);
|
||||
|
||||
$configdirs[] = \Froxlor\FileDir::makeCorrectDir($dir);
|
||||
|
||||
$dir = $this->_getFile('system', 'apacheconf_diroptions');
|
||||
if ($dir !== false)
|
||||
$configdirs[] = makeCorrectDir($dir);
|
||||
|
||||
$configdirs[] = \Froxlor\FileDir::makeCorrectDir($dir);
|
||||
|
||||
// file pattern
|
||||
$pattern = "/^([0-9]){2}_(froxlor|syscp)_(.+)\.conf$/";
|
||||
|
||||
|
||||
// check ALL the folders
|
||||
foreach ($configdirs as $config_dir) {
|
||||
|
||||
|
||||
// check directory
|
||||
if (@is_dir($config_dir)) {
|
||||
|
||||
|
||||
// create directory iterator
|
||||
$its = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($config_dir));
|
||||
|
||||
$its = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($config_dir));
|
||||
|
||||
// iterate through all subdirs,
|
||||
// look for vhost/diroption files
|
||||
// and delete them
|
||||
foreach ($its as $fullFileName => $it) {
|
||||
if ($it->isFile() && preg_match($pattern, $it->getFilename())) {
|
||||
// remove file
|
||||
safe_exec('rm -f ' . escapeshellarg(makeCorrectFile($its->getPathname())));
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($its->getPathname())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,18 +151,18 @@ class ConfigIO
|
||||
*/
|
||||
private function _cleanHtpasswdFiles()
|
||||
{
|
||||
|
||||
|
||||
// get correct directory
|
||||
$configdir = $this->_getFile('system', 'apacheconf_htpasswddir');
|
||||
|
||||
|
||||
if ($configdir !== false) {
|
||||
$configdir = makeCorrectDir($configdir);
|
||||
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
safe_exec('rm -f ' . makeCorrectFile($configdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . \Froxlor\FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,12 +177,13 @@ class ConfigIO
|
||||
if (Settings::Get('system.awstats_enabled') == '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// dhr: cleanout froxlor-generated awstats configs prior to re-creation
|
||||
$awstatsclean = array();
|
||||
$awstatsclean['header'] = "## GENERATED BY FROXLOR\n";
|
||||
$awstatsclean['headerold'] = "## GENERATED BY SYSCP\n";
|
||||
$awstatsclean['path'] = $this->_getFile('system', 'awstats_conf');
|
||||
|
||||
|
||||
/**
|
||||
* don't do anything if the directory does not exist
|
||||
* (e.g.
|
||||
@@ -189,7 +193,7 @@ class ConfigIO
|
||||
if ($awstatsclean['path'] !== false && is_dir($awstatsclean['path'])) {
|
||||
$awstatsclean['dir'] = dir($awstatsclean['path']);
|
||||
while ($awstatsclean['entry'] = $awstatsclean['dir']->read()) {
|
||||
$awstatsclean['fullentry'] = makeCorrectFile($awstatsclean['path'] . '/' . $awstatsclean['entry']);
|
||||
$awstatsclean['fullentry'] = \Froxlor\FileDir::makeCorrectFile($awstatsclean['path'] . '/' . $awstatsclean['entry']);
|
||||
/**
|
||||
* don't do anything if the file does not exist
|
||||
*/
|
||||
@@ -197,9 +201,9 @@ class ConfigIO
|
||||
$awstatsclean['fh'] = fopen($awstatsclean['fullentry'], 'r');
|
||||
$awstatsclean['headerRead'] = fgets($awstatsclean['fh'], strlen($awstatsclean['header']) + 1);
|
||||
fclose($awstatsclean['fh']);
|
||||
|
||||
|
||||
if ($awstatsclean['headerRead'] == $awstatsclean['header'] || $awstatsclean['headerRead'] == $awstatsclean['headerold']) {
|
||||
$awstats_conf_file = makeCorrectFile($awstatsclean['fullentry']);
|
||||
$awstats_conf_file = \Froxlor\FileDir::makeCorrectFile($awstatsclean['fullentry']);
|
||||
@unlink($awstats_conf_file);
|
||||
}
|
||||
}
|
||||
@@ -219,17 +223,17 @@ class ConfigIO
|
||||
if (Settings::Get('system.mod_fcgid') == '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// get correct directory
|
||||
$configdir = $this->_getFile('system', 'mod_fcgid_configdir');
|
||||
if ($configdir !== false) {
|
||||
|
||||
$configdir = makeCorrectDir($configdir);
|
||||
|
||||
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir);
|
||||
|
||||
if (@is_dir($configdir)) {
|
||||
// create directory iterator
|
||||
$its = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($configdir));
|
||||
|
||||
$its = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($configdir));
|
||||
|
||||
// iterate through all subdirs,
|
||||
// look for php-fcgi-starter files
|
||||
// and take immutable-flag away from them
|
||||
@@ -237,14 +241,14 @@ class ConfigIO
|
||||
foreach ($its as $fullFileName => $it) {
|
||||
if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter') {
|
||||
// set chattr -i
|
||||
removeImmutable($its->getPathname());
|
||||
\Froxlor\FileDir::removeImmutable($its->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now get rid of old stuff
|
||||
// (but append /* so we don't delete the directory)
|
||||
$configdir .= '/*';
|
||||
safe_exec('rm -rf ' . makeCorrectFile($configdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . \Froxlor\FileDir::makeCorrectFile($configdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,31 +263,31 @@ class ConfigIO
|
||||
if (Settings::Get('phpfpm.enabled') == '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// get all fpm config paths
|
||||
$fpmconf_sel = Database::prepare("SELECT config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($fpmconf_sel);
|
||||
$fpmconf_paths = $fpmconf_sel->fetchAll(PDO::FETCH_ASSOC);
|
||||
$fpmconf_sel = \Froxlor\Database\Database::prepare("SELECT config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
\Froxlor\Database\Database::pexecute($fpmconf_sel);
|
||||
$fpmconf_paths = $fpmconf_sel->fetchAll(\PDO::FETCH_ASSOC);
|
||||
// clean all php-fpm config-dirs
|
||||
foreach ($fpmconf_paths as $configdir) {
|
||||
$configdir = makeCorrectDir($configdir['config_dir']);
|
||||
$configdir = \Froxlor\FileDir::makeCorrectDir($configdir['config_dir']);
|
||||
if (@is_dir($configdir)) {
|
||||
// now get rid of old stuff
|
||||
// (but append /*.conf so we don't delete the directory)
|
||||
$configdir .= '/*.conf';
|
||||
safe_exec('rm -f ' . makeCorrectFile($configdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . makeCorrectFile($configdir));
|
||||
} else {
|
||||
safe_exec('mkdir -p ' . $configdir);
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . $configdir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// also remove aliasconfigdir #1273
|
||||
$aliasconfigdir = $this->_getFile('phpfpm', 'aliasconfigdir');
|
||||
if ($aliasconfigdir !== false) {
|
||||
$aliasconfigdir = makeCorrectDir($aliasconfigdir);
|
||||
$aliasconfigdir = \Froxlor\FileDir::makeCorrectDir($aliasconfigdir);
|
||||
if (@is_dir($aliasconfigdir)) {
|
||||
$aliasconfigdir .= '/*';
|
||||
safe_exec('rm -rf ' . makeCorrectFile($aliasconfigdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . \Froxlor\FileDir::makeCorrectFile($aliasconfigdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,10 +306,10 @@ class ConfigIO
|
||||
*/
|
||||
private function _getFile($group, $varname, $check_exists = true)
|
||||
{
|
||||
|
||||
|
||||
// read from settings
|
||||
$file = Settings::Get($group . '.' . $varname);
|
||||
|
||||
|
||||
// check whether it exists
|
||||
if ($check_exists && @file_exists($file) == false) {
|
||||
return false;
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,69 +12,71 @@
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.29
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.29
|
||||
*
|
||||
*/
|
||||
|
||||
class DomainSSL {
|
||||
class DomainSSL
|
||||
{
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
public function __construct() {}
|
||||
public function __construct()
|
||||
{}
|
||||
|
||||
/**
|
||||
* read domain-related (or if empty, parentdomain-related) ssl-certificates from the database
|
||||
* and (if not empty) set the corresponding array-indices (ssl_cert_file, ssl_key_file,
|
||||
* ssl_ca_file and ssl_cert_chainfile). Hence the parameter as reference.
|
||||
*
|
||||
* @param array $domain domain-array as reference so we can set the corresponding array-indices
|
||||
* ssl_ca_file and ssl_cert_chainfile).
|
||||
* Hence the parameter as reference.
|
||||
*
|
||||
* @param array $domain
|
||||
* domain-array as reference so we can set the corresponding array-indices
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function setDomainSSLFilesArray(array &$domain = null) {
|
||||
public function setDomainSSLFilesArray(array &$domain = null)
|
||||
{
|
||||
// check if the domain itself has a certificate defined
|
||||
$dom_certs_stmt = Database::prepare("
|
||||
SELECT * FROM `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` WHERE `domainid` = :domid
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domid
|
||||
");
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, array('domid' => $domain['id']));
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, array(
|
||||
'domid' => $domain['id']
|
||||
));
|
||||
|
||||
if (!is_array($dom_certs)
|
||||
|| !isset($dom_certs['ssl_cert_file'])
|
||||
|| $dom_certs['ssl_cert_file'] == ''
|
||||
) {
|
||||
if (! is_array($dom_certs) || ! isset($dom_certs['ssl_cert_file']) || $dom_certs['ssl_cert_file'] == '') {
|
||||
// maybe its parent?
|
||||
if (isset($domain['parentdomainid']) && $domain['parentdomainid'] != 0) {
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, array('domid' => $domain['parentdomainid']));
|
||||
$dom_certs = Database::pexecute_first($dom_certs_stmt, array(
|
||||
'domid' => $domain['parentdomainid']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// check if it's an array and if the most important field is set
|
||||
if (is_array($dom_certs)
|
||||
&& isset($dom_certs['ssl_cert_file'])
|
||||
&& $dom_certs['ssl_cert_file'] != ''
|
||||
) {
|
||||
if (is_array($dom_certs) && isset($dom_certs['ssl_cert_file']) && $dom_certs['ssl_cert_file'] != '') {
|
||||
// get destination path
|
||||
$sslcertpath = makeCorrectDir(Settings::Get('system.customer_ssl_path'));
|
||||
// create path if it does not exist
|
||||
if (!file_exists($sslcertpath)) {
|
||||
safe_exec('mkdir -p '.escapeshellarg($sslcertpath));
|
||||
if (! file_exists($sslcertpath)) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($sslcertpath));
|
||||
}
|
||||
// make correct files for the certificates
|
||||
$ssl_files = array(
|
||||
'ssl_cert_file' => makeCorrectFile($sslcertpath.'/'.$domain['domain'].'.crt'),
|
||||
'ssl_key_file' => makeCorrectFile($sslcertpath.'/'.$domain['domain'].'.key')
|
||||
'ssl_cert_file' => makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.crt'),
|
||||
'ssl_key_file' => makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.key')
|
||||
);
|
||||
|
||||
if (Settings::Get('system.webserver') == 'lighttpd') {
|
||||
// put my.crt and my.key together for lighty.
|
||||
$dom_certs['ssl_cert_file'] = trim($dom_certs['ssl_cert_file'])."\n".trim($dom_certs['ssl_key_file'])."\n";
|
||||
$dom_certs['ssl_cert_file'] = trim($dom_certs['ssl_cert_file']) . "\n" . trim($dom_certs['ssl_key_file']) . "\n";
|
||||
$ssl_files['ssl_key_file'] = '';
|
||||
}
|
||||
|
||||
@@ -79,19 +85,19 @@ class DomainSSL {
|
||||
$ssl_files['ssl_cert_chainfile'] = '';
|
||||
// set them if they are != empty
|
||||
if ($dom_certs['ssl_ca_file'] != '') {
|
||||
$ssl_files['ssl_ca_file'] = makeCorrectFile($sslcertpath.'/'.$domain['domain'].'_CA.pem');
|
||||
$ssl_files['ssl_ca_file'] = makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_CA.pem');
|
||||
}
|
||||
if ($dom_certs['ssl_cert_chainfile'] != '') {
|
||||
if (Settings::Get('system.webserver') == 'nginx') {
|
||||
// put ca.crt in my.crt, as nginx does not support a separate chain file.
|
||||
$dom_certs['ssl_cert_file'] = trim($dom_certs['ssl_cert_file'])."\n".trim($dom_certs['ssl_cert_chainfile'])."\n";
|
||||
$dom_certs['ssl_cert_file'] = trim($dom_certs['ssl_cert_file']) . "\n" . trim($dom_certs['ssl_cert_chainfile']) . "\n";
|
||||
} else {
|
||||
$ssl_files['ssl_cert_chainfile'] = makeCorrectFile($sslcertpath.'/'.$domain['domain'].'_chain.pem');
|
||||
$ssl_files['ssl_cert_chainfile'] = makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_chain.pem');
|
||||
}
|
||||
}
|
||||
// will only be generated to be used externally, froxlor does not need this
|
||||
if ($dom_certs['ssl_fullchain_file'] != '') {
|
||||
$ssl_files['ssl_fullchain_file'] = makeCorrectFile($sslcertpath.'/'.$domain['domain'].'_fullchain.pem');
|
||||
$ssl_files['ssl_fullchain_file'] = makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '_fullchain.pem');
|
||||
}
|
||||
// create them on the filesystem
|
||||
foreach ($ssl_files as $type => $filename) {
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,18 +12,17 @@
|
||||
* 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> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class HttpConfigBase
|
||||
*
|
||||
* Base class for all HTTP server configs
|
||||
*
|
||||
*/
|
||||
class HttpConfigBase
|
||||
{
|
||||
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\Fpm;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -21,15 +24,9 @@ if (! defined('MASTER_CRONJOB'))
|
||||
* @todo ssl-redirect to non-standard port
|
||||
*/
|
||||
|
||||
require_once (dirname(__FILE__) . '/../classes/class.HttpConfigBase.php');
|
||||
|
||||
class lighttpd extends HttpConfigBase
|
||||
class Lighttpd extends HttpConfigBase
|
||||
{
|
||||
|
||||
private $logger = false;
|
||||
|
||||
private $idnaConvert = false;
|
||||
|
||||
// protected
|
||||
protected $lighttpd_data = array();
|
||||
|
||||
@@ -49,19 +46,13 @@ class lighttpd extends HttpConfigBase
|
||||
*/
|
||||
private $_deactivated = false;
|
||||
|
||||
public function __construct($logger, $idnaConvert)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->idnaConvert = $idnaConvert;
|
||||
}
|
||||
|
||||
public function reload()
|
||||
{
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
// get all start/stop commands
|
||||
$startstop_sel = Database::prepare("SELECT reload_cmd, config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($startstop_sel);
|
||||
$restart_cmds = $startstop_sel->fetchAll(PDO::FETCH_ASSOC);
|
||||
$restart_cmds = $startstop_sel->fetchAll(\PDO::FETCH_ASSOC);
|
||||
// restart all php-fpm instances
|
||||
foreach ($restart_cmds as $restart_cmd) {
|
||||
// check whether the config dir is empty (no domains uses this daemon)
|
||||
@@ -69,7 +60,7 @@ class lighttpd extends HttpConfigBase
|
||||
$_conffiles = glob(makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
|
||||
if ($_conffiles === false || empty($_conffiles)) {
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, 'lighttpd::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
|
||||
phpinterface_fpm::createDummyPool($restart_cmd['config_dir']);
|
||||
Fpm::createDummyPool($restart_cmd['config_dir']);
|
||||
}
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, 'lighttpd::reload: running ' . $restart_cmd['reload_cmd']);
|
||||
safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
|
||||
@@ -83,7 +74,7 @@ class lighttpd extends HttpConfigBase
|
||||
{
|
||||
$result_ipsandports_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC");
|
||||
|
||||
while ($row_ipsandports = $result_ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($row_ipsandports = $result_ipsandports_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if (filter_var($row_ipsandports['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$ip = '[' . $row_ipsandports['ip'] . ']';
|
||||
$port = $row_ipsandports['port'];
|
||||
@@ -176,7 +167,7 @@ class lighttpd extends HttpConfigBase
|
||||
'fpm_config_id' => isset($fpm_config['id']) ? $fpm_config['id'] : 1
|
||||
);
|
||||
|
||||
$php = new phpinterface($domain);
|
||||
$php = new PhpInterface($domain);
|
||||
|
||||
$this->lighttpd_data[$vhost_filename] .= ' fastcgi.server = ( ' . "\n";
|
||||
$this->lighttpd_data[$vhost_filename] .= "\t" . '".php" => (' . "\n";
|
||||
@@ -345,7 +336,7 @@ class lighttpd extends HttpConfigBase
|
||||
));
|
||||
|
||||
$htaccess_text = '';
|
||||
while ($row_htpasswds = $result_htpasswds_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($row_htpasswds = $result_htpasswds_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$row_htpasswds['path'] = makeCorrectDir($row_htpasswds['path']);
|
||||
mkDirWithCorrectOwnership($domain['documentroot'], $row_htpasswds['path'], $domain['guid'], $domain['guid']);
|
||||
|
||||
@@ -658,7 +649,7 @@ class lighttpd extends HttpConfigBase
|
||||
'domainid' => $domain['id']
|
||||
));
|
||||
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(\PDO::FETCH_ASSOC)) !== false) {
|
||||
|
||||
$server_alias .= ' ' . $alias_domain['domain'] . ' ';
|
||||
|
||||
@@ -707,7 +698,7 @@ class lighttpd extends HttpConfigBase
|
||||
$path_options = '';
|
||||
$error_string = '';
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (! empty($row['error404path'])) {
|
||||
$defhandler = $row['error404path'];
|
||||
@@ -768,7 +759,7 @@ class lighttpd extends HttpConfigBase
|
||||
'customerid' => $domain['customerid']
|
||||
));
|
||||
|
||||
while ($row_htpasswds = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($row_htpasswds = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if ($auth_backend_loaded[$domain['ipandport']] != 'yes' && $auth_backend_loaded[$domain['ssl_ipandport']] != 'yes') {
|
||||
$filename = $domain['customerid'] . '.htpasswd';
|
||||
|
||||
@@ -832,7 +823,7 @@ class lighttpd extends HttpConfigBase
|
||||
'domainid' => $domain['id']
|
||||
));
|
||||
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(\PDO::FETCH_ASSOC)) !== false) {
|
||||
$alias_domain_name = str_replace('.', '\.', $alias_domain['domain']);
|
||||
|
||||
if ($alias_domain['iswildcarddomain'] == '1') {
|
||||
@@ -953,7 +944,7 @@ class lighttpd extends HttpConfigBase
|
||||
{
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, "lighttpd::writeConfigs: rebuilding " . Settings::Get('system.apacheconf_vhost'));
|
||||
|
||||
$vhostDir = new frxDirectory(Settings::Get('system.apacheconf_vhost'));
|
||||
$vhostDir = new \Froxlor\Http\Directory(Settings::Get('system.apacheconf_vhost'));
|
||||
if (! $vhostDir->isConfigDir()) {
|
||||
// Save one big file
|
||||
$vhosts_file = '';
|
||||
@@ -998,7 +989,7 @@ class lighttpd extends HttpConfigBase
|
||||
}
|
||||
|
||||
// Write the diroptions
|
||||
$htpasswdDir = new frxDirectory(Settings::Get('system.apacheconf_htpasswddir'));
|
||||
$htpasswdDir = new \Froxlor\Http\Directory(Settings::Get('system.apacheconf_htpasswddir'));
|
||||
if ($htpasswdDir->isConfigDir()) {
|
||||
foreach ($this->needed_htpasswds as $key => $data) {
|
||||
if (! is_dir(Settings::Get('system.apacheconf_htpasswddir'))) {
|
||||
151
lib/Froxlor/Cron/Http/LighttpdFcgi.php
Normal file
151
lib/Froxlor/Cron/Http/LighttpdFcgi.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
class LighttpdFcgi extends Lighttpd
|
||||
{
|
||||
|
||||
protected function composePhpOptions($domain)
|
||||
{
|
||||
$php_options_text = '';
|
||||
|
||||
if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
|
||||
$php = new PhpInterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int) $domain['phpsettingid']);
|
||||
|
||||
// vhost data for php-fpm
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
$php_options_text = ' fastcgi.server = ( ' . "\n";
|
||||
$php_options_text .= "\t" . '".php" => (' . "\n";
|
||||
$php_options_text .= "\t\t" . '"localhost" => (' . "\n";
|
||||
$php_options_text .= "\t\t" . '"socket" => "' . $php->getInterface()->getSocketFile() . '",' . "\n";
|
||||
$php_options_text .= "\t\t" . '"check-local" => "enable",' . "\n";
|
||||
$php_options_text .= "\t\t" . '"disable-time" => 1' . "\n";
|
||||
$php_options_text .= "\t" . ')' . "\n";
|
||||
$php_options_text .= "\t" . ')' . "\n";
|
||||
$php_options_text .= ' )' . "\n";
|
||||
} // vhost data for fcgid
|
||||
elseif ((int) Settings::Get('system.mod_fcgid') == 1) {
|
||||
$php_options_text = ' fastcgi.server = ( ' . "\n";
|
||||
$file_extensions = explode(' ', $phpconfig['file_extensions']);
|
||||
foreach ($file_extensions as $f_extension) {
|
||||
$php_options_text .= "\t" . '".' . $f_extension . '" => (' . "\n";
|
||||
$php_options_text .= "\t\t" . '"localhost" => (' . "\n";
|
||||
$php_options_text .= "\t\t" . '"socket" => "/var/run/lighttpd/' . $domain['loginname'] . '-' . $domain['domain'] . '-php.socket",' . "\n";
|
||||
$php_options_text .= "\t\t" . '"bin-path" => "' . $phpconfig['binary'] . ' -c ' . $php->getInterface()->getIniFile() . '",' . "\n";
|
||||
$php_options_text .= "\t\t" . '"bin-environment" => (' . "\n";
|
||||
if ((int) $domain['mod_fcgid_starter'] != - 1) {
|
||||
$php_options_text .= "\t\t\t" . '"PHP_FCGI_CHILDREN" => "' . (int) $domain['mod_fcgid_starter'] . '",' . "\n";
|
||||
} else {
|
||||
if ((int) $phpconfig['mod_fcgid_starter'] != - 1) {
|
||||
$php_options_text .= "\t\t\t" . '"PHP_FCGI_CHILDREN" => "' . (int) $phpconfig['mod_fcgid_starter'] . '",' . "\n";
|
||||
} else {
|
||||
$php_options_text .= "\t\t\t" . '"PHP_FCGI_CHILDREN" => "' . (int) Settings::Get('system.mod_fcgid_starter') . '",' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ((int) $domain['mod_fcgid_maxrequests'] != - 1) {
|
||||
$php_options_text .= "\t\t\t" . '"PHP_FCGI_MAX_REQUESTS" => "' . (int) $domain['mod_fcgid_maxrequests'] . '"' . "\n";
|
||||
} else {
|
||||
if ((int) $phpconfig['mod_fcgid_maxrequests'] != - 1) {
|
||||
$php_options_text .= "\t\t\t" . '"PHP_FCGI_MAX_REQUESTS" => "' . (int) $phpconfig['mod_fcgid_maxrequests'] . '"' . "\n";
|
||||
} else {
|
||||
$php_options_text .= "\t\t\t" . '"PHP_FCGI_MAX_REQUESTS" => "' . (int) Settings::Get('system.mod_fcgid_maxrequests') . '"' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$php_options_text .= "\t\t" . ')' . "\n";
|
||||
$php_options_text .= "\t" . ')' . "\n";
|
||||
$php_options_text .= "\t" . ')' . "\n";
|
||||
} // foreach extension
|
||||
$php_options_text .= ' )' . "\n";
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
} else {
|
||||
$php_options_text .= ' # PHP is disabled for this vHost' . "\n";
|
||||
}
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.enabled_ownvhost') == '1') {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__)))); // /var/www/froxlor, needed for chown
|
||||
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
|
||||
// get fpm config
|
||||
$fpm_sel_stmt = Database::prepare("
|
||||
SELECT f.id FROM `" . TABLE_PANEL_FPMDAEMONS . "` f
|
||||
LEFT JOIN `" . TABLE_PANEL_PHPCONFIGS . "` p ON p.fpmsettingid = f.id
|
||||
WHERE p.id = :phpconfigid
|
||||
");
|
||||
$fpm_config = Database::pexecute_first($fpm_sel_stmt, array(
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
));
|
||||
|
||||
$domain = array(
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'adminid' => 1, /* first admin-user (superadmin) */
|
||||
'mod_fcgid_starter' => - 1,
|
||||
'mod_fcgid_maxrequests' => - 1,
|
||||
'guid' => $user,
|
||||
'openbasedir' => 0,
|
||||
'email' => Settings::Get('panel.adminmail'),
|
||||
'loginname' => 'froxlor.panel',
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath,
|
||||
'fpm_config_id' => isset($fpm_config['id']) ? $fpm_config['id'] : 1
|
||||
);
|
||||
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
|
||||
// get php.ini for our own vhost
|
||||
$php = new PhpInterface($domain);
|
||||
|
||||
// get php-config
|
||||
if (Settings::Get('phpfpm.enabled') == '1') {
|
||||
// fpm
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('phpfpm.vhost_defaultini'));
|
||||
} else {
|
||||
// fcgid
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('system.mod_fcgid_defaultini_ownvhost'));
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
if (! defined('MASTER_CRONJOB'))
|
||||
die('You cannot access this file directly!');
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\Fpm;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -15,18 +18,11 @@ if (! defined('MASTER_CRONJOB'))
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
require_once (dirname(__FILE__) . '/../classes/class.HttpConfigBase.php');
|
||||
|
||||
class nginx extends HttpConfigBase
|
||||
class Nginx extends HttpConfigBase
|
||||
{
|
||||
|
||||
private $logger = false;
|
||||
|
||||
private $idnaConvert = false;
|
||||
|
||||
private $nginx_server = array();
|
||||
|
||||
// protected
|
||||
@@ -54,10 +50,8 @@ class nginx extends HttpConfigBase
|
||||
*/
|
||||
private $_deactivated = false;
|
||||
|
||||
public function __construct($logger, $idnaConvert, $nginx_server = array())
|
||||
public function __construct($nginx_server = array())
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->idnaConvert = $idnaConvert;
|
||||
$this->nginx_server = $nginx_server;
|
||||
}
|
||||
|
||||
@@ -67,7 +61,7 @@ class nginx extends HttpConfigBase
|
||||
// get all start/stop commands
|
||||
$startstop_sel = Database::prepare("SELECT reload_cmd, config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($startstop_sel);
|
||||
$restart_cmds = $startstop_sel->fetchAll(PDO::FETCH_ASSOC);
|
||||
$restart_cmds = $startstop_sel->fetchAll(\PDO::FETCH_ASSOC);
|
||||
// restart all php-fpm instances
|
||||
foreach ($restart_cmds as $restart_cmd) {
|
||||
// check whether the config dir is empty (no domains uses this daemon)
|
||||
@@ -75,7 +69,7 @@ class nginx extends HttpConfigBase
|
||||
$_conffiles = glob(makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
|
||||
if ($_conffiles === false || empty($_conffiles)) {
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, 'nginx::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
|
||||
phpinterface_fpm::createDummyPool($restart_cmd['config_dir']);
|
||||
Fpm::createDummyPool($restart_cmd['config_dir']);
|
||||
}
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, 'nginx::reload: running ' . $restart_cmd['reload_cmd']);
|
||||
safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
|
||||
@@ -143,7 +137,7 @@ class nginx extends HttpConfigBase
|
||||
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC
|
||||
");
|
||||
|
||||
while ($row_ipsandports = $result_ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($row_ipsandports = $result_ipsandports_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if (filter_var($row_ipsandports['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$ip = '[' . $row_ipsandports['ip'] . ']';
|
||||
} else {
|
||||
@@ -170,10 +164,10 @@ class nginx extends HttpConfigBase
|
||||
if ($row_ipsandports['ssl'] == '1') {
|
||||
if ($row_ipsandports['ssl_cert_file'] == '') {
|
||||
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
|
||||
if (!file_exists($row_ipsandports['ssl_cert_file'])) {
|
||||
if (! file_exists($row_ipsandports['ssl_cert_file'])) {
|
||||
// explicitly disable ssl for this vhost
|
||||
$row_ipsandports['ssl_cert_file'] = "";
|
||||
$this->logger->logAction(CRON_ACTION, LOG_DEBUG, 'System certificate file "'.Settings::Get('system.ssl_cert_file').'" does not seem to exist. Disabling SSL-vhost for "'.Settings::Get('system.hostname').'"');
|
||||
$this->logger->logAction(CRON_ACTION, LOG_DEBUG, 'System certificate file "' . Settings::Get('system.ssl_cert_file') . '" does not seem to exist. Disabling SSL-vhost for "' . Settings::Get('system.hostname') . '"');
|
||||
}
|
||||
}
|
||||
if ($row_ipsandports['ssl_key_file'] == '') {
|
||||
@@ -313,7 +307,7 @@ class nginx extends HttpConfigBase
|
||||
'fpm_config_id' => isset($fpm_config['id']) ? $fpm_config['id'] : 1
|
||||
);
|
||||
|
||||
$php = new phpinterface($domain);
|
||||
$php = new PhpInterface($domain);
|
||||
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_pass unix:" . $php->getInterface()->getSocketFile() . ";\n";
|
||||
} else {
|
||||
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_pass " . Settings::Get('system.nginx_php_backend') . ";\n";
|
||||
@@ -425,7 +419,7 @@ class nginx extends HttpConfigBase
|
||||
'domainid' => $domain['id']
|
||||
));
|
||||
|
||||
while ($ipandport = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($ipandport = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
$domain['ip'] = $ipandport['ip'];
|
||||
$domain['port'] = $ipandport['port'];
|
||||
@@ -454,7 +448,7 @@ class nginx extends HttpConfigBase
|
||||
|
||||
$http2 = $ssl_vhost == true && (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1');
|
||||
|
||||
$vhost_content .= "\t" . 'listen ' . $ipport . ($ssl_vhost == true ? ' ssl' : '') . ($http2 == true ? ' http2' : '') . ';' . "\n";
|
||||
$vhost_content .= "\t" . 'listen ' . $ipport . ($ssl_vhost == true ? ' ssl' : '') . ($http2 == true ? ' http2' : '') . ';' . "\n";
|
||||
}
|
||||
|
||||
// get all server-names
|
||||
@@ -508,7 +502,7 @@ class nginx extends HttpConfigBase
|
||||
$code = getDomainRedirectCode($domain['id']);
|
||||
|
||||
$vhost_content .= "\t" . 'if ($request_uri !~ ^/.well-known/acme-challenge/[-\w]+$) {' . "\n";
|
||||
$vhost_content .= "\t\t" . 'return ' . $code .' ' . $uri . '$request_uri;' . "\n";
|
||||
$vhost_content .= "\t\t" . 'return ' . $code . ' ' . $uri . '$request_uri;' . "\n";
|
||||
$vhost_content .= "\t" . '}' . "\n";
|
||||
} else {
|
||||
mkDirWithCorrectOwnership($domain['customerroot'], $domain['documentroot'], $domain['guid'], $domain['guid'], true);
|
||||
@@ -620,10 +614,10 @@ class nginx extends HttpConfigBase
|
||||
|
||||
if ($domain_or_ip['ssl_cert_file'] == '') {
|
||||
$domain_or_ip['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
|
||||
if (!file_exists($domain_or_ip['ssl_cert_file'])) {
|
||||
if (! file_exists($domain_or_ip['ssl_cert_file'])) {
|
||||
// explicitly disable ssl for this vhost
|
||||
$domain_or_ip['ssl_cert_file'] = "";
|
||||
$this->logger->logAction(CRON_ACTION, LOG_DEBUG, 'System certificate file "'.Settings::Get('system.ssl_cert_file').'" does not seem to exist. Disabling SSL-vhost for "'.$domain_or_ip['domain'].'"');
|
||||
$this->logger->logAction(CRON_ACTION, LOG_DEBUG, 'System certificate file "' . Settings::Get('system.ssl_cert_file') . '" does not seem to exist. Disabling SSL-vhost for "' . $domain_or_ip['domain'] . '"');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,10 +644,10 @@ class nginx extends HttpConfigBase
|
||||
// $sslsettings .= "\t" . 'ssl on;' . "\n";
|
||||
$sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", Settings::Get('system.ssl_protocols')) . ';' . "\n";
|
||||
$sslsettings .= "\t" . 'ssl_ciphers ' . Settings::Get('system.ssl_cipher_list') . ';' . "\n";
|
||||
if (!empty(Settings::Get('system.dhparams_file'))) {
|
||||
if (! empty(Settings::Get('system.dhparams_file'))) {
|
||||
$dhparams = makeCorrectFile(Settings::Get('system.dhparams_file'));
|
||||
if (!file_exists($dhparams)) {
|
||||
safe_exec('openssl dhparam -out '.escapeshellarg($dhparams).' 4096');
|
||||
if (! file_exists($dhparams)) {
|
||||
safe_exec('openssl dhparam -out ' . escapeshellarg($dhparams) . ' 4096');
|
||||
}
|
||||
$sslsettings .= 'ssl_dhparam ' . $dhparams . ';' . "\n";
|
||||
}
|
||||
@@ -681,12 +675,10 @@ class nginx extends HttpConfigBase
|
||||
$sslsettings .= '";' . "\n";
|
||||
}
|
||||
|
||||
if ((isset($domain_or_ip['ocsp_stapling']) && $domain_or_ip['ocsp_stapling'] == "1") ||
|
||||
(isset($domain_or_ip['letsencrypt']) && $domain_or_ip['letsencrypt'] == "1") ) {
|
||||
if ((isset($domain_or_ip['ocsp_stapling']) && $domain_or_ip['ocsp_stapling'] == "1") || (isset($domain_or_ip['letsencrypt']) && $domain_or_ip['letsencrypt'] == "1")) {
|
||||
$sslsettings .= "\t" . 'ssl_stapling on;' . "\n";
|
||||
$sslsettings .= "\t" . 'ssl_stapling_verify on;' . "\n";
|
||||
$sslsettings .= "\t" . 'ssl_trusted_certificate ' .
|
||||
makeCorrectFile($domain_or_ip['ssl_cert_file']) . ';' . "\n";
|
||||
$sslsettings .= "\t" . 'ssl_trusted_certificate ' . makeCorrectFile($domain_or_ip['ssl_cert_file']) . ';' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -696,8 +688,6 @@ class nginx extends HttpConfigBase
|
||||
|
||||
protected function create_pathOptions($domain)
|
||||
{
|
||||
$has_location = false;
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM " . TABLE_PANEL_HTACCESS . "
|
||||
WHERE `path` LIKE :docroot
|
||||
@@ -710,7 +700,7 @@ class nginx extends HttpConfigBase
|
||||
$htpasswds = $this->getHtpasswds($domain);
|
||||
|
||||
// for each entry in the htaccess table
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if (! empty($row['error404path'])) {
|
||||
$defhandler = $row['error404path'];
|
||||
if (! validateUrl($defhandler)) {
|
||||
@@ -860,7 +850,7 @@ class nginx extends HttpConfigBase
|
||||
|
||||
$returnval = array();
|
||||
$x = 0;
|
||||
while ($row_htpasswds = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
while ($row_htpasswds = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if (count($row_htpasswds) > 0) {
|
||||
$htpasswd_filename = makeCorrectFile(Settings::Get('system.apacheconf_htpasswddir') . '/' . $row_htpasswds['customerid'] . '-' . md5($row_htpasswds['path']) . '.htpasswd');
|
||||
|
||||
@@ -1067,7 +1057,7 @@ class nginx extends HttpConfigBase
|
||||
'domainid' => $domain['id']
|
||||
));
|
||||
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(\PDO::FETCH_ASSOC)) !== false) {
|
||||
$server_alias .= ' ' . $alias_domain['domain'] . ' ';
|
||||
|
||||
if ($alias_domain['iswildcarddomain'] == '1') {
|
||||
@@ -1121,7 +1111,7 @@ class nginx extends HttpConfigBase
|
||||
'domainid' => $domain['id']
|
||||
));
|
||||
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
|
||||
while (($alias_domain = $alias_domains_stmt->fetch(\PDO::FETCH_ASSOC)) !== false) {
|
||||
$server_alias .= ' ' . $alias_domain['domain'];
|
||||
|
||||
if ($alias_domain['iswildcarddomain'] == '1') {
|
||||
@@ -1144,7 +1134,7 @@ class nginx extends HttpConfigBase
|
||||
{
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, "nginx::writeConfigs: rebuilding " . Settings::Get('system.apacheconf_vhost'));
|
||||
|
||||
$vhostDir = new frxDirectory(Settings::Get('system.apacheconf_vhost'));
|
||||
$vhostDir = new \Froxlor\Http\Directory(Settings::Get('system.apacheconf_vhost'));
|
||||
if (! $vhostDir->isConfigDir()) {
|
||||
// Save one big file
|
||||
$vhosts_file = '';
|
||||
@@ -1,4 +1,9 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,22 +13,23 @@
|
||||
* 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
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
class nginx_phpfpm extends nginx
|
||||
class NginxFcgi extends Nginx
|
||||
{
|
||||
protected function composePhpOptions($domain, $ssl_vhost = false) {
|
||||
|
||||
protected function composePhpOptions($domain, $ssl_vhost = false)
|
||||
{
|
||||
$php_options_text = '';
|
||||
|
||||
if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
|
||||
$php = new phpinterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
$php = new PhpInterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int) $domain['phpsettingid']);
|
||||
|
||||
$php_options_text = "\t" . 'location ~ ^(.+?\.php)(/.*)?$ {' . "\n";
|
||||
$php_options_text .= "\t\t" . 'try_files ' . $domain['nonexistinguri'] . ' @php;' . "\n";
|
||||
$php_options_text .= "\t" . '}' . "\n\n";
|
||||
@@ -40,26 +46,23 @@ class nginx_phpfpm extends nginx
|
||||
$php_options_text .= "\t\t" . 'fastcgi_pass unix:' . $php->getInterface()->getSocketFile() . ";\n";
|
||||
$php_options_text .= "\t\t" . 'fastcgi_index index.php;' . "\n";
|
||||
$php_options_text .= "\t}\n\n";
|
||||
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
else {
|
||||
$php_options_text.= ' # PHP is disabled for this vHost' . "\n";
|
||||
} else {
|
||||
$php_options_text .= ' # PHP is disabled for this vHost' . "\n";
|
||||
}
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
|
||||
public function createOwnVhostStarter() {
|
||||
if (Settings::Get('phpfpm.enabled') == '1'
|
||||
&& Settings::Get('phpfpm.enabled_ownvhost') == '1'
|
||||
) {
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.enabled_ownvhost') == '1') {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__)))); // /var/www/froxlor, needed for chown
|
||||
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
@@ -79,8 +82,8 @@ class nginx_phpfpm extends nginx
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'adminid' => 1, /* first admin-user (superadmin) */
|
||||
'mod_fcgid_starter' => -1,
|
||||
'mod_fcgid_maxrequests' => -1,
|
||||
'mod_fcgid_starter' => - 1,
|
||||
'mod_fcgid_maxrequests' => - 1,
|
||||
'guid' => $user,
|
||||
'openbasedir' => 0,
|
||||
'email' => Settings::Get('panel.adminmail'),
|
||||
@@ -95,7 +98,7 @@ class nginx_phpfpm extends nginx
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
|
||||
// get php.ini for our own vhost
|
||||
$php = new phpinterface($domain);
|
||||
$php = new PhpInterface($domain);
|
||||
|
||||
// get php-config
|
||||
if (Settings::Get('phpfpm.enabled') == '1') {
|
||||
@@ -114,6 +117,4 @@ class nginx_phpfpm extends nginx
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,85 +12,89 @@
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
*/
|
||||
|
||||
class phpinterface_fcgid {
|
||||
class Fcgid
|
||||
{
|
||||
|
||||
/**
|
||||
* Domain-Data array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
*/
|
||||
private $_domain = array();
|
||||
|
||||
/**
|
||||
* Admin-Date cache array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
*/
|
||||
private $_admin_cache = array();
|
||||
|
||||
/**
|
||||
* main constructor
|
||||
*/
|
||||
public function __construct($domain) {
|
||||
*/
|
||||
public function __construct($domain)
|
||||
{
|
||||
$this->_domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* create fcgid-starter-file
|
||||
*
|
||||
* @param array $phpconfig
|
||||
*/
|
||||
public function createConfig($phpconfig) {
|
||||
public function createConfig($phpconfig)
|
||||
{
|
||||
|
||||
// create starter
|
||||
$starter_file = "#!/bin/sh\n\n";
|
||||
$starter_file.= "#\n";
|
||||
$starter_file.= "# starter created/changed on " . date("Y.m.d H:i:s") . " for domain '" . $this->_domain['domain'] . "' with id #" . $this->_domain['id'] . " from php template '" . $phpconfig['description'] . "' with id #" . $phpconfig['id'] . "\n";
|
||||
$starter_file.= "# Do not change anything in this file, it will be overwritten by the Froxlor Cronjob!\n";
|
||||
$starter_file.= "#\n\n";
|
||||
$starter_file.= "umask ".$phpconfig['mod_fcgid_umask']."\n";
|
||||
$starter_file.= "PHPRC=" . escapeshellarg($this->getConfigDir()) . "\n";
|
||||
$starter_file.= "export PHPRC\n";
|
||||
$starter_file .= "#\n";
|
||||
$starter_file .= "# starter created/changed on " . date("Y.m.d H:i:s") . " for domain '" . $this->_domain['domain'] . "' with id #" . $this->_domain['id'] . " from php template '" . $phpconfig['description'] . "' with id #" . $phpconfig['id'] . "\n";
|
||||
$starter_file .= "# Do not change anything in this file, it will be overwritten by the Froxlor Cronjob!\n";
|
||||
$starter_file .= "#\n\n";
|
||||
$starter_file .= "umask " . $phpconfig['mod_fcgid_umask'] . "\n";
|
||||
$starter_file .= "PHPRC=" . escapeshellarg($this->getConfigDir()) . "\n";
|
||||
$starter_file .= "export PHPRC\n";
|
||||
|
||||
// set number of processes for one domain
|
||||
if ((int)$this->_domain['mod_fcgid_starter'] != - 1) {
|
||||
$starter_file.= "PHP_FCGI_CHILDREN=" . (int)$this->_domain['mod_fcgid_starter'] . "\n";
|
||||
|
||||
if ((int) $this->_domain['mod_fcgid_starter'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int) $this->_domain['mod_fcgid_starter'] . "\n";
|
||||
} else {
|
||||
if ((int)$phpconfig['mod_fcgid_starter'] != - 1) {
|
||||
$starter_file.= "PHP_FCGI_CHILDREN=" . (int)$phpconfig['mod_fcgid_starter'] . "\n";
|
||||
if ((int) $phpconfig['mod_fcgid_starter'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int) $phpconfig['mod_fcgid_starter'] . "\n";
|
||||
} else {
|
||||
$starter_file.= "PHP_FCGI_CHILDREN=" . (int)Settings::Get('system.mod_fcgid_starter') . "\n";
|
||||
$starter_file .= "PHP_FCGI_CHILDREN=" . (int) Settings::Get('system.mod_fcgid_starter') . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$starter_file.= "export PHP_FCGI_CHILDREN\n";
|
||||
$starter_file .= "export PHP_FCGI_CHILDREN\n";
|
||||
|
||||
// set number of maximum requests for one domain
|
||||
if ((int)$this->_domain['mod_fcgid_maxrequests'] != - 1) {
|
||||
$starter_file.= "PHP_FCGI_MAX_REQUESTS=" . (int)$this->_domain['mod_fcgid_maxrequests'] . "\n";
|
||||
if ((int) $this->_domain['mod_fcgid_maxrequests'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int) $this->_domain['mod_fcgid_maxrequests'] . "\n";
|
||||
} else {
|
||||
if ((int)$phpconfig['mod_fcgid_maxrequests'] != - 1) {
|
||||
$starter_file.= "PHP_FCGI_MAX_REQUESTS=" . (int)$phpconfig['mod_fcgid_maxrequests'] . "\n";
|
||||
if ((int) $phpconfig['mod_fcgid_maxrequests'] != - 1) {
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int) $phpconfig['mod_fcgid_maxrequests'] . "\n";
|
||||
} else {
|
||||
$starter_file.= "PHP_FCGI_MAX_REQUESTS=" . (int)Settings::Get('system.mod_fcgid_maxrequests') . "\n";
|
||||
$starter_file .= "PHP_FCGI_MAX_REQUESTS=" . (int) Settings::Get('system.mod_fcgid_maxrequests') . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$starter_file.= "export PHP_FCGI_MAX_REQUESTS\n";
|
||||
$starter_file .= "export PHP_FCGI_MAX_REQUESTS\n";
|
||||
|
||||
// Set Binary
|
||||
$starter_file.= "exec " . $phpconfig['binary'] . " -c " . escapeshellarg($this->getConfigDir()) . "\n";
|
||||
$starter_file .= "exec " . $phpconfig['binary'] . " -c " . escapeshellarg($this->getConfigDir()) . "\n";
|
||||
|
||||
//remove +i attibute, so starter can be overwritten
|
||||
// remove +i attibute, so starter can be overwritten
|
||||
if (file_exists($this->getStarterFile())) {
|
||||
removeImmutable($this->getStarterFile());
|
||||
}
|
||||
@@ -104,8 +112,8 @@ class phpinterface_fcgid {
|
||||
*
|
||||
* @param array $phpconfig
|
||||
*/
|
||||
public function createIniFile($phpconfig) {
|
||||
|
||||
public function createIniFile($phpconfig)
|
||||
{
|
||||
$openbasedir = '';
|
||||
$openbasedirc = ';';
|
||||
|
||||
@@ -124,9 +132,7 @@ class phpinterface_fcgid {
|
||||
$_phpappendopenbasedir .= appendOpenBasedirPath($cobd);
|
||||
}
|
||||
|
||||
if ($this->_domain['openbasedir_path'] == '0'
|
||||
&& strstr($this->_domain['documentroot'], ":") === false
|
||||
) {
|
||||
if ($this->_domain['openbasedir_path'] == '0' && strstr($this->_domain['documentroot'], ":") === false) {
|
||||
$openbasedir = appendOpenBasedirPath($this->_domain['documentroot'], true);
|
||||
} else {
|
||||
$openbasedir = appendOpenBasedirPath($this->_domain['customerroot'], true);
|
||||
@@ -134,7 +140,6 @@ class phpinterface_fcgid {
|
||||
|
||||
$openbasedir .= appendOpenBasedirPath($this->getTempDir());
|
||||
$openbasedir .= $_phpappendopenbasedir;
|
||||
|
||||
} else {
|
||||
$openbasedir = 'none';
|
||||
$openbasedirc = ';';
|
||||
@@ -142,29 +147,29 @@ class phpinterface_fcgid {
|
||||
|
||||
$admin = $this->_getAdminData($this->_domain['adminid']);
|
||||
$php_ini_variables = array(
|
||||
'SAFE_MODE' => 'Off', // keep this for compatibility, just in case
|
||||
'PEAR_DIR' => Settings::Get('system.mod_fcgid_peardir'),
|
||||
'TMP_DIR' => $this->getTempDir(),
|
||||
'CUSTOMER_EMAIL' => $this->_domain['email'],
|
||||
'ADMIN_EMAIL' => $admin['email'],
|
||||
'DOMAIN' => $this->_domain['domain'],
|
||||
'CUSTOMER' => $this->_domain['loginname'],
|
||||
'ADMIN' => $admin['loginname'],
|
||||
'OPEN_BASEDIR' => $openbasedir,
|
||||
'OPEN_BASEDIR_C' => $openbasedirc,
|
||||
'OPEN_BASEDIR_GLOBAL' => Settings::Get('system.phpappendopenbasedir'),
|
||||
'DOCUMENT_ROOT' => makeCorrectDir($this->_domain['documentroot']),
|
||||
'CUSTOMER_HOMEDIR' => makeCorrectDir($this->_domain['customerroot'])
|
||||
'SAFE_MODE' => 'Off', // keep this for compatibility, just in case
|
||||
'PEAR_DIR' => Settings::Get('system.mod_fcgid_peardir'),
|
||||
'TMP_DIR' => $this->getTempDir(),
|
||||
'CUSTOMER_EMAIL' => $this->_domain['email'],
|
||||
'ADMIN_EMAIL' => $admin['email'],
|
||||
'DOMAIN' => $this->_domain['domain'],
|
||||
'CUSTOMER' => $this->_domain['loginname'],
|
||||
'ADMIN' => $admin['loginname'],
|
||||
'OPEN_BASEDIR' => $openbasedir,
|
||||
'OPEN_BASEDIR_C' => $openbasedirc,
|
||||
'OPEN_BASEDIR_GLOBAL' => Settings::Get('system.phpappendopenbasedir'),
|
||||
'DOCUMENT_ROOT' => makeCorrectDir($this->_domain['documentroot']),
|
||||
'CUSTOMER_HOMEDIR' => makeCorrectDir($this->_domain['customerroot'])
|
||||
);
|
||||
|
||||
//insert a small header for the file
|
||||
// insert a small header for the file
|
||||
$phpini_file = ";\n";
|
||||
$phpini_file.= "; php.ini created/changed on " . date("Y.m.d H:i:s") . " for domain '" . $this->_domain['domain'] . "' with id #" . $this->_domain['id'] . " from php template '" . $phpconfig['description'] . "' with id #" . $phpconfig['id'] . "\n";
|
||||
$phpini_file.= "; Do not change anything in this file, it will be overwritten by the Froxlor Cronjob!\n";
|
||||
$phpini_file.= ";\n\n";
|
||||
$phpini_file.= replace_variables($phpconfig['phpsettings'], $php_ini_variables);
|
||||
$phpini_file .= "; php.ini created/changed on " . date("Y.m.d H:i:s") . " for domain '" . $this->_domain['domain'] . "' with id #" . $this->_domain['id'] . " from php template '" . $phpconfig['description'] . "' with id #" . $phpconfig['id'] . "\n";
|
||||
$phpini_file .= "; Do not change anything in this file, it will be overwritten by the Froxlor Cronjob!\n";
|
||||
$phpini_file .= ";\n\n";
|
||||
$phpini_file .= replace_variables($phpconfig['phpsettings'], $php_ini_variables);
|
||||
$phpini_file = str_replace('"none"', 'none', $phpini_file);
|
||||
//$phpini_file = preg_replace('/\"+/', '"', $phpini_file);
|
||||
// $phpini_file = preg_replace('/\"+/', '"', $phpini_file);
|
||||
$phpini_file_handler = fopen($this->getIniFile(), 'w');
|
||||
fwrite($phpini_file_handler, $phpini_file);
|
||||
fclose($phpini_file_handler);
|
||||
@@ -175,15 +180,16 @@ class phpinterface_fcgid {
|
||||
/**
|
||||
* fcgid-config directory
|
||||
*
|
||||
* @param boolean $createifnotexists create the directory if it does not exist
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getConfigDir($createifnotexists = true) {
|
||||
|
||||
public function getConfigDir($createifnotexists = true)
|
||||
{
|
||||
$configdir = makeCorrectDir(Settings::Get('system.mod_fcgid_configdir') . '/' . $this->_domain['loginname'] . '/' . $this->_domain['domain'] . '/');
|
||||
|
||||
if (!is_dir($configdir) && $createifnotexists) {
|
||||
if (! is_dir($configdir) && $createifnotexists) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
safe_exec('chown ' . $this->_domain['guid'] . ':' . $this->_domain['guid'] . ' ' . escapeshellarg($configdir));
|
||||
}
|
||||
@@ -194,15 +200,16 @@ class phpinterface_fcgid {
|
||||
/**
|
||||
* fcgid-temp directory
|
||||
*
|
||||
* @param boolean $createifnotexists create the directory if it does not exist
|
||||
*
|
||||
* @param boolean $createifnotexists
|
||||
* create the directory if it does not exist
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getTempDir($createifnotexists = true) {
|
||||
|
||||
public function getTempDir($createifnotexists = true)
|
||||
{
|
||||
$tmpdir = makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir') . '/' . $this->_domain['loginname'] . '/');
|
||||
|
||||
if (!is_dir($tmpdir) && $createifnotexists) {
|
||||
if (! is_dir($tmpdir) && $createifnotexists) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
safe_exec('chown -R ' . $this->_domain['guid'] . ':' . $this->_domain['guid'] . ' ' . escapeshellarg($tmpdir));
|
||||
safe_exec('chmod 0750 ' . escapeshellarg($tmpdir));
|
||||
@@ -216,7 +223,8 @@ class phpinterface_fcgid {
|
||||
*
|
||||
* @return string the directory
|
||||
*/
|
||||
public function getStarterFile() {
|
||||
public function getStarterFile()
|
||||
{
|
||||
$starter_filename = makeCorrectFile($this->getConfigDir() . '/php-fcgi-starter');
|
||||
return $starter_filename;
|
||||
}
|
||||
@@ -226,7 +234,8 @@ class phpinterface_fcgid {
|
||||
*
|
||||
* @return string full with path file-name
|
||||
*/
|
||||
public function getIniFile() {
|
||||
public function getIniFile()
|
||||
{
|
||||
$phpini_filename = makeCorrectFile($this->getConfigDir() . '/php.ini');
|
||||
return $phpini_filename;
|
||||
}
|
||||
@@ -234,19 +243,21 @@ class phpinterface_fcgid {
|
||||
/**
|
||||
* return the admin-data of a specific admin
|
||||
*
|
||||
* @param int $adminid id of the admin-user
|
||||
*
|
||||
* @param int $adminid
|
||||
* id of the admin-user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function _getAdminData($adminid) {
|
||||
|
||||
private function _getAdminData($adminid)
|
||||
{
|
||||
$adminid = intval($adminid);
|
||||
|
||||
if (!isset($this->_admin_cache[$adminid])) {
|
||||
if (! isset($this->_admin_cache[$adminid])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT `email`, `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :id"
|
||||
);
|
||||
$this->_admin_cache[$adminid] = Database::pexecute_first($stmt, array('id' => $adminid));
|
||||
SELECT `email`, `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :id");
|
||||
$this->_admin_cache[$adminid] = Database::pexecute_first($stmt, array(
|
||||
'id' => $adminid
|
||||
));
|
||||
}
|
||||
return $this->_admin_cache[$adminid];
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,17 +12,17 @@
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
*/
|
||||
class phpinterface_fpm
|
||||
class Fpm
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -55,7 +59,7 @@ class phpinterface_fpm
|
||||
*/
|
||||
public function __construct($domain)
|
||||
{
|
||||
if (!isset($domain['fpm_config_id']) || empty($domain['fpm_config_id'])) {
|
||||
if (! isset($domain['fpm_config_id']) || empty($domain['fpm_config_id'])) {
|
||||
$domain['fpm_config_id'] = 1;
|
||||
}
|
||||
$this->_domain = $domain;
|
||||
@@ -89,9 +93,9 @@ class phpinterface_fpm
|
||||
public function createConfig($phpconfig)
|
||||
{
|
||||
$fh = @fopen($this->getConfigFile(), 'w');
|
||||
|
||||
|
||||
if ($fh) {
|
||||
|
||||
|
||||
if ($phpconfig['override_fpmconfig'] == 1) {
|
||||
$this->_fpm_cfg['pm'] = $phpconfig['pm'];
|
||||
$this->_fpm_cfg['max_children'] = $phpconfig['max_children'];
|
||||
@@ -102,7 +106,7 @@ class phpinterface_fpm
|
||||
$this->_fpm_cfg['idle_timeout'] = $phpconfig['idle_timeout'];
|
||||
$this->_fpm_cfg['limit_extensions'] = $phpconfig['limit_extensions'];
|
||||
}
|
||||
|
||||
|
||||
$fpm_pm = $this->_fpm_cfg['pm'];
|
||||
$fpm_children = (int) $this->_fpm_cfg['max_children'];
|
||||
$fpm_start_servers = (int) $this->_fpm_cfg['start_servers'];
|
||||
@@ -111,11 +115,11 @@ class phpinterface_fpm
|
||||
$fpm_requests = (int) $this->_fpm_cfg['max_requests'];
|
||||
$fpm_process_idle_timeout = (int) $this->_fpm_cfg['idle_timeout'];
|
||||
$fpm_limit_extensions = $this->_fpm_cfg['limit_extensions'];
|
||||
|
||||
|
||||
if ($fpm_children == 0) {
|
||||
$fpm_children = 1;
|
||||
}
|
||||
|
||||
|
||||
$fpm_config = ';PHP-FPM configuration for "' . $this->_domain['domain'] . '" created on ' . date("Y.m.d H:i:s") . "\n";
|
||||
$fpm_config .= '[' . $this->_domain['domain'] . ']' . "\n";
|
||||
$fpm_config .= 'listen = ' . $this->getSocketFile() . "\n";
|
||||
@@ -128,7 +132,7 @@ class phpinterface_fpm
|
||||
}
|
||||
// see #1418 why this is 0660
|
||||
$fpm_config .= 'listen.mode = 0660' . "\n";
|
||||
|
||||
|
||||
if ($this->_domain['loginname'] == 'froxlor.panel') {
|
||||
$fpm_config .= 'user = ' . $this->_domain['guid'] . "\n";
|
||||
$fpm_config .= 'group = ' . $this->_domain['guid'] . "\n";
|
||||
@@ -136,10 +140,10 @@ class phpinterface_fpm
|
||||
$fpm_config .= 'user = ' . $this->_domain['loginname'] . "\n";
|
||||
$fpm_config .= 'group = ' . $this->_domain['loginname'] . "\n";
|
||||
}
|
||||
|
||||
|
||||
$fpm_config .= 'pm = ' . $fpm_pm . "\n";
|
||||
$fpm_config .= 'pm.max_children = ' . $fpm_children . "\n";
|
||||
|
||||
|
||||
if ($fpm_pm == 'dynamic') {
|
||||
// honor max_children
|
||||
if ($fpm_children < $fpm_min_spare_servers) {
|
||||
@@ -161,9 +165,9 @@ class phpinterface_fpm
|
||||
} elseif ($fpm_pm == 'ondemand') {
|
||||
$fpm_config .= 'pm.process_idle_timeout = ' . $fpm_process_idle_timeout . "\n";
|
||||
}
|
||||
|
||||
|
||||
$fpm_config .= 'pm.max_requests = ' . $fpm_requests . "\n";
|
||||
|
||||
|
||||
// possible slowlog configs
|
||||
if ($phpconfig['fpm_slowlog'] == '1') {
|
||||
$fpm_config .= 'request_terminate_timeout = ' . $phpconfig['fpm_reqterm'] . "\n";
|
||||
@@ -172,23 +176,23 @@ class phpinterface_fpm
|
||||
$fpm_config .= 'slowlog = ' . $slowlog . "\n";
|
||||
$fpm_config .= 'catch_workers_output = yes' . "\n";
|
||||
}
|
||||
|
||||
|
||||
$fpm_config .= ';chroot = ' . makeCorrectDir($this->_domain['documentroot']) . "\n";
|
||||
$fpm_config .= 'security.limit_extensions = '.$fpm_limit_extensions . "\n";
|
||||
|
||||
$fpm_config .= 'security.limit_extensions = ' . $fpm_limit_extensions . "\n";
|
||||
|
||||
$tmpdir = makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->_domain['loginname'] . '/');
|
||||
if (! is_dir($tmpdir)) {
|
||||
$this->getTempDir();
|
||||
}
|
||||
|
||||
|
||||
$env_path = Settings::Get('phpfpm.envpath');
|
||||
if (!empty($env_path)) {
|
||||
if (! empty($env_path)) {
|
||||
$fpm_config .= 'env[PATH] = ' . $env_path . "\n";
|
||||
}
|
||||
$fpm_config .= 'env[TMP] = ' . $tmpdir . "\n";
|
||||
$fpm_config .= 'env[TMPDIR] = ' . $tmpdir . "\n";
|
||||
$fpm_config .= 'env[TEMP] = ' . $tmpdir . "\n";
|
||||
|
||||
|
||||
$openbasedir = '';
|
||||
if ($this->_domain['loginname'] != 'froxlor.panel') {
|
||||
if ($this->_domain['openbasedir'] == '1') {
|
||||
@@ -197,25 +201,25 @@ class phpinterface_fpm
|
||||
foreach ($_custom_openbasedir as $cobd) {
|
||||
$_phpappendopenbasedir .= appendOpenBasedirPath($cobd);
|
||||
}
|
||||
|
||||
|
||||
$_custom_openbasedir = explode(':', Settings::Get('system.phpappendopenbasedir'));
|
||||
foreach ($_custom_openbasedir as $cobd) {
|
||||
$_phpappendopenbasedir .= appendOpenBasedirPath($cobd);
|
||||
}
|
||||
|
||||
|
||||
if ($this->_domain['openbasedir_path'] == '0' && strstr($this->_domain['documentroot'], ":") === false) {
|
||||
$openbasedir = appendOpenBasedirPath($this->_domain['documentroot'], true);
|
||||
} else {
|
||||
$openbasedir = appendOpenBasedirPath($this->_domain['customerroot'], true);
|
||||
}
|
||||
|
||||
|
||||
$openbasedir .= appendOpenBasedirPath($this->getTempDir());
|
||||
$openbasedir .= $_phpappendopenbasedir;
|
||||
}
|
||||
}
|
||||
$fpm_config .= 'php_admin_value[session.save_path] = ' . makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->_domain['loginname'] . '/') . "\n";
|
||||
$fpm_config .= 'php_admin_value[upload_tmp_dir] = ' . makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->_domain['loginname'] . '/') . "\n";
|
||||
|
||||
|
||||
$admin = $this->_getAdminData($this->_domain['adminid']);
|
||||
$php_ini_variables = array(
|
||||
'SAFE_MODE' => 'Off', // keep this for compatibility, just in case
|
||||
@@ -232,10 +236,10 @@ class phpinterface_fpm
|
||||
'DOCUMENT_ROOT' => makeCorrectDir($this->_domain['documentroot']),
|
||||
'CUSTOMER_HOMEDIR' => makeCorrectDir($this->_domain['customerroot'])
|
||||
);
|
||||
|
||||
|
||||
$phpini = replace_variables($phpconfig['phpsettings'], $php_ini_variables);
|
||||
$phpini_array = explode("\n", $phpini);
|
||||
|
||||
|
||||
$fpm_config .= "\n\n";
|
||||
foreach ($phpini_array as $inisection) {
|
||||
$is = explode("=", $inisection);
|
||||
@@ -249,13 +253,13 @@ class phpinterface_fpm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now check if 'sendmail_path' has not beed set in the custom-php.ini
|
||||
// if not we use our fallback-default as usual
|
||||
if (strpos($fpm_config, 'php_admin_value[sendmail_path]') === false) {
|
||||
$fpm_config .= 'php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f ' . $this->_domain['email'] . "\n";
|
||||
}
|
||||
|
||||
|
||||
fwrite($fh, $fpm_config, strlen($fpm_config));
|
||||
fclose($fh);
|
||||
}
|
||||
@@ -284,11 +288,11 @@ class phpinterface_fpm
|
||||
{
|
||||
$configdir = $this->_fpm_cfg['config_dir'];
|
||||
$config = makeCorrectFile($configdir . '/' . $this->_domain['domain'] . '.conf');
|
||||
|
||||
|
||||
if (! is_dir($configdir) && $createifnotexists) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
}
|
||||
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
@@ -305,12 +309,12 @@ class phpinterface_fpm
|
||||
$socketdir = makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir'));
|
||||
// add fpm-config-id to filename so it's unique for the fpm-daemon and doesn't interfere with running configs when reuilding
|
||||
$socket = strtolower(makeCorrectFile($socketdir . '/' . $this->_domain['fpm_config_id'] . '-' . $this->_domain['loginname'] . '-' . $this->_domain['domain'] . '-php-fpm.socket'));
|
||||
|
||||
|
||||
if (! is_dir($socketdir) && $createifnotexists) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($socketdir));
|
||||
safe_exec('chown -R ' . Settings::Get('system.httpuser') . ':' . Settings::Get('system.httpgroup') . ' ' . escapeshellarg($socketdir));
|
||||
}
|
||||
|
||||
|
||||
return $socket;
|
||||
}
|
||||
|
||||
@@ -325,13 +329,13 @@ class phpinterface_fpm
|
||||
public function getTempDir($createifnotexists = true)
|
||||
{
|
||||
$tmpdir = makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->_domain['loginname'] . '/');
|
||||
|
||||
|
||||
if (! is_dir($tmpdir) && $createifnotexists) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
safe_exec('chown -R ' . $this->_domain['guid'] . ':' . $this->_domain['guid'] . ' ' . escapeshellarg($tmpdir));
|
||||
safe_exec('chmod 0750 ' . escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
|
||||
return $tmpdir;
|
||||
}
|
||||
|
||||
@@ -345,18 +349,18 @@ class phpinterface_fpm
|
||||
*/
|
||||
public function getAliasConfigDir($createifnotexists = true)
|
||||
{
|
||||
|
||||
|
||||
// ensure default...
|
||||
if (Settings::Get('phpfpm.aliasconfigdir') == null) {
|
||||
Settings::Set('phpfpm.aliasconfigdir', '/var/www/php-fpm');
|
||||
}
|
||||
|
||||
|
||||
$configdir = makeCorrectDir(Settings::Get('phpfpm.aliasconfigdir') . '/' . $this->_domain['loginname'] . '/' . $this->_domain['domain'] . '/');
|
||||
if (! is_dir($configdir) && $createifnotexists) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($configdir));
|
||||
safe_exec('chown ' . $this->_domain['guid'] . ':' . $this->_domain['guid'] . ' ' . escapeshellarg($configdir));
|
||||
}
|
||||
|
||||
|
||||
return $configdir;
|
||||
}
|
||||
|
||||
@@ -373,7 +377,7 @@ class phpinterface_fpm
|
||||
}
|
||||
$config = makeCorrectFile($configdir . '/dummy.conf');
|
||||
$dummy = "[dummy]
|
||||
user = ".Settings::Get('system.httpuser')."
|
||||
user = " . Settings::Get('system.httpuser') . "
|
||||
listen = /run/" . md5($configdir) . "-fpm.sock
|
||||
pm = static
|
||||
pm.max_children = 1
|
||||
@@ -392,7 +396,7 @@ pm.max_children = 1
|
||||
private function _getAdminData($adminid)
|
||||
{
|
||||
$adminid = intval($adminid);
|
||||
|
||||
|
||||
if (! isset($this->_admin_cache[$adminid])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT `email`, `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :id");
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http\Php;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,33 +12,36 @@
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
* @since 0.9.16
|
||||
*
|
||||
*/
|
||||
|
||||
class phpinterface {
|
||||
class PhpInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Domain-Data array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_domain = array();
|
||||
|
||||
/**
|
||||
* Interface object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private $_interface = null;
|
||||
|
||||
/**
|
||||
* Admin-User data array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_admin_cache = array();
|
||||
@@ -42,7 +49,8 @@ class phpinterface {
|
||||
/**
|
||||
* main constructor
|
||||
*/
|
||||
public function __construct($domain) {
|
||||
public function __construct($domain)
|
||||
{
|
||||
$this->_domain = $domain;
|
||||
$this->_setInterface();
|
||||
}
|
||||
@@ -51,34 +59,36 @@ class phpinterface {
|
||||
* returns the interface-object
|
||||
* from where we can control it
|
||||
*/
|
||||
public function getInterface() {
|
||||
public function getInterface()
|
||||
{
|
||||
return $this->_interface;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set interface-object by type of
|
||||
* php-interface: fcgid or php-fpm
|
||||
* sets private $_interface variable
|
||||
*/
|
||||
private function _setInterface() {
|
||||
private function _setInterface()
|
||||
{
|
||||
// php-fpm
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$this->_interface = new phpinterface_fpm($this->_domain);
|
||||
|
||||
} elseif ((int)Settings::Get('system.mod_fcgid') == 1) {
|
||||
$this->_interface = new phpinterface_fcgid($this->_domain);
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
$this->_interface = new Fpm($this->_domain);
|
||||
} elseif ((int) Settings::Get('system.mod_fcgid') == 1) {
|
||||
$this->_interface = new Fcgid($this->_domain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the php-configuration from the database
|
||||
*
|
||||
* @param int $php_config_id id of the php-configuration
|
||||
*
|
||||
*
|
||||
* @param int $php_config_id
|
||||
* id of the php-configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPhpConfig($php_config_id) {
|
||||
|
||||
public function getPhpConfig($php_config_id)
|
||||
{
|
||||
$php_config_id = intval($php_config_id);
|
||||
|
||||
// If domain has no config, we will use the default one.
|
||||
@@ -86,20 +96,21 @@ class phpinterface {
|
||||
$php_config_id = 1;
|
||||
}
|
||||
|
||||
if (!isset($this->php_configs_cache[$php_config_id])) {
|
||||
if (! isset($this->php_configs_cache[$php_config_id])) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id"
|
||||
);
|
||||
$this->_php_configs_cache[$php_config_id] = Database::pexecute_first($stmt, array('id' => $php_config_id));
|
||||
if ((int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id");
|
||||
$this->_php_configs_cache[$php_config_id] = Database::pexecute_first($stmt, array(
|
||||
'id' => $php_config_id
|
||||
));
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` WHERE `id` = :id"
|
||||
);
|
||||
$this->_php_configs_cache[$php_config_id]['fpm_settings'] = Database::pexecute_first($stmt, array('id' => $this->_php_configs_cache[$php_config_id]['fpmsettingid']));
|
||||
SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` WHERE `id` = :id");
|
||||
$this->_php_configs_cache[$php_config_id]['fpm_settings'] = Database::pexecute_first($stmt, array(
|
||||
'id' => $this->_php_configs_cache[$php_config_id]['fpmsettingid']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_php_configs_cache[$php_config_id];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,14 +12,14 @@
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.31
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.31
|
||||
*
|
||||
*/
|
||||
class WebserverBase
|
||||
{
|
||||
@@ -43,9 +47,9 @@ class WebserverBase
|
||||
WHERE `d`.`aliasdomain` IS NULL AND `d`.`email_only` <> '1'
|
||||
ORDER BY `d`.`parentdomainid` DESC, `d`.`iswildcarddomain`, `d`.`domain` ASC;
|
||||
";
|
||||
|
||||
|
||||
$result_domains_stmt = Database::query($query);
|
||||
|
||||
|
||||
// prepare IP statement
|
||||
$ip_stmt = Database::prepare("
|
||||
SELECT `di`.`id_domain` , `p`.`ssl`, `p`.`ssl_cert_file`, `p`.`ssl_key_file`, `p`.`ssl_ca_file`, `p`.`ssl_cert_chainfile`
|
||||
@@ -54,17 +58,17 @@ class WebserverBase
|
||||
AND `di`.`id_domain` = :domainid
|
||||
AND `p`.`ssl` = '1'
|
||||
");
|
||||
|
||||
|
||||
// prepare fpm-config select query
|
||||
$fpm_sel_stmt = Database::prepare("
|
||||
SELECT f.id FROM `" . TABLE_PANEL_FPMDAEMONS . "` f
|
||||
LEFT JOIN `" . TABLE_PANEL_PHPCONFIGS . "` p ON p.fpmsettingid = f.id
|
||||
WHERE p.id = :phpconfigid
|
||||
");
|
||||
|
||||
|
||||
$domains = array();
|
||||
while ($domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
// set whole domain
|
||||
$domains[$domain['domain']] = $domain;
|
||||
// set empty-defaults for non-ssl
|
||||
@@ -73,7 +77,7 @@ class WebserverBase
|
||||
$domains[$domain['domain']]['ssl_key_file'] = '';
|
||||
$domains[$domain['domain']]['ssl_ca_file'] = '';
|
||||
$domains[$domain['domain']]['ssl_cert_chainfile'] = '';
|
||||
|
||||
|
||||
// now, if the domain has an ssl ip/port assigned, get
|
||||
// the corresponding information from the db
|
||||
if (domainHasSslIpPort($domain['id'])) {
|
||||
@@ -81,7 +85,7 @@ class WebserverBase
|
||||
$ssl_ip = Database::pexecute_first($ip_stmt, array(
|
||||
'domainid' => $domain['id']
|
||||
));
|
||||
|
||||
|
||||
// set ssl info for domain
|
||||
$domains[$domain['domain']]['ssl'] = '1';
|
||||
$domains[$domain['domain']]['ssl_cert_file'] = $ssl_ip['ssl_cert_file'];
|
||||
@@ -89,7 +93,7 @@ class WebserverBase
|
||||
$domains[$domain['domain']]['ssl_ca_file'] = $ssl_ip['ssl_ca_file'];
|
||||
$domains[$domain['domain']]['ssl_cert_chainfile'] = $ssl_ip['ssl_cert_chainfile'];
|
||||
}
|
||||
|
||||
|
||||
// read fpm-config-id if using fpm
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
|
||||
@@ -104,7 +108,7 @@ class WebserverBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $domains;
|
||||
}
|
||||
}
|
||||
@@ -1,168 +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
|
||||
*
|
||||
*/
|
||||
|
||||
class lighttpd_fcgid extends lighttpd
|
||||
{
|
||||
protected function composePhpOptions($domain)
|
||||
{
|
||||
$php_options_text = '';
|
||||
|
||||
if($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1')
|
||||
{
|
||||
$php = new phpinterface($domain);
|
||||
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);
|
||||
|
||||
// vhost data for php-fpm
|
||||
if((int)Settings::Get('phpfpm.enabled') == 1)
|
||||
{
|
||||
$php_options_text = ' fastcgi.server = ( '."\n";
|
||||
$php_options_text.= "\t".'".php" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"localhost" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"socket" => "'.$php->getInterface()->getSocketFile().'",'."\n";
|
||||
$php_options_text.= "\t\t".'"check-local" => "enable",'."\n";
|
||||
$php_options_text.= "\t\t".'"disable-time" => 1'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
$php_options_text.= ' )'."\n";
|
||||
}
|
||||
// vhost data for fcgid
|
||||
elseif((int)Settings::Get('system.mod_fcgid') == 1)
|
||||
{
|
||||
$php_options_text = ' fastcgi.server = ( '."\n";
|
||||
$file_extensions = explode(' ', $phpconfig['file_extensions']);
|
||||
foreach($file_extensions as $f_extension)
|
||||
{
|
||||
$php_options_text.= "\t".'".'.$f_extension.'" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"localhost" => ('."\n";
|
||||
$php_options_text.= "\t\t".'"socket" => "/var/run/lighttpd/'.$domain['loginname'].'-'.$domain['domain'].'-php.socket",'."\n";
|
||||
$php_options_text.= "\t\t".'"bin-path" => "'.$phpconfig['binary'].' -c '.$php->getInterface()->getIniFile().'",'."\n";
|
||||
$php_options_text.= "\t\t".'"bin-environment" => ('."\n";
|
||||
if((int)$domain['mod_fcgid_starter'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_CHILDREN" => "' . (int)$domain['mod_fcgid_starter'] . '",'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if((int)$phpconfig['mod_fcgid_starter'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_CHILDREN" => "' . (int)$phpconfig['mod_fcgid_starter'] . '",'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_CHILDREN" => "' . (int)Settings::Get('system.mod_fcgid_starter') . '",'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if((int)$domain['mod_fcgid_maxrequests'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_MAX_REQUESTS" => "' . (int)$domain['mod_fcgid_maxrequests'] . '"'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if((int)$phpconfig['mod_fcgid_maxrequests'] != - 1)
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_MAX_REQUESTS" => "' . (int)$phpconfig['mod_fcgid_maxrequests'] . '"'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= "\t\t\t".'"PHP_FCGI_MAX_REQUESTS" => "' . (int)Settings::Get('system.mod_fcgid_maxrequests') . '"'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
$php_options_text.= "\t\t".')'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
$php_options_text.= "\t".')'."\n";
|
||||
|
||||
} // foreach extension
|
||||
$php_options_text.= ' )'."\n";
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
$php_options_text.= ' # PHP is disabled for this vHost' . "\n";
|
||||
}
|
||||
|
||||
return $php_options_text;
|
||||
}
|
||||
|
||||
public function createOwnVhostStarter()
|
||||
{
|
||||
if (Settings::Get('phpfpm.enabled') == '1'
|
||||
&& Settings::Get('phpfpm.enabled_ownvhost') == '1'
|
||||
) {
|
||||
$mypath = makeCorrectDir(dirname(dirname(dirname(__FILE__)))); // /var/www/froxlor, needed for chown
|
||||
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
|
||||
// get fpm config
|
||||
$fpm_sel_stmt = Database::prepare("
|
||||
SELECT f.id FROM `" . TABLE_PANEL_FPMDAEMONS . "` f
|
||||
LEFT JOIN `" . TABLE_PANEL_PHPCONFIGS . "` p ON p.fpmsettingid = f.id
|
||||
WHERE p.id = :phpconfigid
|
||||
");
|
||||
$fpm_config = Database::pexecute_first($fpm_sel_stmt, array(
|
||||
'phpconfigid' => Settings::Get('phpfpm.vhost_defaultini')
|
||||
));
|
||||
|
||||
$domain = array(
|
||||
'id' => 'none',
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'adminid' => 1, /* first admin-user (superadmin) */
|
||||
'mod_fcgid_starter' => -1,
|
||||
'mod_fcgid_maxrequests' => -1,
|
||||
'guid' => $user,
|
||||
'openbasedir' => 0,
|
||||
'email' => Settings::Get('panel.adminmail'),
|
||||
'loginname' => 'froxlor.panel',
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath,
|
||||
'fpm_config_id' => isset($fpm_config['id']) ? $fpm_config['id'] : 1
|
||||
);
|
||||
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($mypath));
|
||||
|
||||
// get php.ini for our own vhost
|
||||
$php = new phpinterface($domain);
|
||||
|
||||
// get php-config
|
||||
if (Settings::Get('phpfpm.enabled') == '1') {
|
||||
// fpm
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('phpfpm.vhost_defaultini'));
|
||||
} else {
|
||||
// fcgid
|
||||
$phpconfig = $php->getPhpConfig(Settings::Get('system.mod_fcgid_defaultini_ownvhost'));
|
||||
}
|
||||
|
||||
// create starter-file | config-file
|
||||
$php->getInterface()->createConfig($phpconfig);
|
||||
|
||||
// create php.ini (fpm does nothing here, as it
|
||||
// defines ini-settings in its pool config)
|
||||
$php->getInterface()->createIniFile($phpconfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
151
lib/Froxlor/Cron/MasterCron.php
Normal file
151
lib/Froxlor/Cron/MasterCron.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\FroxlorLogger;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
{
|
||||
define('MASTER_CRONJOB', 1);
|
||||
|
||||
include_once \Froxlor\Froxlor::getInstallDir() . '/lib/cron_init.php';
|
||||
|
||||
$jobs_to_run = array();
|
||||
|
||||
/**
|
||||
* check for --help
|
||||
*/
|
||||
if (count($argv) < 2 || (isset($argv[1]) && strtolower($argv[1]) == '--help')) {
|
||||
echo "\n*** Froxlor Master Cronjob ***\n\n";
|
||||
echo "Below are possible parameters for this file\n\n";
|
||||
echo "--[cronname]\t\tincludes the given cron-file\n";
|
||||
echo "--force\t\t\tforces re-generating of config-files (webserver, nameserver, etc.)\n";
|
||||
echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n";
|
||||
echo "--no-fork\t\t\tdo not fork to backkground (traffic cron only).\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* check for parameters
|
||||
*
|
||||
* --[cronname] include [cronname]
|
||||
* --force to include cron_tasks even if it's not its turn
|
||||
* --debug to output debug information
|
||||
*/
|
||||
for ($x = 1; $x < count($argv); $x ++) {
|
||||
// check argument
|
||||
if (isset($argv[$x])) {
|
||||
// --force
|
||||
if (strtolower($argv[$x]) == '--force') {
|
||||
// really force re-generating of config-files by
|
||||
// inserting task 1
|
||||
inserttask('1');
|
||||
// bind (if enabled, inserttask() checks this)
|
||||
inserttask('4');
|
||||
// set quotas (if enabled)
|
||||
inserttask('10');
|
||||
// also regenerate cron.d-file
|
||||
inserttask('99');
|
||||
addToQueue($jobs_to_run, 'tasks');
|
||||
} elseif (strtolower($argv[$x]) == '--debug') {
|
||||
define('CRON_DEBUG_FLAG', 1);
|
||||
} elseif (strtolower($argv[$x]) == '--no-fork') {
|
||||
define('CRON_NOFORK_FLAG', 1);
|
||||
} // --[cronname]
|
||||
elseif (substr(strtolower($argv[$x]), 0, 2) == '--') {
|
||||
if (strlen($argv[$x]) > 3) {
|
||||
$cronname = substr(strtolower($argv[$x]), 2);
|
||||
addToQueue($jobs_to_run, $cronname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cronlog->setCronDebugFlag(defined('CRON_DEBUG_FLAG'));
|
||||
|
||||
$tasks_cnt_stmt = \Froxlor\Database\Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt = $tasks_cnt_stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
// do we have anything to include?
|
||||
if (count($jobs_to_run) > 0) {
|
||||
// include all jobs we want to execute
|
||||
foreach ($jobs_to_run as $cron) {
|
||||
self::updateLastRunOfCron($cron);
|
||||
$cronfile = self::getCronModule($cron);
|
||||
if ($cronfile && class_exists($cronfile)) {
|
||||
$cronfile::run();
|
||||
}
|
||||
}
|
||||
|
||||
if ($tasks_cnt['jobcnt'] > 0) {
|
||||
if (\Froxlor\Settings::Get('system.nssextrausers') == 1) {
|
||||
\Froxlor\Cron\System\Extrausers::generateFiles($cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570
|
||||
if (\Froxlor\Settings::Get('system.mod_fcgid') == 1 || (int) \Froxlor\Settings::Get('phpfpm.enabled') == 1) {
|
||||
$false_val = false;
|
||||
\Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array(
|
||||
'>'
|
||||
));
|
||||
\Froxlor\FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, array(
|
||||
'>'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* we have to check the system's last guid with every cron run
|
||||
* in case the admin installed new software which added a new user
|
||||
* so users in the database don't conflict with system users
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Checking system\'s last guid');
|
||||
checkLastGuid();
|
||||
|
||||
// shutdown cron
|
||||
include_once \Froxlor\Froxlor::getInstallDir() . '/lib/cron_shutdown.php';
|
||||
}
|
||||
|
||||
private 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
|
||||
));
|
||||
}
|
||||
|
||||
private static function getCronModule($cronname)
|
||||
{
|
||||
$upd_stmt = Database::prepare("
|
||||
SELECT `cronclass` FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `cronfile` = :cron;
|
||||
");
|
||||
$cron = Database::pexecute_first($upd_stmt, array(
|
||||
'cron' => $cronname
|
||||
));
|
||||
if ($cron) {
|
||||
return $cron['cronclass'];
|
||||
}
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_ERROR, "Requested cronjob '" . $cronname . "' could not be found.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
use \Froxlor\FroxlorLogger;
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\FroxlorLogger;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -96,7 +96,7 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($row['data']['destdir']));
|
||||
}
|
||||
|
||||
createCustomerBackup($row['data'], $customerdocroot, FroxlorLogger::getInstanceOf());
|
||||
self::createCustomerBackup($row['data'], $customerdocroot, FroxlorLogger::getInstanceOf());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,4 +111,112 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* depending on the give choice, the customers web-data, email-data and databases are being backup'ed
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
private static function createCustomerBackup($data = null, $customerdocroot = null, &$cronlog)
|
||||
{
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating Backup for user "' . $data['loginname'] . '"');
|
||||
|
||||
// create tmp folder
|
||||
$tmpdir = makeCorrectDir($data['destdir'] . '/.tmp/');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating tmp-folder "' . $tmpdir . '"');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
$create_backup_tar_data = "";
|
||||
|
||||
// MySQL databases
|
||||
if ($data['backup_dbs'] == 1) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating mysql-folder "' . \Froxlor\FileDir::makeCorrectDir($tmpdir . '/mysql') . '"');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mysql')));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mysql')));
|
||||
|
||||
// get all customer database-names
|
||||
$sel_stmt = Database::prepare("SELECT `databasename` FROM `" . TABLE_PANEL_DATABASES . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($sel_stmt, array(
|
||||
'cid' => $data['customerid']
|
||||
));
|
||||
|
||||
Database::needRoot(true);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
|
||||
$has_dbs = false;
|
||||
while ($row = $sel_stmt->fetch()) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -pXXXXX ' . $row['databasename'] . ' > ' . \Froxlor\FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'));
|
||||
$bool_false = false;
|
||||
\Froxlor\FileDir::safe_exec('mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -p' . $sql_root['passwd'] . ' ' . $row['databasename'] . ' > ' . \Froxlor\FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'), $bool_false, array(
|
||||
'>'
|
||||
));
|
||||
$has_dbs = true;
|
||||
}
|
||||
|
||||
if ($has_dbs) {
|
||||
$create_backup_tar_data .= './mysql ';
|
||||
}
|
||||
|
||||
unset($sql_root);
|
||||
}
|
||||
|
||||
// E-mail data
|
||||
if ($data['backup_mail'] == 1) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating mail-folder "' . \Froxlor\FileDir::makeCorrectDir($tmpdir . '/mail') . '"');
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir($tmpdir . '/mail')));
|
||||
|
||||
// get all customer mail-accounts
|
||||
$sel_stmt = Database::prepare("SELECT `homedir`, `maildir` FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($sel_stmt, array(
|
||||
'cid' => $data['customerid']
|
||||
));
|
||||
|
||||
$tar_file_list = "";
|
||||
$mail_homedir = "";
|
||||
while ($row = $sel_stmt->fetch()) {
|
||||
$tar_file_list .= escapeshellarg("./" . $row['maildir']) . " ";
|
||||
$mail_homedir = $row['homedir'];
|
||||
}
|
||||
|
||||
if (! empty($tar_file_list)) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
\Froxlor\FileDir::safe_exec('tar cfz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
$create_backup_tar_data .= './mail ';
|
||||
}
|
||||
}
|
||||
|
||||
// Web data
|
||||
if ($data['backup_web'] == 1) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating web-folder "' . \Froxlor\FileDir::makeCorrectDir($tmpdir . '/web') . '"');
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(\Froxlor\FileDir::makeCorrectDir($tmpdir . '/web')));
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", \Froxlor\FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(\Froxlor\FileDir::makeCorrectDir($tmpdir), 0, - 1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
\Froxlor\FileDir::safe_exec('tar cfz ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", \Froxlor\FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(\Froxlor\FileDir::makeCorrectFile($tmpdir), 0, - 1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
$create_backup_tar_data .= './web ';
|
||||
}
|
||||
|
||||
if (! empty($create_backup_tar_data)) {
|
||||
$backup_file = \Froxlor\FileDir::makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-backup_' . date('YmdHi', time()) . '.tar.gz');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating backup-file "' . $backup_file . '"');
|
||||
// pack all archives in tmp-dir to one
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
\Froxlor\FileDir::safe_exec('tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
// move to destination directory
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
\Froxlor\FileDir::safe_exec('mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
// remove tmp-files
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> rm -rf ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($tmpdir));
|
||||
// set owner to customer
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> chown -R ' . (int) $data['uid'] . ':' . (int) $data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . (int) $data['uid'] . ':' . (int) $data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Froxlor\Cron\System;
|
||||
* @since 0.9.29.1
|
||||
*
|
||||
*/
|
||||
class MailboxSizeCron extends \Froxlor\Cron\FroxlorCron
|
||||
class MailboxsizeCron extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
433
lib/Froxlor/Cron/System/TasksCron.php
Normal file
433
lib/Froxlor/Cron/System/TasksCron.php
Normal file
@@ -0,0 +1,433 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
{
|
||||
/**
|
||||
* LOOK INTO TASKS TABLE TO SEE IF THERE ARE ANY UNDONE JOBS
|
||||
*/
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, "TasksCron: Searching for tasks to do");
|
||||
// no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `id` ASC
|
||||
");
|
||||
$num_results = Database::num_rows();
|
||||
$resultIDs = array();
|
||||
|
||||
while ($row = $result_tasks_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
$resultIDs[] = $row['id'];
|
||||
|
||||
if ($row['data'] != '') {
|
||||
$row['data'] = json_decode($row['data'], true);
|
||||
}
|
||||
|
||||
if ($row['type'] == '1') {
|
||||
/**
|
||||
* TYPE=1 MEANS TO REBUILD APACHE VHOSTS.CONF
|
||||
*/
|
||||
self::rebuildWebserverConfigs();
|
||||
} elseif ($row['type'] == '2') {
|
||||
/**
|
||||
* TYPE=2 MEANS TO CREATE A NEW HOME AND CHOWN
|
||||
*/
|
||||
self::createNewHome($row);
|
||||
} elseif ($row['type'] == '4' && (int) Settings::Get('system.bind_enable') != 0) {
|
||||
/**
|
||||
* TYPE=4 MEANS THAT SOMETHING IN THE BIND CONFIG HAS CHANGED.
|
||||
* REBUILD froxlor_bind.conf IF BIND IS ENABLED
|
||||
*/
|
||||
self::rebuildDnsConfigs();
|
||||
} elseif ($row['type'] == '5') {
|
||||
/**
|
||||
* TYPE=5 MEANS THAT A NEW FTP-ACCOUNT HAS BEEN CREATED, CREATE THE DIRECTORY
|
||||
*/
|
||||
self::createNewFtpHome($row);
|
||||
} elseif ($row['type'] == '6') {
|
||||
/**
|
||||
* TYPE=6 MEANS THAT A CUSTOMER HAS BEEN DELETED AND THAT WE HAVE TO REMOVE ITS FILES
|
||||
*/
|
||||
self::deleteCustomerData($row);
|
||||
} elseif ($row['type'] == '7') {
|
||||
/**
|
||||
* TYPE=7 Customer deleted an email account and wants the data to be deleted on the filesystem
|
||||
*/
|
||||
self::deleteEmailData($row);
|
||||
} elseif ($row['type'] == '8') {
|
||||
/**
|
||||
* TYPE=8 Customer deleted a ftp account and wants the homedir to be deleted on the filesystem
|
||||
* refs #293
|
||||
*/
|
||||
self::deleteFtpData($row);
|
||||
} elseif ($row['type'] == '10' && (int) Settings::Get('system.diskquota_enabled') != 0) {
|
||||
/**
|
||||
* TYPE=10 Set the filesystem - quota
|
||||
*/
|
||||
self::setFilesystemQuota();
|
||||
} elseif ($row['type'] == '11' && Settings::Get('system.dns_server') == 'PowerDNS') {
|
||||
/**
|
||||
* TYPE=11 domain has been deleted, remove from pdns database if used
|
||||
*/
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']);
|
||||
\Froxlor\Dns\PowerDNS::cleanDomainZone($row['data']['domain']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($num_results != 0) {
|
||||
$where = array();
|
||||
$where_data = array();
|
||||
foreach ($resultIDs as $id) {
|
||||
$where[] = "`id` = :id_" . (int) $id;
|
||||
$where_data['id_' . $id] = $id;
|
||||
}
|
||||
$where = implode($where, ' OR ');
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE " . $where);
|
||||
Database::pexecute($del_stmt, $where_data);
|
||||
unset($resultIDs);
|
||||
unset($where);
|
||||
}
|
||||
|
||||
Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = 'system' AND `varname` = 'last_tasks_run';");
|
||||
}
|
||||
|
||||
private static function rebuildWebserverConfigs()
|
||||
{
|
||||
// get configuration-I/O object
|
||||
$configio = new \Froxlor\Cron\Http\ConfigIO();
|
||||
// clean up old configs
|
||||
$configio->cleanUp();
|
||||
|
||||
if (Settings::Get('system.webserver') == "apache2") {
|
||||
$websrv = '\\Froxlor\\Cron\\Http\\Apache';
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= 'Fcgi';
|
||||
}
|
||||
} elseif (Settings::Get('system.webserver') == "lighttpd") {
|
||||
$websrv = '\\Froxlor\\Cron\\Http\\Lighttpd';
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= 'Fcgi';
|
||||
}
|
||||
} elseif (Settings::Get('system.webserver') == "nginx") {
|
||||
$websrv = '\\Froxlor\\Cron\\Http\\Nginx';
|
||||
if (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= 'Fcgi';
|
||||
}
|
||||
}
|
||||
|
||||
$webserver = new $websrv();
|
||||
|
||||
if (isset($webserver)) {
|
||||
$webserver->createIpPort();
|
||||
$webserver->createVirtualHosts();
|
||||
$webserver->createFileDirOptions();
|
||||
$webserver->writeConfigs();
|
||||
$webserver->createOwnVhostStarter();
|
||||
$webserver->reload();
|
||||
} else {
|
||||
echo "Please check you Webserver settings\n";
|
||||
}
|
||||
|
||||
// if we use php-fpm and have a local user for froxlor, we need to
|
||||
// add the webserver-user to the local-group in order to allow the webserver
|
||||
// to access the fpm-socket
|
||||
if (Settings::Get('phpfpm.enabled') == 1 && function_exists("posix_getgrnam")) {
|
||||
// get group info about the local-user's group (e.g. froxlorlocal)
|
||||
$groupinfo = posix_getgrnam(Settings::Get('phpfpm.vhost_httpgroup'));
|
||||
// check group members
|
||||
if (isset($groupinfo['members']) && ! in_array(Settings::Get('system.httpuser'), $groupinfo['members'])) {
|
||||
// webserver has no access, add it
|
||||
if (isFreeBSD()) {
|
||||
\Froxlor\FileDir::safe_exec('pw usermod ' . escapeshellarg(Settings::Get('system.httpuser')) . ' -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')));
|
||||
} else {
|
||||
\Froxlor\FileDir::safe_exec('usermod -a -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')) . ' ' . escapeshellarg(Settings::Get('system.httpuser')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the Let's Encrypt cron it's okay to generate the certificate and enable the redirect afterwards
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '3' WHERE `ssl_redirect` = '2'");
|
||||
Database::pexecute($upd_stmt);
|
||||
}
|
||||
|
||||
private static function createNewHome($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, 'TasksCron: Task2 started - create new home');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
// define paths
|
||||
$userhomedir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
$usermaildir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
// stats directory
|
||||
if (Settings::Get('system.awstats_enabled') == '1') {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
// in case we changed from the other stats -> remove old
|
||||
// (yes i know, the stats are lost - that's why you should not change all the time!)
|
||||
if (file_exists($userhomedir . 'webalizer')) {
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
}
|
||||
} else {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
// in case we changed from the other stats -> remove old
|
||||
// (yes i know, the stats are lost - that's why you should not change all the time!)
|
||||
if (file_exists($userhomedir . 'awstats')) {
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
}
|
||||
}
|
||||
|
||||
// maildir
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir));
|
||||
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($usermaildir));
|
||||
|
||||
// check if admin of customer has added template for new customer directories
|
||||
if ((int) $row['data']['store_defaultindex'] == 1) {
|
||||
storeDefaultIndex($row['data']['loginname'], $userhomedir, \Froxlor\FroxlorLogger::getInstanceOf(), true);
|
||||
}
|
||||
|
||||
// strip of last slash of paths to have correct chown results
|
||||
$userhomedir = (substr($userhomedir, 0, - 1) == '/') ? substr($userhomedir, 0, - 1) : $userhomedir;
|
||||
$usermaildir = (substr($usermaildir, 0, - 1) == '/') ? substr($usermaildir, 0, - 1) : $usermaildir;
|
||||
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int) $row['data']['uid'] . ':' . (int) $row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . (int) $row['data']['uid'] . ':' . (int) $row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
// don't allow others to access the directory (webserver will be the group via libnss-mysql)
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
// fcgid or fpm
|
||||
\Froxlor\FileDir::safe_exec('chmod 0750 ' . escapeshellarg($userhomedir));
|
||||
} else {
|
||||
// mod_php -> no libnss-mysql -> no webserver-user in group
|
||||
\Froxlor\FileDir::safe_exec('chmod 0755 ' . escapeshellarg($userhomedir));
|
||||
}
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int) Settings::Get('system.vmail_uid') . ':' . (int) Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . (int) Settings::Get('system.vmail_uid') . ':' . (int) Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
|
||||
if (Settings::Get('system.nssextrausers') == 1) {
|
||||
// explicitly create files after user has been created to avoid unknown user issues for apache/php-fpm when task#1 runs after this
|
||||
Extrausers::generateFiles(\Froxlor\FroxlorLogger::getInstanceOf());
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
$false_val = false;
|
||||
\Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array(
|
||||
'>'
|
||||
));
|
||||
\Froxlor\FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, array(
|
||||
'>'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function rebuildDnsConfigs()
|
||||
{
|
||||
$dnssrv = '\\Froxlor\\Cron\\Dns\\' . Settings::Get('system.dns_server');
|
||||
|
||||
$nameserver = new $dnssrv(\Froxlor\FroxlorLogger::getInstanceOf());
|
||||
|
||||
if (Settings::Get('dkim.use_dkim') == '1') {
|
||||
$nameserver->writeDKIMconfigs();
|
||||
}
|
||||
|
||||
$nameserver->writeConfigs();
|
||||
}
|
||||
|
||||
private static function createNewFtpHome($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, 'Creating new FTP-home');
|
||||
$result_directories_stmt = Database::query("
|
||||
SELECT `f`.`homedir`, `f`.`uid`, `f`.`gid`, `c`.`documentroot` AS `customerroot`
|
||||
FROM `" . TABLE_FTP_USERS . "` `f` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING (`customerid`)
|
||||
");
|
||||
|
||||
while ($directory = $result_directories_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
\Froxlor\FileDir::mkDirWithCorrectOwnership($directory['customerroot'], $directory['homedir'], $directory['uid'], $directory['gid']);
|
||||
}
|
||||
}
|
||||
|
||||
private static function deleteCustomerData($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, 'TasksCron: Task6 started - deleting customer data');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
if (isset($row['data']['loginname'])) {
|
||||
// remove homedir
|
||||
$homedir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($homedir) && $homedir != '/' && $homedir != Settings::Get('system.documentroot_prefix') && substr($homedir, 0, strlen(Settings::Get('system.documentroot_prefix'))) == Settings::Get('system.documentroot_prefix')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($homedir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($homedir));
|
||||
}
|
||||
|
||||
// remove maildir
|
||||
$maildir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($maildir) && $maildir != '/' && $maildir != Settings::Get('system.vmail_homedir') && substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir), $return, array(
|
||||
'|',
|
||||
'&',
|
||||
'`',
|
||||
'$',
|
||||
'?'
|
||||
));
|
||||
}
|
||||
|
||||
// remove tmpdir if it exists
|
||||
$tmpdir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
if (file_exists($tmpdir) && is_dir($tmpdir) && $tmpdir != "/" && $tmpdir != Settings::Get('system.mod_fcgid_tmpdir') && substr($tmpdir, 0, strlen(Settings::Get('system.mod_fcgid_tmpdir'))) == Settings::Get('system.mod_fcgid_tmpdir')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($tmpdir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
// webserver logs
|
||||
$logsdir = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.logfiles_directory') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($logsdir) && $logsdir != '/' && $logsdir != \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.logfiles_directory')) && substr($logsdir, 0, strlen(Settings::Get('system.logfiles_directory'))) == Settings::Get('system.logfiles_directory')) {
|
||||
// build up wildcard for webX-{access,error}.log{*}
|
||||
$logfiles .= '-*';
|
||||
\Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg($logfiles));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function deleteEmailData($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, 'TasksCron: Task7 started - deleting customer e-mail data');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['loginname']) && isset($row['data']['email'])) {
|
||||
// remove specific maildir
|
||||
$email_full = $row['data']['email'];
|
||||
if (empty($email_full)) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_ERROR, 'FATAL: Task7 asks to delete a email account but email field is empty!');
|
||||
}
|
||||
$email_user = substr($email_full, 0, strrpos($email_full, "@"));
|
||||
$email_domain = substr($email_full, strrpos($email_full, "@") + 1);
|
||||
$maildirname = trim(Settings::Get('system.vmail_maildirname'));
|
||||
// Add trailing slash to Maildir if needed
|
||||
$maildirpath = $maildirname;
|
||||
if (! empty($maildirname) and substr($maildirname, - 1) != "/") {
|
||||
$maildirpath .= "/";
|
||||
}
|
||||
|
||||
$maildir = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $email_domain . '/' . $email_user);
|
||||
|
||||
if ($maildir != '/' && ! empty($maildir) && ! empty($email_full) && $maildir != Settings::Get('system.vmail_homedir') && substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir) && is_dir(\Froxlor\FileDir::makeCorrectDir($maildir . '/' . $maildirpath)) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir), $return, array(
|
||||
'|',
|
||||
'&',
|
||||
'`',
|
||||
'$',
|
||||
'~',
|
||||
'?'
|
||||
));
|
||||
} else {
|
||||
// backward-compatibility for old folder-structure
|
||||
$maildir_old = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $row['data']['email']);
|
||||
|
||||
if ($maildir_old != '/' && ! empty($maildir_old) && $maildir_old != Settings::Get('system.vmail_homedir') && substr($maildir_old, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir_old) && fileowner($maildir_old) == Settings::Get('system.vmail_uid') && filegroup($maildir_old) == Settings::Get('system.vmail_gid')) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir_old));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir_old), $return, array(
|
||||
'|',
|
||||
'&',
|
||||
'`',
|
||||
'$',
|
||||
'~',
|
||||
'?'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function deleteFtpData($row = null)
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, 'TasksCron: Task8 started - deleting customer ftp homedir');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['loginname']) && isset($row['data']['homedir'])) {
|
||||
// remove specific homedir
|
||||
$ftphomedir = \Froxlor\FileDir::makeCorrectDir($row['data']['homedir']);
|
||||
$customerdocroot = \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
if (file_exists($ftphomedir) && $ftphomedir != '/' && $ftphomedir != Settings::Get('system.documentroot_prefix') && $ftphomedir != $customerdocroot) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($ftphomedir));
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . escapeshellarg($ftphomedir));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function setFilesystemQuota()
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, 'TasksCron: Task10 started - setting filesystem quota');
|
||||
|
||||
// @fixme
|
||||
$usedquota = getFilesystemQuota();
|
||||
|
||||
// Check whether we really have entries to check
|
||||
if (is_array($usedquota) && count($usedquota) > 0) {
|
||||
// Select all customers Froxlor knows about
|
||||
$result_stmt = Database::query("SELECT `guid`, `loginname`, `diskspace` FROM `" . TABLE_PANEL_CUSTOMERS . "`;");
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// We do not want to set a quota for root by accident
|
||||
if ($row['guid'] != 0) {
|
||||
// The user has no quota in Froxlor, but on the filesystem
|
||||
if (($row['diskspace'] == 0 || $row['diskspace'] == - 1024) && $usedquota[$row['guid']]['block']['hard'] != 0) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']);
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":0:0 " . $row['guid']);
|
||||
} else {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
} // The user quota in Froxlor is different than on the filesystem
|
||||
elseif ($row['diskspace'] != $usedquota[$row['guid']]['block']['hard'] && $row['diskspace'] != - 1024) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $usedquota[$row['guid']]['block']['hard'] . " to " . $row['diskspace']);
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":" . $row['diskspace'] . ":" . $row['diskspace'] . " " . $row['guid']);
|
||||
} else {
|
||||
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl " . $row['diskspace'] . " -q " . $row['diskspace'] . " " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,445 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
// necessary includes
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.dns.10.bind.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.dns.20.pdns.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.10.apache.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.15.apache_fcgid.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.20.lighttpd.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.25.lighttpd_fcgid.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.30.nginx.php');
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.35.nginx_phpfpm.php');
|
||||
|
||||
/**
|
||||
* LOOK INTO TASKS TABLE TO SEE IF THERE ARE ANY UNDONE JOBS
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "cron_tasks: Searching for tasks to do");
|
||||
// no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `id` ASC
|
||||
");
|
||||
$num_results = Database::num_rows();
|
||||
$resultIDs = array();
|
||||
|
||||
while ($row = $result_tasks_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$resultIDs[] = $row['id'];
|
||||
|
||||
if ($row['data'] != '') {
|
||||
$row['data'] = json_decode($row['data'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=1 MEANS TO REBUILD APACHE VHOSTS.CONF
|
||||
*/
|
||||
if ($row['type'] == '1') {
|
||||
|
||||
// get configuration-I/O object
|
||||
$configio = new ConfigIO();
|
||||
// clean up old configs
|
||||
$configio->cleanUp();
|
||||
|
||||
if (!isset($webserver)) {
|
||||
if (Settings::Get('system.webserver') == "apache2") {
|
||||
$websrv = 'apache';
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= '_fcgid';
|
||||
}
|
||||
} elseif (Settings::Get('system.webserver') == "lighttpd") {
|
||||
$websrv = 'lighttpd';
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= '_fcgid';
|
||||
}
|
||||
} elseif (Settings::Get('system.webserver') == "nginx") {
|
||||
$websrv = 'nginx';
|
||||
if (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$websrv .= '_phpfpm';
|
||||
}
|
||||
}
|
||||
|
||||
$webserver = new $websrv($cronlog, $idna_convert);
|
||||
}
|
||||
|
||||
if (isset($webserver)) {
|
||||
$webserver->createIpPort();
|
||||
$webserver->createVirtualHosts();
|
||||
$webserver->createFileDirOptions();
|
||||
$webserver->writeConfigs();
|
||||
$webserver->createOwnVhostStarter();
|
||||
$webserver->reload();
|
||||
} else {
|
||||
echo "Please check you Webserver settings\n";
|
||||
}
|
||||
|
||||
// if we use php-fpm and have a local user for froxlor, we need to
|
||||
// add the webserver-user to the local-group in order to allow the webserver
|
||||
// to access the fpm-socket
|
||||
if (Settings::Get('phpfpm.enabled') == 1 && function_exists("posix_getgrnam")) {
|
||||
// get group info about the local-user's group (e.g. froxlorlocal)
|
||||
$groupinfo = posix_getgrnam(Settings::Get('phpfpm.vhost_httpgroup'));
|
||||
// check group members
|
||||
if (isset($groupinfo['members'])
|
||||
&& !in_array(Settings::Get('system.httpuser'), $groupinfo['members'])
|
||||
) {
|
||||
// webserver has no access, add it
|
||||
if (isFreeBSD()) {
|
||||
safe_exec('pw usermod '.escapeshellarg(Settings::Get('system.httpuser')).' -G '.escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')));
|
||||
} else {
|
||||
safe_exec('usermod -a -G ' . escapeshellarg(Settings::Get('phpfpm.vhost_httpgroup')).' '.escapeshellarg(Settings::Get('system.httpuser')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the Let's Encrypt cron it's okay to generate the certificate and enable the redirect afterwards
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '3' WHERE `ssl_redirect` = '2'");
|
||||
Database::pexecute($upd_stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=2 MEANS TO CREATE A NEW HOME AND CHOWN
|
||||
*/
|
||||
elseif ($row['type'] == '2') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task2 started - create new home');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
// define paths
|
||||
$userhomedir = makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname'] . '/');
|
||||
$usermaildir = makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
// stats directory
|
||||
if (Settings::Get('system.awstats_enabled') == '1') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
// in case we changed from the other stats -> remove old
|
||||
// (yes i know, the stats are lost - that's why you should not change all the time!)
|
||||
if (file_exists($userhomedir . 'webalizer')) {
|
||||
safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
}
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||
// in case we changed from the other stats -> remove old
|
||||
// (yes i know, the stats are lost - that's why you should not change all the time!)
|
||||
if (file_exists($userhomedir . 'awstats')) {
|
||||
safe_exec('rm -rf ' . escapeshellarg($userhomedir . 'awstats'));
|
||||
}
|
||||
}
|
||||
|
||||
// maildir
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir));
|
||||
safe_exec('mkdir -p ' . escapeshellarg($usermaildir));
|
||||
|
||||
//check if admin of customer has added template for new customer directories
|
||||
if ((int)$row['data']['store_defaultindex'] == 1) {
|
||||
storeDefaultIndex($row['data']['loginname'], $userhomedir, $cronlog, true);
|
||||
}
|
||||
|
||||
// strip of last slash of paths to have correct chown results
|
||||
$userhomedir = (substr($userhomedir, 0, -1) == '/') ? substr($userhomedir, 0, -1) : $userhomedir;
|
||||
$usermaildir = (substr($usermaildir, 0, -1) == '/') ? substr($usermaildir, 0, -1) : $usermaildir;
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)$row['data']['uid'] . ':' . (int)$row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
safe_exec('chown -R ' . (int)$row['data']['uid'] . ':' . (int)$row['data']['gid'] . ' ' . escapeshellarg($userhomedir));
|
||||
// don't allow others to access the directory (webserver will be the group via libnss-mysql)
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) {
|
||||
// fcgid or fpm
|
||||
safe_exec('chmod 0750 ' . escapeshellarg($userhomedir));
|
||||
} else {
|
||||
// mod_php -> no libnss-mysql -> no webserver-user in group
|
||||
safe_exec('chmod 0755 ' . escapeshellarg($userhomedir));
|
||||
}
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: chown -R ' . (int)Settings::Get('system.vmail_uid') . ':' . (int)Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
safe_exec('chown -R ' . (int)Settings::Get('system.vmail_uid') . ':' . (int)Settings::Get('system.vmail_gid') . ' ' . escapeshellarg($usermaildir));
|
||||
|
||||
if (Settings::Get('system.nssextrausers') == 1)
|
||||
{
|
||||
// explicitly create files after user has been created to avoid unknown user issues for apache/php-fpm when task#1 runs after this
|
||||
include_once makeCorrectFile(\Froxlor\Froxlor::getInstallDir().'/scripts/classes/class.Extrausers.php');
|
||||
Extrausers::generateFiles($cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570
|
||||
if (Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
$false_val = false;
|
||||
safe_exec('nscd -i passwd 1> /dev/null', $false_val, array('>'));
|
||||
safe_exec('nscd -i group 1> /dev/null', $false_val, array('>'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=4 MEANS THAT SOMETHING IN THE BIND CONFIG HAS CHANGED. REBUILD froxlor_bind.conf IF BIND IS ENABLED
|
||||
*/
|
||||
elseif ($row['type'] == '4' && (int)Settings::Get('system.bind_enable') != 0) {
|
||||
|
||||
$dnssrv = Settings::Get('system.dns_server');
|
||||
|
||||
if (!isset($nameserver)) {
|
||||
$nameserver = new $dnssrv($cronlog);
|
||||
}
|
||||
|
||||
if (Settings::Get('dkim.use_dkim') == '1') {
|
||||
$nameserver->writeDKIMconfigs();
|
||||
}
|
||||
|
||||
$nameserver->writeConfigs();
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=5 MEANS THAT A NEW FTP-ACCOUNT HAS BEEN CREATED, CREATE THE DIRECTORY
|
||||
*/
|
||||
elseif ($row['type'] == '5') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating new FTP-home');
|
||||
$result_directories_stmt = Database::query("
|
||||
SELECT `f`.`homedir`, `f`.`uid`, `f`.`gid`, `c`.`documentroot` AS `customerroot`
|
||||
FROM `" . TABLE_FTP_USERS . "` `f` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING (`customerid`)
|
||||
");
|
||||
|
||||
while ($directory = $result_directories_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
mkDirWithCorrectOwnership($directory['customerroot'], $directory['homedir'], $directory['uid'], $directory['gid']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=6 MEANS THAT A CUSTOMER HAS BEEN DELETED AND THAT WE HAVE TO REMOVE ITS FILES
|
||||
*/
|
||||
elseif ($row['type'] == '6') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task6 started - deleting customer data');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
if (isset($row['data']['loginname'])) {
|
||||
// remove homedir
|
||||
$homedir = makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($homedir)
|
||||
&& $homedir != '/'
|
||||
&& $homedir != Settings::Get('system.documentroot_prefix')
|
||||
&& substr($homedir, 0, strlen(Settings::Get('system.documentroot_prefix'))) == Settings::Get('system.documentroot_prefix')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($homedir));
|
||||
safe_exec('rm -rf '.escapeshellarg($homedir));
|
||||
}
|
||||
|
||||
// remove maildir
|
||||
$maildir = makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname']);
|
||||
|
||||
if (file_exists($maildir)
|
||||
&& $maildir != '/'
|
||||
&& $maildir != Settings::Get('system.vmail_homedir')
|
||||
&& substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir')
|
||||
&& is_dir($maildir)
|
||||
&& fileowner($maildir) == Settings::Get('system.vmail_uid')
|
||||
&& filegroup($maildir) == Settings::Get('system.vmail_gid')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
safe_exec('rm -rf '.escapeshellarg($maildir), $return, array('|', '&', '`', '$', '~', '?'));
|
||||
}
|
||||
|
||||
// remove tmpdir if it exists
|
||||
$tmpdir = makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir') . '/' . $row['data']['loginname'] . '/');
|
||||
|
||||
if (file_exists($tmpdir)
|
||||
&& is_dir($tmpdir)
|
||||
&& $tmpdir != "/"
|
||||
&& $tmpdir != Settings::Get('system.mod_fcgid_tmpdir')
|
||||
&& substr($tmpdir, 0, strlen(Settings::Get('system.mod_fcgid_tmpdir'))) == Settings::Get('system.mod_fcgid_tmpdir')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($tmpdir));
|
||||
safe_exec('rm -rf '.escapeshellarg($tmpdir));
|
||||
}
|
||||
|
||||
// webserver logs
|
||||
$logsdir = makeCorrectFile(Settings::Get('system.logfiles_directory').'/'.$row['data']['loginname']);
|
||||
|
||||
if (file_exists($logsdir)
|
||||
&& $logsdir != '/'
|
||||
&& $logsdir != makeCorrectDir(Settings::Get('system.logfiles_directory'))
|
||||
&& substr($logsdir, 0, strlen(Settings::Get('system.logfiles_directory'))) == Settings::Get('system.logfiles_directory')
|
||||
) {
|
||||
// build up wildcard for webX-{access,error}.log{*}
|
||||
$logfiles .= '-*';
|
||||
safe_exec('rm -f '.escapeshellarg($logfiles));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=7 Customer deleted an email account and wants the data to be deleted on the filesystem
|
||||
*/
|
||||
elseif ($row['type'] == '7') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task7 started - deleting customer e-mail data');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['loginname'])
|
||||
&& isset($row['data']['email'])
|
||||
) {
|
||||
// remove specific maildir
|
||||
$email_full = $row['data']['email'];
|
||||
if (empty($email_full)) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_ERROR, 'FATAL: Task7 asks to delete a email account but email field is empty!');
|
||||
}
|
||||
$email_user = substr($email_full,0,strrpos($email_full,"@"));
|
||||
$email_domain = substr($email_full,strrpos($email_full,"@")+1);
|
||||
$maildirname = trim(Settings::Get('system.vmail_maildirname'));
|
||||
// Add trailing slash to Maildir if needed
|
||||
$maildirpath = $maildirname;
|
||||
if (!empty($maildirname) and substr($maildirname,-1) != "/") {
|
||||
$maildirpath .= "/";
|
||||
}
|
||||
|
||||
$maildir = makeCorrectDir(Settings::Get('system.vmail_homedir') .'/'. $row['data']['loginname'] .'/'. $email_domain .'/'. $email_user);
|
||||
|
||||
if ($maildir != '/'
|
||||
&& !empty($maildir)
|
||||
&& !empty($email_full)
|
||||
&& $maildir != Settings::Get('system.vmail_homedir')
|
||||
&& substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir')
|
||||
&& is_dir($maildir)
|
||||
&& is_dir(makeCorrectDir($maildir.'/'.$maildirpath))
|
||||
&& fileowner($maildir) == Settings::Get('system.vmail_uid')
|
||||
&& filegroup($maildir) == Settings::Get('system.vmail_gid')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
safe_exec('rm -rf '.escapeshellarg($maildir), $return, array('|', '&', '`', '$', '~', '?'));
|
||||
|
||||
} else {
|
||||
// backward-compatibility for old folder-structure
|
||||
$maildir_old = makeCorrectDir(Settings::Get('system.vmail_homedir') .'/'. $row['data']['loginname'] .'/'. $row['data']['email']);
|
||||
|
||||
if ($maildir_old != '/'
|
||||
&& !empty($maildir_old)
|
||||
&& $maildir_old != Settings::Get('system.vmail_homedir')
|
||||
&& substr($maildir_old, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir')
|
||||
&& is_dir($maildir_old)
|
||||
&& fileowner($maildir_old) == Settings::Get('system.vmail_uid')
|
||||
&& filegroup($maildir_old) == Settings::Get('system.vmail_gid')
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir_old));
|
||||
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
|
||||
$return = false;
|
||||
safe_exec('rm -rf '.escapeshellarg($maildir_old), $return, array('|', '&', '`', '$', '~', '?'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=8 Customer deleted a ftp account and wants the homedir to be deleted on the filesystem
|
||||
* refs #293
|
||||
*/
|
||||
elseif ($row['type'] == '8') {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task8 started - deleting customer ftp homedir');
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
|
||||
if (isset($row['data']['loginname'])
|
||||
&& isset($row['data']['homedir'])
|
||||
) {
|
||||
// remove specific homedir
|
||||
$ftphomedir = makeCorrectDir($row['data']['homedir']);
|
||||
$customerdocroot = makeCorrectDir(Settings::Get('system.documentroot_prefix').'/'.$row['data']['loginname'].'/');
|
||||
|
||||
if (file_exists($ftphomedir)
|
||||
&& $ftphomedir != '/'
|
||||
&& $ftphomedir != Settings::Get('system.documentroot_prefix')
|
||||
&& $ftphomedir != $customerdocroot
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($ftphomedir));
|
||||
safe_exec('rm -rf '.escapeshellarg($ftphomedir));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=10 Set the filesystem - quota
|
||||
*/
|
||||
elseif ($row['type'] == '10' && (int)Settings::Get('system.diskquota_enabled') != 0) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_tasks: Task10 started - setting filesystem quota');
|
||||
|
||||
$usedquota = getFilesystemQuota();
|
||||
|
||||
// Check whether we really have entries to check
|
||||
if (is_array($usedquota) && count($usedquota) > 0) {
|
||||
// Select all customers Froxlor knows about
|
||||
$result_stmt = Database::query("SELECT `guid`, `loginname`, `diskspace` FROM `" . TABLE_PANEL_CUSTOMERS . "`;");
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// We do not want to set a quota for root by accident
|
||||
if ($row['guid'] != 0) {
|
||||
// The user has no quota in Froxlor, but on the filesystem
|
||||
if (($row['diskspace'] == 0 || $row['diskspace'] == -1024)
|
||||
&& $usedquota[$row['guid']]['block']['hard'] != 0
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']);
|
||||
if (isFreeBSD()) {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":0:0 " . $row['guid']);
|
||||
} else {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
}
|
||||
// The user quota in Froxlor is different than on the filesystem
|
||||
elseif ($row['diskspace'] != $usedquota[$row['guid']]['block']['hard']
|
||||
&& $row['diskspace'] != -1024
|
||||
) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $usedquota[$row['guid']]['block']['hard'] . " to " . $row['diskspace']);
|
||||
if (isFreeBSD()) {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":" . $row['diskspace'] . ":" . $row['diskspace'] . " " . $row['guid']);
|
||||
} else {
|
||||
safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl " . $row['diskspace'] . " -q " . $row['diskspace'] . " " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TYPE=11 domain has been deleted, remove from pdns database if used
|
||||
*/
|
||||
if ($row['type'] == '11' && Settings::Get('system.dns_server') == 'pdns')
|
||||
{
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']);
|
||||
PowerDNS::cleanDomainZone($row['data']['domain']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($num_results != 0) {
|
||||
$where = array();
|
||||
$where_data = array();
|
||||
foreach ($resultIDs as $id) {
|
||||
$where[] = "`id` = :id_" . (int)$id;
|
||||
$where_data['id_'.$id] = $id;
|
||||
}
|
||||
$where = implode($where, ' OR ');
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE " . $where);
|
||||
Database::pexecute($del_stmt, $where_data);
|
||||
unset($resultIDs);
|
||||
unset($where);
|
||||
}
|
||||
|
||||
Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = 'system' AND `varname` = 'last_tasks_run';");
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* ARCHIVING CLOSED TICKETS
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Ticket-archiving run started...');
|
||||
$result_tickets_stmt = Database::query("
|
||||
SELECT `id`, `lastchange`, `subject` FROM `" . TABLE_PANEL_TICKETS . "`
|
||||
WHERE `status` = '3' AND `answerto` = '0';"
|
||||
);
|
||||
$archiving_count = 0;
|
||||
|
||||
while ($row_ticket = $result_tickets_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$lastchange = $row_ticket['lastchange'];
|
||||
$now = time();
|
||||
$days = (int)(($now - $lastchange) / 86400);
|
||||
|
||||
if ($days >= Settings::Get('ticket.archiving_days')) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'archiving ticket "' . $row_ticket['subject'] . '" (ID #' . $row_ticket['id'] . ')');
|
||||
$mainticket = ticket::getInstanceOf(null, (int)$row_ticket['id']);
|
||||
$mainticket->Set('lastchange', $now, true, true);
|
||||
$mainticket->Set('lastreplier', '1', true, true);
|
||||
$mainticket->Set('status', '3', true, true);
|
||||
$mainticket->Update();
|
||||
$mainticket->Archive();
|
||||
$archiving_count++;
|
||||
}
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Archived ' . $archiving_count . ' tickets');
|
||||
Database::query("
|
||||
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP()
|
||||
WHERE `settinggroup` = 'system' AND `varname` = 'last_archive_run'"
|
||||
);
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* RESET USED TICKETS COUNTER
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Resetting customers used ticket counter");
|
||||
Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `tickets_used` = '0'");
|
||||
361
lib/Froxlor/Cron/Traffic/ReportsCron.php
Normal file
361
lib/Froxlor/Cron/Traffic/ReportsCron.php
Normal file
@@ -0,0 +1,361 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Traffic;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class ReportsCron extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
{
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_INFO, 'Web- and Traffic-usage reporting started...');
|
||||
$yesterday = time() - (60 * 60 * 24);
|
||||
|
||||
/**
|
||||
* Initialize the mailingsystem
|
||||
*/
|
||||
$mail = new \PHPMailer\PHPMailer\PHPMailer(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) {
|
||||
// Warn the customers at xx% traffic-usage
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
|
||||
`c`.`company`, `c`.`traffic`, `c`.`email`, `c`.`def_language`,
|
||||
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` `t`
|
||||
WHERE `t`.`customerid` = `c`.`customerid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c`
|
||||
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` AS `a`
|
||||
ON `a`.`adminid` = `c`.`adminid` WHERE `c`.`reportsent` <> '1'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday)
|
||||
);
|
||||
Database::pexecute($result_stmt, $result_data);
|
||||
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['traffic']) && $row['traffic'] > 0 && $row['traffic_used'] != null && (($row['traffic_used'] * 100) / $row['traffic']) >= (int) Settings::Get('system.report_trafficmax')) {
|
||||
$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
|
||||
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'TRAFFICUSED' => round(($row['traffic_used'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => round(($row['traffic_used'] * 100) / $row['traffic'], 2),
|
||||
'MAX_PERCENT' => Settings::Get('system.report_trafficmax')
|
||||
);
|
||||
|
||||
$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 makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once 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' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$result2_data['varname'] = 'trafficmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['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['firstname'] . ' ' . $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) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->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` = '1'
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'customerid' => $row['customerid']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Warn the admins at xx% traffic-usage
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `a`.*,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC_ADMINS . "` `t`
|
||||
WHERE `t`.`adminid` = `a`.`adminid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used_total`
|
||||
FROM `" . TABLE_PANEL_ADMINS . "` `a` WHERE `a`.`reportsent` = '0'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday)
|
||||
);
|
||||
Database::pexecute($result_stmt, $result_data);
|
||||
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['traffic']) && $row['traffic'] > 0 && (($row['traffic_used_total'] * 100) / $row['traffic']) >= (int) Settings::Get('system.report_trafficmax')) {
|
||||
|
||||
$replace_arr = array(
|
||||
'NAME' => $row['name'],
|
||||
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'TRAFFICUSED' => round(($row['traffic_used_total'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => round(($row['traffic_used_total'] * 100) / $row['traffic'], 2),
|
||||
'MAX_PERCENT' => Settings::Get('system.report_trafficmax')
|
||||
);
|
||||
|
||||
$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 makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once 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
|
||||
");
|
||||
$resul2_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$resul2_data['varname'] = 'trafficmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['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) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->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` = '1'
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'adminid' => $row['adminid']
|
||||
));
|
||||
}
|
||||
|
||||
// Another month, let's build our report
|
||||
if (date('d') == '01') {
|
||||
|
||||
$mail_subject = 'Trafficreport ' . date("m/y", $yesterday) . ' for ' . $row['name'];
|
||||
$mail_body = 'Trafficreport ' . date("m/y", $yesterday) . ' for ' . $row['name'] . "\n";
|
||||
$mail_body .= '---------------------------------------------------------------' . "\n";
|
||||
$mail_body .= 'Loginname Traffic used (Percent) | Traffic available' . "\n";
|
||||
$customers_stmt = Database::prepare("
|
||||
SELECT `c`.*,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` `t`
|
||||
WHERE `t`.`customerid` = `c`.`customerid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used_total`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `c`.`adminid` = :adminid
|
||||
");
|
||||
$customers_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday),
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
Database::pexecute($customers_stmt, $customers_data);
|
||||
|
||||
while ($customer = $customers_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$t = $customer['traffic_used_total'] / 1048576;
|
||||
if ($customer['traffic'] > 0) {
|
||||
$p = (($customer['traffic_used_total'] * 100) / $customer['traffic']);
|
||||
$tg = $customer['traffic'] / 1048576;
|
||||
$str = sprintf('%00.1f GB ( %00.1f %% )', $t, $p);
|
||||
$mail_body .= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . sprintf('%00.1f GB', $tg) . "\n";
|
||||
} else if ($customer['traffic'] == 0) {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body .= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . '0' . "\n";
|
||||
} else {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body .= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . 'unlimited' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$mail_body .= '---------------------------------------------------------------' . "\n";
|
||||
|
||||
$t = $row['traffic_used_total'] / 1048576;
|
||||
if ($row['traffic'] > 0) {
|
||||
$p = (($row['traffic_used_total'] * 100) / $row['traffic']);
|
||||
$tg = $row['traffic'] / 1048576;
|
||||
$str = sprintf('%00.1f GB ( %00.1f %% )', $t, $p);
|
||||
$mail_body .= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . sprintf('%00.1f GB', $tg) . "\n";
|
||||
} else if ($row['traffic'] == 0) {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body .= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . '0' . "\n";
|
||||
} else {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body .= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . 'unlimited' . "\n";
|
||||
}
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$mail->SetFrom($row['email'], $row['name']);
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->Body = $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) {
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(CRON_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg);
|
||||
echo 'Error sending mail: ' . $mailerr_msg . "\n";
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
}
|
||||
}
|
||||
} // trafficmax > 0
|
||||
|
||||
// include diskspace-usage report, #466
|
||||
include dirname(__FILE__) . '/cron_usage.inc.diskspace.php';
|
||||
|
||||
// Another month, reset the reportstatus
|
||||
if (date('d') == '01') {
|
||||
Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '0';");
|
||||
Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '0';");
|
||||
}
|
||||
}
|
||||
}
|
||||
933
lib/Froxlor/Cron/Traffic/TrafficCron.php
Normal file
933
lib/Froxlor/Cron/Traffic/TrafficCron.php
Normal file
@@ -0,0 +1,933 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Traffic;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class TrafficCron extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
|
||||
public static function run()
|
||||
{
|
||||
|
||||
// Check Traffic-Lock
|
||||
if (function_exists('pcntl_fork') && ! defined('CRON_NOFORK_FLAG')) {
|
||||
$TrafficLock = makeCorrectFile(dirname($lockfile) . "/froxlor_cron_traffic.lock");
|
||||
if (file_exists($TrafficLock) && is_numeric($TrafficPid = file_get_contents($TrafficLock))) {
|
||||
if (function_exists('posix_kill')) {
|
||||
$TrafficPidStatus = @posix_kill($TrafficPid, 0);
|
||||
} else {
|
||||
system("kill -CHLD " . $TrafficPid . " 1> /dev/null 2> /dev/null", $TrafficPidStatus);
|
||||
$TrafficPidStatus = $TrafficPidStatus ? false : true;
|
||||
}
|
||||
if ($TrafficPidStatus) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Traffic Run already in progress');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Create Traffic Log and Fork
|
||||
// We close the database - connection before we fork, so we don't share resources with the child
|
||||
Database::needRoot(false); // this forces the connection to be set to null
|
||||
$TrafficPid = pcntl_fork();
|
||||
// Parent
|
||||
if ($TrafficPid) {
|
||||
file_put_contents($TrafficLock, $TrafficPid);
|
||||
// unnecessary to recreate database connection here
|
||||
return 0;
|
||||
} // Child
|
||||
elseif ($TrafficPid == 0) {
|
||||
posix_setsid();
|
||||
fclose($debugHandler);
|
||||
// re-create db
|
||||
Database::needRoot(false);
|
||||
} // Fork failed
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (extension_loaded('pcntl')) {
|
||||
$msg = "PHP compiled with pcntl but pcntl_fork function is not available.";
|
||||
} else {
|
||||
$msg = "PHP compiled without pcntl.";
|
||||
}
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, $msg . " Not forking traffic-cron, this may take a long time!");
|
||||
}
|
||||
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/TrafficCron.inc.functions.php');
|
||||
|
||||
/**
|
||||
* TRAFFIC AND DISKUSAGE MESSURE
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Traffic run started...');
|
||||
$admin_traffic = array();
|
||||
$domainlist = array();
|
||||
$speciallogfile_domainlist = array();
|
||||
$result_domainlist_stmt = Database::query("
|
||||
SELECT `id`, `domain`, `customerid`, `parentdomainid`, `speciallogfile`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain` IS NULL AND `email_only` <> '1';
|
||||
");
|
||||
|
||||
while ($row_domainlist = $result_domainlist_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (! isset($domainlist[$row_domainlist['customerid']])) {
|
||||
$domainlist[$row_domainlist['customerid']] = array();
|
||||
}
|
||||
|
||||
$domainlist[$row_domainlist['customerid']][$row_domainlist['id']] = $row_domainlist['domain'];
|
||||
|
||||
if ($row_domainlist['parentdomainid'] == '0' && $row_domainlist['speciallogfile'] == '1') {
|
||||
if (! isset($speciallogfile_domainlist[$row_domainlist['customerid']])) {
|
||||
$speciallogfile_domainlist[$row_domainlist['customerid']] = array();
|
||||
}
|
||||
$speciallogfile_domainlist[$row_domainlist['customerid']][$row_domainlist['id']] = $row_domainlist['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
$mysqlusage_all = array();
|
||||
$databases_stmt = Database::query("SELECT * FROM " . TABLE_PANEL_DATABASES . " ORDER BY `dbserver`");
|
||||
$last_dbserver = 0;
|
||||
|
||||
$databases_list = array();
|
||||
Database::needRoot(true);
|
||||
$databases_list_result_stmt = Database::query("SHOW DATABASES");
|
||||
while ($databases_list_row = $databases_list_result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$databases_list[] = strtolower($databases_list_row['Database']);
|
||||
}
|
||||
|
||||
while ($row_database = $databases_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if ($last_dbserver != $row_database['dbserver']) {
|
||||
Database::needRoot(true, $row_database['dbserver']);
|
||||
$last_dbserver = $row_database['dbserver'];
|
||||
|
||||
$databases_list = array();
|
||||
$databases_list_result_stmt = Database::query("SHOW DATABASES");
|
||||
while ($databases_list_row = $databases_list_result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$databases_list[] = strtolower($databases_list_row['Database']);
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array(strtolower($row_database['databasename']), $databases_list)) {
|
||||
// sum up data_length and index_length
|
||||
$mysql_usage_result_stmt = Database::prepare("
|
||||
SELECT SUM(data_length + index_length) AS customerusage
|
||||
FROM information_schema.TABLES
|
||||
WHERE table_schema = :database
|
||||
GROUP BY table_schema;
|
||||
");
|
||||
// get the result
|
||||
$mysql_usage_row = Database::pexecute_first($mysql_usage_result_stmt, array(
|
||||
'database' => $row_database['databasename']
|
||||
));
|
||||
// initialize counter for customer
|
||||
if (! isset($mysqlusage_all[$row_database['customerid']])) {
|
||||
$mysqlusage_all[$row_database['customerid']] = 0;
|
||||
}
|
||||
// sum up result
|
||||
$mysqlusage_all[$row_database['customerid']] += floatval($mysql_usage_row['customerusage']);
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Seems like the database " . $row_database['databasename'] . " had been removed manually.");
|
||||
}
|
||||
}
|
||||
|
||||
Database::needRoot(false);
|
||||
|
||||
// We are using the file-system quota, this will speed up the diskusage - collection
|
||||
if (Settings::Get('system.diskquota_enabled')) {
|
||||
$usedquota = getFilesystemQuota();
|
||||
}
|
||||
|
||||
/**
|
||||
* MAIL-Traffic
|
||||
*/
|
||||
if (Settings::Get("system.mailtraffic_enabled")) {
|
||||
$mailTrafficCalc = new \Froxlor\MailLogParser(Settings::Get("system.last_traffic_run"));
|
||||
}
|
||||
|
||||
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` ORDER BY `customerid` ASC");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
/**
|
||||
* HTTP-Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'http traffic for ' . $row['loginname'] . ' started...');
|
||||
$httptraffic = 0;
|
||||
|
||||
if (isset($domainlist[$row['customerid']]) && is_array($domainlist[$row['customerid']]) && count($domainlist[$row['customerid']]) != 0) {
|
||||
// Examining which caption to use for default webalizer stats...
|
||||
if ($row['standardsubdomain'] != '0') {
|
||||
// ... of course we'd prefer to use the standardsubdomain ...
|
||||
$caption = $domainlist[$row['customerid']][$row['standardsubdomain']];
|
||||
} else {
|
||||
// ... but if there is no standardsubdomain, we have to use the loginname ...
|
||||
$caption = $row['loginname'];
|
||||
|
||||
// ... which results in non-usable links to files in the stats, so lets have a look if we find a domain which is not speciallogfiledomain
|
||||
foreach ($domainlist[$row['customerid']] as $domainid => $domain) {
|
||||
|
||||
if (! isset($speciallogfile_domainlist[$row['customerid']]) || ! isset($speciallogfile_domainlist[$row['customerid']][$domainid])) {
|
||||
$caption = $domain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$httptraffic = 0;
|
||||
reset($domainlist[$row['customerid']]);
|
||||
|
||||
if (isset($speciallogfile_domainlist[$row['customerid']]) && is_array($speciallogfile_domainlist[$row['customerid']]) && count($speciallogfile_domainlist[$row['customerid']]) != 0) {
|
||||
reset($speciallogfile_domainlist[$row['customerid']]);
|
||||
if (Settings::Get('system.awstats_enabled') == '0') {
|
||||
foreach ($speciallogfile_domainlist[$row['customerid']] as $domainid => $domain) {
|
||||
$httptraffic += floatval(callWebalizerGetTraffic($row['loginname'] . '-' . $domain, $row['documentroot'] . '/webalizer/' . $domain . '/', $domain, $domainlist[$row['customerid']]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($domainlist[$row['customerid']]);
|
||||
|
||||
// callAwstatsGetTraffic is called ONLY HERE and
|
||||
// *not* also in the special-logfiles-loop, because the function
|
||||
// will iterate through all customer-domains and the awstats-configs
|
||||
// know the logfile-name, #246
|
||||
if (Settings::Get('system.awstats_enabled') == '1') {
|
||||
$httptraffic += floatval(callAwstatsGetTraffic($row['customerid'], $row['documentroot'] . '/awstats/', $domainlist[$row['customerid']]));
|
||||
} else {
|
||||
$httptraffic += floatval(callWebalizerGetTraffic($row['loginname'], $row['documentroot'] . '/webalizer/', $caption, $domainlist[$row['customerid']]));
|
||||
}
|
||||
|
||||
// make the stuff readable for the customer, #258
|
||||
makeChownWithNewStats($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* FTP-Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'ftp traffic for ' . $row['loginname'] . ' started...');
|
||||
$ftptraffic_stmt = Database::prepare("
|
||||
SELECT SUM(`up_bytes`) AS `up_bytes_sum`, SUM(`down_bytes`) AS `down_bytes_sum`
|
||||
FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :customerid
|
||||
");
|
||||
$ftptraffic = Database::pexecute_first($ftptraffic_stmt, array(
|
||||
'customerid' => $row['customerid']
|
||||
));
|
||||
|
||||
if (! is_array($ftptraffic)) {
|
||||
$ftptraffic = array(
|
||||
'up_bytes_sum' => 0,
|
||||
'down_bytes_sum' => 0
|
||||
);
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_USERS . "` SET `up_bytes` = '0', `down_bytes` = '0' WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'customerid' => $row['customerid']
|
||||
));
|
||||
|
||||
/**
|
||||
* Mail-Traffic
|
||||
*/
|
||||
$mailtraffic = 0;
|
||||
if (Settings::Get("system.mailtraffic_enabled")) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'mail traffic usage for ' . $row['loginname'] . " started...");
|
||||
|
||||
$currentDate = date("Y-m-d");
|
||||
|
||||
$domains_stmt = Database::prepare("SELECT domain FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($domains_stmt, array(
|
||||
"cid" => $row['customerid']
|
||||
));
|
||||
while ($domainRow = $domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$domainMailTraffic = $mailTrafficCalc->getDomainTraffic($domainRow["domain"]);
|
||||
if (! is_array($domainMailTraffic)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($domainMailTraffic as $dateTraffic => $dayTraffic) {
|
||||
$dayTraffic = floatval($dayTraffic / 1024);
|
||||
|
||||
list ($year, $month, $day) = explode("-", $dateTraffic);
|
||||
if ($dateTraffic == $currentDate) {
|
||||
$mailtraffic = $dayTraffic;
|
||||
} else {
|
||||
// Check if an entry for the given day exists
|
||||
$stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE `customerid` = :cid
|
||||
AND `year` = :year
|
||||
AND `month` = :month
|
||||
AND `day` = :day");
|
||||
$params = array(
|
||||
"cid" => $row['customerid'],
|
||||
"year" => $year,
|
||||
"month" => $month,
|
||||
"day" => $day
|
||||
);
|
||||
Database::pexecute($stmt, $params);
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$updRow = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_TRAFFIC . "` SET
|
||||
`mail` = :mail
|
||||
WHERE `id` = :id");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
"mail" => $updRow['mail'] + $dayTraffic,
|
||||
"id" => $updRow['id']
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Total Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'total traffic for ' . $row['loginname'] . ' started');
|
||||
$current_traffic = array();
|
||||
$current_traffic['http'] = floatval($httptraffic);
|
||||
$current_traffic['ftp_up'] = floatval(($ftptraffic['up_bytes_sum'] / 1024));
|
||||
$current_traffic['ftp_down'] = floatval(($ftptraffic['down_bytes_sum'] / 1024));
|
||||
$current_traffic['mail'] = floatval($mailtraffic);
|
||||
$current_traffic['all'] = $current_traffic['http'] + $current_traffic['ftp_up'] + $current_traffic['ftp_down'] + $current_traffic['mail'];
|
||||
|
||||
$ins_data = array(
|
||||
'customerid' => $row['customerid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'http' => $current_traffic['http'],
|
||||
'ftp_up' => $current_traffic['ftp_up'],
|
||||
'ftp_down' => $current_traffic['ftp_down'],
|
||||
'mail' => $current_traffic['mail']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TRAFFIC . "` SET
|
||||
`customerid` = :customerid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`http` = :http,
|
||||
`ftp_up` = :ftp_up,
|
||||
`ftp_down` = :ftp_down,
|
||||
`mail` = :mail
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
$sum_month_traffic_stmt = Database::prepare("
|
||||
SELECT SUM(`http`) AS `http`, SUM(`ftp_up`) AS `ftp_up`, SUM(`ftp_down`) AS `ftp_down`, SUM(`mail`) AS `mail`
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `year` = :year AND `month` = :month AND `customerid` = :customerid
|
||||
");
|
||||
$sum_month_traffic = Database::pexecute_first($sum_month_traffic_stmt, array(
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'customerid' => $row['customerid']
|
||||
));
|
||||
$sum_month_traffic['all'] = $sum_month_traffic['http'] + $sum_month_traffic['ftp_up'] + $sum_month_traffic['ftp_down'] + $sum_month_traffic['mail'];
|
||||
|
||||
if (! isset($admin_traffic[$row['adminid']]) || ! is_array($admin_traffic[$row['adminid']])) {
|
||||
$admin_traffic[$row['adminid']]['http'] = 0;
|
||||
$admin_traffic[$row['adminid']]['ftp_up'] = 0;
|
||||
$admin_traffic[$row['adminid']]['ftp_down'] = 0;
|
||||
$admin_traffic[$row['adminid']]['mail'] = 0;
|
||||
$admin_traffic[$row['adminid']]['all'] = 0;
|
||||
$admin_traffic[$row['adminid']]['sum_month'] = 0;
|
||||
}
|
||||
|
||||
$admin_traffic[$row['adminid']]['http'] += $current_traffic['http'];
|
||||
$admin_traffic[$row['adminid']]['ftp_up'] += $current_traffic['ftp_up'];
|
||||
$admin_traffic[$row['adminid']]['ftp_down'] += $current_traffic['ftp_down'];
|
||||
$admin_traffic[$row['adminid']]['mail'] += $current_traffic['mail'];
|
||||
$admin_traffic[$row['adminid']]['all'] += $current_traffic['all'];
|
||||
$admin_traffic[$row['adminid']]['sum_month'] += $sum_month_traffic['all'];
|
||||
|
||||
/**
|
||||
* WebSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating webspace usage for ' . $row['loginname']);
|
||||
$webspaceusage = 0;
|
||||
|
||||
// Using repquota, it's faster using this tool than using du traversing the complete directory
|
||||
if (Settings::Get('system.diskquota_enabled') && isset($usedquota[$row['guid']]['block']['used']) && $usedquota[$row['guid']]['block']['used'] >= 1) {
|
||||
// We may use the array we created earlier, the used diskspace is stored in [<guid>][block][used]
|
||||
$webspaceusage = floatval($usedquota[$row['guid']]['block']['used']);
|
||||
} else {
|
||||
|
||||
// Use the old fashioned way with "du"
|
||||
if (file_exists($row['documentroot']) && is_dir($row['documentroot'])) {
|
||||
$back = safe_exec('du -sk ' . escapeshellarg($row['documentroot']) . '');
|
||||
foreach ($back as $backrow) {
|
||||
$webspaceusage = explode(' ', $backrow);
|
||||
}
|
||||
|
||||
$webspaceusage = floatval($webspaceusage['0']);
|
||||
unset($back);
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, 'documentroot ' . $row['documentroot'] . ' does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MailSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating mailspace usage for ' . $row['loginname']);
|
||||
$emailusage = 0;
|
||||
|
||||
$maildir = makeCorrectDir(Settings::Get('system.vmail_homedir') . $row['loginname']);
|
||||
if (file_exists($maildir) && is_dir($maildir)) {
|
||||
$back = safe_exec('du -sk ' . escapeshellarg($maildir) . '');
|
||||
foreach ($back as $backrow) {
|
||||
$emailusage = explode(' ', $backrow);
|
||||
}
|
||||
|
||||
$emailusage = floatval($emailusage['0']);
|
||||
unset($back);
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, 'maildir ' . $maildir . ' does not exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQLSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating mysqlspace usage for ' . $row['loginname']);
|
||||
$mysqlusage = 0;
|
||||
|
||||
if (isset($mysqlusage_all[$row['customerid']])) {
|
||||
$mysqlusage = floatval($mysqlusage_all[$row['customerid']] / 1024);
|
||||
}
|
||||
|
||||
$current_diskspace = array();
|
||||
$current_diskspace['webspace'] = floatval($webspaceusage);
|
||||
$current_diskspace['mail'] = floatval($emailusage);
|
||||
$current_diskspace['mysql'] = floatval($mysqlusage);
|
||||
$current_diskspace['all'] = $current_diskspace['webspace'] + $current_diskspace['mail'] + $current_diskspace['mysql'];
|
||||
|
||||
$ins_data = array(
|
||||
'customerid' => $row['customerid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'webspace' => $current_diskspace['webspace'],
|
||||
'mail' => $current_diskspace['mail'],
|
||||
'mysql' => $current_diskspace['mysql']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DISKSPACE . "` SET
|
||||
`customerid` = :customerid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`webspace` = :webspace,
|
||||
`mail` = :mail,
|
||||
`mysql` = :mysql
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
if (! isset($admin_diskspace[$row['adminid']]) || ! is_array($admin_diskspace[$row['adminid']])) {
|
||||
$admin_diskspace[$row['adminid']] = array();
|
||||
$admin_diskspace[$row['adminid']]['webspace'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['mail'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['mysql'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['all'] = 0;
|
||||
}
|
||||
|
||||
$admin_diskspace[$row['adminid']]['webspace'] += $current_diskspace['webspace'];
|
||||
$admin_diskspace[$row['adminid']]['mail'] += $current_diskspace['mail'];
|
||||
$admin_diskspace[$row['adminid']]['mysql'] += $current_diskspace['mysql'];
|
||||
$admin_diskspace[$row['adminid']]['all'] += $current_diskspace['all'];
|
||||
|
||||
/**
|
||||
* Total Usage
|
||||
*/
|
||||
$diskusage = floatval($webspaceusage + $emailusage + $mysqlusage);
|
||||
|
||||
$upd_data = array(
|
||||
'diskspace' => $current_diskspace['all'],
|
||||
'traffic' => $sum_month_traffic['all'],
|
||||
'customerid' => $row['customerid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET
|
||||
`diskspace_used` = :diskspace,
|
||||
`traffic_used` = :traffic
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
/**
|
||||
* Proftpd Quota
|
||||
*/
|
||||
$upd_data = array(
|
||||
'biu' => ($current_diskspace['all'] * 1024),
|
||||
'loginname' => $row['loginname'],
|
||||
'loginnamelike' => $row['loginname'] . Settings::Get('customer.ftpprefix') . "%"
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_QUOTATALLIES . "` SET
|
||||
`bytes_in_used` = :biu WHERE `name` = :loginname OR `name` LIKE :loginnamelike
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
/**
|
||||
* Pureftpd Quota
|
||||
*/
|
||||
if (Settings::Get('system.ftpserver') == "pureftpd") {
|
||||
|
||||
$result_quota_stmt = Database::prepare("
|
||||
SELECT homedir FROM `" . TABLE_FTP_USERS . "` WHERE customerid = :customerid
|
||||
");
|
||||
Database::pexecute($result_quota_stmt, array(
|
||||
'customerid' => $row['customerid']
|
||||
));
|
||||
|
||||
// get correct user
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) && $row['deactivated'] == '0') {
|
||||
$user = $row['loginname'];
|
||||
$group = $row['loginname'];
|
||||
} else {
|
||||
$user = $row['guid'];
|
||||
$group = $row['guid'];
|
||||
}
|
||||
|
||||
while ($row_quota = $result_quota_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$quotafile = "" . $row_quota['homedir'] . ".ftpquota";
|
||||
$fh = fopen($quotafile, 'w');
|
||||
$stringdata = "0 " . $current_diskspace['all'] * 1024 . "";
|
||||
fwrite($fh, $stringdata);
|
||||
fclose($fh);
|
||||
safe_exec('chown ' . $user . ':' . $group . ' ' . escapeshellarg($quotafile) . '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin Usage
|
||||
*/
|
||||
$result_stmt = Database::query("SELECT `adminid` FROM `" . TABLE_PANEL_ADMINS . "` ORDER BY `adminid` ASC");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($admin_traffic[$row['adminid']])) {
|
||||
|
||||
$ins_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'http' => $admin_traffic[$row['adminid']]['http'],
|
||||
'ftp_up' => $admin_traffic[$row['adminid']]['ftp_up'],
|
||||
'ftp_down' => $admin_traffic[$row['adminid']]['ftp_down'],
|
||||
'mail' => $admin_traffic[$row['adminid']]['mail']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TRAFFIC_ADMINS . "` SET
|
||||
`adminid` = :adminid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`http` = :http,
|
||||
`ftp_up` = :ftp_up,
|
||||
`ftp_down` = :ftp_down,
|
||||
`mail` = :mail
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
$upd_data = array(
|
||||
'traffic' => $admin_traffic[$row['adminid']]['sum_month'],
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`traffic_used` = :traffic
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
|
||||
if (isset($admin_diskspace[$row['adminid']])) {
|
||||
|
||||
$ins_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'webspace' => $admin_diskspace[$row['adminid']]['webspace'],
|
||||
'mail' => $admin_diskspace[$row['adminid']]['mail'],
|
||||
'mysql' => $admin_diskspace[$row['adminid']]['mysql']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DISKSPACE_ADMINS . "` SET
|
||||
`adminid` = :adminid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`webspace` = :webspace,
|
||||
`mail` = :mail,
|
||||
`mysql` = :mysql
|
||||
");
|
||||
|
||||
$upd_data = array(
|
||||
'diskspace' => $admin_diskspace[$row['adminid']]['all'],
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`diskspace_used` = :diskspace
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
}
|
||||
|
||||
Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = 'system' AND `varname` = 'last_traffic_run'");
|
||||
|
||||
if (function_exists('pcntl_fork') && ! defined('CRON_NOFORK_FLAG')) {
|
||||
@unlink($TrafficLock);
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function awstatsDoSingleDomain($domain, $outputdir)
|
||||
{
|
||||
$returnval = 0;
|
||||
|
||||
$domainconfig = makeCorrectFile(Settings::Get('system.awstats_conf') . '/awstats.' . $domain . '.conf');
|
||||
|
||||
if (file_exists($domainconfig)) {
|
||||
|
||||
$outputdir = makeCorrectDir($outputdir . '/' . $domain);
|
||||
$staticOutputdir = makeCorrectDir($outputdir . '/' . date('Y') . '-' . date('m'));
|
||||
|
||||
if (! is_dir($staticOutputdir)) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($staticOutputdir));
|
||||
}
|
||||
|
||||
// check for correct path of awstats_buildstaticpages.pl
|
||||
$awbsp = makeCorrectFile(Settings::Get('system.awstats_path') . '/awstats_buildstaticpages.pl');
|
||||
$awprog = makeCorrectFile(Settings::Get('system.awstats_awstatspath') . '/awstats.pl');
|
||||
|
||||
if (! file_exists($awbsp)) {
|
||||
echo "WANRING: Necessary awstats_buildstaticpages.pl script could not be found, no traffic is being calculated and no stats are generated. Please check your AWStats-Path setting";
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Necessary awstats_buildstaticpages.pl script could not be found, no traffic is being calculated and no stats are generated. Please check your AWStats-Path setting");
|
||||
exit();
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Running awstats_buildstaticpages.pl for domain '" . $domain . "' (Output: '" . $staticOutputdir . "')");
|
||||
safe_exec($awbsp . ' -awstatsprog=' . escapeshellarg($awprog) . ' -update -month=' . date('m') . ' -year=' . date('Y') . ' -config=' . $domain . ' -dir=' . escapeshellarg($staticOutputdir));
|
||||
|
||||
// update our awstats index files
|
||||
awstatsGenerateIndex($domain, $outputdir);
|
||||
|
||||
// the default selection is 'current',
|
||||
// so link the latest dir to it
|
||||
$new_current = makeCorrectFile($outputdir . '/current');
|
||||
safe_exec('ln -fTs ' . escapeshellarg($staticOutputdir) . ' ' . escapeshellarg($new_current));
|
||||
|
||||
// statistics file looks like: 'awstats[month][year].[domain].txt'
|
||||
$file = makeCorrectFile($outputdir . '/awstats' . date('mY', time()) . '.' . $domain . '.txt');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '" . $file . "'");
|
||||
|
||||
if (file_exists($file)) {
|
||||
|
||||
$content = @file_get_contents($file);
|
||||
if ($content !== false) {
|
||||
$content_array = explode("\n", $content);
|
||||
|
||||
$count_bdw = false;
|
||||
foreach ($content_array as $line) {
|
||||
// skip empty lines and comments
|
||||
if (trim($line) == '' || substr(trim($line), 0, 1) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parts = explode(' ', $line);
|
||||
|
||||
if (isset($parts[0]) && strtoupper($parts[0]) == 'BEGIN_DOMAIN') {
|
||||
$count_bdw = true;
|
||||
}
|
||||
|
||||
if ($count_bdw) {
|
||||
if (isset($parts[0]) && strtoupper($parts[0]) == 'END_DOMAIN') {
|
||||
$count_bdw = false;
|
||||
break;
|
||||
} elseif (isset($parts[3])) {
|
||||
$returnval += floatval($parts[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $returnval;
|
||||
}
|
||||
|
||||
public static function awstatsGenerateIndex($domain, $outputdir)
|
||||
{
|
||||
|
||||
// Generation header
|
||||
$header = "<!-- GENERATED BY FROXLOR -->\n";
|
||||
|
||||
// Looking for {year}-{month} directories
|
||||
$entries = array();
|
||||
foreach (scandir($outputdir) as $a) {
|
||||
if (is_dir(makeCorrectDir($outputdir . '/' . $a)) && preg_match('/^[0-9]{4}-[0-9]{2}$/', $a)) {
|
||||
array_push($entries, '<option value="' . $a . '">' . $a . '</option>');
|
||||
}
|
||||
}
|
||||
|
||||
// These are the variables we will replace
|
||||
$regex = array(
|
||||
'/\{SITE_DOMAIN\}/',
|
||||
'/\{SELECT_ENTRIES\}/'
|
||||
);
|
||||
|
||||
$replace = array(
|
||||
$domain,
|
||||
implode($entries)
|
||||
);
|
||||
|
||||
// File names
|
||||
$index_file = \Froxlor\Froxlor::getInstallDir() . '/templates/misc/awstats/index.html';
|
||||
$index_file = makeCorrectFile($index_file);
|
||||
$nav_file = \Froxlor\Froxlor::getInstallDir() . '/templates/misc/awstats/nav.html';
|
||||
$nav_file = makeCorrectFile($nav_file);
|
||||
|
||||
// Write the index file
|
||||
{
|
||||
// 'index.html' used to be a symlink (ignore errors in case this is the first run and no index.html exists yet)
|
||||
@unlink(makeCorrectFile($outputdir . '/' . 'index.html'));
|
||||
|
||||
$awstats_index_file = fopen(makeCorrectFile($outputdir . '/' . 'index.html'), 'w');
|
||||
$awstats_index_tpl = fopen($index_file, 'r');
|
||||
|
||||
// Write the header
|
||||
fwrite($awstats_index_file, $header);
|
||||
|
||||
// Write the configuration file
|
||||
while (($line = fgets($awstats_index_tpl, 4096)) !== false) {
|
||||
if (! preg_match('/^#/', $line) && trim($line) != '') {
|
||||
fwrite($awstats_index_file, preg_replace($regex, $replace, $line));
|
||||
}
|
||||
}
|
||||
fclose($awstats_index_file);
|
||||
fclose($awstats_index_tpl);
|
||||
}
|
||||
|
||||
// Write the nav file
|
||||
{
|
||||
$awstats_nav_file = fopen(makeCorrectFile($outputdir . '/' . 'nav.html'), 'w');
|
||||
$awstats_nav_tpl = fopen($nav_file, 'r');
|
||||
|
||||
// Write the header
|
||||
fwrite($awstats_nav_file, $header);
|
||||
|
||||
// Write the configuration file
|
||||
while (($line = fgets($awstats_nav_tpl, 4096)) !== false) {
|
||||
if (! preg_match('/^#/', $line) && trim($line) != '') {
|
||||
fwrite($awstats_nav_file, preg_replace($regex, $replace, $line));
|
||||
}
|
||||
}
|
||||
fclose($awstats_nav_file);
|
||||
fclose($awstats_nav_tpl);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public static function callAwstatsGetTraffic($customerid, $outputdir, $usersdomainlist)
|
||||
{
|
||||
global $cronlog;
|
||||
|
||||
$returnval = 0;
|
||||
|
||||
foreach ($usersdomainlist as $domainid => $singledomain) {
|
||||
// as we check for the config-model awstats will only parse
|
||||
// 'real' domains and no subdomains which are aliases in the
|
||||
// model-config-file.
|
||||
$returnval += awstatsDoSingleDomain($singledomain, $outputdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* as of #124, awstats traffic is saved in bytes instead
|
||||
* of kilobytes (like webalizer does)
|
||||
*/
|
||||
$returnval = floatval($returnval / 1024);
|
||||
|
||||
/**
|
||||
* now, because this traffic is being saved daily, we have to
|
||||
* subtract the values from all the month's values to return
|
||||
* a sane value for our panel_traffic and to remain the whole stats
|
||||
* (awstats overwrites the customers .html stats-files)
|
||||
*/
|
||||
if ($customerid !== false) {
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT SUM(`http`) as `trafficmonth` FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE `customerid` = :customerid
|
||||
AND `year` = :year AND `month` = :month
|
||||
");
|
||||
$result_data = array(
|
||||
'customerid' => $customerid,
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time())
|
||||
);
|
||||
$result = Database::pexecute_first($result_stmt, $result_data);
|
||||
|
||||
if (is_array($result) && isset($result['trafficmonth'])) {
|
||||
$returnval = ($returnval - floatval($result['trafficmonth']));
|
||||
}
|
||||
}
|
||||
|
||||
return floatval($returnval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function which make webalizer statistics and returns used traffic since last run
|
||||
*
|
||||
* @param
|
||||
* string Name of logfile
|
||||
* @param
|
||||
* string Place where stats should be build
|
||||
* @param
|
||||
* string Caption for webalizer output
|
||||
* @return int Used traffic
|
||||
* @author Florian Lippert <flo@syscp.org>
|
||||
*/
|
||||
public static function callWebalizerGetTraffic($logfile, $outputdir, $caption, $usersdomainlist)
|
||||
{
|
||||
global $cronlog;
|
||||
|
||||
$returnval = 0;
|
||||
|
||||
$logfile = makeCorrectFile(Settings::Get('system.logfiles_directory') . $logfile . '-access.log');
|
||||
if (file_exists($logfile)) {
|
||||
$domainargs = '';
|
||||
foreach ($usersdomainlist as $domainid => $domain) {
|
||||
// hide referer
|
||||
$domainargs .= ' -r ' . escapeshellarg($domain);
|
||||
}
|
||||
|
||||
$outputdir = makeCorrectDir($outputdir);
|
||||
if (! file_exists($outputdir)) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($outputdir));
|
||||
}
|
||||
|
||||
if (file_exists($outputdir . 'webalizer.hist.1')) {
|
||||
@unlink($outputdir . 'webalizer.hist.1');
|
||||
}
|
||||
|
||||
if (file_exists($outputdir . 'webalizer.hist') && ! file_exists($outputdir . 'webalizer.hist.1')) {
|
||||
safe_exec('cp ' . escapeshellarg($outputdir . 'webalizer.hist') . ' ' . escapeshellarg($outputdir . 'webalizer.hist.1'));
|
||||
}
|
||||
|
||||
$verbosity = '';
|
||||
if (Settings::Get('system.webalizer_quiet') == '1') {
|
||||
$verbosity = '-q';
|
||||
} elseif (Settings::Get('system.webalizer_quiet') == '2') {
|
||||
$verbosity = '-Q';
|
||||
}
|
||||
|
||||
$we = '/usr/bin/webalizer';
|
||||
|
||||
// FreeBSD uses other paths, #140
|
||||
if (! file_exists($we)) {
|
||||
$we = '/usr/local/bin/webalizer';
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Running webalizer for domain '" . $caption . "'");
|
||||
safe_exec($we . ' ' . $verbosity . ' -p -o ' . escapeshellarg($outputdir) . ' -n ' . escapeshellarg($caption) . $domainargs . ' ' . escapeshellarg($logfile));
|
||||
|
||||
/**
|
||||
* Format of webalizer.hist-files:
|
||||
* Month: $webalizer_hist_row['0']
|
||||
* Year: $webalizer_hist_row['1']
|
||||
* KB: $webalizer_hist_row['5']
|
||||
*/
|
||||
$httptraffic = array();
|
||||
$webalizer_hist = @file_get_contents($outputdir . 'webalizer.hist');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '" . $webalizer_hist . "'");
|
||||
|
||||
$webalizer_hist_rows = explode("\n", $webalizer_hist);
|
||||
foreach ($webalizer_hist_rows as $webalizer_hist_row) {
|
||||
if ($webalizer_hist_row != '') {
|
||||
|
||||
$webalizer_hist_row = explode(' ', $webalizer_hist_row);
|
||||
|
||||
if (isset($webalizer_hist_row['0']) && isset($webalizer_hist_row['1']) && isset($webalizer_hist_row['5'])) {
|
||||
$month = intval($webalizer_hist_row['0']);
|
||||
$year = intval($webalizer_hist_row['1']);
|
||||
$traffic = floatval($webalizer_hist_row['5']);
|
||||
|
||||
if (! isset($httptraffic[$year])) {
|
||||
$httptraffic[$year] = array();
|
||||
}
|
||||
|
||||
$httptraffic[$year][$month] = $traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($httptraffic);
|
||||
$httptrafficlast = array();
|
||||
$webalizer_lasthist = @file_get_contents($outputdir . 'webalizer.hist.1');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '" . $webalizer_lasthist . "'");
|
||||
|
||||
$webalizer_lasthist_rows = explode("\n", $webalizer_lasthist);
|
||||
foreach ($webalizer_lasthist_rows as $webalizer_lasthist_row) {
|
||||
if ($webalizer_lasthist_row != '') {
|
||||
|
||||
$webalizer_lasthist_row = explode(' ', $webalizer_lasthist_row);
|
||||
|
||||
if (isset($webalizer_lasthist_row['0']) && isset($webalizer_lasthist_row['1']) && isset($webalizer_lasthist_row['5'])) {
|
||||
$month = intval($webalizer_lasthist_row['0']);
|
||||
$year = intval($webalizer_lasthist_row['1']);
|
||||
$traffic = floatval($webalizer_lasthist_row['5']);
|
||||
|
||||
if (! isset($httptrafficlast[$year])) {
|
||||
$httptrafficlast[$year] = array();
|
||||
}
|
||||
|
||||
$httptrafficlast[$year][$month] = $traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($httptrafficlast);
|
||||
foreach ($httptraffic as $year => $months) {
|
||||
foreach ($months as $month => $traffic) {
|
||||
if (! isset($httptrafficlast[$year][$month])) {
|
||||
$returnval += $traffic;
|
||||
} elseif ($httptrafficlast[$year][$month] < $httptraffic[$year][$month]) {
|
||||
$returnval += ($httptraffic[$year][$month] - $httptrafficlast[$year][$month]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return floatval($returnval);
|
||||
}
|
||||
}
|
||||
@@ -17,342 +17,4 @@
|
||||
*
|
||||
*/
|
||||
|
||||
function awstatsDoSingleDomain($domain, $outputdir) {
|
||||
|
||||
global $cronlog, $theme;
|
||||
$returnval = 0;
|
||||
|
||||
$domainconfig = makeCorrectFile(Settings::Get('system.awstats_conf').'/awstats.' . $domain . '.conf');
|
||||
|
||||
if (file_exists($domainconfig)) {
|
||||
|
||||
$outputdir = makeCorrectDir($outputdir . '/' . $domain);
|
||||
$staticOutputdir = makeCorrectDir($outputdir . '/' . date('Y') . '-' . date('m'));
|
||||
|
||||
if (!is_dir($staticOutputdir)) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($staticOutputdir));
|
||||
}
|
||||
|
||||
//check for correct path of awstats_buildstaticpages.pl
|
||||
$awbsp = makeCorrectFile(Settings::Get('system.awstats_path').'/awstats_buildstaticpages.pl');
|
||||
$awprog = makeCorrectFile(Settings::Get('system.awstats_awstatspath').'/awstats.pl');
|
||||
|
||||
if (!file_exists($awbsp)) {
|
||||
echo "WANRING: Necessary awstats_buildstaticpages.pl script could not be found, no traffic is being calculated and no stats are generated. Please check your AWStats-Path setting";
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Necessary awstats_buildstaticpages.pl script could not be found, no traffic is being calculated and no stats are generated. Please check your AWStats-Path setting");
|
||||
exit;
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Running awstats_buildstaticpages.pl for domain '".$domain."' (Output: '".$staticOutputdir."')");
|
||||
safe_exec($awbsp.' -awstatsprog='.escapeshellarg($awprog).' -update -month=' . date('m') . ' -year=' . date('Y') . ' -config=' . $domain . ' -dir='.escapeshellarg($staticOutputdir));
|
||||
|
||||
// update our awstats index files
|
||||
awstatsGenerateIndex($domain, $outputdir);
|
||||
|
||||
// the default selection is 'current',
|
||||
// so link the latest dir to it
|
||||
$new_current = makeCorrectFile($outputdir . '/current');
|
||||
safe_exec('ln -fTs ' . escapeshellarg($staticOutputdir) . ' ' . escapeshellarg($new_current));
|
||||
|
||||
//statistics file looks like: 'awstats[month][year].[domain].txt'
|
||||
$file = makeCorrectFile($outputdir.'/awstats'.date('mY', time()).'.'.$domain.'.txt');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '".$file."'");
|
||||
|
||||
if (file_exists($file)) {
|
||||
|
||||
$content = @file_get_contents($file);
|
||||
if ($content !== false) {
|
||||
$content_array = explode("\n", $content);
|
||||
|
||||
$count_bdw = false;
|
||||
foreach ($content_array as $line) {
|
||||
// skip empty lines and comments
|
||||
if (trim($line) == ''
|
||||
|| substr(trim($line), 0, 1) == '#'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parts = explode(' ', $line);
|
||||
|
||||
if (isset($parts[0])
|
||||
&& strtoupper($parts[0]) == 'BEGIN_DOMAIN'
|
||||
) {
|
||||
$count_bdw = true;
|
||||
}
|
||||
|
||||
if ($count_bdw) {
|
||||
if (isset($parts[0])
|
||||
&& strtoupper($parts[0]) == 'END_DOMAIN'
|
||||
) {
|
||||
$count_bdw = false;
|
||||
break;
|
||||
} elseif (isset($parts[3])) {
|
||||
$returnval += floatval($parts[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $returnval;
|
||||
}
|
||||
|
||||
|
||||
function awstatsGenerateIndex($domain, $outputdir) {
|
||||
|
||||
// Generation header
|
||||
$header = "<!-- GENERATED BY FROXLOR -->\n";
|
||||
|
||||
// Looking for {year}-{month} directories
|
||||
$entries = array();
|
||||
foreach (scandir($outputdir) as $a) {
|
||||
if (is_dir(makeCorrectDir($outputdir . '/' . $a)) && preg_match('/^[0-9]{4}-[0-9]{2}$/', $a)) {
|
||||
array_push($entries, '<option value="' . $a . '">' . $a . '</option>');
|
||||
}
|
||||
}
|
||||
|
||||
// These are the variables we will replace
|
||||
$regex = array(
|
||||
'/\{SITE_DOMAIN\}/',
|
||||
'/\{SELECT_ENTRIES\}/'
|
||||
);
|
||||
|
||||
$replace = array(
|
||||
$domain,
|
||||
implode($entries)
|
||||
);
|
||||
|
||||
// File names
|
||||
$index_file = \Froxlor\Froxlor::getInstallDir().'/templates/misc/awstats/index.html';
|
||||
$index_file = makeCorrectFile($index_file);
|
||||
$nav_file = \Froxlor\Froxlor::getInstallDir().'/templates/misc/awstats/nav.html';
|
||||
$nav_file = makeCorrectFile($nav_file);
|
||||
|
||||
// Write the index file
|
||||
{
|
||||
// 'index.html' used to be a symlink (ignore errors in case this is the first run and no index.html exists yet)
|
||||
@unlink(makeCorrectFile($outputdir . '/' . 'index.html'));
|
||||
|
||||
$awstats_index_file = fopen(makeCorrectFile($outputdir . '/' . 'index.html'), 'w');
|
||||
$awstats_index_tpl = fopen($index_file, 'r');
|
||||
|
||||
// Write the header
|
||||
fwrite($awstats_index_file, $header);
|
||||
|
||||
// Write the configuration file
|
||||
while (($line = fgets($awstats_index_tpl, 4096)) !== false) {
|
||||
if (!preg_match('/^#/', $line)
|
||||
&& trim($line) != ''
|
||||
) {
|
||||
fwrite($awstats_index_file, preg_replace($regex, $replace, $line));
|
||||
}
|
||||
}
|
||||
fclose($awstats_index_file);
|
||||
fclose($awstats_index_tpl);
|
||||
}
|
||||
|
||||
// Write the nav file
|
||||
{
|
||||
$awstats_nav_file = fopen(makeCorrectFile($outputdir . '/' . 'nav.html'), 'w');
|
||||
$awstats_nav_tpl = fopen($nav_file, 'r');
|
||||
|
||||
// Write the header
|
||||
fwrite($awstats_nav_file, $header);
|
||||
|
||||
// Write the configuration file
|
||||
while (($line = fgets($awstats_nav_tpl, 4096)) !== false) {
|
||||
if (!preg_match('/^#/', $line)
|
||||
&& trim($line) != ''
|
||||
) {
|
||||
fwrite($awstats_nav_file, preg_replace($regex, $replace, $line));
|
||||
}
|
||||
}
|
||||
fclose($awstats_nav_file);
|
||||
fclose($awstats_nav_tpl);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
function callAwstatsGetTraffic($customerid, $outputdir, $usersdomainlist) {
|
||||
|
||||
global $cronlog;
|
||||
|
||||
$returnval = 0;
|
||||
|
||||
foreach ($usersdomainlist as $domainid => $singledomain) {
|
||||
// as we check for the config-model awstats will only parse
|
||||
// 'real' domains and no subdomains which are aliases in the
|
||||
// model-config-file.
|
||||
$returnval += awstatsDoSingleDomain($singledomain, $outputdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* as of #124, awstats traffic is saved in bytes instead
|
||||
* of kilobytes (like webalizer does)
|
||||
*/
|
||||
$returnval = floatval($returnval / 1024);
|
||||
|
||||
/**
|
||||
* now, because this traffic is being saved daily, we have to
|
||||
* subtract the values from all the month's values to return
|
||||
* a sane value for our panel_traffic and to remain the whole stats
|
||||
* (awstats overwrites the customers .html stats-files)
|
||||
*/
|
||||
if ($customerid !== false) {
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT SUM(`http`) as `trafficmonth` FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE `customerid` = :customerid
|
||||
AND `year` = :year AND `month` = :month
|
||||
");
|
||||
$result_data = array(
|
||||
'customerid' => $customerid,
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time())
|
||||
);
|
||||
$result = Database::pexecute_first($result_stmt, $result_data);
|
||||
|
||||
if (is_array($result)
|
||||
&& isset($result['trafficmonth'])
|
||||
) {
|
||||
$returnval = ($returnval - floatval($result['trafficmonth']));
|
||||
}
|
||||
}
|
||||
|
||||
return floatval($returnval);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function which make webalizer statistics and returns used traffic since last run
|
||||
*
|
||||
* @param string Name of logfile
|
||||
* @param string Place where stats should be build
|
||||
* @param string Caption for webalizer output
|
||||
* @return int Used traffic
|
||||
* @author Florian Lippert <flo@syscp.org>
|
||||
*/
|
||||
function callWebalizerGetTraffic($logfile, $outputdir, $caption, $usersdomainlist) {
|
||||
|
||||
global $cronlog;
|
||||
|
||||
$returnval = 0;
|
||||
|
||||
$logfile = makeCorrectFile(Settings::Get('system.logfiles_directory') . $logfile . '-access.log');
|
||||
if (file_exists($logfile)) {
|
||||
$domainargs = '';
|
||||
foreach ($usersdomainlist as $domainid => $domain) {
|
||||
// hide referer
|
||||
$domainargs.= ' -r ' . escapeshellarg($domain);
|
||||
}
|
||||
|
||||
$outputdir = makeCorrectDir($outputdir);
|
||||
if (!file_exists($outputdir)) {
|
||||
safe_exec('mkdir -p ' . escapeshellarg($outputdir));
|
||||
}
|
||||
|
||||
if (file_exists($outputdir . 'webalizer.hist.1')) {
|
||||
@unlink($outputdir . 'webalizer.hist.1');
|
||||
}
|
||||
|
||||
if (file_exists($outputdir . 'webalizer.hist')
|
||||
&& !file_exists($outputdir . 'webalizer.hist.1')
|
||||
) {
|
||||
safe_exec('cp ' . escapeshellarg($outputdir . 'webalizer.hist') . ' ' . escapeshellarg($outputdir . 'webalizer.hist.1'));
|
||||
}
|
||||
|
||||
$verbosity = '';
|
||||
if (Settings::Get('system.webalizer_quiet') == '1') {
|
||||
$verbosity = '-q';
|
||||
} elseif (Settings::Get('system.webalizer_quiet') == '2') {
|
||||
$verbosity = '-Q';
|
||||
}
|
||||
|
||||
$we = '/usr/bin/webalizer';
|
||||
|
||||
// FreeBSD uses other paths, #140
|
||||
if (!file_exists($we)) {
|
||||
$we = '/usr/local/bin/webalizer';
|
||||
}
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Running webalizer for domain '".$caption."'");
|
||||
safe_exec($we . ' ' . $verbosity . ' -p -o ' . escapeshellarg($outputdir) . ' -n ' . escapeshellarg($caption) . $domainargs . ' ' . escapeshellarg($logfile));
|
||||
|
||||
/**
|
||||
* Format of webalizer.hist-files:
|
||||
* Month: $webalizer_hist_row['0']
|
||||
* Year: $webalizer_hist_row['1']
|
||||
* KB: $webalizer_hist_row['5']
|
||||
*/
|
||||
$httptraffic = array();
|
||||
$webalizer_hist = @file_get_contents($outputdir . 'webalizer.hist');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '".$webalizer_hist."'");
|
||||
|
||||
$webalizer_hist_rows = explode("\n", $webalizer_hist);
|
||||
foreach ($webalizer_hist_rows as $webalizer_hist_row) {
|
||||
if ($webalizer_hist_row != '') {
|
||||
|
||||
$webalizer_hist_row = explode(' ', $webalizer_hist_row);
|
||||
|
||||
if (isset($webalizer_hist_row['0'])
|
||||
&& isset($webalizer_hist_row['1'])
|
||||
&& isset($webalizer_hist_row['5'])
|
||||
) {
|
||||
$month = intval($webalizer_hist_row['0']);
|
||||
$year = intval($webalizer_hist_row['1']);
|
||||
$traffic = floatval($webalizer_hist_row['5']);
|
||||
|
||||
if (!isset($httptraffic[$year])) {
|
||||
$httptraffic[$year] = array();
|
||||
}
|
||||
|
||||
$httptraffic[$year][$month] = $traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($httptraffic);
|
||||
$httptrafficlast = array();
|
||||
$webalizer_lasthist = @file_get_contents($outputdir . 'webalizer.hist.1');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Gathering traffic information from '".$webalizer_lasthist."'");
|
||||
|
||||
$webalizer_lasthist_rows = explode("\n", $webalizer_lasthist);
|
||||
foreach ($webalizer_lasthist_rows as $webalizer_lasthist_row) {
|
||||
if ($webalizer_lasthist_row != '') {
|
||||
|
||||
$webalizer_lasthist_row = explode(' ', $webalizer_lasthist_row);
|
||||
|
||||
if (isset($webalizer_lasthist_row['0'])
|
||||
&& isset($webalizer_lasthist_row['1'])
|
||||
&& isset($webalizer_lasthist_row['5'])
|
||||
) {
|
||||
$month = intval($webalizer_lasthist_row['0']);
|
||||
$year = intval($webalizer_lasthist_row['1']);
|
||||
$traffic = floatval($webalizer_lasthist_row['5']);
|
||||
|
||||
if (!isset($httptrafficlast[$year])) {
|
||||
$httptrafficlast[$year] = array();
|
||||
}
|
||||
|
||||
$httptrafficlast[$year][$month] = $traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($httptrafficlast);
|
||||
foreach ($httptraffic as $year => $months) {
|
||||
foreach ($months as $month => $traffic) {
|
||||
if (!isset($httptrafficlast[$year][$month])) {
|
||||
$returnval+= $traffic;
|
||||
} elseif ($httptrafficlast[$year][$month] < $httptraffic[$year][$month]) {
|
||||
$returnval+= ($httptraffic[$year][$month] - $httptrafficlast[$year][$month]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return floatval($returnval);
|
||||
}
|
||||
|
||||
@@ -1,615 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
|
||||
// Check Traffic-Lock
|
||||
if (function_exists('pcntl_fork') && !defined('CRON_NOFORK_FLAG')) {
|
||||
$TrafficLock = makeCorrectFile(dirname($lockfile)."/froxlor_cron_traffic.lock");
|
||||
if (file_exists($TrafficLock)
|
||||
&& is_numeric($TrafficPid=file_get_contents($TrafficLock))
|
||||
) {
|
||||
if (function_exists('posix_kill')) {
|
||||
$TrafficPidStatus = @posix_kill($TrafficPid,0);
|
||||
} else {
|
||||
system("kill -CHLD " . $TrafficPid . " 1> /dev/null 2> /dev/null", $TrafficPidStatus);
|
||||
$TrafficPidStatus = $TrafficPidStatus ? false : true;
|
||||
}
|
||||
if ($TrafficPidStatus) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Traffic Run already in progress');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Create Traffic Log and Fork
|
||||
// We close the database - connection before we fork, so we don't share resources with the child
|
||||
Database::needRoot(false); // this forces the connection to be set to null
|
||||
$TrafficPid = pcntl_fork();
|
||||
// Parent
|
||||
if ($TrafficPid) {
|
||||
file_put_contents($TrafficLock, $TrafficPid);
|
||||
// unnecessary to recreate database connection here
|
||||
return 0;
|
||||
|
||||
}
|
||||
//Child
|
||||
elseif ($TrafficPid == 0) {
|
||||
posix_setsid();
|
||||
fclose($debugHandler);
|
||||
// re-create db
|
||||
Database::needRoot(false);
|
||||
}
|
||||
//Fork failed
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (extension_loaded('pcntl')) {
|
||||
$msg = "PHP compiled with pcntl but pcntl_fork function is not available.";
|
||||
} else {
|
||||
$msg = "PHP compiled without pcntl.";
|
||||
}
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, $msg." Not forking traffic-cron, this may take a long time!");
|
||||
}
|
||||
|
||||
require_once makeCorrectFile(dirname(__FILE__) . '/cron_traffic.inc.functions.php');
|
||||
|
||||
/**
|
||||
* TRAFFIC AND DISKUSAGE MESSURE
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Traffic run started...');
|
||||
$admin_traffic = array();
|
||||
$domainlist = array();
|
||||
$speciallogfile_domainlist = array();
|
||||
$result_domainlist_stmt = Database::query("
|
||||
SELECT `id`, `domain`, `customerid`, `parentdomainid`, `speciallogfile`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain` IS NULL AND `email_only` <> '1';
|
||||
");
|
||||
|
||||
while ($row_domainlist = $result_domainlist_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (!isset($domainlist[$row_domainlist['customerid']])) {
|
||||
$domainlist[$row_domainlist['customerid']] = array();
|
||||
}
|
||||
|
||||
$domainlist[$row_domainlist['customerid']][$row_domainlist['id']] = $row_domainlist['domain'];
|
||||
|
||||
if ($row_domainlist['parentdomainid'] == '0'
|
||||
&& $row_domainlist['speciallogfile'] == '1'
|
||||
) {
|
||||
if (!isset($speciallogfile_domainlist[$row_domainlist['customerid']])) {
|
||||
$speciallogfile_domainlist[$row_domainlist['customerid']] = array();
|
||||
}
|
||||
$speciallogfile_domainlist[$row_domainlist['customerid']][$row_domainlist['id']] = $row_domainlist['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
$mysqlusage_all = array();
|
||||
$databases_stmt = Database::query("SELECT * FROM " . TABLE_PANEL_DATABASES . " ORDER BY `dbserver`");
|
||||
$last_dbserver = 0;
|
||||
|
||||
$databases_list = array();
|
||||
Database::needRoot(true);
|
||||
$databases_list_result_stmt = Database::query("SHOW DATABASES");
|
||||
while ($databases_list_row = $databases_list_result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$databases_list[] = strtolower($databases_list_row['Database']);
|
||||
}
|
||||
|
||||
while ($row_database = $databases_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if ($last_dbserver != $row_database['dbserver']) {
|
||||
Database::needRoot(true, $row_database['dbserver']);
|
||||
$last_dbserver = $row_database['dbserver'];
|
||||
|
||||
$databases_list = array();
|
||||
$databases_list_result_stmt = Database::query("SHOW DATABASES");
|
||||
while ($databases_list_row = $databases_list_result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$databases_list[] = strtolower($databases_list_row['Database']);
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array(strtolower($row_database['databasename']), $databases_list)) {
|
||||
// sum up data_length and index_length
|
||||
$mysql_usage_result_stmt = Database::prepare("
|
||||
SELECT SUM(data_length + index_length) AS customerusage
|
||||
FROM information_schema.TABLES
|
||||
WHERE table_schema = :database
|
||||
GROUP BY table_schema;
|
||||
");
|
||||
// get the result
|
||||
$mysql_usage_row = Database::pexecute_first($mysql_usage_result_stmt, array('database' => $row_database['databasename']));
|
||||
// initialize counter for customer
|
||||
if (!isset($mysqlusage_all[$row_database['customerid']])) {
|
||||
$mysqlusage_all[$row_database['customerid']] = 0;
|
||||
}
|
||||
// sum up result
|
||||
$mysqlusage_all[$row_database['customerid']] += floatval($mysql_usage_row['customerusage']);
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Seems like the database " . $row_database['databasename'] . " had been removed manually.");
|
||||
}
|
||||
}
|
||||
|
||||
Database::needRoot(false);
|
||||
|
||||
// We are using the file-system quota, this will speed up the diskusage - collection
|
||||
if (Settings::Get('system.diskquota_enabled')) {
|
||||
$usedquota = getFilesystemQuota();
|
||||
}
|
||||
|
||||
/**
|
||||
* MAIL-Traffic
|
||||
*/
|
||||
if (Settings::Get("system.mailtraffic_enabled")) {
|
||||
$mailTrafficCalc = new \Froxlor\MailLogParser(Settings::Get("system.last_traffic_run"));
|
||||
}
|
||||
|
||||
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` ORDER BY `customerid` ASC");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
/**
|
||||
* HTTP-Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'http traffic for ' . $row['loginname'] . ' started...');
|
||||
$httptraffic = 0;
|
||||
|
||||
if (isset($domainlist[$row['customerid']])
|
||||
&& is_array($domainlist[$row['customerid']])
|
||||
&& count($domainlist[$row['customerid']]) != 0
|
||||
) {
|
||||
// Examining which caption to use for default webalizer stats...
|
||||
if ($row['standardsubdomain'] != '0') {
|
||||
// ... of course we'd prefer to use the standardsubdomain ...
|
||||
$caption = $domainlist[$row['customerid']][$row['standardsubdomain']];
|
||||
} else {
|
||||
// ... but if there is no standardsubdomain, we have to use the loginname ...
|
||||
$caption = $row['loginname'];
|
||||
|
||||
// ... which results in non-usable links to files in the stats, so lets have a look if we find a domain which is not speciallogfiledomain
|
||||
foreach ($domainlist[$row['customerid']] as $domainid => $domain) {
|
||||
|
||||
if (!isset($speciallogfile_domainlist[$row['customerid']])
|
||||
|| !isset($speciallogfile_domainlist[$row['customerid']][$domainid])
|
||||
) {
|
||||
$caption = $domain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$httptraffic = 0;
|
||||
reset($domainlist[$row['customerid']]);
|
||||
|
||||
if (isset($speciallogfile_domainlist[$row['customerid']])
|
||||
&& is_array($speciallogfile_domainlist[$row['customerid']])
|
||||
&& count($speciallogfile_domainlist[$row['customerid']]) != 0
|
||||
) {
|
||||
reset($speciallogfile_domainlist[$row['customerid']]);
|
||||
if (Settings::Get('system.awstats_enabled') == '0') {
|
||||
foreach ($speciallogfile_domainlist[$row['customerid']] as $domainid => $domain) {
|
||||
$httptraffic+= floatval(callWebalizerGetTraffic($row['loginname'] . '-' . $domain, $row['documentroot'] . '/webalizer/' . $domain . '/', $domain, $domainlist[$row['customerid']]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($domainlist[$row['customerid']]);
|
||||
|
||||
// callAwstatsGetTraffic is called ONLY HERE and
|
||||
// *not* also in the special-logfiles-loop, because the function
|
||||
// will iterate through all customer-domains and the awstats-configs
|
||||
// know the logfile-name, #246
|
||||
if (Settings::Get('system.awstats_enabled') == '1') {
|
||||
$httptraffic+= floatval(callAwstatsGetTraffic($row['customerid'], $row['documentroot'] . '/awstats/', $domainlist[$row['customerid']]));
|
||||
} else {
|
||||
$httptraffic+= floatval(callWebalizerGetTraffic($row['loginname'], $row['documentroot'] . '/webalizer/', $caption, $domainlist[$row['customerid']]));
|
||||
}
|
||||
|
||||
// make the stuff readable for the customer, #258
|
||||
makeChownWithNewStats($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* FTP-Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'ftp traffic for ' . $row['loginname'] . ' started...');
|
||||
$ftptraffic_stmt = Database::prepare("
|
||||
SELECT SUM(`up_bytes`) AS `up_bytes_sum`, SUM(`down_bytes`) AS `down_bytes_sum`
|
||||
FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :customerid
|
||||
");
|
||||
$ftptraffic = Database::pexecute_first($ftptraffic_stmt, array('customerid' => $row['customerid']));
|
||||
|
||||
if (!is_array($ftptraffic)) {
|
||||
$ftptraffic = array(
|
||||
'up_bytes_sum' => 0,
|
||||
'down_bytes_sum' => 0
|
||||
);
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_USERS . "` SET `up_bytes` = '0', `down_bytes` = '0' WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('customerid' => $row['customerid']));
|
||||
|
||||
/**
|
||||
* Mail-Traffic
|
||||
*/
|
||||
$mailtraffic = 0;
|
||||
if (Settings::Get("system.mailtraffic_enabled")) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'mail traffic usage for ' . $row['loginname'] . " started...");
|
||||
|
||||
$currentDate = date("Y-m-d");
|
||||
|
||||
$domains_stmt = Database::prepare("SELECT domain FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($domains_stmt, array("cid" => $row['customerid']));
|
||||
while ($domainRow = $domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$domainMailTraffic = $mailTrafficCalc->getDomainTraffic($domainRow["domain"]);
|
||||
if (!is_array($domainMailTraffic)) { continue; }
|
||||
|
||||
foreach ($domainMailTraffic as $dateTraffic => $dayTraffic) {
|
||||
$dayTraffic = floatval($dayTraffic / 1024);
|
||||
|
||||
list($year, $month, $day) = explode("-", $dateTraffic);
|
||||
if ($dateTraffic == $currentDate) {
|
||||
$mailtraffic = $dayTraffic;
|
||||
} else {
|
||||
// Check if an entry for the given day exists
|
||||
$stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE `customerid` = :cid
|
||||
AND `year` = :year
|
||||
AND `month` = :month
|
||||
AND `day` = :day");
|
||||
$params = array(
|
||||
"cid" => $row['customerid'],
|
||||
"year" => $year,
|
||||
"month" => $month,
|
||||
"day" => $day
|
||||
);
|
||||
Database::pexecute($stmt, $params);
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$updRow = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_TRAFFIC . "` SET
|
||||
`mail` = :mail
|
||||
WHERE `id` = :id");
|
||||
Database::pexecute($upd_stmt, array("mail" => $updRow['mail'] + $dayTraffic, "id" => $updRow['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Total Traffic
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'total traffic for ' . $row['loginname'] . ' started');
|
||||
$current_traffic = array();
|
||||
$current_traffic['http'] = floatval($httptraffic);
|
||||
$current_traffic['ftp_up'] = floatval(($ftptraffic['up_bytes_sum'] / 1024));
|
||||
$current_traffic['ftp_down'] = floatval(($ftptraffic['down_bytes_sum'] / 1024));
|
||||
$current_traffic['mail'] = floatval($mailtraffic);
|
||||
$current_traffic['all'] = $current_traffic['http'] + $current_traffic['ftp_up'] + $current_traffic['ftp_down'] + $current_traffic['mail'];
|
||||
|
||||
$ins_data = array(
|
||||
'customerid' => $row['customerid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'http' => $current_traffic['http'],
|
||||
'ftp_up' => $current_traffic['ftp_up'],
|
||||
'ftp_down' => $current_traffic['ftp_down'],
|
||||
'mail' => $current_traffic['mail']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TRAFFIC . "` SET
|
||||
`customerid` = :customerid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`http` = :http,
|
||||
`ftp_up` = :ftp_up,
|
||||
`ftp_down` = :ftp_down,
|
||||
`mail` = :mail
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
$sum_month_traffic_stmt = Database::prepare("
|
||||
SELECT SUM(`http`) AS `http`, SUM(`ftp_up`) AS `ftp_up`, SUM(`ftp_down`) AS `ftp_down`, SUM(`mail`) AS `mail`
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `year` = :year AND `month` = :month AND `customerid` = :customerid
|
||||
");
|
||||
$sum_month_traffic = Database::pexecute_first($sum_month_traffic_stmt, array('year' => date('Y', time()), 'month' => date('m', time()), 'customerid' => $row['customerid']));
|
||||
$sum_month_traffic['all'] = $sum_month_traffic['http'] + $sum_month_traffic['ftp_up'] + $sum_month_traffic['ftp_down'] + $sum_month_traffic['mail'];
|
||||
|
||||
if (!isset($admin_traffic[$row['adminid']])
|
||||
|| !is_array($admin_traffic[$row['adminid']])
|
||||
) {
|
||||
$admin_traffic[$row['adminid']]['http'] = 0;
|
||||
$admin_traffic[$row['adminid']]['ftp_up'] = 0;
|
||||
$admin_traffic[$row['adminid']]['ftp_down'] = 0;
|
||||
$admin_traffic[$row['adminid']]['mail'] = 0;
|
||||
$admin_traffic[$row['adminid']]['all'] = 0;
|
||||
$admin_traffic[$row['adminid']]['sum_month'] = 0;
|
||||
}
|
||||
|
||||
$admin_traffic[$row['adminid']]['http']+= $current_traffic['http'];
|
||||
$admin_traffic[$row['adminid']]['ftp_up']+= $current_traffic['ftp_up'];
|
||||
$admin_traffic[$row['adminid']]['ftp_down']+= $current_traffic['ftp_down'];
|
||||
$admin_traffic[$row['adminid']]['mail']+= $current_traffic['mail'];
|
||||
$admin_traffic[$row['adminid']]['all']+= $current_traffic['all'];
|
||||
$admin_traffic[$row['adminid']]['sum_month']+= $sum_month_traffic['all'];
|
||||
|
||||
/**
|
||||
* WebSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating webspace usage for ' . $row['loginname']);
|
||||
$webspaceusage = 0;
|
||||
|
||||
// Using repquota, it's faster using this tool than using du traversing the complete directory
|
||||
if (Settings::Get('system.diskquota_enabled')
|
||||
&& isset($usedquota[$row['guid']]['block']['used'])
|
||||
&& $usedquota[$row['guid']]['block']['used'] >= 1
|
||||
) {
|
||||
// We may use the array we created earlier, the used diskspace is stored in [<guid>][block][used]
|
||||
$webspaceusage = floatval($usedquota[$row['guid']]['block']['used']);
|
||||
|
||||
} else {
|
||||
|
||||
// Use the old fashioned way with "du"
|
||||
if (file_exists($row['documentroot'])
|
||||
&& is_dir($row['documentroot'])
|
||||
) {
|
||||
$back = safe_exec('du -sk ' . escapeshellarg($row['documentroot']) . '');
|
||||
foreach ($back as $backrow) {
|
||||
$webspaceusage = explode(' ', $backrow);
|
||||
}
|
||||
|
||||
$webspaceusage = floatval($webspaceusage['0']);
|
||||
unset($back);
|
||||
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, 'documentroot ' . $row['documentroot'] . ' does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MailSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating mailspace usage for ' . $row['loginname']);
|
||||
$emailusage = 0;
|
||||
|
||||
$maildir = makeCorrectDir(Settings::Get('system.vmail_homedir') . $row['loginname']);
|
||||
if (file_exists($maildir) && is_dir($maildir)) {
|
||||
$back = safe_exec('du -sk ' . escapeshellarg($maildir) . '');
|
||||
foreach ($back as $backrow) {
|
||||
$emailusage = explode(' ', $backrow);
|
||||
}
|
||||
|
||||
$emailusage = floatval($emailusage['0']);
|
||||
unset($back);
|
||||
|
||||
} else {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, 'maildir ' . $maildir . ' does not exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQLSpace-Usage
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'calculating mysqlspace usage for ' . $row['loginname']);
|
||||
$mysqlusage = 0;
|
||||
|
||||
if (isset($mysqlusage_all[$row['customerid']])) {
|
||||
$mysqlusage = floatval($mysqlusage_all[$row['customerid']] / 1024);
|
||||
}
|
||||
|
||||
$current_diskspace = array();
|
||||
$current_diskspace['webspace'] = floatval($webspaceusage);
|
||||
$current_diskspace['mail'] = floatval($emailusage);
|
||||
$current_diskspace['mysql'] = floatval($mysqlusage);
|
||||
$current_diskspace['all'] = $current_diskspace['webspace'] + $current_diskspace['mail'] + $current_diskspace['mysql'];
|
||||
|
||||
$ins_data = array(
|
||||
'customerid' => $row['customerid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'webspace' => $current_diskspace['webspace'],
|
||||
'mail' => $current_diskspace['mail'],
|
||||
'mysql' => $current_diskspace['mysql']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DISKSPACE . "` SET
|
||||
`customerid` = :customerid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`webspace` = :webspace,
|
||||
`mail` = :mail,
|
||||
`mysql` = :mysql
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
if (!isset($admin_diskspace[$row['adminid']])
|
||||
|| !is_array($admin_diskspace[$row['adminid']])
|
||||
) {
|
||||
$admin_diskspace[$row['adminid']] = array();
|
||||
$admin_diskspace[$row['adminid']]['webspace'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['mail'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['mysql'] = 0;
|
||||
$admin_diskspace[$row['adminid']]['all'] = 0;
|
||||
}
|
||||
|
||||
$admin_diskspace[$row['adminid']]['webspace']+= $current_diskspace['webspace'];
|
||||
$admin_diskspace[$row['adminid']]['mail']+= $current_diskspace['mail'];
|
||||
$admin_diskspace[$row['adminid']]['mysql']+= $current_diskspace['mysql'];
|
||||
$admin_diskspace[$row['adminid']]['all']+= $current_diskspace['all'];
|
||||
|
||||
/**
|
||||
* Total Usage
|
||||
*/
|
||||
$diskusage = floatval($webspaceusage + $emailusage + $mysqlusage);
|
||||
|
||||
$upd_data = array(
|
||||
'diskspace' => $current_diskspace['all'],
|
||||
'traffic' => $sum_month_traffic['all'],
|
||||
'customerid' => $row['customerid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET
|
||||
`diskspace_used` = :diskspace,
|
||||
`traffic_used` = :traffic
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
/**
|
||||
* Proftpd Quota
|
||||
*/
|
||||
$upd_data = array(
|
||||
'biu' => ($current_diskspace['all'] * 1024),
|
||||
'loginname' => $row['loginname'],
|
||||
'loginnamelike' => $row['loginname'] . Settings::Get('customer.ftpprefix') . "%"
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_QUOTATALLIES . "` SET
|
||||
`bytes_in_used` = :biu WHERE `name` = :loginname OR `name` LIKE :loginnamelike
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
/**
|
||||
* Pureftpd Quota
|
||||
*/
|
||||
if (Settings::Get('system.ftpserver') == "pureftpd") {
|
||||
|
||||
$result_quota_stmt = Database::prepare("
|
||||
SELECT homedir FROM `" . TABLE_FTP_USERS . "` WHERE customerid = :customerid
|
||||
");
|
||||
Database::pexecute($result_quota_stmt, array('customerid' => $row['customerid']));
|
||||
|
||||
// get correct user
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || Settings::Get('phpfpm.enabled') == 1) && $row['deactivated'] == '0') {
|
||||
$user = $row['loginname'];
|
||||
$group = $row['loginname'];
|
||||
} else {
|
||||
$user = $row['guid'];
|
||||
$group = $row['guid'];
|
||||
}
|
||||
|
||||
while ($row_quota = $result_quota_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$quotafile = "" . $row_quota['homedir'] . ".ftpquota";
|
||||
$fh = fopen($quotafile, 'w');
|
||||
$stringdata = "0 " . $current_diskspace['all']*1024 . "";
|
||||
fwrite($fh, $stringdata);
|
||||
fclose($fh);
|
||||
safe_exec('chown ' . $user . ':' . $group . ' ' . escapeshellarg($quotafile) . '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin Usage
|
||||
*/
|
||||
$result_stmt = Database::query("SELECT `adminid` FROM `" . TABLE_PANEL_ADMINS . "` ORDER BY `adminid` ASC");
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($admin_traffic[$row['adminid']])) {
|
||||
|
||||
$ins_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'http' => $admin_traffic[$row['adminid']]['http'],
|
||||
'ftp_up' => $admin_traffic[$row['adminid']]['ftp_up'],
|
||||
'ftp_down' => $admin_traffic[$row['adminid']]['ftp_down'],
|
||||
'mail' => $admin_traffic[$row['adminid']]['mail']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TRAFFIC_ADMINS . "` SET
|
||||
`adminid` = :adminid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`http` = :http,
|
||||
`ftp_up` = :ftp_up,
|
||||
`ftp_down` = :ftp_down,
|
||||
`mail` = :mail
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
|
||||
$upd_data = array(
|
||||
'traffic' => $admin_traffic[$row['adminid']]['sum_month'],
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`traffic_used` = :traffic
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
|
||||
if (isset($admin_diskspace[$row['adminid']])) {
|
||||
|
||||
$ins_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'year' => date('Y', time()),
|
||||
'month' => date('m', time()),
|
||||
'day' => date('d', time()),
|
||||
'stamp' => time(),
|
||||
'webspace' => $admin_diskspace[$row['adminid']]['webspace'],
|
||||
'mail' => $admin_diskspace[$row['adminid']]['mail'],
|
||||
'mysql' => $admin_diskspace[$row['adminid']]['mysql']
|
||||
);
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DISKSPACE_ADMINS . "` SET
|
||||
`adminid` = :adminid,
|
||||
`year` = :year,
|
||||
`month` = :month,
|
||||
`day` = :day,
|
||||
`stamp` = :stamp,
|
||||
`webspace` = :webspace,
|
||||
`mail` = :mail,
|
||||
`mysql` = :mysql
|
||||
");
|
||||
|
||||
$upd_data = array(
|
||||
'diskspace' => $admin_diskspace[$row['adminid']]['all'],
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`diskspace_used` = :diskspace
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = 'system' AND `varname` = 'last_traffic_run'");
|
||||
|
||||
if (function_exists('pcntl_fork') && !defined('CRON_NOFORK_FLAG')) {
|
||||
@unlink($TrafficLock);
|
||||
die();
|
||||
}
|
||||
@@ -1,347 +0,0 @@
|
||||
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Web- and Traffic-usage reporting started...');
|
||||
$yesterday = time() - (60 * 60 * 24);
|
||||
|
||||
/**
|
||||
* Initialize the mailingsystem
|
||||
*/
|
||||
$mail = new \PHPMailer\PHPMailer\PHPMailer(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)
|
||||
{
|
||||
// Warn the customers at xx% traffic-usage
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
|
||||
`c`.`company`, `c`.`traffic`, `c`.`email`, `c`.`def_language`,
|
||||
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` `t`
|
||||
WHERE `t`.`customerid` = `c`.`customerid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c`
|
||||
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` AS `a`
|
||||
ON `a`.`adminid` = `c`.`adminid` WHERE `c`.`reportsent` <> '1'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday)
|
||||
);
|
||||
Database::pexecute($result_stmt, $result_data);
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['traffic'])
|
||||
&& $row['traffic'] > 0
|
||||
&& $row['traffic_used'] != null
|
||||
&& (($row['traffic_used'] * 100) / $row['traffic']) >= (int)Settings::Get('system.report_trafficmax')
|
||||
) {
|
||||
$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
|
||||
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'TRAFFICUSED' => round(($row['traffic_used'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => round(($row['traffic_used'] * 100) / $row['traffic'], 2),
|
||||
'MAX_PERCENT' => Settings::Get('system.report_trafficmax')
|
||||
);
|
||||
|
||||
$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 makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once 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' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$result2_data['varname'] = 'trafficmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['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['firstname'] . ' ' . $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` = '1'
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('customerid' => $row['customerid']));
|
||||
}
|
||||
}
|
||||
|
||||
// Warn the admins at xx% traffic-usage
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `a`.*,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC_ADMINS . "` `t`
|
||||
WHERE `t`.`adminid` = `a`.`adminid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used_total`
|
||||
FROM `" . TABLE_PANEL_ADMINS . "` `a` WHERE `a`.`reportsent` = '0'
|
||||
");
|
||||
|
||||
$result_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday)
|
||||
);
|
||||
Database::pexecute($result_stmt, $result_data);
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
if (isset($row['traffic'])
|
||||
&& $row['traffic'] > 0
|
||||
&& (($row['traffic_used_total'] * 100) / $row['traffic']) >= (int)Settings::Get('system.report_trafficmax')
|
||||
) {
|
||||
|
||||
$replace_arr = array(
|
||||
'NAME' => $row['name'],
|
||||
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'TRAFFICUSED' => round(($row['traffic_used_total'] / 1024), 2), /* traffic is stored in KB, template uses MB */
|
||||
'USAGE_PERCENT' => round(($row['traffic_used_total'] * 100) / $row['traffic'], 2),
|
||||
'MAX_PERCENT' => Settings::Get('system.report_trafficmax')
|
||||
);
|
||||
|
||||
$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 makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
|
||||
// include admin/customer language file
|
||||
include_once 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
|
||||
");
|
||||
$resul2_data = array(
|
||||
'adminid' => $row['adminid'],
|
||||
'lang' => $row['def_language'],
|
||||
'varname' => 'trafficmaxpercent_subject'
|
||||
);
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
|
||||
|
||||
$resul2_data['varname'] = 'trafficmaxpercent_mailbody';
|
||||
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
|
||||
$mail_body = html_entity_decode(replace_variables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['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` = '1'
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array('adminid' => $row['adminid']));
|
||||
}
|
||||
|
||||
// Another month, let's build our report
|
||||
if (date('d') == '01') {
|
||||
|
||||
$mail_subject = 'Trafficreport ' . date("m/y", $yesterday) . ' for ' . $row['name'];
|
||||
$mail_body = 'Trafficreport ' . date("m/y", $yesterday) . ' for ' . $row['name'] . "\n";
|
||||
$mail_body.= '---------------------------------------------------------------' . "\n";
|
||||
$mail_body.= 'Loginname Traffic used (Percent) | Traffic available' . "\n";
|
||||
$customers_stmt = Database::prepare("
|
||||
SELECT `c`.*,
|
||||
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "` `t`
|
||||
WHERE `t`.`customerid` = `c`.`customerid` AND `t`.`year` = :year AND `t`.`month` = :month
|
||||
) as `traffic_used_total`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `c`.`adminid` = :adminid
|
||||
");
|
||||
$customers_data = array(
|
||||
'year' => date("Y", $yesterday),
|
||||
'month' => date("m", $yesterday),
|
||||
'adminid' => $row['adminid']
|
||||
);
|
||||
Database::pexecute($customers_stmt, $customers_data);
|
||||
|
||||
while ($customer = $customers_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$t = $customer['traffic_used_total']/1048576;
|
||||
if ($customer['traffic'] > 0) {
|
||||
$p = (($customer['traffic_used_total'] * 100) / $customer['traffic'] );
|
||||
$tg = $customer['traffic']/1048576;
|
||||
$str = sprintf('%00.1f GB ( %00.1f %% )', $t, $p);
|
||||
$mail_body.= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . sprintf('%00.1f GB', $tg) . "\n";
|
||||
} else if ($customer['traffic'] == 0) {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . '0' . "\n";
|
||||
} else {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $customer['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . 'unlimited' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$mail_body.= '---------------------------------------------------------------' . "\n";
|
||||
|
||||
$t = $row['traffic_used_total']/1048576;
|
||||
if ($row['traffic'] > 0) {
|
||||
$p = (($row['traffic_used_total'] * 100) / $row['traffic']);
|
||||
$tg = $row['traffic']/1048576;
|
||||
$str = sprintf('%00.1f GB ( %00.1f %% )', $t, $p);
|
||||
$mail_body.= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . sprintf('%00.1f GB', $tg) . "\n";
|
||||
} else if ($row['traffic'] == 0) {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . '0' . "\n";
|
||||
} else {
|
||||
$str = sprintf('%00.1f GB ( - )', $t);
|
||||
$mail_body.= sprintf('%-15s', $row['loginname']) . ' ' . sprintf('%-25s', $str) . ' ' . 'unlimited' . "\n";
|
||||
}
|
||||
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom($row['email'], $row['name']);
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->Body = $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();
|
||||
}
|
||||
}
|
||||
} // trafficmax > 0
|
||||
|
||||
// include diskspace-usage report, #466
|
||||
include dirname(__FILE__).'/cron_usage.inc.diskspace.php';
|
||||
|
||||
// Another month, reset the reportstatus
|
||||
if (date('d') == '01') {
|
||||
Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `reportsent` = '0';");
|
||||
Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `reportsent` = '0';");
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class DbManager {
|
||||
/**
|
||||
* main constructor
|
||||
*
|
||||
* @param \FroxlorLogger $log
|
||||
* @param \Froxlor\FroxlorLogger $log
|
||||
*/
|
||||
public function __construct($log = null) {
|
||||
$this->_log = $log;
|
||||
|
||||
@@ -46,7 +46,7 @@ class DbManagerMySQL
|
||||
/**
|
||||
* main constructor
|
||||
*
|
||||
* @param \FroxlorLogger $log
|
||||
* @param \Froxlor\FroxlorLogger $log
|
||||
*/
|
||||
public function __construct(&$log = null)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
namespace Froxlor\Dns;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -12,7 +15,7 @@
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DnsEntry
|
||||
{
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
namespace Froxlor\Dns;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -12,7 +13,7 @@
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DnsZone
|
||||
{
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
namespace Froxlor\Dns;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -12,7 +15,7 @@
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*
|
||||
*/
|
||||
class PowerDNS
|
||||
{
|
||||
@@ -71,8 +74,8 @@ class PowerDNS
|
||||
|
||||
// try to connect
|
||||
try {
|
||||
self::$pdns_db = new PDO($dsn, $mysql_data['gmysql-user'], $mysql_data['gmysql-password'], $options);
|
||||
} catch (PDOException $e) {
|
||||
self::$pdns_db = new \PDO($dsn, $mysql_data['gmysql-user'], $mysql_data['gmysql-password'], $options);
|
||||
} catch (\PDOException $e) {
|
||||
die($e->getMessage());
|
||||
}
|
||||
|
||||
@@ -81,22 +84,22 @@ class PowerDNS
|
||||
self::$pdns_db->setAttribute(constant("PDO::" . $k), constant("PDO::" . $v));
|
||||
}
|
||||
|
||||
$version_server = self::$pdns_db->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
$version_server = self::$pdns_db->getAttribute(\PDO::ATTR_SERVER_VERSION);
|
||||
$sql_mode = 'NO_ENGINE_SUBSTITUTION';
|
||||
if (version_compare($version_server, '8.0.11', '<')) {
|
||||
$sql_mode .= ',NO_AUTO_CREATE_USER';
|
||||
}
|
||||
self::$pdns_db->exec('SET sql_mode = "'.$sql_mode.'"');
|
||||
self::$pdns_db->exec('SET sql_mode = "' . $sql_mode . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* get pdo database connection to powerdns database
|
||||
*
|
||||
* @return PDO
|
||||
* @return \PDO
|
||||
*/
|
||||
public static function getDB()
|
||||
{
|
||||
if (! isset(self::$pdns_db) || (self::$pdns_db instanceof PDO) == false) {
|
||||
if (! isset(self::$pdns_db) || (self::$pdns_db instanceof \PDO) == false) {
|
||||
self::connectToPdnsDb();
|
||||
}
|
||||
return self::$pdns_db;
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
|
||||
final class Froxlor
|
||||
{
|
||||
|
||||
@@ -8,7 +10,7 @@ final class Froxlor
|
||||
const VERSION = '0.10.0';
|
||||
|
||||
// Database version (YYYYMMDDC where C is a daily counter)
|
||||
const DBVERSION = '201812170';
|
||||
const DBVERSION = '201812190';
|
||||
|
||||
// Distribution branding-tag (used for Debian etc.)
|
||||
const BRANDING = '';
|
||||
@@ -95,4 +97,108 @@ final class Froxlor
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function isDatabaseVersion
|
||||
*
|
||||
* checks if a given database-version is the current one
|
||||
*
|
||||
* @param int $to_check
|
||||
* version to check
|
||||
*
|
||||
* @return bool true if version to check matches, else false
|
||||
*/
|
||||
public static function isDatabaseVersion($to_check = null)
|
||||
{
|
||||
if (Settings::Get('panel.frontend') == 'froxlor' && Settings::Get('panel.db_version') == $to_check) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function updateToDbVersion
|
||||
*
|
||||
* updates the panel.version field
|
||||
* to the given value (no checks here!)
|
||||
*
|
||||
* @param string $new_version
|
||||
* new-version
|
||||
*
|
||||
* @return bool true on success, else false
|
||||
*/
|
||||
public static function updateToDbVersion($new_version = null)
|
||||
{
|
||||
if ($new_version !== null && $new_version != '') {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :newversion
|
||||
WHERE `settinggroup` = 'panel' AND `varname` = 'db_version'");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'newversion' => $new_version
|
||||
));
|
||||
Settings::Set('panel.db_version', $new_version);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function updateToVersion
|
||||
*
|
||||
* updates the panel.version field
|
||||
* to the given value (no checks here!)
|
||||
*
|
||||
* @param string $new_version
|
||||
* new-version
|
||||
*
|
||||
* @return bool true on success, else false
|
||||
*/
|
||||
public static function updateToVersion($new_version = null)
|
||||
{
|
||||
if ($new_version !== null && $new_version != '') {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :newversion
|
||||
WHERE `settinggroup` = 'panel' AND `varname` = 'version'");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'newversion' => $new_version
|
||||
));
|
||||
Settings::Set('panel.version', $new_version);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function isFroxlor
|
||||
*
|
||||
* checks if the panel is froxlor
|
||||
*
|
||||
* @return bool true if panel is froxlor, else false
|
||||
*/
|
||||
public static function isFroxlor()
|
||||
{
|
||||
if (Settings::Get('panel.frontend') !== null && Settings::Get('panel.frontend') == 'froxlor') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function isFroxlorVersion
|
||||
*
|
||||
* checks if a given version is the
|
||||
* current one (and panel is froxlor)
|
||||
*
|
||||
* @param string $to_check
|
||||
* version to check
|
||||
*
|
||||
* @return bool true if version to check matches, else false
|
||||
*/
|
||||
public static function isFroxlorVersion($to_check = null)
|
||||
{
|
||||
if (Settings::Get('panel.frontend') == 'froxlor' && Settings::Get('panel.version') == $to_check) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
namespace Froxlor\Http;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,24 +9,27 @@
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.33
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
* @since 0.9.33
|
||||
*
|
||||
*/
|
||||
use Froxlor\Database;
|
||||
use Froxlor\FileDir;
|
||||
|
||||
/**
|
||||
* Class frxDirectory handles directory actions and gives information
|
||||
* about a given directory in connections with its usage in froxlor
|
||||
*
|
||||
* @author Michael Kaufmann (d00p) <d00p@froxlor.org>
|
||||
*
|
||||
*
|
||||
*/
|
||||
class frxDirectory {
|
||||
class Directory
|
||||
{
|
||||
|
||||
/**
|
||||
* directory string
|
||||
@@ -39,18 +43,22 @@ class frxDirectory {
|
||||
*
|
||||
* @param string $dir
|
||||
*/
|
||||
public function __construct($dir = null) {
|
||||
public function __construct($dir = null)
|
||||
{
|
||||
$this->_dir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the directory has options set in panel_htaccess
|
||||
*/
|
||||
public function hasUserOptions() {
|
||||
public function hasUserOptions()
|
||||
{
|
||||
$uo_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) as `usropts` FROM `".TABLE_PANEL_HTACCESS."` WHERE `path` = :dir
|
||||
SELECT COUNT(`id`) as `usropts` FROM `" . TABLE_PANEL_HTACCESS . "` WHERE `path` = :dir
|
||||
");
|
||||
$uo_res = Database::pexecute_first($uo_stmt, array('dir' => makeCorrectDir($this->_dir)));
|
||||
$uo_res = Database::pexecute_first($uo_stmt, array(
|
||||
'dir' => FileDir::makeCorrectDir($this->_dir)
|
||||
));
|
||||
if ($uo_res != false && isset($uo_res['usropts'])) {
|
||||
return ($uo_res['usropts'] > 0 ? true : false);
|
||||
}
|
||||
@@ -60,11 +68,14 @@ class frxDirectory {
|
||||
/**
|
||||
* check whether the directory is protected using panel_htpasswd
|
||||
*/
|
||||
public function isUserProtected() {
|
||||
public function isUserProtected()
|
||||
{
|
||||
$up_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) as `usrprot` FROM `".TABLE_PANEL_HTPASSWDS."` WHERE `path` = :dir
|
||||
SELECT COUNT(`id`) as `usrprot` FROM `" . TABLE_PANEL_HTPASSWDS . "` WHERE `path` = :dir
|
||||
");
|
||||
$up_res = Database::pexecute_first($up_stmt, array('dir' => makeCorrectDir($this->_dir)));
|
||||
$up_res = Database::pexecute_first($up_stmt, array(
|
||||
'dir' => FileDir::makeCorrectDir($this->_dir)
|
||||
));
|
||||
if ($up_res != false && isset($up_res['usrprot'])) {
|
||||
return ($up_res['usrprot'] > 0 ? true : false);
|
||||
}
|
||||
@@ -75,14 +86,15 @@ class frxDirectory {
|
||||
* Checks if a given directory is valid for multiple configurations
|
||||
* or should rather be used as a single file
|
||||
*
|
||||
* @param bool $ifexists also check whether file/dir exists
|
||||
*
|
||||
* @param bool $ifexists
|
||||
* also check whether file/dir exists
|
||||
*
|
||||
* @return bool true if usable as dir, false otherwise
|
||||
*/
|
||||
public function isConfigDir($ifexists = false) {
|
||||
|
||||
public function isConfigDir($ifexists = false)
|
||||
{
|
||||
if (is_null($this->_dir)) {
|
||||
trigger_error(__CLASS__.'::'.__FUNCTION__.' has been called with a null value', E_USER_WARNING);
|
||||
trigger_error(__CLASS__ . '::' . __FUNCTION__ . ' has been called with a null value', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -93,8 +105,8 @@ class frxDirectory {
|
||||
$returnval = false;
|
||||
}
|
||||
} else {
|
||||
if (!$ifexists) {
|
||||
if (substr($this->_dir, -1) == '/') {
|
||||
if (! $ifexists) {
|
||||
if (substr($this->_dir, - 1) == '/') {
|
||||
$returnval = true;
|
||||
} else {
|
||||
$returnval = false;
|
||||
@@ -105,5 +117,4 @@ class frxDirectory {
|
||||
}
|
||||
return $returnval;
|
||||
}
|
||||
|
||||
}
|
||||
21
lib/Froxlor/Http/LetsEncrypt/Base64UrlSafeEncoder.php
Normal file
21
lib/Froxlor/Http/LetsEncrypt/Base64UrlSafeEncoder.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Froxlor\Http\LetsEncrypt;
|
||||
|
||||
class Base64UrlSafeEncoder
|
||||
{
|
||||
|
||||
public static function encode($input)
|
||||
{
|
||||
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
|
||||
}
|
||||
|
||||
public static function decode($input)
|
||||
{
|
||||
$remainder = strlen($input) % 4;
|
||||
if ($remainder) {
|
||||
$padlen = 4 - $remainder;
|
||||
$input .= str_repeat('=', $padlen);
|
||||
}
|
||||
return base64_decode(strtr($input, '-_', '+/'));
|
||||
}
|
||||
}
|
||||
98
lib/Froxlor/Http/LetsEncrypt/Client.php
Normal file
98
lib/Froxlor/Http/LetsEncrypt/Client.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
namespace Froxlor\Http\LetsEncrypt;
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
private $lastCode;
|
||||
|
||||
private $lastHeader;
|
||||
|
||||
private $base;
|
||||
|
||||
public function __construct($base)
|
||||
{
|
||||
$this->base = $base;
|
||||
}
|
||||
|
||||
private function curl($method, $url, $data = null)
|
||||
{
|
||||
$headers = array(
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/json'
|
||||
);
|
||||
$handle = curl_init();
|
||||
curl_setopt($handle, CURLOPT_URL, preg_match('~^http~', $url) ? $url : $this->base . $url);
|
||||
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($handle, CURLOPT_HEADER, true);
|
||||
|
||||
// DO NOT DO THAT!
|
||||
// curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
|
||||
// curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
break;
|
||||
case 'POST':
|
||||
curl_setopt($handle, CURLOPT_POST, true);
|
||||
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
}
|
||||
$response = curl_exec($handle);
|
||||
|
||||
if (curl_errno($handle)) {
|
||||
throw new \RuntimeException('Curl: ' . curl_error($handle));
|
||||
}
|
||||
|
||||
$header_size = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
|
||||
|
||||
$header = substr($response, 0, $header_size);
|
||||
$body = substr($response, $header_size);
|
||||
|
||||
$this->lastHeader = $header;
|
||||
$this->lastCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
||||
|
||||
$data = json_decode($body, true);
|
||||
return $data === null ? $body : $data;
|
||||
}
|
||||
|
||||
public function post($url, $data)
|
||||
{
|
||||
return $this->curl('POST', $url, $data);
|
||||
}
|
||||
|
||||
public function get($url)
|
||||
{
|
||||
return $this->curl('GET', $url);
|
||||
}
|
||||
|
||||
public function getLastNonce()
|
||||
{
|
||||
if (preg_match('~Replay\-Nonce: (.+)~i', $this->lastHeader, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
$this->curl('GET', '/directory');
|
||||
return $this->getLastNonce();
|
||||
}
|
||||
|
||||
public function getLastLocation()
|
||||
{
|
||||
if (preg_match('~Location: (.+)~i', $this->lastHeader, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getLastCode()
|
||||
{
|
||||
return $this->lastCode;
|
||||
}
|
||||
|
||||
public function getLastLinks()
|
||||
{
|
||||
preg_match_all('~Link: <(.+)>;rel="up"~', $this->lastHeader, $matches);
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
<?php
|
||||
namespace Froxlor\Http\LetsEncrypt;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
// Copyright (c) 2015, Stanislav Humplik <sh@analogic.cz>
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -26,11 +31,10 @@
|
||||
|
||||
// This file is copied from https://github.com/analogic/lescript
|
||||
// and modified to work without files and integrate in Froxlor
|
||||
class lescript
|
||||
class LeScript
|
||||
{
|
||||
|
||||
// https://letsencrypt.org/repository/
|
||||
|
||||
private $logger;
|
||||
|
||||
private $client;
|
||||
@@ -62,13 +66,13 @@ class lescript
|
||||
{
|
||||
// Let's see if we have the private accountkey
|
||||
$this->accountKey = $certrow['leprivatekey'];
|
||||
$this->customerId = (!$isFroxlorVhost ? $certrow['customerid'] : null);
|
||||
$this->customerId = (! $isFroxlorVhost ? $certrow['customerid'] : null);
|
||||
$this->isFroxlorVhost = $isFroxlorVhost;
|
||||
$this->isLeProduction = (Settings::Get('system.letsencryptca') == 'production');
|
||||
|
||||
$leregistered=$certrow['leregistered'];
|
||||
$leregistered = $certrow['leregistered'];
|
||||
|
||||
if (! $this->accountKey || $this->accountKey == 'unset' || !$this->isLeProduction) {
|
||||
if (! $this->accountKey || $this->accountKey == 'unset' || ! $this->isLeProduction) {
|
||||
|
||||
// generate and save new private key for account
|
||||
// ---------------------------------------------
|
||||
@@ -91,13 +95,13 @@ class lescript
|
||||
));
|
||||
}
|
||||
}
|
||||
$leregistered=0;
|
||||
$leregistered = 0;
|
||||
$this->accountKey = $keys['private'];
|
||||
} else {
|
||||
$this->log('Using existing account key');
|
||||
}
|
||||
|
||||
if ($leregistered==0) { // Account not registered
|
||||
if ($leregistered == 0) { // Account not registered
|
||||
|
||||
$this->log('Starting new account registration');
|
||||
$response = $this->postNewReg();
|
||||
@@ -108,13 +112,12 @@ class lescript
|
||||
} else {
|
||||
throw new \RuntimeException("Account not initialized, probably due to rate limiting. Whole response: " . json_encode($response));
|
||||
}
|
||||
$accountUrl=$this->client->getLastLocation();
|
||||
$accountUrl = $this->client->getLastLocation();
|
||||
|
||||
$leregistered = 1;
|
||||
$this->setLeRegisteredState($leregistered); // Account registered
|
||||
$this->log('Lets encrypt Terms of Service accepted');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,7 +126,7 @@ class lescript
|
||||
* @param string $domainkey
|
||||
* @param string $csr
|
||||
* optional, same behavior as $reuseCsr from the original class, but we're passing the content of the csr already
|
||||
*
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return string[]
|
||||
*/
|
||||
@@ -159,18 +162,18 @@ class lescript
|
||||
if ($this->client->getLastCode() == 403) {
|
||||
$this->log("Got status 403 - setting LE status to unregistered.");
|
||||
$this->setLeRegisteredState(0);
|
||||
throw new RuntimeException("Got 'unauthorized' response - we need to re-register at next run. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("Got 'unauthorized' response - we need to re-register at next run. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
// if response is not an array but a string, it's most likely a server-error, e.g.
|
||||
// <HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY>An error occurred while processing your request.
|
||||
// <p>Reference #179.d8be1402.1458059103.3613c4db</BODY></HTML>
|
||||
if (! is_array($response)) {
|
||||
throw new RuntimeException("Invalid response from LE for domain $domain. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("Invalid response from LE for domain $domain. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
if (! array_key_exists('challenges', $response)) {
|
||||
throw new RuntimeException("No challenges received for $domain. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("No challenges received for $domain. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
// choose http-01 challenge only
|
||||
@@ -179,7 +182,7 @@ class lescript
|
||||
});
|
||||
|
||||
if (! $challenge) {
|
||||
throw new RuntimeException("HTTP Challenge for $domain is not available. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("HTTP Challenge for $domain is not available. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
$this->log("Got challenge token for $domain");
|
||||
@@ -214,9 +217,8 @@ class lescript
|
||||
$this->log("Token for $domain saved at $tokenPath and should be available at $uri");
|
||||
|
||||
// simple self check
|
||||
if (Settings::Get('system.disable_le_selfcheck') == '0')
|
||||
{
|
||||
$selfcheckpayload = HttpClient::urlGet($uri, false);
|
||||
if (Settings::Get('system.disable_le_selfcheck') == '0') {
|
||||
$selfcheckpayload = \Froxlor\Http\HttpClient::urlGet($uri, false);
|
||||
if ($payload !== trim($selfcheckpayload)) {
|
||||
$errmsg = json_encode(error_get_last());
|
||||
if ($errmsg != "null") {
|
||||
@@ -300,23 +302,22 @@ class lescript
|
||||
|
||||
$this->log("Certificate generation pending, sleeping 1s");
|
||||
sleep(1);
|
||||
} else
|
||||
if ($this->client->getLastCode() == 200) {
|
||||
} else if ($this->client->getLastCode() == 200) {
|
||||
|
||||
$this->log("Got certificate! YAY!");
|
||||
$this->log("Got certificate! YAY!");
|
||||
$certificates[] = $this->parsePemFromBody($result);
|
||||
|
||||
foreach ($this->client->getLastLinks() as $link) {
|
||||
$this->log("Requesting chained cert at $link");
|
||||
$result = $this->client->get($link);
|
||||
$certificates[] = $this->parsePemFromBody($result);
|
||||
|
||||
foreach ($this->client->getLastLinks() as $link) {
|
||||
$this->log("Requesting chained cert at $link");
|
||||
$result = $this->client->get($link);
|
||||
$certificates[] = $this->parsePemFromBody($result);
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
|
||||
throw new \RuntimeException("Can't get certificate: HTTP code " . $this->client->getLastCode());
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
|
||||
throw new \RuntimeException("Can't get certificate: HTTP code " . $this->client->getLastCode());
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($certificates))
|
||||
@@ -361,7 +362,7 @@ class lescript
|
||||
{
|
||||
$this->log('Getting last terms of service URL');
|
||||
$directory = $this->client->get('/directory');
|
||||
if (!isset($directory['meta']) || !isset($directory['meta']['terms-of-service'])) {
|
||||
if (! isset($directory['meta']) || ! isset($directory['meta']['terms-of-service'])) {
|
||||
throw new \RuntimeException("No terms of service link available!");
|
||||
}
|
||||
$this->log('Sending registration to letsencrypt server');
|
||||
@@ -478,118 +479,3 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, "letsencrypt " . $message);
|
||||
}
|
||||
}
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
private $lastCode;
|
||||
|
||||
private $lastHeader;
|
||||
|
||||
private $base;
|
||||
|
||||
public function __construct($base)
|
||||
{
|
||||
$this->base = $base;
|
||||
}
|
||||
|
||||
private function curl($method, $url, $data = null)
|
||||
{
|
||||
$headers = array(
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/json'
|
||||
);
|
||||
$handle = curl_init();
|
||||
curl_setopt($handle, CURLOPT_URL, preg_match('~^http~', $url) ? $url : $this->base . $url);
|
||||
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($handle, CURLOPT_HEADER, true);
|
||||
|
||||
// DO NOT DO THAT!
|
||||
// curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
|
||||
// curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
break;
|
||||
case 'POST':
|
||||
curl_setopt($handle, CURLOPT_POST, true);
|
||||
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
}
|
||||
$response = curl_exec($handle);
|
||||
|
||||
if (curl_errno($handle)) {
|
||||
throw new \RuntimeException('Curl: ' . curl_error($handle));
|
||||
}
|
||||
|
||||
$header_size = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
|
||||
|
||||
$header = substr($response, 0, $header_size);
|
||||
$body = substr($response, $header_size);
|
||||
|
||||
$this->lastHeader = $header;
|
||||
$this->lastCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
||||
|
||||
$data = json_decode($body, true);
|
||||
return $data === null ? $body : $data;
|
||||
}
|
||||
|
||||
public function post($url, $data)
|
||||
{
|
||||
return $this->curl('POST', $url, $data);
|
||||
}
|
||||
|
||||
public function get($url)
|
||||
{
|
||||
return $this->curl('GET', $url);
|
||||
}
|
||||
|
||||
public function getLastNonce()
|
||||
{
|
||||
if (preg_match('~Replay\-Nonce: (.+)~i', $this->lastHeader, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
$this->curl('GET', '/directory');
|
||||
return $this->getLastNonce();
|
||||
}
|
||||
|
||||
public function getLastLocation()
|
||||
{
|
||||
if (preg_match('~Location: (.+)~i', $this->lastHeader, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getLastCode()
|
||||
{
|
||||
return $this->lastCode;
|
||||
}
|
||||
|
||||
public function getLastLinks()
|
||||
{
|
||||
preg_match_all('~Link: <(.+)>;rel="up"~', $this->lastHeader, $matches);
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
class Base64UrlSafeEncoder
|
||||
{
|
||||
|
||||
public static function encode($input)
|
||||
{
|
||||
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
|
||||
}
|
||||
|
||||
public static function decode($input)
|
||||
{
|
||||
$remainder = strlen($input) % 4;
|
||||
if ($remainder) {
|
||||
$padlen = 4 - $remainder;
|
||||
$input .= str_repeat('=', $padlen);
|
||||
}
|
||||
return base64_decode(strtr($input, '-_', '+/'));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Http\LetsEncrypt;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
// Copyright (c) 2015, Stanislav Humplik <sh@analogic.cz>
|
||||
// All rights reserved.
|
||||
@@ -27,7 +31,7 @@
|
||||
|
||||
// This file is copied from https://github.com/analogic/lescript
|
||||
// and modified to work without files and integrate in Froxlor
|
||||
class lescript_v2
|
||||
class LeScript_v2
|
||||
{
|
||||
|
||||
// https://letsencrypt.org/repository/
|
||||
@@ -60,7 +64,7 @@ class lescript_v2
|
||||
}
|
||||
$this->client = new Client($ca);
|
||||
$this->log("Using '$ca' to generate certificate");
|
||||
|
||||
|
||||
// get request-uris from /directory
|
||||
$response = $this->client->get('/directory');
|
||||
$this->_req_uris['newAccount'] = $response['newAccount'];
|
||||
@@ -77,14 +81,14 @@ class lescript_v2
|
||||
$this->isFroxlorVhost = $isFroxlorVhost;
|
||||
$this->isLeProduction = (Settings::Get('system.letsencryptca') == 'production');
|
||||
$this->_acc_location = $certrow['leaccount'];
|
||||
|
||||
|
||||
$leregistered = $certrow['leregistered'];
|
||||
|
||||
|
||||
if (! $this->accountKey || $this->accountKey == 'unset' || ! $this->isLeProduction) {
|
||||
|
||||
|
||||
// generate and save new private key for account
|
||||
// ---------------------------------------------
|
||||
|
||||
|
||||
$this->log('Creating new account key');
|
||||
$keys = $this->generateKey();
|
||||
// Only store the accountkey in production, in staging always generate a new key
|
||||
@@ -108,9 +112,9 @@ class lescript_v2
|
||||
} else {
|
||||
$this->log('Using existing account key');
|
||||
}
|
||||
|
||||
|
||||
if ($leregistered == 0) { // Account not registered
|
||||
|
||||
|
||||
$this->log('Starting new account registration');
|
||||
$response = $this->postNewReg();
|
||||
if ($this->client->getLastCode() == 409) {
|
||||
@@ -121,7 +125,7 @@ class lescript_v2
|
||||
throw new \RuntimeException("Account not initialized, probably due to rate limiting. Whole response: " . json_encode($response));
|
||||
}
|
||||
$this->_acc_location = $this->client->getLastLocation();
|
||||
|
||||
|
||||
$leregistered = 1;
|
||||
$this->setLeRegisteredState($leregistered);
|
||||
}
|
||||
@@ -142,19 +146,19 @@ class lescript_v2
|
||||
if (! $this->accountKey) {
|
||||
throw new \RuntimeException("Account not initialized");
|
||||
}
|
||||
|
||||
|
||||
$this->log('Starting certificate generation process for domains');
|
||||
|
||||
|
||||
$privateAccountKey = openssl_pkey_get_private($this->accountKey);
|
||||
$accountKeyDetails = openssl_pkey_get_details($privateAccountKey);
|
||||
|
||||
|
||||
// start domains authentication
|
||||
// ----------------------------
|
||||
|
||||
// Prepare order
|
||||
$domains_in_order = array();
|
||||
foreach ($domains as $domain) {
|
||||
$domains_in_order []= array(
|
||||
$domains_in_order[] = array(
|
||||
"type" => "dns",
|
||||
"value" => $domain
|
||||
);
|
||||
@@ -164,68 +168,68 @@ class lescript_v2
|
||||
$response = $this->signedRequest($this->_req_uris['newOrder'], array(
|
||||
"identifiers" => $domains_in_order
|
||||
), false);
|
||||
|
||||
|
||||
if ($this->client->getLastCode() == 403) {
|
||||
$this->log("Got status 403 - setting LE status to unregistered.");
|
||||
$this->_acc_location = '';
|
||||
$this->setLeRegisteredState(0);
|
||||
throw new RuntimeException("Got 'unauthorized' response - we need to re-register at next run. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("Got 'unauthorized' response - we need to re-register at next run. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
|
||||
// if response is not an array but a string, it's most likely a server-error, e.g.
|
||||
// <HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY>An error occurred while processing your request.
|
||||
// <p>Reference #179.d8be1402.1458059103.3613c4db</BODY></HTML>
|
||||
if (! is_array($response)) {
|
||||
throw new RuntimeException("Invalid response from LE for domain $domain. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("Invalid response from LE for domain $domain. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
|
||||
if (! array_key_exists('authorizations', $response)) {
|
||||
throw new RuntimeException("No authorizations received for $domain. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("No authorizations received for $domain. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
$authorizations = $response['authorizations'];
|
||||
$finalizeLink = $response['finalize'];
|
||||
|
||||
$i = 0;
|
||||
|
||||
|
||||
foreach ($authorizations as $authorization) {
|
||||
|
||||
|
||||
// 1. getting available authentication options
|
||||
// -------------------------------------------
|
||||
|
||||
$domain = $response['identifiers'][$i++]['value'];
|
||||
|
||||
$domain = $response['identifiers'][$i ++]['value'];
|
||||
|
||||
$this->log("Requesting challenge for $domain");
|
||||
|
||||
|
||||
// get authorization
|
||||
$auth_response = $this->client->get($authorization);
|
||||
|
||||
|
||||
if (! array_key_exists('challenges', $auth_response)) {
|
||||
throw new RuntimeException("No challenges received for $domain. Whole response: " . json_encode($auth_response));
|
||||
throw new \RuntimeException("No challenges received for $domain. Whole response: " . json_encode($auth_response));
|
||||
}
|
||||
|
||||
|
||||
// choose http-01 challenge only
|
||||
$challenge = array_reduce($auth_response['challenges'], function ($v, $w) {
|
||||
return $v ? $v : ($w['type'] == 'http-01' ? $w : false);
|
||||
});
|
||||
|
||||
|
||||
if (! $challenge) {
|
||||
throw new RuntimeException("HTTP Challenge for $domain is not available. Whole response: " . json_encode($response));
|
||||
throw new \RuntimeException("HTTP Challenge for $domain is not available. Whole response: " . json_encode($response));
|
||||
}
|
||||
|
||||
|
||||
$this->log("Got challenge token for $domain");
|
||||
$location = $challenge['url'];
|
||||
|
||||
|
||||
// 2. saving authentication token for web verification
|
||||
// ---------------------------------------------------
|
||||
|
||||
|
||||
$directory = Settings::Get('system.letsencryptchallengepath') . '/.well-known/acme-challenge';
|
||||
$tokenPath = $directory . '/' . $challenge['token'];
|
||||
|
||||
|
||||
if (! file_exists($directory) && ! @mkdir($directory, 0755, true)) {
|
||||
throw new \RuntimeException("Couldn't create directory to expose challenge: ${tokenPath}");
|
||||
}
|
||||
|
||||
|
||||
$header = array(
|
||||
// need to be in precise order!
|
||||
"e" => Base64UrlSafeEncoder::encode($accountKeyDetails["rsa"]["e"]),
|
||||
@@ -233,20 +237,20 @@ class lescript_v2
|
||||
"n" => Base64UrlSafeEncoder::encode($accountKeyDetails["rsa"]["n"])
|
||||
);
|
||||
$payload = $challenge['token'] . '.' . Base64UrlSafeEncoder::encode(hash('sha256', json_encode($header), true));
|
||||
|
||||
|
||||
file_put_contents($tokenPath, $payload);
|
||||
chmod($tokenPath, 0644);
|
||||
|
||||
|
||||
// 3. verification process itself
|
||||
// -------------------------------
|
||||
|
||||
|
||||
$uri = "http://${domain}/.well-known/acme-challenge/${challenge['token']}";
|
||||
|
||||
|
||||
$this->log("Token for $domain saved at $tokenPath and should be available at $uri");
|
||||
|
||||
|
||||
// simple self check
|
||||
if (Settings::Get('system.disable_le_selfcheck') == '0') {
|
||||
$selfcheckpayload = HttpClient::urlGet($uri, false);
|
||||
$selfcheckpayload = \Froxlor\Http\HttpClient::urlGet($uri, false);
|
||||
if ($payload !== trim($selfcheckpayload)) {
|
||||
$errmsg = json_encode(error_get_last());
|
||||
if ($errmsg != "null") {
|
||||
@@ -257,16 +261,16 @@ class lescript_v2
|
||||
$this->logger->logAction(CRON_ACTION, LOG_WARNING, "[Lets Encrypt self-check] Please check $uri - token seems to be not available. This is just a simple self-check, it might be wrong but consider using this information when Let's Encrypt fails to issue a certificate" . $errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->log("Sending request to challenge");
|
||||
|
||||
|
||||
// send request to challenge
|
||||
$result = $this->signedRequest($challenge['url'], array(
|
||||
"type" => "http-01",
|
||||
"keyAuthorization" => $payload,
|
||||
"token" => $challenge['token']
|
||||
), false);
|
||||
|
||||
|
||||
// waiting loop
|
||||
// we wait for a maximum of 30 seconds to avoid endless loops
|
||||
$count = 0;
|
||||
@@ -276,36 +280,36 @@ class lescript_v2
|
||||
throw new \RuntimeException("Verification ended with error: " . json_encode($result));
|
||||
}
|
||||
$ended = ! ($result['status'] === "pending" || $result['status'] === "processing");
|
||||
|
||||
|
||||
if (! $ended) {
|
||||
$this->log("Verification " . $result['status'] . ", sleeping 1s");
|
||||
sleep(1);
|
||||
$count ++;
|
||||
}
|
||||
|
||||
|
||||
$result = $this->client->get($location);
|
||||
} while (! $ended && $count < 30);
|
||||
|
||||
|
||||
$this->log("Verification ended with status: ${result['status']}");
|
||||
@unlink($tokenPath);
|
||||
}
|
||||
|
||||
|
||||
// requesting certificate
|
||||
// ----------------------
|
||||
|
||||
|
||||
// generate private key for domain if not exist
|
||||
if (empty($domainkey) || Settings::Get('system.letsencryptreuseold') == 0) {
|
||||
$keys = $this->generateKey();
|
||||
$domainkey = $keys['private'];
|
||||
}
|
||||
|
||||
|
||||
// load domain key
|
||||
$privateDomainKey = openssl_pkey_get_private($domainkey);
|
||||
|
||||
|
||||
if (empty($csr)) {
|
||||
$csr = $this->generateCSR($privateDomainKey, $domains);
|
||||
}
|
||||
|
||||
|
||||
// request certificates creation
|
||||
$result = $this->signedRequest($finalizeLink, array(
|
||||
'csr' => $csr
|
||||
@@ -316,7 +320,7 @@ class lescript_v2
|
||||
if (! isset($result['certificate'])) {
|
||||
throw new \RuntimeException("No certificate URL specified in result");
|
||||
}
|
||||
|
||||
|
||||
$certificates = array();
|
||||
$certdata = $this->client->get($result['certificate']);
|
||||
$this->log("Got certificate! YAY!");
|
||||
@@ -326,14 +330,14 @@ class lescript_v2
|
||||
$result = $this->client->get($link);
|
||||
$certificates[] = $result;
|
||||
}
|
||||
|
||||
|
||||
if (empty($certificates))
|
||||
throw new \RuntimeException('No certificates generated');
|
||||
|
||||
|
||||
$fullchain = implode("\n", $certificates);
|
||||
$crt = array_shift($certificates);
|
||||
$chain = implode("\n", $certificates);
|
||||
|
||||
|
||||
$this->log("Done, returning new certificates and key");
|
||||
return array(
|
||||
'fullchain' => $fullchain,
|
||||
@@ -375,7 +379,7 @@ class lescript_v2
|
||||
throw new \RuntimeException("No terms of service link available!");
|
||||
}
|
||||
$this->log('Sending registration to letsencrypt server');
|
||||
|
||||
|
||||
return $this->signedRequest($this->_req_uris['newAccount'], array(
|
||||
'termsOfServiceAgreed' => true
|
||||
));
|
||||
@@ -390,7 +394,7 @@ class lescript_v2
|
||||
$tmpConf = tmpfile();
|
||||
$tmpConfMeta = stream_get_meta_data($tmpConf);
|
||||
$tmpConfPath = $tmpConfMeta["uri"];
|
||||
|
||||
|
||||
// workaround to get SAN working
|
||||
fwrite($tmpConf, 'HOME = .
|
||||
RANDFILE = $ENV::HOME/.rnd
|
||||
@@ -405,7 +409,7 @@ countryName = Country Name (2 letter code)
|
||||
basicConstraints = CA:FALSE
|
||||
subjectAltName = ' . $san . '
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
|
||||
|
||||
|
||||
$csr = openssl_csr_new(array(
|
||||
"CN" => $domain,
|
||||
"ST" => Settings::Get('system.letsencryptstate'),
|
||||
@@ -415,15 +419,15 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
|
||||
"config" => $tmpConfPath,
|
||||
"digest_alg" => "sha256"
|
||||
));
|
||||
|
||||
|
||||
if (! $csr)
|
||||
throw new \RuntimeException("CSR couldn't be generated! " . openssl_error_string());
|
||||
|
||||
|
||||
openssl_csr_export($csr, $csr);
|
||||
fclose($tmpConf);
|
||||
|
||||
|
||||
preg_match('~REQUEST-----(.*)-----END~s', $csr, $matches);
|
||||
|
||||
|
||||
return trim(Base64UrlSafeEncoder::encode(base64_decode($matches[1])));
|
||||
}
|
||||
|
||||
@@ -433,13 +437,13 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
|
||||
"private_key_type" => OPENSSL_KEYTYPE_RSA,
|
||||
"private_key_bits" => (int) Settings::Get('system.letsencryptkeysize')
|
||||
));
|
||||
|
||||
|
||||
if (! openssl_pkey_export($res, $privateKey)) {
|
||||
throw new \RuntimeException("Key export failed!");
|
||||
}
|
||||
|
||||
|
||||
$details = openssl_pkey_get_details($res);
|
||||
|
||||
|
||||
return array(
|
||||
'private' => $privateKey,
|
||||
'public' => $details['key']
|
||||
@@ -450,11 +454,11 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
|
||||
{
|
||||
$privateKey = openssl_pkey_get_private($this->accountKey);
|
||||
$details = openssl_pkey_get_details($privateKey);
|
||||
|
||||
|
||||
$header = array(
|
||||
"alg" => "RS256"
|
||||
);
|
||||
|
||||
|
||||
if ($needs_jwk) {
|
||||
$header["jwk"] = array(
|
||||
"kty" => "RSA",
|
||||
@@ -465,24 +469,24 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
|
||||
// need account-url
|
||||
$header["kid"] = $this->_acc_location;
|
||||
}
|
||||
|
||||
|
||||
$protected = $header;
|
||||
$protected["nonce"] = $this->client->getLastNonce();
|
||||
$protected["url"] = $uri;
|
||||
|
||||
|
||||
$payload64 = Base64UrlSafeEncoder::encode(json_encode($payload, JSON_UNESCAPED_SLASHES));
|
||||
$protected64 = Base64UrlSafeEncoder::encode(json_encode($protected));
|
||||
|
||||
|
||||
openssl_sign($protected64 . '.' . $payload64, $signed, $privateKey, "SHA256");
|
||||
|
||||
|
||||
$signed64 = Base64UrlSafeEncoder::encode($signed);
|
||||
|
||||
|
||||
$data = array(
|
||||
'protected' => $protected64,
|
||||
'payload' => $payload64,
|
||||
'signature' => $signed64
|
||||
);
|
||||
|
||||
|
||||
$this->log("Sending signed request to $uri");
|
||||
return $this->client->post($uri, json_encode($data));
|
||||
}
|
||||
@@ -492,118 +496,3 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
|
||||
$this->logger->logAction(CRON_ACTION, LOG_INFO, "letsencrypt-v2 " . $message);
|
||||
}
|
||||
}
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
private $lastCode;
|
||||
|
||||
public $lastHeader;
|
||||
|
||||
private $base;
|
||||
|
||||
public function __construct($base)
|
||||
{
|
||||
$this->base = $base;
|
||||
}
|
||||
|
||||
private function curl($method, $url, $data = null)
|
||||
{
|
||||
$headers = array(
|
||||
'Accept: application/jose+json',
|
||||
'Content-Type: application/jose+json'
|
||||
);
|
||||
$handle = curl_init();
|
||||
curl_setopt($handle, CURLOPT_URL, preg_match('~^http~', $url) ? $url : $this->base . $url);
|
||||
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($handle, CURLOPT_HEADER, true);
|
||||
|
||||
// DO NOT DO THAT!
|
||||
// curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
|
||||
// curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
break;
|
||||
case 'POST':
|
||||
curl_setopt($handle, CURLOPT_POST, true);
|
||||
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
}
|
||||
$response = curl_exec($handle);
|
||||
|
||||
if (curl_errno($handle)) {
|
||||
throw new \RuntimeException('Curl: ' . curl_error($handle));
|
||||
}
|
||||
|
||||
$header_size = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
|
||||
|
||||
$header = substr($response, 0, $header_size);
|
||||
$body = substr($response, $header_size);
|
||||
|
||||
$this->lastHeader = $header;
|
||||
$this->lastCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
||||
|
||||
$data = json_decode($body, true);
|
||||
return $data === null ? $body : $data;
|
||||
}
|
||||
|
||||
public function post($url, $data)
|
||||
{
|
||||
return $this->curl('POST', $url, $data);
|
||||
}
|
||||
|
||||
public function get($url)
|
||||
{
|
||||
return $this->curl('GET', $url);
|
||||
}
|
||||
|
||||
public function getLastNonce()
|
||||
{
|
||||
if (preg_match('~Replay\-Nonce: (.+)~i', $this->lastHeader, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
$this->curl('GET', '/acme/new-nonce');
|
||||
return $this->getLastNonce();
|
||||
}
|
||||
|
||||
public function getLastLocation()
|
||||
{
|
||||
if (preg_match('~Location: (.+)~i', $this->lastHeader, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getLastCode()
|
||||
{
|
||||
return $this->lastCode;
|
||||
}
|
||||
|
||||
public function getLastLinks()
|
||||
{
|
||||
preg_match_all('~Link: <(.+)>;rel="up"~', $this->lastHeader, $matches);
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
class Base64UrlSafeEncoder
|
||||
{
|
||||
|
||||
public static function encode($input)
|
||||
{
|
||||
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
|
||||
}
|
||||
|
||||
public static function decode($input)
|
||||
{
|
||||
$remainder = strlen($input) % 4;
|
||||
if ($remainder) {
|
||||
$padlen = 4 - $remainder;
|
||||
$input .= str_repeat('=', $padlen);
|
||||
}
|
||||
return base64_decode(strtr($input, '-_', '+/'));
|
||||
}
|
||||
}
|
||||
@@ -1,794 +0,0 @@
|
||||
<?php
|
||||
|
||||
use \Froxlor\Database;
|
||||
use \Froxlor\Settings;
|
||||
use \Froxlor\FroxlorLogger;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
* 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 Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Logger
|
||||
*
|
||||
* @link http://www.nutime.de/
|
||||
*
|
||||
* Support Tickets - Tickets-Class
|
||||
*/
|
||||
class ticket
|
||||
{
|
||||
|
||||
/**
|
||||
* Userinfo
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $userinfo = array();
|
||||
|
||||
/**
|
||||
* Ticket ID
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $tid = - 1;
|
||||
|
||||
/**
|
||||
* Ticket Data Array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $t_data = array();
|
||||
|
||||
/**
|
||||
* Ticket-Object-Array
|
||||
*
|
||||
* @var ticket[]
|
||||
*/
|
||||
private static $tickets = array();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param
|
||||
* array userinfo
|
||||
* @param
|
||||
* int ticket id
|
||||
*/
|
||||
private function __construct($userinfo, $tid = - 1)
|
||||
{
|
||||
$this->userinfo = $userinfo;
|
||||
$this->tid = $tid;
|
||||
|
||||
// initialize data array
|
||||
$this->initData();
|
||||
|
||||
// read data from database
|
||||
$this->readData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton ftw ;-)
|
||||
*
|
||||
* @param
|
||||
* array userinfo
|
||||
* @param
|
||||
* int ticket id
|
||||
*/
|
||||
static public function getInstanceOf($_usernfo, $_tid)
|
||||
{
|
||||
if (! isset(self::$tickets[$_tid . '-' . $_usernfo['userid']])) {
|
||||
self::$tickets[$_tid . '-' . $_usernfo['userid']] = new ticket($_usernfo, $_tid);
|
||||
}
|
||||
return self::$tickets[$_tid . '-' . $_usernfo['userid']];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize data-array
|
||||
*/
|
||||
private function initData()
|
||||
{
|
||||
$this->Set('customer', 0, true, true);
|
||||
$this->Set('admin', 1, true, true);
|
||||
$this->Set('subject', '', true, true);
|
||||
$this->Set('category', '0', true, true);
|
||||
$this->Set('priority', '2', true, true);
|
||||
$this->Set('message', '', true, true);
|
||||
$this->Set('dt', 0, true, true);
|
||||
$this->Set('lastchange', 0, true, true);
|
||||
$this->Set('ip', '', true, true);
|
||||
$this->Set('status', '0', true, true);
|
||||
$this->Set('lastreplier', '0', true, true);
|
||||
$this->Set('by', '0', true, true);
|
||||
$this->Set('answerto', '0', true, true);
|
||||
$this->Set('archived', '0', true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read ticket data from database.
|
||||
*/
|
||||
private function readData()
|
||||
{
|
||||
if (isset($this->tid) && $this->tid != - 1) {
|
||||
|
||||
if ($this->userinfo['customerid'] > 0) {
|
||||
$_ticket_stmt = Database::prepare('
|
||||
SELECT * FROM `' . TABLE_PANEL_TICKETS . '` WHERE `id` = :tid AND `customerid` = :cid');
|
||||
$tdata = array(
|
||||
'tid' => $this->tid,
|
||||
'cid' => $this->userinfo['customerid']
|
||||
);
|
||||
} else {
|
||||
$_ticket_stmt = Database::prepare('
|
||||
SELECT * FROM `' . TABLE_PANEL_TICKETS . '` WHERE `id` = :tid' . ($this->userinfo['customers_see_all'] ? '' : ' AND `adminid` = :adminid'));
|
||||
$tdata = array(
|
||||
'tid' => $this->tid
|
||||
);
|
||||
if ($this->userinfo['customers_see_all'] != '1') {
|
||||
$tdata['adminid'] = $this->userinfo['adminid'];
|
||||
}
|
||||
}
|
||||
$_ticket = Database::pexecute_first($_ticket_stmt, $tdata);
|
||||
|
||||
if ($_ticket == false) {
|
||||
throw new Exception("Invalid ticket id");
|
||||
}
|
||||
|
||||
$this->Set('customer', $_ticket['customerid'], true, false);
|
||||
$this->Set('admin', $_ticket['adminid'], true, false);
|
||||
$this->Set('subject', $_ticket['subject'], true, false);
|
||||
$this->Set('category', $_ticket['category'], true, false);
|
||||
$this->Set('priority', $_ticket['priority'], true, false);
|
||||
$this->Set('message', $_ticket['message'], true, false);
|
||||
$this->Set('dt', $_ticket['dt'], true, false);
|
||||
$this->Set('lastchange', $_ticket['lastchange'], true, false);
|
||||
$this->Set('ip', $_ticket['ip'], true, false);
|
||||
$this->Set('status', $_ticket['status'], true, false);
|
||||
$this->Set('lastreplier', $_ticket['lastreplier'], true, false);
|
||||
$this->Set('by', $_ticket['by'], true, false);
|
||||
$this->Set('answerto', $_ticket['answerto'], true, false);
|
||||
$this->Set('archived', $_ticket['archived'], true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert data to database
|
||||
*/
|
||||
public function Insert()
|
||||
{
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TICKETS . "` SET
|
||||
`customerid` = :customerid,
|
||||
`adminid` = :adminid,
|
||||
`category` = :category,
|
||||
`priority` = :priority,
|
||||
`subject` = :subject,
|
||||
`message` = :message,
|
||||
`dt` = :dt,
|
||||
`lastchange` = :lastchange,
|
||||
`ip` = :ip,
|
||||
`status` = :status,
|
||||
`lastreplier` = :lastreplier,
|
||||
`by` = :by,
|
||||
`answerto` = :answerto");
|
||||
$ins_data = array(
|
||||
'customerid' => $this->Get('customer'),
|
||||
'adminid' => $this->Get('admin'),
|
||||
'category' => $this->Get('category'),
|
||||
'priority' => $this->Get('priority'),
|
||||
'subject' => $this->Get('subject'),
|
||||
'message' => $this->Get('message'),
|
||||
'dt' => time(),
|
||||
'lastchange' => time(),
|
||||
'ip' => $this->Get('ip'),
|
||||
'status' => $this->Get('status'),
|
||||
'lastreplier' => $this->Get('lastreplier'),
|
||||
'by' => $this->Get('by'),
|
||||
'answerto' => $this->Get('answerto')
|
||||
);
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
$this->tid = Database::lastInsertId();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update data in database
|
||||
*/
|
||||
public function Update()
|
||||
{
|
||||
|
||||
// Update "main" ticket
|
||||
$upd_stmt = Database::prepare('
|
||||
UPDATE `' . TABLE_PANEL_TICKETS . '` SET
|
||||
`priority` = :priority,
|
||||
`lastchange` = :lastchange,
|
||||
`status` = :status,
|
||||
`lastreplier` = :lastreplier
|
||||
WHERE `id` = :tid');
|
||||
$upd_data = array(
|
||||
'priority' => $this->Get('priority'),
|
||||
'lastchange' => $this->Get('lastchange'),
|
||||
'status' => $this->Get('status'),
|
||||
'lastreplier' => $this->Get('lastreplier'),
|
||||
'tid' => $this->tid
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a ticket to the archive
|
||||
*/
|
||||
public function Archive()
|
||||
{
|
||||
|
||||
// Update "main" ticket
|
||||
$upd_stmt = Database::prepare('
|
||||
UPDATE `' . TABLE_PANEL_TICKETS . '` SET `archived` = "1" WHERE `id` = :tid');
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'tid' => $this->tid
|
||||
));
|
||||
|
||||
// Update "answers" to ticket
|
||||
$upd_stmt = Database::prepare('
|
||||
UPDATE `' . TABLE_PANEL_TICKETS . '` SET `archived` = "1" WHERE `answerto` = :tid');
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'tid' => $this->tid
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove ticket from database
|
||||
*/
|
||||
public function Delete()
|
||||
{
|
||||
|
||||
// Delete "main" ticket
|
||||
$del_stmt = Database::prepare('
|
||||
DELETE FROM `' . TABLE_PANEL_TICKETS . '` WHERE `id` = :tid');
|
||||
Database::pexecute($del_stmt, array(
|
||||
'tid' => $this->tid
|
||||
));
|
||||
|
||||
// Delete "answers" to ticket"
|
||||
$del_stmt = Database::prepare('
|
||||
DELETE FROM `' . TABLE_PANEL_TICKETS . '` WHERE `answerto` = :tid');
|
||||
Database::pexecute($del_stmt, array(
|
||||
'tid' => $this->tid
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mail notifications
|
||||
*/
|
||||
public function sendMail($customerid = - 1, $template_subject = null, $default_subject = null, $template_body = null, $default_body = null)
|
||||
{
|
||||
global $mail, $theme;
|
||||
|
||||
// Some checks are to be made here in the future
|
||||
if ($customerid != - 1) {
|
||||
// Get e-mail message for customer
|
||||
$usr_stmt = Database::prepare('
|
||||
SELECT `name`, `firstname`, `company`, `email`
|
||||
FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `customerid` = :customerid');
|
||||
$usr = Database::pexecute_first($usr_stmt, array(
|
||||
'customerid' => $customerid
|
||||
));
|
||||
|
||||
$replace_arr = array(
|
||||
'FIRSTNAME' => $usr['firstname'],
|
||||
'NAME' => $usr['name'],
|
||||
'COMPANY' => $usr['company'],
|
||||
'SALUTATION' => getCorrectUserSalutation($usr),
|
||||
'SUBJECT' => $this->Get('subject', true)
|
||||
);
|
||||
} else {
|
||||
$replace_arr = array(
|
||||
'SUBJECT' => $this->Get('subject', true)
|
||||
);
|
||||
}
|
||||
$tpl_seldata = array(
|
||||
'adminid' => $this->userinfo['adminid'],
|
||||
'lang' => $this->userinfo['def_language'],
|
||||
'tplsubject' => $template_subject
|
||||
);
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||
WHERE `adminid`= :adminid
|
||||
AND `language`= :lang
|
||||
AND `templategroup`= 'mails' AND `varname`= :tplsubject");
|
||||
$result = Database::pexecute_first($result_stmt, $tpl_seldata);
|
||||
$mail_subject = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $default_subject), $replace_arr));
|
||||
|
||||
unset($tpl_seldata['tplsubject']);
|
||||
$tpl_seldata['tplmailbody'] = $template_body;
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "`
|
||||
WHERE `adminid`= :adminid
|
||||
AND `language`= :lang
|
||||
AND `templategroup`= 'mails' AND `varname`= :tplmailbody");
|
||||
$result = Database::pexecute_first($result_stmt, $tpl_seldata);
|
||||
$mail_body = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $default_body), $replace_arr));
|
||||
|
||||
if ($customerid != - 1) {
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom(Settings::Get('ticket.noreply_email'), Settings::Get('ticket.noreply_name'));
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$mail->AddAddress($usr['email'], $usr['firstname'] . ' ' . $usr['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) {
|
||||
$rstlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'ticket_class'
|
||||
));
|
||||
$rstlog->logAction(ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
standard_error('errorsendingmail', $usr['email']);
|
||||
}
|
||||
$mail->ClearAddresses();
|
||||
} else {
|
||||
|
||||
$admin_stmt = Database::prepare("
|
||||
SELECT `name`, `email` FROM `" . TABLE_PANEL_ADMINS . "`
|
||||
WHERE `adminid` = :adminid");
|
||||
$admin = Database::pexecute_first($admin_stmt, array(
|
||||
'adminid' => $this->userinfo['adminid']
|
||||
));
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$mail->SetFrom(Settings::Get('ticket.noreply_email'), Settings::Get('ticket.noreply_name'));
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$mail->AddAddress($admin['email'], $admin['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) {
|
||||
$rstlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'ticket_class'
|
||||
));
|
||||
$rstlog->logAction(ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
standard_error('errorsendingmail', $admin['email']);
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a support-categories
|
||||
*/
|
||||
static public function addCategory($_category = null, $_admin = 1, $_order = 1)
|
||||
{
|
||||
if ($_category != null && $_category != '') {
|
||||
if ($_order < 1) {
|
||||
$_order = 1;
|
||||
}
|
||||
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TICKET_CATS . "` SET
|
||||
`name` = :name,
|
||||
`adminid` = :adminid,
|
||||
`logicalorder` = :lo");
|
||||
$ins_data = array(
|
||||
'name' => $_category,
|
||||
'adminid' => $_admin,
|
||||
'lo' => $_order
|
||||
);
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a support-categories
|
||||
*/
|
||||
static public function editCategory($_category = null, $_id = 0, $_order = 1)
|
||||
{
|
||||
if ($_category != null && $_category != '' && $_id != 0) {
|
||||
if ($_order < 1) {
|
||||
$_order = 1;
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_TICKET_CATS . "` SET
|
||||
`name` = :name,
|
||||
`logicalorder` = :lo
|
||||
WHERE `id` = :id
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'name' => $_category,
|
||||
'lo' => $_order,
|
||||
'id' => $_id
|
||||
));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a support-categories
|
||||
*/
|
||||
static public function deleteCategory($_id = 0)
|
||||
{
|
||||
if ($_id != 0) {
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) as `numtickets` FROM `" . TABLE_PANEL_TICKETS . "`
|
||||
WHERE `category` = :cat");
|
||||
$result = Database::pexecute_first($result_stmt, array(
|
||||
'cat' => $_id
|
||||
));
|
||||
|
||||
if ($result['numtickets'] == "0") {
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_TICKET_CATS . "` WHERE `id` = :id");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $_id
|
||||
));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a support-category-name
|
||||
*/
|
||||
static public function getCategoryName($_id = 0)
|
||||
{
|
||||
if ($_id != 0) {
|
||||
$stmt = Database::prepare("
|
||||
SELECT `name` FROM `" . TABLE_PANEL_TICKET_CATS . "` WHERE `id` = :id");
|
||||
$category = Database::pexecute_first($stmt, array(
|
||||
'id' => $_id
|
||||
));
|
||||
return $category['name'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the highest order number
|
||||
*
|
||||
* @param object $_uid
|
||||
* admin-id (optional)
|
||||
*
|
||||
* @return int highest order number
|
||||
*/
|
||||
static public function getHighestOrderNumber($_uid = 0)
|
||||
{
|
||||
$where = '';
|
||||
$sel_data = array();
|
||||
if ($_uid > 0) {
|
||||
$where = " WHERE `adminid` = :adminid";
|
||||
$sel_data['adminid'] = $_uid;
|
||||
}
|
||||
$sql = "SELECT MAX(`logicalorder`) as `highestorder` FROM `" . TABLE_PANEL_TICKET_CATS . "`" . $where . ";";
|
||||
$result_stmt = Database::prepare($sql);
|
||||
$result = Database::pexecute_first($result_stmt, $sel_data);
|
||||
return (isset($result['highestorder']) ? (int) $result['highestorder'] : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the last x archived tickets
|
||||
*/
|
||||
static public function getLastArchived($_num = 10, $_admin = 1)
|
||||
{
|
||||
if ($_num > 0) {
|
||||
|
||||
$archived = array();
|
||||
$counter = 0;
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT *, (
|
||||
SELECT COUNT(`sub`.`id`)
|
||||
FROM `" . TABLE_PANEL_TICKETS . "` `sub`
|
||||
WHERE `sub`.`answerto` = `main`.`id`
|
||||
) as `ticket_answers`
|
||||
FROM `" . TABLE_PANEL_TICKETS . "` `main`
|
||||
WHERE `main`.`answerto` = '0' AND `main`.`archived` = '1'
|
||||
AND `main`.`adminid` = :adminid
|
||||
ORDER BY `main`.`lastchange` DESC LIMIT 0, " . (int) $_num);
|
||||
Database::pexecute($result_stmt, array(
|
||||
'adminid' => $_admin
|
||||
));
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$archived[$counter]['id'] = $row['id'];
|
||||
$archived[$counter]['customerid'] = $row['customerid'];
|
||||
$archived[$counter]['adminid'] = $row['adminid'];
|
||||
$archived[$counter]['lastreplier'] = $row['lastreplier'];
|
||||
$archived[$counter]['ticket_answers'] = $row['ticket_answers'];
|
||||
$archived[$counter]['category'] = $row['category'];
|
||||
$archived[$counter]['priority'] = $row['priority'];
|
||||
$archived[$counter]['subject'] = $row['subject'];
|
||||
$archived[$counter]['message'] = $row['message'];
|
||||
$archived[$counter]['dt'] = $row['dt'];
|
||||
$archived[$counter]['lastchange'] = $row['lastchange'];
|
||||
$archived[$counter]['status'] = $row['status'];
|
||||
$archived[$counter]['by'] = $row['by'];
|
||||
$counter ++;
|
||||
}
|
||||
|
||||
if (isset($archived[0]['id'])) {
|
||||
return $archived;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sql-statement to search the archive
|
||||
* including necessary parameter-array for PDO
|
||||
*
|
||||
* @return array 0 = query, 1 = params-array
|
||||
*/
|
||||
static public function getArchiveSearchStatement($subject = null, $priority = null, $fromdate = null, $todate = null, $message = null, $customer = - 1, $admin = 1, $categories = null)
|
||||
{
|
||||
$search_params = array();
|
||||
|
||||
$query = "
|
||||
SELECT `main`.*, (
|
||||
SELECT COUNT(`sub`.`id`) FROM `" . TABLE_PANEL_TICKETS . "` `sub`
|
||||
WHERE `sub`.`answerto` = `main`.`id`
|
||||
) as `ticket_answers`
|
||||
FROM `" . TABLE_PANEL_TICKETS . "` `main`
|
||||
WHERE `main`.`archived` = '1' AND `main`.`adminid` = :admin";
|
||||
|
||||
$search_params['admin'] = $admin;
|
||||
|
||||
if ($subject != NULL && $subject != '') {
|
||||
$query .= " AND `main`.`subject` LIKE :subject";
|
||||
$search_params['subject'] = "%" . $subject . "%";
|
||||
}
|
||||
|
||||
if ($priority != null && isset($priority[0]) && $priority[0] != '') {
|
||||
|
||||
if (isset($priority[1]) && $priority[1] != '') {
|
||||
|
||||
if (isset($priority[2]) && $priority[2] != '') {
|
||||
|
||||
$query .= " AND (`main`.`priority` = '1' OR `main`.`priority` = '2' OR `main`.`priority` = '3')";
|
||||
} else {
|
||||
|
||||
$query .= " AND (`main`.`priority` = '1' OR `main`.`priority` = '1')";
|
||||
}
|
||||
} elseif (isset($priority[2]) && $priority[2] != '') {
|
||||
|
||||
$query .= " AND (`main`.`priority` = '1' OR `main`.`priority` = '3')";
|
||||
} else {
|
||||
$query .= " AND `main`.`priority` = '1'";
|
||||
}
|
||||
} elseif ($priority != null && isset($priority[1]) && $priority[1] != '') {
|
||||
if (isset($priority[2]) && $priority[2] != '') {
|
||||
$query .= " AND (`main`.`priority` = '2' OR `main`.`priority` = '3')";
|
||||
} else {
|
||||
$query .= " AND `main`.`priority` = '2'";
|
||||
}
|
||||
} elseif ($priority != null) {
|
||||
|
||||
if (isset($priority[3]) && $priority[3] != '') {
|
||||
$query .= " AND `main`.`priority` = '3'";
|
||||
}
|
||||
}
|
||||
|
||||
if ($fromdate != null && $fromdate > 0) {
|
||||
$query .= " AND `main`.`lastchange` > :fromdate";
|
||||
$search_params['fromdate'] = strtotime($fromdate);
|
||||
}
|
||||
|
||||
if ($todate != null && $todate > 0) {
|
||||
$query .= " AND `main`.`lastchange` < :todate";
|
||||
$search_params['todate'] = strtotime($todate);
|
||||
}
|
||||
|
||||
if ($message != null && $message != '') {
|
||||
$query .= " AND `main`.`message` LIKE :message";
|
||||
$search_params['message'] = "%" . $message . "%";
|
||||
}
|
||||
|
||||
if ($customer != - 1) {
|
||||
$query .= " AND `main`.`customerid` = :customer";
|
||||
$search_params['customer'] = $customer;
|
||||
}
|
||||
|
||||
if ($categories != null) {
|
||||
|
||||
$cats = array();
|
||||
foreach ($categories as $index => $catid) {
|
||||
if ($catid != "") {
|
||||
$cats[] = $catid;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($cats) > 0) {
|
||||
$query .= " AND (";
|
||||
}
|
||||
|
||||
foreach ($cats as $catid) {
|
||||
if (isset($catid) && $catid > 0) {
|
||||
$query .= "`main`.`category` = :catid_" . $catid . " OR ";
|
||||
$search_params['catid_' . $catid] = $catid;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($cats) > 0) {
|
||||
$query = substr($query, 0, strlen($query) - 3);
|
||||
$query .= ") ";
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'0' => $query,
|
||||
'1' => $search_params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statustext by status-no
|
||||
*/
|
||||
static public function getStatusText($_lng, $_status = 0)
|
||||
{
|
||||
switch ($_status) {
|
||||
case 0:
|
||||
return $_lng['ticket']['open'];
|
||||
break;
|
||||
case 1:
|
||||
return $_lng['ticket']['wait_reply'];
|
||||
break;
|
||||
case 2:
|
||||
return $_lng['ticket']['replied'];
|
||||
break;
|
||||
default:
|
||||
return $_lng['ticket']['closed'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prioritytext by priority-no
|
||||
*/
|
||||
static public function getPriorityText($_lng, $_priority = 0)
|
||||
{
|
||||
switch ($_priority) {
|
||||
case 1:
|
||||
return $_lng['ticket']['high'];
|
||||
break;
|
||||
case 2:
|
||||
return $_lng['ticket']['normal'];
|
||||
break;
|
||||
default:
|
||||
return $_lng['ticket']['low'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function convertLatin1ToHtml($str)
|
||||
{
|
||||
$html_entities = array(
|
||||
"Ä" => "Ä",
|
||||
"ä" => "ä",
|
||||
"Ö" => "Ö",
|
||||
"ö" => "ö",
|
||||
"Ü" => "Ü",
|
||||
"ü" => "ü",
|
||||
"ß" => "ß"
|
||||
/*
|
||||
* @TODO continue this table for all the special-characters
|
||||
*/
|
||||
);
|
||||
|
||||
foreach ($html_entities as $key => $value) {
|
||||
$str = str_replace($key, $value, $str);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* function customerHasTickets
|
||||
*
|
||||
* @param
|
||||
* int customer-id
|
||||
*
|
||||
* @return array/bool array of ticket-ids if customer has any, else false
|
||||
*/
|
||||
static public function customerHasTickets($_cid = 0)
|
||||
{
|
||||
if ($_cid != 0) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_TICKETS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($result_stmt, array(
|
||||
'cid' => $_cid
|
||||
));
|
||||
|
||||
$tickets = array();
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$tickets[] = $row['id'];
|
||||
}
|
||||
|
||||
return $tickets;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a data-var
|
||||
*/
|
||||
public function Get($_var = '', $_vartrusted = false)
|
||||
{
|
||||
if ($_var != '') {
|
||||
if (! $_vartrusted) {
|
||||
$_var = htmlspecialchars($_var);
|
||||
}
|
||||
|
||||
if (isset($this->t_data[$_var])) {
|
||||
if (strtolower($_var) == 'message') {
|
||||
// avoid double line-breaks, #1413
|
||||
$this->t_data[$_var] = str_replace("<br />\n", "\n", $this->t_data[$_var]);
|
||||
return nl2br($this->t_data[$_var]);
|
||||
} elseif (strtolower($_var) == 'subject') {
|
||||
return nl2br($this->t_data[$_var]);
|
||||
} else {
|
||||
return $this->t_data[$_var];
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a data-var
|
||||
*/
|
||||
public function Set($_var = '', $_value = '', $_vartrusted = false, $_valuetrusted = false)
|
||||
{
|
||||
if ($_var != '' && $_value != '') {
|
||||
if (! $_vartrusted) {
|
||||
$_var = strip_tags($_var);
|
||||
}
|
||||
|
||||
if (! $_valuetrusted) {
|
||||
$_value = strip_tags($_value, '<br />');
|
||||
}
|
||||
|
||||
if (strtolower($_var) == 'message' || strtolower($_var) == 'subject') {
|
||||
$_value = $this->convertLatin1ToHtml($_value);
|
||||
}
|
||||
|
||||
$this->t_data[$_var] = $_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ while ($fName = readdir($lockDirHandle)) {
|
||||
* whether the permission of the files are still correct
|
||||
*/
|
||||
fwrite($debugHandler, 'Checking froxlor file permissions' . "\n");
|
||||
$_mypath = makeCorrectDir(\Froxlor\Froxlor::getInstallDir());
|
||||
$_mypath = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir());
|
||||
|
||||
if (((int) \Froxlor\Settings::Get('system.mod_fcgid') == 1 && (int) \Froxlor\Settings::Get('system.mod_fcgid_ownvhost') == 1) || ((int) \Froxlor\Settings::Get('phpfpm.enabled') == 1 && (int) \Froxlor\Settings::Get('phpfpm.enabled_ownvhost') == 1)) {
|
||||
$user = \Froxlor\Settings::Get('system.mod_fcgid_httpuser');
|
||||
@@ -156,12 +156,12 @@ if (((int) \Froxlor\Settings::Get('system.mod_fcgid') == 1 && (int) \Froxlor\Set
|
||||
}
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
} else {
|
||||
// back to webserver permission
|
||||
$user = \Froxlor\Settings::Get('system.httpuser');
|
||||
$group = \Froxlor\Settings::Get('system.httpgroup');
|
||||
safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
\Froxlor\FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
}
|
||||
|
||||
// Initialize logging
|
||||
|
||||
@@ -15,109 +15,3 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* depending on the give choice, the customers web-data, email-data and databases are being backup'ed
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
function createCustomerBackup($data = null, $customerdocroot = null, &$cronlog)
|
||||
{
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating Backup for user "'.$data['loginname'].'"');
|
||||
|
||||
// create tmp folder
|
||||
$tmpdir = makeCorrectDir($data['destdir'] . '/.tmp/');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating tmp-folder "'.$tmpdir.'"');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg($tmpdir));
|
||||
safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
$create_backup_tar_data = "";
|
||||
|
||||
// MySQL databases
|
||||
if ($data['backup_dbs'] == 1) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating mysql-folder "'.makeCorrectDir($tmpdir . '/mysql').'"');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mysql')));
|
||||
safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mysql')));
|
||||
|
||||
// get all customer database-names
|
||||
$sel_stmt = Database::prepare("SELECT `databasename` FROM `" . TABLE_PANEL_DATABASES . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($sel_stmt, array(
|
||||
'cid' => $data['customerid']
|
||||
));
|
||||
|
||||
Database::needRoot(true);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
|
||||
$has_dbs = false;
|
||||
while ($row = $sel_stmt->fetch()) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -pXXXXX ' . $row['databasename'] . ' > ' . makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'));
|
||||
$bool_false = false;
|
||||
safe_exec('mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -p' . $sql_root['passwd'] . ' ' . $row['databasename'] . ' > ' . makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'), $bool_false, array('>'));
|
||||
$has_dbs = true;
|
||||
}
|
||||
|
||||
if ($has_dbs) {
|
||||
$create_backup_tar_data .= './mysql ';
|
||||
}
|
||||
|
||||
unset($sql_root);
|
||||
}
|
||||
|
||||
// E-mail data
|
||||
if ($data['backup_mail'] == 1) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating mail-folder "'.makeCorrectDir($tmpdir . '/mail').'"');
|
||||
safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mail')));
|
||||
|
||||
// get all customer mail-accounts
|
||||
$sel_stmt = Database::prepare("SELECT `homedir`, `maildir` FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($sel_stmt, array(
|
||||
'cid' => $data['customerid']
|
||||
));
|
||||
|
||||
$tar_file_list = "";
|
||||
$mail_homedir = "";
|
||||
while ($row = $sel_stmt->fetch()) {
|
||||
$tar_file_list .= escapeshellarg("./".$row['maildir']) . " ";
|
||||
$mail_homedir = $row['homedir'];
|
||||
}
|
||||
|
||||
if (! empty($tar_file_list)) {
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg(makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C '.escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
safe_exec('tar cfz ' . escapeshellarg(makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C '.escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
$create_backup_tar_data .= './mail ';
|
||||
}
|
||||
}
|
||||
|
||||
// Web data
|
||||
if ($data['backup_web'] == 1) {
|
||||
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating web-folder "'.makeCorrectDir($tmpdir . '/web').'"');
|
||||
safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/web')));
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg(makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", makeCorrectFile($tmpdir.'/*'))) .' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(makeCorrectDir($tmpdir), 0, -1))) .' -C '.escapeshellarg($customerdocroot). ' .');
|
||||
safe_exec('tar cfz ' . escapeshellarg(makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", makeCorrectFile($tmpdir.'/*'))) .' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(makeCorrectFile($tmpdir), 0, -1))) .' -C '.escapeshellarg($customerdocroot).' .');
|
||||
$create_backup_tar_data .= './web ';
|
||||
}
|
||||
|
||||
if (!empty($create_backup_tar_data))
|
||||
{
|
||||
$backup_file = makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-backup_' . date('YmdHi', time()) . '.tar.gz');
|
||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating backup-file "'.$backup_file.'"');
|
||||
// pack all archives in tmp-dir to one
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg($backup_file) . ' -C '.escapeshellarg($tmpdir).' '.trim($create_backup_tar_data));
|
||||
safe_exec('tar cfz ' . escapeshellarg($backup_file) . ' -C '.escapeshellarg($tmpdir).' '.trim($create_backup_tar_data));
|
||||
// move to destination directory
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
safe_exec('mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
// remove tmp-files
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> rm -rf '.escapeshellarg($tmpdir));
|
||||
safe_exec('rm -rf '.escapeshellarg($tmpdir));
|
||||
// set owner to customer
|
||||
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
safe_exec('chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($data['destdir']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,68 +15,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function updateToVersion
|
||||
*
|
||||
* updates the panel.version field
|
||||
* to the given value (no checks here!)
|
||||
*
|
||||
* @param string $new_version new-version
|
||||
*
|
||||
* @return bool true on success, else false
|
||||
*/
|
||||
function updateToVersion($new_version = null) {
|
||||
|
||||
if ($new_version !== null && $new_version != '') {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `".TABLE_PANEL_SETTINGS."` SET `value` = :newversion
|
||||
WHERE `settinggroup` = 'panel' AND `varname` = 'version'"
|
||||
);
|
||||
Database::pexecute($upd_stmt, array('newversion' => $new_version));
|
||||
Settings::Set('panel.version', $new_version);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function isFroxlor
|
||||
*
|
||||
* checks if the panel is froxlor
|
||||
*
|
||||
* @return bool true if panel is froxlor, else false
|
||||
*/
|
||||
function isFroxlor() {
|
||||
|
||||
if (Settings::Get('panel.frontend') !== null
|
||||
&& Settings::Get('panel.frontend') == 'froxlor'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function isFroxlorVersion
|
||||
*
|
||||
* checks if a given version is the
|
||||
* current one (and panel is froxlor)
|
||||
*
|
||||
* @param string $to_check version to check
|
||||
*
|
||||
* @return bool true if version to check matches, else false
|
||||
*/
|
||||
function isFroxlorVersion($to_check = null) {
|
||||
|
||||
if (Settings::Get('panel.frontend') == 'froxlor'
|
||||
&& Settings::Get('panel.version') == $to_check
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function showUpdateStep
|
||||
@@ -151,66 +89,3 @@ function lastStepStatus($status = -1, $message = '') {
|
||||
$filelog->logAction(ADM_ACTION, LOG_WARNING, 'Success');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validate if full path to update.log is sane
|
||||
* if not, the update.log is created in /tmp/
|
||||
*
|
||||
* @param string $filename the file name to validate
|
||||
*
|
||||
* @return string the full path with filename (can differ if not writeable => /tmp)
|
||||
*/
|
||||
function validateUpdateLogFile($filename) {
|
||||
|
||||
if (!is_dir($filename)) {
|
||||
$fh = @fopen($filename, 'a');
|
||||
if ($fh) {
|
||||
fclose($fh);
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
return '/tmp/froxlor_update.log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function isDatabaseVersion
|
||||
*
|
||||
* checks if a given database-version is the current one
|
||||
*
|
||||
* @param int $to_check version to check
|
||||
*
|
||||
* @return bool true if version to check matches, else false
|
||||
*/
|
||||
function isDatabaseVersion($to_check = null) {
|
||||
|
||||
if (Settings::Get('panel.frontend') == 'froxlor'
|
||||
&& Settings::Get('panel.db_version') == $to_check
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function updateToDbVersion
|
||||
*
|
||||
* updates the panel.version field
|
||||
* to the given value (no checks here!)
|
||||
*
|
||||
* @param string $new_version new-version
|
||||
*
|
||||
* @return bool true on success, else false
|
||||
*/
|
||||
function updateToDbVersion($new_version = null) {
|
||||
|
||||
if ($new_version !== null && $new_version != '') {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `".TABLE_PANEL_SETTINGS."` SET `value` = :newversion
|
||||
WHERE `settinggroup` = 'panel' AND `varname` = 'db_version'"
|
||||
);
|
||||
Database::pexecute($upd_stmt, array('newversion' => $new_version));
|
||||
Settings::Set('panel.db_version', $new_version);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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 Functions
|
||||
*
|
||||
*/
|
||||
|
||||
function setCycleOfCronjob($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues) {
|
||||
|
||||
switch ($newfieldvalue)
|
||||
{
|
||||
case 0:
|
||||
$interval = 'DAY';
|
||||
break;
|
||||
case 1:
|
||||
$interval = 'WEEK';
|
||||
break;
|
||||
case 2:
|
||||
$interval = 'MONTH';
|
||||
break;
|
||||
case 3:
|
||||
$interval = 'YEAR';
|
||||
break;
|
||||
default:
|
||||
$interval = 'MONTH';
|
||||
break;
|
||||
}
|
||||
|
||||
Database::query("UPDATE `cronjobs_run` SET `interval` = '1 ".$interval."' WHERE `cronfile` = 'used_tickets_reset';");
|
||||
|
||||
return array(FORMFIELDS_PLAUSIBILITY_CHECK_OK);
|
||||
}
|
||||
@@ -41,8 +41,6 @@ define('TABLE_PANEL_DISKSPACE', 'panel_diskspace');
|
||||
define('TABLE_PANEL_DISKSPACE_ADMINS', 'panel_diskspace_admins');
|
||||
define('TABLE_PANEL_LANGUAGE', 'panel_languages');
|
||||
define('TABLE_PANEL_IPSANDPORTS', 'panel_ipsandports');
|
||||
define('TABLE_PANEL_TICKETS', 'panel_tickets');
|
||||
define('TABLE_PANEL_TICKET_CATS', 'panel_ticket_categories');
|
||||
define('TABLE_PANEL_LOG', 'panel_syslog');
|
||||
define('TABLE_PANEL_PHPCONFIGS', 'panel_phpconfigs');
|
||||
define('TABLE_PANEL_CRONRUNS', 'cronjobs_run');
|
||||
|
||||
@@ -525,111 +525,9 @@ $lng['admin']['webalizer']['veryquiet'] = 'Geen uitvoer';
|
||||
$lng['serversettings']['webalizer_quiet']['title'] = 'Uitvoer Webalizer';
|
||||
$lng['serversettings']['webalizer_quiet']['description'] = 'Informatieniveau van Webalizer';
|
||||
|
||||
// ADDED IN 1.2.18-svn3
|
||||
|
||||
$lng['ticket']['admin_email'] = 'root@localhost';
|
||||
$lng['ticket']['noreply_email'] = 'tickets@froxlor';
|
||||
$lng['admin']['ticketsystem'] = 'Ondersteuningstickets';
|
||||
$lng['menue']['ticket']['ticket'] = 'Ondersteuningstickets';
|
||||
$lng['menue']['ticket']['categories'] = 'Ondersteuningscategorieën';
|
||||
$lng['menue']['ticket']['archive'] = 'Ticket-archief';
|
||||
$lng['ticket']['description'] = 'Hier kunt u hulpverzoeken naar uw beheerder sturen.<br /> Notificatie\'s worden verzonden via email.';
|
||||
$lng['ticket']['ticket_new'] = 'Een nieuw ticket openen';
|
||||
$lng['ticket']['ticket_reply'] = 'Ticket beantwoorden';
|
||||
$lng['ticket']['ticket_reopen'] = 'Ticket heropenen';
|
||||
$lng['ticket']['ticket_newcateory'] = 'Nieuwe categorie maken';
|
||||
$lng['ticket']['ticket_editcateory'] = 'Categorie bewerken';
|
||||
$lng['ticket']['ticket_view'] = 'Ticketverloop weergeven';
|
||||
$lng['ticket']['ticketcount'] = 'Tickets';
|
||||
$lng['ticket']['ticket_answers'] = 'Antwoorden';
|
||||
$lng['ticket']['lastchange'] = 'Laatste actie';
|
||||
$lng['ticket']['subject'] = 'Onderwerp';
|
||||
$lng['ticket']['status'] = 'Status';
|
||||
$lng['ticket']['lastreplier'] = 'Laatste beantwoorder';
|
||||
$lng['ticket']['priority'] = 'Prioriteit';
|
||||
$lng['ticket']['low'] = 'Laag';
|
||||
$lng['ticket']['normal'] = 'Normaal';
|
||||
$lng['ticket']['high'] = 'Hoog';
|
||||
$lng['ticket']['lastchange'] = 'Laatste wijziging';
|
||||
$lng['ticket']['lastchange_from'] = 'Datum vanaf (dd.mm.yyyy)';
|
||||
$lng['ticket']['lastchange_to'] = 'Datum tot (dd.mm.yyyy)';
|
||||
$lng['ticket']['category'] = 'Categorie';
|
||||
$lng['ticket']['no_cat'] = 'Geen';
|
||||
$lng['ticket']['message'] = 'Bericht';
|
||||
$lng['ticket']['show'] = 'Tonen';
|
||||
$lng['ticket']['answer'] = 'Beantwoorden';
|
||||
$lng['ticket']['close'] = 'Sluiten';
|
||||
$lng['ticket']['reopen'] = 'Heropenen';
|
||||
$lng['ticket']['archive'] = 'Archiveren';
|
||||
$lng['ticket']['ticket_delete'] = 'Ticket verwijderen';
|
||||
$lng['ticket']['lastarchived'] = 'Recentelijk ontvangen tickets';
|
||||
$lng['ticket']['archivedtime'] = 'Gearchiveerd';
|
||||
$lng['ticket']['open'] = 'Openen';
|
||||
$lng['ticket']['wait_reply'] = 'Gereed voor antwoord';
|
||||
$lng['ticket']['replied'] = 'Beantwoord';
|
||||
$lng['ticket']['closed'] = 'Gesloten';
|
||||
$lng['ticket']['staff'] = 'Staf';
|
||||
$lng['ticket']['customer'] = 'Klant';
|
||||
$lng['ticket']['old_tickets'] = 'Berichten voor ticket';
|
||||
$lng['ticket']['search'] = 'Archief doorzoeken';
|
||||
$lng['ticket']['nocustomer'] = 'Geen keuze';
|
||||
$lng['ticket']['archivesearch'] = 'Zoekresultaten archief';
|
||||
$lng['ticket']['noresults'] = 'Geen resultaten gevonden';
|
||||
$lng['ticket']['notmorethanxopentickets'] = 'Omwille van spambeveiliging kunt u niet meer dan %s tickets open hebben';
|
||||
$lng['ticket']['supportstatus'] = 'Status support';
|
||||
$lng['ticket']['supportavailable'] = '<span class="ticket_low">Onze ondersteuningsmedewerkers zijn beschikbaar.</span>';
|
||||
$lng['ticket']['supportnotavailable'] = '<span class="ticket_high">Onze ondersteuningsmedewerkers zijn niet beschikbaar</span>';
|
||||
$lng['admin']['templates']['ticket'] = 'Notificatie-mails voor ondersteuningstickets';
|
||||
$lng['admin']['templates']['SUBJECT'] = 'Wordt vervangen door het onderwerp van het ondersteuni';
|
||||
$lng['admin']['templates']['new_ticket_for_customer'] = 'Informatie voor de klant dat het ticket is verstuurd';
|
||||
$lng['admin']['templates']['new_ticket_by_customer'] = 'Notificatie voor beheerder';
|
||||
$lng['admin']['templates']['new_reply_ticket_by_customer'] = 'Notificatie voor beheerder voor antwoord van klant';
|
||||
$lng['admin']['templates']['new_ticket_by_staff'] = 'Notificatie voor klant van ticket geopend door stafleden';
|
||||
$lng['admin']['templates']['new_reply_ticket_by_staff'] = 'Notificatie voor klant van antwoorden door stafleden';
|
||||
$lng['mails']['new_ticket_for_customer']['mailbody'] = 'Hallo {FIRSTNAME} {NAME},\n\nuw ondersteuningsticket met het onderwerp "{SUBJECT}" is verstuurd.\n\nU krijgt bericht wanneer uw ticket beantwoord is.\n\nMet vriendelijke groet,\nuw beheerder';
|
||||
$lng['mails']['new_ticket_for_customer']['subject'] = 'Uw ondersteuningsticket is verzonden';
|
||||
$lng['mails']['new_ticket_by_customer']['mailbody'] = 'Hallo beheerder,\n\neen nieuw ondersteuningsticket met onderwerp "{SUBJECT}" is verstuurd.\n\nU dient in te loggen om het ticket te behandelen.\n\nMet vriendelijke groet,\nuw beheerder';
|
||||
$lng['mails']['new_ticket_by_customer']['subject'] = 'Nieuw ondersteuningsticket verzonden';
|
||||
$lng['mails']['new_reply_ticket_by_customer']['mailbody'] = 'Hallo beheerder,\n\nhet ondersteuningsticket "{SUBJECT}" is beantwoord door een klant.\n\nU dient in te loggen om het ticket te behandelen.\n\nMet vriendelijk groet,\nuw beheerder';
|
||||
$lng['mails']['new_reply_ticket_by_customer']['subject'] = 'Nieuw antwoord op ondersteuningsticket';
|
||||
$lng['mails']['new_ticket_by_staff']['mailbody'] = 'Hallo {FIRSTNAME} {NAME},\n\neen ondersteuningsticket met onderwerp "{SUBJECT}" is voor u geopend.\n\nU dient in te loggen om het ticket te bekijken.\n\nMet vriendelijk groet,\nuw beheerder';
|
||||
$lng['mails']['new_ticket_by_staff']['subject'] = 'Nieuw ondersteuningsticket verzonden';
|
||||
$lng['mails']['new_reply_ticket_by_staff']['mailbody'] = 'Hallo {FIRSTNAME} {NAME},\n\nhet ondersteuningsticket met onderwerp "{SUBJECT}" is door onze staf beantwoord.\n\nU dient in te loggen om het ticket te bekijken.\n\nMet vriendelijk groet,\nuw beheerder';
|
||||
$lng['mails']['new_reply_ticket_by_staff']['subject'] = 'Nieuw antwoord op ondersteuningsticket';
|
||||
$lng['question']['ticket_reallyclose'] = 'Weet u zeker dat u ticket "%s" wilt sluiten?';
|
||||
$lng['question']['ticket_reallydelete'] = 'Weet u zeker dat u ticket "%s" wilt verwijderen?';
|
||||
$lng['question']['ticket_reallydeletecat'] = 'Weet u zeker dat u de categorie "%s" wilt verwijderen?';
|
||||
$lng['question']['ticket_reallyarchive'] = 'Weet u zeker dat u ticket "%s" wilt archiveren?';
|
||||
$lng['error']['nomoreticketsavailable'] = 'U hebt al uw beschikbare tickets verbruikt. Neem contact op met uw beheerder.';
|
||||
$lng['error']['nocustomerforticket'] = 'U kunt geen tickets aanmaken zonder gebruikers';
|
||||
$lng['error']['categoryhastickets'] = 'Deze categorie bevat nog tickets.<br />Verwijder de tickets eerst alvorens de categorie te verwijderen';
|
||||
$lng['admin']['ticketsettings'] = 'Instellingen voor ondersteuningstickets';
|
||||
$lng['admin']['archivelastrun'] = 'Laatste archivering tickets';
|
||||
$lng['serversettings']['ticket']['noreply_email']['title'] = 'Emailadres voor geen-antwoord';
|
||||
$lng['serversettings']['ticket']['noreply_email']['description'] = 'Het adres van de afzender, in de meeste gevallen zoiets als no-reply@domein.tld';
|
||||
$lng['serversettings']['ticket']['worktime_begin']['title'] = 'Aanvang beschikbaarheid ondersteuning (hh:mm)';
|
||||
$lng['serversettings']['ticket']['worktime_begin']['description'] = 'Tijd vanaf beschikbaarheid ondersteuning';
|
||||
$lng['serversettings']['ticket']['worktime_end']['title'] = 'Eindtijd beschikbaarheid onder steuning (hh:mm)';
|
||||
$lng['serversettings']['ticket']['worktime_end']['description'] = 'Eindtijd beschikbaarheid ondersteuning';
|
||||
$lng['serversettings']['ticket']['worktime_sat'] = 'Ondersteuning beschikbaar op zaterdagen?';
|
||||
$lng['serversettings']['ticket']['worktime_sun'] = 'Ondersteuning beschikbaar op zondagen?';
|
||||
$lng['serversettings']['ticket']['worktime_all']['title'] = 'Geen tijdlimiet voor ondersteuning';
|
||||
$lng['serversettings']['ticket']['worktime_all']['description'] = 'Indien "Ja" worden de instelling voor de tijd overschreven';
|
||||
$lng['serversettings']['ticket']['archiving_days'] = 'Na hoeveel dagen dienen gesloten tickets te worden gearchiveerd?';
|
||||
$lng['customer']['tickets'] = 'Ondersteuningstickets';
|
||||
|
||||
// ADDED IN 1.2.18-svn4
|
||||
|
||||
$lng['admin']['domain_nocustomeraddingavailable'] = 'Het is niet mogelijk een domein toe te voegen. U dient tenminste een klant aan te maken.';
|
||||
$lng['serversettings']['ticket']['enable'] = 'Ticketsysteem inschakelijk';
|
||||
$lng['serversettings']['ticket']['concurrentlyopen'] = 'Hoeveel tickets kunnen per keer open staan?';
|
||||
$lng['error']['norepymailiswrong'] = 'Het "geen-antwoord-adres" is onjuist. Alleen geldige emailadressen zijn toegestaan.';
|
||||
$lng['error']['tadminmailiswrong'] = 'Het "Ticketbeheerder-adres" is onjuist. Alleen geldige emailadressen zijn toegestaan.';
|
||||
$lng['ticket']['awaitingticketreply'] = 'U hebt %s onbeantwoorde ondersteuningsticket(s)';
|
||||
|
||||
// ADDED IN 1.2.18-svn5
|
||||
|
||||
$lng['serversettings']['ticket']['noreply_name'] = 'Afzender van emailas ondersteuningsticket';
|
||||
|
||||
// ADDED IN 1.2.19-svn1
|
||||
|
||||
@@ -637,16 +535,6 @@ $lng['serversettings']['mod_fcgid']['configdir']['title'] = 'Configuratiemap';
|
||||
$lng['serversettings']['mod_fcgid']['configdir']['description'] = 'Waar dienen alle configuratiebestanden voor FCGID te worden opgeslagen? Indien u geen aangepaste versie van SuExec gebruikt, zoals gebruikelijk is, dient dit pad onder /var/www/ te liggen';
|
||||
$lng['serversettings']['mod_fcgid']['tmpdir']['title'] = 'Map voor tijdelijke bestanden';
|
||||
|
||||
// ADDED IN 1.2.19-svn3
|
||||
|
||||
$lng['serversettings']['ticket']['reset_cycle']['title'] = 'Cyclus voor opnieuw instellen gebruikte tickets';
|
||||
$lng['serversettings']['ticket']['reset_cycle']['description'] = 'Stelt het door klant gebruikte tickets in op 0 na deze periode';
|
||||
$lng['admin']['tickets']['daily'] = 'Dagelijks';
|
||||
$lng['admin']['tickets']['weekly'] = 'Wekelijks';
|
||||
$lng['admin']['tickets']['monthly'] = 'Maandelijks';
|
||||
$lng['admin']['tickets']['yearly'] = 'Jaarlijks';
|
||||
$lng['error']['ticketresetcycleiswrong'] = 'De cyclus dient "Dagelijks", "Wekelijks", "Maandelijks" of "Jaarlijks" te zijn.';
|
||||
|
||||
// ADDED IN 1.2.19-svn4
|
||||
|
||||
$lng['menue']['traffic']['traffic'] = 'Dataverkeer';
|
||||
@@ -744,7 +632,6 @@ $lng['dkim']['dkimrestart_command']['description'] = 'Geef het commando om de mi
|
||||
|
||||
$lng['admin']['allips'] = 'Alle IP\'s';
|
||||
$lng['panel']['nosslipsavailable'] = 'Er zijn op dit moment geen SSL IP/poorten beschikbaar';
|
||||
$lng['ticket']['by'] = 'door';
|
||||
$lng['dkim']['use_dkim']['title'] = 'Activeer ondersteuning voor DKIM?';
|
||||
$lng['dkim']['use_dkim']['description'] = 'Wilt u gebruikmaken van Domain Keys (DKIM) systeem?';
|
||||
$lng['error']['invalidmysqlhost'] = 'Ongeldig adres voor MySQL-host: %s';
|
||||
@@ -988,8 +875,6 @@ $lng['tasks']['rebuild_bindconfig'] = 'Opnieuw opbouwen bind-configuratie';
|
||||
$lng['tasks']['creating_ftpdir'] = 'Map aanmaken voor nieuwe FTP-gebruiker';
|
||||
$lng['tasks']['deleting_customerfiles'] = 'Verwijderen klantbestanden van %loginname%';
|
||||
$lng['tasks']['noneoutstanding'] = 'Er zijn op dit moment geen uitstaande taken voor Froxlor';
|
||||
$lng['ticket']['nonexistingcustomer'] = '(verwijderde klant)';
|
||||
$lng['admin']['ticket_nocustomeraddingavailable'] = 'Het is niet mogelijk een nieuw supportticket te openen. U dient minimaal 1 klant toe te voegen.';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.1
|
||||
|
||||
@@ -1044,8 +929,6 @@ $lng['admin']['cron']['add'] = 'Cron-taak toevoegen';
|
||||
$lng['crondesc']['cron_tasks'] = 'aanmaken configuratiebestanden';
|
||||
$lng['crondesc']['cron_legacy'] = 'oude cron-taak';
|
||||
$lng['crondesc']['cron_traffic'] = 'berekenen verkeersgegevens';
|
||||
$lng['crondesc']['cron_ticketsreset'] = 'opnieuw instellen ticket-tellers';
|
||||
$lng['crondesc']['cron_ticketarchive'] = 'oude tickets archiveren';
|
||||
$lng['cronmgmt']['seconds'] = 'seconden';
|
||||
$lng['cronmgmt']['minutes'] = 'minuten';
|
||||
$lng['cronmgmt']['hours'] = 'uren';
|
||||
@@ -1077,8 +960,6 @@ $lng['panel']['neverloggedin'] = 'Nog niet ingelogd';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn1
|
||||
$lng['serversettings']['defaultttl'] = 'Standaard TTL voor domeinen in seconden (standaard \'604800\' = 1 week)';
|
||||
$lng['ticket']['logicalorder'] = 'Logische volgorde';
|
||||
$lng['ticket']['orderdesc'] = 'Hier kunt u uw eigen logische volgorde instellen voor het weergeven van de categorie voor tickets. Gebruik 1 - 999, lage nummers worden bovenaan getoond.';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn3
|
||||
$lng['serversettings']['defaultwebsrverrhandler_enabled'] = 'Standaard foutdocumenten voor alle klanten activeren';
|
||||
@@ -1090,9 +971,6 @@ $lng['serversettings']['defaultwebsrverrhandler_err404'] = 'Bestand/URL voor fou
|
||||
$lng['serversettings']['defaultwebsrverrhandler_err500']['title'] = 'Bestand/URL voor foutcode 500';
|
||||
$lng['serversettings']['defaultwebsrverrhandler_err500']['description'] = '<div class="red">Wordt niet ondersteund in: lighttpd</div>';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn4
|
||||
$lng['serversettings']['ticket']['default_priority'] = 'Standaardprioriteit voor support-tickets';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn5
|
||||
$lng['serversettings']['mod_fcgid']['defaultini'] = 'Standaard PHP-configuratie voor nieuwe domeinen';
|
||||
|
||||
|
||||
@@ -228,7 +228,6 @@ $lng['error']['destinationnonexist'] = 'Please create your forwarder in the fiel
|
||||
$lng['error']['destinationalreadyexistasmail'] = 'The forwarder to %s already exists as active email-address.';
|
||||
$lng['error']['destinationalreadyexist'] = 'You have already defined a forwarder to "%s"';
|
||||
$lng['error']['destinationiswrong'] = 'The forwarder %s contains invalid character(s) or is incomplete.';
|
||||
$lng['error']['ticketnotaccessible'] = 'You cannot access this ticket.';
|
||||
$lng['error']['backupfoldercannotbedocroot'] = 'The folder for backups cannot be your homedir, please chose a folder within your homedir, e.g. /backups';
|
||||
|
||||
/**
|
||||
@@ -589,110 +588,10 @@ $lng['admin']['webalizer']['veryquiet'] = 'No output';
|
||||
$lng['serversettings']['webalizer_quiet']['title'] = 'Webalizer output';
|
||||
$lng['serversettings']['webalizer_quiet']['description'] = 'Verbosity of the webalizer-program';
|
||||
|
||||
// ADDED IN 1.2.18-svn3
|
||||
|
||||
$lng['ticket']['admin_email'] = 'root@localhost';
|
||||
$lng['ticket']['noreply_email'] = 'tickets@froxlor';
|
||||
$lng['admin']['ticketsystem'] = 'Support-tickets';
|
||||
$lng['menue']['ticket']['ticket'] = 'Support tickets';
|
||||
$lng['menue']['ticket']['categories'] = 'Support categories';
|
||||
$lng['menue']['ticket']['archive'] = 'Ticket-archive';
|
||||
$lng['ticket']['description'] = 'Here you can send help-requests to your responsible administrator.<br />Notifications will be sent via e-mail.';
|
||||
$lng['ticket']['ticket_new'] = 'Open a new ticket';
|
||||
$lng['ticket']['ticket_reply'] = 'Answer ticket';
|
||||
$lng['ticket']['ticket_reopen'] = 'Reopen ticket';
|
||||
$lng['ticket']['ticket_newcateory'] = 'Create new category';
|
||||
$lng['ticket']['ticket_editcateory'] = 'Edit category';
|
||||
$lng['ticket']['ticket_view'] = 'View ticketcourse';
|
||||
$lng['ticket']['ticketcount'] = 'Tickets';
|
||||
$lng['ticket']['ticket_answers'] = 'Replies';
|
||||
$lng['ticket']['subject'] = 'Subject';
|
||||
$lng['ticket']['status'] = 'Status';
|
||||
$lng['ticket']['lastreplier'] = 'Last replier';
|
||||
$lng['ticket']['priority'] = 'Priority';
|
||||
$lng['ticket']['low'] = 'Low';
|
||||
$lng['ticket']['normal'] = 'Normal';
|
||||
$lng['ticket']['high'] = 'High';
|
||||
$lng['ticket']['lastchange'] = 'Last change';
|
||||
$lng['ticket']['lastchange_from'] = 'From date (dd.mm.yyyy)';
|
||||
$lng['ticket']['lastchange_to'] = 'To date (dd.mm.yyyy)';
|
||||
$lng['ticket']['category'] = 'Category';
|
||||
$lng['ticket']['no_cat'] = 'None';
|
||||
$lng['ticket']['message'] = 'Message';
|
||||
$lng['ticket']['show'] = 'View';
|
||||
$lng['ticket']['answer'] = 'Answer';
|
||||
$lng['ticket']['close'] = 'Close';
|
||||
$lng['ticket']['reopen'] = 'Re-open';
|
||||
$lng['ticket']['archive'] = 'Archive';
|
||||
$lng['ticket']['ticket_delete'] = 'Delete ticket';
|
||||
$lng['ticket']['lastarchived'] = 'Recently archived tickets';
|
||||
$lng['ticket']['archivedtime'] = 'Archived';
|
||||
$lng['ticket']['open'] = 'Open';
|
||||
$lng['ticket']['wait_reply'] = 'Waiting for reply';
|
||||
$lng['ticket']['replied'] = 'Replied';
|
||||
$lng['ticket']['closed'] = 'Closed';
|
||||
$lng['ticket']['staff'] = 'Staff';
|
||||
$lng['ticket']['customer'] = 'Customer';
|
||||
$lng['ticket']['old_tickets'] = 'Ticket messages';
|
||||
$lng['ticket']['search'] = 'Search archive';
|
||||
$lng['ticket']['nocustomer'] = 'No choice';
|
||||
$lng['ticket']['archivesearch'] = 'Archive searchresults';
|
||||
$lng['ticket']['noresults'] = 'No tickets found';
|
||||
$lng['ticket']['notmorethanxopentickets'] = 'Due to spam-protection you cannot have more than %s open tickets';
|
||||
$lng['ticket']['supportstatus'] = 'Support-Status';
|
||||
$lng['ticket']['supportavailable'] = '<span class="ticket_low">Our support engineers are available and ready to assist.</span>';
|
||||
$lng['ticket']['supportnotavailable'] = '<span class="ticket_high">Our support engineers are currently not available</span>';
|
||||
$lng['admin']['templates']['ticket'] = 'Notification-mails for support-tickets';
|
||||
$lng['admin']['templates']['SUBJECT'] = 'Replaced with the support-ticket subject';
|
||||
$lng['admin']['templates']['new_ticket_for_customer'] = 'Customer-information that the ticket has been sent';
|
||||
$lng['admin']['templates']['new_ticket_by_customer'] = 'Admin-notification for a ticket opened by a customer';
|
||||
$lng['admin']['templates']['new_reply_ticket_by_customer'] = 'Admin-notification for a ticket-reply by a customer';
|
||||
$lng['admin']['templates']['new_ticket_by_staff'] = 'Customer-notification for a ticket opened by a staff';
|
||||
$lng['admin']['templates']['new_reply_ticket_by_staff'] = 'Customer-notification for a ticket-reply by a staff';
|
||||
$lng['mails']['new_ticket_for_customer']['mailbody'] = 'Hello {FIRSTNAME} {NAME},\n\nyour support-ticket with the subject "{SUBJECT}" has been sent.\n\nYou will be notified when your ticket has been answered.\n\nThank you,\nyour administrator';
|
||||
$lng['mails']['new_ticket_for_customer']['subject'] = 'Your support ticket has been sent';
|
||||
$lng['mails']['new_ticket_by_customer']['mailbody'] = 'Hello admin,\n\na new support-ticket with the subject "{SUBJECT}" has been submitted.\n\nPlease login to open the ticket.\n\nThank you,\nyour administrator';
|
||||
$lng['mails']['new_ticket_by_customer']['subject'] = 'New support ticket submitted';
|
||||
$lng['mails']['new_reply_ticket_by_customer']['mailbody'] = 'Hello admin,\n\nthe support-ticket "{SUBJECT}" has been answered by a customer.\n\nPlease login to open the ticket.\n\nThank you,\nyour administrator';
|
||||
$lng['mails']['new_reply_ticket_by_customer']['subject'] = 'New reply to support ticket';
|
||||
$lng['mails']['new_ticket_by_staff']['mailbody'] = 'Hello {FIRSTNAME} {NAME},\n\na support-ticket with the subject "{SUBJECT}" has been opened for you.\n\nPlease login to open the ticket.\n\nThank you,\nyour administrator';
|
||||
$lng['mails']['new_ticket_by_staff']['subject'] = 'New support ticket submitted';
|
||||
$lng['mails']['new_reply_ticket_by_staff']['mailbody'] = 'Hello {FIRSTNAME} {NAME},\n\nthe support-ticket with the subject "{SUBJECT}" has been answered by our staff.\n\nPlease login to view the ticket.\n\nThank you,\nyour administrator';
|
||||
$lng['mails']['new_reply_ticket_by_staff']['subject'] = 'New reply to support ticket';
|
||||
$lng['question']['ticket_reallyclose'] = 'Do you really want to close the ticket "%s"?';
|
||||
$lng['question']['ticket_reallydelete'] = 'Do you really want to delete the ticket "%s"?';
|
||||
$lng['question']['ticket_reallydeletecat'] = 'Do you really want to delete the category "%s"?';
|
||||
$lng['question']['ticket_reallyarchive'] = 'Do you really want to move the ticket "%s" to the archive?';
|
||||
$lng['error']['nomoreticketsavailable'] = 'You have used all your available tickets. Please contact your administrator.';
|
||||
$lng['error']['nocustomerforticket'] = 'Cannot create tickets without customers';
|
||||
$lng['error']['categoryhastickets'] = 'The category still has tickets in it.<br />Please delete the tickets to delete the category';
|
||||
$lng['admin']['ticketsettings'] = 'Support-Ticket settings';
|
||||
$lng['admin']['archivelastrun'] = 'Last ticket archiving';
|
||||
$lng['serversettings']['ticket']['noreply_email']['title'] = 'No-reply e-mail address';
|
||||
$lng['serversettings']['ticket']['noreply_email']['description'] = 'The sender-address for support-ticket, mostly something like no-reply@domain.tld';
|
||||
$lng['serversettings']['ticket']['worktime_begin']['title'] = 'Begin support-time (hh:mm)';
|
||||
$lng['serversettings']['ticket']['worktime_begin']['description'] = 'Start-time when support is available';
|
||||
$lng['serversettings']['ticket']['worktime_end']['title'] = 'End support-time (hh:mm)';
|
||||
$lng['serversettings']['ticket']['worktime_end']['description'] = 'End-time when support is available';
|
||||
$lng['serversettings']['ticket']['worktime_sat'] = 'Support available on saturdays?';
|
||||
$lng['serversettings']['ticket']['worktime_sun'] = 'Support available on sundays?';
|
||||
$lng['serversettings']['ticket']['worktime_all']['title'] = 'No time limit for support';
|
||||
$lng['serversettings']['ticket']['worktime_all']['description'] = 'If "Yes" the options for start- and endtime will be overwritten';
|
||||
$lng['serversettings']['ticket']['archiving_days'] = 'After how many days should closed tickets be archived?';
|
||||
$lng['customer']['tickets'] = 'Support-tickets';
|
||||
|
||||
// ADDED IN 1.2.18-svn4
|
||||
|
||||
$lng['admin']['domain_nocustomeraddingavailable'] = 'It\'s not possible to add a domain currently. You first need to add at least one customer.';
|
||||
$lng['serversettings']['ticket']['enable'] = 'Enable ticketsystem';
|
||||
$lng['serversettings']['ticket']['concurrentlyopen'] = 'How many tickets shall be able to be opened at one time?';
|
||||
$lng['error']['norepymailiswrong'] = 'The "Noreply-address" is wrong. Only a valid email-address is allowed.';
|
||||
$lng['error']['tadminmailiswrong'] = 'The "Ticketadmin-address" is wrong. Only a valid email-address is allowed.';
|
||||
$lng['ticket']['awaitingticketreply'] = 'You have %s unanswered support-ticket(s)';
|
||||
|
||||
// ADDED IN 1.2.18-svn5
|
||||
|
||||
$lng['serversettings']['ticket']['noreply_name'] = 'Ticket e-mail sendername';
|
||||
|
||||
// ADDED IN 1.2.19-svn1
|
||||
|
||||
@@ -700,16 +599,6 @@ $lng['serversettings']['mod_fcgid']['configdir']['title'] = 'Configuration direc
|
||||
$lng['serversettings']['mod_fcgid']['configdir']['description'] = 'Where should all fcgid-configuration files be stored? If you don\'t use a self compiled suexec binary, which is the normal situation, this path must be under /var/www/<br /><br /><div class="red">NOTE: This folder\'s content gets deleted regulary so avoid storing data in there manually.</div>';
|
||||
$lng['serversettings']['mod_fcgid']['tmpdir']['title'] = 'Temp directory';
|
||||
|
||||
// ADDED IN 1.2.19-svn3
|
||||
|
||||
$lng['serversettings']['ticket']['reset_cycle']['title'] = 'Reset used tickets cycle';
|
||||
$lng['serversettings']['ticket']['reset_cycle']['description'] = 'Reset the customers used ticket counter to 0 in the chosen cycle';
|
||||
$lng['admin']['tickets']['daily'] = 'Daily';
|
||||
$lng['admin']['tickets']['weekly'] = 'Weekly';
|
||||
$lng['admin']['tickets']['monthly'] = 'Monthly';
|
||||
$lng['admin']['tickets']['yearly'] = 'Yearly';
|
||||
$lng['error']['ticketresetcycleiswrong'] = 'The cycle for ticket-resets has to be "daily", "weekly", "monthly" or "yearly".';
|
||||
|
||||
// ADDED IN 1.2.19-svn4
|
||||
|
||||
$lng['menue']['traffic']['traffic'] = 'Traffic';
|
||||
@@ -819,7 +708,6 @@ $lng['admin']['caneditphpsettings'] = 'Can change php-related domain settings?';
|
||||
|
||||
$lng['admin']['allips'] = 'All IP\'s';
|
||||
$lng['panel']['nosslipsavailable'] = 'There are currently no ssl ip/port combinations for this server';
|
||||
$lng['ticket']['by'] = 'by';
|
||||
$lng['dkim']['use_dkim']['title'] = 'Activate DKIM support?';
|
||||
$lng['dkim']['use_dkim']['description'] = 'Would you like to use the Domain Keys (DKIM) system?<br/><em class="red">Note: DKIM is only supported using dkim-filter, not opendkim (yet)</em>';
|
||||
$lng['error']['invalidmysqlhost'] = 'Invalid MySQL host address: %s';
|
||||
@@ -1073,8 +961,6 @@ $lng['tasks']['rebuild_bindconfig'] = 'Rebuilding bind-configuration';
|
||||
$lng['tasks']['creating_ftpdir'] = 'Creating directory for new ftp-user';
|
||||
$lng['tasks']['deleting_customerfiles'] = 'Deleting customer-files %loginname%';
|
||||
$lng['tasks']['noneoutstanding'] = 'There are currently no outstanding tasks for Froxlor';
|
||||
$lng['ticket']['nonexistingcustomer'] = '(deleted customer)';
|
||||
$lng['admin']['ticket_nocustomeraddingavailable'] = 'It\'s not possible to open a new support-ticket currently. You first need to add at least one customer.';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.1
|
||||
|
||||
@@ -1129,8 +1015,6 @@ $lng['admin']['cron']['add'] = 'Add cronjob';
|
||||
$lng['crondesc']['cron_tasks'] = 'generating of configfiles';
|
||||
$lng['crondesc']['cron_legacy'] = 'legacy (old) cronjob';
|
||||
$lng['crondesc']['cron_traffic'] = 'traffic calculation';
|
||||
$lng['crondesc']['cron_ticketsreset'] = 'resetting ticket-counters';
|
||||
$lng['crondesc']['cron_ticketarchive'] = 'archiving old tickets';
|
||||
$lng['cronmgmt']['minutes'] = 'minutes';
|
||||
$lng['cronmgmt']['hours'] = 'hours';
|
||||
$lng['cronmgmt']['days'] = 'days';
|
||||
@@ -1162,8 +1046,6 @@ $lng['panel']['neverloggedin'] = 'No login yet';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn1
|
||||
$lng['serversettings']['defaultttl'] = 'Domain TTL for bind in seconds (default \'604800\' = 1 week)';
|
||||
$lng['ticket']['logicalorder'] = 'Logical order';
|
||||
$lng['ticket']['orderdesc'] = 'Here you can define your own logical order for the ticket-category. Use 1 - 999, lower numbers are displayed first.';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn3
|
||||
$lng['serversettings']['defaultwebsrverrhandler_enabled'] = 'Enable default errordocuments for all customers';
|
||||
@@ -1175,9 +1057,6 @@ $lng['serversettings']['defaultwebsrverrhandler_err404'] = 'File/URL for error 4
|
||||
$lng['serversettings']['defaultwebsrverrhandler_err500']['title'] = 'File/URL for error 500';
|
||||
$lng['serversettings']['defaultwebsrverrhandler_err500']['description'] = '<div class="red">Not supported in: lighttpd</div>';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn4
|
||||
$lng['serversettings']['ticket']['default_priority'] = 'Default support-ticket priority';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn5
|
||||
$lng['serversettings']['mod_fcgid']['defaultini'] = 'Default PHP configuration for new domains';
|
||||
|
||||
@@ -1691,7 +1570,6 @@ $lng['serversettings']['catchall_enabled']['description'] = 'Do you want to pro
|
||||
// ADDED IN 0.9.28.svn6
|
||||
$lng['serversettings']['apache_24']['title'] = 'Use modifications for Apache 2.4';
|
||||
$lng['serversettings']['apache_24']['description'] = '<strong class="red">ATTENTION:</strong> use only if you acutally have apache version 2.4 or higher installed<br />otherwise your webserver will not be able to start';
|
||||
$lng['admin']['tickets_see_all'] = 'Can see all ticket-categories?';
|
||||
$lng['serversettings']['nginx_fastcgiparams']['title'] = 'Path to fastcgi_params file';
|
||||
$lng['serversettings']['nginx_fastcgiparams']['description'] = 'Specify the path to nginx\'s fastcgi_params file including filename';
|
||||
|
||||
|
||||
@@ -226,7 +226,6 @@ $lng['error']['destinationnonexist'] = 'Bitte geben Sie Ihre Weiterleitungsadres
|
||||
$lng['error']['destinationalreadyexistasmail'] = 'Die Weiterleitung zu "%s" existiert bereits als aktive E-Mail-Adresse.';
|
||||
$lng['error']['destinationalreadyexist'] = 'Es existiert bereits eine Weiterleitung nach "%s".';
|
||||
$lng['error']['destinationiswrong'] = 'Die Weiterleitungsadresse "%s" enthält ungültige Zeichen oder ist nicht vollständig.';
|
||||
$lng['error']['ticketnotaccessible'] = 'Sie können sich das Ticket nicht ansehen.';
|
||||
$lng['error']['backupfoldercannotbedocroot'] = 'Der Ordner für Backups darf nicht das Heimatverzeichnis sein, wählen Sie einen Ordner unterhalb des Heimatverzeichnisses, z.B. /backups';
|
||||
|
||||
/**
|
||||
@@ -584,110 +583,9 @@ $lng['admin']['webalizer']['veryquiet'] = 'Keine Ausgaben';
|
||||
$lng['serversettings']['webalizer_quiet']['title'] = 'Webalizerausgabe';
|
||||
$lng['serversettings']['webalizer_quiet']['description'] = 'Ausgabefreudigkeit des Webalizer-Programms';
|
||||
|
||||
// ADDED IN 1.2.18-svn3
|
||||
|
||||
$lng['ticket']['admin_email'] = 'root@localhost';
|
||||
$lng['ticket']['noreply_email'] = 'tickets@froxlor';
|
||||
$lng['admin']['ticketsystem'] = 'Support-Tickets';
|
||||
$lng['menue']['ticket']['ticket'] = 'Support-Tickets';
|
||||
$lng['menue']['ticket']['categories'] = 'Support-Kategorien';
|
||||
$lng['menue']['ticket']['archive'] = 'Ticket-Archiv';
|
||||
$lng['ticket']['description'] = 'Hier können Sie Hilfe-Anfragen an Ihren zuständigen Administrator senden.<br />Benachrichtigungen werden per E-Mail verschickt.';
|
||||
$lng['ticket']['ticket_new'] = 'Neues Support-Ticket erstellen';
|
||||
$lng['ticket']['ticket_reply'] = 'Auf Support-Ticket antworten';
|
||||
$lng['ticket']['ticket_reopen'] = 'Ticket wiedereröffnen';
|
||||
$lng['ticket']['ticket_newcateory'] = 'Neue Support-Kategorie erstellen';
|
||||
$lng['ticket']['ticket_editcateory'] = 'Support-Kategorie bearbeiten';
|
||||
$lng['ticket']['ticket_view'] = 'Ticketverlauf ansehen';
|
||||
$lng['ticket']['ticketcount'] = 'Anzahl Tickets';
|
||||
$lng['ticket']['ticket_answers'] = 'Antworten';
|
||||
$lng['ticket']['subject'] = 'Betreff';
|
||||
$lng['ticket']['status'] = 'Status';
|
||||
$lng['ticket']['lastreplier'] = 'Letzte Antwort';
|
||||
$lng['ticket']['priority'] = 'Priorität';
|
||||
$lng['ticket']['low'] = 'Niedrig';
|
||||
$lng['ticket']['normal'] = 'Normal';
|
||||
$lng['ticket']['high'] = 'Hoch';
|
||||
$lng['ticket']['lastchange'] = 'Letzte Änderung';
|
||||
$lng['ticket']['lastchange_from'] = 'Anfangsdatum (tt.mm.jjjj)';
|
||||
$lng['ticket']['lastchange_to'] = 'Enddatum (tt.mm.jjjj)';
|
||||
$lng['ticket']['category'] = 'Kategorie';
|
||||
$lng['ticket']['no_cat'] = 'Keine';
|
||||
$lng['ticket']['message'] = 'Nachricht';
|
||||
$lng['ticket']['show'] = 'Anschauen';
|
||||
$lng['ticket']['answer'] = 'Antworten';
|
||||
$lng['ticket']['close'] = 'Schließen';
|
||||
$lng['ticket']['reopen'] = 'Wiedereröffnen';
|
||||
$lng['ticket']['archive'] = 'Archivieren';
|
||||
$lng['ticket']['ticket_delete'] = 'Ticket löschen';
|
||||
$lng['ticket']['lastarchived'] = 'Zuletzt archivierte Tickets';
|
||||
$lng['ticket']['archivedtime'] = 'Archiviert';
|
||||
$lng['ticket']['open'] = 'Offen';
|
||||
$lng['ticket']['wait_reply'] = 'Warte auf Antwort';
|
||||
$lng['ticket']['replied'] = 'Beantwortet';
|
||||
$lng['ticket']['closed'] = 'Geschlossen';
|
||||
$lng['ticket']['staff'] = 'Mitarbeiter';
|
||||
$lng['ticket']['customer'] = 'Kunde';
|
||||
$lng['ticket']['old_tickets'] = 'Bisheriger Ticketverlauf';
|
||||
$lng['ticket']['search'] = 'Archiv durchsuchen';
|
||||
$lng['ticket']['nocustomer'] = 'Keine Angabe';
|
||||
$lng['ticket']['archivesearch'] = 'Archiv Suchergebnis';
|
||||
$lng['ticket']['noresults'] = 'Keine Tickets gefunden';
|
||||
$lng['ticket']['notmorethanxopentickets'] = 'Zum Schutz gegen Spam können Sie nicht mehr als "%s" offene Tickets haben';
|
||||
$lng['ticket']['supportstatus'] = 'Support-Status';
|
||||
$lng['ticket']['supportavailable'] = '<span class="ticket_low">Der Support ist besetzt und steht zu Ihrer Verfügung.</span>';
|
||||
$lng['ticket']['supportnotavailable'] = '<span class="ticket_high">Der Support ist zur Zeit nicht besetzt.</span>';
|
||||
$lng['admin']['templates']['ticket'] = 'Benachrichtigungs-Mails für Support-Tickets';
|
||||
$lng['admin']['templates']['SUBJECT'] = 'Wird mit dem Betreff des Support-Tickets ersetzt';
|
||||
$lng['admin']['templates']['new_ticket_for_customer'] = 'Kunden-Information, dass das Ticket übermittelt wurde';
|
||||
$lng['admin']['templates']['new_ticket_by_customer'] = 'Admin-Benachrichtigung für ein Ticket eines Kunden';
|
||||
$lng['admin']['templates']['new_reply_ticket_by_customer'] = 'Admin-Benachrichtigung für ein beantwortetes Ticket';
|
||||
$lng['admin']['templates']['new_ticket_by_staff'] = 'Kunden-Benachrichtigung für ein Ticket eines Mitarbeiters';
|
||||
$lng['admin']['templates']['new_reply_ticket_by_staff'] = 'Kunden-Benachrichtigung für ein beantwortetes Ticket';
|
||||
$lng['mails']['new_ticket_for_customer']['mailbody'] = 'Hallo {FIRSTNAME} {NAME},\n\nihr Support-Ticket mit dem Betreff "{SUBJECT}" wurde erfolgreich gesendet.\n\nSobald ihr Ticket beantwortet wurde, werden Sie per E-Mail benachrichtigt.\n\nVielen Dank,\nIhr Administrator';
|
||||
$lng['mails']['new_ticket_for_customer']['subject'] = 'Wir haben Ihr Support-Ticket erhalten.';
|
||||
$lng['mails']['new_ticket_by_customer']['mailbody'] = 'Hallo Admin,\n\nein neues Support-Ticket wurde uebermittelt.\n\nBitte melde Dich an um es aufzurufen.\n\nVielen Dank,\nIhr Administrator';
|
||||
$lng['mails']['new_ticket_by_customer']['subject'] = 'Neues Support-Ticket';
|
||||
$lng['mails']['new_reply_ticket_by_customer']['mailbody'] = 'Hallo Admin,\n\ndas Support-Ticket "{SUBJECT}" wurde von einem Kunden beantwortet.\n\nBitte melde Dich an um es aufzurufen.\n\nVielen Dank,\nIhr Administrator';
|
||||
$lng['mails']['new_reply_ticket_by_customer']['subject'] = 'Neue Antwort zu einem Support-Ticket';
|
||||
$lng['mails']['new_ticket_by_staff']['mailbody'] = 'Hallo {FIRSTNAME} {NAME},\n\nein Support-Ticket mit dem Betreff "{SUBJECT}" wurde an Sie übermittelt.\n\nBitte melden Sie sich an, um das Ticket aufzurufen.\n\nVielen Dank,\nIhr Administrator';
|
||||
$lng['mails']['new_ticket_by_staff']['subject'] = 'Neues Support-Ticket';
|
||||
$lng['mails']['new_reply_ticket_by_staff']['mailbody'] = 'Hallo {FIRSTNAME} {NAME},\n\ndas Support-Ticket mit dem Betreff "{SUBJECT}" wurde von einem Mitarbeiter beantwortet.\n\nBitte melden Sie sich an, um das Ticket aufzurufen.\n\nVielen Dank,\nIhr Administrator';
|
||||
$lng['mails']['new_reply_ticket_by_staff']['subject'] = 'Neue Antwort zu einem Support-Ticket';
|
||||
$lng['question']['ticket_reallyclose'] = 'Wollen Sie das Ticket "%s" wirklich schließen?';
|
||||
$lng['question']['ticket_reallydelete'] = 'Wollen Sie das Ticket "%s" wirklich löschen?';
|
||||
$lng['question']['ticket_reallydeletecat'] = 'Wollen Sie die Kategorie "%s" wirklich löschen?';
|
||||
$lng['question']['ticket_reallyarchive'] = 'Wollen Sie das Ticket "%s" wirklich in das Archiv verschieben?';
|
||||
$lng['error']['nomoreticketsavailable'] = 'Sie haben Ihr Ticketkontingent aufgebraucht. Bitte kontaktieren Sie ihren Administrator.';
|
||||
$lng['error']['nocustomerforticket'] = 'Keine Kunden vorhanden, um ein Ticket zu erstellen.';
|
||||
$lng['error']['categoryhastickets'] = 'In dieser Kategorie befinden sich noch Tickets.<br />Bitte löschen Sie diese, um die Kategorie zu löschen';
|
||||
$lng['admin']['ticketsettings'] = 'Support-Ticket-Einstellungen';
|
||||
$lng['admin']['archivelastrun'] = 'Letzte Ticket-Archivierung';
|
||||
$lng['serversettings']['ticket']['noreply_email']['title'] = 'Absender-Adresse';
|
||||
$lng['serversettings']['ticket']['noreply_email']['description'] = 'Die Absender-Adresse der Support-Tickets. Meist sowas wie keine-antwort@domain.tld';
|
||||
$lng['serversettings']['ticket']['worktime_begin']['title'] = 'Beginn Support-Zeit (hh:mm)';
|
||||
$lng['serversettings']['ticket']['worktime_begin']['description'] = 'Beginn der Zeit in der der Support besetzt ist.';
|
||||
$lng['serversettings']['ticket']['worktime_end']['title'] = 'Ende Support-Zeit (hh:mm)';
|
||||
$lng['serversettings']['ticket']['worktime_end']['description'] = 'Ende der Zeit in der der Support besetzt ist.';
|
||||
$lng['serversettings']['ticket']['worktime_sat'] = 'Support an Samstagen besetzt?';
|
||||
$lng['serversettings']['ticket']['worktime_sun'] = 'Support an Sonntagen besetzt?';
|
||||
$lng['serversettings']['ticket']['worktime_all']['title'] = 'Kein zeitlich begrenzter Support';
|
||||
$lng['serversettings']['ticket']['worktime_all']['description'] = 'Wenn "Ja" überschreibt diese Option Start- und Endzeit des Supports';
|
||||
$lng['serversettings']['ticket']['archiving_days'] = 'Nach wievielen Tagen sollen abgeschlossene Tickets archiviert werden?';
|
||||
$lng['customer']['tickets'] = 'Support-Tickets';
|
||||
|
||||
// ADDED IN 1.2.18-svn4
|
||||
|
||||
$lng['admin']['domain_nocustomeraddingavailable'] = 'Es können derzeit keine Domains angelegt werden. Sie müssen zuerst einen Kunden anlegen';
|
||||
$lng['serversettings']['ticket']['enable'] = 'Ticketsystem aktivieren';
|
||||
$lng['serversettings']['ticket']['concurrentlyopen'] = 'Wieviele Tickets kann ein Kunde gleichzeitig öffnen?';
|
||||
$lng['error']['norepymailiswrong'] = 'Die "Keine-Antwort-Adresse" ist fehlerhaft. Es ist nur eine gültige E-Mail-Adresse erlaubt';
|
||||
$lng['error']['tadminmailiswrong'] = 'Die "Ticket-Admin-Adresse" ist fehlerhaft. Es ist nur eine gültige E-Mail-Adresse erlaubt';
|
||||
$lng['ticket']['awaitingticketreply'] = 'Sie haben "%s" unbeantwortete(s) Support-Ticket(s)';
|
||||
|
||||
// ADDED IN 1.2.18-svn5
|
||||
|
||||
$lng['serversettings']['ticket']['noreply_name'] = 'E-Mail-Absendername für Tickets';
|
||||
|
||||
// ADDED IN 1.2.19-svn
|
||||
|
||||
@@ -695,16 +593,6 @@ $lng['serversettings']['mod_fcgid']['configdir']['title'] = 'Konfigurations-Verz
|
||||
$lng['serversettings']['mod_fcgid']['configdir']['description'] = 'Wo sollen alle Konfigurationsdateien von fcgid liegen? Wenn Sie keine selbst kompilierte suexec Binary benutzen, was in der Regel der Fall ist, muss dieser Pfad unter /var/www/ liegen.<br /><br /><div class="red">ACHTUNG: Der Inhalt dieses Ordners wird regelmäßig geleert, daher sollten dort keinerlei Daten manuell abgelegt werden.</div>';
|
||||
$lng['serversettings']['mod_fcgid']['tmpdir']['title'] = 'Temporäres Verzeichnis';
|
||||
|
||||
// ADDED IN 1.2.19-svn3
|
||||
|
||||
$lng['serversettings']['ticket']['reset_cycle']['title'] = 'Turnus verbrauchte Tickets zurücksetzen';
|
||||
$lng['serversettings']['ticket']['reset_cycle']['description'] = 'Setzt die Anzahl der vom Kunden verbrauchten Tickets in dem angegebenen Turnus auf 0';
|
||||
$lng['admin']['tickets']['daily'] = 'Täglich';
|
||||
$lng['admin']['tickets']['weekly'] = 'Wöchentlich';
|
||||
$lng['admin']['tickets']['monthly'] = 'Monatlich';
|
||||
$lng['admin']['tickets']['yearly'] = 'Jährlich';
|
||||
$lng['error']['ticketresetcycleiswrong'] = 'Der Turnus des Ticket-Zurücksetzen muss "Täglich", "Wöchentlich", "Monatlich" oder "Jährlich" sein.';
|
||||
|
||||
// ADDED IN 1.2.19-svn4
|
||||
|
||||
$lng['menue']['traffic']['traffic'] = 'Traffic';
|
||||
@@ -814,7 +702,6 @@ $lng['admin']['caneditphpsettings'] = 'Kann PHP-bezogene Domaineinstellungen vor
|
||||
|
||||
$lng['admin']['allips'] = 'Alle IP-Adressen';
|
||||
$lng['panel']['nosslipsavailable'] = 'Für diesen Server wurden noch keine SSL IP/Port Kombinationen eingetragen';
|
||||
$lng['ticket']['by'] = 'von';
|
||||
$lng['dkim']['use_dkim']['title'] = 'DKIM-Support aktivieren?';
|
||||
$lng['dkim']['use_dkim']['description'] = 'Wollen Sie das Domain-Keys-System (DKIM) benutzen?<br/><em class="red">Hinweis: Derzeit wird DKIM nur via dkim-filter unterstützt, nicht opendkim.</em>';
|
||||
$lng['error']['invalidmysqlhost'] = 'Ungültige MySQL-Host-Adresse: "%s"';
|
||||
@@ -1046,8 +933,6 @@ $lng['tasks']['rebuild_bindconfig'] = 'Neuerstellung der Bind-Konfiguration';
|
||||
$lng['tasks']['creating_ftpdir'] = 'Erstelle Verzeichnis für neuen FTP-Benutzer';
|
||||
$lng['tasks']['deleting_customerfiles'] = 'Löschen von Kunden-Dateien %loginname%';
|
||||
$lng['tasks']['noneoutstanding'] = 'Zur Zeit gibt es keine ausstehenden Aufgaben für Froxlor';
|
||||
$lng['ticket']['nonexistingcustomer'] = '(gelöschter Kunde)';
|
||||
$lng['admin']['ticket_nocustomeraddingavailable'] = 'Es können derzeit keine neuen Support-Tickets eröffnet werden. Sie müssen zuerst einen Kunden anlegen';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.1
|
||||
|
||||
@@ -1102,8 +987,6 @@ $lng['admin']['cron']['add'] = 'Cronjob hinzufügen';
|
||||
$lng['crondesc']['cron_tasks'] = 'Erstellen von Konfigurationsdateien';
|
||||
$lng['crondesc']['cron_legacy'] = 'Legacy (alter) Cronjob';
|
||||
$lng['crondesc']['cron_traffic'] = 'Traffic-Berechnung';
|
||||
$lng['crondesc']['cron_ticketsreset'] = 'Zurücksetzen der Ticket-Zähler';
|
||||
$lng['crondesc']['cron_ticketarchive'] = 'Archivieren alter Tickets';
|
||||
$lng['cronmgmt']['minutes'] = 'Minuten';
|
||||
$lng['cronmgmt']['hours'] = 'Stunden';
|
||||
$lng['cronmgmt']['days'] = 'Tage';
|
||||
@@ -1153,8 +1036,6 @@ $lng['panel']['neverloggedin'] = 'Keine Anmeldung bisher';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn1
|
||||
$lng['serversettings']['defaultttl'] = 'Domain TTL für Bind in Sekunden (default \'604800\' = 1 Woche)';
|
||||
$lng['ticket']['logicalorder'] = 'Logische Sortierung';
|
||||
$lng['ticket']['orderdesc'] = 'Hier kann eine logische Sortierung für die Ticket-Kategorien angegeben werden. Benutzen Sie 1 - 999, niedrigere Zahlen werden zuerst angezeigt.';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn3
|
||||
$lng['serversettings']['defaultwebsrverrhandler_enabled'] = 'Verwende Standard-Fehlerdokumente für alle Kunden';
|
||||
@@ -1166,9 +1047,6 @@ $lng['serversettings']['defaultwebsrverrhandler_err404'] = 'Datei/URL für Fehle
|
||||
$lng['serversettings']['defaultwebsrverrhandler_err500']['title'] = 'Datei/URL für Fehler 500';
|
||||
$lng['serversettings']['defaultwebsrverrhandler_err500']['description'] = '<div class="red">Nicht unterstützt in: lighttpd</div>';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn4
|
||||
$lng['serversettings']['ticket']['default_priority'] = 'Voreingestellte Support-Ticket Priorität';
|
||||
|
||||
// ADDED IN FROXLOR 0.9.6-svn5
|
||||
$lng['serversettings']['mod_fcgid']['defaultini'] = 'Voreingestellte PHP-Konfiguration für neue Domains';
|
||||
|
||||
@@ -1417,7 +1295,6 @@ $lng['serversettings']['catchall_enabled']['description'] = 'Möchten Sie Ihren
|
||||
// ADDED IN 0.9.28.svn6
|
||||
$lng['serversettings']['apache_24']['title'] = 'Anpassungen für Apache 2.4 verwenden';
|
||||
$lng['serversettings']['apache_24']['description'] = '<div class="red">Achtung: Bitte nur verwenden, wenn wirklich Apache mit Version 2.4 oder höher installiert ist, ansonsten wird der Webserver nicht starten.</div>';
|
||||
$lng['admin']['tickets_see_all'] = 'Kann alle Ticket-Kategorien sehen?';
|
||||
$lng['serversettings']['nginx_fastcgiparams']['title'] = 'Pfad zur fastcgi_params Datei';
|
||||
$lng['serversettings']['nginx_fastcgiparams']['description'] = 'Geben Sie den Pfad zu nginx\'s fastcgi_params Datei an. Inklusive Dateiname!';
|
||||
|
||||
|
||||
@@ -29,10 +29,6 @@ $lng['error']['myname'] = '\'' . $lng['customer']['name'] . '\'';
|
||||
$lng['error']['myfirstname'] = '\'' . $lng['customer']['firstname'] . '\'';
|
||||
$lng['error']['emailadd'] = '\'' . $lng['customer']['email'] . '\'';
|
||||
$lng['error']['domainname'] = $lng['domains']['domainname'];
|
||||
$lng['error']['mysubject'] = '\'' . $lng['ticket']['subject'] . '\'';
|
||||
$lng['error']['mymessage'] = '\'' . $lng['ticket']['message'] . '\'';
|
||||
$lng['error']['mycategory'] = '\'' . $lng['ticket']['category'] . '\'';
|
||||
$lng['error']['notmorethanxopentickets'] = $lng['ticket']['notmorethanxopentickets'];
|
||||
|
||||
/**
|
||||
* other language-strings which need no translation
|
||||
|
||||
@@ -15,105 +15,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
define('MASTER_CRONJOB', 1);
|
||||
|
||||
include_once dirname(dirname(__FILE__)) . '/lib/cron_init.php';
|
||||
|
||||
$jobs_to_run = array();
|
||||
|
||||
/**
|
||||
* check for --help
|
||||
*/
|
||||
if (count($argv) < 2 || (isset($argv[1]) && strtolower($argv[1]) == '--help')) {
|
||||
echo "\n*** Froxlor Master Cronjob ***\n\n";
|
||||
echo "Below are possible parameters for this file\n\n";
|
||||
echo "--[cronname]\t\tincludes the given cron-file\n";
|
||||
echo "--force\t\t\tforces re-generating of config-files (webserver, nameserver, etc.)\n";
|
||||
echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n";
|
||||
echo "--no-fork\t\t\tdo not fork to backkground (traffic cron only).\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* check for parameters
|
||||
*
|
||||
* --[cronname] include [cronname]
|
||||
* --force to include cron_tasks even if it's not its turn
|
||||
* --debug to output debug information
|
||||
*/
|
||||
for ($x = 1; $x < count($argv); $x++) {
|
||||
// check argument
|
||||
if (isset($argv[$x])) {
|
||||
// --force
|
||||
if (strtolower($argv[$x]) == '--force') {
|
||||
// really force re-generating of config-files by
|
||||
// inserting task 1
|
||||
inserttask('1');
|
||||
// bind (if enabled, inserttask() checks this)
|
||||
inserttask('4');
|
||||
// set quotas (if enabled)
|
||||
inserttask('10');
|
||||
// also regenerate cron.d-file
|
||||
inserttask('99');
|
||||
addToQueue($jobs_to_run, 'tasks');
|
||||
}
|
||||
elseif (strtolower($argv[$x]) == '--debug') {
|
||||
define('CRON_DEBUG_FLAG', 1);
|
||||
}
|
||||
elseif (strtolower($argv[$x]) == '--no-fork') {
|
||||
define('CRON_NOFORK_FLAG', 1);
|
||||
}
|
||||
// --[cronname]
|
||||
elseif (substr(strtolower($argv[$x]), 0, 2) == '--') {
|
||||
if (strlen($argv[$x]) > 3) {
|
||||
$cronname = substr(strtolower($argv[$x]), 2);
|
||||
addToQueue($jobs_to_run, $cronname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cronlog->setCronDebugFlag(defined('CRON_DEBUG_FLAG'));
|
||||
|
||||
$tasks_cnt_stmt = \Froxlor\Database\Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt = $tasks_cnt_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// do we have anything to include?
|
||||
if (count($jobs_to_run) > 0) {
|
||||
// include all jobs we want to execute
|
||||
foreach ($jobs_to_run as $cron) {
|
||||
updateLastRunOfCron($cron);
|
||||
$cronfile = getCronFile($cron);
|
||||
require_once $cronfile;
|
||||
}
|
||||
|
||||
if ($tasks_cnt['jobcnt'] > 0)
|
||||
{
|
||||
if (\Froxlor\Settings::Get('system.nssextrausers') == 1)
|
||||
{
|
||||
\Froxlor\Cron\System\Extrausers::generateFiles($cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570
|
||||
if (\Froxlor\Settings::Get('system.mod_fcgid') == 1 || (int)\Froxlor\Settings::Get('phpfpm.enabled') == 1) {
|
||||
$false_val = false;
|
||||
safe_exec('nscd -i passwd 1> /dev/null', $false_val, array('>'));
|
||||
safe_exec('nscd -i group 1> /dev/null', $false_val, array('>'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwrite($debugHandler, 'Cronfiles have been included' . "\n");
|
||||
|
||||
/**
|
||||
* we have to check the system's last guid with every cron run
|
||||
* in case the admin installed new software which added a new user
|
||||
* so users in the database don't conflict with system users
|
||||
*/
|
||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Checking system\'s last guid');
|
||||
checkLastGuid();
|
||||
|
||||
// shutdown cron
|
||||
include_once FROXLOR_INSTALL_DIR . '/lib/cron_shutdown.php';
|
||||
|
||||
// -- helper function
|
||||
function getCronFile($cronname) {
|
||||
@@ -129,9 +31,3 @@ function addToQueue(&$jobs_to_run, $cronname) {
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
86
templates/Sparkle/admin/tickets/archive.tpl
vendored
86
templates/Sparkle/admin/tickets/archive.tpl
vendored
@@ -1,86 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/ticket_archive_big.png" alt="" />
|
||||
{$lng['ticket']['lastarchived']}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
|
||||
<table class="full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$lng['ticket']['archivedtime']}</th>
|
||||
<th>{$lng['ticket']['ticket_answers']}</th>
|
||||
<th>{$lng['ticket']['subject']}</th>
|
||||
<th>{$lng['ticket']['lastreplier']}</th>
|
||||
<th>{$lng['ticket']['priority']}</th>
|
||||
<th>{$lng['panel']['options']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
$tickets
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</section>
|
||||
|
||||
</article>
|
||||
<br />
|
||||
<br />
|
||||
<article>
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
|
||||
<input type="hidden" name="s" value="$s"/>
|
||||
<input type="hidden" name="page" value="$page"/>
|
||||
<input type="hidden" name="send" value="send" />
|
||||
|
||||
<table class="full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">{$lng['ticket']['search']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>{$lng['ticket']['subject']}:</td>
|
||||
<td ><input type="text" name="subject" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$lng['ticket']['priority']}:</td>
|
||||
<td >{$priorities_options}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$lng['ticket']['category']}:</td>
|
||||
<td>{$category_options}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$lng['ticket']['lastchange']}:</td>
|
||||
<td>
|
||||
<label for="fromdate">{$lng['ticket']['lastchange_from']}<br /><input type="text" id="fromdate" name="fromdate" /></label><br />
|
||||
<label for="todate">{$lng['ticket']['lastchange_to']}<br /><input type="text" id="todate" name="todate" /></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$lng['ticket']['message']}:</td>
|
||||
<td><textarea rows="12" cols="50" name="message"></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$lng['ticket']['customer']}:</td>
|
||||
<td><select name="customer">$customers</select></td>
|
||||
</tr>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td class="main_field_confirm" colspan="2" align="right"><input type="hidden" name="send" value="send" /><input type="submit" class="bottom" value="{$lng['panel']['search']}" /></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
</section>
|
||||
|
||||
</article>
|
||||
$footer
|
||||
@@ -1,12 +0,0 @@
|
||||
<tr>
|
||||
<td>{$ticket['lastchange']}</td>
|
||||
<td>{$ticket['ticket_answers']}</td>
|
||||
<td>{$ticket['subject']}</td>
|
||||
<td>{$ticket['lastreplier']}</td>
|
||||
<td>{$ticket['priority']}</td>
|
||||
<td>
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'archive', 'action' => 'view', 'id' => $ticket['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/view.png" alt="{$lng['ticket']['show']}" title="{$lng['ticket']['show']}" class="tipper"/>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1,31 +0,0 @@
|
||||
$header
|
||||
<section>
|
||||
<header>
|
||||
<h2><img src="templates/{$theme}/assets/img/icons/ticket_archive_big.png" alt="" /> {$lng['ticket']['archivesearch']}</h2>
|
||||
</header>
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post">
|
||||
<input type="hidden" name="s" value="$s"/>
|
||||
<input type="hidden" name="page" value="$page"/>
|
||||
<input type="hidden" name="send" value="send" />
|
||||
<table class="full">
|
||||
<if 0 < $tickets_count >
|
||||
<tr>
|
||||
<th class="field_display_border_left">{$lng['ticket']['archivedtime']}</th>
|
||||
<th class="field_display">{$lng['ticket']['ticket_answers']}</th>
|
||||
<th class="field_display">{$lng['ticket']['subject']}</th>
|
||||
<th class="field_display">{$lng['ticket']['lastreplier']}</th>
|
||||
<th class="field_display">{$lng['ticket']['priority']}</th>
|
||||
<th class="field_display_search"> </th>
|
||||
</tr>
|
||||
$tickets
|
||||
</if>
|
||||
|
||||
<if $tickets_count < 1 >
|
||||
<tr>
|
||||
<td class="field_display_border_left" colspan="6">{$lng['ticket']['noresults']}</td>
|
||||
</tr>
|
||||
</if>
|
||||
</table>
|
||||
</form>
|
||||
</section>
|
||||
$footer
|
||||
60
templates/Sparkle/admin/tickets/categories.tpl
vendored
60
templates/Sparkle/admin/tickets/categories.tpl
vendored
@@ -1,60 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/categories_big.png" alt="" />
|
||||
{$lng['menue']['ticket']['categories']}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<input type="hidden" name="s" value="$s"/>
|
||||
<input type="hidden" name="page" value="$page"/>
|
||||
<input type="hidden" name="send" value="send" />
|
||||
|
||||
<div class="overviewsearch">
|
||||
{$searchcode}
|
||||
</div>
|
||||
|
||||
<div class="overviewadd">
|
||||
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'categories', 'action' => 'addcategory'))}">{$lng['ticket']['ticket_newcateory']}</a>
|
||||
</div>
|
||||
|
||||
<table class="full hl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$lng['ticket']['category']} {$arrowcode['name']}</th>
|
||||
<th>{$lng['ticket']['logicalorder']} {$arrowcode['logicalorder']}</th>
|
||||
<th>{$lng['ticket']['ticketcount']} <if $categories_count < 0 >{$arrowcode['ticketcount']}</if></th>
|
||||
<th>{$lng['panel']['options']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<if $pagingcode != ''>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">{$pagingcode}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</if>
|
||||
<tbody>
|
||||
$ticketcategories
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<if 15 < $categories_count >
|
||||
<div class="overviewadd">
|
||||
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'categories', 'action' => 'addcategory'))}">{$lng['ticket']['ticket_newcateory']}</a>
|
||||
</div>
|
||||
</if>
|
||||
|
||||
</section>
|
||||
|
||||
</article>
|
||||
$footer
|
||||
|
||||
74
templates/Sparkle/admin/tickets/tickets.tpl
vendored
74
templates/Sparkle/admin/tickets/tickets.tpl
vendored
@@ -1,74 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/tickets_big.png" alt="" />
|
||||
{$lng['menue']['ticket']['ticket']}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<input type="hidden" name="s" value="$s"/>
|
||||
<input type="hidden" name="page" value="$page"/>
|
||||
<input type="hidden" name="send" value="send" />
|
||||
|
||||
<div class="overviewsearch">
|
||||
{$searchcode}
|
||||
</div>
|
||||
|
||||
<if ($userinfo['tickets_used'] < $userinfo['tickets'] || $userinfo['tickets'] == '-1') && $countcustomers !=0 >
|
||||
<div class="overviewadd">
|
||||
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'new'))}">{$lng['ticket']['ticket_new']}</a>
|
||||
</div>
|
||||
</if>
|
||||
|
||||
<table class="full hl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$lng['ticket']['lastchange']} {$arrowcode['lastchange']}</th>
|
||||
<th>{$lng['ticket']['ticket_answers']}</th>
|
||||
<th>{$lng['ticket']['subject']} {$arrowcode['subject']}</th>
|
||||
<th>{$lng['ticket']['status']} {$arrowcode['status']}</th>
|
||||
<th>{$lng['ticket']['lastreplier']} {$arrowcode['lastreplier']}</th>
|
||||
<th>{$lng['ticket']['priority']}</th>
|
||||
<th>{$lng['panel']['options']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<if $pagingcode != ''>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">{$pagingcode}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</if>
|
||||
<tbody>
|
||||
{$tickets}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<if ($userinfo['tickets_used'] < $userinfo['tickets'] || $userinfo['tickets'] == '-1') && 15 < $tickets_count >
|
||||
<div class="overviewadd">
|
||||
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'new'))}">{$lng['ticket']['ticket_new']}</a>
|
||||
</div>
|
||||
</if>
|
||||
|
||||
<if $countcustomers == 0 >
|
||||
<div class="warningcontainer bradius">
|
||||
<div class="warningtitle">{$lng['admin']['warning']}</div>
|
||||
<div class="warning">
|
||||
<a href="{$linker->getLink(array('section' => 'customers', 'page' => 'customers', 'action' => 'add'))}">{$lng['admin']['ticket_nocustomeraddingavailable']}</a>
|
||||
</div>
|
||||
</div>
|
||||
</if>
|
||||
|
||||
</section>
|
||||
|
||||
</article>
|
||||
$footer
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<tr>
|
||||
<td>{$row['name']}</td>
|
||||
<td>{$row['logicalorder']}</td>
|
||||
<td>{$row['ticketcount']} ({$row['ticketcountnotclosed']} {$lng['ticket']['open']} | {$closedtickets_count} {$lng['ticket']['closed']})</td>
|
||||
<td>
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'categories', 'action' => 'editcategory', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/edit.png" alt="{$lng['panel']['edit']}" title="{$lng['panel']['edit']}" class="tipper" />
|
||||
</a>
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'categories', 'action' => 'deletecategory', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" class="tipper" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<tr>
|
||||
<td class="field_name_border_left" colspan="10"><strong>{$customer} (<a href="{$linker->getLink(array('section' => 'customers', 'page' => 'customers', 'action' => 'su', 'id' => $customerid))}" rel="external">{$customerloginname}</a>)</strong></td>
|
||||
</tr>
|
||||
@@ -1,27 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/categories_edit_big.png" alt="{$title}" />
|
||||
{$title}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<input type="hidden" name="s" value="$s" />
|
||||
<input type="hidden" name="page" value="$page" />
|
||||
<input type="hidden" name="action" value="$action" />
|
||||
<input type="hidden" name="id" value="$id" />
|
||||
<input type="hidden" name="send" value="send" />
|
||||
|
||||
<table class="full">
|
||||
{$category_edit_form}
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</section>
|
||||
|
||||
</article>
|
||||
$footer
|
||||
26
templates/Sparkle/admin/tickets/tickets_new.tpl
vendored
26
templates/Sparkle/admin/tickets/tickets_new.tpl
vendored
@@ -1,26 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/ticket_add_big.png" alt="{$title}" />
|
||||
{$title}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<input type="hidden" name="s" value="$s" />
|
||||
<input type="hidden" name="page" value="$page" />
|
||||
<input type="hidden" name="action" value="$action" />
|
||||
<input type="hidden" name="send" value="send" />
|
||||
|
||||
<table class="full">
|
||||
{$ticket_new_form}
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</section>
|
||||
|
||||
</article>
|
||||
$footer
|
||||
@@ -1,26 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/categories_add_big.png" alt="{$title}" />
|
||||
{$title}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<input type="hidden" name="s" value="$s" />
|
||||
<input type="hidden" name="page" value="$page" />
|
||||
<input type="hidden" name="action" value="$action" />
|
||||
<input type="hidden" name="send" value="send" />
|
||||
|
||||
<table class="full">
|
||||
{$category_new_form}
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</section>
|
||||
|
||||
</article>
|
||||
$footer
|
||||
@@ -1,40 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/ticket_reply_big.png" alt="{$title}" />
|
||||
{$title}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<if 0 < $isclosed >
|
||||
<div class="messagewrapperfull">
|
||||
<div class="warningcontainer bradius">
|
||||
<div class="warningtitle">{$lng['ticket']['ticket_reopen']}</div>
|
||||
<div class="warning"><br /><strong><a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'reopen', 'id' => $id))}">{$lng['ticket']['ticket_reopen']}</a></strong></div>
|
||||
</div>
|
||||
</div>
|
||||
</if>
|
||||
|
||||
<if 0 < $ticket_replies_count >
|
||||
$ticket_replies
|
||||
</if>
|
||||
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'tickets'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<input type="hidden" name="s" value="$s" />
|
||||
<input type="hidden" name="page" value="$page" />
|
||||
<input type="hidden" name="action" value="$action" />
|
||||
<input type="hidden" name="id" value="$id" />
|
||||
<input type="hidden" name="send" value="send" />
|
||||
|
||||
<table class="full">
|
||||
{$ticket_reply_form}
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</section>
|
||||
|
||||
</article>
|
||||
$footer
|
||||
@@ -1,34 +0,0 @@
|
||||
<tr>
|
||||
<td>{$row['lastchange']}</td>
|
||||
<td>{$row['ticket_answers']}</td>
|
||||
<td>{$row['subject']}</td>
|
||||
<td>{$row['status']}</td>
|
||||
<td>{$row['lastreplier']}</td>
|
||||
<td>{$row['priority']}</td>
|
||||
<td>
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'answer', 'id' => $row['id']))}">
|
||||
<if $cananswer < 1 >
|
||||
<img src="templates/{$theme}/assets/img/icons/view.png" alt="{$lng['ticket']['show']}" title="{$lng['ticket']['show']}" />
|
||||
</if>
|
||||
<if 0 < $cananswer >
|
||||
<img src="templates/{$theme}/assets/img/icons/edit.png" alt="{$lng['ticket']['answer']}" title="{$lng['ticket']['answer']}" />
|
||||
</if>
|
||||
</a>
|
||||
<if $reopen < 1 >
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'close', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/lock.png" alt="{$lng['ticket']['close']}" title="{$lng['ticket']['close']}" />
|
||||
</a>
|
||||
</if>
|
||||
<if 0 < $reopen >
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'reopen', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/unlock.png" alt="{$lng['ticket']['reopen']}" title="{$lng['ticket']['reopen']}" />
|
||||
</a>
|
||||
</if>
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'archive', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/archive.png" alt="{$lng['ticket']['archive']}" title="{$lng['ticket']['archive']}" />
|
||||
</a>
|
||||
<a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'tickets', 'action' => 'delete', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1,15 +0,0 @@
|
||||
<section>
|
||||
<table class="full">
|
||||
<tr>
|
||||
<th>{$lastchange} {$lng['ticket']['by']} {$by}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$subject}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$message}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br /><br />
|
||||
</section>
|
||||
<br />
|
||||
@@ -1,15 +0,0 @@
|
||||
<section>
|
||||
<table class="full">
|
||||
<tr>
|
||||
<th>{$dt} {$lng['ticket']['by']} {$by} ({$status})</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$subject}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$message}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
</section>
|
||||
<br />
|
||||
17
templates/Sparkle/admin/tickets/tickets_view.tpl
vendored
17
templates/Sparkle/admin/tickets/tickets_view.tpl
vendored
@@ -1,17 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/ticket_archive_big.png" alt="" />
|
||||
{$lng['ticket']['ticket_delete']}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<if 0 < $ticket_replies_count >
|
||||
$ticket_replies
|
||||
</if>
|
||||
<p><a href="{$linker->getLink(array('section' => 'tickets', 'page' => 'archive', 'action' => 'delete', 'id' => $id))}"><img src="templates/{$theme}/assets/img/icons/delete.png" alt="" /> {$lng['panel']['delete']}</a></p>
|
||||
</section>
|
||||
</article>
|
||||
$footer
|
||||
54
templates/Sparkle/customer/traffic/traffic.tpl
vendored
54
templates/Sparkle/customer/traffic/traffic.tpl
vendored
@@ -1,54 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/traffic_big.png" alt="{$lng['menue']['traffic']['traffic']}" />
|
||||
{$lng['menue']['traffic']['traffic']}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'traffic'))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<fieldset>
|
||||
<table class="full hl" id="datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$lng['traffic']['month']}</td>
|
||||
<th>{$lng['traffic']['ftp']}</th>
|
||||
<th>{$lng['traffic']['http']}</th>
|
||||
<th>{$lng['traffic']['mail']}</th>
|
||||
<th>{$lng['customer']['traffic']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
$traffic
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>{$lng['traffic']['months']['total']}</td>
|
||||
<td>{$traffic_complete['ftp']}</td>
|
||||
<td>{$traffic_complete['http']}</td>
|
||||
<td>{$traffic_complete['mail']}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<div id="charts" class="hidden">
|
||||
<if !\Froxlor\Settings::IsInList('panel.customer_hide_options','traffic.http')>
|
||||
<h3>HTTP {$lng['admin']['traffic']} ({$lng['traffic']['months']['total']} {$traffic_complete['http']})</h3>
|
||||
<div id="httpchart" class="trafficchart"></div>
|
||||
</if>
|
||||
<if !\Froxlor\Settings::IsInList('panel.customer_hide_options','traffic.ftp')>
|
||||
<h3>FTP {$lng['admin']['traffic']} ({$lng['traffic']['months']['total']} {$traffic_complete['ftp']})</h3>
|
||||
<div id="ftpchart" class="trafficchart"></div>
|
||||
</if>
|
||||
<if !\Froxlor\Settings::IsInList('panel.customer_hide_options','traffic.mail')>
|
||||
<h3>Mail {$lng['admin']['traffic']} ({$lng['traffic']['months']['total']} {$traffic_complete['mail']})</h3>
|
||||
<div id="mailchart" class="trafficchart"></div>
|
||||
</if>
|
||||
</div>
|
||||
</article>
|
||||
$footer
|
||||
@@ -1,48 +0,0 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/traffic_big.png" alt="{$lng['menue']['traffic']['traffic']}" />
|
||||
{$lng['menue']['traffic']['traffic']} $show
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<table class="full hl" id="datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$lng['traffic']['day']}</th>
|
||||
<th>{$lng['traffic']['ftp']}</th>
|
||||
<th>{$lng['traffic']['http']}</th>
|
||||
<th>{$lng['traffic']['mail']}</th>
|
||||
<th>{$lng['traffic']['mb']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>{$lng['traffic']['months']['total']}</td>
|
||||
<td>{$traffic_complete['ftp']}</td>
|
||||
<td>{$traffic_complete['http']}</td>
|
||||
<td>{$traffic_complete['mail']}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
$traffic
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="charts" class="hidden">
|
||||
<if !\Froxlor\Settings::IsInList('panel.customer_hide_options','traffic.http')>
|
||||
<h3>HTTP {$lng['admin']['traffic']} ({$lng['traffic']['months']['total']} {$traffic_complete['http']})</h3>
|
||||
<div id="httpchart" class="trafficchart"></div>
|
||||
</if>
|
||||
<if !\Froxlor\Settings::IsInList('panel.customer_hide_options','traffic.ftp')>
|
||||
<h3>FTP {$lng['admin']['traffic']} ({$lng['traffic']['months']['total']} {$traffic_complete['ftp']})</h3>
|
||||
<div id="ftpchart" class="trafficchart"></div>
|
||||
</if>
|
||||
<if !\Froxlor\Settings::IsInList('panel.customer_hide_options','traffic.mail')>
|
||||
<h3>Mail {$lng['admin']['traffic']} ({$lng['traffic']['months']['total']} {$traffic_complete['mail']})</h3>
|
||||
<div id="mailchart" class="trafficchart"></div>
|
||||
</if>
|
||||
</div>
|
||||
</article>
|
||||
$footer
|
||||
@@ -1,8 +0,0 @@
|
||||
<tr>
|
||||
<td>{$traf['day']}</td>
|
||||
<td>{$traf['ftp']}</td>
|
||||
<td>{$traf['http']}</td>
|
||||
<td>{$traf['mail']}</td>
|
||||
<td>{$traf['byte']}</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<tr>
|
||||
<td><a href="{$linker->getLink(array('section' => 'traffic', 'month' => $traf['month'], 'year' => $traf['year']))}">{$traf['monthname']}</a></td>
|
||||
<td>{$traf['ftp']}</td>
|
||||
<td>{$traf['http']}</td>
|
||||
<td>{$traf['mail']}</td>
|
||||
<td>{$traf['byte']}</td>
|
||||
</tr>
|
||||
Reference in New Issue
Block a user