format json not valid using jsonResponse in symfony - json

i'm using in my symfony project Json data and in my controller i return data with New Response , it would be like :
{"cn":"dvsdvsdvergfe","gender":"M","fgff":"data","mail":"sino#hotmail.fr","sn":"SINO","uid":"sino"}
but if i return my data in a JsonResponse i have data like this format :
"{\"cn\":\"dvsdvsdvergfe\",\"gender\":\"M\",\"fgff\":\"data\",\"mail\":\"sino#hotmail.fr\",\"sn\":\"SINO\",\"uid\":\"sino\",
}"
the controller :
public function getUserByUidAction($uid)
{
$url = self::Ws_URL . self::Ws_PORT . self::Ws_GetUserByUID . $uid;
$headers = array() ;
$headers[] = "auth_token: ".self::Ws_Token ;
$headers[] = "Content-Type: application/json" ;
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
"http" =>array(
"method" => "GET",
"header" => "auth_token: ".self::Ws_Token
)
);
$response = file_get_contents($url, true, stream_context_create($arrContextOptions));
$viewHandler = $this->get('fos_rest.view_handler');
$view = View::create($response);
$view->setFormat('json');
return $viewHandler->handle($view);
return New Response($response) ;
}
what is happened ?

Related

http post json dart Error: XMLHttpRequest error

