Skip to content

Instantly share code, notes, and snippets.

@philipjohn
Created September 25, 2018 13:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philipjohn/7567ecea12fd25085010b1f83ce4c4ed to your computer and use it in GitHub Desktop.
Save philipjohn/7567ecea12fd25085010b1f83ce4c4ed to your computer and use it in GitHub Desktop.
A WordPress plugin for tracking the time to publish for posts.
<?php
/*
Plugin Name: Time to Publish
Plugin URI: https://vip.wordpress.com
Description: Track "Time to Publish" on your WordPress site.
Version: 0.1.0
Author: WordPress.com VIP
Author URI: http://vip.wordpress.com
Text Domain: time_to_publish
Domain Path: /languages
*/
/**
* Track the "Time to Publish" - how long it takes for editors/reporters to take
* an article from scratch to fully published.
*/
function ttp_action_transition_post_status( $new_status, $old_status, $post ) {
// We've already logged published posts so let's ignore them.
if ( 'publish' === $old_status ) {
return;
}
// We only want to track when a post moves to published.
if ( 'publish' !== $new_status ) {
return;
}
// Log the TTP.
ttp_log_time_to_publish( $post );
}
add_action( 'transition_post_status', 'ttp_action_transition_post_status', 10, 3 );
function ttp_log_time_to_publish( WP_Post $post ) {
// Double-check we haven't already logged this post. For example, maybe it
// got published, logged, then moved back into draft and re-published.
$logged = get_post_meta( $post->ID, 'ttp_time_to_publish', true );
if ( ! empty( $logged ) ) {
return;
}
// We need to grab the very first revision, which should be an auto-draft.
// The time of this draft should be the very first time the post editor was
// opened for the post that is currently being published for the first time.
$revisions = wp_get_post_revisions( $post->ID );
if ( empty( $revisions ) ) {
// There are no revisions. Set the meta key and return.
add_post_meta( $post->ID, 'ttp_time_to_publish', 0 );
return false;
}
// Grab the oldest revision.
$oldest_revision = array_pop( $revisions );
// Grab the timestamp for the oldest revision.
$start = strtotime( $oldest_revision->post_date );
// Grab the timestamp for our published post.
$published = strtotime( $post->post_date );
// *drumroll* Time to publish.
$time_to_publish = $published - $start;
// Save it in meta.
add_post_meta( $post->ID, 'ttp_time_to_publish', $time_to_publish );
return $time_to_publish;
}
if ( defined( 'WP_CLI' ) && WP_CLI ):
/**
* Command to run through posts and log Time to Publish.
*/
function ttp_log_cli_command( $args, $assoc_args ) {
$args = wp_parse_args(
$args,
[
'posts_per_page' => 100,
'post_status' => 'publish',
'post_type' => 'post',
'meta_query' => [
[
'key' => 'ttp_time_to_publish',
'compare' => 'NOT EXISTS',
]
],
]
);
$posts = get_posts( $args );
if ( ! empty( $posts ) ) {
foreach ( $posts as $post ) {
$ttp = ttp_log_time_to_publish( $post );
WP_CLI::line(
sprintf(
'Logging TTP of %d for post ID %d',
$ttp,
$post->ID
)
);
}
} else {
WP_CLI::line('No posts to log.');
}
}
WP_CLI::add_command( 'time-to-publish log', 'ttp_log_cli_command' );
function ttp_report_time_to_publish( $args, $assoc_args ) {
$args = wp_parse_args(
$args,
[
'time-period' => 'last hour',
]
);
// Define some acceptable time period values. Key is the accepted value for
// 'time-period' and the value is the value for 'date_query' in WP_Query,
// using strtotime() strings.
$time_periods = [
'last hour' => [ 'after' => '-1 hour' ],
'last 4 hours' => [ 'after' => '-4 hours' ],
'last 8 hours' => [ 'after' => '-8 hours' ],
'last 12 hours' => [ 'after' => '-12 hours' ],
'last 24 hours' => [ 'after' => '-24 hours' ],
'last 2 days' => [ 'after' => '-48 hours' ],
'last 5 days' => [ 'after' => '-120 hours' ],
'last 7 days' => [ 'after' => '-168 hours' ],
'this week' => [ 'after' => 'monday this week' ],
'last week' => [
'after' => 'monday last week',
'before' => 'sunday 23:59:59 last week',
],
'this month' => [ 'after' => 'first day of this month 00:00:00' ],
'last month' => [
'after' => 'first day of last month 00:00:00',
'before' => 'last day of last month 23:59:59',
],
];
// Check the chosen time period is valid.
if ( ! array_key_exists( $args['time-period'], $time_periods ) ) {
WP_CLI::error(
sprintf(
'"%s" is not a valid time period. Please choose one of: %s.',
esc_attr( $args['time-period'] ),
implode( ', ', array_keys( $time_periods ) )
)
);
}
WP_CLI::line( sprintf( 'Looking at posts from the %s', $args['time-period'] ) );
$query_args = [
'post_type' => 'post',
'post_status' => 'publish',
'meta_query' => [
[
'key' => 'ttp_time_to_publish',
'compare' => 'EXISTS',
],
],
'date_query' => $time_periods[ $args['time-period'] ],
];
$data = [];
$total_time_to_publish = 0;
$posts = get_posts( $query_args );
WP_CLI::line( sprintf( 'Found %d posts', count( $posts ) ) );
if ( ! empty( $posts ) ) {
$progress = \WP_CLI\Utils\make_progress_bar( 'Calculating TTP', count( $posts ) );
foreach ( $posts as $post ) {
$ttp = get_post_meta( $post->ID, 'ttp_time_to_publish', true );
$data[] = [
'post_id' => $post->ID,
'time_to_publish' => $ttp,
];
$total_time_to_publish += $ttp;
$progress->tick();
}
$progress->finish();
// Grab and report average time to publish.
$avg_ttp = $total_time_to_publish / count( $posts );
WP_CLI\Utils\format_items( 'table', $data, array( 'post_id', 'time_to_publish' ) );
WP_CLI::line(
sprintf(
'Average time to publish: %ds',
$avg_ttp
)
);
}
}
WP_CLI::add_command( 'time-to-publish report', 'ttp_report_time_to_publish' );
endif;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment