Laravel 5.5 Supplementing Resource Controllers example - php

I have difficults to create a supplementing Resource in a controller laravel and insert it in the web.php for the routing.
I would to implement a search functions, in an Articles controller .Beyond the authomatic generated function like (index, show...) i have created another one:
public function search($title){
$articles = Article::findOrFail($title);
return $articles;
}
And I have added it in the web.php for the routing:
Route::resource('articles/{title}', 'ArticleController#search');
When I try to test this search, it doesn't work. All the implicit controller go well, I have problem only with this selfmade function.
How can I solve this issue?
thanks

You need to add another route before resource one to make it work:
Route::get('articles/{title}', 'ArticleController#search');
You also want to change the query if you want to find an article by it's slug, for example:
$article = User::where('slug', $title)->first();

Related

Final Route URL Change Laravel 5.5

I am working on a school project. while working on a schools detail page I am facing an issue with the URL. My client needs a clean URL to run AdWords. My school detail page URL: http://edlooker.com/schools/detail/4/Shiksha-Juniors-Ganapathy. But he needs it like http://edlooker.com/Shiksha-Juniors-Ganapathy. If anyone helps me out it will be helpful, thanks in advance.
You need to define this route after all routes in your web.php (if laravel 5.x) or in routes.php (if it is laravel 4.2).
Route::get('{school}','YourController#getIndex');
And your controller should be having getIndex method like this,
public function getIndex($school_name)
{
print_r($school_name);die; // This is just to print on page,
//otherwise you can write your logic or code to fetch school data and pass the data array to view from here.
}
This way, you don't need to use the database to get URL based on the URL segment and you can directly check for the school name in the database and after fetching the data from DB, you can pass it to the school details view. And it will serve your purpose.
Check Route Model Binding section in docs.
Customizing The Key Name
If you would like model binding to use a database column other than id when retrieving a given model class, you may override the getRouteKeyName method on the Eloquent model:
/**
* Get the route key for the model.
*
* #return string
*/
public function getRouteKeyName()
{
return 'slug';
}
In this case, you will have to use one front controller for all requests and get data by slugs, for example:
public function show($slug)
{
$page = Page::where('slug', $slug)->first();
....
}
Your route could look like this:
Route::get('{slug}', 'FrontController#show');

Laravel 5.4 function index try using function show

I have route:
Route::resource('admin/question', 'QuestionsController');
and function index:
public function index() {
return "Hello";
}
But when I try used index Laravel returned me the error:
Method [show] does not exist.
I'm using the link:
http://localhost:8012/siwz/siwz/public/admin/question
The server is WampServer program.
I can only use index function when I change route file:
Route::get('admin/question/index', 'QuestionsController#index');
Route::resource('admin/question', 'QuestionsController');
In Laravel version 5.3 I did not have to do it, it was enough to use:
Route::resource('.../...', '...Controller');
Actually, the URL is going to the correct function. admin/question should go to index. admin/question/{question} is the route that goes to show.
Take a look here and check how Laravel create Resource routes:
https://laravel.com/docs/5.4/controllers#resource-controllers
Since that you didn't provide your full routes. I am guessing that the link you were accessing is going to the wrong controller. You should check the ordering of the routes. Maybe you are accessing something like this on your route,
Route::resource('admin','AdminController');
And the AdminController doesn't have a method show(). Thats why laravel return that error.
Here's you can do
Comment out the rest of routes except route that you are accessing.
Try to reorder the affected routes. Maybe Laravel is confused with your route.

Laravel get url's route name [duplicate]

