Dynamic routes in laravel instead of manual routes - php

I want to prevent write all route in Laravel route.php,actually i follow MVC routing like this www.example.com/controller/action/p1/p2/p3
if you have any good idea give it to me,
i wrote this
$controller = ucfirst(Request::segment(1));
$controller = $controller . 'Controller';
$result=App::make('indexController')->ChechIfExistController($controller);
if($result){
if(Request::segment(2))
$action=Request::segment(2);
else
$action='index';
if(Request::segment(5))
Route::any('/{controller?}/{action?}/{p1?}/{p2?}/{p3?}',array('uses'=>$controller.'#'.$action));
else if(Request::segment(4))
Route::any('/{controller?}/{action?}/{p1?}/{p2?}',array('uses'=>$controller.'#'.$action));
else if(Request::segment(3))
Route::any('/{controller?}/{action?}/{p1?}',array('uses'=>$controller.'#'.$action));
else
Route::any('/{controller?}/{action?}',array('uses'=>$controller.'#'.$action));
} else{
echo '404';
EXIT;
}
but i don't know how to control and check controller and action in laravel to understand if it exist or not.
i need your help.
thanks a lot.
ifound it,this code fix the problem and check if action exist or not,but i would like to do that with laravel but it seems laravel does not have any thing for checking controller and actions
$controller=='Controller'?$controller='IndexController':$controller;
$controllers=new $controller ();
if(method_exists($controllers,$action)){...}
and in composer define my route,
that's all

routes.php
Route::controllers([
'auth' => 'Auth\AuthController',
]);
in AuthController you can do that:
// will be available as METHODNAME /auth/url/{one?}/{two?}/{three?}/{four?}/{five?}
public [methodName]Url($one, $two, $three, $four, $five)
{
//...
}
// for example POST /auth/register
public function postRegister(Request $request)
{
// ...
}
// GET /auth/login
public function getLogin()
{
//...
}
it's not documented, but you can see that in sources:
https://github.com/laravel/framework/blob/5.0/src%2FIlluminate%2FRouting%2FControllerInspector.php
https://github.com/laravel/framework/blob/5.0/src%2FIlluminate%2FRouting%2FRouter.php#L238

That can be done such way:
First we have to write static routes and after that, dynamic route which uses database.
routes.php
Route::get('/', function () {
return 'welcome';
});
Route::get('/faq', function () {
return 'faq';
});
Route::get('/about', function () {
return 'about';
});
Route::get('/{slug}', function ($slug) {
return Article::where('slug', $slug)->first();
});

Related

Laravel route resolving to a different method

I'm trying to set up a basic Laravel CRUD application, and I'm getting stuck setting up the pages for each action.
When I visit the route case/create, it opens the page for show instead.
routes/web.php
use App\Http\Controllers\HospitalCase as HospitalCase;
Route::controller(HospitalCase::class)->group(function() {
Route::get('/cases','index')->middleware('auth')->name('cases');
Route::get('/case/{id}','show')->middleware('auth');
Route::get('/case/create','create')->middleware('auth');
Route::post('/case/create','store')->middleware('auth');
Route::get('/case/edit/{$id}','edit')->middleware('auth');
Route::post('/case/edit/{$id}','update')->middleware('auth');
Route::get('/case/delete/{$id}','destroy')->middleware('auth');
});
HospitalCase.php controller
class HospitalCase extends Controller
{
function index()
{
echo 'index';
}
function create()
{
echo 'create';
}
function show($id)
{
echo 'show';
}
function store()
{
// validation rules
}
function edit($id)
{
return view('case/edit');
}
function update($id)
{
}
function destroy($id)
{
}
}
This is what I see on the browser:
I have been trying to figure this out for hours and can't think of what I'm doing wrong.
PS: The auth middleware is using laravel breeze (unmodified)
The reason it's showing the show route is because you defined
Route::get('/case/{id}','show')->middleware('auth');
before it, therefore, it's matching case/create as show('create')
Try defining the route afterwards.
Route::get('/case/create','create')->middleware('auth');
Route::post('/case/create','store')->middleware('auth');
Route::get('/case/{id}','show')->middleware('auth');
Just want to reiterate what #TimLewis has suggested, I think you need to put this route:
Route::get('/case/create','create')->middleware('auth');
Above this route:
Route::get('/case/{id}','show')->middleware('auth');
But you could try using Laravel’s route resource so you don’t need to write out all the routes -
use App\Http\Controllers\HospitalCaseController;
Route::resource('case', HospitalCaseController::class);

How can you create wildcard routes on Lumen?

