Pull to refresh

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

В 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;
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.
Change theme settings