Laravel Nested resources and re-usable controllers - php

I am creating an API and I want to include both regular resources and nested resources
For example, I will say I have a Post resource and Comment resource. I have setup the appropriate routes and controllers like the following
Routes
Route::resource('posts', 'PostsControllers'); // /posts/{id}
Route::resource('comments', 'CommentsControllers'); /comments/{id}
But I also want to have comments as a nested resource of posts, like this
Nested resource route
Route::resource('posts.comments', 'PostCommentsControllers'); /posts/{id}/comments/{id}
Because I have already written my CommentsController, I would like to know of the best method to re-use the CommentsController for my PostsController
Thanks

Using inheritance is the best way:
class BaseController extends Controller {
public function index() {
}
public function create() {
}
public function store() {
}
public function update() {
}
}
class PostsController extends BaseController {
}
class CommentsController extends BaseController {
}

You can just extend your Blog/Comment/*Controller on a generic FooBarController which holds all the logic.
You will have to supply the model and other model-related data, I do this via the constructor, and my models holding data about the columns, etc.

Related

Laravel using separate controller for separate logic

I think we have separate controllers respective to separate logic or modules of our application, and i have also found that using a controller inside another controller is not a good practice.
Here i have facing a difficulty.
there are two controllers PagesController and PostsController
PagesController handle all pages related tasks.
class PagesController
{
public function index()
{
// method of our root request, get and show all posts
}
public function contactUs()
{
// show contact us page etc.
}
}
PostsController handle all posts related tasks.
class PostsController
{
public function getPosts() {} // get all posts from database
public function deletePost($id) {} // delete a post
public function editPost($id) {} // edit a post
}
Now post controller handle all posts specific tasks and pages controller handle all pages related tasks. The problem is that i want to use posts controller getPosts() method to get all posts and pass them to view. How can i use PostsController's getPosts() method inside our PagesController index() method.
One way is extends PostsController and use it. But what if we want to use another controller's method also.
Please provide me better way to do that.
https://www.youtube.com/watch?v=MF0jFKvS4SI
This talk is a bit advance about controllers but it is surely a good practice regarding controllers.
better to create a trait......
How to use traits in Laravel 5.4.18?
You can use XyzController method in any controller by following way
use App\Http\Controllers\XyzController ;
class AnyController extends Controller {
public function functionName()
{
$result = (new XyzController)->methodName();
// this will call method of XyzController
}
}
Hope this will help.
Your controller should not have any logic. Create a service or create a method in Repository and move PostsController's getPosts()'s code into this method. And then call this new method in both PostsController and PageController.
The whole point of having Repository is for this purpose.
I usually prefer Repository pattern to get task done.
Here's an Overview.
interface BaseMethodsForRepository {
/**
* #return mixed
*/
public function get();
//other base methods like store (handle create/update in common method) and delete.
}
class PostRepository implements BaseMethodsForRepository {
public function get() {
return Post::all();
}
//Many more methods
}
class PagesRepository implements BaseMethodsForRepository {
public function get(){
return Page::all();
}
}
class PageController {
private $postRepository
public function __construct(PostRepository $postRepository) {
$this->postRepository = $postRepository;
}
public function index(){
//here you can use all public methods of PostRepository
//usage
$post = $this->postRepository->get();
}
}
I found this useful and code is reusable.

Accessing controller's function

I am using Codeigniter framework to develop a website. I am currently working on home.php view under the view folder. I need to use UserInfo() function which is inside one of the controllers. Any suggestion how to access that function?
class Welcome extends CI_Controller {
public function UserInfo(){
$this->load->model('model_user');
$data['title'] = 'Users';
$data['users'] = $this->model_user->getUser();
$this->load->view('template/users', $data);
}
}
You cant call controller method inside another controller. Its No Way to do it.
You have two way to resolve this issue
If you want to access the function which place inside the
controller, add that into an model. So by loading model you can call
it.
use redirect('welcome/UserInfo') if you just need to call the function
As You want to call controller function in other controller.In codeigniter App folder core folder exists you make a custom core controller and all other controllers extend with your custom controller
In your Custom Core controller
class CustomCore extends CI_Controller
{
/* ---YOUR FUNCTION IN CUSTOMCORE---- */
public function mycorefunc()
{
//Do something
}
}
and your all other controllers extend with custom core
class YourController extends Customcore
{
function controllerfunction()
{
$this->mycorefunc();// Call corefunction
}
}

Call function in Controller using URL

