How functions in the controller are chosen? - php

I have seen the below functionality and I don't understand how functions in controller is choosed?
class ProfilesController extends \BaseController {
public function index() {}
public function create() {}
public function store(){}
public function show($id){}
public function edit($id){}
public function update($id){}
public function destroy($id){}
}
For local.com/profiles it would call index() function and list all the profiles. For viewing any record local.com/profiles/99 it is using show() method.
For editing any record local.com/profiles/99/edit it is using edit().
Are these methods are created automatically? Please suggest me any link or document which helps in understanding Laravel better.

The links provided to you are good to understand how to implement restful urls in Laravel but you don't know what is restful.
The method naming chosen by Laravel it's a convention used to represent what each method does. It's called CRUD.
Now which method is been called depends on the HTTP Request Method.
GET /resource index resource.index
GET /resource/create create resource.create
POST /resource store resource.store
GET /resource/{resource} show resource.show
GET /resource/{resource}/edit edit resource.edit
PUT/PATCH /resource/{resource} update resource.update
DELETE /resource/{resource} destroy resource.destroy
To avoid redundant code when we have a CRUD we use resource controller.
You have to add the below route to your routes.php and the controller you have already provide.
Route::resource('profile', 'ProfilesController');
It's the same as writing
Route::get('profile', 'ProfilesController#index'));
Route::get('profile/create', 'ProfilesController#create'));
Route::post('profile', 'ProfilesController#store'));
Route::get('profile/{id}', 'ProfilesController#show'));
Route::get('profile/{id}/edit', 'ProfilesController#edit'));
Route::put('profile/{id}', 'ProfilesController#update'));
Route::patch('profile/{id}', 'ProfilesController#update'));
Route::delete('profile/{id}', 'ProfilesController#destroy'));
If you want to generate those lines. You can use Jeffreys Way generators.
See Teach a Dog to REST to understand what I'm talking about.

You can look at github Laravel page at Router.php ->
https://github.com/laravel/framework/blob/master/src/Illuminate/Routing/Router.php
Check the resourceDefaults and addResource* functions :)
--
And of course go to Laravel documentation > http://laravel.com/docs/controllers there is the info which you need for your work..

I assume you are using Resource Controllers, http://laravel.com/docs/controllers#resource-controllers.

Related

Access Laravel Resource Controller from HTTP Controller

I'm implementing a small project to maintain a list of books. I'm using PHP 7, Laravel 5.5, Eloquent and SQLite.
I created a Model class book and the respective resource controller BookController. For the sake of simplicity, a book only has to public properties: title and author.
Furthermore, I created an AdminController that creates an admin page. I want to use this page to add books to the database and remove other ones.
My BookController has a store() function:
public function store(Request $request)
{
// Validate the request...
$book = new Book;
$book->title = $request->title;
$book->author = $request->author;
$book->save();
}
My AdminController has a HTML form with input fields for new books (one for title, one for author) as well as a submit button. This button calls AdminController#post.
Now I wonder how to actually add the book from there.
Should I call the BookController from the AdminController and pass the request object to the BookController? Is this the way, controllers communicate in Laravel? Or should I avoid the store function and add the functionality to the AdminController directly?
I think you should separate two controller for two purposes. You can declare variable as Book model in other controllers and work with it.
You can using BookController for both, just need to define two routes for one controller and write some logic in the store method, my viewpoint... that is not good way. Because it need check some vars to detect which request from admin and from user. I don't want to make some thing complex between workflow of user & admin.

Laravel boilerplate send object to controller

