enhanced listing actions

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2022-02-28 09:21:04 +01:00
parent 2b771b11d6
commit 5b961be0f8
21 changed files with 279 additions and 135 deletions

View File

@@ -20,7 +20,7 @@
const AREA = 'admin';
require __DIR__ . '/lib/init.php';
use Froxlor\Api\Commands\Admins as Admins;
use Froxlor\Api\Commands\Admins;
use Froxlor\Database\Database;
use Froxlor\Settings;
use Froxlor\UI\Panel\UI;

View File

@@ -19,6 +19,7 @@ const AREA = 'admin';
require __DIR__ . '/lib/init.php';
use Froxlor\Api\Commands\Cronjobs;
use Froxlor\UI\Panel\UI;
use Froxlor\UI\Request;
$id = (int) Request::get('id');
@@ -27,51 +28,18 @@ if ($page == 'cronjobs' || $page == 'overview') {
if ($action == '') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed admin_cronjobs');
$fields = array(
'c.module' => 'Module',
'c.lastrun' => $lng['cron']['lastrun'],
'c.interval' => $lng['cron']['interval'],
'c.isactive' => $lng['cron']['isactive']
);
try {
// get total count
$json_result = Cronjobs::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 = Cronjobs::getLocal($userinfo, $paging->getApiCommandParams())->listing();
$cron_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/admin/tablelisting.cronjobs.php';
$collection = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Cronjobs::class, $userinfo))
->withPagination($cron_list_data['cron_list']['columns']);
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$crons = '';
$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;
$cmod = '';
foreach ($result['list'] as $row) {
if ($cmod != $row['module']) {
$_mod = explode("/", $row['module']);
$module = ucfirst($_mod[1]);
eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjobmodule') . "\";");
$cmod = $row['module'];
}
$row = \Froxlor\PhpHelper::htmlentitiesArray($row);
$row['lastrun'] = date('d.m.Y H:i', $row['lastrun']);
$row['isactive'] = ((int) $row['isactive'] == 1) ? $lng['panel']['yes'] : $lng['panel']['no'];
$description = $lng['crondesc'][$row['desc_lng_key']];
eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjob') . "\";");
$count ++;
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs') . "\";");
UI::twigBuffer('user/table.html.twig', [
'listing' => \Froxlor\UI\Listing::format($collection, $cron_list_data['cron_list']),
]);
UI::twigOutputBuffer();
} elseif ($action == 'new') {
/*
* @TODO later

View File

@@ -0,0 +1,28 @@
<?php
namespace Froxlor\UI\Callbacks;
use Froxlor\Settings;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Froxlor\UI\Callbacks
*
*/
class Customer
{
public static function isLocked(array $attributes)
{
return $attributes['fields']['loginfail_count'] >= Settings::Get('login.maxloginattempts')
&& $attributes['fields']['lastlogin_fail'] > (time() - Settings::Get('login.deactivatetime'));
}
}

View File

@@ -62,6 +62,13 @@ class Domain
&& empty($attributes['fields']['domainaliasid']);
}
public static function adminCanDelete(array $attributes): bool
{
return $attributes['fields']['id'] != Settings::Get('system.hostname_id')
&& empty($attributes['fields']['domainaliasid'])
&& $attributes['fields']['standardsubdomain'] != $attributes['fields']['id'];
}
public static function canEditDNS(array $attributes): bool
{
return $attributes['fields']['isbinddomain'] == '1'
@@ -71,6 +78,13 @@ class Domain
&& Settings::Get('system.dnsenabled') == '1';
}
public static function adminCanEditDNS(array $attributes): bool
{
return $attributes['fields']['isbinddomain'] == '1'
&& Settings::Get('system.bind_enable') == '1'
&& Settings::Get('system.dnsenabled') == '1';
}
public function canEditSSL(array $attributes): bool
{
// FIXME: https://github.com/Froxlor/Froxlor/blob/master/templates/Sparkle/customer/domains/domains_domain.tpl#L41

View File

@@ -41,4 +41,14 @@ class Text
{
return PhpHelper::sizeReadable($attributes['data'], null, 'bi');
}
public static function timestamp(array $attributes): string
{
return (int)$attributes['data'] > 0 ? date('d.m.Y H:i', (int)$attributes['data']) : UI::getLng('panel.never');
}
public static function crondesc(array $attributes): string
{
return UI::getLng('crondesc.' . $attributes['data']);
}
}

