Search code examples
laravellaravel-medialibrary

Laravel Media Library: How to get model from custom property?


Using Laravel Media Library, User 1 can send an image to User 2.

User 1's user ID is stored as a custom property in the media collection: 'from_user_id'

When retrieving user 2's images, how do I get the model for User 1 so that I can display their current name and username under the thumbnail?

Here's my current collection

{
  "a048e97c-13b4-4654-be78-6fbdf491e029": {
    "name": "T1fQlGCfnPt10IUagmurMSnYIF03y0o81LfILZOd",
    "file_name": "foo.jpg",
    "uuid": "a048e97c-13b4-4654-be78-6fbdf491e029",
    "preview_url": "foo-preview.jpg",
    "original_url": "foo.jpg",
    "order": 1,
    "custom_properties": {
      "from_user_id": 1,
    },
    "extension": "jpg",
    "size": 31634
  }
}

Im trying to get something like the following for each media in the collection, but just can't work it out.

{
  "a048e97c-13b4-4654-be78-6fbdf491e029": {
    "name": "T1fQlGCfnPt10IUagmurMSnYIF03y0o81LfILZOd",
    "file_name": "foo.jpg",
    "uuid": "a048e97c-13b4-4654-be78-6fbdf491e029",
    "preview_url": "foo-preview.jpg",
    "original_url": "foo.jpg",
    "order": 1,
    "custom_properties": {
      "from_user_id": 1,
    },
    "extension": "jpg",
    "size": 31634
  },
  "user": { // append a user relationship here, but how?
    "id": 1,
    "username": "foobaz",
    "email": "[email protected]"
  }
}

This is how I'm retrieving user 2's media

$media = Auth::user()->getMedia('sentToMe');

The creator of Laravel Media Library suggested to another person to use a filter, but that just doesn't make any sense to me because I don't want to filter the collection, I want to load the User model (user 1).

This is what I've tried but, of course, it just returns the media, it doesn't get the record of user 1 along with it.

$media = Auth::user()->getMedia('sentToMe')->filter(function ($media) {
    return $media->hasCustomProperty('from_user_id');
});

Any suggestions on to how to get user 1's information?


Solution

  • I came up with a solution.

    It's a bit hacky, but it's working. I'd really like to see if it's possible to do a relation on the query instead of all this foreach nonsense though...

    $medias = Auth::user()->getMedia('sentToMe');
    
    $ids = [];
    $collection = [];
    
    foreach($medias as $media) {
        $ids[$media->id] = $media->getCustomProperty('from_user_id');
    }
    
    $users = App\Models\User::select('id', 'username', 'name', 'avatar')
        ->whereIn('id', $ids)
        ->get();
    
    foreach($ids as $key => $value) {
        foreach($medias as $media) {
            if($key == $media->id) {
                $collection[$key]['media'] = $media;
            }
        }
        foreach($users as $user) {
            if($value == $user->id) {
                $collection[$key]['user'] = $user;
            }
        }
    }
    
    return $collection;
    

    returns

    {
      "2": {
        "media": {
          "id": 2,
          "model_type": "App\Models\User",
          "model_id": 2,
          ...
          ...
          "custom_properties": {
            "from_user_id": 1,
          },
          "original_url": "foo.jpg",
          "preview_url": "foo-preview.jpg"
        },
        "user": {
          "id": 1,
          "username": "foobaz",
          "name": "FooBaz",
          "avatar": "/avatars/foobaz.jpeg",
        }
    }