Хук для списка пользователей

InstantCMS 2.X

рандомная сортировка

#1 13 октября 2025 в 22:45

Всем доброго времени.

Помогите, пожалуйста, вот с каким вопросом. На странице списка всех пользователей есть наборы (Новые, Рейтинг, Онлайн, Популярные и Группы). Нужно, чтобы первоначальный список (например, Все — бывший Новые) сортировался по дате регистрации но не возрастанию или убыванию, а рандомно.

Как я понял, мне нужно что-то сделать с этой конструкцией:

  1. 'filter' => function ($model, $dset) {
  2. return $model->orderBy('i.date_reg', 'desc');

И вроде бы все просто — нужно заменить desc на rand, но система не знает, что такое rand.

Посмотрел виджет списка контента, там рандом реализован черз запрос к БД $model->joinQuery("(SELECT FLOOR(RAND() * (SELECT MAX(id) FROM cms_{$table})) AS id)", 'x', 'i.id >= x.id');. Но там еще куча всего в этой функции, которое я не совсем понимаю.

Как правильно сделать рандомную сортировку? Благодарю.

А заодно вопрос: как вывести список пользователей по набору Рейтинг или Популярные только для одной группы пользователей, например Новые? Благодарю!

#2 14 октября 2025 в 12:56

А чего там куча? Если вы про  метод applyRandomFilter($model), то в вашем  случае будет

  1. $this->disableCache();
  2.  
  3. $table = 'cms_users';
  4.  
  5. $model->joinQuery("(SELECT FLOOR(RAND() * (SELECT MAX(id) FROM cms_{$table})) AS id)", 'x', 'i.id >= x.id');
  6.  
  7. $model->orderBy('i.date_reg');

Но только у вас наверное  не $model, а $this->model; Смотря по передаваемому параметру в метод.

#3 14 октября 2025 в 14:34

Тут ошибка закралась

Изображение

Сегодня в 12:31
#4 14 октября 2025 в 15:08

Закралась)

#5 16 октября 2025 в 19:57

Казалось бы все просто. Но для меня пока сложно. Не работает, ошибаюсь я где-то.

  1. // Пробуем сделать рандомный датасет.
  2.  
  3. $f_groups = $this->model->getFilteredGroups(); // Берем группы в настройках которых есть "Показывать в фильтре"
  4.  
  5. foreach ($f_groups as $group) { //Перебираем полученный массив групп пользователей
  6. $datasets[''] = [ //Для каждый группы формируем массив датасет
  7. 'name' => $group['name'], //Название группы в качестве названия датасета
  8. 'title' => $group['title'], //Заголовок для страницы со списком пользователей
  9. 'filter' => function ($model, $dset) { //Теперь нужно все отфильтровать по модели (запросу к БД) и группе
  10. $table = 'users'; // Таблица с пользователями (без префикса или с префиксом - ничего не меняется)
  11. $this->model->joinQuery("(SELECT FLOOR(RAND() * (SELECT MAX(id) FROM cms_{$table})) AS id)", 'x', 'i.id >= x.id'); // Сложилось ощущение, что запрос к БД вообще не участвует в выдаче
  12. $model->orderBy('i.date_reg'); // Сортируем по дате регистрации (кажется тут ошибка, список всегда выстраивается в порядке регистрации по убфыванию)
  13. return $model->filterGroupByName($dset['name']); // Фильтруем результат по группе пользователей.
  14. }
  15. ];
  16. }
  17.  

То есть как я понимаю, даже если из БД я получаю рандомный список, то этот фильтр ($model->filterGroupByName($dset['name']);) возвращает все на свои места — по дате регистрации. Если удалить этот фильтр и оставить только return $model->filterGroupByName($dset['name']); — опять ничего не меняется.

Хелп ми плийз.

#6 16 октября 2025 в 21:18

А если return $model->orderBy('i.date_reg'); ?

#7 16 октября 2025 в 22:17

Пробовал. Список не перемешивается. Я уже крутил тут как только можно.

Я пробовал использовать shuffle, но это для одномерных массивов — тут выдает ошибку.

Вопрос: можно ли в хуке написать собственную функцию перемешивания? Например что-то типа:

  1. function myshuffle($arr)
  2. {
  3. // extract the array keys
  4. $keys = [];
  5. foreach ($arr as $key => $value) {
  6. $keys[] = $key;
  7. }
  8.  
  9. // shuffle the keys
  10. for ($i = count($keys) - 1; $i >= 1; --$i) {
  11. $r = mt_rand(0, $i);
  12. if ($r != $i) {
  13. $tmp = $keys[$i];
  14. $keys[$i] = $keys[$r];
  15. $keys[$r] = $tmp;
  16. }
  17. }
  18.  
  19. // reconstitute
  20. $result = [];
  21. foreach ($keys as $key) {
  22. $result[$key] = $arr[$key];
  23. }
  24.  
  25. return $result;
  26. }
#8 17 октября 2025 в 11:33

можно ли в хуке написать собственную функцию перемешивания

iDrevniy

Можно.

#9 27 октября 2025 в 00:36
Казалось бы все просто. Но для меня пока сложно. Не работает, ошибаюсь я где-то. // Пробуем сделать рандомный датасет.
iDrevniy

Возможно проблема в этом фрагменте, но это не точно:

  1. foreach ($f_groups as $group) { //Перебираем полученный массив групп пользователей
  2. $datasets[''] = [ //Для каждый группы формируем массив датасет
  3. ....

попробуйте вместо $datasets[''] указать $datasets[$group['name']]

Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.

Похожие темы

Похожее в блогах

🍪Мы используем файлы cookie для работы сайта. Читать подробнее.