Plugin Directory

Changeset 3298419


Ignore:
Timestamp:
05/22/2025 03:55:12 AM (9 months ago)
Author:
JonBishop
Message:

Preparing for 2.0 release: updated trunk and assets

Location:
post-admin-word-count
Files:
5 added
4 edited

Legend:

Unmodified
Added
Removed
  • post-admin-word-count/trunk/post-admin-word-count.php

    r585191 r3298419  
    11<?php
    22
    3 /*
    4   Plugin Name: Post Admin Word Count
    5   Plugin URI: http://www.jonbishop.com/downloads/wordpress-plugins/post-word-count/
    6   Description: Adds a sortable column to the admin's post manager, displaying the word count for each post.
    7   Version: 1.2
    8   Author: Jon Bishop
    9   Author URI: http://www.jonbishop.com
    10   License: GPL2
     3/**
     4 * Plugin Name: Post Admin Word Count
     5 * Plugin URI: https://jonbishop.com/downloads/wordpress-plugins/post-admin-word-count/
     6 * Description: Adds a sortable column to the admin post list displaying the word count for each post.
     7 * Version: 2.0
     8 * Author: Jon Bishop
     9 * Author URI: https://www.jonbishop.com
     10 * License: GPL2+
     11 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
     12 * Text Domain: post-admin-word-count
    1113 */
    1214
    13 class PostAdminWordCount {
     15if (!defined('ABSPATH')) {
     16    exit;
     17}
    1418
    15     function init() {
    16         if (is_admin()) {
    17             add_filter('manage_edit-post_sortable_columns', array(&$this, 'pwc_column_register_sortable'));
    18             add_filter('posts_orderby', array(&$this, 'pwc_column_orderby'), 10, 2);
    19             add_filter("manage_posts_columns", array(&$this, "pwc_columns"));
    20             add_action("manage_posts_custom_column", array(&$this, "pwc_column"));
    21             add_action("admin_footer-edit.php",array(&$this, "pwc_update_date"));
    22             add_action("admin_head-edit.php",array(&$this, "pwc_get_date"));
    23            
     19class Post_Admin_Word_Count
     20{
     21
     22    public function __construct()
     23    {
     24        add_action('init', function () {
     25            foreach (get_post_types(['public' => true], 'names') as $post_type) {
     26                if (in_array($post_type, ['attachment', 'wp_block', 'wp_template', 'wp_template_part'])) continue;
     27                add_filter("manage_{$post_type}_posts_columns", [$this, 'add_word_count_column']);
     28                add_action("manage_{$post_type}_posts_custom_column", [$this, 'render_word_count_column'], 10, 2);
     29                add_filter("manage_edit-{$post_type}_sortable_columns", [$this, 'make_column_sortable']);
     30            }
     31        });
     32
     33        add_action('admin_enqueue_scripts', [$this, 'enqueue_custom_stylesheet']);
     34
     35        add_action('pre_get_posts', [$this, 'handle_column_sorting']);
     36        add_action('save_post', [$this, 'update_word_count_meta'], 10, 2);
     37    }
     38
     39    /**
     40     * Enqueues a custom stylesheet for post types where this plugin is active.
     41     */
     42    public function enqueue_custom_stylesheet($hook_suffix)
     43    {
     44        global $post_type;
     45        if (in_array($post_type, ['post', 'page']) || post_type_supports($post_type, 'editor')) {
     46            wp_enqueue_style('post-admin-word-count-style', plugin_dir_url(__FILE__) . 'css/post-word-count-style.css');
    2447        }
    2548    }
    2649
    27     //=============================================
    28     // Add new columns to action post type
    29     //=============================================
    30     function pwc_columns($columns) {
    31         $columns["post_word_count"] = "Word Count";
     50    /**
     51     * Adds a new "Word Count" column to the Posts admin screen.
     52     */
     53    public function add_word_count_column($columns)
     54    {
     55        $columns['post_word_count'] = __('Words', 'post-admin-word-count');
    3256        return $columns;
    3357    }
    3458
    35     //=============================================
    36     // Add data to new columns of action post type
    37     //=============================================
    38     function pwc_column($column) {
    39         global $post, $pwc_last;
    40         if ("post_word_count" == $column) {
    41             // Grab a fresh word count
    42             $word_count = str_word_count($post->post_content);
    43             echo $word_count;
     59    /**
     60     * Outputs the word count for each post in the custom column.
     61     */
     62    public function render_word_count_column($column, $post_id)
     63    {
     64        if ($column === 'post_word_count') {
     65            $count = get_post_meta($post_id, '_post_word_count', true);
     66
     67            if ($count === '') {
     68                $post = get_post($post_id);
     69                $content = wp_strip_all_tags($post->post_content, true);
     70                $count = str_word_count($content);
     71                update_post_meta($post_id, '_post_word_count', $count);
     72            }
     73
     74            echo esc_html($count);
    4475        }
    4576    }
    4677
    47     //=============================================
    48     // Queries to run when sorting
    49     // new columns of action post type
    50     //=============================================
    51     function pwc_column_orderby($orderby, $wp_query) {
    52         global $wpdb;
    53 
    54         if ('post_word_count' == @$wp_query->query['orderby'])
    55             $orderby = "(SELECT CAST(meta_value as decimal) FROM $wpdb->postmeta WHERE post_id = $wpdb->posts.ID AND meta_key = '_post_word_count') " . $wp_query->get('order');
    56 
    57         return $orderby;
    58     }
    59 
    60     //=============================================
    61     // Make new columns to action post type sortable
    62     //=============================================
    63     function pwc_column_register_sortable($columns) {
     78    /**
     79     * Registers the column as sortable in the admin.
     80     */
     81    public function make_column_sortable($columns)
     82    {
    6483        $columns['post_word_count'] = 'post_word_count';
    6584        return $columns;
    6685    }
    67    
    68     function pwc_get_date(){
    69         global $post, $pwc_last;
    70         // Check last updated
    71         $pwc_last = get_option('pwc_last_checked');
    7286
    73         // Check to make sure we have a post and post type
    74         if ( $post && $post->post_type ){
    75            
    76             // Grab all posts with post type
    77             $args = array(
    78                 'post_type' => $post->post_type,
    79                 'posts_per_page' => -1
    80                 );
    81 
    82             // Grab the posts
    83             $post_list = new WP_Query($args);
    84             if ( $post_list->have_posts() ) : while ( $post_list->have_posts() ) : $post_list->the_post();
    85                
    86                 // Grab a fresh word count
    87                 $word_count = str_word_count($post->post_content);
    88 
    89                 // If post has been updated since last check
    90                 if ($post->post_modified > $pwc_last || $pwc_last == "") {
    91                     // Grab word count from post meta
    92                     $saved_word_count = get_post_meta($post->ID, '_post_word_count', true);
    93                     // Check if new wordcount is different than old word count
    94                     if ($saved_word_count != $word_count || $saved_word_count == "") {
    95                         // Update word count in post meta
    96                         update_post_meta($post->ID, '_post_word_count', $word_count, $saved_word_count);
    97                     }
    98                 }
    99             endwhile;
    100             endif;
    101 
    102             // Let WordPress do it's thing
    103             wp_reset_query();
    104         }
    105     }
    106    
    107     function pwc_update_date(){
    108         // Save the last time this page was generated
    109         $current_date = current_time('mysql');
    110         update_option('pwc_last_checked', $current_date);
     87    /**
     88     * Adjusts query to sort by word count meta key.
     89     */
     90    public function handle_column_sorting($query)
     91    {
     92        if (is_admin() && $query->is_main_query() && $query->get('orderby') === 'post_word_count') {
     93            $query->set('meta_key', '_post_word_count');
     94            $query->set('orderby', 'meta_value_num');
     95        }
    11196    }
    11297
     98    /**
     99     * Updates the word count meta whenever a post is saved.
     100     */
     101    public function update_word_count_meta($post_id, $post)
     102    {
     103        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
     104        if (!current_user_can('edit_post', $post_id)) return;
     105        if (!post_type_supports($post->post_type, 'editor')) return;
     106        if (in_array($post->post_type, ['attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'wp_block', 'wp_template', 'wp_template_part'])) return;
     107
     108        $content = wp_strip_all_tags($post->post_content, true);
     109        $word_count = str_word_count($content);
     110        update_post_meta($post_id, '_post_word_count', $word_count);
     111    }
    113112}
    114113
    115 $postAdminWordCount = new PostAdminWordCount();
    116 $postAdminWordCount->init();
    117 ?>
     114new Post_Admin_Word_Count();
  • post-admin-word-count/trunk/readme.txt

    r585191 r3298419  
    11=== Post Admin Word Count ===
    22Contributors: JonBishop
    3 Donate link: http://www.jonbishop.com/donate/
    4 Tags: wordcount, word count, words, count, column, admin, sortable, posts
    5 Requires at least: 3.0
    6 Tested up to: 3.4.1
    7 Stable tag: 1.2
     3Donate link: https://jonbishop.com/donate/
     4Tags: word count, post word count, admin columns, custom post types, content analysis
     5Requires at least: 5.0
     6Tested up to: 6.8
     7Requires PHP: 7.2
     8Stable tag: 2.0
     9License: GPLv2
    810
    9 Adds a sortable column to the admin's post manager, displaying the word count for each post.
     11Adds a sortable word count column to the admin post list for all public post types. Efficient, lightweight and built with modern best practices.
    1012
    1113== Description ==
    1214
    13 Post Word Count adds a sortable column to the admin's post manager, displaying the word count for each post.
    14 
    15 I often create new drafts in WordPress every time I get an idea to blog. The problem was I had no easy way to see which drafts I had already started working on. This plugin allows me to sort all of my posts, including my drafts, by the posts word count.
     15Post Admin Word Count adds a sortable "Words" column to the WordPress admin for all public post types. This lightweight plugin automatically calculates and stores word counts when posts are saved or viewed in the admin, ensuring performance and accuracy without scanning your entire site. It supports custom post types, integrates cleanly with the WordPress admin UI and adheres to modern coding standards. Ideal for publishers, bloggers and content editors who want quick insight into post length directly from the dashboard.
    1616
    1717== Installation ==
    1818
    19 1. Upload the 'post-word-count' folder to the '/wp-content/plugins/' directory
    20 1. Activate the plugin through the 'Plugins' menu in WordPresss
     191. Upload the plugin files to the `/wp-content/plugins/post-admin-word-count` directory, or install the plugin through the WordPress plugin repository.
     202. Activate the plugin through the 'Plugins' screen in WordPress.
     213. Go to the 'Posts' screen (or any supported post type) in your WordPress admin to see the new "Words" column.
     224. Click the "Words" column header to sort posts by word count.
     23
     24== Frequently Asked Questions ==
     25
     26= Does this plugin work with custom post types? =
     27Yes. The plugin supports all public post types that use the WordPress editor, including custom post types.
     28
     29= Will it calculate word counts for existing posts? =
     30Yes. Word counts are calculated and saved the first time you view the post list if they don’t already exist.
     31
     32= Is the word count updated automatically? =
     33Yes. Word counts are updated automatically whenever a post is saved or updated.
     34
     35= Does this plugin impact site performance? =
     36No. It only calculates word counts when needed and does not run any bulk operations on page load.
     37
     38= Can I sort posts by word count? =
     39Yes. The "Words" column is sortable just like date or title.
     40
    2141
    2242== Screenshots ==
     
    2545
    2646== Changelog ==
     47
     48The current version is 2.0 (2025.05.21)
     49
     50= 2.0 =
     51* Complete plugin rewrite with modern best practices
     52* Word count column now supports all public post types (excluding attachments and system types)
     53* Word counts are lazily saved for existing posts, improving performance and accuracy
     54* Replaced legacy raw SQL with native WordPress query handling
     55* Added sortable column support across custom post types
     56* Improved security, escaping and overall code quality
    2757
    2858= 1.2 =
Note: See TracChangeset for help on using the changeset viewer.