Working on dynamic routing for all frontend urls but while accessing admin routes it goes to abort condition which is on the mentioned route's function.
Web.php
Route::get('/{slug?}', 'slug' )->where('slug','(.*)')->name('slug');
FrontController.php
public function slug(Request $request, $slug=null) {
if ($slug == "admin") {
return redirect()->route('login');
}
if (Str::contains($slug, 'admin/')) {
$routes = Route::getRoutes();
$request = Request::create($slug);
try {
$route->match($request,'admin.dashboard');
//How to access requested url's route name to redirect there
} catch (\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e) {
abort(404);
}
}
if ($slug == "login") {
return view('auth.login');
}
if ($slug == null) {
$page = Pages::where('url', '')->first();
}
if (empty($page)) {
abort(404);
}
$contentWithBlade = Blade::render($page->pages_content);
$session = $request->session()->put('key', $page);
return view('frontend.pages.template', compact('contentWithBlade', 'page'));
}
Any suggestions how to get route name against route url?
check this
Route::getCurrentRoute()->getPath();
or
\Request::route()->getName()
from v5.1
use Illuminate\Support\Facades\Route;
$currentPath= Route::getFacadeRoot()->current()->uri();
Laravel v5.2
Route::currentRouteName(); //use Illuminate\Support\Facades\Route;
Or if you need the action name
Route::getCurrentRoute()->getActionName();
Laravel 5.2 route documentation
Retrieving The Request URI
The path method returns the request's URI. So, if the incoming request is targeted at http://example.com/foo/bar, the path method will return foo/bar:
$uri = $request->path();
The is method allows you to verify that the incoming request URI matches a given pattern. You may use the * character as a wildcard when utilizing this method:
if ($request->is('admin/*')) {
//
}
To get the full URL, not just the path info, you may use the url method on the request instance:
$url = $request->url();
Laravel v5.3 ... v5.8
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
Laravel 5.3 route documentation
Laravel v6.x...7.x
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
** Current as of Nov 11th 2019 - version 6.5 **
Laravel 6.x route documentation
There is an option to use request to get route
$request->route()->getName();
Latest Version of laravel
Related
Hi Folks i upgrading my slim framework from slim 2 to slim 4 for older project
for one route i added the one value before route using slim 2 slim.before in index.php
example code:
$app->hook('slim.before', function () use ($app) {
$env = $app->environment();
$path = $env['PATH_INFO'];
// spliting the route and adding the dynamic value to the route
$uriArray = explode('/', $path);
$dynamicvalue = 'value';
if(array_key_exists($uriArray[1], array)) {
$dynamicvalue = $uriArray[1];
//we are trimming the api route
$path_trimmed = substr($path, strlen($dynamicvalue) + 1);
$env['PATH_INFO'] = $path_trimmed;
}
});
i read about the add beforemiddleware but cannot able find correct way to add it and i cannot able to find the replacement for $app->environment();
i want to append the dynamic value directly to route
for example
i have one route like this
https://api.fakedata.com/fakeid
by using the above route splitting code i appending the value route using slim.before in slim 2
for example take the dynamic value as test
the route will be
https://api.fakedata.com/test/fakeid
the response of the both api will be same we want to just add value to the route
can any one help me how to do with slim 4
I assume you need to and PATH_INFO to the environment so you can later refer to it in the route callback. You can add a middleware to add attributes to the $request the route callback receives:
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class PathInfoMiddleware {
public function __invoke(Request $request, RequestHandler $handler) : Response {
$info = 'some value, path_trimmed for example...'; // this could be whatever you need it to be
$request = $request->withAttribute('PATH_INFO', $info);
return $handler->handle($request);
}
}
// Add middleware to all routes
$app->add(PathInfoMiddleware::class);
// Use the attribute in a route
$app->get('/pathinfo', function(Request $request, Response $response){
$response->getBody()->write($request->getAttribute('PATH_INFO'));
return $response;
});
Now visiting /pathinfo gives the following output:
some value, path_trimmed for example...
In my ChallengesController I have these routes:
public function show($id) {
$challenge = Challenge::find($id);
if (!$challenge) {
return back()->with('error', 'Challenge does not exist');
}
$projects = $challenge->projects;
return view('challenges.show')->with(['challenge' => $challenge, 'projects' => $projects]);
}
public function create() {
if (auth()->user()->role === 'user') {
return back()->with('error', 'You are unauthorized to do that');
}
return view('challenges.create');
}
In my web.php routes I have these routes:
Route::get('/challenges/{id}', 'ChallengesController#show');
Route::get('/challenges/create', 'ChallengesController#create');
Whenever I want to go to /challenges/create it thinks I have to go to /challenges/{id} and is thinking the {id} is "create". But in my other controller where I just specified
Route::resource('projects', 'ProjectsController');
it has the same route structure when I do php artisan route:list, but it's working and my custom /challenge routes are not.
Is there a way to override the /challenges/create or am I doing something wrong. I am using Laravel version 5.7.20.
or even more simpler, change the order of declaration:
Route::get('/challenges/create', 'ChallengesController#create');
Route::get('/challenges/{id}', 'ChallengesController#show');
From Laravel documentation
You may constrain the format of your route parameters using the where
method on a route instance. The where method accepts the name of the
parameter and a regular expression defining how the parameter should
be constrained:
Route::get('challenges/{id}', function ($id) {
//
})->where('id', '[0-9]+');
Now only numeric values will be accepted as the parameter id.
In my Laravel application I have a middleware for specific routes, in this middleware I validate to redirect to a url.
public function handle($request, Closure $next)
{
$isValidated= ....
if ($isValidated) {
session()->put('url.intended', URL::full());
return redirect()->route('routeone')
}
return $next($request);
}
in the store method of that table when you register I do a redirect in the following way, but it turns out that when I do it, it redirects me to domain/img/favicon.png and I did not do the previous route
public function store(Request $request)
{
....
return redirect()->intended(session('url.intended') ?? '/admin');
}
What is the problem here or how could I address this detail to redirect to the url before the middleware redirects. ?
Try to use this code :
$referrer = $this->request->headers->get('referer');
$url = $referrer ? $this->to($referrer) : $this->getPreviousUrlFromSession();
or directly :
$url = request()->headers->get('referer');
and
session()->put('url.intended', $url);
Could you not just do this
return back();
From the docs https://laravel.com/docs/5.7/redirects#creating-redirects
I'm having problems on what URL to be used to link to the php scripts in Laravel5 which I'm running at localhost at the moment. I have created a function in my controller to handle the request. Here is the function:
public function mobile_validator(Request $request) {
$method = $request->method();
if($method == 'POST') {
$username = $request->username;
$password = $request->password;
$user = DB::table('users')->get();
foreach($user as $i) {
if($username == $i->email and $password == $i->password) {
return 'success';
}
else {
return 'failure';
}
}
}
I have also created a route in my route.php.
Route::get('/mobilevalidator', 'AuthController#mobile_validator');
This is my URL in android:
private static final String LOGIN_URL = "http://10.0.2.2:8000/mobilevalidator/";
Now when I login in my app it displays the error com.android.volley.timeouterror
Is the URL correct in defining the php script in Laravel?
In your routes you defined a
Route::get
That means that this route is listening to the GET method. In your controller you specify
$method = $request->method();
if($method == 'POST') {
Which means your controller is actually only returning stuff you have a POST which will ofcourse never happen since your route calling your controller is only listening to GET
You can complety remove the check of the method. A controller method can only be called if you map the route to it. If you want to also support POST simply add
Route::post( ... )
A little hint:
Try to use PostMan or any other RestClient to test your Routes before using them in your app. Also don't forget to remove the web middleware in laravel - otherwise you will also need to add the csrf token to your request.
I need to have the current found controller and action in a middleware, so that I can do some authentication. But I found it impossible, because the pipe is like Middleware1 -> Middleware2-> do the dispatching -> controller#action() -> Middleware2 -> Middleware1.
Therefore before the dispatching, I cannot get the route info. It is definitely not right to do it after the $controller->action().
I did some research and found this.
$allRoutes = $this->app->getRoutes();
$method = \Request::getMethod();
$pathInfo = \Request::getPathInfo();
$currentRoute = $allRoutes[$method.$pathInfo]['action']['uses'];
But this does not work when visiting URI like app/role/1, because $allRoutes only have index of app/role/{id} instead of app/role/1.
Is there any workaround about this?
After do some research, I got solution. Here they go:
Create Custom Dispatcher
First, you have to make your own custom dispatcher, mine is:
App\Dispatcher\GroupCountBased
Stored as:
app/Dispatcher/GroupCountBased.php
Here's the content of GroupCountBased:
<?php namespace App\Dispatcher;
use FastRoute\Dispatcher\GroupCountBased as BaseGroupCountBased;
class GroupCountBased extends BaseGroupCountBased
{
public $current;
protected function dispatchVariableRoute($routeData, $uri) {
foreach ($routeData as $data) {
if (!preg_match($data['regex'], $uri, $matches)) continue;
list($handler, $varNames) = $data['routeMap'][count($matches)];
$vars = [];
$i = 0;
foreach ($varNames as $varName) {
$vars[$varName] = $matches[++$i];
}
// HERE WE SET OUR CURRENT ROUTE INFORMATION
$this->current = [
'handler' => $handler,
'args' => $vars,
];
return [self::FOUND, $handler, $vars];
}
return [self::NOT_FOUND];
}
}
Register Your Custom Dispatcher in Laravel Container
Then, register your own custom dispatcher via singleton() method. Do this after you register all your routes! In my case, I add custom dispatcher in bootstrap/app.php after this line:
require __DIR__.'/../app/Http/routes.php';
This is what it looks like:
/*
|--------------------------------------------------------------------------
| Load The Application Routes
|--------------------------------------------------------------------------
|
| Next we will include the routes file so that they can all be added to
| the application. This will provide all of the URLs the application
| can respond to, as well as the controllers that may handle them.
|
*/
require __DIR__.'/../app/Http/routes.php';
// REGISTER YOUR CUSTOM DISPATCHER IN LARAVEL CONTAINER VIA SINGLETON METHOD
$app->singleton('dispatcher', function () use ($app) {
return FastRoute\simpleDispatcher(function ($r) use ($app) {
foreach ($app->getRoutes() as $route) {
$r->addRoute($route['method'], $route['uri'], $route['action']);
}
}, [
'dispatcher' => 'App\\Dispatcher\\GroupCountBased',
]);
});
// SET YOUR CUSTOM DISPATCHER IN APPLICATION CONTEXT
$app->setDispatcher($app['dispatcher']);
Call In Middleware (UPDATE)
NOTE: I understand it's not elegant, since dispatch called after middleware executed, you must dispatch your dispatcher manually.
In your middleware, inside your handle method, do this:
app('dispatcher')->dispatch($request->getMethod(), $request->getPathInfo());
Example:
public function handle($request, Closure $next)
{
app('dispatcher')->dispatch($request->getMethod(), $request->getPathInfo());
dd(app('dispatcher')->current);
return $next($request);
}
Usage
To get your current route:
app('dispatcher')->current;
I found the correct answer to this problem. I missed one method named routeMiddleware() of Application. This method registers the route-specific middleware which is invoked after dispatching. So Just use $app->routeMiddleware() to register you middleware. And get the matched route info by $request->route() in your middleware.
$methodName = $request->getMethod();
$pathInfo = $request->getPathInfo();
$route = app()->router->getRoutes()[$methodName . $pathInfo]['action']['uses'];
$classNameAndAction = class_basename($route);
$className = explode('#', $classNameAndAction)[0];