public function buildGroupTree(string $cabin, int $contextId, array $actions = [], int $parentId = 0, array $inherited = [], int $depth = 0) : array
{
if ($depth > self::MAX_RECURSE_DEPTH) {
return [];
}
if (empty($cabin) || empty($actions) || empty($contextId)) {
return [];
}
// This is the tree we are building...
$tree = [];
// Let's grab all the groups with a specific ancestor
if (empty($parentId)) {
$groups = $this->db->run(\Airship\queryStringRoot('security.permissions.groups_null', $this->db->getDriver()));
} else {
$groups = $this->db->run(\Airship\queryStringRoot('security.permissions.groups_inherits', $this->db->getDriver()), $parentId);
}
// Nothing? Return an empty array
if (empty($groups)) {
return [];
}
// Let's safely construct a parameter to use to concatenate to the query
$act_keys = \array_keys($actions);
$_acts = $this->db->escapeValueSet($act_keys, 'int');
$baseline = [];
foreach (\array_values($actions) as $a) {
$baseline[$a] = false;
}
// Now let's build the tree
foreach ($groups as $grp) {
$grp['perms'] = $baseline;
$grp['inherit'] = $inherited;
// Let's grab the permission data for this particular group
$sqlQuery = \Airship\queryStringRoot('security.permissions.groups_qs', $this->db->getDriver(), ['actionids' => $_acts]);
$pdata = $this->db->run($sqlQuery, $cabin, $contextId, $grp['groupid']);
foreach ($pdata as $perm) {
$grp['perms'][$perm['label']] = true;
$grp['inherit'][$perm['label']] = true;
}
// Pass onto the next generation
$grp['children'] = self::buildGroupTree($cabin, (int) $contextId, $actions, (int) $grp['groupid'], $grp['inherit'], $depth + 1);
// Append this branch
$tree[] = $grp;
}
// With any luck, we now have a hierarchical array to play with in
// our template.
return $tree;
}