We have a commercial application used by different companies. We created custom user groups and access levels (not using Author, Editor, etc).

We have a group called SiteAdmin. This customer group has access to the Administrator console and can Enable/Disable end users and assign them to groups.

We have a group called ABCAdmin. This group is for developers and people who work at our company. I have them in the Groups hierarch 'under' - a child of - SiteAdmin. This group has more rights than SiteAdmin and can access components that SiteAdmin cannot.

The trouble is, SiteAdmin can see and assign this group to their users. Can I stop this? Can I hide this group?

1 Answer 1


When you're editing a user then the contents of the Assigned User Groups tab is generated by the code in administrator/components/com_users/tmpl/user/edit_groups.php. As with all tmpl files you can create an override within the administrator System / Administrator Templates / Atum Details and Files.

The code in edit_groups.php is just

echo HTMLHelper::_('access.usergroups', 'jform[groups]', $this->groups, true);

which runs the function usergroups() within libraries/src/HTML/Helpers/Access.php.

So you can just move that function into edit_groups.php directly, remembering to include the appropriate use statements, and setting manually the parameters to that function.

The code gets a list of the usergroups on the system and cycles through them to output the checkboxes for each. I've just included code to skip over where the usergroup title is ABCAdmin. Obviously you'd need to do a bit more work to decide based on the current user whether the usergroup should be skipped or not.

use Joomla\CMS\Access\Access as AccessCheck;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\UserGroupsHelper;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;

$name = 'jform[groups]';
$selected = $this->groups;
$checkSuperAdmin = true;

static $count;


$isSuperAdmin = Factory::getUser()->authorise('core.admin');

$groups = array_values(UserGroupsHelper::getInstance()->getAll());

$html = [];

for ($i = 0, $n = count($groups); $i < $n; $i++) {
    $item = &$groups[$i];

    if ($item->title === "ABCAdmin") {

    // If checkSuperAdmin is true, only add item if the user is superadmin or the group is not super admin
    if ((!$checkSuperAdmin) || $isSuperAdmin || (!AccessCheck::checkGroup($item->id, 'core.admin'))) {
        // Setup  the variable attributes.
        $eid = $count . 'group_' . $item->id;

        // Don't call in_array unless something is selected
        $checked = '';

        if ($selected) {
            $checked = in_array($item->id, $selected) ? ' checked="checked"' : '';

        $rel = ($item->parent_id > 0) ? ' rel="' . $count . 'group_' . $item->parent_id . '"' : '';

        // Build the HTML for the item.
        $html[] = ' <div class="control-group">';
        $html[] = '     <div class="controls">';
        $html[] = '         <label class="form-check-label checkbox" for="' . $eid . '">';
        $html[] = '         <input class="form-check-input" type="checkbox" name="' . $name . '[]" value="' . $item->id . '" id="' . $eid . '"';
        $html[] = '                 ' . $checked . $rel . '>';
        $html[] = '         ' . LayoutHelper::render('joomla.html.treeprefix', ['level' => $item->level + 1]) . $item->title;
        $html[] = '         </label>';
        $html[] = '     </div>';
        $html[] = ' </div>';

echo implode("\n", $html);
  • If selected is an empty array, then the in_array() call will not be terribly taxing, right? If you still want to check, you could consolidate as $checked = $selected && in_array($item->id, $selected) ? ' checked="checked' : ''; Also as a topical reference: [What's the proper value for a checked attribute of an HTML checkbox?] (stackoverflow.com/q/7851868/2943403) I might personally use sprintf() with numbered placeholders to build the html markup to avoid concatenation and variable declarations/access. May 20 at 23:45
  • Why a for() loop instead of a foreach()? Is it necessary to make each object ($item) explicitly moifiable? Is this not the natural behaviour of objects anyhow? May 20 at 23:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.