I am working on the Amazon API. I want to submit the product feed on amazon account.
I have validated the XML file (product feed) by the Amazon Scratch Pad and i get the Response that Feed is submitted but when i run the script, to submit the same feed by script, i don't get any response.
Here is my code :
$req = new MarketplaceWebService_Model_SubmitFeedRequest();
$req->setMerchant(MERCHANTID);
$req->setMarketplaceIdList(MARKETPLACEID);
$req->setFeedType('_POST_PRODUCT_DATA_');
$req->setContentMd5(base64_encode(md5(stream_get_contents($fh), true)));
rewind($fh);
$req->setPurgeAndReplace(true);
$req->setFeedContent($fh);
$res = $mws->submitFeed($request);
echo $res;
I am unable to get the response, when i echo the $res.
I have changed the $res = $mws->submitFeed($request); to $res = $mws->submitFeed($req);. Still no success in submitting the feed. I am not getting any response header that Amazon return while submitting the feed.
The code is like this :
$req = new MarketplaceWebService_Model_SubmitFeedRequest();
$fh = fopen('feed.xml', 'r');
$req->setMerchant(MERCHANTID);
$req->setMarketplaceIdList(MARKETPLACEID);
$req->setFeedType('_POST_PRODUCT_DATA_');
$req->setContentMd5(base64_encode(md5(stream_get_contents($fh), true)));
rewind($fh);
$req->setPurgeAndReplace(true);
$req->setFeedContent($fh);
$res = $mws->submitFeed($req);
echo $res;
Apart from other things that might go wrong: You are submitting $request, while the thing you probably want to submit is $req.
Edit: Since you corrected this mistake but still have no result...:
submitFeed() returns a MarketplaceWebService_Model_SubmitFeedResponse object.
Echo does not work with objects, unless the object has a __toString() method, which this class doesn't. Try using print_r($res) or var_dump($res) instead.
Try this
$marketplaceIdArray = array("Id" => array($MARKETPLACE_ID));
$feedHandle = #fopen('php://temp', 'rw+');
fwrite($feedHandle, $feed);
rewind($feedHandle);
$parameters = array(
'Merchant' => $MERCHANT_ID,
'MarketplaceIdList' => $marketplaceIdArray,
'FeedType' => '_POST_PRODUCT_DATA_',
'FeedContent' => $feedHandle,
'PurgeAndReplace' => false,
'ContentMd5' => base64_encode(md5(stream_get_contents($feedHandle), true))
);
rewind($feedHandle);
$request = new MarketplaceWebService_Model_SubmitFeedRequest($parameters);
$return_feed = invokeSubmitFeed($service, $request);
fclose($feedHandle);
Related
I need an example of how to modify an existing document with existing text in Google Docs via API. The documentation only shows how to insert and delete text, but not how to update. Have been looking frantically on the web to find examples or a direction on how to do it but without luck.
Finally figured it out myself.
First, follow this video to prepare authentication to the Google Docs API (even though it's about Google Sheets but the process is basically the same). Basically it consists of these steps:
create project in Google Developer Console
enable Google Docs API
create credentials, including a service account for programmatic access
share your document with the service account client email address
install Google API's PHP client: composer require google/apiclient
Then create a script like the following:
require_once(__DIR__ .'/vendor/autoload.php');
$client = new \Google_Client();
$client->setApplicationName('Some name'); //this name doesn't matter
$client->setScopes([\Google_Service_Docs::DOCUMENTS]);
$client->setAccessType('offline');
$client->setAuthConfig(__DIR__ .'/googleapi-credentials.json'); //see https://www.youtube.com/watch?v=iTZyuszEkxI for how to create this file
$service = new \Google_Service_Docs($client);
$documentId = 'YOUR-DOCUMENT-ID-GOES-HERE'; //set your document ID here, eg. "j4i1m57GDYthXKqlGce9WKs4tpiFvzl1FXKmNRsTAAlH"
$doc = $service->documents->get($documentId);
// Collect all pieces of text (see https://developers.google.com/docs/api/concepts/structure to understand the structure)
$allText = [];
foreach ($doc->body->content as $structuralElement) {
if ($structuralElement->paragraph) {
foreach ($structuralElement->paragraph->elements as $paragraphElement) {
if ($paragraphElement->textRun) {
$allText[] = $paragraphElement->textRun->content;
}
}
}
}
// Go through and create search/replace requests
$requests = $textsAlreadyDone = $forEasyCompare = [];
foreach ($allText as $currText) {
if (in_array($currText, $textsAlreadyDone, true)) {
// If two identical pieces of text are found only search-and-replace it once - no reason to do it multiple times
continue;
}
if (preg_match_all("/(.*?)(dogs)(.*?)/", $currText, $matches, PREG_SET_ORDER)) {
//NOTE: for simple static text searching you could of course just use strpos()
// - and then loop on $matches wouldn't be necessary, and str_replace() would be simplified
$modifiedText = $currText;
foreach ($matches as $match) {
$modifiedText = str_replace($match[0], $match[1] .'cats'. $match[3], $modifiedText);
}
$forEasyCompare[] = ['old' => $currText, 'new' => $modifiedText];
$replaceAllTextRequest = [
'replaceAllText' => [
'replaceText' => $modifiedText,
'containsText' => [
'text' => $currText,
'matchCase' => true,
],
],
];
$requests[] = new \Google_Service_Docs_Request($replaceAllTextRequest);
}
$textsAlreadyDone[] = $currText;
}
// you could dump out $forEasyCompare to see the changes that would be made
$batchUpdateRequest = new \Google_Service_Docs_BatchUpdateDocumentRequest(['requests' => $requests]);
$response = $service->documents->batchUpdate($documentId, $batchUpdateRequest);
This is my way - easy one
public function replaceText($search, $replace)
{
$client = $this->getClient();
$service = new \Google_Service_Docs($client);
$documentId = ''; // Put your document ID here
$e = new \Google_Service_Docs_SubstringMatchCriteria();
$e->text = "{{".$search."}}";
$e->setMatchCase(false);
$requests[] = new \Google_Service_Docs_Request(array(
'replaceAllText' => array(
'replaceText' => $replace,
'containsText' => $e
),
));
$batchUpdateRequest = new \Google_Service_Docs_BatchUpdateDocumentRequest(array(
'requests' => $requests
));
$response = $service->documents->batchUpdate($documentId, $batchUpdateRequest);
}
I have a SPA (react) that is uses PHP calls to connect to a MongoDB.
Works great.
However, due to 'rules' I need to serve the javascript files from a different server -- a server that supports neither MongoDB nor MongoDB php client. Let's call this server, SERVER_A.
Let's call the server hosting the MongoDB PHP client and the MongoDB, SERVER_B. ('B' for 'backend'... :) )
The solution, I believe, was to build a php 'middleman' on SERVER_A that simply passes data on to SERVER_B. Research shows me that file_get_contents is the tool for this.
So I take my original known-working PHP file, I put it on SERVER_B and rename it to "mongoPatch_backend.php".
<?php
$user = "xxxx";
$pwd = 'xxx';
$filter = [];
if (isset($_REQUEST['needleKey'])) {
$needleKey = $_REQUEST['needleKey'];
$needle = $_REQUEST['needle'];
$filter = [$needleKey => $needle];
}
$newData = $_REQUEST['newData'];
$filter = ['x' => ['$gt' => 1]];
$options = [
'projection' => ['_id' => 0],
'sort' => ['x' => -1],
];
$bson = MongoDB\BSON\fromJSON($newData);
$value = MongoDB\BSON\toPHP($bson);
$manager = new MongoDB\Driver\Manager("mongodb://${user}:${pwd}#SERVER_B:27017");
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->update(
[$needleKey => $needle],
['$set' => $value],
['multi' => false, 'upsert' => true]
);
$results = $manager->executeBulkWrite('sedwe.users', $bulk);
var_dump($results);
?>
On SERVER_A I then make a new file, dbPatch.php, like so:
<?php
$API = "https://SERVER_B/php/mongoPatch_backend.php?";
if (isset($_REQUEST['needleKey'])) {
$needleKey = $_REQUEST['needleKey'];
$needle = $_REQUEST['needle'];
$filter = [$needleKey => $needle];
}
$newData = $_REQUEST['newData'];
$postData = "needleKey=".urlencode($needleKey);
$postData .= "&needle=".urlencode($needle);
$postData .= "&newData=".urlencode($newData);
// echo $API.$postData;
$data = file_get_contents($API.$postData);
echo $data;
?>
But when I call it, I get nothing echo'd back out of $data.
Any idea why? Remember, the exact same call directly to mongoPatch_backend.php works just fine (but it's a CORS call, so it's not a valid option).
So here is what I've tried:
First, to ensure my AJAX call was still working, I spit out the response to the console. I get nothing.
So I changed the last line of the middleman (dbPatch.php) to echo "Hello World" instead of echo $data and received "Hello World" on the console as expected.
Next, I then changed the last line of my middleman (dbPatch.php) back to echo $data and tried reducing the 'backend' to a simple <?php echo "Hello Back World"; ?> and got nothing on the console.
Next, I go to https://SERVER_B/php/mongoPatch_backend.php in a browser ... and I'm greeted with "Hello Back World" as expected in the browser.
... which leads me to believe something is up with the transferring of info from server to server. Logical call, eh?
Unfortunately, when I try the same thing with just a 'fetch' command, it works perfectly fine:
Here is my 'middleman' (dbFetch.php) script on SERVER_A:
<?php
$API = "https://SERVER_B/php/mongoFetch_backend.php?";
$collection = $_REQUEST['collection'];
$postData = "collection=".urlencode($collection);
$needleID = $_REQUEST['needleID'];
$postData .= "&needleID=".urlencode($needleID);
$data = file_get_contents($API.$postData);
echo $data;
?>
And this is the file on the backend, SERVER_B:
<?php
$user = "xxxx";
$pwd = 'xxxx';
$filter = [];
if (isset($_REQUEST['needleID'])) {
$needleID = $_REQUEST['needleID'];
$filter = ['id'=> $needleID];
}
if (isset($_REQUEST['collection'])) {
$collection = $_REQUEST['collection'];
}
//Manager Class
$connection = new MongoDB\Driver\Manager("mongodb://${user}:${pwd}#SERVER_B:27017");
// Query Class
$query = new MongoDB\Driver\Query($filter);
$rows = $connection->executeQuery("db_name.$collection", $query);
// Convert rows to Array and send result back to client
$rowsArr = $rows->toArray();
echo json_encode($rowsArr);
?>
Huzzah, this works! ... and it's also proof there doesn't appear to be a problem with the server-to-server communication.
So back to ground zero.
I then go with a very simple newData value -- shorter, but same general layout - stringified json. It works! The data ends up in the database.
So I'm forced to think something is wrong with the data in newData (which is only a few hundred lines of stringified JSON made like this: encodeURIComponent(JSON.stringify(newData)). But, this bears repeating: this works if I skip the middleman.
... and that puts me at a loss. PHP isn't something I understand well... can you help?
EDIT to answer comment:
When I call mongoPatch_backend.php directly on SERVER_B it works (as stated above). I had it echo the $newData and it spits out a stringified JSON version of the variable (not URLencoded).
When I call dbPatch.php, it does not give me anything that was passed back from mongoPatch_backend.
As I said in the OP, if I modify mongoPatch_backend.php to do nothing other than echo "hellow world" I am still unable to log it to console when calling it via the above dbPatch.php file.
EDIT: I also tried putting the two PHP files on the same server and am getting the same results. (ie: both the dbPatch.php and mongoPatch.php files are in the same directory on the same server)
EDIT2: I have done a var_dump from the middleman and I get standard-looking human-readable stringified text back.
I do the same var_dump($_REQUEST['newData']); in the backend file and I get nothing back.
I have a sample JSON Array labeled sample.txt that is sent from a sweepstakes form that captures a user's name and e-mail. I'm using WooBox so the JSON Array sends information over by each entry, so there are two entries here: http://pastebin.ca/3409546
On a previous question, I was told to break the ][ so that JSON_ENCODE can figure the separate entries. I would like to capture just the name and e-mail and import the array to my e-mail database (campaign monitor).
My question is: How do I add JSON variable labels to an array? If you see my code, I have tried to use the label $email. Is this the correct form or should it be email[0] with a for loop?
$url = 'http://www.mywebsite.com/sweeps/test.txt';
$content = file_get_contents($url);
$json = json_decode($content,true);
$tmp = explode('][', $json_string);
if (!count($tmp)) {
$json = json_decode($json_string);
var_dump($json);
} else {
foreach ($tmp as $json_part) {
$json = json_decode('['.rtrim(ltrim($json_string, '['), ']').']');
var_dump($json);
}
}
require_once 'csrest_general.php';
require_once 'csrest_subscribers.php';
$auth = array(
'api_key' => 'xxxxxxxxxxxxxxx');
$wrap = new CS_REST_Subscribers('xxxxxxxxxx', $auth);
$result = $wrap->add($json(
'EmailAddress' => $email,
'Name' => $custom_3_first,
'Resubscribe' => false
));
https://github.com/campaignmonitor/createsend-php/blob/master/samples/subscriber/add.php
This should have been fairly easy: if you have a JSON string and you call json_decode($string, true) on it, you get its equivalent in a PHP variable, plain and simple. From there, you can access it like you would any PHP array, object, etc.
The problem is, you don't have a proper JSON string. You have a string that looks like JSON, but isn't valid JSON. Run it through a linter and you'll see what I mean.
PHP doesn't know what to do with your supposed JSON, so you have to resort to manual parsing, which is not a path I would recommend. Still, you were almost there.
require_once 'csrest_general.php';
require_once 'csrest_subscribers.php';
$auth = array('api_key' => 'xxxxxxxxxxxxxxx');
$wrap = new CS_REST_Subscribers('xxxxxxxxxx', $auth);
$url = 'http://www.mywebsite.com/sweeps/test.txt';
$content = file_get_contents($url);
$tmp = explode('][', $content);
foreach ($tmp as $json_part) {
$user = json_decode('['.rtrim(ltrim($json_string, '['), ']').']', true);
$result = $wrap->add(array(
'EmailAddress' => $user->email,
'Name' => $user->fullname,
'Resubscribe' => true
));
}
I'm trying to parse the xml response from a soap service. However, I can't get simplexml_load_string to work! Here is my code:
//make soap call
objClient = new SoapClient('my-wsdl',
array('trace' => true,'exceptions' => 0, 'encoding' => 'UTF-8'));
$soapvar = new SoapVar('my-xml', XSD_ANYXML);
$objResponse = $objClient->__soapCall($operation, array($soapvar));
//process result
$str_xml = $objClient->__getLastResponse();
$rs_xml = simplexml_load_string($str_xml);
...$rs_xml always has just one element with name Envelope.
However, if I use *"print var_export($objClient->__getLastResponse(),true);"* to dump the result to my browser, then cut and paste it into my code as a string variable, it work fine! This is what I mean:
$str_xml = 'my cut and pasted xml';
$rs_xml = simplexml_load_string($str_xml);
So it seems the problem is somehow related to something $objClient->__getLastResponse() is doing to the string it creates... but I'm at a loss as to what the problem is or how to fix it.
Do the following:
$str_xml = $objClient->__getLastResponse();
$str_xml = strstr($str_xml, '<');
$rs_xml = simplexml_load_string($str_xml);
As it's a quick and easy hack to strip off stuff before the first opening element.
I am trying to download a rapidshare file using its "download" subroutine as a free user. The following is the code that I use to get response from the subroutine.
function rs_download($params)
{
$url = "http://api.rapidshare.com/cgi-bin/rsapi.cgi?sub=download&fileid=".$params['fileid']."&filename=".$params['filename'];
$reply = #file_get_contents($url);
if(!$reply)
{
return false;
}
$result_arr = array();
$result_keys = array(0=> 'hostname', 1=>'dlauth', 2=>'countdown_time', 3=>'md5hex');
if( preg_match("/DL:(.*)/", $reply, $reply_matches) )
{
$reply_altered = $reply_matches[1];
}
else
{
return false;
}
foreach( explode(',', $reply_altered) as $index => $value )
{
$result_arr[ $result_keys[$index] ] = $value;
}
return $result_arr;
}
For instance; trying to download this...
http://rapidshare.com/files/440817141/AutoRun__live-down.com_Champ.rar
I pass the fileid(440817141) and filename(AutoRun__live-down.com_Champ.rar) to rs_download(...) and I get a response just as rapidshare's api doc says.
The rapidshare api doc (see "sub=download") says call the server hostname with the download authentication string but I couldn't figure out what form the url should take.
Any suggestions?, I tried
$download_url = "http://$the-hostname/$the-dlauth-string/files/$fileid/$filename"
and a couple other variations of the above, nothing worked.
I use curl to download the file, like the following;
$cr = curl_init();
$fp = fopen ("d:/downloaded_files/file1.rar", "w");
// set curl options
$curl_options = array(
CURLOPT_URL => $download_url
,CURLOPT_FILE => $fp
,CURLOPT_HEADER => false
,CURLOPT_CONNECTTIMEOUT => 0
,CURLOPT_FOLLOWLOCATION => true
);
curl_setopt_array($cr, $curl_options);
curl_exec($cr);
curl_close($cr);
fclose($fp);
The above curl code doesn't seem to work, nothing gets downloaded. Probably its the download url that is incorrect.
Also tried this format for the download url:
"http://rs$serverid$shorthost.rapidshare.com/files/$fileid/$filename"
With this curl writes a file entry but that is all it does(writes a 0/1 kb file).
Here is the code that I use to get the serverid, shorthost, among a few other values from rapidshare.
function rs_checkfile($params)
{
$url = "http://api.rapidshare.com/cgi-bin/rsapi.cgi?sub=checkfiles_v1&files=".$params['fileids']."&filenames=".$params['filenames'];
// the response from rapishare would a string something like:
// 440817141,AutoRun__live-down.com_Champ.rar,47768,20,1,l3,0
$reply = #file_get_contents($url);
if(!$reply)
{
return false;
}
$result_arr = array();
$result_keys = array(0=> 'file_id', 1=>'file_name', 2=>'file_size', 3=>'server_id', 4=>'file_status', 5=>'short_host'
, 6=>'md5');
foreach( explode(',', $reply) as $index => $value )
{
$result_arr[ $result_keys[$index] ] = $value;
}
return $result_arr;
}
rs_checkfile(...) takes comma seperated fileids and filenames(no commas if calling for a single file)
Thanks in advance for any suggestions.
You start by requesting ?sub=download&fileid=X&filename=Y, and it returns $hostname,$dlauth,$countdown,$md5hex.. since you're a free user you have to delay for $countdown seconds, and then call ?sub=download&fileid=X&filename=Y&dlauth=Z to perform the download.
There's a working implementation in python here that would probably answer any of your other questions.