(ОБНОВЛЕНИЕ) Как пользователю дать возможность менять группу пользователей в своем профиле

+24
1.97K
Иллюстрация
Как мы знаем, на данный момент устанавливать группу для пользователей возможно только в админ-панели.
Как быть, если для нашего проекта понадобилось, чтобы пользователи могли сами менять свою группу в настройках своего профиля?
В этом уроке я расскажу вам, как это реализовать.
Нам понадобится создать всего 7 файлов, и немного отредактировать 1 файл шаблона.
Итак, приступим:

1) (1-й файл) Создаем экшн.
В папке system/controllers/users/actions/ Создаем файл profile_edit_groups.php
с таким содержанием:
  1. <?php
  2.  
  3. class actionUsersProfileEditGroups extends cmsAction {
  4.  
  5. public $lock_explicit_call = true;
  6.  
  7. public function run($profile){
  8.  
  9. if (!$this->is_own_profile && !$this->cms_user->is_admin) { cmsCore::error404(); }
  10.  
  11. $form = new cmsForm();
  12.  
  13. if ($this->cms_user->is_admin) {
  14.  
  15. $fieldset_groups = $form->addFieldset('Группа');
  16.  
  17. $form->addField($fieldset_groups,
  18. new fieldListGroups('groups', array(
  19. 'show_all' => false,
  20. 'rules' => array(
  21. array('required')
  22. )
  23. ))
  24. );
  25.  
  26. $fieldset_id = $form->addFieldset('Запретить пользователям самостоятельный переход в группы:');
  27.  
  28. $form->addField($fieldset_id,
  29. new fieldListGroupsSet('groups_set', array(
  30. 'show_all' => false,
  31. 'rules' => array(
  32. array('required')
  33. )
  34. ))
  35. );
  36.  
  37. } else {
  38.  
  39. $fieldset_groups = $form->addFieldset('Группа');
  40.  
  41. $form->addField($fieldset_groups,
  42. new fieldListGroupsprofile('groups', array(
  43. 'show_all' => false,
  44. 'rules' => array(
  45. array('required')
  46. )
  47. ))
  48. );
  49.  
  50. }
  51.  
  52. $is_submitted = $this->request->has('submit');
  53.  
  54. $data = array();
  55.  
  56. if ($is_submitted){
  57.  
  58. $data = $form->parse($this->request, $is_submitted);
  59.  
  60. $errors = $form->validate($this, $data);
  61.  
  62. $usersgrpoups_model = cmsCore::getModel('usersgroups');
  63.  
  64. if (!$this->cms_user->is_admin) {
  65.  
  66. $usersgrpoups = $usersgrpoups_model->getGroups();
  67.  
  68. if($usersgrpoups){
  69.  
  70. $usersgrpoups = cmsModel::yamlToArray($usersgrpoups[1]['groups']);
  71.  
  72. if(!empty($data['groups'])){
  73.  
  74. $intersect = !empty(array_intersect($data['groups'], $usersgrpoups));
  75.  
  76. if($intersect) { $errors = true; }
  77.  
  78. }
  79. }
  80.  
  81. }
  82.  
  83.  
  84. if (!$errors){
  85.  
  86. $profile = array_merge($profile, $data);
  87.  
  88. if ($this->cms_user->is_admin) {
  89. $usersgrpoups_model->updateUserGroupsSet($data);
  90. }
  91.  
  92. $result = $this->model->updateUser($profile['id'], $profile);
  93.  
  94. if ($result['success']){
  95. cmsUser::addSessionMessage('Группа изменена', 'success');
  96. $this->redirectTo('users', $profile['id']);
  97. } else {
  98. $errors = $result['errors'];
  99. }
  100.  
  101. }
  102.  
  103. if ($errors){
  104. cmsUser::addSessionMessage(LANG_FORM_ERRORS, 'error');
  105. }
  106.  
  107. }
  108.  
  109. return $this->cms_template->render('profile_edit_groups', array(
  110. 'id' => $profile['id'],
  111. 'profile' => $profile,
  112. 'data' => $data,
  113. 'form' => $form,
  114. 'errors' => isset($errors) ? $errors : false
  115. ));
  116.  
  117. }
  118.  
  119. }
  120.  
