Laravel 5 custom module routes not working - php

I'm creating my custom modules for my projects to be able to add some features to a project or another depending of the requeriments.
My issue is with the routes, I load the routes in a ModuleServiceProvider loaded in app.php:
include __DIR__.'/../../modules/canae/Http/routes.php';
I checked that this works with an echo inside that file. The routes.php file contains the following code:
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function() {
Route::controller('dogs', 'Canae\Http\Controllers\Admin\DogController');
});
I also checked that Laravel can find the Controller, the problem is that it's unable to execute the code inside it.
Here's the code I have inside DogController:
<?php namespace Canae\Http\Controllers\Admin;
class DogController extends \Origin\Http\Controllers\Controller {
public function getIndex() {
echo "Hello!";die();
}
}
And the error is Controller method not found.
If I modify the extends below to Origin\Http\Controllers\Controller (removing the first \) I get the following error: Class 'Canae\Http\Controllers\Admin\Origin\Http\Controllers\Controller' not found so my conclusion is that the code inside this controller is executing, at least reading from Laravel.
Also I'm trying to achieve the Index function with this route http://localhost/canae/public/admin/dogs/index.
This is the tail result of executing php artisan route:list:
| | GET|HEAD | admin/dogs/index/{one?}/{two?}/{three?}/{four?}/{five?} | | Canae\Http\Controllers\Admin\DogController#getIndex | auth |
| | GET|HEAD | admin/dogs | | Canae\Http\Controllers\Admin\DogController#getIndex | auth |
| | GET|HEAD|POST|PUT|PATCH|DELETE | admin/dogs/{_missing} | | Canae\Http\Controllers\Admin\DogController#missingMethod | auth |
+--------+--------------------------------+-------------------------------------------------------------------------------+--------+--------------------------------------------------------------------+------------+
Tell me if you need more information. And thanks for your time.

I solved it moving the line inside providers that loads this routes to the first item of the providers array, even before the application ones. Don't know why, but now it's working.

In light of the docs at: http://laravel.com/docs/master/controllers
Have you tried using the "use" statement? Your code would then look like:
<?php
namespace Canae\Http\Controllers\Admin;
use Canae\Http\Controllers\Controller;
class DogController extends Controller {
public function getIndex() {
echo "Hello!";die();
}
}
I'm also not sure why your namespace is "Canae\Http\Controllers\Admin" as the example shows "App\Http\Controllers" only. I'm not familiar with the specific structure of your project, but removing the "\Admin" might also help.

Related

Laravel Route Model Binding - Resource Controller [duplicate]

