Программно изменяем значение у пользователей, с условиями

Решил поделиться одним готовым решением. Лично мне, нужно нескольким тысячам юзеров в разных группах, раздать разные значения потраченных денег на покупки (эдакий перенос со старого сайта). Но если кто не понял, то давайте просто представим, что нам нужно изменить некоторые данные у пользователей, которые находятся в определенной группе. Казалось бы все просто. Нам нужно указать id определенной группы, вытащить из неё всех пользователей и изменить им нужные нам данные. Для многих программистов давно работающих с MODX, это дело 5-ти минут. У меня же это заняло около двух часов. В итоге решил, разу уж написал решение, нужно как обычно поделиться, мало ли кому-нибудь, когда-нибудь это понадобится. Ну или вон, Николай спарсит на модкс-клаб (шутка). =)

Сам скриптик:
<?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 поправят меня и мой скрипт (если это нужно), то я только за.
iWatchYouFromAfar
10 декабря 2018, 22:01
modx.pro
8
1 449
+8
Поблагодарить автора Отправить деньги

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

Павел Гвоздь
11 декабря 2018, 07:06
1
+2
Это
echo 'Идентификатор = '.$userArray['id'].'
'
      .'Логин = '.$userArray['username'].'
'
      .'Имя = '.$userArray['fullname'].'
'
      .'Email = '.$userArray['email'].'

';
Я бы так сделал:
print_r(join(PHP_EOL, [
    'Идентификатор = ' . $userArray['id'],
    'Логин = ' . $userArray['username'],
    'Имя = ' . $userArray['fullname'],
    'Email = ' . $userArray['email'],
]);
На работу скрипта никак не влияет, но блин, красиво!)
    Илья Уткин
    11 декабря 2018, 08:29
    +2
    Jevix превращает все теги BR в перенос строк (даже если эти теги внутри code). Так что, думаю, код был ещё более-менее симпатичный.
      Павел Гвоздь
      11 декабря 2018, 08:38
      +2
      Оу, не дошло до меня, да. Тогда в моём коде вместо PHP_EOL надо прописать <br>

      P.S. Всежрущий Jevix…
    Сергей Шлоков
    11 декабря 2018, 10:28
    +2
    У меня только один вопрос — зачем в цикле сбрасывать кэш сайта? Хотя есть ещё один — а нужно ли вообще его сбрасывать?

    П.С. Кроме того, не понятно, зачем подгружать коллекцию объектов для того, чтобы потом перевести в массив?
      iWatchYouFromAfar
      11 декабря 2018, 12:40
      0
      С циклом это да, за такое по рукам бить надо. Спасибо поправил. А вот с коллекцией не совсем понял. А как иначе? Я получил коллекцию и мне нужно по ней пройтись, чтобы изменить значение всех пользователей ну или как минимум мне нужно получить id всех пользователей.

      P.S.
      Лично мне нужно сбрасывать кэш, т.к. данные потраченных денег, я вывожу на фронте у авторизированных пользователей через сниппет. При отработке скрипта без чистки кэша, на фронте данные не меняются, только если очистки кэша.
        Сергей Шлоков
        11 декабря 2018, 13:38
        0
        А вот с коллекцией не совсем понял. А как иначе?
        Поищи тут статьи Василия про xPDO.

        Лично мне нужно сбрасывать кэш, т.к. данные потраченных денег, я вывожу на фронте у авторизированных пользователей через сниппет. При отработке скрипта без чистки кэша, на фронте данные не меняются, только если очистки кэша.
        Такие вещи нужно выводить через некэшированные сниппеты.
      Сергей Шлоков
      11 декабря 2018, 10:37
      +3
      Позволю себе выложить решение с помощью modHelpers.
      $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();
      По-моему, выглядит покороче и попроще )
        Сергей Шлоков
        11 декабря 2018, 10:40
        +3
        П.С. Не знаю, аксакал я или нет, но просил ревью, получай )
          iWatchYouFromAfar
          11 декабря 2018, 12:41
          0
          Чуть-чуть подправил скрипт по комментариям выше, всем спасибо!
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            9