Created
April 14, 2015 19:42
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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