Commit 2ee5c7da authored by Erick Hitter's avatar Erick Hitter
Browse files

Version 0.5

* Add additional rewrite rules for situations where verbose page rules are required. Fixes #1.
* Disable canonical redirect when print template is requested. Also fixes #1.
* Update is_print() method to use WordPress API.
* Correct translation string implementation.
* Update code to better conform to WordPress Coding Standards.
parent 91b4c462
......@@ -4,7 +4,7 @@ Donate link: http://www.thinkoomph.com/plugins-modules/wp-print-friendly/
Tags: print, template, printer, printable
Requires at least: 3.1
Tested up to: 3.4
Stable tag: 0.4.4.1
Stable tag: 0.5
Extends WordPress' template system to support printer-friendly templates. Works with permalink structures to support nice URLs.
......@@ -57,6 +57,13 @@ This plugin is known to conflict with certain plugins, many pertaining to SEO an
== Changelog ==
= 0.5 =
* Add additional rewrite rules for situations where verbose page rules are required.
* Disable canonical redirect when print template is requested.
* Update is_print() method to use WordPress API.
* Correct translation string implementation.
* Update code to better conform to WordPress Coding Standards.
= 0.4.4.1 =
* Remove unnecessary query_var filter.
......@@ -119,6 +126,9 @@ This plugin is known to conflict with certain plugins, many pertaining to SEO an
== Upgrade Notice ==
= 0.5 =
Adds better support for sites that use verbose page rules, resolving situations where requests for print template redirect to the post.
= 0.4.4.1 =
Removes unnecessary query_var filter.
......
......@@ -4,7 +4,7 @@ Plugin Name: WP Print Friendly
Plugin URI: http://www.thinkoomph.com/plugins-modules/wp-print-friendly/
Description: Extends WordPress' template system to support printer-friendly templates. Works with permalink structures to support nice URLs.
Author: Erick Hitter (Oomph, Inc.)
Version: 0.4.4.2
Version: 0.5
Author URI: http://www.thinkoomph.com/
*/
......@@ -28,71 +28,76 @@ class wp_print_friendly {
var $notice_key = 'wpf_admin_notice_dismissed';
/*
/**
* Register deactivation hook and filter.
*
* @uses register_deactivation_hook, add_filter
* @return null
*/
function __construct() {
public function __construct() {
register_deactivation_hook( __FILE__, array( $this, 'deactivation_hook' ) );
add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
}
/*
/**
* Clean up after plugin deactivation.
*
* @uses flush_rewrite_rules, delete_option
* @action register_deactivation_hook
* @return null
*/
function deactivation_hook() {
public function deactivation_hook() {
flush_rewrite_rules();
delete_option( $this->settings_key );
delete_option( $this->notice_key );
}
/*
/**
* Register actions and filters.
*
* @uses add_action, add_filter, get_option
* @action plugins_loaded
* @return null
*/
function action_plugins_loaded() {
public function action_plugins_loaded() {
add_action( 'init', array( $this, 'action_init' ), 20 );
add_action( 'admin_init', array( $this, 'action_admin_init' ) );
add_action( 'admin_menu', array( $this, 'action_admin_menu' ) );
add_filter( 'request', array( $this, 'filter_request' ) );
add_action( 'pre_get_posts', array( $this, 'action_pre_get_posts' ) );
add_filter( 'template_include', array( $this, 'filter_template_include' ) );
add_filter( 'redirect_canonical', array( $this, 'filter_redirect_canonical' ) );
add_filter( 'body_class', array( $this, 'filter_body_class' ) );
add_filter( 'the_content', array( $this, 'filter_the_content' ), 0 );
add_filter( 'the_content', array( $this, 'filter_the_content_auto' ) );
add_filter( 'the_content', array( $this, 'filter_the_content_late' ), 99 );
if( !get_option( $this->notice_key ) )
if ( ! get_option( $this->notice_key ) )
add_action( 'admin_notices', array( $this, 'action_admin_notices_activation' ) );
}
/*
/**
* Add print endpoint and rewrite rules for term taxonomy archives
* @uses add_rewrite_endpoint, $wp_rewrite, get_taxonomies, add_rewrite_rule
*
* @uses add_rewrite_endpoint, $wp_rewrite, get_taxonomies, add_rewrite_rule, trailingslashit
* @action init
* @return null
*/
function action_init() {
public function action_init() {
add_rewrite_endpoint( $this->query_var, EP_ALL );
global $wp_rewrite;
//Taxonomies, since they aren't covered by add_rewrite_endpoint
if( $wp_rewrite->permalink_structure ) {
if ( $wp_rewrite->permalink_structure ) {
$taxonomies = get_taxonomies( array(), 'objects' );
foreach( $taxonomies as $taxonomy => $args ) {
if( $args->rewrite == false )
foreach ( $taxonomies as $taxonomy => $args ) {
if ( $args->rewrite == false || 'post_format' == $taxonomy )
continue;
$taxonomy_slug = '';
if( $args->rewrite[ 'with_front' ] && $wp_rewrite->front != '/' ) $taxonomy_slug .= $wp_rewrite->front;
if ( $args->rewrite[ 'with_front' ] && $wp_rewrite->front != '/' ) $taxonomy_slug .= $wp_rewrite->front;
$taxonomy_slug .= $args->rewrite[ 'slug' ];
$query_var = $args->query_var ? $args->query_var : 'taxonomy=' . $taxonomy . '&term';
......@@ -111,49 +116,51 @@ class wp_print_friendly {
}
}
/*
/**
* Register plugin option and disable rewrite rule flush warning.
*
* @uses register_setting, update_option
* @action admin_init
* @return null
*/
function action_admin_init() {
public function action_admin_init() {
register_setting( $this->settings_key, $this->settings_key, array( $this, 'admin_options_validate' ) );
if( isset( $_GET[ $this->notice_key ] ) )
if ( isset( $_GET[ $this->notice_key ] ) )
update_option( $this->notice_key, 1 );
}
/*
/**
* Determine if print template is being requested.
* @uses $wp_query
*
* @uses get_query_var
* @return bool
*/
function is_print() {
global $wp_query;
return is_array( $wp_query->query ) && array_key_exists( $this->query_var, $wp_query->query );
public function is_print() {
return (bool) get_query_var( $this->query_var );
}
/*
/**
* Select appropriate template based on post type and available templates.
* Returns an array with name and path keys for available template or false if no template is found.
*
* @uses get_queried_object, is_home, is_front_page, locate_template
* @return array or false
*/
function template_chooser() {
public function template_chooser() {
//Get queried object to check post type
$queried_object = get_queried_object();
//Get plugin path
$pluginpath = dirname( __FILE__ );
if( ( is_home() || is_front_page() ) && ( '' !== ( $path = locate_template( 'wpf-home.php', false ) ) ) ) {
if ( ( is_home() || is_front_page() ) && ( '' !== ( $path = locate_template( 'wpf-home.php', false ) ) ) ) {
$template = array(
'name' => 'wpf-home',
'path' => $path
);
}
elseif(
elseif (
is_object( $queried_object ) &&
property_exists( $queried_object, 'taxonomy' ) &&
property_exists( $queried_object, 'slug' ) &&
......@@ -163,7 +170,7 @@ class wp_print_friendly {
'name' => 'wpf-' . $queried_object->taxonomy,
'path' => $path
);
elseif(
elseif (
is_object( $queried_object ) &&
property_exists( $queried_object, 'post_type' ) &&
property_exists( $queried_object, 'post_name' ) &&
......@@ -173,7 +180,7 @@ class wp_print_friendly {
'name' => 'wpf-' . $queried_object->post_type,
'path' => $path
);
elseif(
elseif (
is_object( $queried_object ) &&
property_exists( $queried_object, 'post_name' ) &&
( '' !== ( $path = locate_template( 'wpf-' . $queried_object->post_name . '.php', false ) ) )
......@@ -182,12 +189,12 @@ class wp_print_friendly {
'name' => 'wpf-' . $queried_object->post_name,
'path' => $path
);
elseif( '' !== ( $path = locate_template( 'wpf.php', false ) ) )
elseif ( '' !== ( $path = locate_template( 'wpf.php', false ) ) )
$template = array(
'name' => 'wpf-default',
'path' => $path
);
elseif( file_exists( $pluginpath . '/default-template.php' ) )
elseif ( file_exists( $pluginpath . '/default-template.php' ) )
$template = array(
'name' => 'wpf-plugin-default',
'path' => $pluginpath . '/default-template.php'
......@@ -196,64 +203,83 @@ class wp_print_friendly {
return isset( $template ) ? $template : false;
}
/*
* Detect request for print stylesheet on the homepage and reset query variables
/**
* Detect request for print stylesheet on the homepage and reset query variables.
*
* @param array $qv
* @filter request
* @return array
*/
function filter_request( $qv ) {
if( array_key_exists( 'pagename', $qv ) && $qv[ 'pagename' ] == $this->query_var ) {
public function filter_request( $qv ) {
if ( array_key_exists( 'pagename', $qv ) && $qv[ 'pagename' ] == $this->query_var ) {
$qv[ $this->query_var ] = '';
unset( $qv[ 'page' ] );
unset( $qv[ 'pagename' ] );
}
if( array_key_exists( $this->query_var, $qv ) && is_numeric( $qv[ $this->query_var ] ) )
if ( array_key_exists( $this->query_var, $qv ) && is_numeric( $qv[ $this->query_var ] ) )
$qv[ 'page' ] = intval( $qv[ $this->query_var ] );
return $qv;
}
/*
/**
* Filter query when request to print specific page is made.
*
* @param object $query
* @action pre_get_posts
* @return object
*/
function action_pre_get_posts( $query ) {
if( array_key_exists( $this->query_var, $query->query_vars ) && !empty( $query->query_vars[ $this->query_var ] ) ) {
public function action_pre_get_posts( $query ) {
if ( array_key_exists( $this->query_var, $query->query_vars ) && ! empty( $query->query_vars[ $this->query_var ] ) ) {
$qv = explode( '/', $query->query_vars[ $this->query_var ] );
if( array_key_exists( 1, $qv ) && is_numeric( $qv[ 1 ] ) )
if ( array_key_exists( 1, $qv ) && is_numeric( $qv[ 1 ] ) )
$query->query_vars[ 'page' ] = (int)$qv[ 1 ];
}
return $query;
}
/*
/**
* Filter template include to return print template if requested.
*
* @param string $template
* @filter template_include
* @return string
*/
function filter_template_include( $template ) {
if( $this->is_print() && ( $print_template = $this->template_chooser() ) )
public function filter_template_include( $template ) {
if ( $this->is_print() && ( $print_template = $this->template_chooser() ) )
$template = $print_template[ 'path' ];
return $template;
}
/*
/**
* Prevent canonical redirect if print URL is requested.
*
* @param string $url
* @uses this::is_print
* @filter redirect_canonical
* @return string or false
*/
public function filter_redirect_canonical( $url ) {
if ( $this->is_print() )
$url = false;
return $url;
}
/**
* Filter body classes to include references to print template.
*
* @param array $classes
* @filter body_class
* @return array
*/
function filter_body_class( $classes ) {
if( $this->is_print() && ( $print_template = $this->template_chooser() ) ) {
if( $print_template[ 'name' ] == 'default' )
public function filter_body_class( $classes ) {
if ( $this->is_print() && ( $print_template = $this->template_chooser() ) ) {
if ( $print_template[ 'name' ] == 'default' )
$classes[] = 'wpf';
else
$classes[] = $print_template[ 'name' ];
......@@ -262,18 +288,19 @@ class wp_print_friendly {
return $classes;
}
/*
/**
* Filter post content to support printing entire post on one page.
*
* @param string $content
* @uses get_query_var
* @filter the_content
* @return string
*/
function filter_the_content( $content ) {
if( $this->is_print() ) {
public function filter_the_content( $content ) {
if ( $this->is_print() ) {
$print = get_query_var( $this->query_var );
if( $print == 'all' || $print == '/all' || empty( $print ) ) {
if ( $print == 'all' || $print == '/all' || empty( $print ) ) {
global $post;
$content = $post->post_content;
......@@ -287,26 +314,27 @@ class wp_print_friendly {
return $content;
}
/*
* Filter the content if automatic inclusion is selected
/**
* Filter the content if automatic inclusion is selected.
*
* @param string $content
* @uses $this::get_options, $post, $this::print_url, get_query_var, apply_filters
* @filter the_content
* @return string
*/
function filter_the_content_auto( $content ) {
public function filter_the_content_auto( $content ) {
$options = $this->get_options();
global $post;
if( is_array( $options ) && array_key_exists( 'auto', $options ) && $options[ 'auto' ] == true && in_array( $post->post_type, $options[ 'post_types' ] ) && !$this->is_print() ) {
if ( is_array( $options ) && array_key_exists( 'auto', $options ) && $options[ 'auto' ] == true && in_array( $post->post_type, $options[ 'post_types' ] ) && ! $this->is_print() ) {
extract( $options );
//Basic URL
$print_url = $this->print_url();
//Page URL, if necessary
if( !empty( $print_text_page ) && strpos( $post->post_content, '<!--nextpage-->' ) !== false ) {
if ( ! empty( $print_text_page ) && strpos( $post->post_content, '<!--nextpage-->' ) !== false ) {
$page = get_query_var( 'page' );
$page = $page ? $page : 1;
......@@ -316,7 +344,7 @@ class wp_print_friendly {
//Build link(s)
$link = '<p class="wpf_wrapper"><a class="' . $css_class . '" href="' . $print_url . '"' . ( $link_target == 'new' ? ' target="_blank"' : '' ) . '>' . $print_text . '</a>';
if( isset( $print_url_page ) ) {
if ( isset( $print_url_page ) ) {
$link .= ' | ';
$link .= '<a class="' . $css_class . ' ' . $css_class . '_cur" href="' . $print_url_page . '"' . ( $link_target == 'new' ? ' target="_blank"' : '' ) . '>' . $print_text_page . '</a>';
}
......@@ -324,47 +352,48 @@ class wp_print_friendly {
$link .= '</p><!-- .wpf_wrapper -->';
//Place link(s)
if( $placement == 'above' )
if ( $placement == 'above' )
$content = $link . $content;
elseif( $placement == 'below' )
elseif ( $placement == 'below' )
$content = $content . $link;
elseif( $placement == 'both' )
elseif ( $placement == 'both' )
$content = $link . $content . $link;
}
return $content;
}
/*
* Convert links to endnotes if desired
/**
* Convert links to endnotes if desired.
*
* @param string $content
* @uses $this::is_print, $this::get_options
* @filter the_content
* @return string
*/
function filter_the_content_late( $content ) {
if( $this->is_print() ) {
public function filter_the_content_late( $content ) {
if ( $this->is_print() ) {
global $post;
$options = $this->get_options();
//Endnotes
if( $options[ 'endnotes' ] ) {
if ( $options[ 'endnotes' ] ) {
$links = array();
$i = 1;
//Build array of links
preg_match_all( '#<a href=(["\'{1}])([^"\']+)(["\'{1}])([^>]*)>(.*?)</a>#i', $content, $matches );
if(
if (
isset( $matches ) && is_array( $matches ) &&
array_key_exists( 0, $matches ) && !empty( $matches[ 0 ] ) &&
array_key_exists( 2, $matches ) && !empty( $matches[ 2 ] ) &&
array_key_exists( 5, $matches ) && !empty( $matches[ 5 ] )
array_key_exists( 0, $matches ) && ! empty( $matches[ 0 ] ) &&
array_key_exists( 2, $matches ) && ! empty( $matches[ 2 ] ) &&
array_key_exists( 5, $matches ) && ! empty( $matches[ 5 ] )
) {
//Format matches for replacement in content
$replacements = array();
foreach( $matches[ 0 ] as $key => $match ) {
foreach ( $matches[ 0 ] as $key => $match ) {
$replacements[ $match ] = array(
'url' => $matches[ 2 ][ $key ],
'title' => $matches[ 5 ][ $key ]
......@@ -372,7 +401,7 @@ class wp_print_friendly {
}
//Replace links with endnote markers
foreach( $replacements as $match => $args ) {
foreach ( $replacements as $match => $args ) {
$content = str_replace( $match, $args[ 'title' ] . '[' . $i . ']', $content );
$links[ $i ] = $args;
$i++;
......@@ -382,7 +411,7 @@ class wp_print_friendly {
$endnotes = '<div class="wpf-endnotes">';
$endnotes .= '<strong>' . $options[ 'endnotes_label' ] . '</strong>';
$endnotes .= '<ol>';
foreach( $links as $link ) {
foreach ( $links as $link ) {
$endnotes .= '<li>';
$endnotes .= preg_replace( '#<img(.*)>#', '[Image]', $link[ 'title' ] ) . ': ' . esc_url( $link[ 'url' ] );
$endnotes .= '</li>';
......@@ -397,79 +426,80 @@ class wp_print_friendly {
return $content;
}
/*
* Generate URL for post's printer-friendly format
/**
* Generate URL for post's printer-friendly format.
*
* @param int $post_id
* @param int $page
* @uses is_view_all, is_home, is_front_page, home_url, $post, get_permalink, is_category, get_category_link, is_tag, get_tag_link, is_date, get_query_var, get_day_link, get_month_link, get_year_link, is_tax, get_queried_object, get_term_link, $wp_rewrite, path_join, trailingslashit, add_query_arg
* @return string or bool
*/
function print_url( $post_id = false, $page = false ) {
if( $page === true )
public function print_url( $post_id = false, $page = false ) {
if ( $page === true )
return false;
if( function_exists( 'is_view_all' ) && is_view_all() )
if ( function_exists( 'is_view_all' ) && is_view_all() )
$page = false;
$link = false;
//Get link base specific to page type being viewed
if( is_singular() || in_the_loop() ) {
if( $post_id == false ) {
if ( is_singular() || in_the_loop() ) {
if ( $post_id == false ) {
global $post;
$post_id = $post->ID;
}
if( !$post_id )
if ( ! $post_id )
return false;
$link = get_permalink( $post_id );
}
elseif( is_home() || is_front_page() )
elseif ( is_home() || is_front_page() )
$link = home_url( '/' );
elseif( is_category() )
elseif ( is_category() )
$link = get_category_link( get_query_var( 'cat' ) );
elseif( is_tag() )
elseif ( is_tag() )
$link = get_tag_link( get_query_var( 'tag_id' ) );
/* DISABLED FOR NOW AS PRINTING OF DATE-BASED ARCHIVES DOESN'T WORK YET
elseif( is_date() ) {
elseif ( is_date() ) {
$year = get_query_var( 'year' );
$monthnum = get_query_var( 'monthnum' );
$day = get_query_var( 'day' );
if( $day )
if ( $day )
$link = get_day_link( $year, $monthnum, $day );
elseif( $monthnum )
elseif ( $monthnum )
$link = get_month_link( $year, $monthnum );
else
$link = get_year_link( $year );
}*/
elseif( is_tax() ) {
elseif ( is_tax() ) {
$queried_object = get_queried_object();
if( is_object( $queried_object ) && property_exists( $queried_object, 'taxonomy' ) && property_exists( $queried_object, 'term_id' ) )
if ( is_object( $queried_object ) && property_exists( $queried_object, 'taxonomy' ) && property_exists( $queried_object, 'term_id' ) )
$link = get_term_link( (int)$queried_object->term_id, $queried_object->taxonomy );
}
//If link base is set, build link
if( $link !== false ) {
if ( $link !== false ) {
global $wp_rewrite;
$page = intval( $page );
if( $wp_rewrite->using_permalinks() ) {
if ( $wp_rewrite->using_permalinks() ) {
$link = path_join( $link, $this->query_var );
if( $page )
if ( $page )
$link = path_join( $link, intval( $page ) );
if( $wp_rewrite->use_trailing_slashes )
if ( $wp_rewrite->use_trailing_slashes )
$link = trailingslashit( $link );
}
else {
$link = add_query_arg( $this->query_var, is_numeric( $page ) ? intval( $page ) : 'all', $link );
if( $page )
if ( $page )
$link = add_query_arg( 'page', is_numeric( $page ) ? intval( $page ) : 'all', $link );
}
}
......@@ -477,22 +507,24 @@ class wp_print_friendly {
return $link;
}
/*
* Add menu item for options page
/**
* Add menu item for options page.
*
* @uses add_options_page
* @action admin_menu
* @return null
*/
function action_admin_menu() {
public function action_admin_menu() {
add_options_page( 'WP Print Friendly Options', 'WP Print Friendly', 'manage_options', $this->ns, array( $this, 'admin_options' ) );
}
/*
* Render options page
/**
* Render options page.
*
* @uses settings_fields, $this::get_options, _e, checked, esc_attr
* @return html
*/
function admin_options() {
public function admin_options() {
?>
<div class="wrap">
<h2>WP Print Friendly</h2>
......@@ -509,25 +541,25 @@ class wp_print_friendly {
<table class="form-table">
<tr>
<th scope="row"><?php _e( 'Automatically add print links based on settings below?', $this->ns ); ?></th>
<th scope="row"><?php _e( 'Automatically add print links based on settings below?', 'wp_print_friendly' ); ?></th>
<td>
<input type="radio" name="<?php echo esc_attr( $this->settings_key ); ?>[auto]" id="auto-true" value="1"<?php checked( $options[ 'auto' ], true, true ); ?> /> <label for="auto-true"><?php _e( 'Yes', $this->ns ); ?></label><br />
<input type="radio" name="<?php echo esc_attr( $this->settings_key ); ?>[auto]" id="auto-false" value="0"<?php checked( $options[ 'auto' ], false, true ); ?> /> <label for="auto-false"><?php _e( 'No', $this->ns ); ?></label>
<input type="radio" name="<?php echo esc_attr( $this->settings_key ); ?>[auto]" id="auto-true" value="1"<?php checked( $options[ 'auto' ], true, true ); ?> /> <label for="auto-true"><?php _e( 'Yes', 'wp_print_friendly' ); ?></label><br />
<input type="radio" name="<?php echo esc_attr( $this->settings_key ); ?>[auto]" id="auto-false" value="0"<?php checked( $options[ 'auto' ], false, true ); ?> /> <label for="auto-false"><?php _e( 'No', 'wp_print_friendly' ); ?></label>
</td>
</tr>
<tr>
<th scope="row"><?php _e( 'Automatically place link:', $this->ns ); ?></th>
<th scope="row"><?php _e( 'Automatically place link:', 'wp_print_friendly' ); ?></th>
<td>
<input type="radio" name="<?php echo esc_attr( $this->settings_key ); ?>[placement]" id="placement-above" value="above"<?php checked( $options[ 'placement' ], 'above', true ); ?> /> <label for="placement-above"><?php _e( 'Above content', $this->ns ); ?></label><br />
<input type="radio" name="<?php echo esc_attr( $this->settings_key ); ?>[placement]" id="placement-below" value="below"<?php checked(