From 8f7876b850dc91e58dc623c2f7f622474c621ea8 Mon Sep 17 00:00:00 2001 From: envoyr Date: Tue, 22 Feb 2022 19:07:04 +0100 Subject: [PATCH] update table listing and add callbacks --- admin_admins.php | 3 +- admin_customers.php | 96 +------------------ admin_domains.php | 3 +- lib/Froxlor/UI/Callbacks/Number.php | 50 ++++++++++ lib/Froxlor/UI/Callbacks/ProgressBar.php | 50 ++++++++++ lib/Froxlor/UI/Callbacks/Text.php | 25 +++++ lib/Froxlor/UI/Collection.php | 2 +- lib/Froxlor/UI/Listing.php | 43 +++++++++ .../admin/admin/tablelisting.admin.php | 10 +- .../admin/admin/tablelisting.customer.php | 8 +- templates/Froxlor/table/table.html.twig | 36 ++----- templates/Froxlor/table/tablemacros.html.twig | 53 ---------- templates/Froxlor/user/table.html.twig | 2 +- 13 files changed, 189 insertions(+), 192 deletions(-) create mode 100644 lib/Froxlor/UI/Callbacks/Number.php create mode 100644 lib/Froxlor/UI/Callbacks/ProgressBar.php create mode 100644 lib/Froxlor/UI/Callbacks/Text.php delete mode 100644 templates/Froxlor/table/tablemacros.html.twig diff --git a/admin_admins.php b/admin_admins.php index 5f3fab75..0f51bf02 100644 --- a/admin_admins.php +++ b/admin_admins.php @@ -103,8 +103,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { */ UI::twigBuffer('user/table.html.twig', [ - 'collection' => $collection->getData(), - 'table_options' => $admin_list_data['admin_list'], + 'listing' => \Froxlor\UI\Listing::format($collection, $admin_list_data['admin_list']), ]); UI::twigOutputBuffer(); } elseif ($action == 'su') { diff --git a/admin_customers.php b/admin_customers.php index 6b01d8ea..ac5245f4 100644 --- a/admin_customers.php +++ b/admin_customers.php @@ -44,103 +44,9 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - /* - $result = json_decode($json_result, true)['data']; - - $customers = ''; - $sortcode = $paging->getHtmlSortCode($lng, true); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $count = 0; - - foreach ($result['list'] as $row) { - - $domains_stmt = Database::prepare(" - SELECT COUNT(`id`) AS `domains` - FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `customerid` = :cid - AND `parentdomainid` = '0' - AND `id`<> :stdd - "); - Database::pexecute($domains_stmt, array( - 'cid' => $row['customerid'], - 'stdd' => $row['standardsubdomain'] - )); - $domains = $domains_stmt->fetch(PDO::FETCH_ASSOC); - $row['domains'] = intval($domains['domains']); - $dec_places = Settings::Get('panel.decimal_places'); - - // get disk-space usages for web, mysql and mail - $usages_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "` - WHERE `customerid` = :cid - ORDER BY `stamp` DESC LIMIT 1 - "); - $usages = Database::pexecute_first($usages_stmt, array( - 'cid' => $row['customerid'] - )); - - if ($usages) { - $row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places); - $row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places); - $row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places); - } else { - $row['webspace_used'] = 0; - $row['mailspace_used'] = 0; - $row['dbspace_used'] = 0; - } - $row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places); - $row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places); - $row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places); - $row['diskspace'] = round($row['diskspace'] / 1024, $dec_places); - $last_login = ((int) $row['lastlogin_succ'] == 0) ? $lng['panel']['neverloggedin'] : date('d.m.Y', $row['lastlogin_succ']); - - // percent-values for progressbar - if ($row['diskspace'] > 0) { - $disk_percent = round(($row['diskspace_used'] * 100) / $row['diskspace'], 0); - $disk_doublepercent = round($disk_percent * 2, 2); - } else { - $disk_percent = 0; - $disk_doublepercent = 0; - } - if ($row['traffic'] > 0) { - $traffic_percent = round(($row['traffic_used'] * 100) / $row['traffic'], 0); - $traffic_doublepercent = round($traffic_percent * 2, 2); - } else { - $traffic_percent = 0; - $traffic_doublepercent = 0; - } - - $islocked = 0; - if ($row['loginfail_count'] >= Settings::Get('login.maxloginattempts') && $row['lastlogin_fail'] > (time() - Settings::Get('login.deactivatetime'))) { - $islocked = 1; - } - - $row = \Froxlor\PhpHelper::strReplaceArray('-1', 'UL', $row, 'diskspace traffic mysqls emails email_accounts email_forwarders ftps subdomains'); - $row = \Froxlor\PhpHelper::htmlentitiesArray($row); - - // fix progress-bars if value is >100% - if ($disk_percent > 100) { - $disk_percent = 100; - } - if ($traffic_percent > 100) { - $traffic_percent = 100; - } - - $row['custom_notes'] = ($row['custom_notes'] != '') ? nl2br($row['custom_notes']) : ''; - - eval("\$customers.=\"" . \Froxlor\UI\Template::getTemplate("customers/customers_customer") . "\";"); - $count++; - } - - $customercount = $result['count'] . " / " . $paging->getEntries(); - eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";"); - */ UI::twigBuffer('user/table.html.twig', [ - 'collection' => $collection->getData(), - 'table_options' => $customer_list_data['customer_list'], + 'listing' => \Froxlor\UI\Listing::format($collection, $customer_list_data['customer_list']), ]); UI::twigOutputBuffer(); } elseif ($action == 'su' && $id != 0) { diff --git a/admin_domains.php b/admin_domains.php index caad37ab..525cc1d9 100644 --- a/admin_domains.php +++ b/admin_domains.php @@ -51,8 +51,7 @@ if ($page == 'domains' || $page == 'overview') { } UI::twigBuffer('user/table.html.twig', [ - 'collection' => $collection->getData(), - 'table_options' => $domain_list_data['domain_list'], + 'listing' => \Froxlor\UI\Listing::format($collection, $domain_list_data['domain_list']), ]); UI::twigOutputBuffer(); } elseif ($action == 'delete' && $id != 0) { diff --git a/lib/Froxlor/UI/Callbacks/Number.php b/lib/Froxlor/UI/Callbacks/Number.php new file mode 100644 index 00000000..99ea278a --- /dev/null +++ b/lib/Froxlor/UI/Callbacks/Number.php @@ -0,0 +1,50 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Listing + * + */ +class Number +{ + /** + * Formats the diskspace to human-readable number + * + * @param string $data + * @return string + */ + public static function diskspace(string $data): string + { + if ($data < 0) { + return 'Unlimited'; + } + + return round($data / 1024, 3) . ' MB'; + } + + /** + * Formats the traffic to human-readable number + * + * @param string $data + * @return string + */ + public static function traffic(string $data): string + { + if ($data < 0) { + return 'Unlimited'; + } + + return round($data / (1024 * 1024), 3) . ' MB'; + } +} \ No newline at end of file diff --git a/lib/Froxlor/UI/Callbacks/ProgressBar.php b/lib/Froxlor/UI/Callbacks/ProgressBar.php new file mode 100644 index 00000000..896aebe8 --- /dev/null +++ b/lib/Froxlor/UI/Callbacks/ProgressBar.php @@ -0,0 +1,50 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Listing + * + */ +class ProgressBar +{ + /** + * TODO: use twig for html templates ... + * + * @param string $data + * @param array $attributes + * @return string + */ + public static function diskspace(string $data, array $attributes): string + { + $percentage = $attributes['diskspace_used'] ? round(100 * $attributes['diskspace_used'] / $attributes['diskspace']) : 0; + $text = Number::diskspace($attributes['diskspace_used']) . ' / ' . Number::diskspace($attributes['diskspace']); + + return '
' . $text . '
'; + } + + /** + * TODO: use twig for html templates ... + * + * @param string $data + * @param array $attributes + * @return string + */ + public static function traffic(string $data, array $attributes): string + { + $percentage = $attributes['traffic_used'] ? round(100 * $attributes['traffic_used'] / $attributes['traffic']) : 0; + $text = Number::traffic($attributes['traffic_used']) . ' / ' . Number::traffic($attributes['traffic']); + + return '
' . $text . '
'; + } +} \ No newline at end of file diff --git a/lib/Froxlor/UI/Callbacks/Text.php b/lib/Froxlor/UI/Callbacks/Text.php new file mode 100644 index 00000000..b33fdb18 --- /dev/null +++ b/lib/Froxlor/UI/Callbacks/Text.php @@ -0,0 +1,25 @@ + (2010-) + * @author Maurice Preuß + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Listing + * + */ +class Text +{ + public static function boolean(string $data): string + { + return $data ? '' : ''; + } +} \ No newline at end of file diff --git a/lib/Froxlor/UI/Collection.php b/lib/Froxlor/UI/Collection.php index 24f88dd0..4a20eda2 100644 --- a/lib/Froxlor/UI/Collection.php +++ b/lib/Froxlor/UI/Collection.php @@ -39,7 +39,7 @@ class Collection public function count() { - return $this->get()['data']['count']; + return json_decode($this->class::getLocal($this->userInfo, $this->params)->listingCount(), true); } public function get() diff --git a/lib/Froxlor/UI/Listing.php b/lib/Froxlor/UI/Listing.php index 6d72981c..8101d361 100644 --- a/lib/Froxlor/UI/Listing.php +++ b/lib/Froxlor/UI/Listing.php @@ -18,6 +18,37 @@ namespace Froxlor\UI; */ class Listing { + public static function format(Collection $collection, array $tabellisting): array + { + $items = $collection->getData()['list']; + $table = []; + + foreach ($tabellisting['visible_columns'] as $visible_column) { + $table['th'][] = $tabellisting['columns'][$visible_column]['label']; + } + + foreach ($items as $key => $item) { + foreach ($tabellisting['visible_columns'] as $visible_column) { + $format_callback = $tabellisting['columns'][$visible_column]['format_callback'] ?? null; + $column = $tabellisting['columns'][$visible_column]['column']; + $data = self::getMultiArrayFromString($item, $column); + + // TODO: contextual_class ... + + if ($format_callback) { + $table['tr'][$key][] = call_user_func($format_callback, $data, $item); + } else { + $table['tr'][$key][] = $data; + } + } + } + + return [ + 'table' => $table, + 'pagination' => null, // TODO: write some logic + ]; + } + public static function getVisibleColumnsForListing($listing, $default_columns) { // Hier käme dann die Logik, die das aus der DB zieht ... @@ -26,4 +57,16 @@ class Listing return $default_columns; } + + public static function getMultiArrayFromString($arr, $str) + { + foreach (explode('.', $str) as $key) { + if (!array_key_exists($key, $arr)) { + return null; + } + $arr = $arr[$key]; + } + + return $arr; + } } \ No newline at end of file diff --git a/lib/tablelisting/admin/admin/tablelisting.admin.php b/lib/tablelisting/admin/admin/tablelisting.admin.php index ca23ffde..6a134ea8 100644 --- a/lib/tablelisting/admin/admin/tablelisting.admin.php +++ b/lib/tablelisting/admin/admin/tablelisting.admin.php @@ -38,27 +38,27 @@ return [ 'diskspace' => [ 'label' => $lng['customer']['diskspace'], 'column' => 'diskspace', - 'type' => 'usage', + 'format_callback' => [\Froxlor\UI\Callbacks\Number::class, 'diskspace'], ], 'diskspace_used' => [ 'label' => $lng['customer']['diskspace'] . ' (' . $lng['panel']['used'] . ')', 'column' => 'diskspace_used', - 'type' => 'usage', + 'format_callback' => [\Froxlor\UI\Callbacks\ProgressBar::class, 'diskspace'], ], 'traffic' => [ 'label' => $lng['customer']['traffic'], 'column' => 'traffic', - 'type' => 'usage', + 'format_callback' => [\Froxlor\UI\Callbacks\Number::class, 'traffic'], ], 'traffic_used' => [ 'label' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')', 'column' => 'traffic_used', - 'type' => 'usage', + 'format_callback' => [\Froxlor\UI\Callbacks\ProgressBar::class, 'traffic'], ], 'deactivated' => [ 'label' => $lng['admin']['deactivated'], 'column' => 'deactivated', - 'type' => 'boolean', + 'format_callback' => [\Froxlor\UI\Callbacks\Text::class, 'boolean'], ], ], 'visible_columns' => \Froxlor\UI\Listing::getVisibleColumnsForListing('admin_list', [ diff --git a/lib/tablelisting/admin/admin/tablelisting.customer.php b/lib/tablelisting/admin/admin/tablelisting.customer.php index a2dc4105..c189062d 100644 --- a/lib/tablelisting/admin/admin/tablelisting.customer.php +++ b/lib/tablelisting/admin/admin/tablelisting.customer.php @@ -48,22 +48,22 @@ return [ 'c.diskspace' => [ 'label' => $lng['customer']['diskspace'], 'column' => 'diskspace', - 'type' => 'usage' + 'format_callback' => [\Froxlor\UI\Callbacks\Number::class, 'diskspace'], ], 'c.diskspace_used' => [ 'label' => $lng['customer']['diskspace'] . ' (' . $lng['panel']['used'] . ')', 'column' => 'diskspace_used', - 'type' => 'usage' + 'format_callback' => [\Froxlor\UI\Callbacks\ProgressBar::class, 'diskspace'], ], 'c.traffic' => [ 'label' => $lng['customer']['traffic'], 'column' => 'traffic', - 'type' => 'usage' + 'format_callback' => [\Froxlor\UI\Callbacks\Number::class, 'traffic'], ], 'c.traffic_used' => [ 'label' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')', 'column' => 'traffic_used', - 'type' => 'usage' + 'format_callback' => [\Froxlor\UI\Callbacks\ProgressBar::class, 'traffic'], ], ], 'visible_columns' => \Froxlor\UI\Listing::getVisibleColumnsForListing('customer_list', [ diff --git a/templates/Froxlor/table/table.html.twig b/templates/Froxlor/table/table.html.twig index 09cc654a..250ed812 100644 --- a/templates/Froxlor/table/table.html.twig +++ b/templates/Froxlor/table/table.html.twig @@ -1,6 +1,4 @@ -{% macro table(table_options, collection, action, title = "") %} - - {% import "Froxlor/table/tablemacros.html.twig" as tablemacros %} +{% macro table(listing, action, title = "") %}
{% if title is not empty %} @@ -16,39 +14,19 @@ - {% for column in table_options.visible_columns %} - + {% for column in listing.table.th %} + {% endfor %} - {% if table_options.actions %} - - {% endif %} - {% for columns in collection.list %} - - {% for column in table_options.visible_columns %} + {% for td in listing.table.tr %} + + {% for value in td %} {% endfor %} - {% if table_options.actions %} - - {% endif %} {% endfor %} diff --git a/templates/Froxlor/table/tablemacros.html.twig b/templates/Froxlor/table/tablemacros.html.twig deleted file mode 100644 index b8af8ba8..00000000 --- a/templates/Froxlor/table/tablemacros.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{% macro contextual_class(contextual_class, columns) %} - {# this could be refactored as filter #} - {% for i_key,i_column in columns %} - {% for c_key, c_column in contextual_class %} - {% if i_key == c_key %} - {% if c_column.value is not empty %} - {# check for values #} - {% if c_column.operator is empty and i_column == c_column.value %} - {{ c_column.return }} - {% elseif c_column.operator is not empty and c_column.operator == '>=' and i_column >= c_column.value %} - {{ c_column.return }} - {% elseif c_column.operator is not empty and c_column.operator == '<=' and i_column <= c_column.value %} - {{ c_column.return }} - {% endif %} - {% elseif c_column.column is not empty %} - {# check for column #} - {% if c_column.operator is empty and columns[c_column.column] == i_column %} - {{ c_column.return }} - {% elseif c_column.operator is not empty and c_column.operator == '>=' and columns[c_column.column] >= i_column %} - {{ c_column.return }} - {% elseif c_column.operator is not empty and c_column.operator == '<=' and columns[c_column.column] <= i_column %} - {{ c_column.return }} - {% endif %} - {% endif %} - {% endif %} - {% endfor %} - {% endfor %} -{% endmacro %} - -{% macro boolean(value) %} - {% if value %} - - {% else %} - - {% endif %} -{% endmacro %} - -{% macro usage(value) %} - {{ value }} -{% endmacro %} - -{% macro column(arr, str) %} - {# this could be refactored as filter #} - {% set strarr = str|split('.') %} - - {% if strarr|length == 1 %} - {{ arr[strarr[0]] }} - {% elseif strarr|length == 2 %} - {{ arr[strarr[0]][strarr[1]] }} - {% else %} - column depth not supported - {% endif %} -{% endmacro %} \ No newline at end of file diff --git a/templates/Froxlor/user/table.html.twig b/templates/Froxlor/user/table.html.twig index c47cdeeb..574824cf 100644 --- a/templates/Froxlor/user/table.html.twig +++ b/templates/Froxlor/user/table.html.twig @@ -4,6 +4,6 @@ {% import "Froxlor/table/table.html.twig" as table %} - {{ table.table(table_options, collection, '#', table_options.title) }} + {{ table.table(listing, table_options.title) }} {% endblock %}
{{ table_options.columns[column].label }}{{ column }}Actions
- {% if table_options.columns[column].type is empty %} - {{ tablemacros.column(columns, table_options.columns[column].column)|trim }} - {% elseif table_options.columns[column].type == 'boolean' %} - {{ tablemacros.boolean(tablemacros.column(columns, table_options.columns[column].column)|trim) }} - {% elseif table_options.columns[column].type == 'usage' %} - {{ tablemacros.usage(tablemacros.column(columns, table_options.columns[column].column)|trim) }} - {% endif %} + {{ value|raw }} - {% for action in table_options.actions %} - {% if action.href is not empty %} - {% if action.icon is not empty %}{% endif %}{{ action.title }} - {% else %} - {% if action.icon is not empty %}{% endif %}{{ action.title }} - {% endif %} - {% endfor %} -