How to upload a file using zend HttpClient? - php

I'm using HTTP client. How to attach a file while sending a post request?
Here's my code:
function executePost($postdata = [], $full_file_path = ''){
self::$client = new Zend\Http\Client(null,
['timeout' => 30] // updated to 30 sec
);
self::$client->setEncType(Zend\Http\Client::ENC_URLENCODED);
self::$client->setUri($url);
self::$client->setMethod($method);
self::$client->setParameterPost($postdata);
$response = $client->send();
Debug::dump($response->getContent(),$label='Response',$echo=true);
}
I have tried $postdata['file_contents'] = '#'.$full_file_path; but it doesn't help.
Does anyone have an idea on how to attach file with the post data?
Thanks in advance.

Instead of using that data array try using the designated method called setFileUpload. So in your example it could look like so:
$client = new \Zend\Http\Client(null, ['timeout' => 30]);
$client->setUri($url);
$client->setFileUpload($full_file_path, 'file_contents');
$client->setMethod('POST'); // this must be either POST or PUT
$response = $client->send();
setFileUpload should also set the enc type.
There's a doc section related to that here.

Related

Getting Wordpress REST-API content data inside a plugin with embed data

I'm creating my own routes for the wodpress api. At some point I need the rest content of the post and pages, to do this i have this function:
function get_rest_content($id, $type)
{
if ($id > 0) {
$request = new WP_REST_Request('GET', '/wp/v2/'.$type.'/' . $id);
$response = rest_do_request($request)->data;
} else {
$response = null;
}
if (empty($response)) {
return new WP_Error('wpse-error',
esc_html__('No '.$type. 'found', 'wpse'),
['status' => 404]);
}
return $response;
}
$post_1 = get_rest_content(1,'posts') // give me the rest content of the post with id=1
but if I want to have the post content with embed data I change:
new WP_REST_Request('GET', '/wp/v2/'.$type.'/' . $id);
to
new WP_REST_Request('GET', '/wp/v2/'.$type.'/' . $id . '?_embed=true');
but this new request returns rest_no_route error
I have read the source code and now understand. The second parameter of new WP_REST_Request() is the route only without query parameters. The query parameters are specified in another method. E.g.,
$request = new WP_REST_Request( 'GET', 'wp/v2/posts/999' );
$request->set_query_params( [ '_embed' => '1' ] );
However, this will not work as '_embed' is a special query parameter. It is not handled by WP_REST_Server::dispatch(), which means rest_do_request() will not handle '_embed' as rest_do_request() is just a wrapper of WP_REST_Server::dispatch().
The reason '_embed' works from a URL is that URLs are processed by WP_REST_Server::serve_request() which calls WP_REST_Server::dispatch() but also calls WP_REST_Server::response_to_data() which calls WP_REST_Server::embed_links().
If you want '_embed' to work in your get_rest_content() you will need to add the code for WP_REST_Server::embed_links().
I found a Github issue but the workaround is not working for me (at least for my code+WordPress version): https://github.com/WP-API/WP-API/issues/2857
Did you try adding the embeddable links to the response?
//get the post
$response = rest_do_request($request)->get_data();
//add the embeddable links
$results_with_embed = rest_ensure_response(rest_get_server()->response_to_data( $response, true ));

Sending a custom header with ZEND_HTTP_CLIENT

How can I send a custom header with the ZEND_HTTP_CLIENT. I am trying to send a variable key with a certain value, that I will check later for authenticity
I've tried this
$client = new Zend_Http_Client('http://localhost/v3/files/');
$client->setHeaders('Content-type','multipart/form-data');
$client->setHeaders('key','XXXxXXXXXXXXXXXXXX');
$client->setParameterPost('document_id', $id);
$client->setParameterPost('type_id', $docType['type']);
$client->setParameterPost('file', $form->file);
$response = $client->request(Zend_Http_Client::POST);
and this
$client = new Zend_Http_Client('http://localhost/v3/files/');
$client->setHeaders(array(
'Content-type','multipart/form-data',
'key','XXXxXXXXXXXXXXXXXX'));
$client->setParameterPost('document_id', $id);
$client->setParameterPost('type_id', $docType['type']);
$client->setParameterPost('file', $form->file);
$response = $client->request(Zend_Http_Client::POST);
but it doesnt seem to work. It says key is not a valid type.
I want to send a custom header like this (similar to what happens when you set headers with the Postman client).
Is this possible?
Try with add a config param like this:
$client = new Zend_Http_Client('http://localhost/v3/files/', array('strict' => false));