In Laravel, we can get route name from current URL via this:
Route::currentRouteName()
But, how can we get the route name from a specific given URL?
Thank you.
A very easy way to do it Laravel 5.2
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1'))->getName()
It outputs my Route name like this slug.posts.show
Update: For method like POST, PUT or DELETE you can do like this
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST'))->getName()//reference https://github.com/symfony/http-foundation/blob/master/Request.php#L309
Also when you run app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST')) this will return Illuminate\Routing\Route instance where you can call multiple useful public methods like getAction, getValidators etc. Check the source https://github.com/illuminate/routing/blob/master/Route.php for more details.
None of the solutions above worked for me.
This is the correct way to match a route with the URI:
$url = 'url-to-match/some-parameter';
$route = collect(\Route::getRoutes())->first(function($route) use($url){
return $route->matches(request()->create($url));
});
The other solutions perform bindings to the container and can screw up your routes...
I don't think this can be done with out-of-the-box Laravel. Also remember that not all routes in Laravel are named, so you probably want to retrieve the route object, not the route name.
One possible solution would be to extend the default \Iluminate\Routing\Router class and add a public method to your custom class that uses the protected Router::findRoute(Request $request) method.
A simplified example:
class MyRouter extends \Illuminate\Routing\Router {
public function resolveRouteFromUrl($url) {
return $this->findRoute(\Illuminate\Http\Request::create($url));
}
}
This should return the route that matches the URL you specified, but I haven't actually tested this.
Note that if you want this new custom router to replace the built-in one, you will likely have to also create a new ServiceProvider to register your new class into the IoC container instead of the default one.
You could adapt the ServiceProvider in the code below to your needs:
https://github.com/jasonlewis/enhanced-router
Otherwise if you just want to manually instantiate your custom router in your code as needed, you'd have to do something like:
$myRouter = new MyRouter(new \Illuminate\Events\Dispatcher());
$route = $myRouter->resolveRouteFromUrl('/your/url/here');
It can be done without extending the default \Iluminate\Routing\Router class.
Route::dispatchToRoute(Request::create('/your/url/here'));
$route = Route::currentRouteName();
If you call Route::currentRouteName() after dispatchToRoute call, it will return current route name of dispatched request.

Laravel get route name from given URL

In Laravel, we can get route name from current URL via this:
Route::currentRouteName()
But, how can we get the route name from a specific given URL?
Thank you.
A very easy way to do it Laravel 5.2
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1'))->getName()
It outputs my Route name like this slug.posts.show
Update: For method like POST, PUT or DELETE you can do like this
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST'))->getName()//reference https://github.com/symfony/http-foundation/blob/master/Request.php#L309
Also when you run app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST')) this will return Illuminate\Routing\Route instance where you can call multiple useful public methods like getAction, getValidators etc. Check the source https://github.com/illuminate/routing/blob/master/Route.php for more details.
None of the solutions above worked for me.
This is the correct way to match a route with the URI:
$url = 'url-to-match/some-parameter';
$route = collect(\Route::getRoutes())->first(function($route) use($url){
return $route->matches(request()->create($url));
});
The other solutions perform bindings to the container and can screw up your routes...
I don't think this can be done with out-of-the-box Laravel. Also remember that not all routes in Laravel are named, so you probably want to retrieve the route object, not the route name.
One possible solution would be to extend the default \Iluminate\Routing\Router class and add a public method to your custom class that uses the protected Router::findRoute(Request $request) method.
A simplified example:
class MyRouter extends \Illuminate\Routing\Router {
public function resolveRouteFromUrl($url) {
return $this->findRoute(\Illuminate\Http\Request::create($url));
}
}
This should return the route that matches the URL you specified, but I haven't actually tested this.
Note that if you want this new custom router to replace the built-in one, you will likely have to also create a new ServiceProvider to register your new class into the IoC container instead of the default one.
You could adapt the ServiceProvider in the code below to your needs:
https://github.com/jasonlewis/enhanced-router
Otherwise if you just want to manually instantiate your custom router in your code as needed, you'd have to do something like:
$myRouter = new MyRouter(new \Illuminate\Events\Dispatcher());
$route = $myRouter->resolveRouteFromUrl('/your/url/here');
It can be done without extending the default \Iluminate\Routing\Router class.
Route::dispatchToRoute(Request::create('/your/url/here'));
$route = Route::currentRouteName();
If you call Route::currentRouteName() after dispatchToRoute call, it will return current route name of dispatched request.

PHP Laravel extending resource routing

Laravel routing functionality allows you to name a resource and name a controller to go with it. I am new to Laravel and would like to know if anyone knows how to extend the resources method in the route class provided.
Basically say I have: (which works fine)
/invoices
But say I want:
/invoices/status/unpaid
How is this achievable?
To see the basics of what I am doing check:
http://laravel.com/docs/controllers#resource-controllers
Resource controllers tie you into a specific URLs, such as:
GET|POST /invoices
GET|PUT /invoices/{$id}
GET /invoices/create
and so on as documented.
Since, by convention, GET /invoices is used to list all invoices, you may want to add some filtering on that:
/invoices?status=unpaid - which you can then use in code
<?php
class InvoiceController extends BaseController {
public function index()
{
$status = Input::get('status');
// Continue with logic, pagination, etc
}
}
If you don't want to use filtering via a query string, in your case, you may be able to do something like:
// routes.php
Route::group(array('prefix' => 'invoice'), function()
{
Route::get('status/unpaid', 'InvoiceController#filter');
});
Route::resource('invoice', 'InvoiceController');
That might work as the order routes are created matter. The first route that matches will be the one used to fulfill the request.

Categories