Программно изменяем значение у пользователей, с условиями
Решил поделиться одним готовым решением. Лично мне, нужно нескольким тысячам юзеров в разных группах, раздать разные значения потраченных денег на покупки (эдакий перенос со старого сайта). Но если кто не понял, то давайте просто представим, что нам нужно изменить некоторые данные у пользователей, которые находятся в определенной группе. Казалось бы все просто. Нам нужно указать id определенной группы, вытащить из неё всех пользователей и изменить им нужные нам данные. Для многих программистов давно работающих с MODX, это дело 5-ти минут. У меня же это заняло около двух часов. В итоге решил, разу уж написал решение, нужно как обычно поделиться, мало ли кому-нибудь, когда-нибудь это понадобится. Ну или вон, Николай спарсит на модкс-клаб (шутка). =)
Сам скриптик:
P.S.
С MODX я не так давно, посему если аксакалы программирования на MODX поправят меня и мой скрипт (если это нужно), то я только за.
Сам скриптик:
<?php
$usergroup = 1; // Указываем id нужной группы
$container = $modx->newQuery('modUser');
$container->innerJoin ('modUserProfile','Profile');
$container->innerJoin ('modUserGroupMember','UserGroupMembers');
$container->innerJoin ('modUserGroup','UserGroup','`UserGroupMembers`.`user_group` = `UserGroup`.`id`');
// Указываем критерии нашей выборки
$container->where(array(
'active' => true,
'UserGroupMembers.user_group' => $usergroup
));
// Добавляем название полей, которые мы хотим видеть
$container->select(array(
'modUser.*',
'Profile.fullname',
'Profile.email',
));
$users = $modx->getCollection('modUser', $container); // Получаем массив объектов modUser
// Бежим по массиву
foreach($users as $user){
$userArray = $user->toArray();
// Показываем всех пользователей в группе (если вам это необходимо, например для проверки)
print_r(join('< br>', [ // У тега br уберите пробел
'Идентификатор = ' . $userArray['id'],
'Логин = ' . $userArray['username'],
'Имя = ' . $userArray['fullname'],
'Email = ' . $userArray['email']
]));
// Ну и всем пользователям группы указываем значение потраченых денежек на покупку
$profile = $modx->getObject('msCustomerProfile',$userArray['id']);
$profile->set('spent', 15000);
$profile->save();
}
// Сбрасываем кэш
$modx->cacheManager->refresh();
Я думаю что тут и без комментариев многое понятно. Добавлю, что условий и действий которые мы выполняем, может быть сколько угодно. Лично мой скрипт изменяет всем пользователям группы с id=1 значение spent на 15000.P.S.
С MODX я не так давно, посему если аксакалы программирования на MODX поправят меня и мой скрипт (если это нужно), то я только за.
Поблагодарить автора
Отправить деньги
Комментарии: 9
Это
echo 'Идентификатор = '.$userArray['id'].'
'
.'Логин = '.$userArray['username'].'
'
.'Имя = '.$userArray['fullname'].'
'
.'Email = '.$userArray['email'].'
';
Я бы так сделал:print_r(join(PHP_EOL, [
'Идентификатор = ' . $userArray['id'],
'Логин = ' . $userArray['username'],
'Имя = ' . $userArray['fullname'],
'Email = ' . $userArray['email'],
]);
На работу скрипта никак не влияет, но блин, красиво!)
Jevix превращает все теги BR в перенос строк (даже если эти теги внутри code). Так что, думаю, код был ещё более-менее симпатичный.
Оу, не дошло до меня, да. Тогда в моём коде вместо PHP_EOL надо прописать <br>
P.S. Всежрущий Jevix…
P.S. Всежрущий Jevix…
У меня только один вопрос — зачем в цикле сбрасывать кэш сайта? Хотя есть ещё один — а нужно ли вообще его сбрасывать?
П.С. Кроме того, не понятно, зачем подгружать коллекцию объектов для того, чтобы потом перевести в массив?
П.С. Кроме того, не понятно, зачем подгружать коллекцию объектов для того, чтобы потом перевести в массив?
С циклом это да, за такое по рукам бить надо. Спасибо поправил. А вот с коллекцией не совсем понял. А как иначе? Я получил коллекцию и мне нужно по ней пройтись, чтобы изменить значение всех пользователей ну или как минимум мне нужно получить id всех пользователей.
P.S.
Лично мне нужно сбрасывать кэш, т.к. данные потраченных денег, я вывожу на фронте у авторизированных пользователей через сниппет. При отработке скрипта без чистки кэша, на фронте данные не меняются, только если очистки кэша.
P.S.
Лично мне нужно сбрасывать кэш, т.к. данные потраченных денег, я вывожу на фронте у авторизированных пользователей через сниппет. При отработке скрипта без чистки кэша, на фронте данные не меняются, только если очистки кэша.
А вот с коллекцией не совсем понял. А как иначе?Поищи тут статьи Василия про xPDO.
Лично мне нужно сбрасывать кэш, т.к. данные потраченных денег, я вывожу на фронте у авторизированных пользователей через сниппет. При отработке скрипта без чистки кэша, на фронте данные не меняются, только если очистки кэша.Такие вещи нужно выводить через некэшированные сниппеты.
Позволю себе выложить решение с помощью modHelpers.
Вот оптимизированный вариант. Всего 2 запроса к БД
$usergroup = 1;
users()
->profile()
->select(['modUser.id, modUser.username, Profile.fullname, Profile.email' ])
->members($usergroup )
->where(['active' => true])
->each(function($user) {
foreach($user as $key => $value) {
echo $key, ": ", $value, "< br>"; // Убрать пробел
}
echo "< br>"; // Убрать пробел
// Ну и всем пользователям группы указываем значение потраченных денежек на покупку
object('msCustomerProfile',$user['id'])->set(['spent' => 15000]);
});
// Сбрасываем кэш (если нужно)
$modx->cacheManager->refresh();
Но это, конечно, очень не оптимально.Такой код оправдан только если нужно выводить данные каждого пользователя. Вопрос — а нужно ли?Вот оптимизированный вариант. Всего 2 запроса к БД
$usergroup = 1;
$ids = users()
->members($usergroup)
->where(['active' => true])
->get('id');
collection('msCustomerProfile', ['id:IN' => $ids])->set(['spent' => 15000]);
// Сбрасываем кэш (если нужно)
$modx->cacheManager->refresh();
По-моему, выглядит покороче и попроще )
П.С. Не знаю, аксакал я или нет, но просил ревью, получай )
Чуть-чуть подправил скрипт по комментариям выше, всем спасибо!
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.