PHP array to get single valid XML - php

I use the following api to get product info from amazon.
It uses a single value for variable $asin to get the data and print it as xml. It works fine, but this is only for one product at a timeā€¦
I would like instead of a single variable $asin, to use an array with multiple values and print to one single xml.
I tried to use foreach, but I get en xml declaration for every loop.
Where do I need to use foreach in my code? Thanks for the help.
<?php
// Region code and Product ASIN
$response = getAmazonPrice("com", "B00KQPGRRE");
function getAmazonPrice($region, $asin) {
$xml = aws_signed_request($region, array(
"Operation" => "ItemLookup",
"ItemId" => $asin,
"IncludeReviewsSummary" => False,
"ResponseGroup" => "Medium,OfferSummary",
));
$item = $xml->Items->Item;
$title = htmlentities((string) $item->ItemAttributes->Title);
$url = htmlentities((string) $item->DetailPageURL);
$image = htmlentities((string) $item->MediumImage->URL);
$price = htmlentities((string) $item->OfferSummary->LowestNewPrice->Amount);
$code = htmlentities((string) $item->OfferSummary->LowestNewPrice->CurrencyCode);
$qty = htmlentities((string) $item->OfferSummary->TotalNew);
if ($qty !== "0") {
$response = array(
"code" => $code,
"price" => number_format((float) ($price / 100), 2, '.', ''),
"image" => $image,
"url" => $url,
"title" => $title
);
}
return $response;
}
function getPage($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$html = curl_exec($curl);
curl_close($curl);
return $html;
}
function aws_signed_request($region, $params) {
$public_key = "PUBLIC_KEY";
$private_key = "PRIVATE_KEY";
$method = "GET";
$host = "ecs.amazonaws." . $region;
$host = "webservices.amazon." . $region;
$uri = "/onca/xml";
$params["Service"] = "AWSECommerceService";
$params["AssociateTag"] = "affiliate-20"; // Put your Affiliate Code here
$params["AWSAccessKeyId"] = $public_key;
$params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z");
$params["Version"] = "2011-08-01";
ksort($params);
$canonicalized_query = array();
foreach ($params as $param => $value) {
$param = str_replace("%7E", "~", rawurlencode($param));
$value = str_replace("%7E", "~", rawurlencode($value));
$canonicalized_query[] = $param . "=" . $value;
}
$canonicalized_query = implode("&", $canonicalized_query);
$string_to_sign = $method . "\n" . $host . "\n" . $uri . "\n" . $canonicalized_query;
$signature = base64_encode(hash_hmac("sha256", $string_to_sign, $private_key, True));
$signature = str_replace("%7E", "~", rawurlencode($signature));
$request = "http://" . $host . $uri . "?" . $canonicalized_query . "&Signature=" . $signature;
$response = getPage($request);
var_dump($response);
$pxml = #simplexml_load_string($response);
if ($pxml === False) {
return False;// no xml
} else {
return $pxml;
}
}
?>
I used the following code to have multiple values:
<?php
// Region code and Product ASIN
$array = array("B00PXRRB2U","B00F90P9R0","B005OJU3K4");
foreach ($array as $asin) {
$response = getAmazonPrice("com", $asin);
}
function getAmazonPrice($region, $asin) {
$xml = aws_signed_request($region, array(
"Operation" => "ItemLookup",
"ItemId" => $asin,
"IncludeReviewsSummary" => False,
"ResponseGroup" => "Medium,OfferSummary",
));
The result is:

Amazon allows the lookup of up to 10 items with a single request. Its service expects the ASINs to be passed as a string separated by commas.
So you could try the following code (please note I didn't actually try it because I don't have credentials but I used it like that before and it worked):
$array = array("B00PXRRB2U","B00F90P9R0","B005OJU3K4");
$xml = aws_signed_request('com', array(
"Operation" => "ItemLookup",
"ItemId" => join(', ', $array),
"IncludeReviewsSummary" => False,
"ResponseGroup" => "Medium,OfferSummary",
));
And then I think what you're looking for will be in $xml->Items but you'd better double check that.

Related

how to pass a value from repository to the controller in laravel

SmartpaySPaymentRepository.php
i am new to laravel. i want to passe this value ($url->nodeValue) which is in the SmartpaySPaymentRepository.php sendPaymentToSmartpaySForPaymentToken function to SmartPaySController.php getQuotePayment($quoteId) function can someone help me to do this?
public function sendPaymentToSmartpaySForPaymentToken($xml, $authToken, $transactionId, $doPrepareUrl)
{
$fields = array(
'authToken' => $authToken,
'&requestXML' => $xml,
);
$fields_string = $xml;
foreach ($fields as $key => $value) {
$fields_string .= $key . '=' . $value . '&';
}
rtrim($fields_string, '&');
//open connection
$ch = curl_init($doPrepareUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
$response_from_smartpays = curl_exec($ch);
curl_close($ch);
$testString = $response_from_smartpays;//xml string
$dom = new \DOMDocument();
$dom->formatOutput = TRUE;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXml($testString);
$result = ($dom->getElementsByTagName('redirectURL'));
foreach ($result as $url){
return ($url->nodeValue);//want to passe this value to controller
}
}
SmartPaySController.php
public function getQuotePayment($quoteId)
{
$quote = $this->quoteRepo->getQuoteById($quoteId);
if($quote) {
$totalPrice = $quote->total_price;
if ($quote->amended_policy) {
$totalPrice = $quote->amend_price;
}
dd($url->nodeValue);//want to use $url->nodeValue here
$currency = CURRENCY_TYPE;
return $this->processSmartpaySPayment(PAYMENT_TYPE_QUOTE, $totalPrice, $currency, $quote->customer_id, $quoteId);
}else {
abort(404);
}
}
You can return them as an array in repository
$resultReturn = []
foreach ($result as $url){
$resultReturn[] = ($url->nodeValue);//want to passe this value to controller
}
return $resultReturn; // pass the array contiling all rsults in the loop
In the controller
$currency = CURRENCY_TYPE;
$results = $this->processSmartpaySPayment(PAYMENT_TYPE_QUOTE, $totalPrice, $currency, $quote->customer_id, $quoteId);
dd($results); //array of $url->nodeValue here
return $results;

ecs.amazonaws.com Api We encountered an internal error

I recently face problem with amazon lookupitem search api . It was working before In a script I have been successfully executing hundreds requests but now i don't know what is the problem Here is my Amazon.php
class Amazon
{
// public key
var $publicKey = "[public key]";
// private key
var $privateKey = "[private key]";
// affiliate tag
var $affiliateTag = 'affiliateTag';
/**
* #param $param
* #return mixed
*/
public function generateSignature($param)
{
// url basics
$signature['method'] = 'GET';
$signature['host'] = 'ecs.amazonaws.' . $param['region'];
$signature['uri'] = '/onca/xml';
// necessary parameters
$param['Service'] = "AWSECommerceService";
$param['AWSAccessKeyId'] = $this->publicKey;
$param['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z");
$param['Version'] = '2009-10-01';
ksort($param);
foreach ($param as $key => $value) {
$key = str_replace("%7E", "~", rawurlencode($key));
$value = str_replace("%7E", "~", rawurlencode($value));
$queryParamsUrl[] = $key . "=" . $value;
}
// glue all the "params=value"'s with an ampersand
$signature['queryUrl'] = implode("&", $queryParamsUrl);
// we'll use this string to make the signature
$StringToSign = $signature['method'] . "\n" . $signature['host'] . "\n" . $signature['uri'] . "\n" . $signature['queryUrl'];
// make signature
$signature['string'] = str_replace("%7E", "~",
rawurlencode(
base64_encode(
hash_hmac("sha256", $StringToSign, $this->privateKey, True
)
)
)
);
return $signature;
}
/**
* #param $params
* #return string
*
*/
public function getSignedUrl($params)
{
$signature = $this->generateSignature($params);
return $signedUrl = "http://" . $signature['host'] . $signature['uri'] . '?' . $signature['queryUrl'] . '&Signature=' . $signature['string'];
}
}
and here is where i call it return a response
error 500 We 'encountered an internal error. Please try again.'
$Amazon = new Amazon();
$parameters = array(
"region" => "com",
"AssociateTag" => 'affiliateTag',
'ResponseGroup' => 'Medium',
"Operation" => "ItemLookup",
"SearchIndex" => "Books",
"IdType" => "ISBN",
"ItemId" => $isbn,
);
$queryUrl = $Amazon->getSignedUrl($parameters);
$response = simplexml_load_file($queryUrl);

Invalid Signature while Connecting to Instapaper's Xauth on PHP

I've been trying to get a PHP application to connect to Instapaper's Xauth services, but for the life of me I can't get it to work. I keep getting an "403: Invalid signature." error.
The error says that my signature base string wasn't what it expected, but when I compare the signature base string I construct with what they say they expect, they're exactly the same (sensitive information removed):
My signature base string:
POST&https%3A%2F%2Fwww.instapaper.com%2Fapi%2F1%2Foauth%2Faccess_token&oauth_callback%3DMy_URL%26oauth_consumer_key%3DCONSUMER_KEY%26oauth_nonce%3Dfe379af261aca07d890d2cfaa0f19ce0%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1461898452%26oauth_version%3D1.0%26x_auth_mode%3Dclient_auth%26x_auth_password%3DPASSWORD%26x_auth_username%3DEXAMPLE%2540gmail.com
What the error says it expects:
POST&https%3A%2F%2Fwww.instapaper.com%2Fapi%2F1%2Foauth%2Faccess_token&oauth_callback%3DMy_URL%26oauth_consumer_key%3DCONSUMER_KEY%26oauth_nonce%3Dfe379af261aca07d890d2cfaa0f19ce0%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1461898452%26oauth_version%3D1.0%26x_auth_mode%3Dclient_auth%26x_auth_password%3DPASSWORD%26x_auth_username%3DEXAMPLE%2540gmail.com
I pulled my php library from https://github.com/mheap/Instapaper-XAuth-PHP, but it's old so I've tried to modify it to work with the current Instapaper API. I believe I'm generating the signature string correctly and am following the instructions found here: https://dev.twitter.com/oauth/overview/creating-signatures and here: http://oauthbible.com/
I don't know what's wrong with the code, can someone please help?
class XAuth_Connection
{
private $_headers = array(
"oauth_signature_method" => "HMAC-SHA1",
"oauth_version" => "1.0",
"oauth_callback" => "MY_URL",
"oauth_consumer_key" => "",
"oauth_nonce" => "",
"oauth_timestamp" => ""
);
private $_params = array(
"x_auth_mode" => "client_auth",
"x_auth_username" => "",
"x_auth_password" => ""
);
private $_access_url = '';
public function __construct($key, $private, $access_url)
{
$this->_headers['oauth_consumer_key'] = $key;
$this->_headers['oauth_nonce'] = md5(uniqid(rand(), true));
$this->_headers['oauth_timestamp'] = time();
$this->_oauth_consumer_private = $private;
$this->_access_url = $access_url;
}
public function set_credentials($user, $password)
{
$this->_params['x_auth_username'] = $user;
$this->_params['x_auth_password'] = $password;
}
public function get_params_as_string()
{
ksort($this->_params);
$req = array();
foreach ($this->_params as $k => $v)
{
$req[] = $k ."=". $this->encode($v);
}
return implode("&", $req);
}
public function get_headers_as_string()
{
ksort($this->_headers);
$req = array();
foreach ($this->_headers as $k => $v)
{
$req[] = $k . "=" . $this->encode($v);
}
return implode("&", $req);
}
public function generate_signature()
{
//combine the parameters, encode, and sort them
$temp_params = array_merge($this->_params, $this->_headers);
$encoded_params = Array();
foreach($temp_params as $k => $v){
$encoded_params[$this->encode($k)] = $this->encode($v);
}
ksort($encoded_params);
//Build the param string
$param_base_string = "";
foreach($encoded_params as $k => $v){
$param_base_string .= $k .'='. $v . '&';
}
$param_base_string = rtrim($param_base_string, '&');
//create the signature base
$signature_base = 'POST&' . $this->encode($this->_access_url) .'&'. $this->encode($param_base_string);
$key = $this->encode($this->_oauth_consumer_private) . '&';
return base64_encode(hash_hmac("sha1",$signature_base, $key, true));
}
public function login()
{
$this->_headers['oauth_signature'] = $this->generate_signature();
ksort($this->_headers);
$header_str = 'OAuth ';
foreach ($this->_headers as $k => $v)
{
$header_str .= $k.'="'.$this->encode($v).'", ';
}
$header_str = rtrim($header_str, ', ');
$oauth_str = $this->get_params_as_string();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->_access_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $oauth_str);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: " . $header_str));
$exec = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] != 200)
{
return false;
}
parse_str($exec, $r);
return $r;
}
private function encode($s)
{
return ($s === false ? $s : str_replace('%7E','~',rawurlencode($s)));
}
}

