Skip to content

Instantly share code, notes, and snippets.

@simonwheatley
Created April 14, 2015 19:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simonwheatley/a3be131e0118f9bef324 to your computer and use it in GitHub Desktop.
Save simonwheatley/a3be131e0118f9bef324 to your computer and use it in GitHub Desktop.
Adapt Automattic/syndication to just use WP_RSS and make life easier for users
<?php
/**
*
*
* @package
**/
class GlowSyndication {
/**
* Singleton stuff.
*
* @access @static
*
* @return object
*/
static public function init() {
static $instance = false;
if ( ! $instance )
$instance = new GlowSyndication();
return $instance;
}
/**
* Class constructor
*
*/
public function __construct() {
add_action( 'admin_head', array( $this, 'action_admin_head' ) );
add_action( 'save_post', array( $this, 'action_save_post' ) );
add_action( 'syn_after_site_form', array( $this, 'action_syn_after_site_form' ) );
add_action( 'syn_post_pull_edit_post', array( $this, 'action_syn_post_pull_edit_post' ), 10, 4 );
add_action( 'syn_post_pull_new_post', array( $this, 'action_syn_post_pull_new_post' ), 10, 4 );
add_action( 'template_redirect', array( $this, 'action_template_redirect' ) );
add_filter( 'author_link', array( $this, 'filter_author_link' ) );
add_filter( 'post_link', array( $this, 'filter_post_link' ), 10, 2 );
add_filter( 'the_author', array( $this, 'filter_the_author' ) );
add_filter( 'syn_rss_pull_filter_post', array( $this, 'filter_syn_rss_pull_filter_post' ), 10, 4 );
add_filter( 'syn_transports', array( $this, 'filter_syn_transports' ) );
}
// HOOKS
// =====
/**
* Hooks the admin_head action
*/
public function action_admin_head() {
if ( 'settings_page_push-syndicate-settings' == get_current_screen()->base ) {
$this->settings_css();
}
}
public function filter_syn_transports( $transports ) {
foreach ( $transports as $transport => $details ) {
if ( 'WP_RSS' != $transport ) {
unset( $transports[ $transport ] );
}
}
return $transports;
}
/**
* Hooks the save_post action to save some post meta for
* the syndication site (i.e. feed) post.
*
* @param int $post_id The ID of the post being saved
*/
public function action_save_post( $post_id ) {
if ( 'syn_site' != get_post( $post_id )->post_type ) {
return;
}
if ( isset( $_POST[ 'glow_rss_syndication' ] ) && $_POST[ 'glow_rss_syndication' ] ) {
$convert_cats_to_tags = (bool) $_POST[ 'convert_cats_to_tags' ];
update_post_meta( $post_id, 'convert_cats_to_tags', $convert_cats_to_tags );
$redirect_to_origin = (bool) $_POST[ 'redirect_to_origin' ];
update_post_meta( $post_id, 'redirect_to_origin', $redirect_to_origin );
update_post_meta( $post_id, 'additional_tags', $_POST[ 'additional_tags' ] );
update_post_meta( $post_id, 'additional_cats', $_POST[ 'additional_cats' ] );
update_post_meta( $post_id, 'author_name', $_POST[ 'author_name' ] );
update_post_meta( $post_id, 'author_link', $_POST[ 'author_link' ] );
}
if ( 'auto-draft' == get_post( $post_id )->post_status ) {
update_post_meta( $post_id, 'syn_transport_type', 'WP_RSS' );
}
}
/**
* Hooks the syn_after_site_form Syndication plugin action to add some additional
* fields to the form.
*
* @param WP_Post $site A WP_Post object in the syn_site CPT which represents this site (feed)
*/
public function action_syn_after_site_form( WP_Post $site ) {
if ( 'WP_RSS' != get_post_meta( $site->ID, 'syn_transport_type', true ) ) {
return;
}
$convert_cats_to_tags = (bool) get_post_meta( $site->ID, 'convert_cats_to_tags', true );
$redirect_to_origin = (bool) get_post_meta( $site->ID, 'redirect_to_origin', true );
$additional_tags = get_post_meta( $site->ID, 'additional_tags', true );
$additional_cats = get_post_meta( $site->ID, 'additional_cats', true );
$author_name = get_post_meta( $site->ID, 'author_name', true );
$author_link = get_post_meta( $site->ID, 'author_link', true );
?>
<input type="hidden" name="glow_rss_syndication" value="1" />
<p>
<input name="convert_cats_to_tags" id="convert_cats_to_tags" type="checkbox" <?php checked( $convert_cats_to_tags ); ?> />
<label for="convert_cats_to_tags"><?php echo esc_html__( 'Convert categories to tags?', 'glow-multi-function' ); ?></label>
</p>
<p>
<label for="additional_tags"><?php echo esc_html__( 'Additional tags added to posts in this feed', 'glow-multi-function' ); ?></label><br />
<span class="description"><?php _e( 'Separate tags with commas: e.g. "Tag 1, Another tag, The third tag in the list"', 'glow-multi-function' ) ?></span>
</p>
<p>
<input type="text" class="widefat" name="additional_tags" id="additional_tags" size="100" value="<?php echo esc_attr( $additional_tags ); ?>" />
</p>
<p>
<label for="additional_cats"><?php echo esc_html__( 'Additional categories added to posts in this feed', 'glow-multi-function' ); ?></label><br />
<span class="description"><?php _e( 'Separate categories with commas as per tags above', 'glow-multi-function' ) ?></span>
</p>
<p>
<input type="text" class="widefat" name="additional_cats" id="additional_cats" size="100" value="<?php echo esc_attr( $additional_cats ); ?>" />
</p>
<p>
<input name="redirect_to_origin" id="redirect_to_origin" type="checkbox" <?php checked( $redirect_to_origin ); ?> />
<label for="redirect_to_origin"><?php echo esc_html__( 'Redirect syndicated posts to the origin blog?', 'glow-multi-function' ); ?></label>
</p>
<p>
<label for="author_name"><?php echo esc_html__( 'Attribute posts to this author name:', 'glow-multi-function' ); ?></label>
</p>
<p>
<input type="text" class="widefat" name="author_name" id="author_name" size="100" value="<?php echo esc_attr( $author_name ); ?>" />
</p>
<p>
<label for="author_link"><?php echo esc_html__( 'Link post attribution (i.e. the author name link) to this URL:', 'glow-multi-function' ); ?></label>
</p>
<p>
<input type="text" class="widefat" name="author_link" id="author_link" size="100" value="<?php echo esc_url( $author_link ); ?>" />
</p>
<?php
}
/**
* Hooks the syn_rss_pull_filter_post Syndication plugin filter during the assembly of the post_data
* array which will be passed to wp_insert_post.
*
* @param array $post_data The post data, as would be passed to wp_insert_post
* @param array $args
* @param SimplePie_Item $item A Simplepie item object
* @param int $site_id The ID of the post holding the data describing this feed
*
* @return array Returns an array of post data suitable for wp_insert_post
*/
public function filter_syn_rss_pull_filter_post( $post_data, $args, $item, $site_id ) {
$convert_cats_to_tags = (bool) get_post_meta( $site_id, 'convert_cats_to_tags', true );
$additional_tags = get_post_meta( $site_id, 'additional_tags', true );
$additional_cats = get_post_meta( $site_id, 'additional_cats', true );
if ( $convert_cats_to_tags ) {
$post_data = $this->convert_cats_to_tags( $post_data );
}
$post_data = $this->add_terms( $post_data, $additional_tags, 'post_tag' );
$post_data = $this->add_terms( $post_data, $additional_cats, 'category' );
$post_data['syn_origin_post_link'] = $item->get_link();
return $post_data;
}
/**
* Hooks the syn_post_pull_new_post Syndication plugin action to save some values as post meta.
*
* @param int $post_id The ID of the post which has been created from a feed item
* @param array $post_data The array of post data that was passed to wp_insert_post
* @param WP_Post $site The WP_Post object in the syn_site CPT representing this site (feed)
* @param string $transport_type The transport type used to syndicate this post
*/
public function action_syn_post_pull_new_post( $post_id, $post_data, WP_Post $site, $transport_type ) {
if ( 'WP_RSS' != $transport_type ) {
return;
}
$this->save_origin_url_meta( $post_id, $post_data );
}
/**
* Hooks the syn_post_pull_edit_post Syndication plugin action to save some values as post meta.
*
* @param int $post_id The ID of the post which has been created from a feed item
* @param array $post_data The array of post data that was passed to wp_update_post
* @param WP_Post $site The WP_Post object in the syn_site CPT representing this site (feed)
* @param string $transport_type The transport type used to syndicate this post
*/
public function action_syn_post_pull_edit_post( $post_id, $post_data, $site, $transport_type ) {
if ( 'WP_RSS' != $transport_type ) {
return;
}
$this->save_origin_url_meta( $post_id, $post_data );
}
/**
* Hooks the post_link filter to change the permalink to link to the origin post
* where appropriate.
*
* @param string $permalink The permalink URL
* @param WP_Post $post The WP_Post object the permalink is for
*
* @return string The permalink URL
*/
public function filter_post_link( $permalink, WP_Post $post ) {
$origin_url = $this->get_post_redirect_location( $post->ID );
if ( $origin_url ) {
return esc_url( $origin_url );
}
return $permalink;
}
/**
* Hooks the template_redirect action to send an HTTP redirect back to the
* origin post where appropriate.
*/
public function action_template_redirect() {
if ( is_singular() ) {
$origin_url = $this->get_post_redirect_location();
if ( $origin_url ) {
wp_redirect( esc_url( $origin_url ), 301 );
exit;
}
}
}
/**
* Hooks the author_link filter to link back to the author URL which is (optionally)
* specified on the site (feed) syn_site CPT post.
*
* @param string $permalink The author permalink
*
* @return string The author permalink URL
*/
public function filter_author_link( $permalink ) {
$syn_site_id = $this->get_post_syndication_site_id();
if ( ! $syn_site_id ) {
return $permalink;
}
$author_link = get_post_meta( $syn_site_id, 'author_link', true );
if ( $author_link ) {
return esc_url( $author_link );
}
return $permalink;
}
/**
* Hooks the the_author filter to change the author name
* to display.
*
* @param string $author_name The author name to display
*
* @return string The author name to display
*/
public function filter_the_author( $author_name ) {
$syn_site_id = $this->get_post_syndication_site_id();
if ( ! $syn_site_id ) {
return $author_name;
}
$author_name = get_post_meta( $syn_site_id, 'author_name', true );
if ( $author_name ) {
return esc_html( $author_name );
}
return $author_name;
}
// METHODS
// =======
/**
* Some CSS to output on the settings screen, to hide things we
* don't want to see (because they're irrelevant).
*/
public function settings_css() {
?>
<style type="text/css">
div.syn-push-syndicate-post-types,
div.syn-delete-pushed-posts,
div.syn-api-token-config,
div.syn-api-token {
display: none;
}
</style>
<?php
}
/**
* Save a value from the post data array to post meta.
*
* @param int $post_id The ID of the post to save the meta on
* @param array $post_data An array of post data similar to that passed to wp_insert_post
*/
protected function save_origin_url_meta( $post_id, $post_data ) {
if ( isset( $post_data['syn_origin_post_link'] ) ) {
$origin_post_url = $post_data['syn_origin_post_link'];
update_post_meta( $post_id, 'syn_origin_post_url', $origin_post_url );
}
}
/**
* Take an array of post data, such as might be passed to wp_insert_post,
* and convert all the cats to tags, creating the tags where they
* don't exist.
*
* @param array $post_data An array of post data similar to that passed to wp_insert_post
*
* @return array An array of post data similar to that passed to wp_insert_post
*/
protected function convert_cats_to_tags( $post_data ) {
foreach ( $post_data['post_category'] as $cat_id ) {
$cat = get_category( $cat_id );
$tag = get_term_by( 'name', $cat->name, 'post_tag' );
// Create tag if it doesn't exist
if ( ! $tag ) {
$tag = wp_insert_term( $cat->name, 'post_tag' );
}
$post_data['tags_input'][] = (int) $tag->term_id;
}
// Substitute an empty array for the cats
$post_data['post_category'] = array();
return $post_data;
}
/**
* @param array $post_data An array of post data similar to that passed to wp_insert_post
* @param string $terms_string A comma separated string of term names
* @param string $tax_name The name of a taxonomy: either post_tag or category
*
* @return array An array of post data similar to that passed to wp_insert_post
*/
protected function add_terms( $post_data, $terms_string, $tax_name ) {
$term_names = explode( ',', $terms_string );
foreach ( $term_names as $term_name ) {
$term_name = trim( $term_name );
$term = get_term_by( 'name', $term_name, $tax_name );
// Create tag if it doesn't exist
if ( ! $term ) {
$term = wp_insert_term( $term_name, $tax_name );
}
if ( 'post_tag' == $tax_name ) {
if ( ! is_array( $post_data['tags_input'] ) ) {
$post_data['tags_input'] = array();
}
$post_data['tags_input'][] = (int) $term->term_id;
}
if ( 'category' == $tax_name ) {
if ( ! is_array( $post_data['post_category'] ) ) {
$post_data['post_category'] = array();
}
$post_data['post_category'][] = (int) $term->term_id;
}
}
return $post_data;
}
/**
* Return the URL for the remote (origin) post which was syndicated to
* create this post, or false if none.
*
* @param int|bool $post_id The ID of a post (optional, "current" global post is used if false)
*
* @return bool|string The URL for the originally syndicated post, or false if none
*/
protected function get_post_redirect_location( $post_id = false ) {
if ( false === $post_id ) {
$post_id = get_post()->ID;
}
$origin_url = get_post_meta( $post_id, 'syn_origin_post_url', true );
// Check for an origin URL saved on the post (no DB queries required)
if ( $origin_url ) {
// Only get the syndication site meta if we need to as this requires a DB query
$syn_site_id = $this->get_post_syndication_site_id();
$redirect_to_origin = (bool) get_post_meta( $syn_site_id, 'redirect_to_origin', true );
if ( $redirect_to_origin ) {
return $origin_url;
}
}
return false;
}
/**
* Returns the ID of the WP post in the syn_site CPT which represents the site (feed)
* this post was syndicated from.
*
* @param int|bool $post_id The ID of a post (optional, "current" global post is used if false)
*
* @return bool|int the ID of a WP post in the syn_site CPT
*/
protected function get_post_syndication_site_id( $post_id = false ) {
if ( false === $post_id ) {
$post_id = get_post()->ID;
}
$origin_url = get_post_meta( $post_id, 'syn_origin_post_url', true );
// Check for an origin URL saved on the post (no DB queries required)
if ( $origin_url ) {
// Only get the syndication site meta if we need to as this requires a DB query
$syn_site_id = (int) get_post_meta( $post_id, 'syn_source_site_id', true );
return $syn_site_id;
}
return false;
}
}
// Initiate the singleton
GlowSyndication::init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment