My project has 2 routing prefixes apart from default route:
- Admin - all urls are accessed via project.com/admin/xxx
- Manager - all urls are accessed via project.com/manager/xxx
Since both “sections” of the app have user login (login and logout methods in UsersController) - I’m attempting to isolate these functions into a trait named LoginTrait and include the trait in UsersController under Admin and Manager.
LoginTrait
namespace App\Traits\Controller; use Cake\Event\Event; trait LoginTrait { /** * Login method * * @return \Cake\Http\Response|null */ public function login() { $user = $this->Users->newEntity(); if( $this->request->is( 'post' ) ) { try { $userDetails = $this->Users->find() ->where( [ 'Users.username' => $this->request->getData( 'username' ) ] ) ->first(); if( !$userDetails ) throw new Exception( __( 'Invalid username or password.' ) ); switch( $userDetails->auth ) { // Database Authentication case 'db': $user = $this->Auth->identify(); if( $user ) { $this->Auth->setUser( $user ); // Login success $event = new Event( 'Controller.Users.afterLogin', $this, [ 'status' => 'success' ] ); $this->eventManager()->dispatch( $event ); return $this->redirect( $this->Auth->redirectUrl() ); } else throw new Exception( __( 'Incorrect username or password.' ) ); break; // AD Authentication case 'ldap': $authenticated = $this->Users->adAuthenticate( $this->request->getData() ); if( $authenticated ) { $this->Auth->setUser( $userDetails ); // Login success $event = new Event( 'Controller.Users.afterLogin', $this, [ 'status' => 'success' ] ); $this->eventManager()->dispatch( $event ); return $this->redirect( $this->Auth->redirectUrl() ); } else throw new Exception( __( 'Incorrect username or password.' ) ); break; } } catch( Exception $ex ) { $this->log( $ex->getMessage(), 'debug' ); $this->Flash->error( $ex->getMessage() ); } } // Set default layout $this->viewBuilder()->setLayout( 'ui_login' ); } /** * Logout method */ public function logout() { $this->Flash->success( __( 'Good-Bye' ) ); $this->redirect( $this->Auth->logout() ); } }
Admin\UsersController
namespace App\Controller\Admin;
use App\Traits\Controller\LoginTrait;
/**
* Users Controller
*
* @property \App\Model\Table\UsersTable $Users
*
* @method \App\Model\Entity\User[] paginate( $object = null, array $settings = [] )
*/
class UsersController extends AppController {
use LoginTrait;
public function initialize() {
parent::initialize();
}
}
Manager\UsersController
namespace App\Controller\Manager;
use App\Traits\Controller\LoginTrait;
/**
* Users Controller
*
* @property \App\Model\Table\UsersTable $Users
*
* @method \App\Model\Entity\User[] paginate( $object = null, array $settings = [] )
*/
class UsersController extends AppController {
use LoginTrait;
public function initialize() {
parent::initialize();
}
// WHAT DO I DO HERE TO CONSUME THE EVENT???
}
The login process under Manager involves a couple of extra steps (e.g. writing some additional info. as Session variables. My idea is:
- Dispatch an event (e.g. Controller.Users.afterLogin) from the Trait following successful login.
- Consume the event only in UsersController under Manager and execute the additional code.
I’m totally new to events and looking for some guidance here on how to go about it.
Thanks.