I'm using Google's own example from https://developers.google.com/google-apps/spreadsheets/
They say:
To update the contents of an existing row, first retrieve the row to update, modify it as desired, and then send a PUT request, with the updated row in the message body, to the row's edit URL.
Be sure that the id value in the entry you PUT exactly matches the id of the existing entry. The edit URL is highlighted in the following row entry:
<entry gd:etag='"S0wCTlpIIip7ImA0X0QI"'>
<id>https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId</id>
<updated>2006-11-17T18:23:45.173Z</updated>
<category scheme="http://schemas.google.com/spreadsheets/2006"
term="http://schemas.google.com/spreadsheets/2006#list"/>
<title type="text">Bingley</title>
<content type="text">Hours: 10, Items: 2, IPM: 0.0033</content>
<link rel="self" type="application/atom+xml"
href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId"/>
<link rel="edit" type="application/atom+xml"
href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId/version"/>
<gsx:name>Bingley</gsx:name>
<gsx:hours>20</gsx:hours>
<gsx:items>4</gsx:items>
<gsx:ipm>0.0033</gsx:ipm>
</entry>
I've been attempting to send this info (using my own data, but exact same structure) with the following CURL:
$headers = array(
"Authorization: GoogleLogin auth=" . $google_auth,
"GData-Version: 3.0",
"Content-Type: application/atom+xml",
"If-Match: *",
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://spreadsheets.google.com/feeds/list/$feed/0/private/full/$row_id");
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_VERBOSE, true);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$response = curl_exec($curl);
echo $response;
It seems that the XML is malformed which is odd as it comes right from Google's example and I get the same response when retrieving a list feed from my own spreadsheets. How do I correct and are there any other issues?
When I paste this xml into http://www.freeformatter.com/xml-formatter.html, I receive an error that
Unable to parse any XML input. org.jdom2.input.JDOMParseException: Error on line 1: The prefix "gd" for attribute "gd:etag" associated with an element type "entry" is not bound.
Thanks.
Well, no real responses....but I finally got it working. Hopefully this helps someone else. The idea is you need to use the namespaces which are retrieved with the feed.
So the XML should look like:
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" gd:etag=""S0wCTlpIIip7ImA0X0QI"">
<id>https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId</id>
<updated>2006-11-17T18:23:45.173Z</updated>
<category scheme="http://schemas.google.com/spreadsheets/2006" term="http://schemas.google.com/spreadsheets/2006#list" />
<title type="text">Bingley</title>
<content type="text">Hours: 10, Items: 2, IPM: 0.0033</content>
<link rel="self" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId" />
<link rel="edit" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId/version" />
<gsx:name>Bingley</gsx:name>
<gsx:hours>20</gsx:hours>
<gsx:items>4</gsx:items>
<gsx:ipm>0.0033</gsx:ipm>
</entry>
And the CURL should look like:
$headers = array(
"Authorization: GoogleLogin auth=" . $google_auth, //google_auth retrieved earlier
"GData-Version: 3.0",
"Content-Type: application/atom+xml",
"If-Match: *",
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://spreadsheets.google.com/feeds/list/$feed/0/private/full/$id"); //feed is obtained from spreadsheet url and id can be obtained by retrieving list feed
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_VERBOSE, true);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$response = curl_exec($curl);
echo $response;
If you want to retrieve and update a proper custom XML instead of a generic Atom XML doc, then you can try APISpark PaaS which has a wrapper for GSpreadsheets that can create and host a custom web API.
See tutorial: https://apispark.com/docs/tutorials/google-spreadsheet
This should be help to you
$accessToken = $ACCESS_TOKEN;
$key = $SPREADSHEET_ID;
$sheetId = $SHEET_ID;
$editUrl = "https://spreadsheets.google.com/feeds/cells/$key/$sheetId/private/full/R2C4?access_token=$accessToken";
$entry = '<?xml version="1.0" encoding="UTF-8" ?><entry xmlns="http://www.w3.org/2005/Atom" xmlns:gs="http://schemas.google.com/spreadsheets/2006"><id>https://spreadsheets.google.com/feeds/cells/'.$key.'/'.$sheetId.'/private/full/R2C4</id><link rel="edit" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/cells/'.$key.'/'.$sheetId.'/private/full/R2C4"/><gs:cell row="2" col="4" inputValue="Enter_Value_Here">Enter_Value_Here</gs:cell></entry>';
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $editUrl );
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: application/atom+xml','If-Match: *','Content-length: ' . strlen($entry)));
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $entry );
$content = curl_exec($ch);
if($content === false)
{
echo 'Curl error: ' . curl_error($ch)."<br>";
}
else
{
echo 'Operation completed without any errors <br>';
$information = curl_getinfo($ch);
}
curl_close($ch);
Related
I am newbie with Social Minor I am trying to create a new Feed in Social Miner using "Social-Miner Create Feed API".
Problem:
When I click on "Create Feed" button on my interface I receive following error: " type Invalid 16-bit integer. invalid Input.format.short "
Code:
<?php
error_reporting(o);
$URL = "http://192.168.200.163:8080/ccp-webapp/ccp/feed";
//Create Feed form values
$type = $_POST['type'];
$feed_name = $_POST['feed_name'];
$description = $_POST['description'];
$ur = $_POST['ur'];
$polling_interval = $_POST['polling_interval'];
$minimum_age = $_POST['minimum_age'];
$reply_template = $_POST['reply_template'];
$tags = $_POST['tags'];
//Storing above values in a string
$myFeedString='<?xml version="1.0" encoding="utf-8"?>
<Feed>
<type>$type</type>
<name>$feed_name</name>
<description>$description</description>
<ur>$ur</ur>
<polling_interval>$polling_interval</polling_interval>
<minimum_age>$minimum_age</minimum_age>
<tags>
<tag>$tags</tag>
</tags>
</Feed>
';
//setting the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$URL);
curl_setopt($ch, CURLOPT_USERPWD, "hashmatkhan" . ":" . "Army2life");
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $myFeedString);
if (curl_errno($ch))
{
//moving to display page to display curl errors
echo curl_errno($ch) ;
echo curl_error($ch);
}
else
{
//getting response from server
$response = curl_exec($ch);
print_r($response);
curl_close($ch);
}
?>
Need Help?
When I try to POST this XML document to Blackboard Learn LIS using PHP cURL I get this error. I'm checking the XML with simplexml to ensure it is well formed, so that's not the issue. I have also checked the XML document to ensure there is no BOM data attached. I've opened it in a Hex editor to ensure this.
I'm completely stumped on this one and I don't have access to the Blackboard logs.
PHP:
include("xml/envelope.php");
//sanity check to see if xml is well formed
$sxml = simplexml_load_string($xml);
$xml = $sxml->asXML();
$xml_length = strlen($xml);
$url = $this->lis_outcome_service_url;
$bodyHash = base64_encode(sha1($xml, TRUE)); // build oauth_body_hash
$consumer = new OAuthConsumer($key, $secret);
$request = OAuthRequest::from_consumer_and_token($consumer, '', 'POST', $url, array('oauth_body_hash' => $bodyHash) );
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, '');
$header = $request->to_header() . "Content-Type: application/xml\r\nContent-Length: $xml_length\r\n"; // add content type header
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
//curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
//curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
//curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$output .= "$url<br><br>$output<pre>$header\n\n".htmlspecialchars($xml)."</pre><p>ERRORS?: ".curl_error($ch);
curl_close($ch);// "<p>Saved grade: "+var_export($output)+"</p>";
return $output;
The XML in envelope.php:
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<imsx_POXEnvelopeRequest xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
<imsx_POXHeader>
<imsx_POXRequestHeaderInfo>
<imsx_version>V1.0</imsx_version>
<imsx_messageIdentifier>$id</imsx_messageIdentifier>
</imsx_POXRequestHeaderInfo>
</imsx_POXHeader>
<imsx_POXBody>
<replaceResultRequest>
<resultRecord>
<sourcedGUID>
<sourcedId>$this->lis_result_sourcedid</sourcedId>
</sourcedGUID>
<result>
<resultScore>
<language>en-us</language>
<textString>0.7</textString>
</resultScore>
</result>
</resultRecord>
</replaceResultRequest>
</imsx_POXBody>
</imsx_POXEnvelopeRequest>
XML;
?>
The XML output in browser after parsing (during cURL request):
<?xml version="1.0" encoding="UTF-8"?>
<imsx_POXEnvelopeRequest xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
<imsx_POXHeader>
<imsx_POXRequestHeaderInfo>
<imsx_version>V1.0</imsx_version>
<imsx_messageIdentifier>53e4657ec1499</imsx_messageIdentifier>
</imsx_POXRequestHeaderInfo>
</imsx_POXHeader>
<imsx_POXBody>
<replaceResultRequest>
<resultRecord>
<sourcedGUID>
<sourcedId>bbgc15659375gi290156</sourcedId>
</sourcedGUID>
<result>
<resultScore>
<language>en-us</language>
<textString>0.7</textString>
</resultScore>
</result>
</resultRecord>
</replaceResultRequest>
</imsx_POXBody>
</imsx_POXEnvelopeRequest>
Since there is so little detailed information on how to do this in LTI, I've posted my solution below. This is a duplicate of my addition to Blackboard's EduGarage forums, but to get it into the public domain I've put it here. I hope it helps other people trying to implement LTI tools.
Here is how to pass back a grade using PHP cURL, the contents of the envelope.php file shouldfollow the XML found in the IMS Global Documentation found here. The cURL request constructs the header and then adds the XML body below it.
Note that the envelope.php file contains the $xml variable in the following format (you will obviously need to add your own $id and set a grade with a variable etc...):
PHP code for passing grade using cURL:
include("xml/envelope.php");
$xml_length = strlen($xml);
$url = $this->lis_outcome_service_url;
$bodyHash = base64_encode(sha1($xml, TRUE)); // build oauth_body_hash
$consumer = new OAuthConsumer($key, $secret);
$request = OAuthRequest::from_consumer_and_token($consumer, '', 'POST', $url, array('oauth_body_hash' => $bodyHash) );
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, '');
$header .= $request->to_header(); // add content type header
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("POST http://your-tools-url-here.edu.au HTTP/1.0",
"Content-Length: $xml_length", $header, "Content-Type: application/xml"));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
I am getting a Premature end of file response to my XML request for following code.
Cant figure out where is the error.
$xml = '<?xml version="1.0" ?>';
$xml .= '<PickUpCityListRQ>';
$xml .= '<Credentials username="'.$api->username.'" password="'.$api->password.'" remoteIp="'.$api->remoteIp.'" />';
$xml .= '<Country>UK</Country>';
$xml .= '</PickUpCityListRQ>';
$url = 'https://secure.rentalcars.com/service/ServiceRequest.do?serverName=www.rentalcars.com&xml='.utf8_decode(trim($xml));
$port = 443;
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
curl_setopt($ch, CURLOPT_FAILONERROR, true); // Fail on errors
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off'))
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);// allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return into a variable
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_PORT, $port); //Set the port number
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // times out after 15s
//curl_setopt($ch, CURLOPT_POST, true);
//curl_setopt($ch, CURLOPT_POSTFIELDS, '&xml='.$xml); // add POST fields
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
if ($port==443) {
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/xml; charset=UTF-8', 'Accept: application/xml; charset=UTF-8'));
$data = curl_exec($ch);
curl_close($ch);
Have tried sending data in post fields as well but did not work.
Response:
<!DOCTYPE DefaultRS SYSTEM 'https://xml.rentalcars.com:443//tj.dtd'><DefaultRS>
<Error id="2">
<Message>Premature end of file.</Message>
</Error>
</DefaultRS>
Any help appreciated.
Thanks
You need to url encode the xml data before you can use it as a query parameter. So the url assignment becomes:
$url = 'https://secure.rentalcars.com/service/ServiceRequest.do?
serverName=www.rentalcars.com&xml='.urlencode(utf8_decode(trim($xml)));
Note, I've just wrapped that for readability - that should obviously be on one line.
After trying a lot of variation I finally managed to make it work.
There were two things that were casuing problem.
utf8_decode should be utf8_encode
POSTFIELDS data is supposed to be an array
otherwise parser will throw Premature end of file or not send back anything.
I am Working send message using youtuba api. But i got a Error on my file. it shows Invalid Token 401 Error. My file is given below.I'm pretty sure I must be missing something vital but small enough to not notice it.
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = array('accountType' => 'GOOGLE',
'Email' => 'User Email',
'Passwd' => 'pass',
'source'=>'PHI-cUrl-Example',
'service'=>'lh2');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$kk = curl_getinfo($ch);
$response = curl_exec($ch);
list($auth, $youtubeuser) = explode("\n", $response);
list($authlabel, $authvalue) = array_map("trim", explode("=", $auth));
list($youtubeuserlabel, $youtubeuservalue) = array_map("trim", explode("=", $youtubeuser));
$developer_key = 'AI39si7SavL5-RUoR0kvGjd0h4mx9kH3ii6f39hcAFs3O1Gf15E_3YbGh-vTnL6mLFKmSmNJXOWcNxauP-0Zw41obCDrcGoZVw';
$token = '7zWKm-LZWm4'; //The user's authentication token
$url = "http://gdata.youtube.com/feeds/api/users/worshipuk/inbox" ; //The URL I need to send the POST request to
$title = $_REQUEST['title']; //The title of the caption track
$lang = $_REQUEST['lang']; //The languageof the caption track
$transcript = $_REQUEST['transcript']; //The caption file data
$headers = array(
'Host: gdata.youtube.com',
'Content-Type: application/atom+xml',
'Content-Language: ' . $lang,
'Slug: ' . rawurlencode($title),
'Authorization: GoogleLogin auth='.$authvalue,
'GData-Version: 2',
'X-GData-Key: key=' . $developer_key
);
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:yt="http://gdata.youtube.com/schemas/2007">
<id>Qm6znjThL2Y</id>
<summary>sending a message from the api</summary>
</entry>';
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_HEADER, TRUE );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode($xml) );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1 );
$tt = curl_getinfo($ch);
print_r($tt);
$result = curl_exec($ch);
print_r($result);
exit;
// close cURL resource, and free up system resources
curl_close($ch);
?>
any problem in my code? Please guide me. How can I get a result from this code?
Most likely your authentication is wrong, please debug that part first. Either you are not using right scope or that API is not enabled from your console.
On a separate note, I strongly suggest to use Youtube Data API v3 for this. We have updated PHP client library and great samples to get you started.
I want to add a contact with data to google contacts.i am getting error as "There was an error in your request. That's all we know."
The code is as follows
<?php
$contact_detail='<?xml version="1.0"?>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005">
<gd:name>
<gd:firstName>John</gd:firstName>
<gd:additionalName> test</gd:additionalName>
<gd:givenName>Doe</gd:givenName>
</gd:name>
<gd:email address="john#doe.com" rel="http://schemas.google.com/g/2005#work"/>
<gd:email address="john2#doe.com" rel="http://schemas.google.com/g/2005#home"/>
<gd:organization rel="http://schemas.google.com/g/2005#work">
<gd:orgName>John Deere</gd:orgName>
<gd:orgTitle>Owner</gd:orgTitle>
</gd:organization>
</atom:entry>';
$url="https://www.google.com/m8/feeds/contacts/default/full";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_MUTE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_POSTFIELDS, "$contact_detail");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
print($output);
curl_close($ch);
https://developers.google.com/google-apps/contacts/v2/developers_guide_protocol
To publish this entry, send it to the contact-list post URL as follows. First, place your Atom element in the body of a new POST request, using the application/atom+xml content type. Then send it to the post URL. For example, to add a contact to the contact list belonging to liz#gmail.com, post the new entry to the following URL: https://www.google.com/m8/feeds/contacts/liz%40gmail.com/full