Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Service/User/UserGroupChange.php
<?php

namespace XF\Service\User;

use function
in_array, is_array;

class
UserGroupChange extends \XF\Service\AbstractService
{
   
/**
     * Inserts (or updates an existing) user group change set.
     *
     * @param integer $userId
     * @param string $key Unique identifier for change set
     * @param string|array $addGroups Comma delimited string or array of user groups IDs to add
     *
     * @return boolean True on change success
     */
   
public function addUserGroupChange($userId, $key, $addGroups)
    {
        if (
is_array($addGroups))
        {
           
$addGroups = implode(',', $addGroups);
        }

       
$oldChanges = $this->getUserGroupChangesForUser($userId);
       
$newChanges = $oldChanges;

        if (!
$addGroups)
        {
            if (isset(
$newChanges[$key]))
            {
               
// already exists and we're removing the groups, so we can just remove the record
               
return $this->removeUserGroupChange($userId, $key);
            }
            else
            {
               
// would be inserting but nothing to do anyway
               
return true;
            }
        }

       
$newChanges[$key] = $addGroups;

       
$db = $this->db();
       
$db->beginTransaction();

       
$success = $this->applyUserGroupChanges($userId, $oldChanges, $newChanges, $addGroups);
        if (
$success)
        {
           
$db->insert('xf_user_group_change', [
               
'user_id' => $userId,
               
'change_key' => $key,
               
'group_ids' => $addGroups
           
], false, 'group_ids = VALUES(group_ids)');

           
$db->commit();
        }
        else
        {
           
$db->rollback();
        }

        return
$success;
    }

   
/**
     * Removes the specified user group change set.
     *
     * @param integer $userId
     * @param string $key Change set key
     *
     * @return boolean True on success
     */
   
public function removeUserGroupChange($userId, $key)
    {
       
$oldChanges = $this->getUserGroupChangesForUser($userId);
        if (!isset(
$oldChanges[$key]))
        {
           
// already removed?
           
return true;
        }

       
$newChanges = $oldChanges;
        unset(
$newChanges[$key]);

       
$db = $this->db();
       
$db->beginTransaction();

       
$success = $this->applyUserGroupChanges($userId, $oldChanges, $newChanges);
        if (
$success)
        {
           
$db->delete('xf_user_group_change',
               
'user_id = ? AND change_key = ?',
                [
$userId, $key]
            );

           
$db->commit();
        }
        else
        {
           
$db->rollback();
        }

        return
$success;
    }

    public function
removeUserGroupChangeLogByKey($key)
    {
       
$this->db()->delete('xf_user_group_change', 'change_key = ?', $key);
    }

    public function
getUserGroupChangesForUser($userId)
    {
        return
$this->db()->fetchPairs('
            SELECT change_key, group_ids
            FROM xf_user_group_change
            WHERE user_id = ?
        '
, $userId);
    }

   
/**
     * Applies a set of user group changes.
     *
     * @param integer $userId
     * @param array $oldGroupStrings Array of comma-delimited strings of existing (accounted for) user group change sets
     * @param array $newGroupStrings Array of comma-delimited strings for new list of user group change sets
     * @param string $forceAdd A comma-delimited list of groups to force add, even if they were already in the old groups
     *
     * @return boolean
     */
   
protected function applyUserGroupChanges($userId, array $oldGroupStrings, array $newGroupStrings, $forceAdd = '')
    {
       
$oldGroups = [];
        foreach (
$oldGroupStrings AS $string)
        {
            if (
$string)
            {
               
$oldGroups = array_merge($oldGroups, explode(',', $string));
            }
        }
       
$oldGroups = array_unique($oldGroups);

       
$newGroups = [];
        foreach (
$newGroupStrings AS $string)
        {
            if (
$string)
            {
               
$newGroups = array_merge($newGroups, explode(',', $string));
            }
        }
       
$newGroups = array_unique($newGroups);

       
$removeGroups = array_diff($oldGroups, $newGroups);
       
$addGroups = array_diff($newGroups, $oldGroups);
        if (
$forceAdd)
        {
           
$addGroups = array_merge($addGroups, explode(',', $forceAdd));
           
$addGroups = array_unique($addGroups);
        }

        if (!
$addGroups && !$removeGroups)
        {
            return
true;
        }

       
/** @var \XF\Entity\User $user */
       
$user = $this->em()->find('XF:User', $userId);
        if (!
$user)
        {
            throw new \
LogicException("User '$userId' could not be found");
        }

       
$secondaryGroupIds = $user->secondary_group_ids;
        if (
$removeGroups)
        {
            foreach (
$secondaryGroupIds AS $key => $secondaryGroup)
            {
                if (
in_array($secondaryGroup, $removeGroups))
                {
                    unset(
$secondaryGroupIds[$key]);
                }
            }
        }
        if (
$addGroups)
        {
           
$secondaryGroupIds = array_merge($secondaryGroupIds, $addGroups);
        }

       
$user->secondary_group_ids = $secondaryGroupIds;

        if (
$user->isChanged('secondary_group_ids'))
        {
            return
$user->save(false, false);
        }
        else
        {
            return
true;
        }
    }
}