How to add form data on Post requests for Buzz HTTP Client on Laravel?

I'm using Buzz HTTP Client for Laravel.
I have a problem adding form data to my POST requests, since it wasn't specified in it's wiki/documentation.
Listed below are the two ways of sending requests.
Example 1:
$response = Buzz::post('http://api.website.com/login');
//how do I add a "username", and "password" field in my POST request?
echo $response;
echo $response->getContent;
Example 2:
$request = new Buzz\Message\Request('POST', '/', 'http://google.com');
$response = new Buzz\Message\Response();
//how do I add a "username", and "password" field in my POST request?
$client = new Buzz\Client\FileGetContents();
$client->send($request, $response);
echo $request;
echo $response;
The answer here is going to really depend on what the API expects. Lets assume, the API expects the password and username sent as JSON in the content of the request. The example http request would look something like:
POST /login HTTP/1.1
Content-Type: application/json
{
"username": "bugsBunny",
"password": "wh4tsUpD0c"
}
To do this with Buzz, this should work:
$jsonPayload = json_encode([
‘username’ => ‘bugsBunny’,
‘password’ => ‘wh4tsUpD0c
]);
$headers = ['Content-Type', 'application/json'];
$response = Buzz::post('http://api.website.com/login', $headers, $jsonPayload);
If you're attempting to submit a form on a given website, you shouldn't use the above method. Instead use Buzz's built in form method which will attach the correct headers.
use Buzz\Message\Form;
$request = new Form(Form::METHOD_POST, ‘login’, ‘api.website.com’);
$request->setFields([
‘username’ => ‘bugsBunny’,
‘password’ => ‘wh4tsUpD0c’
]);
$response = new Buzz\Message\Response();
$client = new Buzz\Client\Curl();
$client->send($request, $response);
On a side note, I'd suggest not using this library. The library is, as you stated, Laravel integration for Buzz. The issue here is, the author should have made buzz a dependency listed in composer, rather than include the Buzz source directly. This prevents updates to Buzz from making their way into this project. You can see on the actual Buzz repo, the last commit was 29 days ago. Also if another package is using Buzz and including it correctly by composer, composer would install both packages. But when an instance of Buzz was created, you couldn't be certain which version was being loaded. You should just use Buzz, which can be found on packagist.
// assuming $headers and $jsonPayload are the same as in previous example.
$browser = new Buzz\Browser();
$response = $browser->post('http://api.website.com/login', $headers, $jsonPayload);
It was foolish of me to not read the code first before asking.
The form data is actually pased on the third parameter for the function. Though it accepts strings only so don't forget to json encode your data.
Buzz Class
public function post($url, $headers = array(), $content = '')
{
....
....
}
Buzz::post($url, array(), json_encode(array('Username'=>'usernamexx','Password'=>'p#$$w0rD')) );

Is it possible to parse JSON with Goutte?

