Laravel 4 Resource perform action after default store - php

I have taken over a project which uses Laravel 4, and the previous developer created a RESTful resource in the routes file like so:
Route::resource('home/information', 'HomeInformationController',
array('except' => array('create', 'edit')));
Now, when I look in HomeInformationController.php I see some other methods the user created, but I do not see a store method, but when I make a post request to the resource, I get a successful 201 CREATED response. My question is, is there a way to perform another action without disturbing what it is already doing by default? I know I could implement a store method myself and do it that way, but I was wondering if there was a way to keep it the way it is and simply perform a default action every time a record is created.
Also, How is laravel even creating the record, since there is no store method? Does laravel create one by default when you create a resource? And how does it know which model use? There is indeed a model called HomeInformation.php. I have searched Laravel documentation but have not found anything.
Thank you.

of course You can.
let's say You know the route:
Route::resource('home/information', 'HomeInformationController',
array('except' => array('create', 'edit')));
and You know that there are methods (in HomeInformationController) of REST excepting create and edit.
so You can create custom routes and use same controller or another controller.
for example:
Route::get('some/custom/route', array('uses' => 'HomeInformationController#existingMethodOrCustomMethod'));
Route::post('some/custom/route/that/handles/post', array('uses' => 'HomeInformationController#existingMethodOrCustomMethod2'));
and add to Your controller:
public function existingMethodOrCustomMethod(){/*implementation here*/}
public function existingMethodOrCustomMethod2(){/*implementation here*/}
with arguments:
Route::get('some/custom/route/{id}', array('uses' => 'HomeInformationController#existingMethodOrCustomMethod'));
Route::post('some/custom/route/that/handles/post/{id}', array('uses' => 'HomeInformationController#existingMethodOrCustomMethod2'));
and add to Your controller:
public function existingMethodOrCustomMethod($id){/*implementation here*/}
public function existingMethodOrCustomMethod2($id){/*implementation here*/}
read about routing here: http://laravel.com/docs/4.2/routing

Related

Laravel 5 redirect to path with parameters (not route name)

