Welcome Guest, Not a member yet? Register   Sign In
problem with custom controller constructor
#11

(This post was last modified: 06-23-2022, 12:01 AM by groovebird.)

Hi,

in the constructor i loaded models, settings and checked if access for the user is possible. All things i need throughout the controller. This is a good place until i need access to the request object. Why is this bad practice? What is the better way except overwriting the initController function or loading the request service ?
Reply
#12

Bad practice may have been an exaggeration.

Of course you can use __construct() unless you don't use  the request object or something that initController() initializes.
True bad practice is try to use uninitialized things. You don't need to do that.

If you want to do something with the request object, you can use Controller Filters.
Reply
#13

I solved this by instantiating the following classes which are already instantiated in BaseController, parent class:
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
Reply
#14

(05-29-2021, 10:18 AM)tino Wrote: i have a SignupController with some methods in it.
these methods use the $session object, which is declared in BaseController::initController(), and everything works fine.

BaseController, i only declared the protected $session property and initialized in initController():
PHP Code:
<?php

namespace App\Controllers;

use 
CodeIgniter\Controller;
use 
CodeIgniter\HTTP\CLIRequest;
use 
CodeIgniter\HTTP\IncomingRequest;
use 
CodeIgniter\HTTP\RequestInterface;
use 
CodeIgniter\HTTP\ResponseInterface;
use 
Psr\Log\LoggerInterface;

/**
 * Class BaseController
 *
 * BaseController provides a convenient place for loading components
 * and performing functions that are needed by all your controllers.
 * Extend this class in any new controllers:
 *    class Home extends BaseController
 *
 * For security be sure to declare any new methods as protected or private.
 */

class BaseController extends Controller
{
 
/**
 * Instance of the main Request object.
 *
 * @var IncomingRequest|CLIRequest
 */
 
protected $request;

 
/**
 * An array of helpers to be loaded automatically upon
 * class instantiation. These helpers will be available
 * to all other controllers that extend BaseController.
 *
 * @var array
 */
 
protected $helpers = [];

 protected 
$session;

 
/**
 * Constructor.
 *
 * @param RequestInterface  $request
 * @param ResponseInterface $response
 * @param LoggerInterface  $logger
 */
 
public function initController(RequestInterface $requestResponseInterface $responseLoggerInterface $logger)
 {
 
// Do Not Edit This Line
 
parent::initController($request$response$logger);

 
//--------------------------------------------------------------------
 // Preload any models, libraries, etc, here.
 //--------------------------------------------------------------------
 // E.g.: $this->session = \Config\Services::session();
 
$this->session session();
 }


i want the SignupController to be accessible only if the session isn't set, so i used to to an if like this in the multiple methods of the SignupController
PHP Code:
if ($this->session->is_logged_id) {
    return redirect()->to("/")


the fact is that i'm trying to refactor everything for better readability and i decided to create a constructor in the SignupController and move the above if in it, so the code looks like this:

PHP Code:
<?php

namespace App\Controllers\Signup;

use 
App\Controllers\BaseController;
use 
CodeIgniter\HTTP\RedirectResponse;

class 
SignupController extends BaseController {

    /**
    * when an instance of this class is created
    * redirect if the user is already logged in
    */
    public function __construct() {
        if ($this->session->is_logged_in) {
            return redirect()->to("/");
        }
    }

    /**
    * shows the signup page
    */
    public function index() {
        // do stuff...
        echo view("signup");
    }

    public function signup() {
        // do stuff...
    }


the problem is that it's like BaseController::initController() is called after my own constructor, so the $session property is set only after the execution of my SignupController::__constructor()

i say this because i tried to do a var_dump() of the $session property inside of SignupController::__constructor() and the output is null, but if i try to do the same thing in the other SignupController methods i can actually see that $session is an object with its properties and methods...



Hi,

Try to create 
app/Filters create an auth file there to validate exp: auth.php

<?php namespace App\Filters;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
class Auth implements FilterInterface
{
public function before(RequestInterface $request, $arguments = null)
{
// if user not logged in
if(! session()->get('logged_in')){
// then redirct to login page
return redirect()->to('/login');
}
}
//--------------------------------------------------------------------
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// Do something here
}
}


After that, open the “Filters.php” file located in the “app/Config” folder, then find the following code:

public $aliases

add one line with

public $aliases = [
'csrf'    => \CodeIgniter\Filters\CSRF::class,
'toolbar'  => \CodeIgniter\Filters\DebugToolbar::class,
'honeypot' => \CodeIgniter\Filters\Honeypot::class,
'auth'    => \App\Filters\Auth::class,---------------------------------this line

Next, open the “Routes.php” file located in the “app/Config” folder, then find the following code:


$routes->get('/dashboard', 'Dashboard::index',['filter' => 'auth']);

this is a better approach to deal with redirect to login
Reply
#15

I have tried to move the stuff I usually do in __constructor to initController() method. It seems to work (and I can avoid initializing the things again that have been initialized  in the BaseController's initController() function. However, the vscode shows a nasty warning:

Quote:Method 'App\Controllers\Booking::initController()' is not compatible with method 'App\Controllers\BaseController::initController()'.intelephense(1038)
What should I make of that? Is intelephense wrong, or am I not seeing something? 

Hard to ignore it psychologically, it triggers me Smile

here is my modified controller (with the previous code commented out:



PHP Code:
class Booking extends BaseController
{
    protected $bookingModel;
    protected $usersModel;
    protected $pagesModel;
    protected $roomsModel;
    protected $eventTypesModel;
    protected $hours;
    protected $rooms;
    protected $validation;

    public function initController(RequestInterface $requestResponseInterface $responseLoggerInterface $logger)
    {
        // Do Not Edit This Line
        parent::initController($request$response$logger);

            $this->bookingModel model('BookingModel');
            $this->usersModel model('UsersModel');
            $this->pagesModel model('PagesModel');
            $this->roomsModel model('RoomsModel');
            $this->eventTypesModel model('EventTypesModel');

            //these  lines are in the baseController initController, so I could finally comment them out:
            //$this->settingsModel = model('SettingsModel');
            //$this->settings = $this->settingsModel->keyValue();
            $hl explode('-'$this->settings['booking_hours']);
            $this->hours range($hl[0], $hl[1]);
            $this->rooms $this->roomsModel->keyValue();
            $this->validation =  \Config\Services::validation();
    }

    // public function __construct()
    // {
    //    $this->bookingModel = model('BookingModel');
    //    $this->usersModel = model('UsersModel');
    //    $this->pagesModel = model('PagesModel');
    //    $this->roomsModel = model('RoomsModel');
    //    $this->eventTypesModel = model('EventTypesModel');

    //    //dublicates baseConstructor initConstructor()
    //    $this->settingsModel = model('SettingsModel');
    //    $this->settings = $this->settingsModel->keyValue();

    //    $hl = explode('-', $this->settings['booking_hours']);
    //    $this->hours = range($hl[0], $hl[1]);
    //    $this->rooms = $this->roomsModel->keyValue();
    //    $this->validation =  \Config\Services::validation();
    // }

    // the other methods go here


==

Donatas G.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB