I am using a Transformer in my Laravel project. When I don't include an other object in the Transformer there isn't any problem but when I include the Customer object I get the following error:
Argument 1 passed to App\Transformers\CustomerTransformer::transform() must be an instance of App\Models\Customer, boolean given, called in /home/vagrant/Code/project/vendor/league/fractal/src/Scope.php on line 365 and defined
When I printed the object from Scope.php there weren't any booleans in it. What could be the problem? (The code crashes after Review #298.
How I call the code:
$reviews = $this->review->paginate();
$transformer = new ReviewTransformer();
$with = $request->get('with', null);
if($with) {
$with = explode(';', $with);
$transformer->parseIncludes($with);
}
return $this->response->paginator($reviews, $transformer);
Fixed the problem, I'm an idiot..
I had the following include in my Transformer class:
public function includeCustomer(Review $review)
{
$customer = $review->customer;
return $this->collection($customer, new CustomerTransformer);
}
The problem is that $customer is an Item an not a Collection. I had to change this->collection to this->item.
Related
I try to implement a webservice Client using php and got stuck...
I'm using an existing webservice called metadataservice with a known wsdl.
I'll use wsdl2phpgenerator to create the php classes for the datatypes and the Service itself.
Using one of the Webservice Methods (addMetadataToObject), I have to send an Array of objects to the Server.
There is a base class:
class AssetInfo
{
public $dataFieldId = null;
public $dataFieldName = null;
public $dataFieldTagName = null;
public function __construct($dataFieldId, $dataFieldName, $dataFieldTagName)
{
$this->dataFieldId = $dataFieldId;
$this->dataFieldName = $dataFieldName;
$this->dataFieldTagName = $dataFieldTagName;
}
}
and a derived class Holding string values (there are also other derived classes for Longs etc.):
class StringAssetInfo extends AssetInfo
{
public $value = null;
public function __construct($dataFieldId, $dataFieldName,$dataFieldTagName, $value)
{
parent::__construct($dataFieldId, $dataFieldName, $dataFieldTagName);
$this->value = $value;
}
}
For the call of Metadataservice->addMetadataToObject there is also a addMetadataToObject defined:
class addMetadataToObject
{
public $objectId = null;
public $objectType = null;
public $assetInfos = null;
public function __construct($objectId, $objectType)
{
$this->objectId = $objectId;
$this->objectType = $objectType;
}
}
The property $assetInfos should hold an Array of AssetInfo objects. wdsl2phpgenerator creates a class for my MetadataService which is derived from SoapClient. This class provides all the avialable Methods for this Service. Here I only show the addMetadataToObject Method:
public function addMetadataToObject(addMetadataToObject $parameters)
{
return $this->__soapCall('addMetadataToObject', array($parameters));
}
My Code does:
// Define the Data
$ServiceOptions = [];
$AssetInfos = [];
$AssetInfo = new StringAssetInfo(2, "TitleName", "TitleName","New Title Name);
array_push($AssetInfos, $AssetInfo);
// Create the Service
$Service = new MetadataService($ServiceOptions, getServiceWSDL($Options, "MetadataService"));
$Service->__setSoapHeaders(getGalaxySoapHeader($Options));
$NewMetaData = new addMetadataToObject(61755, "ASSET");
$NewMetaData->assetInfos = $AssetInfos;
// Call the Service
$failedAssets = $Service->addMetadataToObject($NewMetaData);
The call throws a Soap Exception that a value could not be extracted. Which makes me wonder. I started to monitor the traffic to the Soap Server using wireshark and yes....there is no value anymore as defined in the StringAsset Info Class...Here is the Soap Body shown by wireshark:
<SOAP-ENV:Body>
<ns1:addMetadataToObject>
<objectId>61755</objectId>
<objectType>ASSET</objectType>
<assetInfos>
<dataFieldId>2</dataFieldId>
<dataFieldName>TitleName</dataFieldName>
<dataFieldTagName>TitleName</dataFieldTagName>
</assetInfos>
</ns1:addMetadataToObject>
Id</SOAP-ENV:Body>
I would expect a tag New Title Name. But ist gone. When I checked the $NewMetaData object in my Code or the $Parameter object in $Service->addMetadataToObject I can see that the property "Value" is defined and set.
For me it seems, that the call to
return $this->__soapCall('addMetadataToObject', array($parameters));
only accepts the properties of the base class AssetInfo but not the properties from the derived class StringAssetInfo.
I also changed the Code to use an Array (instead of an object) for $AssetInfo:
$AssetInfo = array("dataFieldId"=>2, "dataFieldName"=>"TitleName","dataFieldTagName"=>"TitleName, "value"=>"New Title Name");
But without any change. It seems that we have here some Kind of runtime type conversion or type alignment but I can't see the reason of this. I'm still new to webservices at all and also on php (however I have to use both for the Moment:-)
Can anybody comment or give me a hint what's happening here?
I was able to realize it by using Arrays and soapvars, Please note my comments in the code:
$ServiceOptions = [];
$AssetInfos = [];
// I have to use an Array because the Server depends on the order of the properties. I wasn't able to define expected order using the existing objects but with arrays
$AssetInfo = array("dataFieldId"=>2, "dataFieldName"=>"TitleName","dataFieldTagName"=>"TitleName, "value"=>"New Title Name");
// instead of pushing the Array directly, I create an instance of an SoapVar, pass the Array as data and set the Encoding, the expected type and the Namespace uri
array_push($AssetInfos, new SoapVar($AssetInfo, SOAP_ENC_OBJECT, "StringAssetInfo", "http://metadataservice.services.provider.com"));
array_push($AssetInfos, $AssetInfo);
// Create the Service
$Service = new MetadataService($ServiceOptions, getServiceWSDL($Options, "MetadataService"));
$Service->__setSoapHeaders(getGalaxySoapHeader($Options));
$NewMetaData = new addMetadataToObject(61755, "ASSET");
$NewMetaData->assetInfos = $AssetInfos;
// Call the Service
$failedAssets = $Service->addMetadataToObject($NewMetaData);
This produced the expected Output in the Soap Body (and also added some namespaces to the Soap envelope
<SOAP-ENV:Body>
<ns1:addMetadataToObject>
<objectId>61755</objectId>
<objectType>ASSET</objectType>
<assetInfos xsi:type="ns1:StringAssetInfo">
<dataFieldId>2</dataFieldId>
<dataFieldName>TitleName</dataFieldName>
<dataFieldTagName>TitleName</dataFieldTagName>
<value>New Titel Name 1146</value>
</assetInfos>
</ns1:addMetadataToObject>
</SOAP-ENV:Body>
I got this error when trying to redirect to another method
Type error: Argument 1 passed to
Symfony\Component\HttpFoundation\ResponseHeaderBag::__construct() must
be of the type array, integer given, called in
/proyect/vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Response.php
on line 199
But I'm sending an empty array
return new RedirectResponse('persons', array(), UrlGeneratorInterface::RELATIVE_PATH);
Any help?
Is this the HttpFoundation\RedirectResponse class ? Your instanciation looks wrong.
// Symfony\Component\HttpFoundation\RedirectResponse
public function __construct($url, $status = 302, $headers = array())
{
...
}
Your third parameter is an integer, when an array is expected. The RedirectResponse constructor calls its parent, the Response constructor, and this code is executed:
// Symfony\Component\HttpFoundation\Response
public function __construct($content = '', $status = 200, $headers = array())
{
$this->headers = new ResponseHeaderBag($headers);
...
}
This is your error, you're using an integer (UrlGeneratorInterface::RELATIVE_PATH, equals to 2) when the expected value is an array of response headers.
As answered by #Cerad the correct solution is to use the redirectToRoute method, but it'll redirect you to an absolute path:
return $this->redirectToRoute('persons', array());
Or, if you still want to use the RedirectResponse with a relative path:
$url = $this->generateUrl('persons', array(), UrlGeneratorInterface::RELATIVE_PATH);
return new RedirectResponse($url);
I have a method, which takes a reference
// CarService.php
public function getCars(&$carCollection = null)
{
$promise = // guzzle request for getting all cars would be here
$promise->then(function (ResponseInterface $response) use (&$carCollection) {
$cars= json_decode($response->getBody(), true);
$carCollection= new CarCollection($cars);
});
}
However, when accessing the collection and trying to reuse it, I'm getting the error
Argument 1 passed to {placeholder} must be an instance of {placeholder}, null given
I know that the reason for this is, that the constructor returns nothing, but how can I still assign my variable to a new instance of the CarCollection (which extends Doctrine's ArrayCollection)
I even tried it with a static method as a work around
// CarCollection.php
public static function create(array $cars): CarCollection
{
$carCollection = new CarCollection($cars);
return $carCollection;
}
// CarService.php
public function getCars(&$carCollection = null)
{
$cars = // curl request for getting all cars would be here
$carCollection = CarCollection::create($cars)
}
but it's still null. Why is that? How can I set a referenced variable to a new class?
I access the method like this
$carService = $this->get('tzfrs.vehicle.services.car');
$carCollection = null;
$promises = [
$carService->getCars($carCollection)
];
\GuzzleHttp\Promise\unwrap($promises);
var_dump($carCollection); // null
When I set the reference directly, eg.
// CarService.php
public function getCars(&$carCollection = null)
{
$carCollection = new CarCollection([]);
}
it works without any problems. Seems like the callback is somehow the problem.
Whoever downvoted this, can you please elaborate why and why you voted to close?
I might be misunderstanding the question, but you should be able to modify an object when passing by reference. See here for an example: https://3v4l.org/KtFvZ
In the later example code that you added, you shouldn't pass $carCollection by reference, the & should only be in the method/function defintion, not provided when you call it. I don't think that is your problem though, that should be throwing an error in php7.
I am working with Yii2 REST api and using Authorisation : Bearer for authentication.
I have a model Event and only 2 actions Create and Update but my Updateaction is not working fine and throws Object Class conversion error.
I am using following code for finding Event model with mixed condition.
public function actionUpdate($id)
{
$params=$_REQUEST;
/*Following line throws error */
$model = Event::find()->where(['event_id'=>$id])->andWhere(['partner_id'=> Yii::$app->user->identity]);
if($model !== null){
$model->attributes=$params;
$model->partner_id = Yii::$app->user->id;
$model->updated_date = time();
if ($model->save()) {
$this->setHeader(200);
echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
}
}
}
The error is something like this
Object of class api\modules\v1\models\User could not be converted to string
I cant figure out why it says i have created object of User class.
Yii::$app->user->identity
is object you should use
Yii::$app->user->identity->id
so final line will be:
$model = Event::find()->where(['event_id'=>$id])->andWhere(['partner_id'=> Yii::$app->user->identity->id]);
The problem is with your andWhere(), you are trying to assign partner_id an object viz. Yii::$app->user->identity, so this is where your code is breaking. And do not use json_encode when you can use Yii's response format Response::FORMAT_JSON, so your code would be like:
public function actionUpdate($id)
{
\Yii::$app->response->format = yii\web\Response::FORMAT_JSON; // formatting response in json format
$params= json_decode(\Yii::$app->request->rawBody, 1);
/*Following line throws error */
$model = Event::find()->where(['event_id'=>$id])->andWhere(['partner_id'=> Yii::$app->user->identity->id]);
if($model !== null){
$model->attributes=$params;
$model->partner_id = Yii::$app->user->id;
$model->updated_date = time();
if ($model->save()) {
$this->setHeader(200);
return array('status'=>1,'data'=> $model); // you can simply use $model
}
}
}
The issue is here:
andWhere(['partner_id'=> Yii::$app->user->identity])
You ARE attempting to convert a user object (Yii::$app->user->identity) to a string. Instead, you need to use the user's id (Yii::$app->user->identity->id) which is a string.
I got the following error:
Catchable Fatal Error: Argument 1 passed to Rowoco\AllgemeinBundle\Entity\Place::setIdUser() must
be an instance of Rowoco\AllgemeinBundle\Entity\FosUser, instance of
Rowoco\UserBundle\Entity\User given, called in
/var/www/symfony/src/Rowoco/AllgemeinBundle/Controller/AllgemeinAjaxController.php on line 64 and
defined in /var/www/symfony/src/Rowoco/AllgemeinBundle/Entity/Place.php line 331
In the following function i try to add a new place:
public function test()
{
$em = $this->getDoctrine()->getManager();
$stateRepo = $em->getRepository( "RowocoAllgemeinBundle:State" );
$stateEntity = $stateRepo->find(1);
$user = $this->get('security.context')->getToken()->getUser();
$place = new Place();
$place->setAdddate( "2014-01-01 12:12:10" );
$place->setTitle( "test" );
$place->setDescription( "testdescription" );
$place->setSpecial( "special" );
$place->setStreet( "strasse" );
$place->setZipcode( "12345" );
$place->setIdState( $stateEntity );
$place->setIdUser( $user );
$em->persist( $place );
$em->flush();
//return new Response('Created product id '.$product->getId());
return true;
}
in the table place i have two foreignkeys
id_state
id_user
how can i fix this error?
Somethings around your code:
First the error is telling you what the problem is and where, take a look at this line:
Catchable Fatal Error: Argument 1 passed to Rowoco\AllgemeinBundle\Entity\Place::setIdUser()
must be an instance of Rowoco\AllgemeinBundle\Entity\FosUser, instance of
Rowoco\UserBundle\Entity\User
You're passing a complete object to setIdUser() method which BTW expect a FOSUser instance
Second, if you're using Symfony > 2.1.x you should use $this->getUser() and not as you're doing (this is a tip)
As third if you only need to insert the id_user as state in question, why pass the entire object? Why not just pass the current logged in user id? Something like $this->getUser()->getId()?