Search code examples
phplaravellaravel-5laravel-bladeservice-provider

How do I pass user profile pic in nav through AppServiceProvider? laravel-5


This is a very common task. I'm trying to display user profile pic on the nav throughout the site. The profile pictures are urls from google,facebook,or from s3 if user uploads them. I have this function to access the pictures

public static function get_profile_pic($user){
    $pic=array_flatten($user->media->where('category','profile'))[0]->path;
    if(empty($pic)){
        $pic = '/images/user-icon.jpg';
        return $pic;
    }else 
        return $pic;
}

In my nav view I have :

@if(Auth::check())                  
<li><img class='nav-pic' src='<?php link_to_action('HomeController@index',$pic)?>'/></li>

my homecontroller:

class HomeController extends Controller {

public function index(Request $request) {
    if ($request->user()) {
        $user = $request->user();
        $pic = User::get_profile_pic($user);
 }
    view()->share('scripts', array('home.js'));
    return view('home.index', compact('user'));
}

and this is what I have in the AppServiceProvider

public function boot()
{
    if (Auth::check()){
        $user = Auth::user();
        $pic = User::get_profile_pic($user);
        view()->composer('includes.new_nav1',function($view){
            $view->with('pic', User::get_profile_pic($user));
        });
    }
}

Solution

  • Any time you see something like User::method($user) it's probably better to refactor that so that the method is on the user object itself, i.e. $user->method()

    Laravel has something even better called an "appended" attribute. That means it behaves exactly like a normal attribute (database column), you just have to define an accessor method for it:


    1 - Take your function:

    public static function get_profile_pic($user)
    

    and change it to

    public function getProfilePicAttribute()
    

    2 - Replace $user with $this inside of that method.

    3 - Finally, add this array to your User model:

    protected $appends = ['profile_pic'];
    

    This tells Laravel that "profile_pic" behaves like a database attribute but should not be saved into the database table.

    Now for any User object, you can simply use $user->profile_pic, e.g.

    <img src="{{ $user->profile_pic }}">
    

    And change your view composer to just view->with($user, Auth::user())