From 42297f797f1c4d8e85b9924785c10b231cd5c870 Mon Sep 17 00:00:00 2001 From: Erick Hitter <ehitter@gmail.com> Date: Mon, 3 Mar 2014 19:29:49 -0800 Subject: [PATCH] Version 0.2: paging by word Build on work by @bendoh merged in f96afe5397 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. --- automatically-paginate-posts.php | 191 ++++++++++++++++++------------- readme.txt | 8 +- 2 files changed, 119 insertions(+), 80 deletions(-) diff --git a/automatically-paginate-posts.php b/automatically-paginate-posts.php index 611d7f7..6b506ab 100644 --- a/automatically-paginate-posts.php +++ b/automatically-paginate-posts.php @@ -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 ); } diff --git a/readme.txt b/readme.txt index 306b06f..f0b45c4 100644 --- a/readme.txt +++ b/readme.txt @@ -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 == -- GitLab