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

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 {
private $post_types_default = array( 'post' );
private $num_pages;
private $num_pages_default = 2;
private $num_words_default = '';
private $paging_type_default = 'pages';
private $num_pages_default = 2;
private $num_words_default = '';
//Ensure option names match values in this::uninstall
private $option_name_post_types = 'autopaging_post_types';
private $option_name_num_pages = 'autopaging_num_pages';
private $option_name_num_words = 'autopaging_num_words';
private $paging_types_allowed = array( 'pages', 'words' );
// Ensure option names match values in this::uninstall
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';
......@@ -94,6 +98,7 @@ class Automatically_Paginate_Posts {
*/
public function uninstall() {
delete_option( 'autopaging_post_types' );
delete_option( 'autopaging_paging_type' );
delete_option( 'autopaging_num_pages' );
delete_option( 'autopaging_num_words' );
}
......@@ -122,13 +127,15 @@ class Automatically_Paginate_Posts {
*/
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_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_words, array( $this, 'sanitize_num_words' ) );
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-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' );
add_settings_field( 'autopaging-paging-type', __( 'Split post by:', 'autopaging' ), array( $this, 'settings_field_paging_type' ), '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 {
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
*
......@@ -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
* @return string
......@@ -227,25 +273,26 @@ class Automatically_Paginate_Posts {
$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" />
<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
}
/**
* 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
* @return int
*/
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 ) )
return '';
if ( ! $num_words ) {
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 {
//Explode content at double (or more) line breaks
$content = explode( "\r\n\r\n", $content );
//Aggregate paragraphs
if( !empty( $num_words ) ) {
$word_counter = 0;
//Aggregate num_words paged content here
$aggregate = array();
$aggregate_index = 0;
//Collapse together paragraph according to number of words per page
foreach( $content as $index => $paragraph ) {
$paragraph_words = count( preg_split( '/\s+/', strip_tags( $paragraph ) ) );
if( $word_counter + $paragraph_words / 2 >= $num_words ) {
$aggregate_index++;
$word_counter = 0;
switch ( get_option( $this->option_name_paging_type, $this->paging_type_default ) ) {
case 'words' :
$word_counter = 0;
// Count words per paragraph and break after the paragraph that exceeds the set threshold
foreach ( $content as $index => $paragraph ) {
$paragraph_words = count( preg_split( '/\s+/', strip_tags( $paragraph ) ) );
$word_counter += $paragraph_words;
if ( $word_counter >= $num_words ) {
$content[ $index ] .= '<!--nextpage-->';
$word_counter = 0;
} else {
continue;
}
}
if( !isset( $aggregate[$aggregate_index] ) )
$aggregate[$aggregate_index] = '';
$aggregate[$aggregate_index] .= $paragraph . "\r\n\r\n";
$word_counter += $paragraph_words;
unset( $word_counter );
unset( $index );
unset( $paragraph );
unset( $paragraph_words );
if( $word_counter > $num_words ) {
$aggregate_index++;
$word_counter = 0;
}
}
break;
//Pretend the aggregated paragraphs based on max_words
//are the original set
$content = $aggregate;
case 'pages' :
default :
//Count number of paragraphs content was exploded to
$count = count( $content );
//Override num_pages
$num_pages = count( $content );
//Determine when to insert Quicktag
$insert_every = $count / $num_pages;
$insert_every_rounded = round( $insert_every );
unset( $word_counter );
unset( $aggregate );
unset( $aggregate_index );
}
//If number of pages is greater than number of paragraphs, put each paragraph on its own page
if ( $num_pages > $count ) {
$insert_every_rounded = 1;
}
//Count number of paragraphs content was exploded to
$count = count( $content );
//Set initial counter position.
$i = $count - 1 == $num_pages ? 2 : 1;
//Determine when to insert Quicktag
$insert_every = $count / $num_pages;
$insert_every_rounded = round( $insert_every );
//Loop through content pieces and append Quicktag as is appropriate
foreach ( $content as $key => $value ) {
if ( $key + 1 == $count ) {
break;
}
//If number of pages is greater than number of paragraphs, put each paragraph on its own page
if ( $num_pages > $count )
$insert_every_rounded = 1;
if ( ( $key + 1 ) == ( $i * $insert_every_rounded ) ) {
$content[ $key ] = $content[ $key ] . '<!--nextpage-->';
$i++;
}
}
//Set initial counter position.
$i = $count - 1 == $num_pages ? 2 : 1;
//Clean up
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;
if ( ( $key + 1 ) == ( $i * $insert_every_rounded ) ) {
$content[ $key ] = $content[ $key ] . '<!--nextpage-->';
$i++;
}
}
//Reunite content
......@@ -408,17 +451,11 @@ class Automatically_Paginate_Posts {
//And, overwrite the original content
$the_post->post_content = $content;
//Clean up
unset( $count );
unset( $insert_every );
unset( $insert_every_rounded );
unset( $key );
unset( $value );
}
//Lastly, clean up.
unset( $num_pages );
unset( $num_words );
unset( $content );
unset( $count );
}
......
......@@ -3,8 +3,8 @@ Contributors: ethitter, thinkoomph, bendoh
Donate link:
Tags: paginate, nextpage, Quicktag
Requires at least: 3.4
Tested up to: 3.8
Stable tag: 0.1
Tested up to: 3.9
Stable tag: 0.2
License: GPLv2 or later
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
= 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_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_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 ==
......
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