I want to send a http post request to the server (json format) and get a response back in json format using flutter and dart.
i have a code on C#, which is works
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://mysite");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"email\":\"no#no.ru\"," +
"\"password\":\"mypass\"," +"\"remember\":\"false\"}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.ReadLine(result.ToString());
}
and on php
$data = array(
'email' => 'no#no.ru',
'password' => 'mypass',
'remember' => 'false'
);
$options = array(
'http' => array(
'method' => 'POST',
'content' => json_encode( $data ),
'header'=> "Content-Type: application/json\r\n" .
"Accept: application/json\r\n"
),
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
)
);
$url='https://mysite';
$context = stream_context_create( $options );
$result = file_get_contents( $url, false, $context );
$response = json_decode($result);
var_dump($response);
but on dart it doesn't works
var body = "{\"email\":\"no#no.ru\"," + "\"password\":\"mypass\"," +"\"remember\":\"false\"}";
var url =
Uri.https('mysite', '/mypath');
Map<String,String> headers = {
'Content-type' : 'application/json',
'Accept': 'application/json',
};
http.Response response = await http.post(
url,body:body,headers: headers);
print(response.body);
pubpecs.yaml:
http: ^0.13.0
i think the following error is caused by cors,but I can't solve it on the server side, as i written here
Error: XMLHttpRequest error.
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 906:28 get current
packages/http/src/browser_client.dart 71:22 <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1613:54 runUnary
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 155:18 handleValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 707:44 handleValueCallback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 736:13 _propagateToListeners
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 533:7 [_complete]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/stream_pipe.dart 61:11 _cancelAndValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/stream.dart 1219:7 <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 324:14 _checkAndCall
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 329:39 dcall
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/html/dart2js/html_dart2js.dart 37307:58 <fn>
at Object.createErrorWithStack (http://localhost:57471/dart_sdk.js:5356:12)
at Object._rethrow (http://localhost:57471/dart_sdk.js:39475:16)
at async._AsyncCallbackEntry.new.callback (http://localhost:57471/dart_sdk.js:39469:13)
at Object._microtaskLoop (http://localhost:57471/dart_sdk.js:39301:13)
at _startMicrotaskLoop (http://localhost:57471/dart_sdk.js:39307:13)
at http://localhost:57471/dart_sdk.js:34814:9
You have to escape your backslashes in your Json body, if that's the exact body you want to send:
var body = "{\\"email\":\\"no#no.ru\\"," + "\\"password\\":\\"mypass\\"," +"\\"remember\\":\\"false\\"}";

Post a not empty file to Dspace with Curl

I am posting a file to dspace through dspace api, I am doing this with an action in php. With postman I send a form-data with the file, filename, bitstream id and token.
I am getting the temp file path with $_FILES and sending it by postfields curl option, but the file uploads empty, or with weird data, without its content.
public function actionSubirBitstream()
{
if (Yii::$app->request->isPost) {
$body = $_POST;
$prefijo = '/rest/items/';
$host = ConfiguracionDspace::find()->where("clave='host'")->one()->valor;
$puerto = ConfiguracionDspace::find()->where("clave='puerto'")->one()->valor;
$token = $body['token'];
$id = $body['id'];
$final = '/bitstreams';
$name = $body['name'];//nombre del archivo sin espacios
$params = "?name=$name";
$url = $host . ':' . $puerto . $prefijo . $id . $final . $params;
$file = $_FILES['file']['tmp_name'];
//$path = $body['path'];
//$file = new CURLFILE("$path");
$headers = array("Content-Type: application/json", 'Accept: application/json', "rest-dspace-token: " . $token);
$curl = curl_init($url);
$options = array(
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => array('file'=> $file,'name' => $name),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers
);
curl_setopt_array($curl, $options);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('photo'=> new CURLFILE('/C:/Users/pfile3.jpeg'),'name' => $name),
this is the example of uploading a file with form key as photo and another key name
in your screen shot you have id and token in form data but in code its not inside POSTFIELDS
in postman you can generate equalent code of request in any language , try generating the PHP equalent code and see if it works:
To do this just click code link under the request url after saving the request
I already post the file by the $_FILE variable, But what I needed to do was to use CURLFILE to create a new file, and give it the temp path of the file in the server
$file = $_FILES['file']['tmp_name'];
and this in the postfields
CURLOPT_POSTFIELDS => array('file'=> new CURLFile("$file"),'name' => $name),
Thanks for the help friends
Here the code:
public function actionSubirBitstream()
{
if (Yii::$app->request->isPost) {
$body = $_POST;
$prefijo = '/rest/items/';
$host = ConfiguracionDspace::find()->where("clave='host'")->one()->valor;
$puerto = ConfiguracionDspace::find()->where("clave='puerto'")->one()->valor;
$token = $body['token'];
$id = $body['id'];
$final = '/bitstreams';
$name = $body['name'];//nombre del archivo sin espacios
$params = "?name=$name";
$url = $host . ':' . $puerto . $prefijo . $id . $final . $params;
$file = $_FILES['file']['tmp_name'];
//$path = $body['path'];
//$file = new CURLFILE("$path");
$headers = array("Content-Type: application/json", 'Accept: application/json', "rest-dspace-token: " . $token);
$curl = curl_init($url);
$options = array(
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => array('file'=> new CURLFile("$file"),'name' => $name),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers
);
curl_setopt_array($curl, $options);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}
The posted files with the rigth size(finally)
The form data I send by Postman, no need to use the field path

How can I upload files to GoogleDrive in “multipart” type by using Guzzle?

With the help of #Tanaike(see here), I can successfully upload files to GoogleDrive by using php-curl, here is my code by using php-curl:
function uploadByCurl($uploadFilePath, $accessToken){
$ch = curl_init();
$boundary = md5(mt_rand() . microtime());
//MetaData
$params = json_encode([
'name' => basename($uploadFilePath),
'description' => 'This is a test',
]);
$fileContent = file_get_contents($uploadFilePath);
$dataToUpload = "--{$boundary}\r\n";
$dataToUpload .= "Content-Type: application/json\r\n\r\n";
$dataToUpload .= "{$params}\r\n";
$dataToUpload .= "--{$boundary}\r\n";
$dataToUpload .= "Content-Transfer-Encoding: base64\r\n\r\n";
$dataToUpload .= base64_encode($fileContent) . "\r\n";
$dataToUpload .= "--{$boundary}--";
$options = [
CURLOPT_URL => 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => $dataToUpload,
CURLOPT_HTTPHEADER => [
'Authorization:Bearer ' . $accessToken,
'Content-Type: multipart/related; boundary=' . $boundary,
],
//In case you're in Windows, sometimes will throw error if not set SSL verification to false
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
//$options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
return $result;
}
$uploadFilePath = '<YOU-FILE-ABS-PATH>';
$accessToken = '<YOU-ACCESS-TOKEN>';
$ret = uploadByCurl($uploadFilePath, $accessToken);
var_dump($ret);
Response json:
{
"kind": "drive#file",
"id": "1lkuCTeMooRmde8uzNa7COUTTCLAk_jdq",
"name": "timg (12).jpeg",
"mimeType": "image/jpeg"
}
But when I'm trying to use Guzzle6(An curl client written by PHP) to do the same thing, the file(image file) can successfully upload but its name is "Untitled" and I can't preview the image(see the screenshot below):
Here is my code snippet by using Guzzle:
function uploadByGuzzle($uploadFilePath, $accessToken){
$boundary = md5(mt_rand() . microtime());
//MetaData
$params = json_encode([
'name' => basename($uploadFilePath),
'description' => 'This is a test',
]);
$fileContent = file_get_contents($uploadFilePath);
$dataToUpload = "--{$boundary}\r\n";
$dataToUpload .= "Content-Type: application/json\r\n\r\n";
$dataToUpload .= "{$params}\r\n";
$dataToUpload .= "--{$boundary}\r\n";
$dataToUpload .= "Content-Transfer-Encoding: base64\r\n\r\n";
$dataToUpload .= base64_encode($fileContent) . "\r\n";
$dataToUpload .= "--{$boundary}--";
$GuzzleConfig = [
'base_uri' => 'https://www.googleapis.com/upload/drive/v3/files/',
'timeout' => 30.0,
];
//In case you need a proxy
$GuzzleConfig['proxy'] = 'http://127.0.0.1:1087';
//GuzzleHttp
$client = new Client($GuzzleConfig);
$uri = '?uploadType=multipart';
$response = $client->request('POST', $uri, [
'verify' => false,
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
'Content-Type' => 'Content-Type: multipart/related; boundary=' . $boundary,
],
'body' => $dataToUpload,
]);
$string = $response->getBody()->getContents();
return $string;
}
$uploadFilePath = '<YOU-FILE-ABS-PATH>';
$accessToken = '<YOU-ACCESS-TOKEN>';
$ret = uploadByGuzzle($uploadFilePath, $accessToken);
var_dump($ret);
I think that the request body is correct. In your script, Content-Type is not correct. In this case, I think that body is sent as application/octet-stream. By this, the file of Untitled is created. And I think that it is the text data of the request body.
So how about this modification?
From:
'Content-Type' => 'Content-Type: multipart/related; boundary=' . $boundary,
To:
'Content-Type' => 'multipart/related; boundary=' . $boundary,

Json returned from recaptcha is ... bad

When doing
$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context);
$result = json_decode($response);
The response is
)]}'
["uvresp","03AJpayVHarkP_b40i5...stuff...VOrIy6m3ws",1,120]
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
The )]}' breaks things. I have no idea where that is coming from.
$g_recaptcha_response looks fine to me (what I am sending to google to verify).
The function to verify recaptcha
function verify_recaptcha ($g_recaptcha_response, $remote_address) {
# Verify captcha
$post_data = http_build_query(
array(
'secret' => 'secret',
'response' => $g_recaptcha_response,
'remoteip' => $remote_address
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
$context = stream_context_create($opts);
$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context);
$result = json_decode($response);
return $result->success;
}
Thanks.
Ok my bad. The above code works, I had a problem further downstream (query was trying to use a column that did not exist).

Use JSON in Symfony controller

I'm looking for a way to execute a little bit of JSON from my Symfony (2.6 btw) controller, moreover than an other action (post data into database)
In fact, there is an register page with a controller which put data into database and then, redirect user to another page. But i need that my controller execute too a little bit of JSON to use Mailchimp API.
I've found a lot of docs about how to render JSON response, but, it seems to me that it's not what i want to be.
There is my controller
public function registerAction(Request $request)
{
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
/** #var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isValid()) {
// Gestion du type d'utilisateur et ajout du role
$user_type = $form->get('user_profile')->get('type')->getData();
$new_role = $this->roles[$user_type];
$event = new FormEvent($form, $request);
$user = $event->getForm()->getData();
$user->addRole($new_role);
$user->getUserProfile()->setEmail($user->getEmail());
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
return $this->render('FOSUserBundle:Registration:register.html.twig', array(
'form' => $form->createView(),
));
}
There is my JSON request
{
"email_address": "$email",
"status": "subscribed",
"merge_fields": {
"FNAME": "$name",
"LNAME": "$lastname",
"DATE": "$date"
}
}
So, how can i do to execute this JSON with this controller ?
Thank you in advance for your help (and sorry for my excellent english)
You probably want to create the JSON from an array rather than try to pass variables. Try:
$data = [
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' => [
'FNAME' => $name,
'LNAME' => $lastname,
'DATE' => $date,
],
];
$json = json_encode($data);
Then I'm assuming this data gets sent to MailChimp in a POST request? If so, you could use Guzzle to send the data to MailChimp:
First add the guzzle dependency in composer by running:
composer require guzzlehttp/guzzle
Then send the data:
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://MAILCHIMP_URL', ['body' => $data]);
To send JSON instead of raw data, do the following:
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://MAILCHIMP_URL', ['json' => $data]);
Depending on the response status, you can then handle the logic afterwards.
You can achieve this also using JsonResponse (Symfony\Component\HttpFoundation\JsonResponse)
use Symfony\Component\HttpFoundation\JsonResponse;
...
// if you know the data to send when creating the response
$data = [
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' => [
'FNAME' => $name,
'LNAME' => $lastname,
'DATE' => $date,
]
];
$response = new JsonResponse($data);
return $response;
More details here https://symfony.com/doc/current/components/http_foundation.html