Home > database >  User Transformer::$availableIncludes must be array
User Transformer::$availableIncludes must be array

Time:12-15

I am using Laravel 6.20 version with php version 8 get this error when call the user transfomer

here is my code

model class

<?php

namespace App\Models;

use Carbon\Carbon;
use App\Models\Country;
use App\Models\Access\Role;
use App\Models\Admin\Staff;
use App\Models\Admin\Driver;
use App\Models\Admin\Owner;
use App\Models\Request\Request;
use App\Models\Master\Developer;
use App\Models\Master\PocClient;
use App\Models\Traits\HasActive;
use App\Models\Admin\AdminDetail;
use App\Models\Admin\UserDetails;
use App\Models\Payment\UserWallet;
use Laravel\Passport\HasApiTokens;
use App\Models\LinkedSocialAccount;
use App\Models\Payment\DriverWallet;
use App\Base\Services\OTP\CanSendOTP;
use App\Models\Traits\DeleteOldFiles;
use App\Models\Traits\UserAccessTrait;
use Illuminate\Support\Facades\Storage;
use Illuminate\Notifications\Notifiable;
use App\Models\Payment\UserWalletHistory;
use App\Models\Traits\HasActiveCompanyKey;
use App\Models\Traits\UserAccessScopeTrait;
use App\Base\Services\OTP\CanSendOTPContract;
use Nicolaslopezj\Searchable\SearchableTrait;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Models\Request\FavouriteLocation;