Let's say I have a controller called TeamsController. Controller has following method, that returns all teams user has access to.
public function findAll(Request $request): JsonResponse
{
//...
}
Then I have bunch of other controllers with the same method. I would like to create a single route, that would work for all controllers, so I would not need to add a line for each controller every time I create a new controller.
I am unable to catch the controller name from URI. This is what I have tried.
$router->group(['middleware' => 'jwt.auth'], function () use ($router) {
// This works
//$router->get('teams', 'TeamsController#findAll');
// This just returns TeamsController#findAll string as a response
$router->get('{resource}', function ($resource) {
return ucfirst($resource) . 'Controller#findAll';
});
});
You return a string instead of calling a controller action:
I believe Laravel loads the controllers this way (not tested)
$router->group(['middleware' => 'jwt.auth'], function () use ($router) {
$router->get('{resource}', function ($resource) {
$app = app();
$controller = $app->make('\App\Http\Controllers\'. ucfirst($resource) . 'Controller');
return $controller->callAction('findAll', $parameters = array());
});
});
But again, I don't really think it's a good idea.

Phalcon PHP: Dispatcher's `forward` function does not work

Within the reentryAction in my CustomerclientController I want to forward into the indexAction in case of successful validity check of the post parameters.
Unfortunately, the forward doesn't work. While debugging, I determined that the reentryAction method will be called again, instead of indexAction.
I registered a Dispatcher in my services.php as follows:
$di->setShared('dispatcher', function() use ($eventsManager) {
$dispatcher = new MvcDispatcher();
// Bind the eventsManager to the view component
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
The CustomerclientController:
class CustomerclientController extends Controller {
public function reentryAction($hash) {
// ... a lot of code
if ($this->request->isPost()) {
// ... a lot of code
if ($valid) {
$this->dispatcher->forward([
"customerclient",
"index"
]);
return;
}
}
}
public function indexAction() {
//Does something wise
}
}
I defined no special routes and do not use a route.php file.
What am I doing wrong or what did I forget?
Thanks in advance for your help!
Are you sure you need use MvcDispatcher?
I checked my project and I am using Dispatcher
$di->set('dispatcher', function() use ($di) {
$dispatcher = new Dispatcher;
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
I hope it works!
First of all, try to return the dispatcher->forward(). Second, maybe write the keys in the array.
if ($valid)
return $this->dispatcher->forward([
"controller" => "customerclient",
"action" => "index"
]);
Hope that helps!

LARAVEL 5.4 ROLE ON MIDDLEWARE

i'm trying to setup my role on routing using middleware, but everytime i log in into my system, it redirects back on my login view.
here is my routing
Route::group(['middleware' => ['auth','admin']],function(){
Route::get('dashboard','RouteController#adminDashboard');
Route::get('admin',function(){
return 'this is admin page';
});
});
and here is my middleware
public function handle($request, Closure $next)
{
if(Auth::User()->id_role == 1){
return $next($request);
}
return redirect::to('dashboard');
}
can u guys helpme.
You're missing the initial slash.
Route::group(['middleware' => ['auth','admin']],function(){
Route::get('/dashboard','RouteController#adminDashboard');
Route::get('/admin',function(){
return 'this is admin page';
});
})
Or inside your controllers declare a construct function like this:
public function __contstruct(){
$this->middleware('auth');
}
Followed by your usual functions
If login is successful then the middleware checks the id, if the id is 1 then you return the next request ($next($request);). Your redirect never occurs.
So the next request is handled by your adminDashboard function in RouteController.
You should return your view in RouteController like this:
public function adminDashboard() {
return view('your-path-to-your-dashboard');
}
and change your route to this
Route::get('/', 'RouteController#adminDashboard');

How to do restful ajax routes to methods in Laravel 5?

So I have a route that looks like this:
Route::any('some/page', ['as' => 'some-page', 'uses' => 'SomePageController#index']);
However, I also have ajax calls at the same URL (using a request parameter called ajax like: some/page/?ajax=my_action) that I want to hit methods on my controller:
index already routes: 'SomePageController#index'
ajax = my_action needs to route: 'SomePageController#ajaxMyAction'
ajax = my_other_action needs to route: 'SomePageController#ajaxMyOtherAction'
ajax = blah_blah needs to route: 'SomePageController#ajaxBlahBlah
...
What's the elegant solution to setting this up in my routes.php file?
After inspection of Laravel's Http Request and Route classes, I found the route() and setAction() methods could be useful.
So I created a middleware to handle this:
<?php namespace App\Http\Middleware;
class Ajax {
public function handle($request, Closure $next)
{
// Looks for the value of request parameter called "ajax"
// to determine controller's method call
if ($request->ajax()) {
$routeAction = $request->route()->getAction();
$ajaxValue = studly_case($request->input("ajax"));
$routeAction['uses'] = str_replace("#index", "#ajax".$ajaxValue, $routeAction['uses']);
$routeAction['controller'] = str_replace("#index", "#ajax".$ajaxValue, $routeAction['controller']);
$request->route()->setAction($routeAction);
}
return $next($request);
}
}
Now my route looks like:
Route::any('some/page/', ['as' => 'some-page', 'middleware'=>'ajax', 'uses' => 'SomePageController#index']);
And correctly hits my controller methods (without disturbing Laravel's normal flow):
<?php namespace App\Http\Controllers;
class SomePageController extends Controller {
public function index()
{
return view('some.page.index');
}
public function ajaxMyAction(Requests\SomeFormRequest $request){
die('Do my action here!');
}
public function ajaxMyOtherAction(Requests\SomeFormRequest $request){
die('Do my other action here!');
}
...
I think this is a fairly clean solution.
You can't make this dispatch in the routing layer if you keep the same URL. You have two options :
Use different routes for your AJAX calls. For example, you can prefix all your ajax calls by /api. This is a common way :
Route::group(['prefix' => 'api'], function()
{
Route::get('items', function()
{
//
});
});
If the only different thing is your response format. You can use a condition in your controller. Laravel provides methods for that, for example :
public function index()
{
$items = ...;
if (Request::ajax()) {
return Response::json($items);
} else {
return View::make('items.index');
}
}
You can read this http://laravel.com/api/5.0/Illuminate/Http/Request.html#method_ajax and this http://laravel.com/docs/5.0/routing#route-groups if you want more details.

Categories