How to get route name from url (not current url) in Laravel? - php

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

Add value to route before in slim framework

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...

/posts/{id} route is blocking /posts/create in Laravel

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.

How to redirect to a previous URL in Laravel 5.6 and intended

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

POST data from android using Volley to Laravel5

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.

Can I get current route information in middleware with Lumen?

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];

Categories