GET & DELETE using file_get_contents() very slow

I use the file_get_contents() from server M to get the response from server X. The result was success but it take too long.
$url = "http://10.20.30.40";
$opts = array('http' =>
array(
'method' => 'GET',
'header' => 'Connection: close\r\n'
)
);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
$result = json_decode($result);
$response = parse_http_response_header($http_response_header);
print_r($result);
print_r($response);
/////// below is just function to parse the response ///////
function parse_http_response_header(array $headers)
{
$responses = array();
$buffer = NULL;
foreach ($headers as $header)
{
if ('HTTP/' === substr($header, 0, 5))
{
// add buffer on top of all responses
if ($buffer) array_unshift($responses, $buffer);
$buffer = array();
list($version, $code, $phrase) = explode(' ', $header, 3) + array('', FALSE, '');
$buffer['status'] = array(
'line' => $header,
'version' => $version,
'code' => (int) $code,
'phrase' => $phrase
);
$fields = &$buffer['fields'];
$fields = array();
continue;
}
list($name, $value) = explode(': ', $header, 2) + array('', '');
// header-names are case insensitive
$name = strtoupper($name);
// values of multiple fields with the same name are normalized into
// a comma separated list (HTTP/1.0+1.1)
if (isset($fields[$name]))
{
$value = $fields[$name].','.$value;
}
$fields[$name] = $value;
}
unset($fields); // remove reference
array_unshift($responses, $buffer);
return $responses;
}
Is there any suggestion or function option to get the response (the content and the response code) faster?
(NOTE: I am not allowed to install cURL, so please gimme other option)

Paypal_IPN doesn't get the result?

I watched a tutorial and did exactly what the guy did. I have the following code for my index.php. The guy in the tutorial recieves a result ( from $result variable ) but i get nothing.
var_dump on $result:
string(0) ""
Where is the problem?
<?php
class Paypal_IPN
{
public function __construct($mode)
{
if ($mode == 'live')
$this->_url = 'https://www.paypal.com/cgi-bin/webscr';
else
$this->_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
}
public function run()
{
$postFields = "cdm=_notify-validate";
foreach ((array)$_POST as $key => $value)
{
$postFields .= "&$key=".urlencode($value);
}
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $this->_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postFields
));
$result = curl_exec($ch);
curl_close($ch);
$fh = fopen('result.txt', 'w');
fwrite($fh, $result . " -- \n" . $postFields);
fclose($fh);
var_dump( $result );
}
}
$paypal = new Paypal_IPN('sandbox');
$paypal->run();
I should have recieved INVALID or VALID as result...
You have a typo in the string
$postFields = "cdm=_notify-validate";
Should be
$postFields = "cmd=_notify-validate";

Categories