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}"
]
}
}
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'
];
I'm using CakePHP version 4.2 and am noticing some odd behavior from the annotate script that comes bundled with the API. For one component, the annotate script wants to default to the App\ domain that is CakePHP's default. I've changed the application name so most other classes default to the correct application name. But not this one script and so far, only for this one file.
I've included the body of the component, for review, below. You can see that the #method annotation uses the App\ domain. The trouble comes in when I use PHPStan to analyze my code. If I leave the annotation as is, PHPStan will tell me:
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------
Line src/Controller/Component/CartManagerComponent.php
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------
43 Property Visualize\Controller\Component\CartManagerComponent::$Controller (Visualize\Controller\AppController) does not accept App\Controller\AppController.
44 Call to method loadModel() on an unknown class App\Controller\AppController.
💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------
The file itself doesn't use the App\ domain anywhere. I'm not sure where to look for the script to figure out whats wrong. Here is the body of my component in case you see something I do not:
<?php
declare(strict_types=1);
namespace Visualize\Controller\Component;
use Authorization\Identity;
use Cake\Controller\Component;
use Cake\Log\Log;
/**
* CartManager component
*
* #method \App\Controller\AppController getController()
* #property \Visualize\Controller\AppController $Controller
* #property \Visualize\Model\Table\CartsTable $Carts
*/
class CartManagerComponent extends Component
{
/**
* Default configuration.
*
* #var array
*/
protected $_defaultConfig = [];
/**
* #var \Visualize\Controller\AppController
*/
protected $Controller;
/**
* #var \Visualize\Model\Table\CartsTable
*/
protected $Carts;
/**
* #param array $config The current configuration array
* #return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->Controller = $this->getController();
$this->Controller->loadModel('Carts');
}
/**
* Returns the most recent active cart.
*
* #param \Authorization\Identity $user The User entity.
* #return array|\Cake\Datasource\EntityInterface|null
* #noinspection PhpUnnecessaryFullyQualifiedNameInspection
*/
public function getUserCart(Identity $user)
{
$cart = $this->Controller->Carts->newEmptyEntity();
if (!empty($this->Controller->Carts) && is_a($this->Controller->Carts, '\Visualize\Model\Table\CartsTable')) {
$query = $this->Controller->Carts->find('userCart', ['user_id' => $user->getIdentifier()]);
if (!$query->isEmpty()) {
$cart = $query->first();
} else {
$cart->set('user_id', $user->getIdentifier());
$this->Controller->Carts->save($cart);
}
if (is_object($cart) && is_a($cart, '\Cake\Datasource\EntityInterface')) {
$session = $this->Controller->getRequest()->getSession();
$session->write('Cart.id', $cart->id);
}
}
return $cart;
}
/**
* Abandons carts
*
* #param int $user_id The associated user ID
* #param int $cart_id The current cart ID
* #return void
*/
public function pruneCarts(int $user_id, int $cart_id): void
{
if (!empty($this->Controller->Carts) && is_a($this->Controller->Carts, '\Visualize\Model\Table\CartsTable')) {
// Find all the carts we didn't just create:
$userCarts = $this->Controller->Carts->find('all', ['fields' => ['id', 'user_id', 'cart_status']])
->where([
'id !=' => $cart_id,
'user_id' => $user_id,
'cart_status' => 'active',
]);
if (!$userCarts->isEmpty()) {
$count = 0;
foreach ($userCarts as $cart) {
if ($count < 5) {
$record = $this->Controller->Carts->newEmptyEntity();
$record = $this->Controller->Carts->patchEntity($record, $cart->toArray());
$record->set('id', $cart->id);
$record->set('cart_status', ABANDONED_CART);
if (!$this->Controller->Carts->save($record)) {
Log::alert('Error abandoning cart');
}
} else {
$this->Controller->Carts->delete($cart);
}
$count++;
}
}
}
}
}
I'm creating a CRUD API in Laravel 7 using resource collection but when i try to send data using post request it gives
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: The POST method is not supported for this route. Supported methods: GET, HEAD. in file D:\xampp\htdocs\safaripet\backend\vendor\laravel\framework\src\Illuminate\Routing\AbstractRouteCollection.php on line 117
my route
Route::apiResource('locations','Api\LocationsController');
my controller code
<?PHP
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\Locations as LocationsResource;
use App\Locations;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Validator;
class LocationsController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return new LocationsResource(Locations::paginate(3));
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'location_name' => 'required|unique:locations',
],
[
'location_name.required' => 'Enter name',
'location_name.unique' => 'location name already exist',
]);
$locations = new Locations();
$locations->location_name = $request->location_name;
$locations->slug = Str::slug($request->location_name);
$locations->save();
return new LocationsResource($locations);
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
please help me
thanks in advance.
You are posting to http://localhost:8000/locations, while your routes list clearly defines the URI http://localhost:8000/api/locations
I have no idea why, but after a few (unrelated) changes all my returns are objects instead of arrays. For example:
ReceiptController.php
/**
* Get all receipts for the team.
*
* #param String $id
* #return array
*
* #SWG\Response(
* response=201,
* description="Get all receipt for the team.",
* #SWG\Schema(
* type="array"
* )
* )
*/
public function getTeamReceiptsAction($id): array
{
$parameterBag = [
'teamId' => $id
];
$items = $this->manager->getAll($parameterBag);
return $items;
}
Receiptrepository
/**
* #inheritdoc
*/
public function getFilterQuery($parameterBag): QueryBuilder
{
$qb = $this
->createQueryBuilder('s')
;
if (isset($parameterBag['id'])) {
$qb->andWhere('s.id=(:id)')
->setParameter('id', $parameterBag['id']);
}
if (isset($parameterBag['teamId'])) {
$qb->andWhere('s.team=(:team)')
->setParameter('team', $parameterBag['teamId']);
}
return $qb;
}
/**
* #inheritdoc
*/
public function getAll($parameterBag): ?array
{
$qb = $this->getFilterQuery($parameterBag);
return $qb->getQuery()->getResult();
}
Returns:
{"0":{"email":"admin#benj.be","first_name"...
While i would expect [{"email":"admin#benj.be","first_name"... ?
So it returns an object with multiple objects in it instead of an array.
But that's weird, because all my functions are typed to return array's, and I don't get any errors?
try to change this:
return $qb->getQuery()->getResult();
to this:
return $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
In this mode you can retrieve results in array
Or as Tomasz Madeysk wrote try this:
return $qb->getQuery()->getArrayResult()
I am receiving the following error
While attempting to create memberformmembernextpasswordchange(alias: Member\Form\member\NextPasswordChange) an invalid factory was registered for this instance type.
I created the following file structure ( with sub directories for Forms, Input Filters and Services ) to make it easier for long term maintenance since each section of the Member module will have so much content:
[root#localhost src]$ find . -type d
.
./Member
./Member/Form
./Member/Form/member
./Member/Form/member/Factory
./Member/Controller
./Member/Controller/Factory
./Member/Service
./Member/Service/Form
./Member/Service/Form/Factory
./Member/Service/Factory
./Member/InputFilter
./Member/InputFilter/member
But I haven't been able to figure out how to "link" the files the sub directories contain. Is this even possible?
Within module.config.php I have
'form_elements' => [
'factories' => [
'Member\Form\member\NextPasswordChange' => 'Member\Form\member\Factory\NextPasswordChangeFactory',
],
],
'input_filters' => [
'invokables' => [
'Member\InputFilter\member\NextPasswordChange' => 'Member\InputFilter\member\NextPasswordChange',
]
],
'service_manager' => [
'factories' => [
'Member\Service\Member' => 'Member\Service\Factory\MemberFactory',
'Member\Service\Form\NextPasswordChange' => 'Member\Service\Form\Factory\NextPasswordChangeFactory',
]
],
Within MemberControllerFactory I have
/**
* #param ServiceLocatorInterface $serviceLocator
*
* #return MemberController
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
/**
* #var \Zend\ServiceManager\ServiceLocatorAwareTrait $serviceLocator
*/
$sl = $serviceLocator->getServiceLocator();
/**
* #var \Member\Form\member\NextPasswordChange $formNextPasswordChange
*/
$formNextPasswordChange = $sl->get('FormElementManager')
->get('Member\Form\member\NextPasswordChange');
/**
* #var \Member\Service\Member $serviceMember
*/
$serviceMember = $sl->get('Member\Service\Member');
/**
* #var \Member\Service\Form\NextPasswordChange $serviceNextPasswordChange
*/
$serviceNextPasswordChange = $sl->get('Member\Service\Form\NextPasswordChange');
return new MemberController(
$formNextPasswordChange,
$serviceMember,
$serviceNextPasswordChange
);
}
The header section of MemberController contains
namespace Member\Controller;
use Member\Form\member\NextPasswordChange as FormNextPasswordChange;
use Member\Service\Member as ServiceMember;
use Member\Service\Form\NextPasswordChange as ServiceNextPasswordChange;
use Zend\Http\Request;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
/**
* Class MemberController
*
* #package Member\Controller
*
* #method Request getRequest()
*/
class MemberController extends AbstractActionController
{
/**
* #var FormNextPasswordChange $formNextPasswordChange
*/
private $formNextPasswordChange;
/**
* #var ServiceMember $serviceMember
*/
private $serviceMember;
/**
* #var ServiceNextPasswordChange $serviceNextPasswordChange
*/
private $serviceNextPasswordChange;
/**
* #param FormNextPasswordChange $formNextPasswordChange
* #param ServiceMember $serviceMember
*/
public function __construct(
FormNextPasswordChange $formNextPasswordChange,
ServiceMember $serviceMember,
ServiceNextPasswordChange $serviceNextPasswordChange
)
{
$this->formNextPasswordChange = $formNextPasswordChange;
$this->serviceMember = $serviceMember;
$this->serviceNextPasswordChange = $serviceNextPasswordChange;
}