I have been using RESTful controllers in my Laravel project. By including:
Route::controller('things', 'ThingController')
in my routes.php, I can define functions in the ThingController like:
public function getDisplay($id) {
$thing = Thing::find($id)
...
}
so that GETting the URL "...things/display/1" would automatically be directed to the controller function. This seems pretty handy and has been working great for me so far.
I noticed many of my controller functions start with getting a model by id from the url, and I thought it would be nice to be able to use route model binding to do this for me instead. So I updated my routes.php to
Route::model('thing', 'Thing');
Route::controller('things', 'ThingController')
and changed the ThingController functions to
public function getDisplay($thing) {
...
}
I assumed this would magically work the way I wanted it to (like everything else I've tried so far in Laravel has) but unfortunately I get "Trying to get property of non-object" when I attempt to use $thing in the function. Is this something that should be able to work and I have just done it wrong, or can route model binding only work with routes explicitly named in routes.php?
If you don't mind with URI path, method name and just work only show, edit and update method, you can use Resource Controller to generate URI string which can define model binding.
In routes.php change to
Route::model('things', 'Thing');
Route::resource('things', 'ThingController');
You can use php artisan routes command to see all URIs
$ artisan routes | grep ThingController
GET|HEAD things | things.index | ThingController#index
GET|HEAD things/create | things.create | ThingController#create
POST things | things.store | ThingController#store
GET|HEAD things/{things} | things.show | ThingController#show
GET|HEAD things/{things}/edit | things.edit | ThingController#edit
PUT things/{things} | things.update | ThingController#update
PATCH things/{things} | | ThingController#update
After that you can threat parameter as Thing object without explicitly name route.
/**
* Display the specified thing.
*
* #param Thing $thing
* #return mixed
*/
public function show(Thing $thing)
{
return $thing->toJson();
}
If you want to access ThingController#show, pass your model ID and Laravel will retrieve it automatically.
http://example.com/things/1
{"id":1,"type":"Yo!"}
You can use Route:resource and still provide other methods. Place the route you need just before that particular Route::resource line.
Eg:
Route::model('things', 'Thing');
Route::get('things/{things}/owner', 'ThingController#getOwner');
Route::resource('things', 'ThingController');
Then create the corresponding method in your controller.
public function getOwner($things) {
return Response::json($things->owner()->get());
}
Here is the official documentation from the Laravel 4.2 docs:
Source: http://laravel.com/docs/controllers#resource-controllers
Adding Additional Routes To Resource Controllers
If it becomes necessary for you to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource:
Route::get('photos/popular');
Route::resource('photos', 'PhotoController');

laravel 5.7 how to pass variable id of one controller to other

I have two controllers and I try pass id of variable form method one controller to method to second controller and I got an error like this >MethodNotAllowedHttpException . I will add that my url after the action looks like this >http://localhost/comment?12 . How is the best way of solving this problem ?
You are most probably getting MethodNotAllowedException, because you are opening a route that is defined as a POST route via GET or the other way around.
To avoid that you can use php artisan route:list and get a list of all defined routes and see how you should "access" them:
+--------+-----------+----------------------------------------------------+------------------------+------------------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+----------------------------------------------------+------------------------+------------------------------------------------------------------------+--------------+
| | GET|HEAD | /a/show/{id} | | App\Http\Controllers\AController#show | web |
| | GET|HEAD | /b/show/{id} | | App\Http\Controllers\BController#show | web |
So let's say you have 2 controllers: AController and BController. Each of the controllers have a show() method declared in them.
class AController extends Controller {
//... other AController related code
public function show($id) {
dd($id);
}
}
class BController extends Controller {
//... other BController related code
public function show($id) {
dd($id);
}
}
Then you can define your routes like this:
Route::get('/a/show/{id}', 'AController#show');
Links like: example.com/a/show/10 will "load" AController's show() method. All we have in our AController::show() method's body is dump and die on $id, we will get 10 printed if we visit that link.
We can replace that dd($id); with:
redirect()->action('BController#show', ['id' => $id]);
And define another route:
Route::get('/b/show/{id}', 'BController#show');
This way if we open the previous link: example.com/a/show/10, we will be redirected to: example.com/b/show/10 and BController::show() method will be executed and it prints the variable using dump and die.
Key points:
Route Parameters
Controller Parameters
redirect()-ing

Cahephp 3.x : dashed rest api not working

I'm building a RESTful API System with CakePHP 3.1.13 ( i can't use 3.2.x because the Server PHP Version is 5.5.x ).
My controller name is CmsCouplesController.php and the url :
http://localhost/~emanuele/works/grai/html/api/v1/cms-couples.json
works correctly.
BUT the other call ( http://localhost/~emanuele/works/grai/html/api/v1/cms-couples/1.json ) return :
Action CmsCouplesController::1() could not be found, or is not accessible.
If i create a controller CouplesController.php all works fine.
So why?!
UPDATE : routes configuration
Router::scope('/', function ($routes) {
$routes->prefix('v1',function($routes) {
$routes->extensions(['json','xml']);
$routes->resources('Couples');
$routes->fallbacks('DashedRoute');
});
Resource routes require separate inflection configuration
You are missing the proper inflection configuration for your resource routes. By default resource routes are using underscore inflection, ie currently your resource routes will match cms_couples.
Note that you can easily check which/how routes are connected by using the routes shell
bin/cake routes
It will show you something like
| v1:cmscouples:index | /v1/cms_couples | {"controller":"CmsCouples","action":"index","_method":"GET","prefix":"v1","plugin":null} |
| v1:cmscouples:add | /v1/cms_couples | {"controller":"CmsCouples","action":"add","_method":"POST","prefix":"v1","plugin":null} |
| v1:cmscouples:view | /v1/cms_couples/:id | {"controller":"CmsCouples","action":"view","_method":"GET","prefix":"v1","plugin":null} |
| v1:cmscouples:edit | /v1/cms_couples/:id | {"controller":"CmsCouples","action":"edit","_method":["PUT","PATCH"],"prefix":"v1","plugin":null} |
| v1:cmscouples:delete | /v1/cms_couples/:id | {"controller":"CmsCouples","action":"delete","_method":"DELETE","prefix":"v1","plugin":null} |
Long story short, use dasherize inflection and you should be good.
$routes->resources('CmsCouples', [
'inflect' => 'dasherize'
]);
See also
Cookbook > Shells, Tasks & Console Tools > Routes Shell
Cookbook > Routing > URL Inflection for Resource Routes
API > \Cake\Routing\RouteBuilder::resources()
from my understanding...
http://localhost/~emanuele/works/grai/html/api/v1/cms-couples.json
must be pointing to index function of CmsCouplesController.php controller
then for what reason you want this kind of url
http://localhost/~emanuele/works/grai/html/api/v1/cms-couples/1.json
you can give url like
http://localhost/~emanuele/works/grai/html/api/v1/cms-couples/json-request
then you can put your code in jsonReuest function of the CmsCouplesController.php controller ...
If this does not help then explain your question with answer of my question of why you want URl like 1.json

Laravel ignores the method in the controller

There controller:
class HomeController extends BaseController {
public function index() {
return View::make('hello');
}
}
and in the presence of the router:
Route::get('/', 'HomeController#index');
an error:
BadMethodCallException
Method [index] does not exist.
The command php artisan routes, returns what you need:
+--------+------------+------+----------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+------------+------+----------------------+----------------+---------------+
| | GET|HEAD / | | HomeController#index | | |
+--------+------------+------+----------------------+----------------+---------------+
Version: Laravel 4.2.11
Russian version of the question
There are two reasons this would be happening.
There is another controller somewhere called HomeController.
Your controller is namespaced.
If it's the first, remove the other version and if it's the second, add the namespace to the 'uses' parameter in the router definition.

Can route model binding be used with RESTful controllers?

I have been using RESTful controllers in my Laravel project. By including:
Route::controller('things', 'ThingController')
in my routes.php, I can define functions in the ThingController like:
public function getDisplay($id) {
$thing = Thing::find($id)
...
}
so that GETting the URL "...things/display/1" would automatically be directed to the controller function. This seems pretty handy and has been working great for me so far.
I noticed many of my controller functions start with getting a model by id from the url, and I thought it would be nice to be able to use route model binding to do this for me instead. So I updated my routes.php to
Route::model('thing', 'Thing');
Route::controller('things', 'ThingController')
and changed the ThingController functions to
public function getDisplay($thing) {
...
}
I assumed this would magically work the way I wanted it to (like everything else I've tried so far in Laravel has) but unfortunately I get "Trying to get property of non-object" when I attempt to use $thing in the function. Is this something that should be able to work and I have just done it wrong, or can route model binding only work with routes explicitly named in routes.php?
If you don't mind with URI path, method name and just work only show, edit and update method, you can use Resource Controller to generate URI string which can define model binding.
In routes.php change to
Route::model('things', 'Thing');
Route::resource('things', 'ThingController');
You can use php artisan routes command to see all URIs
$ artisan routes | grep ThingController
GET|HEAD things | things.index | ThingController#index
GET|HEAD things/create | things.create | ThingController#create
POST things | things.store | ThingController#store
GET|HEAD things/{things} | things.show | ThingController#show
GET|HEAD things/{things}/edit | things.edit | ThingController#edit
PUT things/{things} | things.update | ThingController#update
PATCH things/{things} | | ThingController#update
After that you can threat parameter as Thing object without explicitly name route.
/**
* Display the specified thing.
*
* #param Thing $thing
* #return mixed
*/
public function show(Thing $thing)
{
return $thing->toJson();
}
If you want to access ThingController#show, pass your model ID and Laravel will retrieve it automatically.
http://example.com/things/1
{"id":1,"type":"Yo!"}
You can use Route:resource and still provide other methods. Place the route you need just before that particular Route::resource line.
Eg:
Route::model('things', 'Thing');
Route::get('things/{things}/owner', 'ThingController#getOwner');
Route::resource('things', 'ThingController');
Then create the corresponding method in your controller.
public function getOwner($things) {
return Response::json($things->owner()->get());
}
Here is the official documentation from the Laravel 4.2 docs:
Source: http://laravel.com/docs/controllers#resource-controllers
Adding Additional Routes To Resource Controllers
If it becomes necessary for you to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource:
Route::get('photos/popular');
Route::resource('photos', 'PhotoController');

Categories