gschoppe
12/22/2017 - 3:31 PM

Upcoming Drafts Alert

Sends regular reminder emails to all users with draft posts scheduled for less than X days in the future.

Usage:

  1. Install and activate WP Utility Script Runner (https://wordpress.org/plugins/wp-utility-script-runner/)
  2. Create a "utilities" subfolder in your theme directory
  3. Place this file in the utilities folder
  4. Go to Tools->Utility Scripts and click "Manage Scripts"
  5. Activate the "Upcoming Drafts Alert" script then click "Schedule"
  6. Expand the "Upcoming Drafts Alert" section, and select your threshold and scheduling options, then click schedule
<?php if(!defined('ABSPATH')) { die(); } // This line ensures that the script is not run directly
/**
 * Utility Name: Upcoming Drafts Alert
 * Description: Sends an email to blog authors with upcoming or overdue posts
 * Author: Greg Schoppe
 * Author URI: https://gschoppe.com
 * Supports: input, cron
 * Version: 1.0.0
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 **/

function uda_utility_input_html( $html ) {
	ob_start();
	?>
	<label>
		<span>Alert Threshold (in days): </span>
		<input type="number" name="alert_threshold" value="7" required min="1" step="1">
	</label>
	<?php
	return ob_get_clean();
}
add_filter('wp_util_input_html', 'uda_utility_input_html');

// this filter contains the actual meat and potatoes of your script
// ---
// $legacy will always be an empty string, but it needed to support a
// legacy version of the utility script format
// ---
// $state is an aritrary value you can return from the previous run of the script,
// and which will be passed through to the next run. One common use is to
// store an offset for paginated database queries. State will be falsy for the
// initial run. It is recommended to store data in state as keys in an array, to
// ensure no overlap with the reserved values of 'complete' and 'error' which
// trigger exiting the script
// ---
// $atts is an array, containing your input form fields, by name, EXCEPT file inputs
// ---
// $files contains an array of any file inputs that were included in the input form
// ---
function uda_utility_script( $legacy, $state, $atts, $files ) {
	$per_page        = 20;
	$alert_threshold = 7;
	$offset          = 0;
	$drafts          = array();
	if( !empty( $state['offset'] ) ) {
		$offset = $state['offset'];
	}
	if( !empty( $state['drafts'] ) ) {
		$drafts = $state['drafts'];
	}
	if( !empty( $atts['alert_threshold'] ) ) {
		$alert_threshold = intval( $atts['alert_threshold'] );
	}
	$retval = array(
		'state'   => 'error',
		'message' => 'an unknown error has occurred'
	);
	$args = array(
		'posts_per_page' => $per_page,
		'post_status' => 'draft',
		'post_type' => 'post',
		'date_query' => array(
			array(
				'before'    => '+' . $alert_threshold . ' days',
			)
		),
		'offset' => $offset
	);
	$posts = get_posts( $args );
	if( $posts ) {
		$now = time();
		foreach( $posts as $post ) {
			$author     = $post->post_author;
			$date_parts = explode( ' ', $post->post_date );
			$date = $date_parts[0];
			$postDate = strtotime( $post->post_date );
			$time_grp = 'future';
			if( $postDate <= $now ) {
				$time_grp = 'past';
			}
			$entry = array(
				'id'    => $post->ID,
				'title' => $post->post_title,
				'link'  => get_edit_post_link( $post->ID ),
				'date'  => $date
			);
			if( !isset( $drafts[$author] ) ) {
				$drafts[$author] = array(
					'past'   => array(),
					'future' => array()
				);
			}
			$drafts[$author][$time_grp][] = $entry;
		}
		return array(
			'state' => array(
				'offset' => $offset + $per_page,
				'drafts' => $drafts
			),
			'message' => "Parsed " . ( $offset + $per_page ) . " Draft Posts."
		);
	} else {
		add_filter( 'wp_mail_content_type','uda_wp_mail_set_content_type' );
		foreach( $drafts as $author => $author_drafts ) {
			$user    = get_userdata($author);
			$email   = $user->user_email;
			$subject = "Outstanding Draft posts for " . get_bloginfo('name');
			$message = uda_generate_email_message( $author_drafts );
			wp_mail( $email, $subject, $message );
		}
		return array(
			'state'   => 'complete',
			'message' => "Messages Sent"
		);
	}
}
add_filter('wp_util_script', 'uda_utility_script', 10, 4);

function uda_generate_email_message( $drafts ) {
	ob_start();
	?>
	<p>
		You're receiving this email because you have unpublished posts on
		<?php echo get_bloginfo('name') ?> that are nearing or have passed
		their publish date. Please check the status of the posts listed below.
	</p>
	<?php
	if( count( $drafts['future'] ) ) {
		?>
		<h2>Upcoming Draft Posts</h2>
		<table>
		<?php
		foreach( $drafts['future'] as $draft ) {
			?>
			<tr>
				<td><?php echo $draft['date']; ?></td><td><a href="<?php echo esc_attr( $draft['link'] ); ?>"><?php echo $draft['title']; ?></a></td>
			</tr>
			<?php
		}
		?>
		</table>
		<?php
	}
	if( count( $drafts['past'] ) ) {
		?>
		<h2>Past Due Draft Posts</h2>
		<table>
		<?php
		foreach( $drafts['past'] as $draft ) {
			?>
			<tr>
				<td><?php echo $draft['date']; ?></td><td><a href="<?php echo esc_attr( $draft['link'] ); ?>"><?php echo $draft['title']; ?></a></td>
			</tr>
			<?php
		}
		?>
		</table>
		<?php
	}
	return ob_get_clean();
}

function uda_wp_mail_set_content_type(){
	return "text/html";
}