loading...
Cover image for How to hide data in transformers — Laravel 5.8

How to hide data in transformers — Laravel 5.8

siliconmachine profile image Alan Mac Cormack ・2 min read

Let's say that we have a user table with some basic data such as id, name, and avatar. But also, we have private data like phone, address, and e-mail which we may not want to return if the request is not being made by the user itself.

We could have a transform function in our UserTransformer as follows:

public function transform(User $user)
{   
    return [
         'id' => $user->id,
         'name' => $user->name,
         'avatar' => $user->avatar,
         'email' => $user->email,     
         'phone' => $user->phone,     
         'address' => $user->address,      
    ];
}

In this case, we are returning all the data no matter who is requesting it.

This means that each time that we call the UserTransformer it will return both, the public and the private data without checking if the user is authorized or not to see it.

Therefore, if we want to show this data based on a condition like the mentioned above, we have to make some changes in our code.

In this case, we will use the Auth facade in order to check who is the user that is making the request as follows:

  1. Import it in our UserTransformer
use Illuminate\Support\Facades\Auth;
  1. Call it and store the id (unique identifier in this case) of the user in a variable
$user_id = Auth::user()id;

So we know how to get the information (id) of the user that is making the request we'll need to check if the record is his own or not.

To do this by we'll compare the ids and merging the data if they're equal.

Applying a little refactor to our code:

public function transform(User $user)
{   
    $data = [ 
        'id' => $user->id,
        'name' => $user->name,
        'avatar' => $user->avatar,
        'email' => $user->email,
        'phone' => $user->phone,
        'address' => $user->address,
    ];
    return $data;
}

Now we have to split the data into private and non-private:

public function transform(User $user)
    $data = [
        'id' => $user->id,
        'name' => $user->name,
        'avatar' => $user->avatar,
    ];
    $private_data = [
        'email' => $user->email,
        'phone' => $user->phone,
        'address' => $user->address,
   ]; 
    return $data;
}

Finally, we will add an if statement checking the ownership of the record and merge the data:

public function transform()
{
    $data = [ 
         'id' => $user->id,
         'name' => $user->name,
         'avatar' => $user->avatar,
    ]; 
    $private_data = [
        'email' => $user->email,            
        'phone' => $user->phone,            
        'address' => $user->address        
    ]; 

    if($user_id == $user->id)
    { 
      $data = array_merge($data, $private_data);    
    } 

    return $data;
}

And it's done! We're showing the private data only to the user that owns it.

We could go further and clean our code we could also extract the last part of it and move it to a static function in the User model:

public static function getPrivateData($user)
{
    $private_data = [
         'email' => $user->email,
         'phone' => $user->phone,
         'address' => $user->address,
    ];
    return $private_data;
}

And refactor our if statement like this:

if (Auth::user()->id === $user->id) {
    $data =           
        array_merge(
            $data, User::getPrivateData($user)
        );
}

A nice piece of code to hide data that we don't want to show to specific users.

We could also check if the user is an admin but I'll be covering this topic in the future :)

Discussion

pic
Editor guide