Fixing noixacl dropping all multigroups and permissions

At PirateGaming we had a problem; using JomSocial users occasionally lost their permissions we set up with noixacl to allow multi-group ACLs.

This is a Problem not specific to JomSocial but any component that will allow users to change anything about their account, like changing passwords or username (like CommunityBuilder).

The problem is in plugins/user/noixacl.php in the onBeforeStoreUser function.

The multigroup permissions will be dropped before adding the (passed as params) passed ones. This is no problem for the admin section, where the perms are actually passed, as they’re in the form.

However, if another form is used to update the user, like frontend ones which obviously don’t provide multigroup lists, they will be dropped without being added again.

To fix this, a simple check if we’re in the admin section does the trick. (if ($app->getName() == 'administrator'))

Before:

    public function onBeforeStoreUser($user, $isnew)
    {
        global $mainframe;

        $db =& JFactory::getDBO();
        $app =& JFactory::getApplication();
        /**
         * get Multigroup
         */
        $arrMultiGroups = JRequest::getVar( 'multigroups' );

        /**
         * check if exists array
         */
        $queryDelMultigroup = "DELETE FROM #__noixacl_multigroups WHERE id_user = {$user['id']}";
        $db->setQuery( $queryDelMultigroup );
        $db->query();

        if( !empty($arrMultiGroups) ){

            foreach($arrMultiGroups as $multigroupID){
                $multigroupID = intval( $multigroupID );

                $queryInsertMultigroup = "INSERT INTO #__noixacl_multigroups(id_user,id_group) "
                                  . "VALUES({$user['id']},{$multigroupID})";
                $db->setQuery( $queryInsertMultigroup );
                if( !$db->query() ){
                    $app->setRedirect("index.php?option=com_noixacl&controller=aclusers",JText::_('NOIXACL_USERS_CANNOT_SAVE_MULTIGROUP'));
                }
            }
        }
    }

After:

    public function onBeforeStoreUser($user, $isnew)
    {
        global $mainframe;

        $db =& JFactory::getDBO();
        $app =& JFactory::getApplication();
        /**
         * get Multigroup
         */
        $arrMultiGroups = JRequest::getVar( 'multigroups' );

        // drop acl if in admin area (and thus request should contain multigroup data)
        if ($app->getName() == 'administrator') {
            $queryDelMultigroup = "DELETE FROM #__noixacl_multigroups WHERE id_user = {$user['id']}";
            $db->setQuery( $queryDelMultigroup );
            $db->query();
        }
        /**
         * check if array exists and is not empty, and set multigroups appropriately
         */
        if( !empty($arrMultiGroups) ){

            foreach($arrMultiGroups as $multigroupID){
                $multigroupID = intval( $multigroupID );

                $queryInsertMultigroup = "INSERT INTO #__noixacl_multigroups(id_user,id_group) "
                                  . "VALUES({$user['id']},{$multigroupID})";
                $db->setQuery( $queryInsertMultigroup );
                if( !$db->query() ){
                    $app->setRedirect("index.php?option=com_noixacl&controller=aclusers",JText::_('NOIXACL_USERS_CANNOT_SAVE_MULTIGROUP'));
                }
            }
        }
    }

Solution via