allow to sort groups in admin by container & group-name like in the tree

This commit is contained in:
ralf 2024-08-13 14:52:37 +02:00
parent b75f850197
commit f465d201ae
5 changed files with 59 additions and 12 deletions

View File

@ -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;

View File

@ -65,6 +65,7 @@
<et2-vbox>
<nextmatch-sortheader label="Group name" id="account_lid"/>
<nextmatch-sortheader label="Description" id="account_description"/>
<nextmatch-sortheader label="{Container} &amp; {Group name}" id="account_dn"/>
</et2-vbox>
<nextmatch-sortheader label="EMail" id="email"/>
<nextmatch-header label="Members" id="account_members"/>
@ -74,6 +75,7 @@
<et2-vbox>
<et2-description id="${row}[account_lid]" noLang="1"></et2-description>
<et2-description id="${row}[account_description]" noLang="1"></et2-description>
<et2-description id="${row}[container]" statustext="$row_cont[account_dn]" noLang="1"></et2-description>
</et2-vbox>
<et2-url-email id="${row}[account_email]" readonly="true" class="adminOverflowEllipsis" noLang="1"></et2-url-email>
<et2-select-account id="${row}[members]" readonly="true" noLang="1"></et2-select-account>

View File

@ -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!!!
*/

View File

@ -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!

View File

@ -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)
{