I'm working on crawling web sites and there is no problem for parsing HTML with Goutte so far. But I need to retrieve JSON from a web site and because of the cookie management, I don't want to do this with file_get_contents() - that doesn't work.
I can do with pure cURL but in this case I just want to use Goutte and don't want to use any other library.
So is there any method that I can parse only text via Goutte or do I really have to do this with good old methods?
/* Sample Code */
$client = new Client();
$crawler = $client->request('foo');
$crawler = $crawler->filter('bar'); // of course not working
Thank you.
After very deep search inside Goutte libraries I found a way and I wanted to share. Because Goutte is really powerful library but there are so complicated documentation.
Parsing JSON via (Goutte > Guzzle)
Just get needed output page and store json into an array.
$client = new Client(); // Goutte Client
$request = $client->getClient()->createRequest('GET', 'http://***.json');
/* getClient() for taking Guzzle Client */
$response = $request->send(); // Send created request to server
$data = $response->json(); // Returns PHP Array
Parsing JSON with Cookies via (Goutte + Guzzle) - For authentication
Send request one of the page of the site (main page looks better) to get cookies and then use these cookies for authentication.
$client = new Client(); // Goutte Client
$crawler = $client->request("GET", "http://foo.bar");
/* Send request directly and get whole data. It includes cookies from server and
it automatically stored in Goutte Client object */
$request = $client->getClient()->createRequest('GET', 'http://foo.bar/baz.json');
/* getClient() for taking Guzzle Client */
$cookies = $client->getRequest()->getCookies();
foreach ($cookies as $key => $value) {
$request->addCookie($key, $value);
}
/* Get cookies from Goutte Client and add to cookies in Guzzle request */
$response = $request->send(); // Send created request to server
$data = $response->json(); // Returns PHP Array
I hope it helps. Because I almost spend 3 days to understand Gouttle and it's components.
I figured this out after several hours of search , simply do this :
$client = new Client(); // Goutte Client
$crawler = $client->request("GET", "http://foo.bar");
$jsonData = $crawler->text();
mithataydogmus' solution didn't work for me. I created a new class "BetterClient":
use Goutte\Client as GoutteClient;
class BetterClient extends GoutteClient
{
private $guzzleResponse;
public function getGuzzleResponse() {
return $this->guzzleResponse;
}
protected function createResponse($response)
{
$this->guzzleResponse = $response;
return parent::createResponse($response);
}
}
Usage:
$client = new BetterClient();
$request = $client->request('GET', $url);
$data = $client->getGuzzleResponse()->json();
I also could get JSON with:
$client->getResponse()->getContent()->getContents()

2 legged oath request without command line

i want to make an 2 legged oauth yql request with php.
So far:
// Include the PHP SDK.
include_once("yosdk/lib/Yahoo.inc");
// Define constants to store your API Key (Consumer Key) and
// Shared Secret (Consumer Secret).
define("API_KEY","her_comes the key");
define("SHARED_SECRET","here_comes_the_secret");
$two_legged_app = new YahooApplication(API_KEY,SHARED_SECRET);
$stock_query = "elect * from ......";
$stockResponse = $two_legged_app->query($stock_query);
var_dump($stockrResponse);
But the problem is, that i dont want to query the command line..... i just want to oauth with the api key i got and use the url directly i got of the command when i typed in yql....
like this:
$url='http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20('+url_stocks+')&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys';
(i edited the url that came out my wishes for).Please dont ask why i dont use the command to query (long story). i would be pleased by getting some help.
thanks.
solved it:
http://code.google.com/p/oauth-php/wiki/ConsumerHowTo
include_once "oauth/library/OAuthStore.php";
include_once"oauth/library/OAuthRequester.php";
$key_1 = "your_key"; $secret_1 = "your_secret";
$ticks="%22AAPL%22%2C%22MSFT%22";
$options = array( 'consumer_key' => $key_1, 'consumer_secret' =>
$secret_1 ); OAuthStore::instance("2Leg", $options );
$url =
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20('$ticks')&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
// this is the URL of the request $method = "GET"; // you can also use
POST instead $params = null;
try {
// Obtain a request object for the request we want to make
$request = new OAuthRequester($url, $method, $params);
// Sign the request, perform a curl request and return the results,
// throws OAuthException2 exception on an error
// $result is an array of the form: array ('code'=>int, 'headers'=>array(), 'body'=>string)
$result = $request->doRequest();
$response = $result['body'];
$resp_array=json_decode($response,TRUE);
echo $resp_array['query']['results']['quote'][1]['symbol']; // MSFT
} catch(OAuthException2 $e) { }

Categories