2) (2-й файл) Создаем шаблон для страницы с выбором группы.
В папке templates/default/controllers/users/ Создаем файл profile_edit_groups.tpl.php
с таким содержанием:
  1. <?php
  2.  
  3. $this->setPageTitle(LANG_USER_GROUP);
  4.  
  5. if($this->controller->listIsAllowed()){
  6. $this->addBreadcrumb(LANG_USERS, href_to('users'));
  7. }
  8. $this->addBreadcrumb($profile['nickname'], href_to('users', $id));
  9. $this->addBreadcrumb(LANG_USERS_EDIT_PROFILE, href_to('users', $id, 'edit'));
  10. $this->addBreadcrumb(LANG_USER_GROUP);
  11.  
  12. $this->addToolButton(array(
  13. 'class' => 'save',
  14. 'title' => LANG_SAVE,
  15. 'href' => "javascript:icms.forms.submit()"
  16. ));
  17.  
  18. $this->addToolButton(array(
  19. 'class' => 'cancel',
  20. 'title' => LANG_CANCEL,
  21. 'href' => href_to('users', $id)
  22. ));
  23.  
  24.  
  25. ?>
  26.  
  27. <?php $this->renderChild('profile_edit_header', array('profile'=>$profile)); ?>
  28.  
  29. <?php
  30. $this->renderForm($form, $profile, array(
  31. 'action' => '',
  32. 'method' => 'post',
  33. 'toolbar' => false
  34. ), $errors);
  35.  
3) (3-й файл) Создаем поле "Группы профиля".
В папке system/fields/ Создаем файл listgroupsprofile.php
с таким содержанием:
  1. <?php
  2.  
  3. class fieldListGroupsprofile extends cmsFormField {
  4.  
  5. public $title = 'Группы профиля';
  6. public $is_public = false;
  7. public $sql = 'text NULL DEFAULT NULL';
  8. public $allow_index = false;
  9. public $var_type = 'array';
  10.  
  11. public function getOptions(){
  12. return array(
  13. new fieldCheckbox('show_all', array(
  14. 'title' => LANG_PARSER_LIST_MULTIPLE_SHOW_ALL,
  15. 'default' => 1
  16. )),
  17. new fieldCheckbox('show_guests', array(
  18. 'title' => LANG_PARSER_LIST_GROUPS_SHOW_GUESTS,
  19. 'default' => 0
  20. )),
  21. );
  22. }
  23.  
  24. public function getListItems(){
  25.  
  26. $usersgrpoups_model = cmsCore::getModel('usersgroups');
  27.  
  28. $usersgrpoups = $usersgrpoups_model->getGroups();
  29.  
  30. $users_model = cmsCore::getModel('users');
  31.  
  32. $items = $this->getProperty('show_all') ? array(0 => LANG_ALL) : array();
  33.  
  34. $groups = $users_model->getGroups((bool)$this->getProperty('show_guests'));
  35.  
  36. if($usersgrpoups){
  37. $usersgrpoups = cmsModel::yamlToArray($usersgrpoups[1]['groups']);
  38. foreach($usersgrpoups as $usersgroup){
  39. unset($groups[$usersgroup]);
  40. }
  41. }
  42.  
  43. foreach($groups as $group){
  44. $items[$group['id']] = $group['title'];
  45. }
  46.  
  47. return $items;
  48.  
  49. }
  50.  
  51. public function getInput($value){
  52.  
  53. $this->data['groups'] = $this->getListItems();
  54.  
  55. if(!is_array($value)){
  56. $value = cmsModel::yamlToArray($value);
  57. }
  58.  
  59. return parent::getInput($value ? $value : array(0));
  60.  
  61. }
  62.  
  63. }
  64.  
4) (4-й файл) Создаем поле "Группы-ограничения".
В папке system/fields/ Создаем файл listgroupsset.php
с таким содержанием:
  1. <?php
  2.  
  3. class fieldListGroupsset extends cmsFormField {
  4.  
  5. public $title = 'Группы-ограничения';
  6. public $is_public = false;
  7. public $sql = 'text NULL DEFAULT NULL';
  8. public $allow_index = false;
  9. public $var_type = 'array';
  10.  
  11. public function getOptions(){
  12. return array(
  13. new fieldCheckbox('show_all', array(
  14. 'title' => LANG_PARSER_LIST_MULTIPLE_SHOW_ALL,
  15. 'default' => 1
  16. )),
  17. new fieldCheckbox('show_guests', array(
  18. 'title' => LANG_PARSER_LIST_GROUPS_SHOW_GUESTS,
  19. 'default' => 0
  20. )),
  21. );
  22. }
  23.  
  24. public function getListItems(){
  25.  
  26. $users_model = cmsCore::getModel('users');
  27.  
  28. $items = $this->getProperty('show_all') ? array(0 => LANG_ALL) : array();
  29.  
  30. $groups = $users_model->getGroups((bool)$this->getProperty('show_guests'));
  31.  
  32. foreach($groups as $group){
  33. $items[$group['id']] = $group['title'];
  34. }
  35.  
  36. return $items;
  37.  
  38. }
  39.  
  40. public function getInput($value){
  41.  
  42.  
  43. $this->data['groups'] = $this->getListItems();
  44.  
  45. $usersgrpoups_model = cmsCore::getModel('usersgroups');
  46. $usersgrpoups = $usersgrpoups_model->getGroups();
  47. if($usersgrpoups){
  48. $value = cmsModel::yamlToArray($usersgrpoups[1]['groups']);
  49. }
  50.  
  51. return parent::getInput($value ? $value : array(0));
  52.  
  53. }
  54.  
  55. }
5) (5-й файл) Создаем шаблон для "Группы профиля".
В папке templates/default/assets/fields/ Создаем файл listgroupsprofile.tpl.php
с таким содержанием:
  1. <?php if ($field->title) { ?><label for="<?php echo $field->id; ?>"><?php echo $field->title; ?></label><?php } ?>
  2. <?php echo html_select_multiple($field->element_name, $field->data['groups'], $value, array('id'=>$field->id)); ?>
  3.  
  4. <script type="text/javascript">
  5. $(function() {
  6. $('#<?php echo $field->id; ?> input').on('click', function (){
  7. v = $(this).val();
  8. p = $(this).parents('.input_checkbox_list');
  9. if(v==0){
  10. $('input', p).not('input[value="0"]').prop('checked', false);
  11. } else {
  12. $('input[value="0"]', p).prop('checked', false);
  13. }
  14. });
  15. });
  16. </script>
6) (6-й файл) Создаем шаблон для "Группы-ограничения".
В папке templates/default/assets/fields/ Создаем файл listgroupsset.tpl.php
с таким содержанием:
  1. <?php if ($field->title) { ?><label for="<?php echo $field->id; ?>"><?php echo $field->title; ?></label><?php } ?>
  2. <?php echo html_select_multiple($field->element_name, $field->data['groups'], $value, array('id'=>$field->id)); ?>
  3.  
  4. <script type="text/javascript">
  5. $(function() {
  6. $('#<?php echo $field->id; ?> input').on('click', function (){
  7. v = $(this).val();
  8. p = $(this).parents('.input_checkbox_list');
  9. if(v==0){
  10. $('input', p).not('input[value="0"]').prop('checked', false);
  11. } else {
  12. $('input[value="0"]', p).prop('checked', false);
  13. }
  14. });
  15. });
  16. </script>
7) (7-й файл) Создаем модель.
В папке system/controllers/ Создаем ПАПКУ usersgroups
В папке system/controllers/usersgroups/ Создаем файл model.php
с таким содержанием:
  1. <?php
  2.  
  3. class modelUsersgroups extends cmsModel {
  4.  
  5. public function getGroups(){
  6.  
  7. return $this->get('cms_users_groups_set');
  8.  
  9. }
  10.  
  11. public function updateUserGroupsSet($data){
  12.  
  13. $data = array('groups' => $data['groups_set']);
  14.  
  15. return $this->update('cms_users_groups_set', 1, $data);
  16.  
  17. }
  18.  
  19. }
После того, как файлы созданы, остается отредактировать 1 файл шаблона.
В нем мы добавим один пункт меню, чтобы в настройках можно было перейти на страницу редактирования группы пользователя.

8) В папке templates/default/controllers/users/ В файле profile_edit_header.tpl.php
заменяем все содержимое на этот код:
  1. <?php
  2.  
  3. $edit_menu = $this->controller->getProfileEditMenu($profile);
  4. $edit_menu[] = array(
  5. 'title' => 'Группа',
  6. 'controller' => 'users',
  7. 'action' => $profile['id'],
  8. 'params' => array('edit', 'groups')
  9. );
  10.  
  11. $this->addMenuItems('profile_tabs', $edit_menu);
  12.  
  13. ?>
  14.  
  15. <h1><?php echo LANG_USERS_EDIT_PROFILE; ?></h1>
  16.  
  17. <div id="user_profile_tabs">
  18. <div class="tabs-menu">
  19. <?php $this->menu('profile_tabs', true, 'tabbed', 7); ?>
  20. </div>
  21. </div>
  22.  
