Интерфейс бана пользователя
Смотрю, что-то заметка про аватар пользователя оказалась слишком простой, поднимем немного градус.
Покажу как будет выглядеть интерфейс бана пользователя по итогу.
Ниже представлен код, куски которого когда-то писали коллеги по данному сайту и чатику в телеграме.
А я уже дописал чего не хватало и собрал все в кучку.
Необходимо будет выполнить несколько шагов
isbanned: int. по умолчанию: 0
banneduntil: datetime. по умолчанию: NULL
banned_noticed: int. по умолчанию: 0
banned_notice_text: text
— OnMODXInit
— OnUserFormPrerender
— OnUserSave
Чанк письма emailUserBanned, в него передается плейсхолдер text. Для тестирования достаточно в данном чанке вызвать плейсхолдер
isbanned: Забанен пользователь или нет (1|0)
banneduntil: Дата, до которой он забнен
banned_noticed: Был ли уже уведомлен пользователь (данное поле не выведено в интерфейс)
banned_notice_text: Текст сообщения для пользователя
Комментарии сделаны с помощью компонента Tickets.
Чтобы не дать пользователю комментировать можно:
1) Скрыть форму
В чанке или в шаблоне простое условие на феноме:
2) Плагином проверять может ли юзер писать комментарии
Событие OnBeforeCommentSave
Ну и бонусом сниппет, который проверяет если юзер забанен и не истек ли срок бана. Код можно перетащить в плагин, кому надо, приложите немного усилий.
Я вызываю сниппет на каждой странице
Затем в чанках и шаблонах будет доступен плейсхолдер banned
Покажу как будет выглядеть интерфейс бана пользователя по итогу.
Ниже представлен код, куски которого когда-то писали коллеги по данному сайту и чатику в телеграме.
А я уже дописал чего не хватало и собрал все в кучку.
Необходимо будет выполнить несколько шагов
- Создание полей в базе
- Плагин
- Создание чанка для письма-уведомления
Cоздать в базе следующие поля для таблицы (modx)_user_attributes:
Ниже, в плагине каждое поле описано подробнее.isbanned: int. по умолчанию: 0
banneduntil: datetime. по умолчанию: NULL
banned_noticed: int. по умолчанию: 0
banned_notice_text: text
Плагин:
- расширение класса пользователя
- интерфейс на extjs
- уведомление пользователя (если необходимо)
— OnMODXInit
— OnUserFormPrerender
— OnUserSave
<?php
switch ($modx->event->name) {
// Расширяем класс пользователя
case "OnMODXInit":
$modx->loadClass('modUserProfile');
//////////////////////////////
$modx->map['modUserProfile']['fields']['isbanned'] = 0;
$modx->map['modUserProfile']['fieldMeta']['isbanned'] = array(
'dbtype' => 'int',
'precision' => 1,
'attributes' => 'unsigned',
'phptype' => 'integer',
'null' => true,
'default' => 0
);
//////////////////////////////
$modx->map['modUserProfile']['fields']['banneduntil'] = NULL;
$modx->map['modUserProfile']['fieldMeta']['banneduntil'] = array(
'dbtype' => 'datetime',
'phptype' => 'datetime',
'null' => true
);
//////////////////////////////
$modx->map['modUserProfile']['fields']['banned_noticed'] = 0;
$modx->map['modUserProfile']['fieldMeta']['banned_noticed'] = array(
'dbtype' => 'int',
'precision' => 1,
'attributes' => 'unsigned',
'phptype' => 'integer',
'null' => true,
'default' => 0,
);
//////////////////////////////
$modx->map['modUserProfile']['fields']['banned_notice_text'] = 0;
$modx->map['modUserProfile']['fieldMeta']['banned_notice_text'] = array(
'dbtype' => 'text',
'phptype' => 'string',
'default' => '',
);
break;
// Строим интерфейс для админа
case "OnUserFormPrerender":
if (!isset($user) || $user->get('id') < 1) {
return;
}
if (!$modx->getCount('modPlugin', array('name' => 'AjaxManager', 'disabled' => false))) {
$data['isbanned'] = $user->Profile->isbanned ? 'true' : 'false';
$data['banneduntil'] = $user->Profile->banneduntil;
$data['banned_notice_text'] = $user->Profile->banned_notice_text;
$modx->controller->addHtml("
<script type='text/javascript'>
Ext.ComponentMgr.onAvailable('modx-user-tabs', function() {
this.on('beforerender', function() {
// Получаем колонки первой вкладки
var leftCol = this.items.items[0].items.items[0].items.items[0];
var rightCol = this.items.items[0].items.items[0].items.items[1];
// Добавляем чекбокс
rightCol.items.insert(13, 'modx-user-isbanned', new Ext.form.Checkbox({
id: 'modx-user-isbanned',
name: 'isbanned',
hideLabel: true,
boxLabel: 'Забанить комментирование',
description: 'Запрещает комментировать новости',
xtype: 'xcheckbox',
inputValue: 1,
listeners: {
beforerender: function(that) {
that.hiddenField = new Ext.Element(document.createElement('input')).set({
type: 'hidden',
name: that.name,
value: 0,
});
},
afterrender: function(that) {
that.el.insertHtml('beforeBegin', that.hiddenField.dom.outerHTML);
},
},
checked: {$data['isbanned']},
}));
rightCol.items.insert(14, 'modx-user-banneduntil', new Ext.form.DateField({
id: 'modx-user-banneduntil',
name: 'banneduntil',
fieldLabel: 'Забанен до',
xtype: 'datefield',
anchor: '100%',
value: '{$data['banneduntil']}',
}));
rightCol.items.insert(15, 'modx-user-banned_notice_text', new Ext.form.TextArea({
id: 'modx-user-banned_notice_text',
name: 'banned_notice_text',
fieldLabel: 'Текст уведомления о бане',
xtype: 'textarea',
anchor: '100%',
value: '{$data['banned_notice_text']}',
}));
});
});
</script>
");
}
break;
// Уведомляем пользователя что его забанили - отправка письма
case "OnUserSave":
$profile = $user->getOne('Profile');
$emailTo = $profile->get('email');
$isbanned = $profile->get('isbanned');
$isnoticed = $profile->get('banned_noticed');
$notice_text = $profile->get('banned_notice_text') ?: " Вы забанены администрацией сайта";
$emailFrom = $modx->getOption('emailsender');
if($isbanned && !$isnoticed) {
$message = $modx->getChunk('emailUserBanned', [
'text' => $notice_text
]);
$modx->getService('mail', 'mail.modPHPMailer');
$modx->mail->set(modMail::MAIL_BODY,$message);
$modx->mail->set(modMail::MAIL_FROM, $emailFrom);
$modx->mail->set(modMail::MAIL_FROM_NAME, 'Администрация site.ru');
$modx->mail->set(modMail::MAIL_SUBJECT,'Пользователь забанен');
$modx->mail->address('to', $emailTo);
$modx->mail->setHTML(true);
if (!$modx->mail->send()) {
$modx->log(modX::LOG_LEVEL_ERROR,'Что-то пошло не так, уведомление пользователю о бане не отправлено: '.$modx->mail->mailer->ErrorInfo);
}
$modx->mail->reset();
$profile->set('banned_noticed',1);
$profile->save();
}
// убрать флаг что пользователь уже был уведомлён
if(!$isbanned && $isnoticed) {
$profile->set('banned_noticed',0);
$profile->save();
}
break;
}
Чанк письма emailUserBanned, в него передается плейсхолдер text. Для тестирования достаточно в данном чанке вызвать плейсхолдер
[[+text]]
По итогу в профиле пользователя мы получим следующие поляisbanned: Забанен пользователь или нет (1|0)
banneduntil: Дата, до которой он забнен
banned_noticed: Был ли уже уведомлен пользователь (данное поле не выведено в интерфейс)
banned_notice_text: Текст сообщения для пользователя
Как это все можно использовать:
Я использую для блокирования возможности комментирования пользователей.Комментарии сделаны с помощью компонента Tickets.
Чтобы не дать пользователю комментировать можно:
1) Скрыть форму
В чанке или в шаблоне простое условие на феноме:
{if $_modx->user.isbanned} тут уведомление что юзер забанен {else} тут чанк формы {/if}
2) Плагином проверять может ли юзер писать комментарии
Событие OnBeforeCommentSave
<?php
switch ($modx->event->name) {
case 'OnBeforeCommentSave':
// проверка, чтобы забаненный пользователь не пытался вставить форму в код ручками
$profile = $modx->user->getOne('Profile');
if($isbanned = $profile->get('isbanned')) {
$modx->event->output('User is banned!');
}
break;
}
Ну и бонусом сниппет, который проверяет если юзер забанен и не истек ли срок бана. Код можно перетащить в плагин, кому надо, приложите немного усилий.
Я вызываю сниппет на каждой странице
<?php
if($modx->user->isAuthenticated()) {
$profile = $modx->user->getOne('Profile');
$isbanned = $profile->get('isbanned');
$bannedtime = $profile->get('banneduntil');
if($isbanned && strtotime($bannedtime) > time()) {
$modx->setPlaceholder('banned', true);
} else {
$profile->set('isbanned', false);
$profile->set('banneduntil', null);
$profile->save();
}
}
return;
Затем в чанках и шаблонах будет доступен плейсхолдер banned
{$_modx->getPlaceholder('banned')}
Всё.