Search code examples
phplaravellaravel-5.5thephpleague-fractal

Conditional Attributes in Fractal laravel transformers


I'm using Fractal laravel package as a presentation and transformation layer for complex data output.

I wrote a UserTransformer like this :

public function transform(User $user)
    {
        return [
            'user_id'            => (int)$user->user_id,
            'name'               => $user->name,
            'family'             => $user->family,
            'username'           => $user->username,
            'token'              => $user->token,
            'mobile'             => $user->mobile,
            'email'              => $user->email,
            'sex'                => $user->sex,
            'tel'                => $user->tel,
            'province'           => $user->province,
            'city'               => $user->city,
            'picture'            => $user->picture,
            'birthday'           => $user->birthday,
            'wedding_date'       => $user->wedding_date,
            'wife_birthday'      => $user->wife_birthday,
            'desc'               => $user->desc,
            'active'             => (bool) $user->active,
            'supervisor'         => $user->supervisor,
            'two_factor_enabled' => (bool) $user->two_factor_enabled,
            'address'            => $user->address,
            'created_at'         => $user->created_at,
        ];
    }

Now in some situation I want to return specific fields of User model as a collection like this :

public function index()
    {
        return $this->collection(User::get(['user_id','name','family','username','created_at']), new UserTransformer());
    }

But in this case result is like this :

"result": [
        {
            "user_id": 1,
            "name": "ahmad",
            "family": "badpey",
            "username": "09139616246",
            "token": null,
            "mobile": null,
            "email": null,
            "sex": null,
            "tel": null,
            "province": null,
            "city": null,
            "picture": null,
            "birthday": null,
            "wedding_date": null,
            "wife_birthday": null,
            "desc": null,
            "active": false,
            "supervisor": null,
            "two_factor_enabled": false,
            "address": null,
            "created_at": {
                "date": "2017-11-15 10:01:24.000000",
                "timezone_type": 3,
                "timezone": "Asia/Tehran"
            }
        }
]

As you can see fields that not included on selection User model, have null value and returned. But I want only included fields return. how can I do that ?


Solution

  • Use array filter to remove them, something like this

    public function transform(User $user)
        {
            return array_filter([
                'user_id'            => (int)$user->user_id,
                'name'               => $user->name,
                'family'             => $user->family,
                'username'           => $user->username,
                'token'              => $user->token,
                'mobile'             => $user->mobile,
                'email'              => $user->email,
                'sex'                => $user->sex,
                'tel'                => $user->tel,
                'province'           => $user->province,
                'city'               => $user->city,
                'picture'            => $user->picture,
                'birthday'           => $user->birthday,
                'wedding_date'       => $user->wedding_date,
                'wife_birthday'      => $user->wife_birthday,
                'desc'               => $user->desc,
                'active'             => (bool) $user->active,
                'supervisor'         => $user->supervisor,
                'two_factor_enabled' => (bool) $user->two_factor_enabled,
                'address'            => $user->address,
                'created_at'         => $user->created_at,
            ], function($item){
                return !is_null($item);
            });
        }
    

    As a note I don't use Laravel, however this is typically how you remove things in bulk from an array.

    http://php.net/manual/en/function.array-filter.php

    Iterates over each value in the array passing them to the callback function. If the callback function returns true, the current value from array is returned into the result array. Array keys are preserved.

    And

    http://php.net/manual/en/function.is-null.php

    Finds whether the given variable is NULL. Returns TRUE if var is null, FALSE otherwise.