MODx Revo 2.2: проблема «кеширования» членства в группах

13 Апр
2012

В MODx Revoluiton появились широкие возможности по разграничению доступа с помощью различных групп и ролей пользователей, групп документов, связывания всего этого добра друг с другом и я решил попробовать это использовать. Как раз нужно было сделать сайт где нужно было организовать платную подписку на различные курсы, контролируемые «учителями». Ученики, в свою очередь, могут видеть работы друг друга и оставлять комментарии. «Вот где мы можем использовать современные навороты!» — подумал я и решил что «ученики» оплатившие курс просто вступают в нужную группу, а контролем доступа пускай занимается MODx. Поначалу всё было хорошо и гладко, но не тут-то было!
Проверкой того, состоит ли юзер в группе занимается метод isMember.
$modx->user->isMember('название группы');


На самом деле он относится не только к юзерам, бывают и другие группы и не только у юзеров, но сейчас это не суть важно

Добавить в группу можно методом joinGroup
$modx->user->joinGroup($groupName)


Узнать список групп, в которых состоит юзер
$modx->user->getUserGroupNames()


Ситуация такая — юзер залогинился, ходит по сайту, покупает курс, мы его отправляем в группу и… ничего не происходит, юзер будто бы ничего не купил. Смотрим в админке — юзер в группе, всё хорошо, но покупку он всё равно не видит, isMember говорит false, в getUserGroupNames группы нет. После долгого гугления я где-то наткнулся что всё станет хорошо после того как юзер перезалогинится. Это не выход, не так ли? Нельзя же заставить пользователя выходить и входить обратно только потому что какой-то MODx так устроен.

В поисках проблемы я устал гуглить, читать англоязычные форумы, такое чувство что или я что-то не так делаю или этот функционал MODx никто не юзает. Пришлось лезть в ядро. Оказывается, список групп, в которых состоит юзер лежит в сессии и совсем не обновляется при вступлении или удалении из группы. Вышеописанный метод getUserGroupNames() как раз-таки берет список групп из переменной в сессии, а если её не существует — получает список из БД и кладет в сессию. «Зачем вам этот геморрой?(с)» — подумал я и просто выпилил часть где возвращаются закешированные данные, пускай эти данные будут всегда актуальными.

Файл, который нужно править находится в /core/model/modx/moduser.class.php. Метод принимает такой вид:
 public function getUserGroupNames() {
$groupNames= array();
$id = $this->get('id') ? (string) $this->get('id') : '0';

$memberGroups= $this->xpdo->getCollectionGraph('modUserGroup', '{"UserGroupMembers":{}}', array('UserGroupMembers.member' => $this->get('id')));
if ($memberGroups) {
foreach ($memberGroups as $group) $groupNames[]= $group->get('name');
}
$_SESSION["modx.user.{$id}.userGroupNames"]= $groupNames; // оставлено на всякий случай

return $groupNames;
}
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх