Skip to content

Instantly share code, notes, and snippets.

@ocean90
Created December 19, 2011 08:51
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save ocean90/1496148 to your computer and use it in GitHub Desktop.
Save ocean90/1496148 to your computer and use it in GitHub Desktop.
WordPress Page Template to build a feed of your Google+ stream
<?php
/**
* Template Name: Google+ Feed
*/
/**
* A WordPress page template for a Google+ feed.
*
* @author Dominik Schilling
* @license GPLv2
* @link http://wpgrafie.de/567/
*
* @version 0.2
*/
class Google_Plus_Feed {
/**
* Google+ API Key.
* See https://code.google.com/apis/console/
*
* @since 0.1
*
* @var string
*/
private $api_key = '';
/**
* Google+ User ID.
*
* @since 0.1
*
* @var string
*/
private $user_id = '';
/**
* Custom settings.
* See $this->set_settings()
*
* @since 0.1
*
* @var array
*/
private $settings = array();
/**
* Don't change the lines after these
* if you don't know what you do.
*/
/**
* Google+ activities.
*
* @since 0.1
*
* @var mixed
*/
private $activities;
/**
* Current queried object.
*
* @since 0.1
*
* @var object
*/
private $curr_obj;
/**
* Construct.
*
* @since 0.1
*
* @return void
*/
function __construct() {
if( empty( $this->curr_obj ) )
$this->curr_obj = get_queried_object();
if( ! $this->get_api_key() || ! $this->get_user_id() )
wp_die( 'Not configured!' );
$this->set_settings();
$this->activities = $this->build_activities();
if ( empty( $this->activities ) )
wp_die( 'Please load again.' );
$this->feed_output();
}
/**
* Get the API key from
* post custom field (gplusfeed_api_key)
* or
* $this->api_key
*
* @since 0.1
*
* @return string|bool Key on success, false if key is missing.
*/
function get_api_key() {
$api_key = get_post_meta( $this->curr_obj->ID, 'gplusfeed_api_key', true );
if ( ! empty( $api_key ) )
return $api_key;
else if( ! empty( $this->api_key ) )
return $this->api_key;
else
return false;
}
/**
* Get the user id from
* post custom field (gplus_feed_user_id)
* or
* $this->user_id
*
* @since 0.1
*
* @return string|bool Key on success, false if key is missing.
*/
function get_user_id() {
$user_id = get_post_meta( $this->curr_obj->ID, 'gplus_feed_user_id', true );
if ( ! empty( $user_id ) )
return $user_id;
else if( ! empty( $this->user_id ) )
return $this->user_id;
else
return false;
}
/**
* Set custom feed settings.
*
* - limit: How many activities should be displayed in feed
* - cache_time: How long the feed should be cached
* - language: The language of the feed
* - update_period: See http://web.resource.org/rss/1.0/modules/syndication/
* - update_frequency: See http://web.resource.org/rss/1.0/modules/syndication/
*
* @since 0.1
*
* @return array Settings saved in an array.
*/
function set_settings() {
$this->settings = wp_parse_args(
array(
'limit' => 10,
'cache_time' => 300,
'language' => 'de',
'update_period' => 'hourly',
'update_frequency' => 1
),
$this->settings
);
}
/**
* Get the Google+ API link.
* See https://developers.google.com/+/api/latest/activities/list
*
* @since 0.1
*
* @return string URL of the Google+ API.
*/
function get_api_link() {
$api_link = add_query_arg(
array(
'alt' => 'json',
'maxResults' => $this->settings['limit'],
'pp' => 1,
'key' => $this->get_api_key()
),
sprintf( 'https://www.googleapis.com/plus/v1/people/%s/activities/public', $this->get_user_id() )
);
return esc_url_raw( $api_link );
}
/**
* Build the activity stream and save it in a transient.
*
* @since 0.1
*
* @return string|bool Activities in XML format or false on error.
*/
function build_activities() {
$dev = true;
if ( false !== ( $activities = get_transient( $this->get_cache_key() ) ) && ! $dev )
return $activities;
$activities = $this->get_activities();
if ( is_wp_error( $activities ) )
return false;
$activities = $this->render_activities( $activities );
if ( empty( $activities ) )
return false;
// Cache activities
set_transient( $this->get_cache_key(), $activities, $this->settings['cache_time'] );
return $activities;
}
/**
* Build an individual cache key.
* Based on settings, user id and API key.
*
* @since 0.1
*
* @return string The cache key.
*/
function get_cache_key() {
return 'gplus_feed_' . md5(
implode( '|', $this->settings )
. $this->get_user_id()
. $this->get_api_key()
);
}
/**
* Get the activities from Google+ API.
*
* @since 0.1
*
* @return array|WP_Error API result in an array or WP_Error on API/HTTP error.
*/
function get_activities() {
$result = wp_remote_retrieve_body(
wp_remote_get(
$this->get_api_link()
)
);
if ( ! empty( $result ) ) {
$result = (array) json_decode( $result );
if ( empty ( $results->error ) )
return $result;
else
return new WP_Error( 'api_error', 'API ERROR', $results->error );
} else {
return new WP_Error( 'http_error', 'HTTP ERROR');
}
}
/**
* Render the activities and return them in XML format.
*
* @since 0.1
*
* @param array $activities
* @return array Rendered activity items for feed.
*/
function render_activities( $activities ) {
$feed = array();
foreach( $activities['items'] as $item => $data ) {
if ( ! preg_match('/^<b\b[^>]*>(.*?)<\/b>/i', $data->object->content, $matches ) ) {
$title = $data->title;
$content = $data->object->content;
} else {
$title = strip_tags( $matches[1] );
$content = str_replace( $matches[0] . '<br /><br />', '', $data->object->content );
}
if ( ! empty( $data->object->attachments ) )
$content .= $this->_render_activity_attachments( $data->object->attachments );
$feed[$item] = "
<item>
<title>{$title}</title>
<link>{$data->url}</link>
<pubDate>" . mysql2date( 'D, d M Y H:i:s +0000', $data->published, false ) . "</pubDate>
<dc:creator>{$data->actor->displayName}</dc:creator>
<guid isPermaLink=\"false\">{$data->url}</guid>
<description><![CDATA[" . wp_trim_words( $content, 20 ) . "]]></description>
<content:encoded><![CDATA[{$content}]]></content:encoded>
<slash:comments>{$data->object->replies->totalItems}</slash:comments>
</item>
";
}
return $feed;
}
/**
* Handle activity attachments, like video, photo and links (articles).
*
* @since 0.2
*
* @param array $attachments
* @return string Attachments in HTML format.
*/
function _render_activity_attachments( $attachments ) {
$articles = $photos = $videos = array();
foreach ( $attachments as $attachment => $meta ) {
switch ( $meta->objectType ) {
case 'article' :
$host = @parse_url( $meta->url, PHP_URL_HOST );
$articles[] = sprintf(
'%s<a href="%s" title="%s">%s</a>',
empty( $host ) ? '' : $host . ' – ',
esc_url( $meta->url ),
empty( $meta->content ) ? '' : esc_attr( $meta->content ),
empty( $meta->displayName ) ? '' : $meta->displayName
);
break;
case 'photo' :
$photos[] = sprintf(
'%s<img src="%s" height="%s" width="%s" alt="%s" title="%s" style="margin:5px;max-width:250px;height:auto" />%s',
empty( $meta->fullImage->url ) ? '' : '<a href="' . esc_url( $meta->fullImage->url ) . '">',
esc_url( $meta->image->url ),
empty( $meta->image->height ) ? '' : esc_attr( $meta->image->height ),
empty( $meta->image->width ) ? '' : esc_attr( $meta->image->width ),
empty( $meta->displayName ) ? '' : $meta->displayName,
empty( $meta->displayName ) ? '' : $meta->displayName,
empty( $meta->fullImage->url ) ? '' : '</a>'
);
break;
case 'video' :
$videos[] = sprintf(
'<a href="%s"><img src="%s" height="%s" width="%s" alt="%s" title="%s" style="margin:5px;max-width:250px;height:auto" /></a>',
esc_url( $meta->url ),
esc_url( $meta->image->url ),
empty( $meta->image->height ) ? '' : esc_attr( $meta->image->height ),
empty( $meta->image->width ) ? '' : esc_attr( $meta->image->width ),
empty( $meta->displayName ) ? '' : $meta->displayName,
empty( $meta->displayName ) ? '' : $meta->displayName
);
break;
}
}
$content = '';
$_html = '<div style="display:table-row"><div style="display:table-cell;vertical-align:top;padding:0 10px 0 0"><b>%s:</b></div>';
if ( ! empty( $articles ) ) {
$articles = implode( '<br />', $articles );
$content .= sprintf(
$_html,
__( 'Links' )
);
$content .= sprintf(
'<div style="display:table-cell">%s</div></div>',
$articles
);
}
if ( ! empty( $photos ) ) {
$photos = implode( '', $photos );
$content .= sprintf(
$_html,
__( 'Images' )
);
$content .= sprintf(
'<div style="display:table-cell">%s</div></div>',
$photos
);
}
if ( ! empty( $videos ) ) {
$videos = implode( '', $videos );
$content .= sprintf(
$_html,
__( 'Video' )
);
$content .= sprintf(
'<div style="display:table-cell">%s</div></div>',
$videos
);
}
if ( ! empty( $content ) )
$content = sprintf(
'<br /><br /><h4>%s</h4><div style="display:table">%s</div>',
__( 'Images and Attachments' ),
$content
);
return $content;
}
/**
* Build the feed output.
*
* @since 0.1
*
* @return void
*/
function feed_output() {
$this->get_rss_header();
$this->get_rss_content();
$this->get_rss_footer();
}
/**
* Retrieve information about the feed.
*
* @since 0.1
*
* @param string $show Feed info to retrieve.
* @param bool $echo Return or print the info. Default: true.
* @return string Feed info.
*/
function get_feed_info( $show, $echo = true ) {
switch ( $show ) {
case 'title' :
$output = apply_filters( 'the_title_rss', $this->curr_obj->post_title ) ;
break;
case 'self' :
$host = @parse_url( home_url() );
$host = $host['host'];
$output = esc_url(
( is_ssl() ? 'https' : 'http' ) . '://'
. $host
. stripslashes( $_SERVER['REQUEST_URI'] )
);
break;
case 'link' :
$output = esc_url( sprintf( 'https://plus.google.com/%d/', $this->get_user_id() ) );
break;
case 'desc' :
$output = apply_filters( 'the_title_rss', $this->curr_obj->post_content );
break;
case 'time' :
$timeout = get_option( '_transient_timeout_' . $this->get_cache_key() );
if ( $timeout === false )
$time = time();
else
$time = $timeout - $this->settings['cache_time'];
$output = date( 'D, d M Y H:i:s +0000', $time );
break;
case 'language' :
$output = $this->settings['language'];
break;
case 'update_period' :
$output = $this->settings['update_period'];
break;
case 'update_frequency' :
$output = $this->settings['update_frequency'];
break;
}
if( ! $echo )
return $output;
echo $output;
}
/**
* Print the feed header.
*
* @since 0.1
*
* @return void
*/
function get_rss_header() {
header( 'Content-Type: text/xml; charset=UTF-8', true );
echo '<?xml version="1.0" encoding="UTF-8"?'.'>';
?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
<title><?php $this->get_feed_info( 'title' ); ?></title>
<atom:link href="<?php $this->get_feed_info( 'self' ); ?>" rel="self" type="application/rss+xml" />
<link><?php $this->get_feed_info( 'link' ); ?></link>
<description><?php $this->get_feed_info( 'desc' ); ?></description>
<lastBuildDate><?php $this->get_feed_info( 'time' ); ?></lastBuildDate>
<language><?php $this->get_feed_info( 'language' ); ?></language>
<sy:updatePeriod><?php $this->get_feed_info( 'update_period' ); ?></sy:updatePeriod>
<sy:updateFrequency><?php $this->get_feed_info( 'update_frequency' ); ?></sy:updateFrequency>
<?php
}
/**
* Print the feed content/activities.
*
* @since 0.1
*
* @return void
*/
function get_rss_content() {
foreach( $this->activities as $item )
echo $item;
}
/**
* Print the feed footer.
*
* @since 0.1
*
* @return void
*/
function get_rss_footer() {
?>
</channel>
</rss>
<?php
}
}
// Init
$feed = new Google_Plus_Feed();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment