Commit 42297f79 authored by Erick Hitter's avatar Erick Hitter
Browse files

Version 0.2: paging by word

Build on work by @bendoh merged in f96afe53 and implement two paging options as toggles in the UI. Also makes the approach to applying the various paging types more modular and a bit easier to follow.

Lastly, WP coding standards. There's lots to clean up, so I only dealt with those bits I actually touched in the aforementioned work.
parent f96afe53
...@@ -30,13 +30,17 @@ class Automatically_Paginate_Posts { ...@@ -30,13 +30,17 @@ class Automatically_Paginate_Posts {
private $post_types_default = array( 'post' ); private $post_types_default = array( 'post' );
private $num_pages; private $num_pages;
private $num_pages_default = 2; private $paging_type_default = 'pages';
private $num_words_default = ''; private $num_pages_default = 2;
private $num_words_default = '';
//Ensure option names match values in this::uninstall private $paging_types_allowed = array( 'pages', 'words' );
private $option_name_post_types = 'autopaging_post_types';
private $option_name_num_pages = 'autopaging_num_pages'; // Ensure option names match values in this::uninstall
private $option_name_num_words = 'autopaging_num_words'; private $option_name_post_types = 'autopaging_post_types';
private $option_name_paging_type = 'pages';
private $option_name_num_pages = 'autopaging_num_pages';
private $option_name_num_words = 'autopaging_num_words';
private $meta_key_disable_autopaging = '_disable_autopaging'; private $meta_key_disable_autopaging = '_disable_autopaging';
...@@ -94,6 +98,7 @@ class Automatically_Paginate_Posts { ...@@ -94,6 +98,7 @@ class Automatically_Paginate_Posts {
*/ */
public function uninstall() { public function uninstall() {
delete_option( 'autopaging_post_types' ); delete_option( 'autopaging_post_types' );
delete_option( 'autopaging_paging_type' );
delete_option( 'autopaging_num_pages' ); delete_option( 'autopaging_num_pages' );
delete_option( 'autopaging_num_words' ); delete_option( 'autopaging_num_words' );
} }
...@@ -122,13 +127,15 @@ class Automatically_Paginate_Posts { ...@@ -122,13 +127,15 @@ class Automatically_Paginate_Posts {
*/ */
public function action_admin_init() { public function action_admin_init() {
register_setting( 'reading', $this->option_name_post_types, array( $this, 'sanitize_supported_post_types' ) ); register_setting( 'reading', $this->option_name_post_types, array( $this, 'sanitize_supported_post_types' ) );
register_setting( 'reading', $this->option_name_paging_type, array( $this, 'sanitize_paging_type' ) );
register_setting( 'reading', $this->option_name_num_pages, array( $this, 'sanitize_num_pages' ) ); register_setting( 'reading', $this->option_name_num_pages, array( $this, 'sanitize_num_pages' ) );
register_setting( 'reading', $this->option_name_num_words, array( $this, 'sanitize_num_words' ) ); register_setting( 'reading', $this->option_name_num_words, array( $this, 'sanitize_num_words' ) );
add_settings_section( 'autopaging', __( 'Automatically Paginate Posts', 'autopaging' ), '__return_false', 'reading' ); add_settings_section( 'autopaging', __( 'Automatically Paginate Posts', 'autopaging' ), '__return_false', 'reading' );
add_settings_field( 'autopaging-post-types', __( 'Supported post types:', 'autopaging' ), array( $this, 'settings_field_post_types' ), 'reading', 'autopaging' ); add_settings_field( 'autopaging-post-types', __( 'Supported post types:', 'autopaging' ), array( $this, 'settings_field_post_types' ), 'reading', 'autopaging' );
add_settings_field( 'autopaging-num-pages', __( 'Number of pages to split content into:', 'autopaging' ), array( $this, 'settings_field_num_pages' ), 'reading', 'autopaging' ); add_settings_field( 'autopaging-paging-type', __( 'Split post by:', 'autopaging' ), array( $this, 'settings_field_paging_type' ), 'reading', 'autopaging' );
add_settings_field( 'autopaging-num-words', __( 'Number of words for each page:', 'autopaging' ), array( $this, 'settings_field_num_words' ), 'reading', 'autopaging' ); // add_settings_field( 'autopaging-num-pages', __( 'Number of pages to split content into:', 'autopaging' ), array( $this, 'settings_field_num_pages' ), 'reading', 'autopaging' );
// add_settings_field( 'autopaging-num-words', __( 'Number of words for each page:', 'autopaging' ), array( $this, 'settings_field_num_words' ), 'reading', 'autopaging' );
} }
/** /**
...@@ -187,6 +194,45 @@ class Automatically_Paginate_Posts { ...@@ -187,6 +194,45 @@ class Automatically_Paginate_Posts {
return $post_types_sanitized; return $post_types_sanitized;
} }
/**
* Render option to choose paging type and options for that type
*
* @uses get_option()
* @uses esc_attr()
* @uses checked()
* @return string
*/
public function settings_field_paging_type() {
$paging_type = get_option( $this->option_name_paging_type, $this->paging_type_default );
if ( ! in_array( $paging_type, $this->paging_types_allowed ) ) {
$paging_type = $this->paging_type_default;
}
$labels = array(
'pages' => __( 'Pages', 'autopaging' ),
'words' => __( 'Words', 'autopaging' ),
);
foreach ( $this->paging_types_allowed as $type ) :
$type_escaped = esc_attr( $type );
$func = 'settings_field_num_' . $type;
?>
<p><input type="radio" name="<?php echo esc_attr( $this->option_name_paging_type ); ?>" id="autopaging-type-<?php echo $type_escaped; ?>" value="<?php echo $type_escaped; ?>"<?php checked( $type, $paging_type ); ?> /> <label for="autopaging-type-<?php echo $type_escaped; ?>">
<strong><?php echo $labels[ $type ]; ?></strong>: <?php $this->{$func}(); ?>
</label></p>
<?php endforeach;
}
/**
* Validate chosen paging type against allowed values
*
* @param string
* @return string
*/
public function sanitize_paging_type( $type ) {
return in_array( $type, $this->paging_types_allowed ) ? $type : $this->paging_type_default;
}
/** /**
* Render dropdown for choosing number of pages to break content over * Render dropdown for choosing number of pages to break content over
* *
...@@ -218,7 +264,7 @@ class Automatically_Paginate_Posts { ...@@ -218,7 +264,7 @@ class Automatically_Paginate_Posts {
} }
/** /**
* Render dropdown for choosing number of pages to break content over * Render input field for specifying approximate number of words each page should contain
* *
* @uses get_option, apply_filters, esc_attr, selected * @uses get_option, apply_filters, esc_attr, selected
* @return string * @return string
...@@ -227,25 +273,26 @@ class Automatically_Paginate_Posts { ...@@ -227,25 +273,26 @@ class Automatically_Paginate_Posts {
$num_words = apply_filters( 'autopaging_num_words', get_option( $this->option_name_num_words ) ) $num_words = apply_filters( 'autopaging_num_words', get_option( $this->option_name_num_words ) )
?> ?>
<input name="<?php echo esc_attr( $this->option_name_num_words ); ?>" value="<?php echo esc_attr( $num_words ); ?>" size="4" /> <input name="<?php echo esc_attr( $this->option_name_num_words ); ?>" value="<?php echo esc_attr( $num_words ); ?>" size="4" />
<p class="description">If set, each page will contain approximately this many words, more or less depending on paragraph lengths, and Number of pages will be ignored.</p> <p class="description">If set, each page will contain approximately this many words, more or less depending on paragraph lengths.</p>
<?php <?php
} }
/** /**
* Sanitize number of words input. No fewer than 10 (by default, filterable by autopaging_min_num_words) * Sanitize number of words input. No fewer than 10 by default, filterable by autopaging_max_num_words
* *
* @param int $numwords * @param int $num_words
* @uses apply_filters * @uses apply_filters
* @return int * @return int
*/ */
public function sanitize_num_words( $num_words ) { public function sanitize_num_words( $num_words ) {
$num_words = apply_filters( 'autopaging_num_words', $num_words ); $num_words = absint( $num_words );
if( empty( $num_words ) ) if ( ! $num_words ) {
return ''; return 0;
}
return max( 1, (int) $num_words ); return max( $num_words, apply_filters( 'autopaging_min_num_words', 10 ) );
} }
/** /**
...@@ -336,71 +383,67 @@ class Automatically_Paginate_Posts { ...@@ -336,71 +383,67 @@ class Automatically_Paginate_Posts {
//Explode content at double (or more) line breaks //Explode content at double (or more) line breaks
$content = explode( "\r\n\r\n", $content ); $content = explode( "\r\n\r\n", $content );
//Aggregate paragraphs switch ( get_option( $this->option_name_paging_type, $this->paging_type_default ) ) {
if( !empty( $num_words ) ) { case 'words' :
$word_counter = 0; $word_counter = 0;
//Aggregate num_words paged content here // Count words per paragraph and break after the paragraph that exceeds the set threshold
$aggregate = array(); foreach ( $content as $index => $paragraph ) {
$aggregate_index = 0; $paragraph_words = count( preg_split( '/\s+/', strip_tags( $paragraph ) ) );
$word_counter += $paragraph_words;
//Collapse together paragraph according to number of words per page
foreach( $content as $index => $paragraph ) { if ( $word_counter >= $num_words ) {
$paragraph_words = count( preg_split( '/\s+/', strip_tags( $paragraph ) ) ); $content[ $index ] .= '<!--nextpage-->';
$word_counter = 0;
if( $word_counter + $paragraph_words / 2 >= $num_words ) { } else {
$aggregate_index++; continue;
$word_counter = 0; }
} }
if( !isset( $aggregate[$aggregate_index] ) ) unset( $word_counter );
$aggregate[$aggregate_index] = ''; unset( $index );
unset( $paragraph );
$aggregate[$aggregate_index] .= $paragraph . "\r\n\r\n"; unset( $paragraph_words );
$word_counter += $paragraph_words;
if( $word_counter > $num_words ) { break;
$aggregate_index++;
$word_counter = 0;
}
}
//Pretend the aggregated paragraphs based on max_words case 'pages' :
//are the original set default :
$content = $aggregate; //Count number of paragraphs content was exploded to
$count = count( $content );
//Override num_pages //Determine when to insert Quicktag
$num_pages = count( $content ); $insert_every = $count / $num_pages;
$insert_every_rounded = round( $insert_every );
unset( $word_counter ); //If number of pages is greater than number of paragraphs, put each paragraph on its own page
unset( $aggregate ); if ( $num_pages > $count ) {
unset( $aggregate_index ); $insert_every_rounded = 1;
} }
//Count number of paragraphs content was exploded to //Set initial counter position.
$count = count( $content ); $i = $count - 1 == $num_pages ? 2 : 1;
//Determine when to insert Quicktag //Loop through content pieces and append Quicktag as is appropriate
$insert_every = $count / $num_pages; foreach ( $content as $key => $value ) {
$insert_every_rounded = round( $insert_every ); if ( $key + 1 == $count ) {
break;
}
//If number of pages is greater than number of paragraphs, put each paragraph on its own page if ( ( $key + 1 ) == ( $i * $insert_every_rounded ) ) {
if ( $num_pages > $count ) $content[ $key ] = $content[ $key ] . '<!--nextpage-->';
$insert_every_rounded = 1; $i++;
}
}
//Set initial counter position. //Clean up
$i = $count - 1 == $num_pages ? 2 : 1; unset( $count );
unset( $insert_every );
unset( $insert_every_rounded );
unset( $key );
unset( $value );
//Loop through content pieces and append Quicktag as is appropriate
foreach( $content as $key => $value ) {
if ( $key + 1 == $count )
break; break;
if ( ( $key + 1 ) == ( $i * $insert_every_rounded ) ) {
$content[ $key ] = $content[ $key ] . '<!--nextpage-->';
$i++;
}
} }
//Reunite content //Reunite content
...@@ -408,17 +451,11 @@ class Automatically_Paginate_Posts { ...@@ -408,17 +451,11 @@ class Automatically_Paginate_Posts {
//And, overwrite the original content //And, overwrite the original content
$the_post->post_content = $content; $the_post->post_content = $content;
//Clean up
unset( $count );
unset( $insert_every );
unset( $insert_every_rounded );
unset( $key );
unset( $value );
} }
//Lastly, clean up. //Lastly, clean up.
unset( $num_pages ); unset( $num_pages );
unset( $num_words );
unset( $content ); unset( $content );
unset( $count ); unset( $count );
} }
......
...@@ -3,8 +3,8 @@ Contributors: ethitter, thinkoomph, bendoh ...@@ -3,8 +3,8 @@ Contributors: ethitter, thinkoomph, bendoh
Donate link: Donate link:
Tags: paginate, nextpage, Quicktag Tags: paginate, nextpage, Quicktag
Requires at least: 3.4 Requires at least: 3.4
Tested up to: 3.8 Tested up to: 3.9
Stable tag: 0.1 Stable tag: 0.2
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html License URI: http://www.gnu.org/licenses/gpl-2.0.html
...@@ -40,8 +40,10 @@ You can also use the filter `autopaging_post_types` to add support by appending ...@@ -40,8 +40,10 @@ You can also use the filter `autopaging_post_types` to add support by appending
= What filters does this plugin include? = = What filters does this plugin include? =
* `autopaging_post_types` - modify the post types supported by this plugin. Will override the values set under Settings > Reading. * `autopaging_post_types` - modify the post types supported by this plugin. Will override the values set under Settings > Reading.
* `autopaging_num_pages_default` - modify the default number of pages over which a post is displayed. Will override the value set under Settings > Reading. * `autopaging_num_pages_default` - modify the default number of pages over which a post is displayed. Will override the value set under Settings > Reading.
* `autopaging_max_num_pages` - override the maximum number of pages available in the settings page dropdown. * `autopaging_max_num_pages` - override the maximum number of pages available in the settings page dropdown when the paging type is "pages".
* `autopaging_max_num_words` - override the minimum number of words allowed per page page when the paging type is "words".
* `autopaging_num_pages` - change the number of pages content is displayed on at runtime. Filter provides access to the full post object in addition to the number of pages. * `autopaging_num_pages` - change the number of pages content is displayed on at runtime. Filter provides access to the full post object in addition to the number of pages.
* `autopaging_num_words` - change the number of words displayed per page at runtime. Filter provides access to the full post object in addition to the number of words.
== Changelog == == Changelog ==
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment