Uche Ndukwe Uche Ndukwe - 16 days ago 4
PHP Question

Extending Laravel base controller

I am a newbie in Laravel framework and I want to extend a base controller which in turn extends controller. However, I discovered that when I do that, my controller no longer recognises my session variables.

Here is my code

namespace App\Http\Controllers\Settings;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Auth\PermissionController;
use App\Fee;

class FeeController extends PermissionController
{

/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
dd(session('userdata')['user_urls']);

$data['title']="Fees";
$data['fees']=Fee::all();
return view('settings.fee.index',$data);
}


And this is my PermissionController code

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Support\Facades\Gate;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PermissionController extends Controller {

/**
* Create a new controller instance.
*
* @return void
*/
public function __construct(Request $request) {
if(!session('userdata')['user_urls']->contains($request->path())){
dd(session('userdata')['user_urls']);
}
}

}


But I realize that my
session('userdata')['user_urls']
becomes null at the PermissionController. But if I make FeeController to extend Controller, my session variables are intact.

I need to use the session variables for some control at the permission controller.

I am running Laravel 5.3 on a MAC OSX and PHP 7

Answer

I have solved the same problem with middleware. I have created a middleware that takes care of the authorization of requests by checking the session to ensure that the controller action being accessed is available in session.

This is the middleware

namespace App\Http\Middleware;

use Closure;

class PermissionMiddleware
{
/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    $currentAction = \Route::currentRouteAction();

    list($nothing,$route_action) = explode('App\Http\Controllers\\', $currentAction);

    $user_actions=session('userdata')['user_urls'];

    if((empty($user_actions))||!$user_actions->contains($route_action)){

        return redirect('denied');
    }
    return $next($request);
   }
}

This is the controller

namespace App\Http\Controllers\Settings;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Auth\PermissionController;
use App\Fee;

class FeeController extends Controller
{

/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index(Request $request)
{


    $data['title']="Fees";
    $data['fees']=Fee::all();
    return view('settings.fee.index',$data);
}

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create(Request $request)
{
    $data['title']='New Fee';
    return view('settings.fee.create',$data);
}

So, instead of using the routes (cos of some other reasons), I used the controller actions. So, once a user logs in, all the controller actions he can access are loaded into session. When he tries to perform any action, the middleware, does the check to ensure he is allowed to perform that action. Otherwise, he is routed away.

So, I either add 'permission' to the routes middleware or call

$this->middleware('permission')

on the controller's construct method.

That is working for me now.

Thank you everybody for your contributions.

Comments