Laravel unknown controller action not found issue - laravel

I'm using Laravel 7.
Facing frustrated error,
InvalidArgumentException Action App\Http\Controllers\CMSController#viewCmsPages not defined.
Successful:
redirect('/admin/view-cms-pages')
Fails:
redirect()->action('CMSController#viewCmsPages')
class CmsController extends Controller
{
public function addCmsPage(Request $request)
{
if ($request->isMethod('post')) {
$data = $request->all();
$cmspage->save();
//return redirect('/admin/view-cms-pages')->with('flash_message_success','success');
//why fail...
return redirect()->action('CMSController#viewCmsPages')->with('flash_message_success', 'success');
}
return view('admin.pages.add_cms_page');
}
public function viewCmsPages()
{
return view('admin.pages.view_cms_pages');
}
}
Route::group(['middleware' => ['adminlogin']], function () {
Route::get('/admin/view-cms-pages','CmsController#viewCmsPages');
//i try to add in this resource version also still can't call to
Route::resource('/admin/pages', 'CMSController');
});
When I run php artisan route:list, I can see CMSController#viewCmsPages registered in the list.

Try this on your controller :
return redirect()->route('cms.view')->with('flash_message_success', 'success');
And then add name for the route on web.php :
// Add name for the route
Route::get('/admin/pages', 'CMSController#viewCmsPages')->name ('cms.view');
If you have a custome route, you should register it first, resource route only work for method [index,create,store,show,destory,edit,update]

Related

Laravel authorization policy not working on Show page

