diff --git a/admin_admins.php b/admin_admins.php index 72009a7f..e806a297 100644 --- a/admin_admins.php +++ b/admin_admins.php @@ -41,11 +41,15 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - UI::twigBuffer('user/table.html.twig', [ - 'listing' => \Froxlor\UI\Listing::format($collection, $admin_list_data['admin_list']), - ]); - UI::twigOutputBuffer(); - } elseif ($action == 'su') { + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($collection, $admin_list_data['admin_list']), + 'actions_links' => [[ + 'href' => $linker->getLink(['section' => 'admins', 'page' => $page, 'action' => 'add']), + 'label' => $lng['admin']['admin_add'] + ]] + ]); + UI::twigOutputBuffer(); + } elseif ($action == 'su') { try { $json_result = Admins::getLocal($userinfo, array( diff --git a/admin_customers.php b/admin_customers.php index b32aac0c..b02dcb2c 100644 --- a/admin_customers.php +++ b/admin_customers.php @@ -33,18 +33,27 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_customers"); try { - $customer_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/admin/tablelisting.customers.php'; + $customer_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/admin/tablelisting.customers.php'; $collection = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Customers::class, $userinfo)) - ->has('admin', \Froxlor\Api\Commands\Admins::class, 'adminid', 'adminid') - ->withPagination($customer_list_data['customer_list']['columns']); - } catch (Exception $e) { - \Froxlor\UI\Response::dynamic_error($e->getMessage()); - } + ->has('admin', \Froxlor\Api\Commands\Admins::class, 'adminid', 'adminid') + ->withPagination($customer_list_data['customer_list']['columns']); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } - UI::twigBuffer('user/table.html.twig', [ - 'listing' => \Froxlor\UI\Listing::format($collection, $customer_list_data['customer_list']), - ]); - UI::twigOutputBuffer(); + $actions_links = false; + if ($userinfo['customers_used'] < $userinfo['customers'] || $userinfo['customers'] == '-1') { + $actions_links = [[ + 'href' => $linker->getLink(['section' => 'customers', 'page' => $page, 'action' => 'add']), + 'label' => $lng['admin']['customer_add'] + ]]; + } + + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($collection, $customer_list_data['customer_list']), + 'actions_links' => $actions_links + ]); + UI::twigOutputBuffer(); } elseif ($action == 'su' && $id != 0) { try { $json_result = Customers::getLocal($userinfo, array( diff --git a/admin_domains.php b/admin_domains.php index 3170667f..d56abe76 100644 --- a/admin_domains.php +++ b/admin_domains.php @@ -38,14 +38,31 @@ if ($page == 'domains' || $page == 'overview') { $collection = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Domains::class, $userinfo)) ->has('customer', \Froxlor\Api\Commands\Customers::class, 'customerid', 'customerid') ->withPagination($domain_list_data['domain_list']['columns']); + $customerCollection = (new \Froxlor\UI\Collection(Customers::class, $userinfo)); } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - UI::twigBuffer('user/table.html.twig', [ - 'listing' => \Froxlor\UI\Listing::format($collection, $domain_list_data['domain_list']), - ]); - UI::twigOutputBuffer(); + $actions_links = false; + if (($userinfo['domains_used'] < $userinfo['domains'] || $userinfo['domains'] == '-1') && $customerCollection->count() != 0) { + $actions_links = []; + $actions_links[] = [ + 'href' => $linker->getLink(['section' => 'domains', 'page' => $page, 'action' => 'add']), + 'label' => $lng['admin']['domain_add'] + ]; + $actions_links[] = [ + 'href' => $linker->getLink(['section' => 'domains', 'page' => $page, 'action' => 'import']), + 'label' => $lng['domains']['domain_import'], + 'icon' => 'fa-solid fa-file-import', + 'class' => 'btn-secondary' + ]; + } + + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($collection, $domain_list_data['domain_list']), + 'actions_links' => $actions_links + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { diff --git a/admin_ipsandports.php b/admin_ipsandports.php index 8f641d29..353ca5a1 100644 --- a/admin_ipsandports.php +++ b/admin_ipsandports.php @@ -39,10 +39,14 @@ if ($page == 'ipsandports' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - UI::twigBuffer('user/table.html.twig', [ - 'listing' => \Froxlor\UI\Listing::format($collection, $ipsandports_list_data['ipsandports_list']), - ]); - UI::twigOutputBuffer(); + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($collection, $ipsandports_list_data['ipsandports_list']), + 'actions_links' => [[ + 'href' => $linker->getLink(['section' => 'ipsandports', 'page' => $page, 'action' => 'add']), + 'label' => $lng['admin']['ipsandports']['add'] + ]] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { $json_result = IpsAndPorts::getLocal($userinfo, array( diff --git a/admin_plans.php b/admin_plans.php index 23132af0..14ace4cd 100644 --- a/admin_plans.php +++ b/admin_plans.php @@ -40,10 +40,14 @@ if ($page == '' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - UI::twigBuffer('user/table.html.twig', [ - 'listing' => \Froxlor\UI\Listing::format($collection, $plan_list_data['plan_list']), - ]); - UI::twigOutputBuffer(); + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($collection, $plan_list_data['plan_list']), + 'actions_links' => [[ + 'href' => $linker->getLink(['section' => 'plans', 'page' => $page, 'action' => 'add']), + 'label' => $lng['admin']['plans']['add'] + ]] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { diff --git a/customer_domains.php b/customer_domains.php index 6c30cb57..2091f961 100644 --- a/customer_domains.php +++ b/customer_domains.php @@ -33,75 +33,40 @@ if (Settings::IsInList('panel.customer_hide_options', 'domains')) { $id = (int) Request::get('id'); -if ($page == 'overview') { - $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains"); - eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";"); -} elseif ($page == 'domains') { +if ($page == 'overview' || $page == 'domains') { if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains::domains"); - $fields = array( - 'd.domain_ace' => $lng['domains']['domainname'], - 'd.aliasdomain' => $lng['domains']['aliasdomain'] - ); + + $parentdomain_id = (int) Request::get('pid', '0'); + try { - // get total count - $json_result = SubDomains::getLocal($userinfo)->listingCount(); - $result = json_decode($json_result, true)['data']; - // initialize pagination and filtering - $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); - // get list - $json_result = SubDomains::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + $domain_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.domains.php'; + $list = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\SubDomains::class, $userinfo)) + //->addParam(['sql_search' => ['d.parentdomainid' => $parentdomain_id]]) + ->withPagination($domain_list_data['domain_list']['columns']) + ->getList(); } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + + $json_result = SubDomains::getLocal($userinfo, ['sql_search' => ['d.parentdomainid' => 0]])->listing(); $result = json_decode($json_result, true)['data']; + $parentdomains_count = $result['count']; - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $domains = ''; - $parentdomains_count = 0; - $domains_count = $paging->getEntries(); - $domain_array = array(); - - foreach ($result['list'] as $row) { - formatDomainEntry($row, $idna_convert); - if ($row['parentdomainid'] == '0' && $row['caneditdomain'] == '1') { - $parentdomains_count++; - } - $domain_array[$row['parentdomainname']][] = $row; + $actions_links = false; + if (($userinfo['subdomains_used'] < $userinfo['subdomains'] || $userinfo['subdomains'] == '-1') && $parentdomains_count != 0) { + $actions_links = [[ + 'href' => $linker->getLink(['section' => 'domains', 'page' => 'domains', 'action' => 'add']), + 'label' => $lng['domains']['subdomain_add'] + ]]; } - foreach ($domain_array as $parentdomain => $sdomains) { - // PARENTDOMAIN - if (Settings::Get('system.awstats_enabled') == '1') { - $statsapp = 'awstats'; - } else { - $statsapp = 'webalizer'; - } - $row = [ - 'domain' => $idna_convert->decode($parentdomain) - ]; - eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_delimiter") . "\";"); - - foreach ($sdomains as $domain) { - $row = \Froxlor\PhpHelper::htmlentitiesArray($domain); - - // show docroot nicely - if (strpos($row['documentroot'], $userinfo['documentroot']) === 0) { - $row['documentroot'] = \Froxlor\FileDir::makeCorrectDir(str_replace($userinfo['documentroot'], "/", $row['documentroot'])); - } - // get ssl-ips if activated - $show_ssledit = false; - if (Settings::Get('system.use_ssl') == '1' && \Froxlor\Domain\Domain::domainHasSslIpPort($row['id']) && $row['caneditdomain'] == '1' && $row['letsencrypt'] == 0) { - $show_ssledit = true; - } - eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";"); - } - } - - eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domainlist") . "\";"); + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($list, $domain_list_data['domain_list']), + 'actions_links' => $actions_links, + 'entity_info' => $lng['domains']['description'] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { $json_result = SubDomains::getLocal($userinfo, array( diff --git a/customer_email.php b/customer_email.php index 93f9da5c..2f1d590d 100644 --- a/customer_email.php +++ b/customer_email.php @@ -34,97 +34,18 @@ if (Settings::IsInList('panel.customer_hide_options', 'email')) { $id = (int) Request::get('id'); -if ($page == 'overview') { - $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email"); - eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/email") . "\";"); -} elseif ($page == 'emails') { +if ($page == 'overview' || $page == 'emails') { if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails"); - $fields = array( - 'd.domain_ace' => $lng['domains']['domainname'], - 'm.email_full' => $lng['emails']['emailaddress'], - 'm.destination' => $lng['emails']['forwarders'] - ); + try { - // get total count - $json_result = Emails::getLocal($userinfo)->listingCount(); - $result = json_decode($json_result, true)['data']; - // initialize pagination and filtering - $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); - // get list - $json_result = Emails::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + $email_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.emails.php'; + $list = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Emails::class, $userinfo)) + ->withPagination($email_list_data['email_list']['columns']) + ->getList(); } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $result = json_decode($json_result, true)['data']; - - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $emails = array(); - $emailscount = $paging->getEntries(); - - foreach ($result['list'] as $row) { - if (! isset($emails[$row['domain']]) || ! is_array($emails[$row['domain']])) { - $emails[$row['domain']] = array(); - } - - $emails[$row['domain']][$row['email_full']] = $row; - } - - if ($paging->sortfield == 'd.domain_ace' && $paging->sortorder == 'desc') { - krsort($emails); - } else { - ksort($emails); - } - - $count = 0; - $accounts = ''; - $emails_count = 0; - $domainname = ''; - foreach ($emails as $domainid => $emailaddresses) { - if ($paging->sortfield == 'm.email_full' && $paging->sortorder == 'desc') { - krsort($emailaddresses); - } else { - ksort($emailaddresses); - } - - foreach ($emailaddresses as $row) { - if ($domainname != $idna_convert->decode($row['domain'])) { - $domainname = $idna_convert->decode($row['domain']); - eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_domain") . "\";"); - } - - $emails_count ++; - $row['email'] = $idna_convert->decode($row['email']); - $row['email_full'] = $idna_convert->decode($row['email_full']); - $row['destination'] = explode(' ', $row['destination']); - uasort($row['destination'], 'strcasecmp'); - - $dest_list = $row['destination']; - foreach ($dest_list as $dest_id => $destination) { - $row['destination'][$dest_id] = $idna_convert->decode($row['destination'][$dest_id]); - - if ($row['destination'][$dest_id] == $row['email_full']) { - unset($row['destination'][$dest_id]); - } - } - - $destinations_count = count($row['destination']); - $row['destination'] = implode(', ', $row['destination']); - - if (strlen($row['destination']) > 35) { - $row['destination'] = substr($row['destination'], 0, 32) . '... (' . $destinations_count . ')'; - } - - $row['mboxsize'] = \Froxlor\PhpHelper::sizeReadable($row['mboxsize'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); - - $row = \Froxlor\PhpHelper::htmlentitiesArray($row); - eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_email") . "\";"); - $count ++; - } - } $result_stmt = Database::prepare(" SELECT COUNT(`id`) as emaildomains @@ -136,7 +57,20 @@ if ($page == 'overview') { )); $emaildomains_count = $result2['emaildomains']; - eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";"); + $actions_links = false; + if (($userinfo['emails_used'] < $userinfo['emails'] || $userinfo['emails'] == '-1') && $emaildomains_count !=0) { + $actions_links = [[ + 'href' => $linker->getLink(['section' => 'email', 'page' => $page, 'action' => 'add']), + 'label' => $lng['emails']['emails_add'] + ]]; + } + + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($list, $email_list_data['email_list']), + 'actions_links' => $actions_links, + 'entity_info' => $lng['emails']['description'] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { $json_result = Emails::getLocal($userinfo, array( diff --git a/customer_extras.php b/customer_extras.php index 59427300..5ea69bd5 100644 --- a/customer_extras.php +++ b/customer_extras.php @@ -33,10 +33,7 @@ if (Settings::IsInList('panel.customer_hide_options', 'extras')) { $id = (int) Request::get('id'); -if ($page == 'overview') { - $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_extras"); - eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/extras") . "\";"); -} elseif ($page == 'htpasswds') { +if ($page == 'overview' || $page == 'htpasswds') { // redirect if this customer sub-page is hidden via settings if (Settings::IsInList('panel.customer_hide_options', 'extras.directoryprotection')) { @@ -50,36 +47,23 @@ if ($page == 'overview') { 'path' => $lng['panel']['path'] ); try { - // get total count - $json_result = DirProtections::getLocal($userinfo)->listingCount(); - $result = json_decode($json_result, true)['data']; - // initialize pagination and filtering - $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); - // get list - $json_result = DirProtections::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + $htpasswd_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.htpasswd.php'; + $list = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\DirProtections::class, $userinfo)) + ->withPagination($htpasswd_list_data['htpasswd_list']['columns']) + ->getList(); } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $result = json_decode($json_result, true)['data']; - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $count = 0; - $htpasswds = ''; - - foreach ($result['list'] as $row) { - if (strpos($row['path'], $userinfo['documentroot']) === 0) { - $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); - } - $row['path'] = \Froxlor\FileDir::makeCorrectDir($row['path']); - $row = \Froxlor\PhpHelper::htmlentitiesArray($row); - eval("\$htpasswds.=\"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds_htpasswd") . "\";"); - $count ++; - } - - eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds") . "\";"); + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($list, $htpasswd_list_data['htpasswd_list']), + 'actions_links' => [[ + 'href' => $linker->getLink(['section' => 'extras', 'page' => 'htpasswds', 'action' => 'add']), + 'label' => $lng['extras']['directoryprotection_add'] + ]], + 'entity_info' => $lng['extras']['description'] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { $json_result = DirProtections::getLocal($userinfo, array( @@ -181,51 +165,27 @@ if ($page == 'overview') { if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_extras::htaccess"); - $fields = array( - 'path' => $lng['panel']['path'], - 'options_indexes' => $lng['extras']['view_directory'], - 'error404path' => $lng['extras']['error404path'], - 'error403path' => $lng['extras']['error403path'], - 'error500path' => $lng['extras']['error500path'], - 'options_cgi' => $lng['extras']['execute_perl'] - ); - try { - // get total count - $json_result = DirOptions::getLocal($userinfo)->listingCount(); - $result = json_decode($json_result, true)['data']; - // initialize pagination and filtering - $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); - // get list - $json_result = DirOptions::getLocal($userinfo, $paging->getApiCommandParams())->listing(); - } catch (Exception $e) { - \Froxlor\UI\Response::dynamic_error($e->getMessage()); - } - $result = json_decode($json_result, true)['data']; - - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $count = 0; - $htaccess = ''; $cperlenabled = \Froxlor\Customer\Customer::customerHasPerlEnabled($userinfo['customerid']); - foreach ($result['list'] as $row) { - if (strpos($row['path'], $userinfo['documentroot']) === 0) { - $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); - } - $row['path'] = \Froxlor\FileDir::makeCorrectDir($row['path']); - $row['options_indexes'] = str_replace('1', $lng['panel']['yes'], $row['options_indexes']); - $row['options_indexes'] = str_replace('0', $lng['panel']['no'], $row['options_indexes']); - $row['options_cgi'] = str_replace('1', $lng['panel']['yes'], $row['options_cgi']); - $row['options_cgi'] = str_replace('0', $lng['panel']['no'], $row['options_cgi']); - $row = \Froxlor\PhpHelper::htmlentitiesArray($row); - eval("\$htaccess.=\"" . \Froxlor\UI\Template::getTemplate("extras/htaccess_htaccess") . "\";"); - $count ++; + try { + $htaccess_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.htaccess.php'; + $list = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\DirOptions::class, $userinfo)) + ->withPagination($htaccess_list_data['htaccess_list']['columns']) + ->getList(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htaccess") . "\";"); + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($list, $htaccess_list_data['htaccess_list']), + 'add_link' => [ + 'href' => $linker->getLink(['section' => 'extras', 'page' => 'htaccess', 'action' => 'add']), + 'label' => $lng['extras']['pathoptions_add'] + ], + 'entity_info' => $lng['extras']['description'] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { $json_result = DirOptions::getLocal($userinfo, array( @@ -363,7 +323,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::standard_success('backupscheduled'); } else { - if (! empty($existing_backupJob)) { + if (!empty($existing_backupJob)) { $action = "abort"; $row = $existing_backupJob['data']; @@ -371,18 +331,19 @@ if ($page == 'overview') { $row['backup_web'] = ($row['backup_web'] == '1') ? $lng['panel']['yes'] : $lng['panel']['no']; $row['backup_mail'] = ($row['backup_mail'] == '1') ? $lng['panel']['yes'] : $lng['panel']['no']; $row['backup_dbs'] = ($row['backup_dbs'] == '1') ? $lng['panel']['yes'] : $lng['panel']['no']; - } - $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); - $backup_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.backup.php'; - $backup_form = \Froxlor\UI\HtmlForm::genHTMLForm($backup_data); - $title = $backup_data['backup']['title']; - $image = $backup_data['backup']['image']; - if (! empty($existing_backupJob)) { // overwrite backup_form after we took everything from it we needed eval("\$backup_form = \"" . \Froxlor\UI\Template::getTemplate("extras/backup_listexisting") . "\";"); } - eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/backup") . "\";"); + + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); + $backup_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.backup.php'; + + UI::twigBuffer('user/form.html.twig', [ + 'formaction' => $linker->getLink(array('section' => 'extras')), + 'formdata' => $backup_data['backup'] + ]); + UI::twigOutputBuffer(); } } } else { diff --git a/customer_ftp.php b/customer_ftp.php index 99743677..ce3bde10 100644 --- a/customer_ftp.php +++ b/customer_ftp.php @@ -32,50 +32,32 @@ if (Settings::IsInList('panel.customer_hide_options', 'ftp')) { $id = (int) Request::get('id', 0); -if ($page == 'overview') { - $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_ftp"); - eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/ftp') . "\";"); -} elseif ($page == 'accounts') { +if ($page == 'overview' || $page == 'accounts') { if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_ftp::accounts"); - $fields = array( - 'username' => $lng['login']['username'], - 'homedir' => $lng['panel']['path'], - 'description' => $lng['panel']['ftpdesc'] - ); try { - // get total count - $json_result = Ftps::getLocal($userinfo)->listingCount(); - $result = json_decode($json_result, true)['data']; - // initialize pagination and filtering - $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); - // get list - $json_result = Ftps::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + $ftp_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.ftps.php'; + $list = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Ftps::class, $userinfo)) + ->withPagination($ftp_list_data['ftp_list']['columns']) + ->getList(); } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $result = json_decode($json_result, true)['data']; - $ftps_count = $paging->getEntries(); - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $count = 0; - $accounts = ''; - foreach ($result['list'] as $row) { - if (strpos($row['homedir'], $userinfo['documentroot']) === 0) { - $row['documentroot'] = str_replace($userinfo['documentroot'], "/", $row['homedir']); - } else { - $row['documentroot'] = $row['homedir']; - } - $row['documentroot'] = \Froxlor\FileDir::makeCorrectDir($row['documentroot']); - $row = \Froxlor\PhpHelper::htmlentitiesArray($row); - eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate('ftp/accounts_account') . "\";"); - $count++; + $actions_links = false; + if ($userinfo['ftps_used'] < $userinfo['ftps'] || $userinfo['ftps'] == '-1') { + $actions_links = [[ + 'href' => $linker->getLink(['section' => 'ftp', 'page' => 'accounts', 'action' => 'add']), + 'label' => $lng['ftp']['account_add'] + ]]; } - eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/accounts') . "\";"); + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($list, $ftp_list_data['ftp_list']), + 'actions_links' => $actions_links, + 'entity_info' => $lng['ftp']['description'] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { $json_result = Ftps::getLocal($userinfo, array( diff --git a/customer_mysql.php b/customer_mysql.php index 895841e0..4985e0f3 100644 --- a/customer_mysql.php +++ b/customer_mysql.php @@ -38,65 +38,41 @@ Database::needRoot(false); $id = (int) Request::get('id'); -if ($page == 'overview') { - $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_mysql"); - Database::needSqlData(); - $sql = Database::getSqlData(); - $lng['mysql']['description'] = str_replace('', $sql['host'], $lng['mysql']['description']); - eval("echo \"" . \Froxlor\UI\Template::getTemplate('mysql/mysql') . "\";"); -} elseif ($page == 'mysqls') { +if ($page == 'overview' || $page == 'mysqls') { if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_mysql::mysqls"); - $fields = array( - 'databasename' => $lng['mysql']['databasename'], - 'description' => $lng['mysql']['databasedescription'] - ); - try { - // get total count - $json_result = Mysqls::getLocal($userinfo)->listingCount(); - $result = json_decode($json_result, true)['data']; - // initialize pagination and filtering - $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); - // get list - $json_result = Mysqls::getLocal($userinfo, $paging->getApiCommandParams())->listing(); - } catch (Exception $e) { - \Froxlor\UI\Response::dynamic_error($e->getMessage()); - } - $result = json_decode($json_result, true)['data']; - - $mysqls_count = $paging->getEntries(); - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $count = 0; - $mysqls = ''; $dbservers_stmt = Database::query("SELECT COUNT(DISTINCT `dbserver`) as numservers FROM `" . TABLE_PANEL_DATABASES . "`"); $dbserver = $dbservers_stmt->fetch(PDO::FETCH_ASSOC); $count_mysqlservers = $dbserver['numservers']; - // Begin root-session - Database::needRoot(true); - foreach ($result['list'] as $row) { - $row = \Froxlor\PhpHelper::htmlentitiesArray($row); - $mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES - WHERE table_schema = :table_schema - GROUP BY table_schema"); - $mbdata = Database::pexecute_first($mbdata_stmt, array( - "table_schema" => $row['databasename'] - )); - if (!$mbdata) { - $mbdata = array('MB' => 0); - } - $row['size'] = \Froxlor\PhpHelper::sizeReadable($mbdata['MB'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); - eval("\$mysqls.=\"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_database') . "\";"); - $count++; + try { + $mysql_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.mysqls.php'; + $list = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Mysqls::class, $userinfo)) + ->withPagination($mysql_list_data['mysql_list']['columns']) + ->getList(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - Database::needRoot(false); - // End root-session - eval("echo \"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls') . "\";"); + Database::needSqlData(); + $sql = Database::getSqlData(); + $lng['mysql']['description'] = str_replace('', $sql['host'], $lng['mysql']['description']); + + $actions_links = false; + if ($userinfo['mysqls_used'] < $userinfo['mysqls'] || $userinfo['mysqls'] == '-1') { + $actions_links = [[ + 'href' => $linker->getLink(['section' => 'mysql', 'page' => 'mysqls', 'action' => 'add']), + 'label' => $lng['mysql']['database_create'] + ]]; + } + + UI::twigBuffer('user/table.html.twig', [ + 'listing' => \Froxlor\UI\Listing::format($list, $mysql_list_data['mysql_list']), + 'actions_links' => $actions_links, + 'entity_info' => $lng['mysql']['description'] + ]); + UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { try { diff --git a/dns_editor.php b/dns_editor.php index 6bac1ac0..4a466c90 100644 --- a/dns_editor.php +++ b/dns_editor.php @@ -19,13 +19,13 @@ if (! defined('AREA')) { * */ -use Froxlor\Api\Commands\DomainZones as DomainZones; +use Froxlor\Api\Commands\DomainZones; use Froxlor\UI\Request; // This file is being included in admin_domains and customer_domains // and therefore does not need to require lib/init.php -$domain_id = (int) Request::get(['domain_id']); +$domain_id = (int) Request::get('domain_id'); $record = isset($_POST['record']['record']) ? trim($_POST['record']['record']) : null; $type = isset($_POST['record']['type']) ? $_POST['record']['type'] : 'A'; diff --git a/lib/Froxlor/Api/Commands/DomainZones.php b/lib/Froxlor/Api/Commands/DomainZones.php index c5b29296..32748c20 100644 --- a/lib/Froxlor/Api/Commands/DomainZones.php +++ b/lib/Froxlor/Api/Commands/DomainZones.php @@ -545,6 +545,6 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS); return $this->response(true); } - return $this->response(null, 204); + return $this->response(true, 304); } } diff --git a/lib/Froxlor/Api/FroxlorRPC.php b/lib/Froxlor/Api/FroxlorRPC.php index 56dfe43c..9e89150c 100644 --- a/lib/Froxlor/Api/FroxlorRPC.php +++ b/lib/Froxlor/Api/FroxlorRPC.php @@ -3,7 +3,6 @@ namespace Froxlor\Api; use Exception; -use voku\helper\AntiXSS; /** * This file is part of the Froxlor project. @@ -23,110 +22,111 @@ use voku\helper\AntiXSS; */ class FroxlorRPC { - /** - * validate a given request - * - * @param $request - * @return array - * @throws Exception - */ - public static function validateRequest($request): array - { - // make basic authentication - if (!isset($_SERVER['PHP_AUTH_USER']) || !self::validateAuth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) { - header('WWW-Authenticate: Basic realm="API"'); - throw new Exception('Unauthenticated. Please provide api user credentials.', 401); - } + /** + * validate a given request + * + * @param $request + * @return array + * @throws Exception + */ + public static function validateRequest($request): array + { + // make basic authentication + if (!isset($_SERVER['PHP_AUTH_USER']) || !self::validateAuth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) { + if (@php_sapi_name() !== 'cli') { + header('WWW-Authenticate: Basic realm="API"'); + } + throw new Exception('Unauthenticated. Please provide api user credentials.', 401); + } - // check if present - if (empty($request)) { - throw new Exception('Empty request body.', 400); - } + // check if present + if (empty($request)) { + throw new Exception('Empty request body.', 400); + } - // decode json request - $decoded_request = json_decode($request, true); + // decode json request + $decoded_request = json_decode($request, true); - // is it valid? - if (is_null($decoded_request)) { - throw new Exception('Invalid JSON Format.', 400); - } + // is it valid? + if (is_null($decoded_request)) { + throw new Exception('Invalid JSON Format.', 400); + } - return self::validateBody($decoded_request); - } + return self::validateBody($decoded_request); + } - /** - * validates the given api credentials - * - * @param string $key - * @param string $secret - * @return boolean - */ - private static function validateAuth(string $key, string $secret): bool - { - $sel_stmt = \Froxlor\Database\Database::prepare( - " + /** + * validates the given api credentials + * + * @param string $key + * @param string $secret + * @return boolean + */ + private static function validateAuth(string $key, string $secret): bool + { + $sel_stmt = \Froxlor\Database\Database::prepare( + " SELECT ak.*, a.api_allowed as admin_api_allowed, c.api_allowed as cust_api_allowed, c.deactivated FROM `api_keys` ak LEFT JOIN `panel_admins` a ON a.adminid = ak.adminid LEFT JOIN `panel_customers` c ON c.customerid = ak.customerid WHERE `apikey` = :ak AND `secret` = :as " - ); - $result = \Froxlor\Database\Database::pexecute_first($sel_stmt, array( - 'ak' => $key, - 'as' => $secret - ), true, true); - if ($result) { - if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == -1 || $result['valid_until'] >= time( - )) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1 && $result['deactivated'] == 0))) { - // get user to check whether api call is allowed - if (!empty($result['allowed_from'])) { - // @todo allow specification and validating of whole subnets later - $ip_list = explode(",", $result['allowed_from']); - $access_ip = inet_ntop(inet_pton($_SERVER['REMOTE_ADDR'])); - if (in_array($access_ip, $ip_list)) { - return true; - } - } else { - return true; - } - } - } - return false; - } + ); + $result = \Froxlor\Database\Database::pexecute_first($sel_stmt, array( + 'ak' => $key, + 'as' => $secret + ), true, true); + if ($result) { + if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == -1 || $result['valid_until'] >= time()) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1 && $result['deactivated'] == 0))) { + // get user to check whether api call is allowed + if (!empty($result['allowed_from'])) { + // @todo allow specification and validating of whole subnets later + $ip_list = explode(",", $result['allowed_from']); + $access_ip = inet_ntop(inet_pton($_SERVER['REMOTE_ADDR'])); + if (in_array($access_ip, $ip_list)) { + return true; + } + } else { + return true; + } + } + } + throw new Exception('Invalid authorization credentials', 403); + } - /** - * validates the given command - * - * @param array $request - * - * @return array - * @throws Exception - */ - private static function validateBody($request) - { - // check command exists - if (empty($request['command'])) { - throw new Exception("Please provide a command.", 400); - } + /** + * validates the given command + * + * @param array $request + * + * @return array + * @throws Exception + */ + private static function validateBody($request) + { + // check command exists + if (empty($request['command'])) { + throw new Exception("Please provide a command.", 400); + } - $command = explode(".", $request['command']); + $command = explode(".", $request['command']); - if (count($command) != 2) { - throw new Exception("The given command is invalid.", 400); - } - // simply check for file-existance, as we do not want to use our autoloader because this way - // it will recognize non-api classes+methods as valid commands - $apiclass = '\\Froxlor\\Api\\Commands\\' . $command[0]; - if (!class_exists($apiclass) || !@method_exists($apiclass, $command[1])) { - throw new Exception("Unknown command", 400); - } - return array( - 'command' => array( - 'class' => $command[0], - 'method' => $command[1] - ), - 'params' => $request['params'] ?? null - ); - } + if (count($command) != 2) { + throw new Exception("The given command is invalid.", 400); + } + // simply check for file-existance, as we do not want to use our autoloader because this way + // it will recognize non-api classes+methods as valid commands + $apiclass = '\\Froxlor\\Api\\Commands\\' . $command[0]; + if (!class_exists($apiclass) || !@method_exists($apiclass, $command[1])) { + throw new Exception("Unknown command", 400); + } + return array( + 'command' => array( + 'class' => $command[0], + 'method' => $command[1] + ), + 'params' => $request['params'] ?? null + ); + } } diff --git a/lib/Froxlor/UI/Callbacks/Domain.php b/lib/Froxlor/UI/Callbacks/Domain.php new file mode 100644 index 00000000..7ba4ad8e --- /dev/null +++ b/lib/Froxlor/UI/Callbacks/Domain.php @@ -0,0 +1,47 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Listing + * + */ + +class Domain +{ + public static function domainTarget(string $data, array $attributes): mixed + { + if (empty($attributes['aliasdomain'])) { + // path or redirect + if (preg_match('/^https?\:\/\//', $attributes['documentroot'])) { + return [ + 'type' => 'link', + 'data' => [ + 'text' => $attributes['documentroot'], + 'href' => $attributes['documentroot'], + 'target' => '_blank' + ] + ]; + } else { + // show docroot nicely + if (strpos($attributes['documentroot'], UI::getCurrentUser()['documentroot']) === 0) { + $attributes['documentroot'] = \Froxlor\FileDir::makeCorrectDir(str_replace(UI::getCurrentUser()['documentroot'], "/", $attributes['documentroot'])); + } + return $attributes['documentroot']; + } + } + return UI::getLng('domains.aliasdomain') . ' ' . $attributes['aliasdomain']; + } +} diff --git a/lib/Froxlor/UI/Callbacks/Email.php b/lib/Froxlor/UI/Callbacks/Email.php new file mode 100644 index 00000000..03e1a164 --- /dev/null +++ b/lib/Froxlor/UI/Callbacks/Email.php @@ -0,0 +1,35 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Listing + * + */ + +class Email +{ + public static function account(string $data, array $attributes): mixed + { + return [ + 'type' => 'booleanWithInfo', + 'data' => [ + 'checked' => $data != 0, + 'info' => $data != 0 ? PhpHelper::sizeReadable($attributes['mboxsize'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s') : '' + ] + ]; + } +} diff --git a/lib/Froxlor/UI/Callbacks/Ftp.php b/lib/Froxlor/UI/Callbacks/Ftp.php new file mode 100644 index 00000000..31f575ab --- /dev/null +++ b/lib/Froxlor/UI/Callbacks/Ftp.php @@ -0,0 +1,33 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Listing + * + */ + +class Ftp +{ + public static function pathRelative(string $data, array $attributes): string + { + if (strpos($data, UI::getCurrentUser()['documentroot']) === 0) { + $data = str_replace(UI::getCurrentUser()['documentroot'], "/", $data); + } + $data = \Froxlor\FileDir::makeCorrectDir($data); + + return $data; + } +} diff --git a/lib/Froxlor/UI/Callbacks/Impersonate.php b/lib/Froxlor/UI/Callbacks/Impersonate.php index c9b508f1..3d3bea32 100644 --- a/lib/Froxlor/UI/Callbacks/Impersonate.php +++ b/lib/Froxlor/UI/Callbacks/Impersonate.php @@ -1,4 +1,5 @@ 'link', - 'data' => [ - 'text' => $data, - 'href' => $linker->getLink([ - 'section' => 'admins', - 'page' => 'admins', - 'action' => 'su', - 'id' => $attributes['adminid'], - ]), - ] - ]; - } + public static function admin(string $data, array $attributes): mixed + { + if (UI::getCurrentUser()['adminid'] != $attributes['adminid']) { + $linker = UI::getLinker(); + return [ + 'type' => 'link', + 'data' => [ + 'text' => $data, + 'href' => $linker->getLink([ + 'section' => 'admins', + 'page' => 'admins', + 'action' => 'su', + 'id' => $attributes['adminid'], + ]), + ] + ]; + } + return $data; + } - public static function customer(string $data, array $attributes): array - { - $linker = UI::getLinker(); - return [ - 'type' => 'link', - 'data' => [ - 'text' => $data, - 'href' => $linker->getLink([ - 'section' => 'customers', - 'page' => 'customers', - 'action' => 'su', - 'sort' => $attributes['loginname'], - 'id' => $attributes['customerid'], - ]), - ] - ]; - } + public static function customer(string $data, array $attributes): array + { + $linker = UI::getLinker(); + return [ + 'type' => 'link', + 'data' => [ + 'text' => $data, + 'href' => $linker->getLink([ + 'section' => 'customers', + 'page' => 'customers', + 'action' => 'su', + 'sort' => $attributes['loginname'], + 'id' => $attributes['customerid'], + ]), + ] + ]; + } } diff --git a/lib/Froxlor/UI/Callbacks/Mysql.php b/lib/Froxlor/UI/Callbacks/Mysql.php new file mode 100644 index 00000000..f3e83411 --- /dev/null +++ b/lib/Froxlor/UI/Callbacks/Mysql.php @@ -0,0 +1,34 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Listing + * + */ + +class Mysql +{ + public static function dbserver(string $data, array $attributes): string + { + // get sql-root access data + Database::needRoot(true, (int) $data); + Database::needSqlData(); + $sql_root = Database::getSqlData(); + Database::needRoot(false); + + return $sql_root['caption'] . '
' . $sql_root['host'] . ''; + } +} diff --git a/lib/Froxlor/UI/Callbacks/Text.php b/lib/Froxlor/UI/Callbacks/Text.php index 04d9b4e0..e26c7f62 100644 --- a/lib/Froxlor/UI/Callbacks/Text.php +++ b/lib/Froxlor/UI/Callbacks/Text.php @@ -1,6 +1,9 @@ 'boolean', - 'data' => (bool) $data - ]; - } + public static function boolean(?string $data): array + { + return [ + 'type' => 'boolean', + 'data' => (bool) $data + ]; + } - public static function domainWithSan(string $data, array $attributes): array - { - return [ - 'type' => 'domainWithSan', - 'data' => [ - 'domain' => $data, - 'san' => implode(', ', $attributes['san'] ?? []), - ] - ]; - } + public static function domainWithSan(string $data, array $attributes): array + { + return [ + 'type' => 'domainWithSan', + 'data' => [ + 'domain' => $data, + 'san' => implode(', ', $attributes['san'] ?? []), + ] + ]; + } + + public static function customerfullname(string $data, array $attributes): string + { + return \Froxlor\User::getCorrectFullUserDetails($attributes); + } + + public static function size(string $data, array $attributes): string + { + return PhpHelper::sizeReadable($data, null, 'bi'); + } } diff --git a/lib/Froxlor/UI/Collection.php b/lib/Froxlor/UI/Collection.php index 5c175a95..ce32c638 100644 --- a/lib/Froxlor/UI/Collection.php +++ b/lib/Froxlor/UI/Collection.php @@ -87,16 +87,23 @@ class Collection public function has(string $column, string $class, string $parentKey = 'id', string $childKey = 'id', array $params = []): Collection { $this->has[] = [ - 'column' => $column, - 'class' => $class, - 'parentKey' => $parentKey, - 'childKey' => $childKey, - 'params' => $params + 'column' => $column, + 'class' => $class, + 'parentKey' => $parentKey, + 'childKey' => $childKey, + 'params' => $params ]; return $this; } + public function addParam(array $keyval): Collection + { + $this->params = array_merge($this->params, $keyval); + + return $this; + } + public function withPagination(array $columns): Collection { // Get only searchable columns diff --git a/lib/Froxlor/UI/Pagination.php b/lib/Froxlor/UI/Pagination.php index 65eae496..d3b593ba 100644 --- a/lib/Froxlor/UI/Pagination.php +++ b/lib/Froxlor/UI/Pagination.php @@ -12,10 +12,10 @@ use Froxlor\Settings; * COPYING file online at http://files.froxlor.org/misc/COPYING.txt * * @copyright (c) the authors - * @author Froxlor team (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package API - * @since 0.10.0 + * @author Froxlor team (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package API + * @since 0.10.0 * */ diff --git a/lib/Froxlor/UI/Panel/UI.php b/lib/Froxlor/UI/Panel/UI.php index 9025b610..696ca466 100644 --- a/lib/Froxlor/UI/Panel/UI.php +++ b/lib/Froxlor/UI/Panel/UI.php @@ -35,6 +35,13 @@ class UI */ private static $linker = null; + /** + * current logged in user + * + * @var array + */ + private static $userinfo = []; + /** * default fallback theme * @@ -224,6 +231,16 @@ class UI return self::$linker; } + public static function setCurrentUser($userinfo = null) + { + self::$userinfo = $userinfo; + } + + public static function getCurrentUser(): array + { + return self::$userinfo; + } + public static function setLng($lng = array()) { self::$lng = $lng; diff --git a/lib/Froxlor/User.php b/lib/Froxlor/User.php index 717579e9..0600683d 100644 --- a/lib/Froxlor/User.php +++ b/lib/Froxlor/User.php @@ -24,7 +24,7 @@ class User $returnval = $userinfo['name'] . ', ' . $userinfo['firstname']; } else { if ($userinfo['name'] != '' && $userinfo['firstname'] != '') { - $returnval = $userinfo['name'] . ', ' . $userinfo['firstname'] . ' | ' . $userinfo['company']; + $returnval = $userinfo['name'] . ', ' . $userinfo['firstname'] . '
' . $userinfo['company'] . ''; } else { $returnval = $userinfo['company']; } diff --git a/lib/formfields/customer/domains/formfield.domains_add.php b/lib/formfields/customer/domains/formfield.domains_add.php index 937975e6..914848f0 100644 --- a/lib/formfields/customer/domains/formfield.domains_add.php +++ b/lib/formfields/customer/domains/formfield.domains_add.php @@ -14,6 +14,9 @@ * @package Formfields * */ + +use Froxlor\Settings; + return array( 'domain_add' => array( 'title' => $lng['domains']['subdomain_add'], @@ -41,19 +44,19 @@ return array( ), 'path' => array( 'label' => $lng['panel']['path'], - 'desc' => (\Froxlor\Settings::Get('panel.pathedit') != 'Dropdown' ? $lng['panel']['pathDescriptionSubdomain'] : null), + 'desc' => (Settings::Get('panel.pathedit') != 'Dropdown' ? $lng['panel']['pathDescriptionSubdomain'] : null), 'type' => $pathSelect['type'], 'select_var' => $pathSelect['select_var'] ?? '', 'value' => $pathSelect['value'], 'note' => $pathSelect['note'] ?? '', ), 'url' => array( - 'visible' => (\Froxlor\Settings::Get('panel.pathedit') == 'Dropdown' ? true : false), + 'visible' => (Settings::Get('panel.pathedit') == 'Dropdown' ? true : false), 'label' => $lng['panel']['urloverridespath'], 'type' => 'text' ), 'redirectcode' => array( - 'visible' => (\Froxlor\Settings::Get('customredirect.enabled') == '1' ? true : false), + 'visible' => (Settings::Get('customredirect.enabled') == '1' ? true : false), 'label' => $lng['domains']['redirectifpathisurl'], 'desc' => $lng['domains']['redirectifpathisurlinfo'], 'type' => 'select', @@ -71,18 +74,18 @@ return array( 'select_var' => $openbasedir ), 'phpsettingid' => array( - 'visible' => (((int) \Froxlor\Settings::Get('system.mod_fcgid') == 1 || (int) \Froxlor\Settings::Get('phpfpm.enabled') == 1) && count($phpconfigs) > 0 ? true : false), + 'visible' => (((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) && count($phpconfigs) > 0 ? true : false), 'label' => $lng['admin']['phpsettings']['title'], 'type' => 'select', 'select_var' => $phpconfigs, - 'selected' => (int) Settings::Get('phpfpm.enabled') == 1) ? Settings::Get('phpfpm.defaultini') : Settings::Get('system.mod_fcgid_defaultini') + 'selected' => (int) Settings::Get('phpfpm.enabled') == 1 ? Settings::Get('phpfpm.defaultini') : Settings::Get('system.mod_fcgid_defaultini') ) ) ), 'section_bssl' => array( 'title' => $lng['admin']['webserversettings_ssl'], 'image' => 'icons/domain_add.png', - 'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports ? true : false) : false, + 'visible' => Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports ? true : false) : false, 'fields' => array( 'sslenabled' => array( 'label' => $lng['admin']['domain_sslenabled'], @@ -98,7 +101,7 @@ return array( 'checked' => false ), 'letsencrypt' => array( - 'visible' => (\Froxlor\Settings::Get('system.leenabled') == '1' ? true : false), + 'visible' => (Settings::Get('system.leenabled') == '1' ? true : false), 'label' => $lng['customer']['letsencrypt']['title'], 'desc' => $lng['customer']['letsencrypt']['description'], 'type' => 'checkbox', @@ -106,7 +109,7 @@ return array( 'checked' => false ), 'http2' => array( - 'visible' => ($ssl_ipsandports ? true : false) && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' && \Froxlor\Settings::Get('system.http2_support') == '1', + 'visible' => ($ssl_ipsandports ? true : false) && Settings::Get('system.webserver') != 'lighttpd' && Settings::Get('system.http2_support') == '1', 'label' => $lng['admin']['domain_http2']['title'], 'desc' => $lng['admin']['domain_http2']['description'], 'type' => 'checkbox', diff --git a/lib/formfields/customer/email/formfield.emails_addaccount.php b/lib/formfields/customer/email/formfield.emails_addaccount.php index e57db43d..08e3827c 100644 --- a/lib/formfields/customer/email/formfield.emails_addaccount.php +++ b/lib/formfields/customer/email/formfield.emails_addaccount.php @@ -23,7 +23,7 @@ return array( 'title' => $lng['emails']['account_add'], 'image' => 'icons/email_add.png', 'fields' => array( - 'email_full' => array( + 'emailaddr' => array( 'label' => $lng['emails']['emailaddress'], 'type' => 'label', 'value' => $result['email_full'] diff --git a/lib/formfields/customer/email/formfield.emails_addforwarder.php b/lib/formfields/customer/email/formfield.emails_addforwarder.php index 2b3fee44..5900f55f 100644 --- a/lib/formfields/customer/email/formfield.emails_addforwarder.php +++ b/lib/formfields/customer/email/formfield.emails_addforwarder.php @@ -23,7 +23,7 @@ return array( 'title' => $lng['emails']['forwarder_add'], 'image' => 'icons/autoresponder_add.png', 'fields' => array( - 'email_full' => array( + 'emailaddr' => array( 'label' => $lng['emails']['from'], 'type' => 'label', 'value' => $result['email_full'] diff --git a/lib/formfields/customer/extras/formfield.backup.php b/lib/formfields/customer/extras/formfield.backup.php index 13de0341..354202ae 100644 --- a/lib/formfields/customer/extras/formfield.backup.php +++ b/lib/formfields/customer/extras/formfield.backup.php @@ -17,7 +17,7 @@ return array( 'backup' => array( 'title' => $lng['extras']['backup'], - 'image' => 'icons/backup_big.png', + 'image' => 'fa-solid fa-server', 'sections' => array( 'section_a' => array( 'title' => $lng['extras']['backup'], @@ -33,8 +33,9 @@ return array( ), 'path_protection_info' => array( 'label' => $lng['extras']['path_protection_label'], - 'type' => 'label', - 'value' => $lng['extras']['path_protection_info'] + 'type' => 'infotext', + 'value' => $lng['extras']['path_protection_info'], + 'classes' => 'fw-bold text-danger' ), 'backup_web' => array( 'label' => $lng['extras']['backup_web'], diff --git a/lib/formfields/customer/extras/formfield.htaccess_add.php b/lib/formfields/customer/extras/formfield.htaccess_add.php index 7d44f488..0c17f77d 100644 --- a/lib/formfields/customer/extras/formfield.htaccess_add.php +++ b/lib/formfields/customer/extras/formfield.htaccess_add.php @@ -17,7 +17,7 @@ return array( 'htaccess_add' => array( 'title' => $lng['extras']['pathoptions_add'], - 'image' => 'icons/htpasswd_add.png', + 'image' => 'fa-solid fa-folder', 'sections' => array( 'section_a' => array( 'title' => $lng['extras']['pathoptions_add'], diff --git a/lib/formfields/customer/extras/formfield.htaccess_edit.php b/lib/formfields/customer/extras/formfield.htaccess_edit.php index bcf0879e..3f6788cc 100644 --- a/lib/formfields/customer/extras/formfield.htaccess_edit.php +++ b/lib/formfields/customer/extras/formfield.htaccess_edit.php @@ -17,7 +17,7 @@ return array( 'htaccess_edit' => array( 'title' => $lng['extras']['pathoptions_edit'], - 'image' => 'icons/htpasswd_edit.png', + 'image' => 'fa-solid fa-folder', 'sections' => array( 'section_a' => array( 'title' => $lng['extras']['pathoptions_edit'], diff --git a/lib/formfields/customer/extras/formfield.htpasswd_add.php b/lib/formfields/customer/extras/formfield.htpasswd_add.php index 6b4bce20..ab2d674c 100644 --- a/lib/formfields/customer/extras/formfield.htpasswd_add.php +++ b/lib/formfields/customer/extras/formfield.htpasswd_add.php @@ -17,7 +17,7 @@ return array( 'htpasswd_add' => array( 'title' => $lng['extras']['directoryprotection_add'], - 'image' => 'icons/htpasswd_add.png', + 'image' => 'fa-solid fa-lock', 'sections' => array( 'section_a' => array( 'title' => $lng['extras']['directoryprotection_add'], diff --git a/lib/formfields/customer/extras/formfield.htpasswd_edit.php b/lib/formfields/customer/extras/formfield.htpasswd_edit.php index 607ef682..2fe44227 100644 --- a/lib/formfields/customer/extras/formfield.htpasswd_edit.php +++ b/lib/formfields/customer/extras/formfield.htpasswd_edit.php @@ -17,7 +17,7 @@ return array( 'htpasswd_edit' => array( 'title' => $lng['extras']['directoryprotection_edit'], - 'image' => 'icons/htpasswd_edit.png', + 'image' => 'fa-solid fa-lock', 'sections' => array( 'section_a' => array( 'title' => $lng['extras']['directoryprotection_edit'], diff --git a/lib/init.php b/lib/init.php index 5c64f2c6..c82a8320 100644 --- a/lib/init.php +++ b/lib/init.php @@ -362,6 +362,7 @@ if ($nosession == 1 && AREA != 'login') { } UI::twig()->addGlobal('userinfo', ($userinfo ?? [])); +UI::setCurrentUser($userinfo); /** * Logic moved out of lng-file diff --git a/lib/navigation/00.froxlor.main.php b/lib/navigation/00.froxlor.main.php index 6e9ea20e..755d7286 100644 --- a/lib/navigation/00.froxlor.main.php +++ b/lib/navigation/00.froxlor.main.php @@ -83,7 +83,7 @@ return array( 'url' => 'customer_ftp.php', 'label' => $lng['menue']['ftp']['ftp'], 'show_element' => (! \Froxlor\Settings::IsInList('panel.customer_hide_options', 'ftp')), - 'icon' => 'fa fa-transfer', + 'icon' => 'fa fa-users', 'elements' => array( array( 'url' => 'customer_ftp.php?page=accounts', diff --git a/lib/tablelisting/admin/tablelisting.customers.php b/lib/tablelisting/admin/tablelisting.customers.php index 629bf7a4..b431c698 100644 --- a/lib/tablelisting/admin/tablelisting.customers.php +++ b/lib/tablelisting/admin/tablelisting.customers.php @@ -16,81 +16,74 @@ * */ +use Froxlor\UI\Callbacks\Text; use Froxlor\UI\Callbacks\Impersonate; use Froxlor\UI\Callbacks\ProgressBar; use Froxlor\UI\Listing; return [ - 'customer_list' => [ - 'title' => $lng['admin']['customers'], - 'icon' => 'fa-solid fa-user', - 'columns' => [ - 'c.loginname' => [ - 'label' => $lng['login']['username'], - 'column' => 'loginname', - 'format_callback' => [Impersonate::class, 'customer'], - ], - 'a.loginname' => [ - 'label' => $lng['admin']['admin'], - 'column' => 'admin.loginname', - 'format_callback' => [Impersonate::class, 'admin'], - ], - 'c.name' => [ - 'label' => $lng['customer']['name'], - 'column' => 'name', - ], - 'c.email' => [ - 'label' => $lng['customer']['email'], - 'column' => 'email', - ], - 'c.firstname' => [ - 'label' => $lng['customer']['firstname'], - 'column' => 'firstname', - ], - 'c.company' => [ - 'label' => $lng['customer']['company'], - 'column' => 'company', - ], - 'c.diskspace' => [ - 'label' => $lng['customer']['diskspace'], - 'column' => 'diskspace', - 'format_callback' => [ProgressBar::class, 'diskspace'], - ], - 'c.traffic' => [ - 'label' => $lng['customer']['traffic'], - 'column' => 'traffic', - 'format_callback' => [ProgressBar::class, 'traffic'], - ], - ], - 'visible_columns' => Listing::getVisibleColumnsForListing('customer_list', [ - 'c.loginname', - 'a.loginname', - 'c.email', - 'c.firstname', - 'c.company', - 'c.diskspace', - 'c.traffic', - ]), - 'actions' => [ - 'edit' => [ - 'icon' => 'fa fa-edit', - 'href' => [ - 'section' => 'customers', - 'page' => 'customers', - 'action' => 'edit', - 'id' => ':customerid' - ], - ], - 'delete' => [ - 'icon' => 'fa fa-trash', - 'class' => 'text-danger', - 'href' => [ - 'section' => 'customers', - 'page' => 'customers', - 'action' => 'delete', - 'id' => ':customerid' - ], - ], - ], - ] + 'customer_list' => [ + 'title' => $lng['admin']['customers'], + 'icon' => 'fa-solid fa-user', + 'columns' => [ + 'c.name' => [ + 'label' => $lng['customer']['name'], + 'column' => 'name', + 'format_callback' => [Text::class, 'customerfullname'], + ], + 'c.loginname' => [ + 'label' => $lng['login']['username'], + 'column' => 'loginname', + 'format_callback' => [Impersonate::class, 'customer'], + ], + 'a.loginname' => [ + 'label' => $lng['admin']['admin'], + 'column' => 'admin.loginname', + 'format_callback' => [Impersonate::class, 'admin'], + ], + 'c.email' => [ + 'label' => $lng['customer']['email'], + 'column' => 'email', + ], + 'c.diskspace' => [ + 'label' => $lng['customer']['diskspace'], + 'column' => 'diskspace', + 'format_callback' => [ProgressBar::class, 'diskspace'], + ], + 'c.traffic' => [ + 'label' => $lng['customer']['traffic'], + 'column' => 'traffic', + 'format_callback' => [ProgressBar::class, 'traffic'], + ], + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('customer_list', [ + 'c.name', + 'c.loginname', + 'a.loginname', + 'c.email', + 'c.diskspace', + 'c.traffic', + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'customers', + 'page' => 'customers', + 'action' => 'edit', + 'id' => ':customerid' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'customers', + 'page' => 'customers', + 'action' => 'delete', + 'id' => ':customerid' + ], + ], + ], + ] ]; diff --git a/lib/tablelisting/admin/tablelisting.domains.php b/lib/tablelisting/admin/tablelisting.domains.php index 602df146..42001055 100644 --- a/lib/tablelisting/admin/tablelisting.domains.php +++ b/lib/tablelisting/admin/tablelisting.domains.php @@ -16,86 +16,76 @@ * */ +use Froxlor\UI\Callbacks\Text; use Froxlor\UI\Callbacks\Impersonate; use Froxlor\UI\Listing; return [ - 'domain_list' => [ - 'title' => $lng['admin']['domains'], - 'icon' => 'fa-solid fa-user', - 'columns' => [ - 'd.domain_ace' => [ - 'label' => $lng['domains']['domainname'], - 'column' => 'domain_ace', - 'sortable' => true, - ], - 'c.name' => [ - 'label' => $lng['customer']['name'], - 'column' => 'customer.name', - ], - 'c.firstname' => [ - 'label' => $lng['customer']['firstname'], - 'column' => 'customer.firstname', - ], - 'c.company' => [ - 'label' => $lng['customer']['company'], - 'column' => 'customer.company', - ], - 'c.loginname' => [ - 'label' => $lng['login']['username'], - 'column' => 'customer.loginname', - 'format_callback' => [Impersonate::class, 'customer'], - 'sortable' => true, - ], - 'd.aliasdomain' => [ - 'label' => $lng['domains']['aliasdomain'], - 'column' => 'aliasdomain', - ], - ], - 'visible_columns' => Listing::getVisibleColumnsForListing('domain_list', [ - 'd.domain_ace', - 'c.name', - 'c.firstname', - 'c.company', - 'c.loginname', - 'd.aliasdomain', - ]), - 'actions' => [ - 'edit' => [ - 'icon' => 'fa fa-edit', - 'href' => [ - 'section' => 'domains', - 'page' => 'domains', - 'action' => 'edit', - 'id' => ':id' - ], - ], - 'logfiles' => [ - 'icon' => 'fa fa-file', - 'href' => [ - 'section' => 'domains', - 'page' => 'logfiles', - 'domain_id' => ':id' - ], - ], - 'domaindnseditor' => [ - 'icon' => 'fa fa-globe', - 'href' => [ - 'section' => 'domains', - 'page' => 'domaindnseditor', - 'domain_id' => ':id' - ], - ], - 'delete' => [ - 'icon' => 'fa fa-trash', - 'class' => 'text-danger', - 'href' => [ - 'section' => 'domains', - 'page' => 'domains', - 'action' => 'delete', - 'id' => ':id' - ], - ], - ] - ] + 'domain_list' => [ + 'title' => $lng['admin']['domains'], + 'icon' => 'fa-solid fa-user', + 'columns' => [ + 'd.domain_ace' => [ + 'label' => $lng['domains']['domainname'], + 'column' => 'domain_ace', + ], + 'c.name' => [ + 'label' => $lng['customer']['name'], + 'column' => 'customer.name', + 'format_callback' => [Text::class, 'customerfullname'], + ], + 'c.loginname' => [ + 'label' => $lng['login']['username'], + 'column' => 'customer.loginname', + 'format_callback' => [Impersonate::class, 'customer'], + ], + 'd.aliasdomain' => [ + 'label' => $lng['domains']['aliasdomain'], + 'column' => 'aliasdomain', + ], + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('domain_list', [ + 'd.domain_ace', + 'c.name', + 'c.loginname', + 'd.aliasdomain', + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'domains', + 'page' => 'domains', + 'action' => 'edit', + 'id' => ':id' + ], + ], + 'logfiles' => [ + 'icon' => 'fa fa-file', + 'href' => [ + 'section' => 'domains', + 'page' => 'logfiles', + 'domain_id' => ':id' + ], + ], + 'domaindnseditor' => [ + 'icon' => 'fa fa-globe', + 'href' => [ + 'section' => 'domains', + 'page' => 'domaindnseditor', + 'domain_id' => ':id' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'domains', + 'page' => 'domains', + 'action' => 'delete', + 'id' => ':id' + ], + ] + ] + ] ]; diff --git a/lib/tablelisting/admin/tablelisting.plans.php b/lib/tablelisting/admin/tablelisting.plans.php index 88d5a7c4..d365bd67 100644 --- a/lib/tablelisting/admin/tablelisting.plans.php +++ b/lib/tablelisting/admin/tablelisting.plans.php @@ -21,7 +21,7 @@ use Froxlor\UI\Listing; return [ 'plan_list' => [ - 'title' => $lng['domains']['ssl_certificates'], + 'title' => $lng['admin']['plans']['plans'], 'icon' => 'fa-solid fa-user', 'columns' => [ 'p.name' => [ diff --git a/lib/tablelisting/customer/tablelisting.domains.php b/lib/tablelisting/customer/tablelisting.domains.php new file mode 100644 index 00000000..84ba85f5 --- /dev/null +++ b/lib/tablelisting/customer/tablelisting.domains.php @@ -0,0 +1,79 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Tabellisting + * + */ + +use Froxlor\UI\Callbacks\Domain; +use Froxlor\UI\Listing; + +return [ + 'domain_list' => [ + 'title' => $lng['admin']['domains'], + 'icon' => 'fa-solid fa-user', + 'columns' => [ + 'd.domain_ace' => [ + 'label' => $lng['domains']['domainname'], + 'column' => 'domain_ace', + ], + 'd.documentroot' => [ + 'label' => $lng['panel']['path'], + 'column' => 'documentroot', + 'format_callback' => [Domain::class, 'domainTarget'], + ] + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('domain_list', [ + 'd.domain_ace', + 'd.documentroot' + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'domains', + 'page' => 'domains', + 'action' => 'edit', + 'id' => ':id' + ], + ], + 'logfiles' => [ + 'icon' => 'fa fa-file', + 'href' => [ + 'section' => 'domains', + 'page' => 'logfiles', + 'domain_id' => ':id' + ], + ], + 'domaindnseditor' => [ + 'icon' => 'fa fa-globe', + 'href' => [ + 'section' => 'domains', + 'page' => 'domaindnseditor', + 'domain_id' => ':id' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'domains', + 'page' => 'domains', + 'action' => 'delete', + 'id' => ':id' + ], + ] + ] + ] +]; diff --git a/lib/tablelisting/customer/tablelisting.emails.php b/lib/tablelisting/customer/tablelisting.emails.php new file mode 100644 index 00000000..b4f79cae --- /dev/null +++ b/lib/tablelisting/customer/tablelisting.emails.php @@ -0,0 +1,83 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Tabellisting + * + */ + +use Froxlor\UI\Callbacks\Email; +use Froxlor\UI\Callbacks\Text; +use Froxlor\UI\Listing; + +return [ + 'email_list' => [ + 'title' => $lng['menue']['email']['emails'], + 'icon' => 'fa-solid fa-envelope', + 'columns' => [ + 'm.email_full' => [ + 'label' => $lng['emails']['emailaddress'], + 'column' => 'email_full', + ], + 'm.destination' => [ + 'label' => $lng['emails']['forwarders'], + 'column' => 'destination', + // @todo formatting + ], + 'm.popaccountid' => [ + 'label' => $lng['emails']['account'], + 'column' => 'popaccountid', + 'format_callback' => [Email::class, 'account'], + ], + 'm.iscatchall' => [ + 'label' => $lng['emails']['catchall'], + 'column' => 'iscatchall', + 'format_callback' => [Text::class, 'boolean'], + 'visible' => \Froxlor\Settings::Get('catchall.catchall_enabled') == '1' + ], + 'm.quota' => [ + 'label' => $lng['emails']['quota'], + 'column' => 'quota', + 'visible' => \Froxlor\Settings::Get('system.mail_quota_enabled') == '1' + ] + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('email_list', [ + 'm.email_full', + 'm.destination', + 'm.popaccountid', + 'm.iscatchall', + 'm.quota' + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'email', + 'page' => 'emails', + 'action' => 'edit', + 'id' => ':id' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'email', + 'page' => 'emails', + 'action' => 'delete', + 'id' => ':id' + ], + ] + ] + ] +]; diff --git a/lib/tablelisting/customer/tablelisting.ftps.php b/lib/tablelisting/customer/tablelisting.ftps.php new file mode 100644 index 00000000..ce338c49 --- /dev/null +++ b/lib/tablelisting/customer/tablelisting.ftps.php @@ -0,0 +1,74 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Tabellisting + * + */ + +use Froxlor\UI\Callbacks\Ftp; +use Froxlor\UI\Listing; + +return [ + 'ftp_list' => [ + 'title' => $lng['menue']['ftp']['accounts'], + 'icon' => 'fa-solid fa-users', + 'columns' => [ + 'username' => [ + 'label' => $lng['login']['username'], + 'column' => 'username', + ], + 'description' => [ + 'label' => $lng['panel']['ftpdesc'], + 'column' => 'description' + ], + 'homedir' => [ + 'label' => $lng['panel']['path'], + 'column' => 'homedir', + 'format_callback' => [Ftp::class, 'pathRelative'] + ], + 'shell' => [ + 'label' => $lng['panel']['shell'], + 'column' => 'shell', + 'visible' => \Froxlor\Settings::Get('system.allow_customer_shell') == '1' + ] + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('ftp_list', [ + 'username', + 'description', + 'homedir', + 'shell' + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'ftp', + 'page' => 'ftps', + 'action' => 'edit', + 'id' => ':id' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'ftp', + 'page' => 'ftps', + 'action' => 'delete', + 'id' => ':id' + ], + ] + ] + ] +]; diff --git a/lib/tablelisting/customer/tablelisting.htaccess.php b/lib/tablelisting/customer/tablelisting.htaccess.php new file mode 100644 index 00000000..eab4b7ab --- /dev/null +++ b/lib/tablelisting/customer/tablelisting.htaccess.php @@ -0,0 +1,87 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Tabellisting + * + */ + +use Froxlor\UI\Callbacks\Ftp; +use Froxlor\UI\Callbacks\Text; +use Froxlor\UI\Listing; + +return [ + 'htaccess_list' => [ + 'title' => $lng['menue']['extras']['pathoptions'], + 'icon' => 'fa-solid fa-folder', + 'columns' => [ + 'path' => [ + 'label' => $lng['panel']['path'], + 'column' => 'path', + 'format_callback' => [Ftp::class, 'pathRelative'] + ], + 'option_indexes' => [ + 'label' => $lng['extras']['view_directory'], + 'column' => 'option_indexes', + 'format_callback' => [Text::class, 'boolean'] + ], + 'error404path' => [ + 'label' => $lng['extras']['error404path'], + 'column' => 'error404path' + ], + 'error403path' => [ + 'label' => $lng['extras']['error403path'], + 'column' => 'error403path' + ], + 'error500path' => [ + 'label' => $lng['extras']['error500path'], + 'column' => 'error500path' + ], + 'options_cgi' => [ + 'label' => $lng['extras']['execute_perl'], + 'column' => 'options_cgi', + 'format_callback' => [Text::class, 'boolean'], + 'visible' => $cperlenabled + ] + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('htaccess_list', [ + 'path', + 'option_indexes', + 'error404path', + 'error403path', + 'error500path', + 'options_cgi' + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'extras', + 'page' => 'htaccess', + 'action' => 'edit', + 'id' => ':id' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'extras', + 'page' => 'htaccess', + 'action' => 'delete', + 'id' => ':id' + ], + ] + ] + ] +]; diff --git a/lib/tablelisting/customer/tablelisting.htpasswd.php b/lib/tablelisting/customer/tablelisting.htpasswd.php new file mode 100644 index 00000000..7d2f1c66 --- /dev/null +++ b/lib/tablelisting/customer/tablelisting.htpasswd.php @@ -0,0 +1,63 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Tabellisting + * + */ + +use Froxlor\UI\Callbacks\Ftp; +use Froxlor\UI\Listing; + +return [ + 'htpasswd_list' => [ + 'title' => $lng['menue']['extras']['directoryprotection'], + 'icon' => 'fa-solid fa-lock', + 'columns' => [ + 'username' => [ + 'label' => $lng['login']['username'], + 'column' => 'username' + ], + 'path' => [ + 'label' => $lng['panel']['path'], + 'column' => 'path', + 'format_callback' => [Ftp::class, 'pathRelative'] + ] + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('htpasswd_list', [ + 'username', + 'path' + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'extras', + 'page' => 'htpasswds', + 'action' => 'edit', + 'id' => ':id' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'extras', + 'page' => 'htpasswds', + 'action' => 'delete', + 'id' => ':id' + ], + ] + ] + ] +]; diff --git a/lib/tablelisting/customer/tablelisting.mysqls.php b/lib/tablelisting/customer/tablelisting.mysqls.php new file mode 100644 index 00000000..488037e5 --- /dev/null +++ b/lib/tablelisting/customer/tablelisting.mysqls.php @@ -0,0 +1,76 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Tabellisting + * + */ + +use Froxlor\UI\Callbacks\Mysql; +use Froxlor\UI\Callbacks\Text; +use Froxlor\UI\Listing; + +return [ + 'mysql_list' => [ + 'title' => $lng['menue']['mysql']['databases'], + 'icon' => 'fa-solid fa-database', + 'columns' => [ + 'databasename' => [ + 'label' => $lng['mysql']['databasename'], + 'column' => 'databasename', + ], + 'description' => [ + 'label' => $lng['mysql']['databasedescription'], + 'column' => 'description' + ], + 'size' => [ + 'label' => $lng['mysql']['size'], + 'column' => 'size', + 'format_callback' => [Text::class, 'size'] + ], + 'dbserver' => [ + 'label' => $lng['mysql']['mysql_server'], + 'column' => 'dbserver', + 'format_callback' => [Mysql::class, 'dbserver'], + 'visible' => $count_mysqlservers > 1 + ] + ], + 'visible_columns' => Listing::getVisibleColumnsForListing('mysql_list', [ + 'databasename', + 'description', + 'size', + 'dbserver' + ]), + 'actions' => [ + 'edit' => [ + 'icon' => 'fa fa-edit', + 'href' => [ + 'section' => 'mysql', + 'page' => 'mysqls', + 'action' => 'edit', + 'id' => ':id' + ], + ], + 'delete' => [ + 'icon' => 'fa fa-trash', + 'class' => 'text-danger', + 'href' => [ + 'section' => 'mysql', + 'page' => 'mysqls', + 'action' => 'delete', + 'id' => ':id' + ], + ] + ] + ] +]; diff --git a/lng/english.lng.php b/lng/english.lng.php index 71eed37c..ecec69dc 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -1893,8 +1893,8 @@ $lng['crondesc']['cron_backup'] = 'Process backup jobs'; $lng['error']['backupfunctionnotenabled'] = 'The backup function is not enabled'; $lng['serversettings']['backupenabled']['title'] = "Enable backup for customers"; $lng['serversettings']['backupenabled']['description'] = "If activated, the customer will be able to schedule backup jobs (cron-backup) which generates an archive within his docroot (subdirectory chosable by customer)"; -$lng['extras']['path_protection_label'] = 'Important'; -$lng['extras']['path_protection_info'] = 'We strongly recommend protecting the given path, see "Extras" -> "Directory protection"'; +$lng['extras']['path_protection_label'] = 'Important'; +$lng['extras']['path_protection_info'] = 'We strongly recommend protecting the given path, see "Extras" -> "Directory protection"'; $lng['tasks']['CREATE_CUSTOMER_BACKUP'] = 'Backup job for customer %loginname%'; $lng['error']['dns_domain_nodns'] = 'DNS is not enabled for this domain'; diff --git a/lng/german.lng.php b/lng/german.lng.php index badb40e6..286585d0 100644 --- a/lng/german.lng.php +++ b/lng/german.lng.php @@ -1543,8 +1543,8 @@ $lng['crondesc']['cron_backup'] = 'Ausstehende Sicherungen erstellen'; $lng['error']['backupfunctionnotenabled'] = 'Die Sicherungs-Funktion is nicht aktiviert'; $lng['serversettings']['backupenabled']['title'] = "Backup für Kunden aktivieren"; $lng['serversettings']['backupenabled']['description'] = "Wenn dies aktiviert ist, kann der Kunde Sicherungen planen (cron-backup) welche ein Archiv in sein Heimatverzeichnis ablegt (Unterordner vom Kunden wählbar)"; -$lng['extras']['path_protection_label'] = 'Wichtig'; -$lng['extras']['path_protection_info'] = 'Wir raten dringend dazu den angegebenen Pfad zu schützen, siehe "Extras" -> "Verzeichnisschutz"'; +$lng['extras']['path_protection_label'] = 'Wichtig'; +$lng['extras']['path_protection_info'] = 'Wir raten dringend dazu den angegebenen Pfad zu schützen, siehe "Extras" -> "Verzeichnisschutz"'; $lng['tasks']['CREATE_CUSTOMER_BACKUP'] = 'Datensicherung für Kunde %loginname%'; $lng['error']['dns_domain_nodns'] = 'DNS ist für diese Domain nicht aktiviert'; diff --git a/logfiles_viewer.php b/logfiles_viewer.php index f943b9e1..63207132 100644 --- a/logfiles_viewer.php +++ b/logfiles_viewer.php @@ -19,15 +19,13 @@ if (! defined('AREA')) { * */ -use Froxlor\Api\Commands\SubDomains as SubDomains; +use Froxlor\Api\Commands\SubDomains; use Froxlor\Settings; use Froxlor\UI\Request; // This file is being included in admin_domains and customer_domains // and therefore does not need to require lib/init.php -// TODO get domain related settings for logfile (speciallogfile) - $domain_id = (int) Request::get('domain_id'); $last_n = (int) Request::get('number_of_lines', 100); diff --git a/templates/Froxlor/form/formfields.html.twig b/templates/Froxlor/form/formfields.html.twig index 1304ef99..2d6d341e 100644 --- a/templates/Froxlor/form/formfields.html.twig +++ b/templates/Froxlor/form/formfields.html.twig @@ -6,7 +6,7 @@ {% if field.desc is defined and field.desc is not empty %}
{{ field.desc|raw }} {% endif %} -
+
{% endif %} {% if field.type == 'text' or field.type == 'password' or field.type == 'number' or field.type == 'file' or field.type == 'email' or field.type == 'hidden' %} {{ _self.input(id, field) }} @@ -24,6 +24,8 @@ {{ _self.link(id, field) }} {% elseif field.type == 'itemlist' %} {{ _self.itemlist(id, field) }} + {% elseif field.type == 'infotext' %} + {{ _self.infotext(id, field) }} {% endif %} {% if norow == false and field.type != 'hidden' %}
@@ -49,11 +51,27 @@ {% endif %} {% endmacro %} +{% macro infotext(id, field) %} + {% if field.next_to is defined %} +
+ {% endif %} + {{ field.value }} + {% if field.next_to is defined %} + {% for nid, nfield in field.next_to %} + {% if nfield.next_to_prefix is defined %} + {{ nfield.next_to_prefix }} + {% endif %} + {{ _self.fieldrow(nid, nfield, true) }} + {% endfor %} +
+ {% endif %} +{% endmacro %} + {% macro plain(id, field) %} {% if field.next_to is defined %}
{% endif %} - + {% if field.next_to is defined %} {% for nid, nfield in field.next_to %} {% if nfield.next_to_prefix is defined %} @@ -74,7 +92,7 @@ {% endif %} {% if field.note is defined and field.note is not empty %} -
{{ field.note|raw }}
+
{{ field.note|raw }}
{% endif %} {% if field.next_to is defined %} {% for nid, nfield in field.next_to %} diff --git a/templates/Froxlor/table/callbacks.html.twig b/templates/Froxlor/table/callbacks.html.twig index 0258ad1d..421bba1e 100644 --- a/templates/Froxlor/table/callbacks.html.twig +++ b/templates/Froxlor/table/callbacks.html.twig @@ -18,6 +18,17 @@ {% endif %} {% endmacro %} +{% macro booleanWithInfo(data) %} + {% if (data.checked) %} + + {% else %} + + {% endif %} + {% if data.info is not empty %} + {{ data.info }} + {% endif %} +{% endmacro %} + {% macro link(data) %} {% apply spaceless %} diff --git a/templates/Froxlor/table/table.html.twig b/templates/Froxlor/table/table.html.twig index 8a79212b..fc6a2364 100644 --- a/templates/Froxlor/table/table.html.twig +++ b/templates/Froxlor/table/table.html.twig @@ -32,6 +32,8 @@ {{ callbacks.progressbar(td.data.data) }} {% elseif td.data.type == 'boolean' %} {{ callbacks.boolean(td.data.data) }} + {% elseif td.data.type == 'booleanWithInfo' %} + {{ callbacks.booleanWithInfo(td.data.data) }} {% elseif td.data.type == 'link' %} {{ callbacks.link(td.data.data) }} {% elseif td.data.type == 'domainWithSan' %} diff --git a/templates/Froxlor/user/table.html.twig b/templates/Froxlor/user/table.html.twig index 334b786f..40abea6e 100644 --- a/templates/Froxlor/user/table.html.twig +++ b/templates/Froxlor/user/table.html.twig @@ -1,9 +1,26 @@ {% extends "Froxlor/userarea.html.twig" %} {% block content %} - - {% import "Froxlor/table/table.html.twig" as table %} - - {{ table.table(listing) }} - + {% endblock %} diff --git a/templates/Froxlor/userarea.html.twig b/templates/Froxlor/userarea.html.twig index 9f77c761..617d9945 100644 --- a/templates/Froxlor/userarea.html.twig +++ b/templates/Froxlor/userarea.html.twig @@ -43,7 +43,7 @@