Теперь делаем запрос в БД. В запросе вместо "БАЗА_ДАННЫХ" укажите свою.

  1. CREATE TABLE `БАЗА_ДАННЫХ`.`cms_users_groups_set` ( `id` INT(1) UNSIGNED NULL DEFAULT NULL AUTO_INCREMENT , `groups` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;
  2.  
  3. INSERT INTO `cms_users_groups_set` (`id`, `groups`) VALUES ('1', '---\r\n- 6\r\n');
Администратор задает ограничение, в какие группы запрещен самостоятельный переход
Иллюстрация
Другим пользователям отображаются только те группы, в которые можно перейти.
Иллюстрация

Готово! Теперь у пользователей вашего сайта появилась возможность изменять группу в настройках своего профиля.
Понравился урок? Ставь большой палец вверх! Это мотивирует автора создавать новые уроки!
В следующей статье мы рассмотрим: "Как вывести фотографии пользователя на странице его профиля."
+2
Алексей Т Алексей Т 5 лет назад #
Спасибо- полено+
+1
ХурумБурум ХурумБурум 5 лет назад #
Вот что значит могучий русский язык. Вместо одного получилось другое. joke
+1
Donto Donto 5 лет назад #
Очень круто! Спасибо большое!
+2
Андрей Андрей 5 лет назад #
Лайкнул, а где это может пригодиться?
+2
SpideR SpideR 5 лет назад #
Отлично, спасибо! Но было бы хорошо если бы в коде можно было указывать какие группы могут выбирать пользователи, указывать их id например. Потому как групп может быть много, и редакторские, и админские, и модераторские, и пользователи не должны иметь доступа к ним.
+4
Александр Александр 5 лет назад #
просто и полезно, но без предустановок, какие группы можно выбирать а какие нет, просто не имеет смысла
+2
RSN RSN 5 лет назад #
а где это может пригодиться?

Например если надо отнести себя к какой то группе (пример в Sape "Вебмастера" и "Рекламодатели" и т.п.) с определенными возможностями для группы.

Однако правильно отмечено:
но без предустановок, какие группы можно выбирать а какие нет, просто не имеет смысла
+3
Red-Ray.Ru Red-Ray.Ru 5 лет назад #
Решение сделал для темы /forum/thread31728-1.html#310921
Полностью с вами согласен, что нужно добавить ограничение для выбора группы.
Добавлю эту возможность.
+3
Red-Ray.Ru Red-Ray.Ru 5 лет назад #
Добавил ограничение, в какие группы запрещен самостоятельный переход.
Теперь пользователи могут перейти только в те группы, в которые разрешил администратор.
0
Honko Honko 5 лет назад #
еще не попробовал, но по описанию получилось просто шикарно!
+1
SpideR SpideR 5 лет назад #
Отлично! Может сделаете в виде компонента и выложите в каталог дополнений?
+4
Red-Ray.Ru Red-Ray.Ru 5 лет назад #
Да, сделаю отдельным компонентом и выложу в каталог дополнений.
0
RSN RSN 5 лет назад #
Да, сделаю отдельным компонентом и выложу в каталог дополнений.

Да, и кстати отличны способ монетизировать разработку, кто хочет может изменять файлы по этой инструкции, а кто не хочет, может купить готовое решение.

Впрочем это конечно Вам решать.

И да, в случае компонента было бы неплохо добавить виджет (который можно разместить где удобно) с кнопками перехода в группу.

Зарегистрировался на сайте, попал в группу например "Новые", а дальше уже видишь кнопки виджета и выбираешь в какую группу надо...
(Такой упрощенный вариант, что бы не решать вопрос как регистрировать Гостя...).
0
Александр Александр 5 лет назад #
Вот теперь отлично.

У smartcontrol был платный компонент который в том числе мог делать переход/вступление/выход по ссылке, но выше 2.10 он неработает
0
Donto Donto 5 лет назад #
И сам он, к сожалению, куда-то пропал
0
lesterkey lesterkey 5 лет назад #
Простите меня! просто читаю, и думаю... куда то обсуждение пошло в сторону! (платность, монетизация, свободный выбор группы)
scratch Как я вижу?: Автор предложил решение , за что ему огромный респект и жирный плюс!
Но по моему данное бесплатное решение может подойти в одном варианте: если есть скажем закрытый корпоративный сайт, где сотрудники сами наполняют его с учетом наделенных прав. и после регистрации они с легкостью могут выбрать свою группу и продолжить работать!
А уж если говорить о (Вебмастерах, разработчиках или рекламодателях) ,тут конечно надо смотреть что мы хотим получит от сайта на "выхлопе". если уж люди хотят зарабатывать или продавать на вашем проэкте то почему бы не взять с низ "мзду"...?
Так что есть отличный компонент Биллинг пользователей который решает все задачи сразу... + дает массу других возможностей.. (создал тарифный план Рекламодатель дал описание. назначил цену перехода в эту группу и время (например на год.) Человек зарегистрировался... захотел дать рекламку, купил тариф... получил право на рекламу и дело в шляпе.. прошел год человек опять пользователь...
Так что ОГРОМНОЕ спасибо за дополнение и развитие InstantCMS... ставим автору лайки и стимулируем его на дальнейшие идеи...
joke Простите меня если кого то зацепил!
0
RSN RSN 5 лет назад #
платность, монетизация, свободный выбор группы

Если об моем предложении, может я не правильно выразился... я имел ввиду монетизацию для автора (а не нас вебмастеров)..., что Red Ray может сделать платный компонент))

... кто хочет делает себе бесплатно по инструкции, или покупает компонент (если не хочет возится с кодом)...

Относительно использования я привел лишь пример на вопрос:
а где это может пригодиться?

Естественно использовать можно на сколько хватит ума и фантазии мастера))
0
Эндрю Ua Эндрю Ua 5 лет назад #
Там выбор можно выбрать хоть в 3 группы сразу. Как то не очень, если бы можно было указать сколько груп может выбрать пользователь

Еще от автора

Новогодние скидки 20 _ 24% на дополнения!
Встречайте Новый год с выгодой! Скидка 24% на плагины — ваш идеальный шанс украсить праздничный сезон дополнительными возможностями.
Аудиоплеер для контента
Аудиоплеер позволяет проигрывать аудиофайлы в списке записей типа контента, а также в самой записи -Фиксация плеера при прокрутке страницы -загрузка и
Платные Группы (Сообщества)
Компонент позволяет вступать в Группы(Сообщества) на платной основе и на определенный период времени Варианты применения: 1.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.