Im comming from CodeIgniter.
There if you had a controller like this:
class Article extends CI_Controller{
public function comments()
{
echo 'Look at this!';
}
}
You could access the comments() function using the URL like this: example.com/Article/comments
How could I do something similar in Laravel?
The way I do it right now is specifiying a route like this:
Route::get('/Article/comments}', 'ArticleController#comments');
But I was hoping for a more dynamic way to do it as I don't want to keep on creating new routes for every function
The recommended way of dynamically calling controllers methods via URL, for Laravel users, is via RESTful Controllers:
<?php
class ArticleController extends controller {
public function getComment()
{
return 'This is only accesible via GET method';
}
public function postComment()
{
return 'This is only accesible via POST method';
}
}
And create your route using telling Laravel this is a RESTful Controller:
Route::controller('articles', 'ArticlesController');
Then if you follow
http://laravel.dev/articles/comments
Using your browser, you should receive:
This is only accesible via GET method
The way you name your controllers methods (getComment, postComment, deleteComment...) tells Laravel wich HTTP method should be used to call those methods.
Check the docs: http://laravel.com/docs/controllers#restful-controllers
But you can also make it dynamic using PHP:
class ArticlesController extends Controller {
public function comments()
{
return 'Look at this!';
}
public function execute($method)
{
return $this->{$method}();
}
}
Use a controller like this one:
Route::get('Article/{method}', 'ArticleController#execute');
Then you just have to
http://laravel.dev/Article/comments
I'll recommend that you stick with the laravel's way to create REST controllers, because that way you can have control over what HTTP Verb is being called with the controller method. The laravel way of doing this is just to add the HTTP Verb in front of the controller method, for your method comments if you want to specify a GET request in Laravel the name of the method would look like getComments.
For example, if you need to do a GET request for the article/comments URI, and then to create a new comment you want to use the same URI with another HTTP verb, lets say POST, you just need to do something like this:
class ArticleController extends BaseController{
// GET: article/comments
public function getComments()
{
echo 'Look at this!';
}
// POST: article/comments
public function postComments()
{
// Do Something
}
}
Further reading:
http://laravel.com/docs/controllers#restful-controllers
Now for your specific answer, this is the Laravel way of doing what you requested:
class ArticleController extends BaseController{
public function getComments()
{
echo 'Look at this!';
}
}
and in the routes.php file you'll need to add the controller as follows:
Route::controller('articles', 'ArticleController');

Is there a way to have multiple controllers for a symfony 1.4 module?

I have a situation where I have a base controller (a base actions.php file) in Symfony 1.4. I want to create another controller, for the same module, that extends that base controller.
I need to extend that base controller because I want to customize the behavior of certain visitors, that are identified based on an ID in the URL.
Any hints?
Another controller class for the same module, I think it's impossible in symfony.
I guess the easiest solution for you is to create another method in the same class, and then invoque it from the base one.
By Example: actions.class.php:
public function executeBaseAction(sfWebRequest $request) {
.. if($user....) then return $this->executeCustomAction($request);
}
public function executeCustomAction(sfWebRequest $request) {
// $this->setTemplate('anotherTemplate?');
}
Actually you can add another controller class for the same module.
You could include several files in your action directory in this way:
In action1Action.class.php
class action1Action extends sfAction
{
public function execute($request) {
//Your code here
}
}
This will use template action1Success.php
In action2Action.class.php
class action2Action extends sfAction
{
public function execute($request) {
//Your code here
}
}
This will use template action2Success.php

Calling member function of other controller in zend framework?

Is it possible to call the member function of another controller in zend framework, if yes then how?
<?php
class FirstController extends Zend_Controller_Action {
public function indexAction() {
// general action
}
public function memberFunction() {
// a resuable function
}
}
Here's another controller
<?php
class SecondController extends Zend_Controller_Action {
public indexAction() {
// here i need to call memberFunction() of FirstController
}
}
Please explain how i can access memberFunction() from second controller.
Solution
Better idea is to define a AppController and make all usual controllers to extend AppController which further extends Zend_Controller_Action.
class AppController extends Zend_Controller_Action {
public function memberFunction() {
// a resuable function
}
}
class FirstController extends AppController {
public function indexAction() {
// call function from any child class
$this->memberFunction();
}
}
Now memberFunction can be invoked from controllers extending AppController as a rule of simple inheritance.
Controllers aren't designed to be used in that way. If you want to execute an action of the other controller after your current controller, use the _forward() method:
// Invokes SecondController::otherActionAction() after the current action has been finished.
$this->_forward('other-action', 'second');
Note that this only works for action methods (“memberAction”), not arbitrary member functions!
If SecondController::memberFunction() does something that is needed across multiple controllers, put that code in a action helper or library class, so that both controllers can access the shared functionality without having to depend on each other.
You should consider factoring out the code into either an action helper or to your model so that it can be called from both controllers that need it.
Regards,
Rob...
I would suggest you to follow DRY and move those functions to common library place. For example create in library folder
My/Util/
and file
CommonFunctions.php
then call your class
My_Util_CommonFunctions
and define your methods
Now you can call them from any place in the code using your new namespace which you have to register.
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace(array('My_'));
in any controller you can call your custom methods by using:
My_Util_CustomFunctions::yourCustomMethod($params);

Categories