Merge branch 'main' of github.com:Froxlor/Froxlor
This commit is contained in:
@@ -26,9 +26,10 @@
|
|||||||
const AREA = 'customer';
|
const AREA = 'customer';
|
||||||
require __DIR__ . '/lib/init.php';
|
require __DIR__ . '/lib/init.php';
|
||||||
|
|
||||||
use Froxlor\Api\Commands\EmailAccounts as EmailAccounts;
|
use Froxlor\Api\Commands\EmailAccounts;
|
||||||
use Froxlor\Api\Commands\EmailForwarders as EmailForwarders;
|
use Froxlor\Api\Commands\EmailForwarders;
|
||||||
use Froxlor\Api\Commands\Emails as Emails;
|
use Froxlor\Api\Commands\Emails;
|
||||||
|
use Froxlor\Api\Commands\EmailDomains;
|
||||||
use Froxlor\Database\Database;
|
use Froxlor\Database\Database;
|
||||||
use Froxlor\FroxlorLogger;
|
use Froxlor\FroxlorLogger;
|
||||||
use Froxlor\PhpHelper;
|
use Froxlor\PhpHelper;
|
||||||
@@ -50,13 +51,49 @@ if (Settings::IsInList('panel.customer_hide_options', 'email') || $userinfo['ema
|
|||||||
$id = (int)Request::any('id');
|
$id = (int)Request::any('id');
|
||||||
|
|
||||||
if ($page == 'overview' || $page == 'emails') {
|
if ($page == 'overview' || $page == 'emails') {
|
||||||
|
$result_stmt = Database::prepare("
|
||||||
|
SELECT COUNT(DISTINCT `domainid`) as maildomains FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid`= :cid
|
||||||
|
");
|
||||||
|
$domain_count = Database::pexecute_first($result_stmt, [
|
||||||
|
"cid" => $userinfo['customerid']
|
||||||
|
]);
|
||||||
|
if ($domain_count['maildomains'] && $domain_count['maildomains'] > 1) {
|
||||||
|
try {
|
||||||
|
$emaildomain_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.emails_overview.php';
|
||||||
|
$collection = (new Collection(EmailDomains::class, $userinfo))
|
||||||
|
->withPagination($emaildomain_list_data['emaildomain_list']['columns'], $emaildomain_list_data['emaildomain_list']['default_sorting']);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Response::dynamicError($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
UI::view('user/table.html.twig', [
|
||||||
|
'listing' => Listing::format($collection, $emaildomain_list_data, 'emaildomain_list'),
|
||||||
|
'actions_links' => CurrentUser::canAddResource('emails') ? [
|
||||||
|
[
|
||||||
|
'href' => $linker->getLink(['section' => 'email', 'page' => $page, 'action' => 'add']),
|
||||||
|
'label' => lng('emails.emails_add')
|
||||||
|
]
|
||||||
|
] : null,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// only emails for one domain -> show email address listing directly
|
||||||
|
$page = 'email_domain';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($page == 'email_domain') {
|
||||||
|
$email_domainid = Request::any('domainid', 0);
|
||||||
if ($action == '') {
|
if ($action == '') {
|
||||||
$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails");
|
$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails");
|
||||||
|
|
||||||
|
$sql_search = [];
|
||||||
|
if ($email_domainid > 0) {
|
||||||
|
$sql_search = ['sql_search' => ['m.domainid' => ['op' => '=', 'value' => $email_domainid]]];
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
$email_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.emails.php';
|
$email_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.emails.php';
|
||||||
$collection = (new Collection(Emails::class, $userinfo))
|
$collection = (new Collection(Emails::class, $userinfo, $sql_search))
|
||||||
->withPagination($email_list_data['email_list']['columns'], $email_list_data['email_list']['default_sorting']);
|
->withPagination($email_list_data['email_list']['columns'],
|
||||||
|
$email_list_data['email_list']['default_sorting']);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Response::dynamicError($e->getMessage());
|
Response::dynamicError($e->getMessage());
|
||||||
}
|
}
|
||||||
@@ -71,15 +108,21 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
]);
|
]);
|
||||||
$emaildomains_count = $result2['emaildomains'];
|
$emaildomains_count = $result2['emaildomains'];
|
||||||
|
|
||||||
$actions_links = false;
|
$actions_links = [
|
||||||
if (CurrentUser::canAddResource('emails')) {
|
[
|
||||||
$actions_links = [
|
'class' => 'btn-outline-primary',
|
||||||
[
|
'href' => $linker->getLink([
|
||||||
'href' => $linker->getLink(['section' => 'email', 'page' => $page, 'action' => 'add']),
|
'section' => 'email',
|
||||||
'label' => lng('emails.emails_add')
|
'page' => 'emails',
|
||||||
]
|
]),
|
||||||
];
|
'label' => 'back to domain overview',
|
||||||
}
|
'icon' => 'fa-solid fa-reply'
|
||||||
|
],
|
||||||
|
CurrentUser::canAddResource('emails') ? [
|
||||||
|
'href' => $linker->getLink(['section' => 'email', 'page' => 'email_domain', 'action' => 'add']),
|
||||||
|
'label' => lng('emails.emails_add')
|
||||||
|
] : null
|
||||||
|
];
|
||||||
|
|
||||||
UI::view('user/table.html.twig', [
|
UI::view('user/table.html.twig', [
|
||||||
'listing' => Listing::format($collection, $email_list_data, 'email_list'),
|
'listing' => Listing::format($collection, $email_list_data, 'email_list'),
|
||||||
@@ -249,6 +292,7 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} elseif ($page == 'accounts') {
|
} elseif ($page == 'accounts') {
|
||||||
|
$email_domainid = Request::any('domainid', 0);
|
||||||
if ($action == 'add' && $id != 0) {
|
if ($action == 'add' && $id != 0) {
|
||||||
if ($userinfo['email_accounts'] == '-1' || ($userinfo['email_accounts_used'] < $userinfo['email_accounts'])) {
|
if ($userinfo['email_accounts'] == '-1' || ($userinfo['email_accounts_used'] < $userinfo['email_accounts'])) {
|
||||||
try {
|
try {
|
||||||
@@ -267,7 +311,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
Response::dynamicError($e->getMessage());
|
Response::dynamicError($e->getMessage());
|
||||||
}
|
}
|
||||||
Response::redirectTo($filename, [
|
Response::redirectTo($filename, [
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]);
|
]);
|
||||||
@@ -292,7 +337,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink([
|
'href' => $linker->getLink([
|
||||||
'section' => 'email',
|
'section' => 'email',
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]),
|
]),
|
||||||
@@ -301,7 +347,7 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink(['section' => 'email', 'page' => 'emails']),
|
'href' => $linker->getLink(['section' => 'email', 'page' => 'email_domain', 'domainid' => $email_domainid]),
|
||||||
'label' => lng('menue.email.emails'),
|
'label' => lng('menue.email.emails'),
|
||||||
'icon' => 'fa-solid fa-envelope'
|
'icon' => 'fa-solid fa-envelope'
|
||||||
]
|
]
|
||||||
@@ -332,7 +378,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
Response::dynamicError($e->getMessage());
|
Response::dynamicError($e->getMessage());
|
||||||
}
|
}
|
||||||
Response::redirectTo($filename, [
|
Response::redirectTo($filename, [
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]);
|
]);
|
||||||
@@ -350,7 +397,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink([
|
'href' => $linker->getLink([
|
||||||
'section' => 'email',
|
'section' => 'email',
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]),
|
]),
|
||||||
@@ -359,7 +407,7 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink(['section' => 'email', 'page' => 'emails']),
|
'href' => $linker->getLink(['section' => 'email', 'page' => 'email_domain', 'domainid' => $email_domainid]),
|
||||||
'label' => lng('menue.email.emails'),
|
'label' => lng('menue.email.emails'),
|
||||||
'icon' => 'fa-solid fa-envelope'
|
'icon' => 'fa-solid fa-envelope'
|
||||||
]
|
]
|
||||||
@@ -385,7 +433,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
Response::dynamicError($e->getMessage());
|
Response::dynamicError($e->getMessage());
|
||||||
}
|
}
|
||||||
Response::redirectTo($filename, [
|
Response::redirectTo($filename, [
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]);
|
]);
|
||||||
@@ -403,7 +452,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink([
|
'href' => $linker->getLink([
|
||||||
'section' => 'email',
|
'section' => 'email',
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]),
|
]),
|
||||||
@@ -412,7 +462,7 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink(['section' => 'email', 'page' => 'emails']),
|
'href' => $linker->getLink(['section' => 'email', 'page' => 'email_domain', 'domainid' => $email_domainid]),
|
||||||
'label' => lng('menue.email.emails'),
|
'label' => lng('menue.email.emails'),
|
||||||
'icon' => 'fa-solid fa-envelope'
|
'icon' => 'fa-solid fa-envelope'
|
||||||
]
|
]
|
||||||
@@ -438,7 +488,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
Response::dynamicError($e->getMessage());
|
Response::dynamicError($e->getMessage());
|
||||||
}
|
}
|
||||||
Response::redirectTo($filename, [
|
Response::redirectTo($filename, [
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]);
|
]);
|
||||||
@@ -446,12 +497,14 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
HTML::askYesNoWithCheckbox('email_reallydelete_account', 'admin_customer_alsoremovemail', $filename, [
|
HTML::askYesNoWithCheckbox('email_reallydelete_account', 'admin_customer_alsoremovemail', $filename, [
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => $action
|
'action' => $action
|
||||||
], $idna_convert->decode($result['email_full']));
|
], $idna_convert->decode($result['email_full']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif ($page == 'forwarders') {
|
} elseif ($page == 'forwarders') {
|
||||||
|
$email_domainid = Request::any('domainid', 0);
|
||||||
if ($action == 'add' && $id != 0) {
|
if ($action == 'add' && $id != 0) {
|
||||||
if ($userinfo['email_forwarders_used'] < $userinfo['email_forwarders'] || $userinfo['email_forwarders'] == '-1') {
|
if ($userinfo['email_forwarders_used'] < $userinfo['email_forwarders'] || $userinfo['email_forwarders'] == '-1') {
|
||||||
try {
|
try {
|
||||||
@@ -471,7 +524,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
Response::dynamicError($e->getMessage());
|
Response::dynamicError($e->getMessage());
|
||||||
}
|
}
|
||||||
Response::redirectTo($filename, [
|
Response::redirectTo($filename, [
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]);
|
]);
|
||||||
@@ -489,7 +543,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink([
|
'href' => $linker->getLink([
|
||||||
'section' => 'email',
|
'section' => 'email',
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]),
|
]),
|
||||||
@@ -498,7 +553,7 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'class' => 'btn-secondary',
|
'class' => 'btn-secondary',
|
||||||
'href' => $linker->getLink(['section' => 'email', 'page' => 'emails']),
|
'href' => $linker->getLink(['section' => 'email', 'page' => 'email_domain', 'domainid' => $email_domainid]),
|
||||||
'label' => lng('menue.email.emails'),
|
'label' => lng('menue.email.emails'),
|
||||||
'icon' => 'fa-solid fa-envelope'
|
'icon' => 'fa-solid fa-envelope'
|
||||||
]
|
]
|
||||||
@@ -540,7 +595,8 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
Response::dynamicError($e->getMessage());
|
Response::dynamicError($e->getMessage());
|
||||||
}
|
}
|
||||||
Response::redirectTo($filename, [
|
Response::redirectTo($filename, [
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => $id
|
'id' => $id
|
||||||
]);
|
]);
|
||||||
@@ -549,6 +605,7 @@ if ($page == 'overview' || $page == 'emails') {
|
|||||||
'id' => $id,
|
'id' => $id,
|
||||||
'forwarderid' => $forwarderid,
|
'forwarderid' => $forwarderid,
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
|
'domainid' => $email_domainid,
|
||||||
'action' => $action
|
'action' => $action
|
||||||
], $idna_convert->decode($result['email_full']) . ' -> ' . $idna_convert->decode($forwarder));
|
], $idna_convert->decode($result['email_full']) . ' -> ' . $idna_convert->decode($forwarder));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace Froxlor\Ajax;
|
|||||||
use Froxlor\Api\Commands\Admins;
|
use Froxlor\Api\Commands\Admins;
|
||||||
use Froxlor\Api\Commands\Customers;
|
use Froxlor\Api\Commands\Customers;
|
||||||
use Froxlor\Api\Commands\Domains;
|
use Froxlor\Api\Commands\Domains;
|
||||||
|
use Froxlor\Api\Commands\EmailDomains;
|
||||||
use Froxlor\Api\Commands\Emails;
|
use Froxlor\Api\Commands\Emails;
|
||||||
use Froxlor\Api\Commands\FpmDaemons;
|
use Froxlor\Api\Commands\FpmDaemons;
|
||||||
use Froxlor\Api\Commands\Ftps;
|
use Froxlor\Api\Commands\Ftps;
|
||||||
@@ -267,7 +268,20 @@ class GlobalSearch
|
|||||||
'result_format' => [
|
'result_format' => [
|
||||||
'title' => ['self', 'getFieldFromResult'],
|
'title' => ['self', 'getFieldFromResult'],
|
||||||
'title_args' => 'email',
|
'title_args' => 'email',
|
||||||
'href' => 'customer_email.php?page=emails&searchfield=m.email&searchtext='
|
'href' => 'customer_email.php?page=email_domain&domainid={domainid}&searchfield=m.email&searchtext='
|
||||||
|
]
|
||||||
|
],
|
||||||
|
// email-domains
|
||||||
|
'email_domains' => [
|
||||||
|
'class' => EmailDomains::class,
|
||||||
|
'searchfields' => [
|
||||||
|
'd.domain',
|
||||||
|
],
|
||||||
|
'result_key' => 'domain',
|
||||||
|
'result_format' => [
|
||||||
|
'title' => ['self', 'getFieldFromResult'],
|
||||||
|
'title_args' => 'domain',
|
||||||
|
'href' => 'customer_email.php?page=emails&searchfield=d.domain&searchtext='
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
// databases
|
// databases
|
||||||
@@ -326,6 +340,14 @@ class GlobalSearch
|
|||||||
if (!isset($result[$entity])) {
|
if (!isset($result[$entity])) {
|
||||||
$result[$entity] = [];
|
$result[$entity] = [];
|
||||||
}
|
}
|
||||||
|
// replacer from result in href
|
||||||
|
$href_replacer = [];
|
||||||
|
if (preg_match_all('/\{([a-z]+)\}/', $edata['result_format']['href'], $href_replacer) !== false) {
|
||||||
|
foreach ($href_replacer[1] as $href_field) {
|
||||||
|
$href_field_value = self::getFieldFromResult($cresult, $href_field);
|
||||||
|
$edata['result_format']['href'] = str_replace('{'.$href_field.'}', $href_field_value, $edata['result_format']['href']);
|
||||||
|
}
|
||||||
|
}
|
||||||
$result[$entity][] = [
|
$result[$entity][] = [
|
||||||
'title' => call_user_func($edata['result_format']['title'], $cresult, ($edata['result_format']['title_args'] ?? null)),
|
'title' => call_user_func($edata['result_format']['title'], $cresult, ($edata['result_format']['title_args'] ?? null)),
|
||||||
'href' => $edata['result_format']['href'] . $cresult[$edata['result_key']]
|
'href' => $edata['result_format']['href'] . $cresult[$edata['result_key']]
|
||||||
@@ -335,7 +357,7 @@ class GlobalSearch
|
|||||||
}
|
}
|
||||||
} // foreach entity
|
} // foreach entity
|
||||||
|
|
||||||
} // foreach splitted search-term
|
} // foreach split search-term
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|||||||
182
lib/Froxlor/Api/Commands/EmailDomains.php
Normal file
182
lib/Froxlor/Api/Commands/EmailDomains.php
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of the Froxlor project.
|
||||||
|
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you can also view it online at
|
||||||
|
* https://files.froxlor.org/misc/COPYING.txt
|
||||||
|
*
|
||||||
|
* @copyright the authors
|
||||||
|
* @author Froxlor team <team@froxlor.org>
|
||||||
|
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Froxlor\Api\Commands;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Froxlor\Api\ApiCommand;
|
||||||
|
use Froxlor\Api\ResourceEntity;
|
||||||
|
use Froxlor\Database\Database;
|
||||||
|
use Froxlor\FroxlorLogger;
|
||||||
|
use Froxlor\Idna\IdnaWrapper;
|
||||||
|
use Froxlor\Settings;
|
||||||
|
use Froxlor\UI\Response;
|
||||||
|
use Froxlor\Validate\Validate;
|
||||||
|
use PDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class EmailDomains extends ApiCommand implements ResourceEntity
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* list all domains with email addresses connected to it.
|
||||||
|
* If called from an admin, list all domains with email addresses
|
||||||
|
* connected to it from all customers you are allowed to view, or
|
||||||
|
* specify id or loginname for one specific customer
|
||||||
|
*
|
||||||
|
* @param int $customerid
|
||||||
|
* optional, admin-only, select email addresses of a specific customer by id
|
||||||
|
* @param string $loginname
|
||||||
|
* optional, admin-only, select email addresses of a specific customer by loginname
|
||||||
|
* @param array $sql_search
|
||||||
|
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =),
|
||||||
|
* LIKE is used if left empty and 'value' => searchvalue
|
||||||
|
* @param int $sql_limit
|
||||||
|
* optional specify number of results to be returned
|
||||||
|
* @param int $sql_offset
|
||||||
|
* optional specify offset for resultset
|
||||||
|
* @param array $sql_orderby
|
||||||
|
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more
|
||||||
|
* fields
|
||||||
|
*
|
||||||
|
* @access admin, customer
|
||||||
|
* @return string json-encoded array count|list
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function listing()
|
||||||
|
{
|
||||||
|
$customer_ids = $this->getAllowedCustomerIds('email');
|
||||||
|
$result = [];
|
||||||
|
$query_fields = [];
|
||||||
|
$result_stmt = Database::prepare("
|
||||||
|
SELECT DISTINCT d.domain, e.domainid,
|
||||||
|
COUNT(e.email) as addresses,
|
||||||
|
IFNULL(SUM(CASE WHEN e.popaccountid > 0 THEN 1 ELSE 0 END), 0) as accounts,
|
||||||
|
IFNULL(SUM(
|
||||||
|
CASE
|
||||||
|
WHEN LENGTH(REPLACE(e.destination, CONCAT(e.email_full, ' '), '')) - LENGTH(REPLACE(REPLACE(e.destination, CONCAT(e.email_full, ' '), ''), ' ', '')) > 0
|
||||||
|
THEN LENGTH(REPLACE(e.destination, CONCAT(e.email_full, ' '), '')) - LENGTH(REPLACE(REPLACE(e.destination, CONCAT(e.email_full, ' '), ''), ' ', ''))
|
||||||
|
WHEN e.destination <> e.email_full THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
), 0) as forwarder
|
||||||
|
FROM `" . TABLE_MAIL_VIRTUAL . "` e
|
||||||
|
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON d.id = e.domainid
|
||||||
|
WHERE e.customerid IN (" . implode(", ", $customer_ids) . ") AND d.domain IS NOT NULL " .
|
||||||
|
$this->getSearchWhere($query_fields, true) . " GROUP BY e.domainid " . $this->getOrderBy() . $this->getLimit());
|
||||||
|
Database::pexecute($result_stmt, $query_fields, true, true);
|
||||||
|
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
$result[] = $row;
|
||||||
|
}
|
||||||
|
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list email-domains");
|
||||||
|
return $this->response([
|
||||||
|
'count' => count($result),
|
||||||
|
'list' => $result
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the total number of accessible domains with email addresses connected to
|
||||||
|
*
|
||||||
|
* @param int $customerid
|
||||||
|
* optional, admin-only, select email addresses of a specific customer by id
|
||||||
|
* @param string $loginname
|
||||||
|
* optional, admin-only, select email addresses of a specific customer by loginname
|
||||||
|
*
|
||||||
|
* @access admin, customer
|
||||||
|
* @return string json-encoded response message
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function listingCount()
|
||||||
|
{
|
||||||
|
$customer_ids = $this->getAllowedCustomerIds('email');
|
||||||
|
$result_stmt = Database::prepare("
|
||||||
|
SELECT COUNT(DISTINCT d.domain) as num_emaildomains
|
||||||
|
FROM `" . TABLE_MAIL_VIRTUAL . "` e
|
||||||
|
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON d.id = e.domainid
|
||||||
|
WHERE e.customerid IN (" . implode(", ", $customer_ids) . ") AND d.domain IS NOT NULL
|
||||||
|
");
|
||||||
|
$result = Database::pexecute_first($result_stmt, null, true, true);
|
||||||
|
if ($result) {
|
||||||
|
return $this->response($result['num_emaildomains']);
|
||||||
|
}
|
||||||
|
return $this->response(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access admin, customer
|
||||||
|
* @return string json-encoded array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function get()
|
||||||
|
{
|
||||||
|
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||||
|
throw new Exception("You cannot access this resource", 405);
|
||||||
|
}
|
||||||
|
throw new Exception('You cannot directly access this resource.', 303);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access admin, customer
|
||||||
|
* @return string json-encoded array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||||
|
throw new Exception("You cannot access this resource", 405);
|
||||||
|
}
|
||||||
|
throw new Exception('You cannot directly add this resource.', 303);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toggle catchall flag of given email address either by id or email-address
|
||||||
|
* @access admin, customer
|
||||||
|
* @return string json-encoded array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function update()
|
||||||
|
{
|
||||||
|
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||||
|
throw new Exception("You cannot access this resource", 405);
|
||||||
|
}
|
||||||
|
throw new Exception('You cannot directly update this resource.', 303);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access admin, customer
|
||||||
|
* @return string json-encoded array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||||
|
throw new Exception("You cannot access this resource", 405);
|
||||||
|
}
|
||||||
|
throw new Exception('You cannot directly delete this resource.', 303);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ return [
|
|||||||
'emails_add' => [
|
'emails_add' => [
|
||||||
'title' => lng('emails.emails_add'),
|
'title' => lng('emails.emails_add'),
|
||||||
'image' => 'fa-solid fa-plus',
|
'image' => 'fa-solid fa-plus',
|
||||||
'self_overview' => ['section' => 'email', 'page' => 'emails'],
|
'self_overview' => ['section' => 'email', 'page' => 'email_domain', 'domainid' => $email_domainid ?: 0],
|
||||||
'sections' => [
|
'sections' => [
|
||||||
'section_a' => [
|
'section_a' => [
|
||||||
'title' => lng('emails.emails_add'),
|
'title' => lng('emails.emails_add'),
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ return [
|
|||||||
'emails_edit' => [
|
'emails_edit' => [
|
||||||
'title' => lng('emails.emails_edit'),
|
'title' => lng('emails.emails_edit'),
|
||||||
'image' => 'fa-solid fa-pen',
|
'image' => 'fa-solid fa-pen',
|
||||||
'self_overview' => ['section' => 'email', 'page' => 'emails'],
|
'self_overview' => ['section' => 'email', 'page' => 'email_domain', 'domainid' => $email_domainid ?: 1],
|
||||||
'sections' => [
|
'sections' => [
|
||||||
'section_a' => [
|
'section_a' => [
|
||||||
'title' => lng('emails.emails_edit'),
|
'title' => lng('emails.emails_edit'),
|
||||||
@@ -48,13 +48,13 @@ return [
|
|||||||
'next_to' => [
|
'next_to' => [
|
||||||
'edit_link' => [
|
'edit_link' => [
|
||||||
'type' => 'link',
|
'type' => 'link',
|
||||||
'href' => $filename . '?page=accounts&action=changepw&id=' . $result['id'],
|
'href' => $filename . '?page=accounts&domainid=' . $result['domainid'] . '&action=changepw&id=' . $result['id'],
|
||||||
'label' => lng('menue.main.changepassword'),
|
'label' => lng('menue.main.changepassword'),
|
||||||
'classes' => 'btn btn-sm btn-secondary'
|
'classes' => 'btn btn-sm btn-secondary'
|
||||||
],
|
],
|
||||||
'del_link' => [
|
'del_link' => [
|
||||||
'type' => 'link',
|
'type' => 'link',
|
||||||
'href' => $filename . '?page=accounts&action=delete&id=' . $result['id'],
|
'href' => $filename . '?page=accounts&domainid=' . $result['domainid'] . '&action=delete&id=' . $result['id'],
|
||||||
'label' => lng('emails.account_delete'),
|
'label' => lng('emails.account_delete'),
|
||||||
'classes' => 'btn btn-sm btn-danger'
|
'classes' => 'btn btn-sm btn-danger'
|
||||||
]
|
]
|
||||||
@@ -68,7 +68,7 @@ return [
|
|||||||
'next_to' => [
|
'next_to' => [
|
||||||
'add_link' => [
|
'add_link' => [
|
||||||
'type' => 'link',
|
'type' => 'link',
|
||||||
'href' => $filename . '?page=accounts&action=add&id=' . $result['id'],
|
'href' => $filename . '?page=accounts&domainid=' . $result['domainid'] . '&action=add&id=' . $result['id'],
|
||||||
'label' => lng('emails.account_add'),
|
'label' => lng('emails.account_add'),
|
||||||
'classes' => 'btn btn-sm btn-primary'
|
'classes' => 'btn btn-sm btn-primary'
|
||||||
]
|
]
|
||||||
@@ -83,7 +83,7 @@ return [
|
|||||||
'add_link' => [
|
'add_link' => [
|
||||||
'visible' => ((int)$result['popaccountid'] != 0 && Settings::Get('system.mail_quota_enabled')),
|
'visible' => ((int)$result['popaccountid'] != 0 && Settings::Get('system.mail_quota_enabled')),
|
||||||
'type' => 'link',
|
'type' => 'link',
|
||||||
'href' => $filename . '?page=accounts&action=changequota&id=' . $result['id'],
|
'href' => $filename . '?page=accounts&domainid=' . $result['domainid'] . '&action=changequota&id=' . $result['id'],
|
||||||
'label' => lng('emails.quota_edit'),
|
'label' => lng('emails.quota_edit'),
|
||||||
'classes' => 'btn btn-sm btn-secondary'
|
'classes' => 'btn btn-sm btn-secondary'
|
||||||
]
|
]
|
||||||
@@ -96,7 +96,7 @@ return [
|
|||||||
'next_to' => [
|
'next_to' => [
|
||||||
'add_link' => [
|
'add_link' => [
|
||||||
'type' => 'link',
|
'type' => 'link',
|
||||||
'href' => $filename . '?page=' . $page . '&action=togglecatchall&id=' . $result['id'],
|
'href' => $filename . '?page=' . $page . '&domainid=' . $result['domainid'] . '&action=togglecatchall&id=' . $result['id'],
|
||||||
'label' => '<i class="fa-solid fa-arrow-right-arrow-left"></i> ' . lng('panel.toggle'),
|
'label' => '<i class="fa-solid fa-arrow-right-arrow-left"></i> ' . lng('panel.toggle'),
|
||||||
'classes' => 'btn btn-sm btn-secondary'
|
'classes' => 'btn btn-sm btn-secondary'
|
||||||
]
|
]
|
||||||
@@ -109,7 +109,7 @@ return [
|
|||||||
'next_to' => [
|
'next_to' => [
|
||||||
'add_link' => [
|
'add_link' => [
|
||||||
'type' => 'link',
|
'type' => 'link',
|
||||||
'href' => $filename . '?page=forwarders&action=add&id=' . $result['id'],
|
'href' => $filename . '?page=forwarders&domainid=' . $result['domainid'] . '&action=add&id=' . $result['id'],
|
||||||
'label' => lng('emails.forwarder_add'),
|
'label' => lng('emails.forwarder_add'),
|
||||||
'classes' => 'btn btn-sm btn-primary'
|
'classes' => 'btn btn-sm btn-primary'
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ return [
|
|||||||
'email_list' => [
|
'email_list' => [
|
||||||
'title' => lng('menue.email.emails'),
|
'title' => lng('menue.email.emails'),
|
||||||
'icon' => 'fa-solid fa-envelope',
|
'icon' => 'fa-solid fa-envelope',
|
||||||
'self_overview' => ['section' => 'email', 'page' => 'emails'],
|
'self_overview' => ['section' => 'email', 'page' => 'email_domain'],
|
||||||
'default_sorting' => ['m.email_full' => 'asc'],
|
'default_sorting' => ['m.email_full' => 'asc'],
|
||||||
'columns' => [
|
'columns' => [
|
||||||
'm.email_full' => [
|
'm.email_full' => [
|
||||||
@@ -74,7 +74,8 @@ return [
|
|||||||
'title' => lng('panel.edit'),
|
'title' => lng('panel.edit'),
|
||||||
'href' => [
|
'href' => [
|
||||||
'section' => 'email',
|
'section' => 'email',
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => ':domainid',
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'id' => ':id'
|
'id' => ':id'
|
||||||
],
|
],
|
||||||
@@ -85,7 +86,8 @@ return [
|
|||||||
'class' => 'btn-danger',
|
'class' => 'btn-danger',
|
||||||
'href' => [
|
'href' => [
|
||||||
'section' => 'email',
|
'section' => 'email',
|
||||||
'page' => 'emails',
|
'page' => 'email_domain',
|
||||||
|
'domainid' => ':domainid',
|
||||||
'action' => 'delete',
|
'action' => 'delete',
|
||||||
'id' => ':id'
|
'id' => ':id'
|
||||||
],
|
],
|
||||||
|
|||||||
76
lib/tablelisting/customer/tablelisting.emails_overview.php
Normal file
76
lib/tablelisting/customer/tablelisting.emails_overview.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of the Froxlor project.
|
||||||
|
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you can also view it online at
|
||||||
|
* https://files.froxlor.org/misc/COPYING.txt
|
||||||
|
*
|
||||||
|
* @copyright the authors
|
||||||
|
* @author Froxlor team <team@froxlor.org>
|
||||||
|
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Froxlor\UI\Callbacks\Impersonate;
|
||||||
|
use Froxlor\UI\Callbacks\Style;
|
||||||
|
use Froxlor\UI\Callbacks\Text;
|
||||||
|
use Froxlor\UI\Listing;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'emaildomain_list' => [
|
||||||
|
'title' => lng('menue.email.emailsoverview'),
|
||||||
|
'icon' => 'fa-solid fa-envelope',
|
||||||
|
'self_overview' => ['section' => 'email', 'page' => 'overview'],
|
||||||
|
'default_sorting' => ['d.domain' => 'asc'],
|
||||||
|
'columns' => [
|
||||||
|
'd.domain' => [
|
||||||
|
'label' => 'Domain',
|
||||||
|
'field' => 'domain',
|
||||||
|
],
|
||||||
|
'addresses' => [
|
||||||
|
'label' => '# Adresses',
|
||||||
|
'field' => 'addresses',
|
||||||
|
'searchable' => false,
|
||||||
|
],
|
||||||
|
'accounts' => [
|
||||||
|
'label' => '# Accounts',
|
||||||
|
'field' => 'accounts',
|
||||||
|
'searchable' => false,
|
||||||
|
],
|
||||||
|
'forwarder' => [
|
||||||
|
'label' => '# Forwarders',
|
||||||
|
'field' => 'forwarder',
|
||||||
|
'searchable' => false,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'visible_columns' => Listing::getVisibleColumnsForListing('emaildomain_list', [
|
||||||
|
'd.domain',
|
||||||
|
'addresses',
|
||||||
|
'accounts',
|
||||||
|
'forwarder',
|
||||||
|
]),
|
||||||
|
'actions' => [
|
||||||
|
'show' => [
|
||||||
|
'icon' => 'fa-solid fa-eye',
|
||||||
|
'title' => lng('apikeys.clicktoview'),
|
||||||
|
'href' => [
|
||||||
|
'section' => 'email',
|
||||||
|
'page' => 'email_domain',
|
||||||
|
'domainid' => ':domainid'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
];
|
||||||
@@ -1073,6 +1073,7 @@ Vielen Dank, Ihr Administrator',
|
|||||||
'email' => 'E-Mail',
|
'email' => 'E-Mail',
|
||||||
'emails' => 'Adressen',
|
'emails' => 'Adressen',
|
||||||
'webmail' => 'Webmail',
|
'webmail' => 'Webmail',
|
||||||
|
'emailsoverview' => 'E-Mail Domain Übersicht',
|
||||||
],
|
],
|
||||||
'mysql' => [
|
'mysql' => [
|
||||||
'mysql' => 'MySQL',
|
'mysql' => 'MySQL',
|
||||||
|
|||||||
@@ -1142,6 +1142,7 @@ Yours sincerely, your administrator',
|
|||||||
'email' => 'Email',
|
'email' => 'Email',
|
||||||
'emails' => 'Addresses',
|
'emails' => 'Addresses',
|
||||||
'webmail' => 'Webmail',
|
'webmail' => 'Webmail',
|
||||||
|
'emailsoverview' => 'Email domains overview',
|
||||||
],
|
],
|
||||||
'mysql' => [
|
'mysql' => [
|
||||||
'mysql' => 'MySQL',
|
'mysql' => 'MySQL',
|
||||||
|
|||||||
Reference in New Issue
Block a user