View File

@@ -3,6 +3,7 @@
namespace Froxlor\UI;
use Froxlor\UI\Panel\UI;
use Exception;
/**
* This file is part of the Froxlor project.
@@ -77,7 +78,10 @@ class Listing
}
$format_callback = $tabellisting['columns'][$visible_column]['format_callback'] ?? null;
$column = $tabellisting['columns'][$visible_column]['field'];
$column = $tabellisting['columns'][$visible_column]['field'] ?? null;
if (empty($column)) {
throw new Exception('Column in "visible columns" specified that is not defined in "fields"');
}
$data = self::getMultiArrayFromString($item, $column);
if ($format_callback) {

View File

@@ -73,6 +73,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'admins',
'page' => 'admins',
@@ -82,6 +83,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'admins',

View File

@@ -0,0 +1,65 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Tabellisting
*
*/
use Froxlor\UI\Callbacks\Text;
use Froxlor\UI\Listing;
return [
'cron_list' => [
'title' => $lng['admin']['cron']['cronsettings'],
'icon' => 'fa-solid fa-clock-rotate-left',
'columns' => [
'c.description' => [
'label' => $lng['cron']['description'],
'field' => 'desc_lng_key',
'format_callback' => [Text::class, 'crondesc']
],
'c.lastrun' => [
'label' => $lng['cron']['lastrun'],
'field' => 'lastrun',
'format_callback' => [Text::class, 'timestamp']
],
'c.interval' => [
'label' => $lng['cron']['interval'],
'field' => 'interval'
],
'c.isactive' => [
'label' => $lng['cron']['isactive'],
'field' => 'isactive',
'format_callback' => [Text::class, 'boolean']
],
],
'visible_columns' => Listing::getVisibleColumnsForListing('cron_list', [
'c.description',
'c.lastrun',
'c.interval',
'c.isactive',
]),
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'cronjobs',
'page' => 'overview',
'action' => 'edit',
'id' => ':id'
],
]
]
]
];

View File

