" . "\n";
$result .= "" . "\n";
$result .= "" . "\n";
$result .= "" . $_POST['recipe_title'] . "" .
"\n";
$result .= "" . $_POST['cuisine'] . "" . "\n";
$result .= "Recipes" . "\n";
$result .= "" . $_POST['time_val'] .
" " . $_POST['time_units'] . "" . "\n";
$result .= "" . $_POST['main_ingredient'] .
"" . "\n";
$result .= "" . $_POST['serves'] .
"" . "\n";
$result .= "" . $_POST['recipe_text'] . "" . "\n";
$result .= "" . "\n";
return $result;
}
/**
* Creates the XML content used to perform a batch delete.
*/
function buildBatchXML() {
$counter = 0;
$result = '' . "\n";
$result .= ' $value) {
if(substr($key, 0, 5) == "link_") {
$counter++;
$result .= '' . "\n";
$result .= '' . $value . '' . "\n";
$result .= '' . "\n";
$result .= '' . $counter . '' . "\n";
$result .= '' . "\n";
}
}
$result .= '' . "\n";
return $result;
}
/**
* Exchanges the given single-use token for a session
* token using AuthSubSessionToken, and returns the result.
*/
function exchangeToken($token) {
$ch = curl_init(); /* Create a CURL handle. */
curl_setopt($ch, CURLOPT_URL,
"https://www.google.com/accounts/AuthSubSessionToken");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: AuthSub token="' . $token . '"'
));
$result = curl_exec($ch); /* Execute the HTTP command. */
curl_close($ch);
$splitStr = split("=", $result);
return trim($splitStr[1]);
}
/**
* Performs a query for all of the user's items using the
* items feed, then parses the resulting XML with the
* startElement, endElement and characterData functions
* (below).
*/
function getItems($token) {
$ch = curl_init(); /* Create a CURL handle. */
global $developerKey, $itemsFeedURL;
curl_setopt($ch, CURLOPT_URL, $itemsFeedURL . "?");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/atom+xml',
'Authorization: AuthSub token="' . trim($token) . '"',
'X-Google-Key: key=' . $developerKey
));
$result = curl_exec($ch); /* Execute the HTTP command. */
curl_close($ch);
/* Parse the resulting XML. */
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
xml_parse($xml_parser, $result);
xml_parser_free($xml_parser);
}
/**
* Inserts a new recipe by performing an HTTP POST to the
* items feed.
*/
function postItem() {
$ch = curl_init(); /* Create a CURL handle. */
global $developerKey, $itemsFeedURL;
/* Set cURL options. */
curl_setopt($ch, CURLOPT_URL, $itemsFeedURL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: AuthSub token="' . $_POST['token'] . '"',
'X-Google-Key: key=' . $developerKey,
'Content-Type: application/atom+xml'
));
curl_setopt($ch, CURLOPT_POSTFIELDS, buildInsertXML());
$result = curl_exec($ch); /* Execute the HTTP request. */
curl_close($ch); /* Close the cURL handle. */
return $result;
}
/**
* Updates an existing recipe by performing an HTTP PUT
* on its feed URI, using the updated values a PUT data.
*/
function updateItem() {
$ch = curl_init(); /* Create a CURL handle. */
global $developerKey;
/* Prepare the data for HTTP PUT. */
$putString = buildInsertXML();
$putData = tmpfile();
fwrite($putData, $putString);
fseek($putData, 0);
/* Set cURL options. */
curl_setopt($ch, CURLOPT_URL, $_POST['link']);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $putData);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($putString));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: AuthSub token="' . $_POST['token'] . '"',
'X-Google-Key: key=' . $developerKey,
'Content-Type: application/atom+xml'
));
$result = curl_exec($ch); /* Execute the HTTP request. */
fclose($putData); /* Close and delete the temp file. */
curl_close($ch); /* Close the cURL handle. */
return $result;
}
/**
* Deletes a recipe by performing an HTTP DELETE (a custom
* cURL request) on its feed URI.
*/
function deleteItem() {
$ch = curl_init();
global $developerKey;
/* Set cURL options. */
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_URL, $_POST['link']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: AuthSub token="' . $_POST['token'] . '"',
'X-Google-Key: key=' . $developerKey
));
$result = curl_exec($ch); /* Execute the HTTP request. */
curl_close($ch); /* Close the cURL handle. */
return $result;
}
/**
* Deletes all recipes by performing an HTTP POST to the
* batch URI.
*/
function batchDelete() {
$ch = curl_init(); /* Create a CURL handle. */
global $developerKey, $itemsFeedURL;
/* Set cURL options. */
curl_setopt($ch, CURLOPT_URL, $itemsFeedURL . "/batch");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: AuthSub token="' . $_POST['token'] . '"',
'X-Google-Key: key=' . $developerKey,
'Content-Type: application/atom+xml'
));
curl_setopt($ch, CURLOPT_POSTFIELDS, buildBatchXML());
$result = curl_exec($ch); /* Execute the HTTP request. */
curl_close($ch); /* Close the cURL handle. */
return $result;
}
/**
* Callback function for XML start tags parsed by
* xml_parse.
*/
function startElement($parser, $name, $attrs) {
global $curElement, $foundEntry, $parsedEntries;
$curElement = $name;
if($curElement == "ENTRY") {
$foundEntry = true;
$parsedEntries[count($parsedEntries)] = array();
} else if($foundEntry && $curElement == "LINK") {
$parsedEntries[count($parsedEntries) - 1][$attrs["REL"]] = $attrs["HREF"];
}
}
/**
* Callback function for XML end tags parsed by
* xml_parse.
*/
function endElement($parser, $name) {
global $curElement, $foundEntry, $parsedEntries;
if($name == "ENTRY") {
$foundEntry = false;
}
}
/**
* Callback function for XML character data parsed by
* xml_parse.
*/
function characterData($parser, $data) {
global $curElement, $foundEntry, $parsedEntries;
if($foundEntry) {
$parsedEntries[count($parsedEntries) - 1][strtolower($curElement)] = $data;
}
}
/**
* We arrive here when the user first comes to the form. The first step is
* to have them get a single-use token.
*/
function showIntroPage() {
global $itemsFeedURL;
$next_url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$redirect_url = 'https://www.google.com/accounts/AuthSubRequest?session=1';
$redirect_url .= '&next=';
$redirect_url .= urlencode($next_url);
$redirect_url .= "&scope=";
$redirect_url .= urlencode($itemsFeedURL);
print '' . "\n";
print '
PHP 4 Demo: Google Base data API' . "\n";
print '' . "\n";
print '' . "\n";
print '
' . "\n";
print '
' . "\n";
print '
' . "\n";
print '
PHP 4 Demo: Google Base data API
' . "\n";
print '
' . "\n";
print '
Before you get started, please sign in to your personal Google Base account.
' . "\n";
print '
' . "\n";
print '
' . "\n";
}
/**
* Prints the table of recipes the user has already entered
* on the left-hand side of the page.
*/
function showRecipeListPane($token) {
global $parsedEntries;
print '
' . "\n";
/* Create an Edit button for each existing recipe. */
print '
' . "\n";
print '' . "\n";
print '
' . "\n";
/* Create a Delete button for each existing recipe. */
print '
' . "\n";
print '' . "\n";
print '
' . "\n";
print '
' . "\n";
}
}
/* Create a "Delete all" button" to demonstrate batch requests. */
print '
' . "\n";
print '
' . "\n";
print '
' . "\n";
print '
' . "\n";
}
/**
* Prints a small form allowing the user to insert a new
* recipe.
*/
function showRecipeInsertPane($token) {
global $cuisines;
print '
' . "\n";
print '
' . "\n";
print '
Insert a new recipe
' . "\n";
print '
' . "\n";
print '
' . "\n";
}
/**
* Shows a menu allowing the user to update an existing
* recipe with the Base API update feature.
*/
function showEditMenu() {
global $cuisines;
$splitCookingTime = split(" ", $_POST['g:cooking_time']);
print '' . "\n";
print 'PHP 4 Demo: Google Base data API' . "\n";
print '' . "\n";
print '' . "\n";
print '
' . "\n";
print '
' . "\n";
print '
Edit recipe:
' . "\n";
print '
' . "\n";
print '' . "\n";
}
/**
* Displays both the "List of current recipes" and
* "Insert a new recipe" panels in a single table.
*/
function showMainMenu($tableTitle, $sessionToken) {
print '' . "\n";
print 'PHP 4 Demo: Google Base data API' . "\n";
print '' . "\n";
print '' . "\n";
print '
' . "\n";
print '
' . "\n";
print '
' . "\n";
print '
PHP 4 Demo: Google Base data API' . "\n";
print '
' . "\n";
print '
' . $tableTitle .
'
' . "\n";
print '
' . "\n";
// Create the two sub-tables.
showRecipeListPane($sessionToken);
showRecipeInsertPane($sessionToken);
// Add a "Sign out" link.
print '
Or click here to' .
' sign out' .
' of your Google account.
' . "\n";
// Close the master table.
print '
' . "\n";
print '
' . "\n";
}
/**
* We arrive here after the user first authenticates and we get back
* a single-use token.
*/
function showFirstAuthScreen() {
$singleUseToken = $_GET['token'];
$sessionToken = exchangeToken($singleUseToken);
if(!$sessionToken) {
showIntroPage();
} else {
$tableTitle =
'Here\'s your single use token:' . $singleUseToken .
'' . "\n" . ' And here\'s the session token:' .
$sessionToken . '';
showMainMenu($tableTitle, $sessionToken);
}
}
/**
* Main logic. Take action based on the GET and POST
* parameters, which reflect whether the user has
* authenticated and which action they want to perform.
*/
if(count($_GET) == 1 && array_key_exists('token', $_GET)) {
showFirstAuthScreen();
} else {
if(count($_POST) == 0) {
showIntroPage();
} else {
if($_POST['action'] == 'insert') {
if(postItem()) {
showMainMenu('Recipe inserted!', $_POST['token']);
} else {
showMainMenu('Recipe insertion failed.', $_POST['token']);
}
} else if($_POST['action'] == 'delete') {
if(deleteItem()) {
showMainMenu('Recipe deleted.', $_POST['token']);
} else {
showMainMenu('Recipe deletion failed.', $_POST['token']);
}
} else if($_POST['action'] == 'delete_all') {
if(batchDelete()) {
showMainMenu('All recipes deleted.', $_POST['token']);
} else {
showMainMenu('Batch deletion failed.', $_POST['token']);
}
} else if($_POST['action'] == 'edit') {
showEditMenu();
} else if($_POST['action'] == 'update') {
if(updateItem()) {
showMainMenu('Recipe successfully updated.', $_POST['token']);
} else {
showMainMenu('Recipe update failed.', $_POST['token']);
}
} else {
showIntroPage();
}
}
}
?>