I've been reading everywhere but couldn't find a way to redirect and include parameters in the redirection.
This method is for flash messages only so I can't use this.
return redirect('user/login')->with('message', 'Login Failed');
This method is only for routes with aliases my routes.php doesn't currently use an alias.
return redirect()->route('profile', [1]);
Question 1
Is there a way to use the path without defining the route aliases?
return redirect('schools/edit', compact($id));
When I use this approach I get this error
InvalidArgumentException with message 'The HTTP status code "0" is not valid.'
I have this under my routes:
Route::get('schools/edit/{id}', 'SchoolController#edit');
Edit
Based on the documentation the 2nd parameter is used for http status code which is why I'm getting the error above. I thought it worked like the URL facade wherein URL::to('schools/edit', [$school->id]) works fine.
Question 2
What is the best way to approach this (without using route aliases)? Should I redirect to Controller action instead? Personally I don't like this approach seems too long for me.
I also don't like using aliases because I've already used paths in my entire application and I'm concerned it might affect the existing paths if I add an alias? No?
redirect("schools/edit/$id");
or (if you prefer)
redirect("schools/edit/{$id}");
Just build the path needed.
'Naming' routes isn't going to change any URI's. It will allow you to internally reference a route via its name as opposed to having to use paths everywhere.
Did you watch the class Illuminate\Routing\Redirector?
You can use:
public function route($route, $parameters = [], $status = 302, $headers = [])
It depends on the route you created. If you create in your app\Http\Routes.php like this:
get('schools/edit/{id}', 'SchoolController#edit');
then you can create the route by:
redirect()->action('SchoolController#edit', compact('id'));
If you want to use the route() method you need to name your route:
get('schools/edit/{id}', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
// based on CRUD it would be:
get('schools/{id}/edit', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
This is pretty basic.
PS. If your schools controller is a resource (CRUD) based you can create a resource() and it will create the basic routes:
Route::resource('schools', 'SchoolController');
// or
$router->resource('schools', 'SchoolController');
PS. Don't forget to watch in artisan the routes you created

Using a different controller for GET and POST in Laravel but using the same name

I am writing route and controller rules for a web application. In a number of rules, a problem has emerged, which is that I need to match both GET and POST verbs, and send them to the controller, but different methods.
I considered using Route::controller('tracking', 'TrackingController') for this, but then it requires different names for each internal route, whereas I want to specify one name for both. Besides, I've read nothing but negativity regarding the usage, suggesting that it is not a good idea.
Here's what I have currently:
Route::match(['get', 'post'], '/tracking', [
'as' => 'tracking',
'uses' => 'TrackingController#index'
]);
While implementing this, I have discovered that I need to have two controller methods, index and track. How can I efficiently route GET to index and POST to track, while maintaining the same controller (TrackingController) and the same name (tracking)?
I considered using two separate routes, e.g. Route::get and Route::post, but that doesn't feel very eloquent.
you can use easily Route Controller,like this
Route::controller('tracking', 'TrackingController')
In here if you wanna use same method for both get and post,just use any prefix in method,like
//for both get and post
public function anyUrl();
//only get
public function getUrl();
//only post
public function postUrl();
Or use
Route::any('/url', function () {
return 'Hello World';
});

Laravel Routing to Wrong View

I'm working with Laravel 4.2. I have an app that's routing to the wrong view, although the URL is correct. On a button click, it's supposed to route to users.create (UsersController#create), but is instead routing to UsersController#show. The resolved URL is correct, though, and the DOM element has the correct URL listed. Can anyone help me out?
Here is my Routes file:
// Home page
Route::get('/', 'BaseController#index');
// Define User model to pass through routes
Route::model('user', 'User');
// Create custom route for editing a user
Route::get('users/edit/{user}',
array('as' => 'users.edit', 'uses' => 'UsersController#edit'));
// Create custom route for showing a user
Route::get('users/{user}',
['as' => 'users.show', 'uses' => 'UsersController#show']);
// Remaining routes
Route::resource('users', 'UsersController',
array('except' => array('edit', 'show')));
Here is my UsersController with the two functions in question:
class UsersController extends \BaseController {
protected $user;
public function create()
{
return View::make('users/create');
}
public function show($user)
{
return View::make('users/show', ['user' => $user]);
}}
And here are the relevant results from php artisan routes:
GET:HEAD users/{user} users.show UsersController#show
GET:HEAD users/create users.create UsersController#create
Thanks for your help!
Edit:
The answer to the problem was to simply re-order the routes so that the resource is defined first. I was aware that Laravel grabs the first route that matches a URI, but I still don't understand why a route that isn't passed a user object would select a route defined as users/{user}. Furthermore, I was accessing the route via link_to_route(), that is to say, by name. Why would Laravel pick a different route from the one I explicitly named?
I suppose these questions are beyond the scope of the initial question, but I would greatly appreciate further explanation from someone. Problem solved!
The first thing that jumps out at me is there is no route for "create". There is the "restful" controller, but maybe you want to just try putting the route in. I'm slightly uncomfortable using restful routes when serving html. In the project i'm working on i've been trying to preserve those for data/json transmission, in order to support outside api action.
I think your routes setup recognizes create as {user} in user/{user}, thus redirect to user/show/create as your "custom route for showing a user" setup.
You may have to avoid getting string variable right after users/ route.

Laravel 4 RESTful API - resource controller - deeper request hierarchy

I'm building my frontend part of the API system.
Using default Resource Controller's by Laravel you can achieve this type of requests:
http://superapi.com/v1/soccer/10
Which will call the:
/app/controllers/SoccerController.php # show($id) method
I need at least one more level of depth, to be able to do it like this:
http://superapi.com/v1/soccer/player/10
So it will resolve to:
/app/controllers/SoccerController.php # show() method having both, "player" and "10" arguments.
public function show($model)
{
return Response::json(array('success' => true, 'message' => 'Test ' . $model));
}
Laravel passes only 1 parameter to method, and I cannot find anything about how to pass more.
I'm doing this basically because my 1 controller is responsible for talking to a few Models, not just one. Either SoccerPlayer or SoccerTeam or SoccerSchedule, it all should be nicely put under
/v1/<controller>/<type>/<id>
Advices?
Thanks!
You can have the best of both worlds anyway, by placing a custom route before the resource route:
Route::get('soccer', 'SoccerController#show');
Route::resource('soccer', 'SoccerController', array('except' => array('show')));
Now the show() method will be escluded from the resource controller control (thus calling soccer/10 or soccer/player will lead to a NotFoundHttpException), and placed into your custom route.
You'll need to edit the show() method to accept the second parameter though:
public function show($type, $id)
{
}
you can use route prefixing
Route::group(array('prefix' => 'soccer'), function()
{
Route::resource('player', 'PlayerController');
});
then, you can put all soccer relavant controllers in the same namespace (and same folder) like Soccer. in this case, change the above route to
Route::resource('player', 'Soccer\PlayerController');

Laravel 4 authentication. Restrict access to some functions of a resource but not all

I have this blog resource which has the usual CRUD methods.(index, create, store, show, edit, update, destroy).
I have the following route in my routes.php:
Route::resource('blog', 'PostsController');
but I want to restrict all but index and show.
so I have
Route::get('blog', 'PostsController#index');
Route::group(array('before' => 'auth'), function()
{
Route::resource('blog', 'PostsController');
});
which is fine for index but I don't know how to route the show method ? Or is there another way? Instead of routing the resource should I route every URI individually and put the ones I want restricted in my restricted access route?
Cheers
Laravel has a feature that lets you specify filters in the controllers' __construct method using $this->beforeFilter. This function takes a second argument that lets your provide exceptions (or enable the filter only for certain methods). Try using your original routes file and set up your controller like this:
class PostsController extends BaseController {
function __construct() {
// ...
$this->beforeFilter('auth', array('except' => array('index', 'show')));
// ...
}
// ...
See Controller Filters in the Laravel documentation. It's not entirely well-documented, but you can also start a deeper journey into the guts of Laravel from here.
In Laravel 5 you use middleware function instead like this:
$this->middleware('auth', array('except' => array('index', 'show')));

Categories