1. Приветствуем Вас на неофициальном форуме технической поддержки XenForo на русском языке. XenForo - коммерческий форумный движок от бывших создателей vBulletin, написанный на PHP.

1.1.1 Програмное назначение группы пользователю. Права не срабатывают.

Тема в разделе "Вопросы и ответы по XenForo Framework", создана пользователем Kronger, 28.02.2012.

Загрузка
  1. Kronger

    Kronger Пользователь

    Регистрация:
    18.01.12
    Сообщения:
    31
    Симпатии:
    16
    Версия XF:
    1.1.3
    Вобщем пишу палагин ядро для своего сайта. Он объединяет другие плагины и управляет ими.
    К примеру при достижении определенной популярности выдает медальку и назначает пользователю новую группу.
    Группа отображается в качестве погон на форуме и т.д.

    Группу добавляю просто через запись в базу:

    PHP:
                $this->_getDb()->query("
                    UPDATE `xf_user`
                    SET user_group_id = ?
                    WHERE `user_id` = ?
                "
    , array( $new_group$user_id));
    Но при этом не забываю добавить ему группу "Зарегистрированные" в дополнительные группы:
    PHP:
                      $secondary_group_ids trim($this->getSecondaryUserGroup($user_id));
                    if (  
    strpos($secondary_group_ids$new_group) === false )
                      {
                            if( 
    strlen($secondary_group_ids) == )
                            {
                              
    $secondary_group_ids $new_group;
                            }
                            else
                            {
                              
    $secondary_group_ids $secondary_group_ids.", ".$new_group;
                            }
                         
                
    $this->_getDb()->query("
                    UPDATE `xf_user`
                    SET secondary_group_ids = ?
                    WHERE `user_id` = ?
                "
    , array( $secondary_group_ids$user_id));
                      }
    При тестировании все группы нормально назначаются, но вот действия прав для пользователя не замечаю.
    Специально сделал одной из назначаемых групп (все права запрещены). Пользователю программно добавляется группа. Эффект нулевой. Все права действуют как у Зарегистрированных пользователей т.е. как у группы с ID=2.
    Может после назначения группы пользователю надо вызвать какую-то процедуру обновления прав пользователя?
    Кто хорошо понимает в движке - подскажите.
     
  2. infis

    infis Местный

    Регистрация:
    27.06.11
    Сообщения:
    5 966
    Симпатии:
    3 548
    Версия XF:
    1.5.9
    Лучше, наверное, использовать существующую модель, а не прямой запрос в базу данных. Чтобы сказать что-то конкретное, нужно уже будет детально разбираться, что происходит при сохранении пользователя и как оно вообще происходит.
     
  3. Kronger

    Kronger Пользователь

    Регистрация:
    18.01.12
    Сообщения:
    31
    Симпатии:
    16
    Версия XF:
    1.1.3
    Да пытался я использовать существующую модель.
    Там есть замена группы но требуется подставить ключ - описания ключей нет.
    И не понятно заменяет она группу или тупо новую добавляет.
    Вот код из файла library\XenForo\Model\User.php
    PHP:
        /**
        * 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 to add
        *
        * @return boolean True on change success
        */
        
    public function addUserGroupChange($userId$key$addGroups)
        {
            if (
    is_array($addGroups))
            {
                
    $addGroups implode(','$addGroups);
            }
     
            if (!
    $addGroups)
            {
                return 
    true;
            }
     
            
    $oldGroups $this->getUserGroupChangesForUser($userId);
     
            
    $newGroups $oldGroups;
     
            if (isset(
    $newGroups[$key]) && !$addGroups)
            {
                
    // already exists and we're removing the groups, so we can just remove the record
                
    return $this->removeUserGroupChange($userId$key);
            }
     
            
    $newGroups[$key] = $addGroups;
     
            
    $db $this->_getDb();
            
    XenForo_Db::beginTransaction($db);
     
            
    $db->query('
                INSERT INTO xf_user_group_change
                    (user_id, change_key, group_ids)
                VALUES
                    (?, ?, ?)
                ON DUPLICATE KEY UPDATE
                    group_ids = VALUES(group_ids)
            '
    , array($userId$key$addGroups));
     
            
    $success $this->_applyUserGroupChanges($userId$oldGroups$newGroups);
     
            
    XenForo_Db::commit($db);
     
            return 
    $success;
        }
     
  4. infis

    infis Местный

    Регистрация:
    27.06.11
    Сообщения:
    5 966
    Симпатии:
    3 548
    Версия XF:
    1.5.9
    Разве не понятно, что такое $key? Это идентификатор записи в таблице.
    Если у пользователя группа убирается, то выполняется соответствующий метод.
    Ну и достаточно посмотреть на запрос - он либо добавляет, либо обновляет. Т.е. передается идентификатор пользователя, идентификатор записи и массив групп.
     
  5. ayep

    ayep Пользователь

    Регистрация:
    20.02.12
    Сообщения:
    9
    Симпатии:
    3
    Версия XF:
    1.1.2
    Так делать не надо, в Ксене для этого есть модели и DataWriter'ы, которые проверяют правильность изменений и автоматически обновляют связанные объекты. В данном случае вы изменили идентификаторы групп, но не обновили кэш прав доступа, поэтому они остались теми же. Если бы то же изменение было проведено через DW, это было бы сделано автоматически:
    PHP:
        $user_id 1$groups_ids '3,4,5';
        
    // Берем класс DW
        
    $writer XenForo_DataWriter::create('XenForo_DataWriter_User');
        
    // Загружаем данные пользователя из базы
        
    $writer->setExistingData($user_id);
        
    // Вносим все изменения сразу
        
    $writer->bulkSet(array(
            
    'user_group_id' => 2// Новая первичная группа
            
    'secondary_group_ids' => $group_ids// Новый список вторичных групп. Внимание, это замена, а не добавление!
        
    ));
        
    // Или по одному
        
    $writer->set('user_group_id'2);
        
    $writer->set('secondary_group_ids'$group_ids);
        
    // Проверим на наличие ошибок
        
    if ($dwErrors $writer->getErrors()) {
            
    // $dwErrors - строка с текстом ошибок
        
    } else {
            
    // Ошибок нет, сохраним результат обратно в базу
            
    $writer->save();
        }
    Для обновления только вторичных групп есть хелпер, который работает с DW сам:
    PHP:
        XenForo_DataWriter_Helper_User::updateSecondaryUserGroupIds(
                
    $user_id$groups_to_add$groups_to_remove
            
    );
    Ему список id групп тоже передается в виде строки. Перечисленные в $groups_to_add будут добавлены, а в $groups_to_remove - удалены. Остальные группы останутся без изменений.

    Но то, что вы раскопали, может быть удобнее:
    PHP:
        // Берем класс модели
        
    $model XenForo_Model::create('XenForo_Model_User');
        
    // Добавляем пользователю вторичные группы и сохраняем их на будущее под ключом 'key'
        
    $model->addUserGroupChange($user_id'key'$groups_to_add1);
        
    // При повторном выполнении список групп просто обновляется
        
    $model->removeUserGroupChange(1'key');
    Таким способом можно только добавлять вторичные группы, но это удобно тем, что можно потом их убрать по ключу, не перечисляя заново. Ключ не должен повторяться для одного пользователя, при повторном добавлении он просто затирается новым списком групп. Для своих целей лучше придумать какой-нибудь префикс. Если группа добавляется сразу двумя ключами, то удаление одного из них не убирает группу у пользователя.
     
    n0rt37 и Kronger нравится это.
  6. Kronger

    Kronger Пользователь

    Регистрация:
    18.01.12
    Сообщения:
    31
    Симпатии:
    16
    Версия XF:
    1.1.3
    Спасибо ayep.
    Я попробывал через базу - как самый прямой и простой способ. Думаю его можно использовать если надо менять только название группы без изменения прав.
    До этой структуры я не докопался, но понимаю, что запись в базу идет через DataWriter :
    PHP:
    $writer XenForo_DataWriter::create('XenForo_DataWriter_User');
        
    // Загружаем данные пользователя из базы
        
    $writer->setExistingData($user_id);
    Проблема использования нужных процедур ограничивается частым использованием в DataWriter защищенных процедур protected и приходится юзать всю конструкцию - которая может сделать намного больше чем планируешь :sneaky: , это тоже не всегда хорошо и приходится изучать всю структуру по цепочке.

    Сейчас попробую, через XenForo_DataWriter
     
  7. Kronger

    Kronger Пользователь

    Регистрация:
    18.01.12
    Сообщения:
    31
    Симпатии:
    16
    Версия XF:
    1.1.3
    Всё проверил.
    Теперь права вступают в силу на лету при смене группы. :thumbsup:
     
  8. ayep

    ayep Пользователь

    Регистрация:
    20.02.12
    Сообщения:
    9
    Симпатии:
    3
    Версия XF:
    1.1.2
    Ах да, забыл. Перед getErrors() надо сделать preSave(), иначе не сработает. Если не нужен список ошибок, можно использовать save() напрямую, он вернет bool в зависимости от результата.
     

Поделиться этой страницей