I have made a package in Laravel 5.4 where i do routing. It looks like this in my
serviceprovider:
public function boot()
{
$routeConfig = [
'namespace' => 'LarsJanssen\GetJson\Controllers',
'prefix' => 'api',
'middleware' => [
'api',
],
];
$this->getRouter()->group($routeConfig, function ($router) {
$router->get('/feeddex/{store}', [
'uses' => 'GetJsonController#store',
'as' => 'getjsonproperly.store',
]);
});
}
The problem is that the parameter store never works!
The controller method looks like this:
public function store($store)
{
//my code
}
Error message:
Missing argument 1
What could I be doing wrong here?
Related
iam new in laravel , and i wrote this code at routes/api.php in laravel 9
Route::group([
'prefix' => 'auth',
'namespace' => 'Auth'
], function(){
Route::post('register', 'RegisterController');
});
and then i got cant run php artisan serve , it said
UnexpectedValueException
Invalid route action: [Auth\RegisterController].
at G:\PRODUCTIVITY\SANBERCODE\LARAVEL-VUE\TUGAS\laravel-vue-crowdfunding-website-batch-37\crowdfunding-website\vendor\laravel\framework\src\Illuminate\Routing\RouteAction.php:92
88▕ */
89▕ protected static function makeInvokable($action)
90▕ {
91▕ if (! method_exists($action, '__invoke')) {
➜ 92▕ throw new UnexpectedValueException("Invalid route action: [{$action}].");
93▕ }
94▕
95▕ return $action.'#__invoke';
96▕ }
1 G:\PRODUCTIVITY\SANBERCODE\LARAVEL-VUE\TUGAS\laravel-vue-crowdfunding-website-batch-37\crowdfunding-website\vendor\laravel\framework\src\Illuminate\Routing\RouteAction.php:47
Illuminate\Routing\RouteAction::makeInvokable("Auth\RegisterController")
2 G:\PRODUCTIVITY\SANBERCODE\LARAVEL-VUE\TUGAS\laravel-vue-crowdfunding-website-batch-37\crowdfunding-website\vendor\laravel\framework\src\Illuminate\Routing\Route.php:190
Illuminate\Routing\RouteAction::parse("api/auth/register", ["Auth\RegisterController", "Auth\RegisterController"])
someone please help me :)
Add RegisterController function
Route::group([
'prefix' => 'auth',
'namespace' => 'Auth'
], function(){
Route::post('register', 'RegisterController#store');
});
You are missing a parameter in your post function from Route.
You want something like
Route::post('route_name', 'Controller#myFunction')
Or in your case:
Route::post('register', 'RegisterController#registerFunctionName');
Other variation per 9.x documentation:
Route::post('register', [RegisterController::class, 'registerFunctionName']);
Please refer to:
https://laravel.com/docs/9.x/routing
This is an invokable controller yes?
you need to just alter the syntax
Route::group([
'prefix' => 'auth',
'namespace' => 'Auth'
], function(){
Route::post('register', [RegisterController::class]);
});
and then import the class at the top of your routes file and make sure you have a single public method of __invoke() in your controller.
I'm trying to have access to {module} inside my function, but it returns me the following error :
Too few arguments to function {closure}(), 1 passed in /Users/Bernard/PROJECTS/myproject/vendor/laravel/lumen-framework/src/Routing/Router.php on line 62 and exactly 2 expected
Here's my code :
$app->router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) {
$router->group([
'namespace' => $version,
'prefix' => "api/$version/{contest}/{module}",
'middleware' => 'App\Http\Middleware\COMMON\DefineContest',
], function ($request, $module) use ($router) {
dd($module);
require __DIR__ . "/../routes/v1/{module}.routes.php";
});
});
In Laravel, it would be as simple as calling Illuminate\Support\Facades\Route::parameter(paramname) but since it is apparently not available in Lumen(looking at Lumen Router there are no methods or parameters for this use case), this is an imperative answer that does get the job done:
$version = 1;
$router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) use ($version) {
$router->group([
'namespace' => $version,
'prefix' => "api/$version/{contest}/{module}",
'middleware' => 'App\Http\Middleware\COMMON\DefineContest'
], function ($router) use ($version) {
$url = $_SERVER['REQUEST_URI'];
if (preg_match("/api\/$version\/(?<contest>\w+)\/(?<module>\w+)/", $url, $output)) {
$module = $output['module'];
dd($module);
}
});
});
I should point out that this code results in an extra step for every route which I don't think matters since it's not that heavy but something to note of.
I am trying to make auth through laravel package using admins table. In the project directory I added admin guard into config/auth.php
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
And in the guard array
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
Following is my login controller inside pacakge
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/admin/dashboard';
protected function redirectTo()
{
return '/admin/dashboard';
}
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function login(Request $request)
{
if(Auth::guard('admin')->attempt($request->only('email','password'), true)){
return redirect()
->intended(route('dashboard'))
->with('status','You are Logged in as Admin!');
}
}
}
and following is my dashboard controller
class DashboardController extends Controller
{
public function __construct()
{
/* dd(Auth::check()); */ //return false : just want to show you
$this->middleware('auth:admin');
}
public function index()
{
return view('xyz::dashboard');
}
}
And in my Admin.php Model following script is there
namespace App;
class Admin extends \ABC\xyz\App\Models\Admin
{
}
Which is extending package model
namespace ABC\xyz\App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
protected $table = 'admins';
}
And below are the routes from my package
$namespace = 'ABC\Xyz\App\Http\Controllers';
Route::group([
'namespace' => $namespace,
'middleware' => ['web'],
'prefix' => 'admin'
], function () {
Route::get('login', function(){
return view('xyz::auth.login');
})->name('login');
Route::post('/login', 'Auth\LoginController#login')->name('customLogin');
});
Route::group(['namespace' => $namespace,'prefix' => 'admin', 'middleware' => ['auth'] ], function () {
Route::get('dashboard', 'DashboardController#index')->name('dashboard');
});
When I try to login, after submitting valid details it does not redirecting me to dashboard, nothing happening. Also when I try for open forcefully /dashboard it take me to login page.
Also right after login attempt when I try Auth::check() it's returns true but same thing returning false in dashboardController.php construct function. In the same way Auth::guard('admin')->user() returns user's info while on dashboardController.php it's returns null.
Strange Result of php artisan route:list
As you can see in DashboardController.php construct I added $this->middleware('auth:admin');
So when I try to add dd(Auth::guard('admin')->user()) and then check in terminal php artisan route:list it returns null and sometime false, any idea why it is happening?
I don't know what and where I am missing something.
I would like to request you kindly guide me about it. I would appreciate.
Thank you
The problem is in your routes file:
Route::group(['namespace' => $namespace,'prefix' => 'admin', 'middleware' => ['auth'] ], function () {
Route::get('dashboard', 'DashboardController#index')->name('dashboard');
});
You are using the default guard with auth middleware. After you are logged in with admin guard you may not be logged in by your default web guard. That is why it fails and tries to redirect you to login page:
When I try to login, after submitting valid details it does not redirecting me to dashboard, nothing happening. Also when I try for open forcefully /dashboard it take me to login page.
Instead, you should specify in your group that you are using the admin guard:
Route::group(['namespace' => $namespace,'prefix' => 'admin', 'middleware' => ['auth:admin']], function () {
Route::get('dashboard', 'DashboardController#index')->name('dashboard');
});
However, you already specified in your DashboardController to use $this->middleware('auth:admin');, so there is no need to specifiy it in the route group again. The following is enough and reduces the likelihood to create an error:
Route::group(['namespace' => $namespace,'prefix' => 'admin'], function () {
Route::get('dashboard', 'DashboardController#index')->name('dashboard');
});
An extraction sample of the how you should define your admin model:
// app/Admin.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use Notifiable;
protected $guard = 'admin';
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
}
For more on multiple authentications guards see: How to use multiple authentication guards
Auth::guard('admin')->attempt($request->only('email','password') its returning true or false? If returning false then maybe toy didnt hashed your password
Try add this in your Model
public function setPasswordAttribute($password)
{
$this->attributes['password'] = Hash::make($password);
}
Please note that the Auth::check doesn't work on construct. this is because the middleware hasn't run yet, so Auth::check() should return false or null when you try to check in construct.
In your login controller, why are you using two redirectto?
protected $redirectTo = '/admin/dashboard';
protected function redirectTo()
{
return '/admin/dashboard';
}
it is better to stick with one :-)
inside your Admin.php , add this:
protected $guard = 'admin';
for your web.php routes, replace
Route::group(['namespace' => $namespace,'prefix' => 'admin', 'middleware' => ['auth'] ], function () {
Route::get('dashboard', 'DashboardController#index')->name('dashboard');
});
with
Route::group(['namespace' => $namespace,'prefix' => 'admin', 'middleware' => ['auth:admin'] ], function () {
Route::get('dashboard', 'DashboardController#index')->name('dashboard');
});
finally, in DashboardController.php
replace the
/* dd(Auth::check()); */ //return false : just want to show you
With:
$this->middleware(function ($request, $next) {
dd(Auth::check()); //return false : just want to show you
die;
});
Auth::check() should return true!
I am working on adding a comment like stackoverflow using chatter discussion package by devdojo so here is the problem I am writing code to show comments but an undefined variable error is coming up.
Error Page ScreenShot
public function show(Chatterreply $chatterreply ,$id)
{
$chatterreplies = Chatterreply::where('chatter_post_id',$id)->get();
return view('chatter::discussion', compact('chatterreplies'));
echo "<pre>"; print_r('$chatterreplies'); die;
}
In Web.php route is
/*
* Post routes.
*/
Route::group([
'as' => 'posts.',
'prefix' => $route('post', 'posts'),
], function () use ($middleware, $authMiddleware) {
// All posts view.
Route::get('/', [
'as' => 'index',
'uses' => 'ChatterPostController#index',
'middleware' => $middleware('post.index'),
]);
// Create post view.
Route::get('create', [
'as' => 'create',
'uses' => 'ChatterPostController#create',
'middleware' => $authMiddleware('post.create'),
]);
// Store post action.
Route::post('/', [
'as' => 'store',
'uses' => 'ChatterPostController#store',
'middleware' => $authMiddleware('post.store'),
]);
//Adding Comments
Route::post('/reply/{id}', [
'as' => 'store',
'uses' => 'ChatterreplyController#store',
'middleware' => $authMiddleware('post.reply.store'),
]);
//showing Comment
Route::get('/reply/{id}', [
'as' => 'show',
'uses' => 'ChatterreplyController#show',
'middleware' => $middleware('post.show'),
]);
First, I would suggest putting your debugging statements (...print_r...) before the return statement in your controller action, this way :
public function show(Chatterreply $chatterreply ,$id)
{
$chatterreplies = Chatterreply::where('chatter_post_id',$id)->get();
echo "<pre>"; print_r('$chatterreplies'); die();
// or use the laravel helper
dd($chatterreplies)
return view('chatter::discussion', compact('chatterreplies'));
}
You should see the content of the $chatterreplies variable.
If this is ok, check your controller name in web.php because it seems that it should be ChatterReplyController#show instead of ChatterreplyController#show (is the R letter in ChatterreplyController#show capital or not ? ) if you're following the camelCase convention as in ChatterPostController#store for instance.
I am facing a problem in my application.
Let there is two middleware
1)User
2)Admin
Is it possible to get which middleware I authenticated in my controller?
I am using Laravel 5.4.
Here is my route declaration
Route::group(['prefix' => 'user'], function () {
Route::group(['middleware' => ['auth:api']], function () {
Route::post('shop/store', 'ApiShopController#shopStore');
Route::post('shop/update', 'ApiShopController#shopUpdate');
});
});
Route::group(['prefix' => 'admin'], function () {
Route::group(['middleware' => ['auth:admin-api']], function () {
Route::post('shop/store', 'ApiShopController#shopStore');
Route::post('shop/update', 'ApiShopController#shopUpdate');
});
});
Here is my midlleware declaration
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
],
]
You should use Auth::guard('role')
You could include this in your Controller constructor to assign in the a middleware directly, for example like this:
class HomeController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return view('home');
}
}
You could run this method in your controller aswell but I did not check it yet:
$middleware = $this->getMiddleware();
That should return the middleware in your controller
if your application has two guards 'admin' and 'user' in your config/auth.php
...
'admin' => [
'driver' => 'session',
'provider' => 'admin',
],
'user' => [
'driver' => 'session',
'provider' => 'user',
],
, then you can get current guard
#if(Auth::guard('admin')->check())
Hello {{Auth::guard('admin')->user()->name}}
#elseif(Auth::guard('user')->check())
Hello {{Auth::guard('user')->user()->name}}
#endif
My understanding about middleware is to help you do a filter on who you allow access a particular route/resources or intercept the request before it hits your resources in your Laravel app and that is why it is placed right during routes declaration or when the constructor is constructed; Check Middleware Introduction
However, for your case I would reconstruct my route declaration to look like this:
Route::group(['middleware' => ['auth:api']], function () {
Route::group(['prefix' => 'user'], function () {
Route::post('shop/store', 'ApiShopController#shopStore');
Route::post('shop/update', 'ApiShopController#shopUpdate');
});
Route::group(['middleware' => ['auth:admin-api']], function () {
Route::group(['prefix' => 'admin'], function () {
Route::post('shop/store', 'ApiShopController#shopStore');
Route::post('shop/update', 'ApiShopController#shopUpdate');
});
});
});
My observation though is that the call to user/shop/store for example will be hitting shopStore method in ApiShopController that admin/shop/store will it.
I advice that you either separate the methods for that each routes are meant to work on or you don't need middleware, since you'll be needing if conditions to be checking stuffs that your middleware would have done for you or you use different controllers for each middleware group.
PS: Let me know if there is something I missed about your question.
The config has what is currently the default guard. If you used the auth middleware than which ever guard did the authenticating is set as the current default:
config('auth.defaults.guard');
Auth::getDefaultDriver();