Fabrizio Fenoglio
Fabrizio Fenoglio

Reputation: 5947

Refactor Controllers PHP / Laravel

I got a situation where I have a controller that is responsible to return Views with some data that need to show it, but this data should be displayed from multiples views.

Let's take an example (is not a real class but just for get the idea):

class UserMapController extends BaseController
{

    public function index($username)
    {
       $posts = Post::all();
       $userInfo = User::findByUsername(username);
       $otherData = Book::all();
       return View::make('user.profile',compact('posts','userInfo','otherData'));
    }

    public function albums($username)
    {
       $posts = Post::all();
       $userInfo = User::findByUsername(username);
       $otherData = Book::all();
       $album = Album::findByUsername($username);
       return View::make('user.albums',compact('posts','userInfo','otherData','username','album'));
    }

}

The default data in this case are $posts, $userInfo, $otherData and I may use it in other 10 methods that it will send it to the view.

I used View Composer in laravel, very helpful but in this case the problem is that I get the value from the url, so I cannot perform a clean and dynamically view composer (Correct me if i'm wrong).

How do you do this kind of refactor, that when you need new data to send to all those views will not painful to insert it?

Upvotes: 0

Views: 957

Answers (2)

user1669496
user1669496

Reputation: 33048

You can look into view composers. Basically what they do is bind some data to a view so that whenever you call a view, that data is automatically retrieved and added. It will keep all this extra logic out of your controllers and you wouldn't have to worry about it anymore.

View::composer(array('user.profile','user.albums'), function($view)
{
    $posts = Post::all();
    $userInfo = User::findByUsername(username);
    $otherData = Book::all();
    $view->with(compact('posts', 'userInfo', 'otherData'));
});

View::composer('user.albums', function($view)
{
    $album = Album::findByUsername($username);
    $view->with(compact('album'));
});

I don't believe that there is any recommended or common practice on where to put these, but I prefer creating a new file for them and adding them to the autoloader.

Upvotes: 1

machuga
machuga

Reputation: 426

Usually setting these up in a beforeFilter or multiple is preferred, then you just set variables as instance variables instead and you may reuse them as you like. You can get the parameters from the route by using Route::parameter('nameOfParam').

beforeFilter and controller filter docs

Example:

<?php


class MyController extends BaseController
{
    public function __construct()
    {
        $this->beforeFilter("@posts");
    }

    public function index()
    {
        return View::make('index', ['posts' => $this->posts]);
    }

    protected function posts()
    {
        $this->posts = Post::all();
    }

Upvotes: 1

Related Questions