class User extends Authenticatable implements CanSendOTPContract
{
    use CanSendOTP,
    DeleteOldFiles,
    HasActive,
    HasApiTokens,
    Notifiable,
    UserAccessScopeTrait,
    UserAccessTrait,
    SearchableTrait,
    HasActiveCompanyKey;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'username', 'email', 'password', 'mobile', 'country', 'profile_picture', 'email_confirmed', 'mobile_confirmed', 'email_confirmation_token', 'active','fcm_token','login_by','apn_token','timezone','rating','rating_total','no_of_ratings','refferal_code','referred_by','social_nickname','social_id','social_token','social_token_secret','social_refresh_token','social_expires_in','social_avatar','social_avatar_original','social_provider','company_key','lang'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token', 'email_confirmation_token',
    ];

    /**
     * The attributes that have files that should be auto deleted on updating or deleting.
     *
     * @var array
     */
    public $deletableFiles = [
        'profile_picture',
    ];

    /**
     * The attributes that can be used for sorting with query string filtering.
     *
     * @var array
     */
    public $sortable = [
        'id', 'name', 'username', 'email', 'mobile', 'profile_picture', 'last_login_at', 'created_at', 'updated_at',
    ];

    /**
     * The relationships that can be loaded with query string filtering includes.
     *
     * @var array
     */
    public $includes = [
        'roles', 'otp','requestDetail'
    ];

    /**
    * The accessors to append to the model's array form.
    *
    * @var array
    */
    protected $appends = [

    ];

    /**
    * Get the Profile image full file path.
    *
    * @param string $value
    * @return string
    */
    // public function getProfilePictureAttribute($value)
    // {
    //     if (empty($value)) {
    //         $default_image_path = config('base.default.user.profile_picture');
    //         return env('APP_URL').$default_image_path;
    //     }
    //     return Storage::disk(env('FILESYSTEM_DRIVER'))->url(file_path($this->uploadPath(), $value));
    // }


    public function getProfilePictureAttribute($value)
    {
        if (!$value) {
            $default_image_path = config('base.default.user.profile_picture');
            return env('APP_URL').$default_image_path;
        }
        return Storage::disk(env('FILESYSTEM_DRIVER'))->url(file_path($this->uploadPath(), $value));
    }
    /**
     * Override the "boot" method of the model.
     *
     * @return void
     */
    public static function boot()
    {
        parent::boot();

        // Model event handlers
    }

    /**
     * Set the password using bcrypt hash if stored as plaintext.
     *
     * @param string $value
     */
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = (password_get_info($value)['algo'] === 0) ? bcrypt($value) : $value;
    }

    /**
     * The roles associated with the user.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function roles()
    {
        return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
    }

    /**
     * The OTP associated with the user's mobile number.
     *
     * @return \Illuminate\Database\Eloquent\Relations\hasOne
     */
    public function otp()
    {
        return $this->hasOne(MobileOtp::class, 'mobile', 'mobile');
    }

    /**
     * Get the user model for the given username.
     *
     * @param string $username
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    public function findForPassport($username)
    {
        return $this->where($this->usernameField($username), $username)->first();
    }

    /**
     * Get the username attribute based on the input value.
     * Result is either 'email' or 'mobile'.
     *
     * @param string $username
     * @return string
     */
    public function usernameField($username)
    {
        return is_valid_email($username) ? 'email' : 'mobile';
    }

    /**
     * The default file upload path.
     *
     * @return string|null
     */
    public function uploadPath()
    {
        return config('base.user.upload.profile-picture.path');
    }

    /**
     * The Staff associated with the user's id.
     *
     * @return \Illuminate\Database\Eloquent\Relations\hasOne
     */
    public function admin()
    {
        return $this->hasOne(AdminDetail::class, 'user_id', 'id');
    }

    /**
     * The Staff associated with the user's id.
     *
     * @return \Illuminate\Database\Eloquent\Relations\hasOne
     */
    public function developer()
    {
        return $this->hasOne(Developer::class, 'user_id', 'id');
    }

    /**
    * The user wallet history associated with the user's id.
    *
    * @return \Illuminate\Database\Eloquent\Relations\hasOne
    */
    public function userWalletHistory()
    {
        return $this->hasMany(UserWalletHistory::class, 'user_id', 'id');
    }

    /**
    * The favouriteLocations associated with the user's id.
    *
    * @return \Illuminate\Database\Eloquent\Relations\hasOne
    */
    public function favouriteLocations()
    {
        return $this->hasMany(FavouriteLocation::class, 'user_id', 'id');
    }

    public function userWallet()
    {
        return $this->hasOne(UserWallet::class, 'user_id', 'id');
    }
    public function driverWallet()
    {
        return $this->hasOne(DriverWallet::class, 'user_id', 'id');
    }
    /**
     * The Driver associated with the user's id.
     *
     * @return \Illuminate\Database\Eloquent\Relations\hasOne
     */
    public function driver()
    {
        return $this->hasOne(Driver::class, 'user_id', 'id');
    }

    public function accounts()
    {
        return $this->hasMany(LinkedSocialAccount::class, 'user_id', 'id');
    }
    public function requestDetail()
    {
        return $this->hasMany(Request::class, 'user_id', 'id');
    }

    /**
     * The Driver associated with the user's id.
     *
     * @return \Illuminate\Database\Eloquent\Relations\hasOne
     */
    public function userDetails()
    {
        return $this->hasOne(UserDetails::class, 'user_id', 'id');
    }

    /**
    * Get formated and converted timezone of user's created at.
    *
    * @param string $value
    * @return string
    */
    public function getConvertedCreatedAtAttribute()
    {
        if ($this->created_at==null||!auth()->user()->exists()) {
            return null;
        }
        $timezone = auth()->user()->timezone?:env('SYSTEM_DEFAULT_TIMEZONE');
        return Carbon::parse($this->created_at)->setTimezone($timezone)->format('jS M h:i A');
    }
    /**
    * Get formated and converted timezone of user's created at.
    *
    * @param string $value
    * @return string
    */
    public function getConvertedUpdatedAtAttribute()
    {
        if ($this->updated_at==null||!auth()->user()->exists()) {
            return null;
        }
        $timezone = auth()->user()->timezone?:env('SYSTEM_DEFAULT_TIMEZONE');
        return Carbon::parse($this->updated_at)->setTimezone($timezone)->format('jS M h:i A');
    }

    /**
    * Specifies the user's FCM token
    *
    * @return string
    */
    public function routeNotificationForFcm()
    {
        return $this->fcm_token;
    }
    public function routeNotificationForApn()
    {
        return $this->apn_token;
    }

    

    protected $searchable = [
        'columns' => [
            'users.name' => 20,
            'users.email'=> 20
        ],
    ];

    /**
    * The user that the country belongs to.
    * @tested
    *
    * @return \Illuminate\Database\Eloquent\Relations\belongsTo
    */
    public function countryDetail()
    {
        return $this->belongsTo(Country::class, 'country', 'id');
    }

    public function owner()
    {
        return $this->hasOne(Owner::class, 'user_id', 'id');
    }
}

controller class

class AccountController extends ApiController
{
    /**
     * Get the current logged in user.
     * @group User-Management
     * @return \Illuminate\Http\JsonResponse
    * @responseFile responses/auth/authenticated_driver.json
    * @responseFile responses/auth/authenticated_user.json
     */
    public function me()
    {
        
            $user = User::where('id', auth()->user()->id)->companyKey()->first();
            $user = fractal($user, new UserTransformer)->parseIncludes(['onTripRequest.driverDetail','onTripRequest.requestBill','metaRequest.driverDetail','favouriteLocations']);
        }

        return $this->respondOk($user);
    
}

transfomer class


class UserTransformer extends Transformer
{
    /**
     * Resources that can be included if requested.
     *
     * @var array
     */
    protected $availableIncludes = [
        'roles','onTripRequest','metaRequest','favouriteLocations'
    ];
    /**
     * Resources that can be included default.
     *
     * @var array
     */
    protected $defaultIncludes = [
        'sos'

    ];