I have a laravel app using Policies to assign roles and permissions, i cant seem to access the show page and im not sure what im doing wrong?
If i set return true it still shows a 403 error as well, so im unsure where im going wrong here. The index page is accessable but the show page is not?
UserPolicy
public function viewAny(User $user)
{
if ($user->isSuperAdmin() || $user->hasPermissionTo(44, 'web')) {
return true;
}
return false;
}
public function view(User $user, User $model)
{
if ($user->isSuperAdmin() || $user->hasPermissionTo(44, 'web')) {
return true;
}
return false;
}
UserController
public function __construct()
{
$this->authorizeResource(User::class, 'user');
}
public function index()
{
$page_title = 'Users';
$page_description = 'User Profiles';
$users = User::all();
return view('pages.users.users.index', compact('page_title', 'page_description', 'users'));
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show($id)
{
$user = User::findOrFail($id);
$user_roles = $user->getRoleNames()->toArray();
return view('pages.users.users.show', compact('user', 'user_roles'));
}
Base on Authorize Resource and Resource Controller documentation.
You should run php artisan make:policy UserPolicy --model=User. This allows the policy to navigate within the model.
When you use the authorizeResource() function you should implement your condition in the middleware like:
// For Index
Route::get('/users', [UserController::class, 'index'])->middleware('can:viewAny,user');
// For View
Route::get('/users/{user}', [UserController::class, 'view'])->middleware('can:view,user');
or you can also use one policy for both view and index on your controller.
I had an issue with authorizeResource function.
I stuck on failed auth policy error:
This action is unauthorized.
The problem was that I named controller resource/request param with different name than its model class name.
F. ex. my model class name is Acknowledge , but I named param as timelineAcknowledge
Laravel writes in its documentation that
The authorizeResource method accepts the model's class name as its first argument, and the name of the route / request parameter that will contain the model's ID as its second argument
So the second argument had to be request parameter name.
// Here request param name is timelineAcknowledge
public function show(Acknowledge $timelineAcknowledge)
{
return $timelineAcknowledge->toArray();
}
// So I used this naming here also
public function __construct()
{
$this->authorizeResource(Acknowledge::class, 'timelineAcknowledge');
}
Solution was to name request param to the same name as its model class name.
Fixed code example
// I changed param name to the same as its model name
public function show(Acknowledge $acknowledge)
{
return $acknowledge->toArray();
}
// Changed here also
public function __construct()
{
$this->authorizeResource(Acknowledge::class, 'acknowledge');
}
I looked over Laravel policy auth code and I saw that the code actually expects the name to be as the model class name, but I couldn't find it anywhere mentioned in Laravel docs.
Of course in most of the cases request param name is the same as model class name, but I had a different case.
Hope it might help for someone.

How can I redirect from a controller with a value to another controller in laravel?

OrderController.php
if (request('payment_method') == 'online') {
return redirect(route('payments.pay', $order->id));
}
web.php
Route::POST('/pay/{orderId}', 'PublicSslCommerzPaymentController#index')->name('payments.pay');
PublicSslCommerzPaymentController.php
session_start();
class PublicSslCommerzPaymentController extends Controller
{
public function index(Request $request, $ordId)
{
//code...
}
}
Here in index function I need the order id from `OrderController.
But the Error I am getting
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for this route. Supported methods: POST.
if you want to redirect to named route you can use this:
return redirect()->route('payments.pay', ['orderId' => $order->id]);
if you want generate redirect to controller action you can try this:
return redirect()->action(
'PublicSslCommerzPaymentController#index', ['ordId' => $order->id]]
);
Just change in your web.php from POST method to GET method
Something like this
Route::GET('/pay/{orderId}', 'PublicSslCommerzPaymentController#index')->name('payments.pay');

how to send id in route and controller in laravel localization

In my Laravel project with localization I made middleware, route group and all parameters, language switch work correct but when I click to send id by
I get the error:
Missing required parameters for [Route: products] [URI:
{lang}/products/{id}]
My Routes:
Route::group(['prefix' => '{lang}'], function () {
Route::get('/', 'AppController#index')->name('home');
Route::get('/categories', 'AppController#categories')->name('categories');
Route::get('products/{id}', 'AppController#products')->name('products');
Auth::routes();
});
My Middleware:
public function handle($request, Closure $next)
{
\App::setLocale($request->lang);
return $next($request);
}
My AppController:
public function products($id)
{
$products = Category::with('products')->where('id', $id)->get();
return view('products', compact('products'));
}
this is the URL:
http://127.0.0.1:8000/fa/products/1
if I change the above URL manually it works and shows the page:
http://127.0.0.1:8000/1/products/1
But if I click on:
I receive the error.
Since you added a route prefix the first parameter of the products method in your controller will be lang and the second one id.
This should fix the controller:
public function products($lang, $id)
{
$products = Category::with('products')->where('id', $id)->get();
return view('products', compact('products', 'lang'));
}
You need to use a key-value array in route('products', ['lang'=>app()->getLocale(), 'id'=>$category->id]) or whatever your route parameters are named in the original route.
Ref. Laravel Named Routes
PS. as Remul notes, since you have a lang param (as route prefix) the first param in your controller will be $lang then $id
public function products($lang, $id)
{
$products = Category::with('products')->where('id', $id)->get();
return view('products', compact('products'));
}

show error while fetch username

show error : Missing argument 1 for App\Http\Controllers\AdminLoginController::name()
public function name($username) {
$user = AdminLogin::find($username);
return response()->json($user);
}
AdminLoginController: Its a adminlogin controller code
class AdminLoginController extends Controller{
public function show(){
$res ="Hello world!";
return response()->json($res);
}
public function log() {
$users = AdminLogin::all();
return response()->json($users);
}
public function name($username) {
$user = AdminLogin::where('username',$username)->first();
return response()->json($user);
}
RouteLoginController: Its a adminlogin controller code :
<?php
$app->get('/', function () use ($app) {
return $app->version();
});
$app->group(['prefix' => 'api/v1'], function ($app)
{
$app->get('adminlogin', 'AdminLoginController#show'); //get single route
$app->get('user', 'AdminLoginController#log'); //get single route
$app->get('username', 'AdminLoginController#name'); //get single route
$app->post('adminlogin', 'AdminLoginController#login'); //get single route
});
Error :
(1/1) ErrorException
Missing argument 1 for App\Http\Controllers\AdminLoginController::name()
Your controller method is taking the username param but the route binding is not passing one. Change your route
$app->get('username', 'AdminLoginController#name');
to
$app->get('user/{username}', 'AdminLoginController#name');
If you don't want to change your route, change your controller function signature to the below (as shown in the other answers), and make sure you are passing the 'username' as request param while invoking the url.
public function name(\Illuminate\Http\Request $request) {
$user = AdminLogin::where('username',$request->username)->first();
return response()->json(['user' => $user]);
}
You are probably calling this function using an ajax request and putting the name in the query string. In this case, the name parameter will not be sent as an attribute of the function but will be part of the request object.
You can solve this like so:
public function name(\Illuminate\Http\Request $request) {
$user = AdminLogin::find($request->username);
return response()->json($user);
}
You should try this :
public function name($username) {
$user = AdminLogin::where('username',$username)->first();
return response()->json(['user' => $user]);
}
OR
public function name(\Illuminate\Http\Request $request) {
$user = AdminLogin::where('username',$request->username)->first();
return response()->json(['user' => $user]);
}

Lravel 5.2 session::forget() and session::flush() not working

i have just make a sub authentication Middleware in my Laravel 5.2 application which use Laravel session to store data.
I can put my data to Laravel session
But when i want to delete that variable form session it working for only that request when page redirect or someone reload the page that variable still exists.
In My controller File
class SubmissionController extends Controller
{
public function login(Request $request){
if($request->session()->has('submission')) return redirect('/submission-directory');
return view('submission.login');
}
public function dologin(Request $request){
if(!$request->get('password') == "reader") return redirect('/submission-directory/login')->withErrors('errors.wrong-password');
Session::put('submission','yes');
$redirect = $request->session()->pull('submission_redirect','/submission-directory');
return redirect($redirect);
}
public function index(Request $request){
dump($request->session()->all());
$request->session()->forget('submission');
dump($request->session()->all());
die('coming here');
}
}
but when I reload the page You can session is still exists..
Notice :: I have put all the routs in web Middleware group
Route.php
Route::group(['middleware' => 'web'], function () {
Route::group(['prefix'=>'/submission-directory'],function(){
Route::get('/login','submissionController#login');
Route::post('/login',['as'=>'submission.login','uses'=>'SubmissionController#doLogin']);
Route::group(['middleware'=>'submission'],function(){
Route::get('/','SubmissionController#index');
});
});
Try this
IN Controller :
use Session;
public function index(Request $request)
{
dump(Session::all());
Session::forget('submission');
print_r((Session::all());
die;
}

Resources