Ошибка MODX или мои кривые руки?
Привет тебе, сообщество!
Для одного проекта делал простенькую кастомную управлялку пользователями из личного кабинета на фронтенде. Можно менять только fullname, email, city и осуществить выбор из двух групп пользователей, либо удалить из всех групп.
Вчера вскрылась ошибка — клиент не смог изменить группу пользователя. Я стал разбираться и увидел, что мой сниппет неверно указывает при загрузке формы редактирования группу пользователя.
Чтобы было понятней, приведу небольшой кусок кода:
Пользователь является членом группы «Группа 1», а в массив $uArray['group']['name'] попадает значение «Группа 2», что не соответствует действительности. Причина, как я полагаю, в лефт джойне профиля. Еще на стадии написания сниппета я заметил, что в $uArray['id'] записывается не id пользователя, а id профиля. Для исправления я подменяю в полученном в результате метода modUser::toArray() массиве поле id полем internalKey.
Однако, $user->getMany('UserGroupMembers') отрабатывает неправильно, поскольку у объекта $user вместо собственного id всё еще id из таблицы _user_attributes, приджойненой в процессе формирования запроса. То есть, берется группа пользователя с другим id.
Разумеется, это проблему можно легко решить, добавив перед $user->getMany('UserGroupMembers') строчку $user->id = $user->internalKey.
Но я чувствую, что во всём этом есть что-то неправильное.
Поэтому у меня к Вам вопрос: это некорректная работа modX::getCollection при передаче в параметр criteria объекта xPDOQuery с лефт-джойном или это моя ошибка и я неправильно приджойнил?
Заранее благодарю за ответ!
Для одного проекта делал простенькую кастомную управлялку пользователями из личного кабинета на фронтенде. Можно менять только fullname, email, city и осуществить выбор из двух групп пользователей, либо удалить из всех групп.
Вчера вскрылась ошибка — клиент не смог изменить группу пользователя. Я стал разбираться и увидел, что мой сниппет неверно указывает при загрузке формы редактирования группу пользователя.
Чтобы было понятней, приведу небольшой кусок кода:
if(!empty($_POST['searchname'])){
$c = $modx->newQuery('modUser');
$c->select(array(
$modx->getSelectColumns('modUser', 'modUser'),
$modx->getSelectColumns('modUserProfile', 'Profile', ''),
));
$c->leftJoin('modUserProfile', 'Profile');
$c->where(array(
'username:LIKE' => '%'.$_POST['searchname'].'%',
'OR:Profile.email:LIKE' => '%'.$_POST['searchname'].'%',
'OR:Profile.fullname:LIKE' => '%'.$_POST['searchname'].'%'
));
$users = $modx->getCollection('modUser', $c);
$out = '';
if(!empty($users)){
foreach($users as $user){
$uArray = $user->toArray();
$uArray['id'] = $uArray['internalKey']; //перезаписываю id пользователя, затёртое профилем
$groupMember = reset($user->getMany('UserGroupMembers'));
if($groupMember instanceof modUserGroupMember) {
$group = $groupMember->getOne('UserGroup');
}
if(!empty($group)) {
$uArray['group'] = $group->toArray();
}else{$uArray['group']['name'] = 'Не является членом групп';}
$out .= $modx->getChunk('userSearchItem', $uArray);
}
return $modx->toJSON(array('success' => 1, 'result' => $out));
}
return $modx->toJSON(array('success' => 0, 'message' => 'Ничего не найдено'));
}
Если кратко, то в поле поиска можно ввести логин, имя или мэил пользователя, после чего сниппет отдаст найденные результаты, предварительно подставив их в чанк.Пользователь является членом группы «Группа 1», а в массив $uArray['group']['name'] попадает значение «Группа 2», что не соответствует действительности. Причина, как я полагаю, в лефт джойне профиля. Еще на стадии написания сниппета я заметил, что в $uArray['id'] записывается не id пользователя, а id профиля. Для исправления я подменяю в полученном в результате метода modUser::toArray() массиве поле id полем internalKey.
Однако, $user->getMany('UserGroupMembers') отрабатывает неправильно, поскольку у объекта $user вместо собственного id всё еще id из таблицы _user_attributes, приджойненой в процессе формирования запроса. То есть, берется группа пользователя с другим id.
Разумеется, это проблему можно легко решить, добавив перед $user->getMany('UserGroupMembers') строчку $user->id = $user->internalKey.
Но я чувствую, что во всём этом есть что-то неправильное.
Поэтому у меня к Вам вопрос: это некорректная работа modX::getCollection при передаче в параметр criteria объекта xPDOQuery с лефт-джойном или это моя ошибка и я неправильно приджойнил?
Заранее благодарю за ответ!
Комментарии: 4
Выбирайте только те поля, которые действительно нужны.
Третий параметр у функции getSelectColumns — префикс, с помощью которого вы можете отделить одинаково названные столбцы. У Вас как раз задано пустой строкой.
Третий параметр у функции getSelectColumns — префикс, с помощью которого вы можете отделить одинаково названные столбцы. У Вас как раз задано пустой строкой.
Спасибо за дельный совет!
Это ответ на все ваши вопросы. Если бы Вы выбирали поля по необходимости использования, то это выглядело примерно так:
Если выбирать все столбцы, то нужно использовать префиксы, и опять же не было бы проблем.
Как Вы составили criteria, так и отработал getCollection.
$users->select(array(
'modUser.id',
'modUser.username',
'Profile.fullname',
'Profile.email',
'Profile.extended'
));
и никаких проблем бы сразу не было.Если выбирать все столбцы, то нужно использовать префиксы, и опять же не было бы проблем.
Как Вы составили criteria, так и отработал getCollection.
Так я же без всякого сарказма написал:)) Действительно спасибо за дельный совет!
Я уже все сделал именно как Вы и написали в последнем комментарии и всё работает. И даже уже статус вопроса успел поменять на «Решено».
Я уже все сделал именно как Вы и написали в последнем комментарии и всё работает. И даже уже статус вопроса успел поменять на «Решено».
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.