    /**
     * A Fractal transformer.
     *
     * @return array
     */
    public function transform(User $user)
    {
        $params = [
            'id' => $user->id,
            'name' => $user->name,
           
            'username' => $user->username,
            'email' => $user->email,
            'mobile' => $user->mobile,
            'profile_picture' => $user->profile_picture,
            'active' => $user->active,
            'email_confirmed' => $user->email_confirmed,
            'mobile_confirmed' => $user->mobile_confirmed,
            'last_known_ip' => $user->last_known_ip,
            'last_login_at' => $user->last_login_at,
            'rating' => round($user->rating, 2),
            'no_of_ratings' => $user->no_of_ratings,
            'refferal_code'=>$user->refferal_code,
            'currency_code'=>$user->countryDetail->currency_code,
            'currency_symbol'=>$user->countryDetail->currency_symbol,
            'map_key'=>env('GOOGLE_MAP_KEY'),
            'show_rental_ride'=>true,
            // 'created_at' => $user->converted_created_at->toDateTimeString(),
            // 'updated_at' => $user->converted_updated_at->toDateTimeString(),
        ];

        $referral_comission = get_settings('referral_commision_for_user');
        $referral_comission_string = 'Refer a friend and earn'.$user->countryDetail->currency_symbol.''.$referral_comission;
        $params['referral_comission_string'] = $referral_comission_string;
        return $params;
    }

    /**
     * Include the roles of the user.
     *
     * @param User $user
     * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource
     */
    public function includeRoles(User $user)
    {
        $roles = $user->roles;

        return $roles
        ? $this->collection($roles, new RoleTransformer)
        : $this->null();
    }
    /**
     * Include the request of the user.
     *
     * @param User $user
     * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource
     */
    public function includeOnTripRequest(User $user)
    {
        $request = $user->requestDetail()->where('is_cancelled', false)->where('user_rated', false)->where('driver_id', '!=', null)->first();

        return $request
        ? $this->item($request, new TripRequestTransformer)
        : $this->null();
    }
    /**
    * Include the request meta of the user.
    *
    * @param User $user
    * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource
    */
    public function includeMetaRequest(User $user)
    {
        $request = $user->requestDetail()->where('is_completed', false)->where('is_cancelled', false)->where('user_rated', false)->where('driver_id', null)->where('is_later', 0)->first();

        return $request
        ? $this->item($request, new TripRequestTransformer)
        : $this->null();
    }

     /**
    * Include the request meta of the user.
    *
    * @param User $user
    * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource
    */
    public function includeSos(User $user)
    {
        $request = Sos::select('id', 'name', 'number', 'user_type', 'created_by')
        ->where('created_by', auth()->user()->id)
        ->orWhere('user_type', 'admin')
        ->orderBy('created_at', 'Desc')
        ->companyKey()->get();

        return $request
        ? $this->collection($request, new SosTransformer)
        : $this->null();
    }

    /**
     * Include the favourite location of the user.
     *
     * @param User $user
     * @return \League\Fractal\Resource\Collection|\League\Fractal\Resource\NullResource
     */
    public function includeFavouriteLocations(User $user)
    {
        $fav_locations = $user->favouriteLocations;

        return $fav_locations
        ? $this->collection($fav_locations, new FavouriteLocationsTransformer)
        : $this->null();
    }
}

but getting error this

Type of App\Transformers\User\UserTransformer::$availableIncludes must be array (as in class League\Fractal\TransformerAbstract)

{
    "success": false,
    "message": "Type of App\\Transformers\\User\\UserTransformer::$availableIncludes must be array (as in class League\\Fractal\\TransformerAbstract)",
    "status_code": 500,
    "code": 64,
    "debug": {
        "line": 15,
        "file": "/home/payeazyc/public_html/tagxi/app/Transformers/User/UserTransformer.php",
        "class": "Symfony\\Component\\Debug\\Exception\\FatalErrorException",
        "trace": [
            "#0 {main}"
        ]
    }
}

CodePudding user response:

Since starting from PHP8.* types system become more stricter, and recent version focused on the language design, some of the old principles wont work as you used to them.

In you case, look at the parent class (Transformer::class), there you will find that property $availableIncludes declared with a type of array.

In your child class( UserTransformer::class) this declaration missing on type hint level, and it causes this exception. To fix it simply add a type to your array explicitly (no doc blocs and annotations). the end result will look:


class UserTransformer extends Transformer
{
protected array $availableIncludes = [
        'roles','onTripRequest','metaRequest','favouriteLocations'
    ];
  • Related