I am newbie with Laravel. I have just fork laravel 5 boilerplate from https://github.com/rappasoft/laravel-5-boilerplate.
In route files, i see that there is a line like that :
Route::group(['prefix' => 'user/{deletedUser}'], function () {
Route::get('delete', 'UserStatusController#delete')->name('user.delete-permanently');
Route::get('restore', 'UserStatusController#restore')->name('user.restore');
});
I understand it means that, when url catch 'restore' it will use function restore in UserStatusController.
And here it is:
public function restore(User $deletedUser, ManageUserRequest $request)
Can anybody can help me to find out that, how can it send object $deletedUser to restore function. Tks you!
If your look at the route definition:
user/{deletedUser}
That {deletedUser} represents the id of the user to be deleted/restored. Variables are declared between {} in routes as the docs states.
Now in your controller:
public function restore(User $deletedUser, ManageUserRequest $request)
You can see that a User object is declared as an argument. This object is being injected by Laravel, that automatically will look for an User object that has that id. This is called Route Model Binding.
The documentation explains it better:
When injecting a model ID to a route or controller action, you will often query to retrieve the model that corresponds to that ID. Laravel route model binding provides a convenient way to automatically inject the model instances directly into your routes. For example, instead of injecting a user's ID, you can inject the entire User model instance that matches the given ID.
The same way, the Request class injected in this case is a ManageUserRequest that should be an instance of a FormRequest.
So, returning to your question, you will just have to specify the user id that you want to delete/restore, like this:
someurl.dev/users/5 // <-- for the user of id=5
Now your controller will interact with that specific object to do what you want:
public function restore(User $deletedUser, ManageUserRequest $request)
{
$deletedUser->delete(); // for example
}
There are two things happening here: parameters (docs) and model binding (docs)
First of all, in ['prefix' => 'user/{deletedUser}'] you can see that you are parsing a parameter from the url. This way, when someone navigates to api/user/3, laravel will pass the 3 to your route handler.
Second, it would be very nice to get the User model instance instead of just getting an id number. That's possible and it's called "model binding". Model binding can be
Explicit
You add your bindings to boot method in your RouteServiceProvider class, telling laravel what is the expected type of parameter.
public function boot()
{
parent::boot();
Route::model('deletedUser', App\User::class);
// in older docs I've seen 'App\User' passed as a string instead of as a class
}
Implicit
Laravel automatically figures out what model you need based on type hints.
public function restore(User $deletedUser, ManageUserRequest $request) {}
Here, $deletedUser has is type hinted as User. Laravel sees this, so it will go ahead and convert the id to the Eloquent model for you.
You seem to be using implicit binding, but feel free to check your RouteServiceProvider class.
Check the documentation links for more details, it's pretty well written. (If you are not using version 5.6, then just change the version number in the links).
You Just need to pass ID of the user as a parameter.
And this function
public function restore(User $deletedUser, ManageUserRequest $request)
you can see $deletedUser is of type User Laravel will search for that id ($deletedUser) in Users table and return an object of that user.
If you don't want User object and just need ID that you are passing in URL update restore() function to
public function restore($deletedUser, ManageUserRequest $request)

Laravel 5.1 - View variables(specifically current controller name) for a controller

What I wanna do is to know, inside a view, if I'm in a specific controller or not. From what I know, I've got two choices and I don't have the answer to either of them :-D
inject a view variable using the share method in my AppServiceProvider, which involves getting the current controller name(or at least the action name so that I can switch it) inside the service provider.
inject a variable to all the views returned in the controller. For example does controllers have a boot method? Or can I override the view() method in the following code snippet?
public function someAction(Request $request)
{
return view('someview', ['myvar' => $myvalue]);
}
well of course there's the easy (yet not easy :|) solution: add the variable in all methods of the controller. I don't like this one.
Thanks
You could use the controller's construct function.
Add this to the top of your controller:
public function __construct()
{
view()->share('key', 'value');
}

Method in one controller calling a method in another controller, using MVC

so i have a user controller, that has methods to update profile, etc. In the system i am developing the user would need to post articles, etc. So i am confused with the design of the system. The main logic of creating articles would be housed under the article_model. But how should i call the methods?
I can create a function in the user controller that calls on the article model to create article?
I can call a method in the user controller and create an article controller and the user controller calls the method on the article controller, which in turns call the model for the main logic.
Or just directly call on a article controller that connects to the article model.
I personally feel i need to have a user controller into this system, as logically speaking a user creates article. So which design is perfect in terms of logic and best practices.
You can load multiple models in a controller, you’re not just restricting to the model in the same domain as the controller. So if you need to interface with articles in the users controller, then just load the articles model. As deceze says, you shouldn’t call other controllers in one controller; that definitely goes against MVC conventions.
In your case, any interaction with an article should be in the articles controller though, accessible at a URL like /articles/add.
I actually use codeigniter and they do it this way. If you want to post an article from your user or profile controller you can just make an instance or load your model.
class ProfileController extends BaseController {
public function __construct()
{
$this->load->model('article_model');
}
public function index(){
$this->article_model->post();
}
}
don't call a controller from another controller
you can add link to any view called with the profile that reefers to add article
if you have to call the controller from another you may have a look at codeigniter hmvc
HMVC: an Introduction and Application
Try to use this extension HMVC for CI. It's allow to call controller methods in another controllers. Something like this:
class Dashboard extends MX_Controller{
public $autoload = array();
public function __construct()
{
parent::__construct();
}
public function index()
{
$params = 'some_params';
$data['some_data'] = Modules::run('another_controller/method', $params);
}
}
Where another_controller - simple CI controller, what expand MX_Controller.

nested resource controller laravel 4

In laravel 4 i would like to have a nested controller.
I have read the documentation but didn't find any explanation on how to do it.
Supose that in a app i have some articles and each article have his own set of comments. I would like to be able to get all comment of a specific article by accessing a URL like this.
http://myapp.com/articles/5/comments
I have created a commentsController, but i don't know how to correctly get the article id from the url, so i can pass it to all my CRUD methods in my controller
in route.php
Route::resource('articles.comments','commentsController');
in controller
public function show($articleId, $comment) {}
public function create($articleId) {}
I am not sure nested resource controllers are the way to go.... Here is what I would do.
Route::resource('articles','articlesController');
Route::get('articles/{$id}/comments','articlesController#comments');
Then in your controller
public function comments($id) {
}

Categories