@@ -16,6 +16,7 @@
*
*/
use Froxlor\UI\Callbacks\Customer;
use Froxlor\UI\Callbacks\Text;
use Froxlor\UI\Callbacks\Impersonate;
use Froxlor\UI\Callbacks\ProgressBar;
@@ -65,8 +66,21 @@ return [
'c.traffic',
]),
'actions' => [
'unlock' => [
'icon' => 'fa fa-unlock',
'title' => $lng['panel']['unlock'],
'class' => 'text-warning',
'href' => [
'section' => 'customers',
'page' => 'customers',
'action' => 'unlock',
'id' => ':customerid'
],
'visible' => [Customer::class, 'isLocked']
],
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'customers',
'page' => 'customers',
@@ -76,6 +90,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'customers',

View File

@@ -16,6 +16,7 @@
*
*/
use Froxlor\UI\Callbacks\Domain;
use Froxlor\UI\Callbacks\Text;
use Froxlor\UI\Callbacks\Impersonate;
use Froxlor\UI\Listing;
@@ -54,6 +55,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'domains',
'page' => 'domains',
@@ -63,6 +65,7 @@ return [
],
'logfiles' => [
'icon' => 'fa fa-file',
'title' => $lng['panel']['viewlogs'],
'href' => [
'section' => 'domains',
'page' => 'logfiles',
@@ -71,14 +74,22 @@ return [
],
'domaindnseditor' => [
'icon' => 'fa fa-globe',
'title' => $lng['dnseditor']['edit'],
'href' => [
'section' => 'domains',
'page' => 'domaindnseditor',
'domain_id' => ':id'
],
'visible' => [Domain::class, 'adminCanEditDNS']
],
'letsencrypt' => [
'icon' => 'fa fa-shield',
'title' => $lng['panel']['letsencrypt'],
'visible' => ':letsencrypt' // @fixme
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'domains',
@@ -86,6 +97,7 @@ return [
'action' => 'delete',
'id' => ':id'
],
'visible' => [Domain::class, 'adminCanDelete']
]
]
]

View File

@@ -87,6 +87,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'ipsandports',
'page' => 'ipsandports',
@@ -96,6 +97,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'ipsandports',

View File

@@ -16,7 +16,7 @@
*
*/
use Froxlor\Settings;
use Froxlor\UI\Callbacks\Text;
use Froxlor\UI\Listing;
return [
@@ -39,9 +39,10 @@ return [
'p.ts' => [
'label' => $lng['admin']['plans']['last_update'],
'field' => 'ts',
'format_callback' => [Text::class, 'timestamp'],
],
],
'visible_columns' => Listing::getVisibleColumnsForListing('sslcertificates_list', [
'visible_columns' => Listing::getVisibleColumnsForListing('plan_list', [
'p.name',
'p.description',
'p.adminname',
@@ -50,6 +51,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'plans',
'page' => 'overview',
@@ -59,6 +61,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'plans',

View File

@@ -66,6 +66,7 @@ return [
'actions' => [
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'domains',

View File

@@ -41,6 +41,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'domains',
'page' => 'domains',
@@ -51,6 +52,7 @@ return [
],
'logfiles' => [
'icon' => 'fa fa-file',
'title' => $lng['panel']['viewlogs'],
'href' => [
'section' => 'domains',
'page' => 'logfiles',
@@ -60,6 +62,7 @@ return [
],
'domaindnseditor' => [
'icon' => 'fa fa-globe',
'title' => $lng['dnseditor']['edit'],
'href' => [
'section' => 'domains',
'page' => 'domaindnseditor',
@@ -67,8 +70,14 @@ return [
],
'visible' => [Domain::class, 'canEditDNS']
],
'letsencrypt' => [
'icon' => 'fa fa-shield',
'title' => $lng['panel']['letsencrypt'],
'visible' => ':letsencrypt' // @fixme
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'domains',

View File

@@ -62,6 +62,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'email',
'page' => 'emails',
@@ -71,6 +72,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'email',

View File

@@ -52,6 +52,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'ftp',
'page' => 'ftps',
@@ -61,6 +62,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'ftp',

View File

@@ -65,6 +65,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'extras',
'page' => 'htaccess',
@@ -74,6 +75,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'extras',

View File

@@ -41,6 +41,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'extras',
'page' => 'htpasswds',
@@ -50,6 +51,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'extras',

View File

@@ -54,6 +54,7 @@ return [
'actions' => [
'edit' => [
'icon' => 'fa fa-edit',
'title' => $lng['panel']['edit'],
'href' => [
'section' => 'mysql',
'page' => 'mysqls',
@@ -63,6 +64,7 @@ return [
],
'delete' => [
'icon' => 'fa fa-trash',
'title' => $lng['panel']['delete'],
'class' => 'text-danger',
'href' => [
'section' => 'mysql',

View File

@@ -31,7 +31,7 @@
{% macro link(data) %}
{% apply spaceless %}
<a href="{{ data.href }}" {% if data.class is defined %}class="{{ data.class }}"{% endif %} {% if data.target is defined %}target="{{ data.target }}"{% endif %}>
<a href="{{ data.href }}" {% if data.class is defined %} class="{{ data.class }}" {% endif %} {% if data.target is defined %} target="{{ data.target }}" {% endif %}{% if data.title is defined %} title="{{ data.title }}" {% endif %}>
{% if data.icon is defined %}
<i class="{{ data.icon }}"></i>
{% endif %}
@@ -45,7 +45,8 @@
{% macro domainWithSan(data) %}
{{ data.domain }}
{% if data.san is not empty %}
<br /><span class="small">SAN: {{ data.san }}</span>
<br/><span class="small">SAN:
{{ data.san }}</span>
{% endif %}
{% endmacro %}

View File

@@ -7,7 +7,7 @@
{% if listing.title is not empty %}
<h3 class="page-header">
{% if listing.icon is not empty %}
<i class="{{ listing.icon }}"></i>
<i class="{{ listing.icon }} me-1"></i>
{% endif %}
{{ listing.title }}
</h3>