Skip to content

Instantly share code, notes, and snippets.

@julian-bond
Created October 23, 2012 11:54
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save julian-bond/3938374 to your computer and use it in GitHub Desktop.
A single file PHP script which serves public posts to a Google Plus account as an Atom feed.
<?php
/**
* gplusatom.php
*
* A single file PHP script which serves public posts to a Google Plus account as an Atom feed.
*
* To use:
* 1) Obtain a google API key here https://code.google.com/apis/console
* 2) Fill in the 3 pieces of setup detail below.
* 3) Serve chilled
*
* Google really ought to provide this themselves in the API.
* If you agree, please go here, like the request and add some comment
* http://code.google.com/p/google-plus-platform/issues/detail?id=139
*
* @author Julian Bond <julian_bond@voidstar.com>
* @version 0.002
* @license 100% FREE TO COPY/USE FOR ANY PURPOSE, BUT DON'T BUG ME ABOUT IT, EVER.
*
* 31 October 2012
*/
$user_plus_id = 'CHANGE_ME'; // The ~21 digit number from your G Plus profile page
$google_api_key = 'CHANGE_ME'; // The ~40 char API key from Google
$user_full_name = 'CHANGE_ME'; // Used in the Feed Description
$max_results = 10;
$api_url = 'https://www.googleapis.com/plus/v1/people/'.$user_plus_id;
$api_url .= '/activities/public?key='.$google_api_key.'&maxResults='.$max_results;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$info = curl_getinfo($ch);
$error = curl_error($ch);
$errno = curl_errno($ch);
curl_close($ch);
if ($code != 200) {
echo 'Error' . PHP_EOL;
echo $code . PHP_EOL;
print_r($response);
print_r($info);
} else {
$all = json_decode($response);
$title = 'Google ' . $all->title;
$updated = date(DATE_ATOM, strtotime($all->updated));
$link = 'https://plus.google.com/' . $user_plus_id . '/posts';
header('Content-type: application/atom+xml; charset=UTF-8', true);
echo '<?xml version="1.0" encoding="utf-8"?' . '>' . PHP_EOL;
echo '<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?>' . PHP_EOL;
echo '<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" ';
echo ' xmlns:georss="http://www.georss.org/georss" >'."\n";
echo '<title>' . $title . '</title>'."\n";
echo '<id>' . $all->id . '</id>'."\n";
echo '<link type="text/html" rel="alternate" href="' . $link . '" />'."\n";
echo '<link type="application/atom+xml" rel="self" href="http://' . $_SERVER[SERVER_NAME].$_SERVER[REQUEST_URI] . '" />'."\n";
echo '<updated>' . $updated . '</updated>'."\n";
echo '<subtitle>Google Plus posts from ' . $user_full_name . '.</subtitle>'."\n";
foreach($all->items as $item) {
$id = $item->id;
$url = $item->url;
$published = date(DATE_ATOM, strtotime($item->published));
$updated = date(DATE_ATOM, strtotime($item->updated));
// Create Content
$post_content = '';
if ($item->verb == 'share' && $item->annotation) {
$post_content .= $item->annotation . "\n";
}
if ($item->verb == 'share') {
$post_content .= '<hr /><div><img src="'.$item->object->actor->image->url.'" style="padding-right:5px;float:left;" /></div>';
$post_content .= '<div><a href="' . $item->object->actor->url . '">' . $item->object->actor->displayName . '</a> originally shared this <a href="' . $item->object->url . '">post</a>:<br />';
}
if ($item->object->content != '') {
$post_content .= $item->object->content;
}
if ($item->verb == 'share') {
$post_content .= '</div><br style="clear:left" />';
}
if ($item->object->attachments) {
foreach ($item->object->attachments as $attachment) {
$post_content .= '<hr />';
if ($attachment->objectType == 'article') {
// get the thumbnail photo from the activity for the share
if ($item->object->attachments[1]->objectType == 'photo') {
$post_content .= '<div><a href="' . $attachment->url . '"><img src="' . $item->object->attachments[1]->image->url . '" style="padding-right:10px;float:left;" /></a></div>';
} else if ($attachment->image) {
$post_content .= '<div><a href="' . $attachment->url . '"><img src="' . $attachment->image->url . '" style="padding-right:10px;float:left;" /></a></div>';
}
$post_content .= '<div>';
//construct favicon for the source website of the share
$host = '';
if ($host = parse_url($attachment->url,PHP_URL_HOST) ) {
$post_content .= '<img src="https://s2.googleusercontent.com/s2/favicons?domain=' . urlencode($host) . '" style="padding-right:5px" />';
}
//Create a title and link to the shared item
$post_content .= '<a href="' . $attachment->url . '">' . $attachment->displayName . ' >></a><br />';
if ($attachment->content) {
$post_content .= $attachment->content. "\n";
}
$post_content .= '</div>';
break;
}
if ($attachment->objectType == 'photo') {
$post_content .= '<a href="' . $attachment->url . '"><img src="' . $attachment->image->url . '" /></a>';
}
if ($attachment->objectType == 'video') {
if ($attachment->embed->url && stristr($attachment->embed->url,'youtube.com') ) {
$post_content .= "\n" . '<iframe width="560" height="315" src="' . $attachment->embed->url . '" frameborder="0" allowfullscreen></iframe>';
} else if ($attachment->url && $attachment->image->url) {
$post_content .= "\n" . '<a href="' . $attachment->url . '"><img src="' . $attachment->image->url . '" /></a>';
} else if ($video_embed = create_video_embed($attachment->url)) {
$post_content .= "\n" . $video_embed;
}
}
}
} //Item Attachments
//Item Location
$georss_content = '';
if ($item->geocode) {
$coordinates = explode(' ',$item->geocode);
$gm_coordinates = implode(',',$coordinates);
$geo_cordinates = implode(' ',$coordinates);
$georss_content = " <georss:point>" . $geo_cordinates . "</georss:point>\n";
$post_content .= "\n".'<br /><a href="http://maps.google.com/?ll=' . $gm_coordinates . '&q=' . $gm_coordinates . '"><img src="http://maps.googleapis.com/maps/api/staticmap?center=' . $gm_coordinates . '&zoom=12&size=75x75&maptype=roadmap&markers=size:small|color:red|' . $gm_coordinates . '&sensor=false"></a>';
}
if ($item->placeName) {
$post_content .= "<br />\n" . $item->placeName;
}
if ($item->address) {
$post_content .= "<br />\n" . '<a href="http://maps.google.com/?ll=' . $gm_coordinates . '&q=' . $gm_coordinates . '">' . $item->address . '</a>';
}
//wrapping the content in CDATA can avoid some XML character set problems.
$post_content = '<![CDATA['.htmlspecialchars($post_content).']]>';
// $post_content = htmlspecialchars($post_content);
// Create title
$post_title = '';
$post_title = $item->title;
// If there's no title get the name of anything attached
if ( $post_title == '' && $item->object->attachments[0]->displayName ) {
$post_title = $item->object->attachments[0]->displayName;
}
// Get only the first line of the title
$post_title = explode("\n", $post_title);
$post_title = $post_title[0];
// Shorten title if it's too long
$max_characters = 255;
if (strlen($post_title)>$max_characters) {
preg_match('/(.{' . $max_characters . '}.*?)\b/', $post_title, $matches);
if ( strlen(rtrim($matches[1])) < strlen($post_title) ) {
$post_title = rtrim($matches[1]) . "...";
}
}
$post_title = htmlspecialchars($post_title);
$authorName = $item->actor->displayName;
$authorUrl = $item->actor->url;
$authorImageUrl = $item->actor->image->url;
//Output the item entry
echo '<entry>'."\n";
echo ' <title>' . $post_title . '</title>'."\n";
echo ' <content type="html">' . $post_content . ' </content>'."\n";
echo ' <id>' . $id . '</id>'."\n";
echo ' <published>' . $published . '</published>'."\n";
echo ' <updated>' . $updated . '</updated>'."\n";
echo ' <link type="text/html" rel="alternate" href="' . $url . '"/>'."\n";
echo ' <link type="image/png" rel="image" href="' . $authorImageUrl . '"/>'."\n";
echo ' <author>'."\n";
echo ' <name>' . $authorName . '</name>'."\n";
echo ' <uri>' . $authorUrl . '</uri>'."\n";
echo ' </author>'."\n";
echo $georss_content;
echo '</entry>'."\n";
}
echo '</feed>."\n"';
}
// *******************
function create_video_embed($swf_url) {
preg_match('#http://www\.youtube\.com/watch\?v=([A-Za-z0-9\-_]+)#s', $swf_url, $matches);
if (isset($matches[1])) {
$content .= '<iframe width="560" height="315" src="http://www.youtube.com/embed/'.$matches[1].'" frameborder="0" allowfullscreen></iframe>';
return $content;
} else {
preg_match('#http://w?w?w?.?vimeo.com/moogaloop.swf\?clip_id=([A-Za-z0-9\-_]+)&#s', $swf_url, $matches);
if (isset($matches[1])) {
return "http://www.vimeo.com/".$matches[1];
} else if (!isset($matches[1])) {
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment