以下是中间件流程:
# Post edit
$this->get( '/edit/{id}/{slug}', \Rib\Src\Apps\Post\PostControllers\EditController::class . ':index' )
->add( new EnforceEditDelay() )
->add( new RequireOwner( 'posts' ) )
->add( new RejectBanned() )
->add( new RequireAuth() );
->add( new RejectBanned() )
导致链中的下一个中间件断开:
'Call to a member function getArguments() on null'
RequireAuth():
class RequireAuth
{
# Variable used to disable redirect to '/user/set-username' from itelf. That would cause infinite redirection loop.
# This is passed to the middleWare from the list of routes. Of course only true for '/user/set-username' pages.
private $disableUserNameValidationCheck;
function __construct( $disableUserNameValidationCheck = false )
{
$this->disableUserNameValidationCheck = $disableUserNameValidationCheck;
}
public function __invoke( Request $request, Response $response, $next )
{
$session = $_SESSION;
# User is not authenticated: we ensure this by checking his id which is necessarily set when he is logged in.
if ( ! isset( $session[ 'id' ] ) ) {
FlashMessages::flashIt( 'message', "The page you tried to access requires that you are logged in the site." );
return $response->withRedirect( '/user/login' );
}
# In case user has logged in from a social network and has not set a user name and password. Username is 'temporary-.....'
# We really want the user to set his username. So on designated page we force redirect to page to setup username and email.
if ( ! $this->disableUserNameValidationCheck and isset( $session[ 'username' ] ) and strpos( $session[ 'username' ], 'temporary' ) !== false ) {
FlashMessages::flashIt( 'message',
"This part of the site requires that you complete your profile with a definitive username and email. Thank you for your understanding." );
return $response->withRedirect( '/user/set-username' );
}
$request = $request->withAttribute( 'session', $session );
# Process regular flow if not interrupted by the middleWare.
return $next( $request, $response );
}
}
RejectBanned():
class RejectBanned
{
/**
* Reject banned user
* @param Request $request
* @param Response $response
* @param $next
* @return Response
*/
public function __invoke( Request $request, Response $response, $next )
{
$session = $request->getAttribute( 'session' ) ?? null;
# Get usergroup from db
$user = ( new DbSql() )->db()->table( 'users' )->find( $session['id'] );
$userGroup = $user->user_group;
# Store it in session
$session['user_group'] = $userGroup;
# Redirect user if usergroup = banned
if ( $userGroup === 'banned' ) {
FlashMessages::flashIt( 'message', 'You are not allowed anymore to access this resource.' );
return $response->withRedirect( '/message' );
}
# Store info for the next middleware or controller
$request = $request->withAttributes( [ 'session' => $session ] );
# User is not banned, pursue
return $next( $request, $response );
}
}
RequireOwner()(这是它中断的地方,我在其中断的地方添加了注释):
class RequireOwner
{
private $table;
function __construct( $tableName )
{
$this->table = $tableName;
}
public function __invoke( Request $request, Response $response, $next )
{
$session = $request->getAttribute( 'session' ) ?? null;
// BREAKS HERE:
$recordId = $request->getAttribute( 'route' )->getArguments()[ 'id' ] ?? null; // BREAKS HERE
$currentUserGroup = $session[ 'user_group' ] ?? null;
$currentUserId = $session[ 'id' ] ?? null;
$recordInstance = ( new DbSql() )->db()->table( $this->table )->find( $recordId );
# If any info is missing, interrupt
if ( ! $recordInstance or ! $session or ! $recordId or ! $currentUserGroup or ! $currentUserId ) {
throw new Exception( 'Missing information to determine the owner of record' );
}
# Store info for the next middleware or controller
$request = $request->withAttributes( [ 'session' => $session, 'recordInstance' => $recordInstance ] );
# User is an Admin, he can edit any post
if ( $currentUserGroup === 'admin' ) {
return $next( $request, $response );
}
# User is not owner of post
if ( $currentUserId != $recordInstance->author_id ) {
FlashMessages::flashIt( 'message', 'You must be the author of this content to be able to edit it.' );
return $response->withRedirect( '/message' );
}
# User is not admin but is owner of content
return $next( $request, $response );
}
}
那么为什么->add( new RejectBanned() )
会在下一个中间件中导致空值?
答案 0 :(得分:0)
在RejectBanned()中:
改
$request = $request->withAttributes( [ 'session' => $session ] );
到
$request = $request->withAttribute( 'session', $session );
它解决了这个问题。