xslibx
xslibx

Reputation: 4349

How do I load a users profile image to a view. Laravel

I'm trying to create a social network site using Laravel. Users have profiles with profile pictures. The profile picture displays in 3 different size. 1 for the main profile page (176x176) a smaller version for comments (50x50) and a tiny version to display on the nav bar as a link to their profile (30x30)

In my database the users are stored in the users table:

id->int->primarykey
media_id->int (id of the media set as the users profile picture)
first_name->varchar
last_name->varchar
email->varchar
password->varchar

The media_id will be the id of the users profile image. All user uploaded images will be stored in the public directory: public/images/users/{users id}/

( however the user's profile image will be stored at public/images/users/{users id}/profilePictures/ )

The url to the image is stored in the medias table:

id->int->primary
user_id->int (id of the user that uploaded the image)
mime_type->varchar
url->varchar

I'm having trouble figuring out how to set the user's media_id on the users table to the id of the media that contains the url of the image that the user uploaded as their profile picture.

Here is my route to the form for uploading profile picture

Route::get('{id}/edit-profile-picture', ['as' => 'profile_editProfilePicture', 'uses' => 'UsersController@showEditProfilePicture']);

UsersController@showEditProfilePicture :

public function showEditProfilePicture($id)
    {
        $user = $this->userRepository->findById($id);

        return View::make('edit_profile-picture');
    }

Here is the form I use for the user to upload the image

{{ Form::open(['route' => 'postProfilePicture', 'files' => true]) }}
  {{ Form::hidden('user_id', Auth::user()->id) }}
  <h5 class="post-type">Upload Picture</h5>
  {{ Form::file('media') }}
  {{ Form::submit('Update Profile Picture', ['class' => 'posting-submit-btn d-bluegreen-btn-thick']) }}
{{ Form::close() }}

Here is the route for when the form submits.

Route::post('edit-profile-picture', ['as' => 'postProfilePicture', 'uses' => 'MediaController@storeProfilePicture'])->before('csrf');

Here is the MediaController@storeProfilePicture. Note how I save the original image to the public/images/{users is}/profilePictures/ directory as well as make 3 different size images and save them there as well.

class MediaController extends \BaseController {


    public function storeProfilePicture()
    {
        $media = new Media;

        $input = Input::all();

        $image = Image::make($input['media']->getRealPath());

        $name =  time() . '-' . Auth::user()->id . '.' . $input['media']->getClientOriginalExtension();
        $imagePath = public_path() . '/images/users/';
        $directory = Auth::user()->id;

        // check if directory exists, if not create the directory
        File::exists($imagePath . $directory . '/profilePictures') or File::makeDirectory($imagePath . $directory . '/profilePictures', 0777, true, true);

        $image->save($imagePath . $directory . '/profilePictures/' . $name)
              ->fit(176, 176)
              ->save($imagePath . $directory . '/profilePictures/' . '176thumb-' . $name)
              ->fit(50, 50)
              ->save($imagePath . $directory . '/profilePictures/' . '50thumb-' . $name)
              ->fit(30, 30)
              ->save($imagePath . $directory . '/profilePictures/' . '30thumb-' . $name);
        // save to database
        $media->url = $name;
        $media->mime_type = $input['media']->getMimeType();
        $media->user_id = $input['user_id'];
        $media->save();

        return Redirect::back();
    }
}

Media model

class Media extends Eloquent {
    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'medias';

    protected $fillable = ['url', 'user_id', 'mime_type'];

    public function user()
    {
        return $this->belongsTo('User');
    }
} 

User model

class User extends Eloquent implements UserInterface, RemindableInterface {

    use UserTrait, RemindableTrait, EventGenerator, FollowableTrait;

    /**
     * Which feilds may be mass assigned
     * @var array
     */
    protected $fillable = ['first_name', 'last_name', 'email', 'password', 'media_id'];

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';


    /**
     * @return mixed
     */
    public function media()
    {
        return $this->hasMany('Media');
    }

}

Here is the route to the profile page

 Route::get('{id}', ['as' => 'profile', 'uses' => 'UsersController@show']);

Here is UsersController@show

public function show($id)
    {
        $user = $this->userRepository->findById($id);

        return View::make('profile')->withUser($user);
    }

Now, in the profile page I'm able to display the users first name easily:

<h4>{{ $user->first_name }}</h4>

Im trying to figure out how to display the users 176x176 profile image.

Since I saved the original image to public/images/users/{user id}/profilePictures/{image-name}

then saved the image name to the media table under the url field

and made 3 different sizes of that image and renamed them to 176thumb-{image-name}, 50thumb-{image-name} and 30thumb-{image-name} and also stored them in the public/images/users/{user id}/profilePictures/{image-name}

I assume that I can get the images by doing:

<img src="images/users/{{ $user->id }}/profilePictures/176thumb-{{ $user->media->url }}" width="176" height="176">
<img src="images/users/{{ $user->id }}/profilePictures/50thumb-{{ $user->media->url }}" width="176" height="176">
<img src="images/users/{{ $user->id }}/profilePictures/30thumb-{{ $user->media->url }}" width="176" height="176">

But this does not work.

I check the public/images/users/ and I see that the images are in the directory. I check the medias table in the database and the user-id is correct, the mime_type is correct, and the url is correct

but I do not know how to get the image to display on the page?

I know one of my problems is that the media_id in the users table does not get set (the user's media_id is suppose to be the id of the media that is the profile picture)

How do I set the user's media_id, when i'm saving the image's user_id, mime_type, and url to the database?

and finally how would I call the url from the medias table that belongs to the user into the page?

Thank you very much in advance, I really appreciate anyone taking time and effort to help me out.

Upvotes: 0

Views: 10158

Answers (1)

lukasgeiter
lukasgeiter

Reputation: 152860

First, add a new relation to the User model:

public function profilePicture(){
    return $this->belongsTo('Media', 'media_id');
}

Then when saving the new media, use associate

$media->save();
$user = Auth::user();
$user->profilePicture()->associate($media);
$user->save();

And then in the view use {{ $user->profilePicture->url }} to retrieve the profile picture URL.

However while this should work, you might want to consider having a is_profile_picture flag in the media table.

Upvotes: 1

Related Questions