Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,77 +11,92 @@
|
||||
namespace IPS\core\modules\front\system;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\Content\Controller;
|
||||
use IPS\core\Warnings\Reason;
|
||||
use IPS\core\Warnings\Warning;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Helpers\Table\Content;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member Warnings
|
||||
*/
|
||||
class _warnings extends \IPS\Content\Controller
|
||||
class warnings extends Controller
|
||||
{
|
||||
/**
|
||||
* [Content\Controller] Class
|
||||
*/
|
||||
protected static $contentModel = 'IPS\core\Warnings\Warning';
|
||||
protected static string $contentModel = 'IPS\core\Warnings\Warning';
|
||||
|
||||
/**
|
||||
* Rebuilt FURL
|
||||
*/
|
||||
protected $rebuiltUrl = NULL;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
parent::execute();
|
||||
|
||||
if ( !\IPS\Settings::i()->warn_on )
|
||||
if ( !Settings::i()->warn_on )
|
||||
{
|
||||
\IPS\Output::i()->error( 'warning_system_disabled', '2C184/7', 403, '' );
|
||||
Output::i()->error( 'warning_system_disabled', '2C184/7', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View List
|
||||
*
|
||||
* @return void
|
||||
* @return mixed
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : mixed
|
||||
{
|
||||
/* Load the member */
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->id );
|
||||
$member = Member::load( Request::i()->id );
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C135/A', 403, '' );
|
||||
Output::i()->error( 'node_error', '2C135/A', 403, '' );
|
||||
}
|
||||
|
||||
/* Check permission */
|
||||
if ( !( \IPS\Settings::i()->warn_on AND ( \IPS\Member::loggedIn()->modPermission('mod_see_warn') or ( \IPS\Settings::i()->warn_show_own and \IPS\Member::loggedIn()->member_id == $member->member_id ) ) ) )
|
||||
if ( !( Settings::i()->warn_on AND ( Member::loggedIn()->modPermission('mod_see_warn') or ( Settings::i()->warn_show_own and Member::loggedIn()->member_id == $member->member_id ) ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
|
||||
Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
|
||||
}
|
||||
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\core\Warnings\Warning', \IPS\Http\Url::internal( "app=core&module=system&controller=warnings&id={$member->member_id}", 'front', 'warn_list', $member->members_seo_name ), array( array( 'wl_member=?', $member->member_id ) ) );
|
||||
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' ), 'warningRow' );
|
||||
$table = new Content( 'IPS\core\Warnings\Warning', Url::internal( "app=core&module=system&controller=warnings&id={$member->member_id}", 'front', 'warn_list', $member->members_seo_name ), array( array( 'wl_member=?', $member->member_id ) ) );
|
||||
$table->rowsTemplate = array( Theme::i()->getTemplate( 'system', 'core', 'front' ), 'warningRow' );
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('members_warnings', FALSE, array( 'sprintf' => array( $member->name ) ) );
|
||||
\IPS\Output::i()->breadcrumb[] = array( $member->url(), $member->name );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('members_warnings', FALSE, array( 'sprintf' => array( $member->name ) ) );
|
||||
Output::i()->breadcrumb[] = array( $member->url(), $member->name );
|
||||
|
||||
if( !\IPS\Request::i()->isAjax() )
|
||||
if( !Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'tables', 'core' )->container( (string) $table );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'tables', 'core' )->container( (string) $table );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
Output::i()->output = (string) $table;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,31 +104,31 @@ class _warnings extends \IPS\Content\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function view()
|
||||
protected function view() : void
|
||||
{
|
||||
/* Load the member */
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->id );
|
||||
$member = Member::load( Request::i()->id );
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C135/4', 403, '' );
|
||||
Output::i()->error( 'node_error', '2C135/4', 403, '' );
|
||||
}
|
||||
|
||||
/* Load it */
|
||||
try
|
||||
{
|
||||
$warning = \IPS\core\Warnings\Warning::loadAndCheckPerms( \IPS\Request::i()->w );
|
||||
$warning = Warning::loadAndCheckPerms( Request::i()->w );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C184/3', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C184/3', 404, '' );
|
||||
}
|
||||
|
||||
/* Show it */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'view_warning_details' );
|
||||
\IPS\Output::i()->breadcrumb[] = array( $member->url(), $member->name );
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=core&module=system&controller=warnings&id={$member->member_id}", NULL, 'warn_list', $member->members_seo_name ), \IPS\Member::loggedIn()->language()->addToStack('members_warnings', FALSE, array( 'sprintf' => array( $member->name ) ) ) );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'view_warning_details' ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('modcp')->warnHovercard( $warning );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'view_warning_details' );
|
||||
Output::i()->breadcrumb[] = array( $member->url(), $member->name );
|
||||
Output::i()->breadcrumb[] = array( Url::internal( "app=core&module=system&controller=warnings&id={$member->member_id}", NULL, 'warn_list', $member->members_seo_name ), Member::loggedIn()->language()->addToStack('members_warnings', FALSE, array( 'sprintf' => array( $member->name ) ) ) );
|
||||
Output::i()->breadcrumb[] = array( NULL, Member::loggedIn()->language()->addToStack( 'view_warning_details' ) );
|
||||
Output::i()->output = Theme::i()->getTemplate('modcp')->warnHovercard( $warning );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,32 +136,32 @@ class _warnings extends \IPS\Content\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function warn()
|
||||
protected function warn() : void
|
||||
{
|
||||
/* Load the member */
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->id );
|
||||
$member = Member::load( Request::i()->id );
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C135/2', 403, '' );
|
||||
Output::i()->error( 'node_error', '2C135/2', 403, '' );
|
||||
}
|
||||
|
||||
/* Permission Check */
|
||||
if ( !\IPS\Member::loggedIn()->canWarn( $member ) )
|
||||
if ( !Member::loggedIn()->canWarn( $member ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2C184/6', 403, '' );
|
||||
Output::i()->error( 'no_module_permission', '2C184/6', 403, '' );
|
||||
}
|
||||
|
||||
/* Build the form */
|
||||
$form = \IPS\core\Warnings\Warning::create();
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form = Warning::create();
|
||||
$form->class = 'ipsForm--vertical ipsForm--warn';
|
||||
$form->attributes = array( 'data-controller' => 'core.front.modcp.warnForm', 'data-member' => $member->member_id );
|
||||
$form->hiddenValues['ref'] = \IPS\Request::i()->ref;
|
||||
$form->hiddenValues['ref'] = Request::i()->ref;
|
||||
$form->hiddenValues['member'] = $member->member_id;
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_modcp.js', 'core' ) );
|
||||
$actions = \IPS\Db::i()->select( '*', 'core_members_warn_actions', NULL, 'wa_points ASC' );
|
||||
if ( \count( $actions ) )
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'front_modcp.js', 'core' ) );
|
||||
$actions = Db::i()->select( '*', 'core_members_warn_actions', NULL, 'wa_points ASC' );
|
||||
if ( count( $actions ) )
|
||||
{
|
||||
$min = NULL;
|
||||
foreach ( $actions as $a )
|
||||
@@ -158,10 +173,10 @@ class _warnings extends \IPS\Content\Controller
|
||||
break;
|
||||
}
|
||||
|
||||
$form->addSidebar( \IPS\Theme::i()->getTemplate( 'modcp' )->warnActions( $actions, $member, $min ) );
|
||||
$form->addSidebar( Theme::i()->getTemplate( 'modcp' )->warnActions( $actions, $member, $min ) );
|
||||
}
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('warn_member', FALSE, array( 'sprintf' => array( $member->name ) ) );
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('warn_member', FALSE, array( 'sprintf' => array( $member->name ) ) );
|
||||
Output::i()->output = $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,47 +184,46 @@ class _warnings extends \IPS\Content\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function acknowledge()
|
||||
protected function acknowledge() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Load the member */
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->id );
|
||||
$member = Member::load( Request::i()->id );
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C184/4', 403, '' );
|
||||
Output::i()->error( 'node_error', '2C184/4', 403, '' );
|
||||
}
|
||||
|
||||
/* Load it */
|
||||
try
|
||||
{
|
||||
$warning = \IPS\core\Warnings\Warning::loadAndCheckPerms( \IPS\Request::i()->w );
|
||||
$warning = Warning::loadAndCheckPerms( Request::i()->w );
|
||||
|
||||
if ( $warning->member !== $member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C184/5', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C184/5', 404, '' );
|
||||
}
|
||||
|
||||
/* Acknowledge it */
|
||||
$warning->acknowledged = TRUE;
|
||||
$warning->save();
|
||||
/* @note SELECT_FROM_WRITE_SERVER: Avoid issue where warning may be in writer table, but not in reader */
|
||||
$member->members_bitoptions['unacknowledged_warnings'] = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'core_members_warn_logs', array( "wl_member=? AND wl_acknowledged=0", $member->member_id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$member->members_bitoptions['unacknowledged_warnings'] = (bool) Db::i()->select( 'COUNT(*)', 'core_members_warn_logs', array( "wl_member=? AND wl_acknowledged=0", $member->member_id ), NULL, NULL, NULL, NULL, Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$member->save();
|
||||
|
||||
/* Redirect */
|
||||
if ( $redirectTo = \IPS\Request::i()->referrer() )
|
||||
if ( $redirectTo = Request::i()->referrer() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $redirectTo );
|
||||
Output::i()->redirect( $redirectTo );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $warning->url() );
|
||||
Output::i()->redirect( $warning->url() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,39 +232,40 @@ class _warnings extends \IPS\Content\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
$class = static::$contentModel;
|
||||
try
|
||||
{
|
||||
$item = $class::loadAndCheckPerms( \IPS\Request::i()->w );
|
||||
$member = \IPS\Member::load( $item->member );
|
||||
/* @var Warning $class */
|
||||
$item = $class::loadAndCheckPerms( Request::i()->w );
|
||||
$member = Member::load( $item->member );
|
||||
|
||||
if ( $item->canDelete() )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->undo ) )
|
||||
if ( isset( Request::i()->undo ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
if ( \IPS\Request::i()->undo )
|
||||
Session::i()->csrfCheck();
|
||||
if ( Request::i()->undo )
|
||||
{
|
||||
$item->undo();
|
||||
}
|
||||
$item->delete();
|
||||
\IPS\Output::i()->redirect( $member->url(), 'warn_revoked' );
|
||||
Output::i()->redirect( $member->url(), 'warn_revoked' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('modcp')->warningRevoke( $item );
|
||||
Output::i()->output = Theme::i()->getTemplate('modcp')->warningRevoke( $item );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'generic_error', '2C184/1', 403, '' );
|
||||
Output::i()->error( 'generic_error', '2C184/1', 403, '' );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C184/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C184/2', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,12 +274,12 @@ class _warnings extends \IPS\Content\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function reasonAjax()
|
||||
protected function reasonAjax() : void
|
||||
{
|
||||
/* Check permission */
|
||||
if ( ! ( \IPS\Settings::i()->warn_on AND \IPS\Member::loggedIn()->modPermission('mod_see_warn') ) )
|
||||
if ( ! ( Settings::i()->warn_on AND Member::loggedIn()->modPermission('mod_see_warn') ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
|
||||
Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
|
||||
}
|
||||
|
||||
$remove = array(
|
||||
@@ -273,9 +288,9 @@ class _warnings extends \IPS\Content\Controller
|
||||
'unlimited' => TRUE,
|
||||
);
|
||||
|
||||
if ( \IPS\Request::i()->id == 'other' )
|
||||
if ( Request::i()->id == 'other' )
|
||||
{
|
||||
\IPS\Output::i()->json( array(
|
||||
Output::i()->json( array(
|
||||
'points' => 0,
|
||||
'points_override' => TRUE,
|
||||
'remove' => $remove,
|
||||
@@ -288,19 +303,19 @@ class _warnings extends \IPS\Content\Controller
|
||||
|
||||
try
|
||||
{
|
||||
$reason = \IPS\core\Warnings\Reason::load( \IPS\Request::i()->id );
|
||||
$reason = Reason::load( Request::i()->id );
|
||||
|
||||
/* Add in the remove properties */
|
||||
if ( $reason->remove AND $reason->remove != -1 )
|
||||
{
|
||||
$date = \IPS\DateTime::create();
|
||||
$date = DateTime::create();
|
||||
if ( $reason->remove_unit == 'h' )
|
||||
{
|
||||
$date->add( new \DateInterval( "PT{$reason->remove}H" ) );
|
||||
$date->add( new DateInterval( "PT{$reason->remove}H" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$date->add( new \DateInterval( "P{$reason->remove}D" ) );
|
||||
$date->add( new DateInterval( "P{$reason->remove}D" ) );
|
||||
}
|
||||
|
||||
$remove = array(
|
||||
@@ -310,7 +325,7 @@ class _warnings extends \IPS\Content\Controller
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( array(
|
||||
Output::i()->json( array(
|
||||
'points' => $reason->points,
|
||||
'points_override' => $reason->points_override,
|
||||
'remove' => $remove,
|
||||
@@ -321,9 +336,9 @@ class _warnings extends \IPS\Content\Controller
|
||||
) );
|
||||
}
|
||||
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->json( array(
|
||||
Output::i()->json( array(
|
||||
'points' => 0,
|
||||
'points_override' => FALSE,
|
||||
'remove' => $remove,
|
||||
@@ -340,7 +355,7 @@ class _warnings extends \IPS\Content\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function actionAjax()
|
||||
protected function actionAjax() : void
|
||||
{
|
||||
$actions = array(
|
||||
'mq' => array(
|
||||
@@ -360,17 +375,17 @@ class _warnings extends \IPS\Content\Controller
|
||||
),
|
||||
);
|
||||
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->member );
|
||||
$member = Member::load( Request::i()->member );
|
||||
|
||||
/* Check permission */
|
||||
if ( !( \IPS\Settings::i()->warn_on AND ( \IPS\Member::loggedIn()->modPermission('mod_see_warn') or ( \IPS\Settings::i()->warn_show_own and \IPS\Member::loggedIn()->member_id == $member->member_id ) ) ) )
|
||||
if ( !( Settings::i()->warn_on AND ( Member::loggedIn()->modPermission('mod_see_warn') or ( Settings::i()->warn_show_own and Member::loggedIn()->member_id == $member->member_id ) ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
|
||||
Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$action = \IPS\Db::i()->select( '*', 'core_members_warn_actions', array( 'wa_points<=?', ( $member->warn_level + (int) \IPS\Request::i()->points ) ), 'wa_points DESC', 1 )->first();
|
||||
$action = Db::i()->select( '*', 'core_members_warn_actions', array( 'wa_points<=?', ( $member->warn_level + (int) Request::i()->points ) ), 'wa_points DESC', 1 )->first();
|
||||
foreach ( array( 'mq', 'rpa', 'suspend' ) as $k )
|
||||
{
|
||||
if ( $action[ 'wa_' . $k ] == -1 )
|
||||
@@ -379,18 +394,18 @@ class _warnings extends \IPS\Content\Controller
|
||||
}
|
||||
elseif ( $action[ 'wa_' . $k ] )
|
||||
{
|
||||
$date = \IPS\DateTime::ts( time() )->add( new \DateInterval( $action[ 'wa_' . $k . '_unit' ] == 'h' ? "PT{$action[ 'wa_' . $k ]}H" : "P{$action[ 'wa_' . $k ]}D" ) );
|
||||
$date = DateTime::ts( time() )->add( new DateInterval( $action[ 'wa_' . $k . '_unit' ] == 'h' ? "PT{$action[ 'wa_' . $k ]}H" : "P{$action[ 'wa_' . $k ]}D" ) );
|
||||
|
||||
$actions[ $k ]['date'] = $date->format( 'Y-m-d' );
|
||||
$actions[ $k ]['time'] = $date->format( 'H:i' );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
catch ( UnderflowException $e ) { }
|
||||
|
||||
\IPS\Output::i()->json( array(
|
||||
Output::i()->json( array(
|
||||
'actions' => $actions,
|
||||
'override' => isset( $action ) ? $action['wa_override'] : \IPS\Member::loggedIn()->modPermission('warning_custom_noaction')
|
||||
'override' => isset( $action ) ? $action['wa_override'] : Member::loggedIn()->modPermission('warning_custom_noaction')
|
||||
) );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user