Skip to content

Instantly share code, notes, and snippets.

@HowdyMcGee
Last active August 31, 2017 20:15
Show Gist options
  • Save HowdyMcGee/7c6296b81b87ad1abafbd77ee0be1633 to your computer and use it in GitHub Desktop.
Save HowdyMcGee/7c6296b81b87ad1abafbd77ee0be1633 to your computer and use it in GitHub Desktop.
Count / Save / Add Wordcount Column to Pages
<?php
/**
* Plugin Name: Word Count Tracker
* Description: Simply saves the word count with the post.
* Version: 1.0.0
*/
if( ! defined( 'ABSPATH' ) ) {
die( 'There was a HOLE here. It\'s gone now.' );
}
/**
* Count number of words in a given string
* @link http://php.net/manual/en/function.str-word-count.php#107363
*
* @param String $str - The given string of content
*
* @return Integer $count - Number of counted words in given string
*/
function wpse_wct_word_count( $str ) {
$count = 0;
if( ! empty( $str ) ) {
$content = strip_tags( $str ); // Strip any HTML so they're not counted
$word_arr = array_filter( preg_split( '~[^\p{L}\p{N}\']+~u', $content ) ); // Retrieve an array of words based on our content
$count = count( $word_arr ); // Count items in array
}
/**
* Allow modification of count variable
*
* @param Integer $count - Number of words expected to be returned
* @param String $str - Unmodified given user string
*
* @return $count
*/
$count = apply_filters( 'wpse_wct_count_modify', $count, $str );
return intval( $count );
}
/**
* Get acceptable post types
*
* @return Array $types - Array of WordPress post types
*/
function wpse_wct_get_post_types() {
/**
* Allow modification of acceptable post types
*
* @param Array of default post types
*
* @return Array of acceptable post types
*/
return apply_filters( 'wpse_wct_accepted_post_types', array( 'post', 'page' ) );
}
/**
* Save word count as postmeta '_wct_word_count'
*
* @param Integer $post_id - The saved Post ID
* @param WP_Post $post - The saved WP_Post Object
*
* @return void
*/
function wpse_wct_save_post( $post_id, $post ) {
// If we're not in the right place, bailout
if( ! is_object( $post ) || wp_is_post_autosave( $post ) || wp_is_post_revision( $post ) ) {
return $post_id;
}
// Get Acceptable post types
$acceptable_post_types = wpse_wct_get_post_types();
// If this post is of an acceptable type
if( ! empty( $acceptable_post_types ) && in_array( $post->post_type, $acceptable_post_types ) ) {
update_post_meta( $post->ID, '_wct_word_count', wpse_wct_word_count( $post->post_content ) );
}
}
add_action( 'save_post', 'wpse_wct_save_post', 10, 2 );
/**
* Admin Initialization - setup admin hooks
*
* @return void
*/
function wpse_wct_admin_hooks() {
// Get Acceptable post types
$acceptable_post_types = wpse_wct_get_post_types();
// Ensure we have an workable array
if( ! empty( $acceptable_post_types ) ) {
// Loop through array of post types and assign hooks
foreach( $acceptable_post_types as $post_type ) {
// Add in new word count column
add_filter( "manage_edit-{$post_type}_columns", 'wpse_wct_word_count_col' );
// Display post word count
add_action( "manage_{$post_type}_posts_custom_column", 'wpse_wct_word_count_col_display', 10, 2 );
// Allow word count column to be sortable
add_filter( "manage_edit-{$post_type}_sortable_columns", 'wpse_wct_word_count_col_sort' );
}
}
}
add_action( 'admin_init', 'wpse_wct_admin_hooks' );
/**
* Add the new word count column
*
* @hook_added wpse_wct_admin_hooks()
*
* @param Array $cols - Array of columns : array( 'col-slug', 'Column Name' )
*
* @return Array $cols
*/
function wpse_wct_word_count_col( $cols ) {
$cols['wct-count'] = __( 'Word Count' );
return $cols;
}
/**
* Display the post word count
*
* @hook_added wpse_wct_admin_hooks()
*
* @param String $col_name - The current columns name
* @param Integer $post_id - The current Post ID
*
* @return void
*/
function wpse_wct_word_count_col_display( $col_name, $post_id ) {
$post = get_post( $post_id );
// Ensure we're displaying the correct column
if( is_object( $post ) && 'wct-count' === $col_name ) {
$count = get_post_meta( $post_id, '_wct_word_count', true ); // Get word count
// Check if the count exists
if( empty( $count ) && ! empty( $post->post_content ) ) { // Doesn't exist
$count = wpse_wct_word_count( $post->post_content ); // Get word count
update_post_meta( $post_id, '_wct_word_count', $count ); // Set word count
}
// Display word count
printf( _n( '%1$s word', '%1$s words', $count ), number_format( $count ) );
}
}
/**
* Allow WordPress to sort on the column
*
* @hook_added Function wpse_wct_admin_hooks()
*
* @param Array $cols - Sortable admin columns
*
* @return Array $cols - Sortable admin columns
*/
function wpse_wct_word_count_col_sort( $cols ) {
// Append columns
$cols['wct-count'] = 'word_count';
return $cols;
}
/**
* Set sortable query
*
* @param WP_Query Object $query - Current admin WP_Query
*
* @return void
*/
function wpse_wct_pre_get_posts( $query ) {
// Only run on the admin side
if( ! is_admin() ) {
return;
}
// Ensure we have our sortable var set
if( 'word_count' !== $query->get( 'orderby' ) ) {
return;
}
// Get Acceptable post types
$acceptable_post_types = wpse_wct_get_post_types();
// Get current post type
$current_post_type = $query->get( 'post_type' );
// Ensure this post type is an acceptable one
if( ! empty( $acceptable_post_types ) && in_array( $current_post_type, $acceptable_post_types ) ) {
$query->set( 'meta_key', '_wct_word_count' ); // Set metakey
$query->set( 'orderby', 'meta_value_num' ); // Order by meta value as a number
}
}
add_action( 'pre_get_posts', 'wpse_wct_pre_get_posts' );
/**
* Change custom admin column width
* Ugh...
*
* @retun void
*/
function wpse_wct_admin_col_styles() {
?>
<style>
.column-wct-count {}
</style>
<?php
}
add_action( 'admin_head', 'wpse_wct_admin_col_styles' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment