From f465d201aeb9a1bff1ea5467d671744a13669804 Mon Sep 17 00:00:00 2001 From: ralf Date: Tue, 13 Aug 2024 14:52:37 +0200 Subject: [PATCH] allow to sort groups in admin by container & group-name like in the tree --- admin/inc/class.admin_ui.inc.php | 4 +++- admin/templates/default/index.xet | 2 ++ api/src/Accounts.php | 37 +++++++++++++++++++++++++++++++ api/src/Contacts/Sql.php | 17 +++++++++++++- api/src/Etemplate/Widget/Tree.php | 11 +-------- 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/admin/inc/class.admin_ui.inc.php b/admin/inc/class.admin_ui.inc.php index 6c94305b50..a05dcb56d1 100644 --- a/admin/inc/class.admin_ui.inc.php +++ b/admin/inc/class.admin_ui.inc.php @@ -507,7 +507,9 @@ class admin_ui { $group['members'] = $GLOBALS['egw']->accounts->members($group['account_id'],true); } - $rows[] = $group; + $rows[] = $group+[ + 'container' => Api\Accounts::container($group) ?? lang('None'), + ]; } $rows['is_huge'] = $is_huge; return $GLOBALS['egw']->accounts->total; diff --git a/admin/templates/default/index.xet b/admin/templates/default/index.xet index 45eef7a5a8..b693d76ddf 100644 --- a/admin/templates/default/index.xet +++ b/admin/templates/default/index.xet @@ -65,6 +65,7 @@ + @@ -74,6 +75,7 @@ + diff --git a/api/src/Accounts.php b/api/src/Accounts.php index 6445cb5a31..ef6fe5fd0a 100644 --- a/api/src/Accounts.php +++ b/api/src/Accounts.php @@ -1592,6 +1592,43 @@ class Accounts }); } + /** + * Get group-container attributes incl. default values + * + * @return array with values [$group_container_attribute, $group_container_regexp, $group_container_replace] + */ + public static function groupContainerAttributs() + { + $group_container_attribute = $GLOBALS['egw_info']['server']['group_container_attribute'] ?? ''; + static $default_regexp = [ + 'account_lid' => '/^([^ ]+) /', + 'account_dn' => '/,CN=([^,]+),/i', + ]; + $group_container_regexp = $GLOBALS['egw_info']['server']['group_container_regexp'] ?? $default_regexp[$group_container_attribute] ?? null; + $group_container_replace = $GLOBALS['egw_info']['server']['group_container_replace'] ?? '$1'; + + return [$group_container_attribute, $group_container_regexp, $group_container_replace]; + } + + /** + * Get container-name of a group, if configured + * + * @param array $group values for keys "account_dn" and "account_lid" + * @return string|null container-name or NULL + */ + public static function container(array $group) : ?string + { + [$group_container_attribute, $group_container_regexp, $group_container_replace] = self::groupContainerAttributs(); + + if ($group_container_attribute && !empty($group[$group_container_attribute]) && + preg_match($group_container_regexp, $group[$group_container_attribute], $matches) && + ($container_name = ucfirst($matches[substr($group_container_replace, 1)] ?? ''))) + { + return $container_name; + } + return null; + } + /** * Internal functions not meant to use outside this class!!! */ diff --git a/api/src/Contacts/Sql.php b/api/src/Contacts/Sql.php index 76f8e6cc42..554e34057a 100644 --- a/api/src/Contacts/Sql.php +++ b/api/src/Contacts/Sql.php @@ -648,7 +648,7 @@ class Sql extends Api\Storage } $extra_cols[] = $table.$column.' '.$matches[2]; //_debug_array($matches); - if (!empty($order_by) && $table) // postgres requires explizit order by + if (!empty($order_by) && $table) // postgres requires explicit order by { $order_by = str_replace($matches[0],$table.$column.' '.$matches[2].' '.$matches[3].$matches[4],$order_by); } @@ -700,6 +700,21 @@ class Sql extends Api\Storage } unset($filter['shared_with']); + // if we have regular expression based container-name AND use MariaDB/MySQL sort by it instead of account_dn + if (preg_match('/(^|,| )account_dn( |,)/', $order_by) && in_array("account_type='g'", $filter) && + !empty($GLOBALS['egw_info']['server']['group_container_attribute']) && $this->db->Type === 'mysql' && + in_array($group_container_attribute=$GLOBALS['egw_info']['server']['group_container_attribute'], ['account_dn', 'account_lid'])) + { + [, $group_container_regexp, $group_container_replace] = Api\Accounts::groupContainerAttributs(); + [,$regexp,] = explode('/', $group_container_regexp); + if ($regexp[0] !== '^') $regexp = ($regexp[0] === ',' ? '^[^,]+' : '^.*').$regexp; + if (substr($regexp, -1) !== '$') $regexp .= '.*$'; + $order = "COALESCE(REGEXP_REPLACE($group_container_attribute,".$this->db->quote($regexp).','. + $this->db->quote(str_replace('$', '\\', $group_container_replace))."), account_lid)"; + $order_by = str_replace('account_dn', $order, $order_by); + $this->sanitize_order_by = false; + } + $rows =& parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count); if ($start === false) $this->total = is_array($rows) ? count($rows) : 0; // so_sql sets total only for $start !== false! diff --git a/api/src/Etemplate/Widget/Tree.php b/api/src/Etemplate/Widget/Tree.php index 6c8b4cf008..8d6600a155 100644 --- a/api/src/Etemplate/Widget/Tree.php +++ b/api/src/Etemplate/Widget/Tree.php @@ -584,13 +584,6 @@ class Tree extends Etemplate\Widget public static function groups(string $root='/groups') { if ($root) $root = rtrim($root, '/').'/'; - $group_container_attr = $GLOBALS['egw_info']['server']['group_container_attribute'] ?? ''; - static $default_regexp = [ - 'account_lid' => '/^([^ ]+) /', - 'account_dn' => '/,CN=([^,]+),/i', - ]; - $group_container_regexp = $GLOBALS['egw_info']['server']['group_container_regexp'] ?? $default_regexp[$group_container_attr] ?? null; - $group_container_replace = $GLOBALS['egw_info']['server']['group_container_replace'] ?? '$1'; $children = []; foreach(Api\Accounts::getInstance()->search(array( @@ -600,9 +593,7 @@ class Tree extends Etemplate\Widget 'start' => false, // to NOT limit number of returned groups )) as $group) { - if ($group_container_attr && !empty($group[$group_container_attr]) && - preg_match($group_container_regexp, $group[$group_container_attr], $matches) && - ($container_name = ucfirst($matches[substr($group_container_replace, 1)] ?? ''))) + if (($container_name = Api\Accounts::container($group))) { foreach($children as &$container) {