First of all, I already check that in other controller (not in resource controller) my session work very well, but when I did it in the resource controller my code for get session didn't work.
Here's my resource controller
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
//tambahan
use DB;
use Session;
//model
use App\_admins;
use App\Mahasiswas;
class MahasiswaController extends Controller
{
protected $data;
protected $token;
public function __contruct(){
$this->data = array();
$this->middleware(function ($request, $next) {
$this->token = $request->session()->get('_admin_id');
if (!$request->session()->has('_admin_id')) {
abort(404);
}
return $next($request);
});
}
private function user($token){
$this->data['query'] = _admins::find($token);
}
public function index(){
echo $this->token;
}
There is more public function, but it's still empty so I am not showing it here to avoid confusion. And here is my route in web.php:
Route::group(['namespace' => 'Admin'],function(){
Route::resource('/admin/mahasiswa','MahasiswaController');
Route::resource('/admin/nilai','NilaiController');
});
In 5.3 the middleware hasn't run yet in the constructor, so you're unable to gather session data. But using your closure-based approach, you should be able to access it with something like this:
$this->middleware(function($request, $next) {
// Get the session value (uses global helper)
$this->token = session('_admin_id');
// If the value is null, abort the request
if (null === $this->token) abort(404);
return $next($request);
});
Related
I'm new to laravel and to php oop. My main goal is to call createLogs() everytime a function is called without putting the call method in each function because it's a hassle. I need help please.
I made a controller called WebLogs with a function called createLogs() that inserts data to a table. I want it to be auto-called whenever another function is called. I tried using this solution and put it in Controller class because WebLogs extends Controller class, and all my other controllers extends Controller class, but the solution doesn't seem to work.
So my Controller class now looks like this:
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
// Added this function from the solution I mentioned
public function __call($method, $arguments) {
echo 'hello world';
echo '<br><br>';
echo $method;
if(method_exists($this, $method)) {
return call_user_func_array(array($this,$method),$arguments);
}
}
}
Example controller:
class DashboardController extends Controller
{
public function index()
{
(new WebLogs)->createLogs(); //I don't want to call this for every function
return view('dashboard');
}
public function showSomething()
{
(new WebLogs)->createLogs();
return view('something');
}
public function updateSomething()
{
(new WebLogs)->createLogs();
return redirect()->back()->with('message','yeey');
}
}
How the functions from DashboardController are being called from web.php:
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
Route::get('/something', [DashboardController::class, 'showSomething'])->name('something');
Route::post('/something/update', [DashboardController::class, 'updateSomething'])->name('something.update');
Create app\Classes\WebLogs.php with content:
<?php
namespace App\Classes;
class WebLogs {
public function __construct() {
return "WebLogs class with construct function was initialized.";
}
public function createLogs($routeName,$routePath) {
$status = 0;
logger('WebLogs class is running:');
logger([$routeName,$routePath]);
// Save to database here
// ...
return $status;
}
}
Then, create an AutoCreateLogs middleware, it will save as app\Http\Middleware\AutoCreateLogs.php:
$ php artisan make:middleware AutoCreateLogs
With content:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Classes\WebLogs;
class AutoCreateLogs
{
public function handle(Request $request, Closure $next)
{
$route = Route::current();
$routePath = $route->uri;
$routeName = $route->action['as'];
$w = new WebLogs;
$w->createLogs($routeName,$routePath);
return $next($request);
}
}
And use this middleware like this:
Route::middleware([AutoCreateLogs::class])->group(function () {
Route::get('/', [App\Http\Controllers\DashboardController::class, 'index'])->name('dashboard');
Route::get('/something', [App\Http\Controllers\DashboardController::class, 'showSomething'])->name('something');
Route::post('/something/update', [App\Http\Controllers\DashboardController::class, 'updateSomething'])->name('something.update');
Route::get('/something/{value}', [App\Http\Controllers\DashboardController::class, 'getSomething'])->name('get.something');
});
With app\Http\Controllers\DashboardController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
public function index()
{
$page = 'index';
return view('welcome', ['page'=>$page]);
}
public function showSomething()
{
$page = 'showSomething';
return view('welcome', ['page'=>$page]);
}
public function updateSomething()
{
$page = 'updateSomething';
return response()->json(['page'=>$page]);
}
public function getSomething(Request $request)
{
$page = 'getSomething';
return view('welcome', ['page'=>$page]);
}
}
Then, empty storage\logs\laravel.log, and run with example route
http://laravel-me.com/something/value99
It will show the successful result:
[2022-02-18 22:56:09] local.DEBUG: WebLogs class is running:
[2022-02-18 22:56:09] local.DEBUG: array (
0 => 'get.something',
1 => 'something/{value}',
)
Read more about middleware: https://laravel.com/docs/8.x/middleware
This is a part of the code.
class StudentController extends Controller
{
public function __construct(Request $request)
{
$school = session('school_data');
$this->middleware($school);
}
}
Now, I've also tried checking the $school by using dd($school) but it returns null
NOTE: The session variable works in other functions inside the same controller.
your sessions are not ready yet.
if you want to use them, use like below:
class StudentController extends Controller
{
public function __construct(Request $request)
{
$this->middleware(function ($request, $next) {
// fetch session and use it in entire class with constructor
$this->school_data = session()->get('school_data');
return $next($request);
});
}
}
from here: laravel - Can't get session in controller constructor
I'm getting the user_id from the session and using it quite a bit throughout my contrpller. So am looking at ways of retrieving that variable.
I have set everything up to get it (How I understand) but the Variable is returning
null
My Controller looks as follows :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\VideoLog;
class VideoController extends Controller
{
private $user_id;
public function __construct(Request $request)
{
$user_id = session('id');
$this->user_id = $user_id;
}
public function log_watched(Request $request)
{
dd($this->user_id);
// See If Video Has Been Watched Before....
$video_watched = VideoLog::where('user_id', $this->user_id);
}
}
Is it something to do with the session?
How would I retrieve it?
The reason you're having this issue is because the controller __construct method is run before the middleware that starts the session.
(more information here)
As the post says, you can get round this issue by using the middleware method in the controller's __construct method:
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->user_id = session('id');
return $next($request);
});
}
This will allow you to set the user_id on the controller.
Hope this helps!
What I want to do is to get the a User's activation status before running any methods and redirect if they're not active. Here's my code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class HomeController extends BaseController
{
public function __construct(){
parent::__CONSTRUCT();
$this->middleware('auth');
//SEE IF ACTIVE, something like auth()->user()->active
}
public function home()
{
return redirect('/home');
}
}
Look at the comment on the last line of the constructor, how do I do that?
From 5.3 onwards, you can't directly access session info in a controllers constructor. You can, though, define a Closure based middleware directly in your controller's constructor. More info in the docs
public function __construct()
{
$this->middleware('auth');
$this->middleware(function ($request, $next) {
if(Auth::user()->active) {
return Redirect::route('activate');
}
return $next($request);
});
}
I have added a controller for my package and I need to call Auth methods inside the constructor of this controller but I get the following error :
ReflectionException in Container.php line 734:
Class hash does not exist
Here is my code :
use Auth;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Session;
class CartController extends Controller
{
private $customer;
public function __construct()
{
$this->middleware('auth', ['except' => ['add']]);
$multiauth = config('cart.multiauth');
if ($multiauth) {
$guard = config('auth.defaults.guard');
$this->customer = Auth::guard($guard)->user();
} else {
$this->customer = Auth::user();
}
}
public function add()
{
// Code
}
}
When I add the code of constructor inside the other functions it works properly but it fails when it is called from constructor of the controller.
I have searched alot for this and found no working solution.
I've solved the problem by adding a middleware :
namespace myNamespace\myPackage;
use Closure;
use Illuminate\Support\Facades\Auth;
class CustomerMiddleware
{
public function handle($request, Closure $next)
{
$multiauth = config('cart.multiauth');
if ($multiauth) {
$guard = config('auth.defaults.guard');
$customer = Auth::guard($guard)->user();
} else {
$customer = Auth::user();
}
$request->attributes->add(['customer' => $customer]);
return $next($request);
}
}
Then I used this middleware for the 'cart/add' route :
Route::group(['middleware' => ['web']], function () {
Route::group(['middleware' => 'customer'], function() {
Route::post('cart/add',
'myNamespace\myPackage\CartController#add');
});
});
So by checking the $request->get('customer') parameter inside the 'add' method of 'CartController', I have access to information of current user :
class CartController extends Controller
{
public function __construct() { }
public function add()
{
$customer = $request->get('customer');
// Code
}
}
I hope this helps someone else :)
You can't use middleware in controller __construct , create a functions and use it