-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from dartiss/develop
First release
- Loading branch information
Showing
11 changed files
with
766 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,19 @@ | ||
# Draft Concluder | ||
|
||
Based on [an idea by John Blackbourn](https://twitter.com/johnbillion/status/1314494422529331203), this plugin is designed to punish those who leave draft posts unloved. Although I've not implemented the suggestion of making the plugin un-uninstallable, the rest of John's ideas are here, with more to boot. | ||
Based on [an idea by John Blackbourn](https://twitter.com/johnbillion/status/1314494422529331203), this plugin is designed to be a reminder to those who leave draft posts unloved. And, yes, all of John's ideas are here, with more to boot. | ||
|
||
* Send emails out on a daily or weekly schedule | ||
* Look for draft posts and/or pages | ||
* Send emails out on a daily or weekly schedule and at a time that you'd prefer | ||
* Look for draft pages as well as posts, if you like. Or just pages, if that's what you want. We won't judge | ||
* Target those drafts that were created more than a specific time period ago, or have not been updated for a while | ||
* Each user, who has drafts that then reminding about, will receive an email. No, they can't unsubscribe from them | ||
* Each email will show the number of drafts, along with a reminder of each of them | ||
* Optional ability to prevent the plugin from being deactivated (allow you to avoid the temptation to do so rather than, you know, deal with the drafts) | ||
* Debug features to allow to verify what's being sent | ||
|
||
Oh, and, naturally, the code passes [WordPress](https://github.com/WordPress/WordPress-Coding-Standards) and [WordPress VIP](https://github.com/Automattic/VIP-Coding-Standards) coding standards 🎉 | ||
|
||
Always forgetting to complete posts or you have other people on your site who do? This is the draft botherer that you need! | ||
|
||
I'd like to thank [Caleb Burks](https://calebburks.com/) for the feedback he provided. Also, the iconography is courtesy of the very talented [Janki Rathod](https://www.linkedin.com/in/jankirathore/) ♥️ | ||
|
||
<p align="right"><a href="https://wordpress.org/plugins/draft-concluder/"><img src="https://img.shields.io/wordpress/plugin/dt/draft-concluder?label=wp.org%20downloads&style=for-the-badge"> <img src="https://img.shields.io/wordpress/plugin/stars/draft-concluder?color=orange&style=for-the-badge"></a></p> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
/** | ||
Plugin Name: Draft Concluder | ||
Plugin URI: https://wordpress.org/plugins/draft-concluder/ | ||
Description: 📝 Email users that have outstanding drafts. | ||
Version: 1.0 | ||
Author: David Artiss | ||
Author URI: https://artiss.blog | ||
Text Domain: draft-concluder | ||
@package draft-concluder | ||
*/ | ||
|
||
// Require the various code components - all held within the inc folder. | ||
require_once plugin_dir_path( __FILE__ ) . 'inc/setup.php'; | ||
|
||
require_once plugin_dir_path( __FILE__ ) . 'inc/settings.php'; | ||
|
||
require_once plugin_dir_path( __FILE__ ) . 'inc/process-drafts.php'; | ||
|
||
require_once plugin_dir_path( __FILE__ ) . 'inc/debug.php'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?php | ||
/** | ||
* Debug | ||
* | ||
* Functions to help with debugging any issues | ||
* | ||
* @package draft-concluder | ||
*/ | ||
|
||
/** | ||
* Now shortcode | ||
* | ||
* Will generate and output the email content. | ||
* | ||
* @param string $paras Parameters. | ||
* @param string $content Content between shortcodes. | ||
*/ | ||
function draft_concluder_now_shortcode( $paras, $content ) { | ||
|
||
draft_concluder_process_posts( true ); | ||
|
||
} | ||
|
||
add_shortcode( 'dc_now', 'draft_concluder_now_shortcode' ); | ||
|
||
|
||
/** | ||
* Last run shortcode | ||
* | ||
* Outputs the results of the last run. | ||
* | ||
* @param string $paras Parameters. | ||
* @param string $content Content between shortcodes. | ||
*/ | ||
function draft_concluder_last_run_shortcode( $paras, $content ) { | ||
|
||
$output = get_option( 'draft_concluder_output' ); | ||
|
||
echo '<p>'; | ||
if ( ! $output ) { | ||
echo esc_html( __( 'Draft Concluder has not yet run.', 'draft_concluder' ) ); | ||
} else { | ||
$timestamp = date( 'l jS \of F Y h:i:s A', $output['timestamp'] ); | ||
if ( 0 == $output['errors'] ) { | ||
/* translators: %1$s: timestamp */ | ||
$text = sprintf( __( 'Draft Concluder last ran at %1$s, successfully.', 'draft_concluder' ), esc_html( $timestamp ) ); | ||
} else { | ||
/* translators: %1$s: timestamp %2$s: number of errors */ | ||
$text = sprintf( __( 'Draft Concluder last ran at %1$s, with %2$s errors.', 'draft_concluder' ), esc_html( $timestamp ), esc_html( $output['errors'] ) ); | ||
} | ||
echo esc_html( $text ) . '<br/>'; | ||
echo wp_kses( | ||
$output['emails'], | ||
array( | ||
'br' => array(), | ||
'p' => array(), | ||
) | ||
); | ||
} | ||
echo '</p>'; | ||
} | ||
|
||
add_shortcode( 'dc_last_run', 'draft_concluder_last_run_shortcode' ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
<?php | ||
/** | ||
* Process posts | ||
* | ||
* Primary function to generate emails for outstanding drafts | ||
* | ||
* @package draft-concluder | ||
*/ | ||
|
||
/** | ||
* Process posts | ||
* | ||
* This processes the draft posts for each user in turn | ||
* It's defined as a seperate function, seperate from the scheduler action, so that it can | ||
* be called seperately, if required. | ||
* | ||
* @param string $debug true or false, determining if this is to be emailed or output. | ||
*/ | ||
function draft_concluder_process_posts( $debug = false ) { | ||
|
||
$output = array(); | ||
$errors = 0; | ||
|
||
$since = get_option( 'draft_concluder_since' ); | ||
|
||
// Get age of acceptable posts. If age not set, assume 0 which means an unlimited. | ||
$age = get_option( 'draft_concluder_age' ); | ||
if ( ! $age ) { | ||
$age = 0; | ||
} | ||
|
||
// Get how regularly it's due to run. If not daily, then assume weekly. | ||
$when = strtolower( get_option( 'draft_concluder_when' ) ); | ||
if ( 'daily' != $when ) { | ||
$when = 'weekly'; | ||
} | ||
|
||
// Set up the post types that will be searched for. | ||
|
||
$postpage = get_option( 'draft_concluder_what' ); | ||
if ( ! $postpage || 'postpage' == $postpage ) { | ||
$postpage = array( 'page', 'post' ); | ||
} | ||
|
||
// Get an array of users and loop through each. | ||
|
||
$users = get_users(); | ||
foreach ( $users as $user ) { | ||
|
||
$draft_count = 0; | ||
|
||
// Now grab all the posts of each user. | ||
|
||
$args = array( | ||
'post_status' => 'draft', | ||
'post_type' => $postpage, | ||
'numberposts' => 99, | ||
'author' => $user->ID, | ||
'orderby' => 'post_date', | ||
'sort_order' => 'asc', | ||
); | ||
|
||
$email_addy = $user->user_email; | ||
|
||
$posts = get_posts( $args ); | ||
$message = ''; | ||
|
||
foreach ( $posts as $post ) { | ||
|
||
// Check to see if draft is old enough! | ||
|
||
$include_draft = true; | ||
|
||
if ( 0 != $age ) { | ||
|
||
if ( 'modified' == $since ) { | ||
$date = $post->post_modified; | ||
} else { | ||
$date = $post->post_date; | ||
} | ||
|
||
// Convert the post edit date into Unix time format. | ||
$post_unix = strtotime( $date ); | ||
|
||
// Get current time in Unix format and subtract the number of days specified. | ||
$check_unix = time() - ( $age * DAY_IN_SECONDS ); | ||
|
||
if ( $post_unix > $check_unix ) { | ||
$include_draft = false; | ||
} | ||
} | ||
|
||
if ( $include_draft ) { | ||
|
||
// Build a list of drafts that require the user's attention. | ||
|
||
$draft_count ++; | ||
|
||
/* translators: Do not translate COUNT,TITLE, LINK, CREATED or MODIFIED : those are placeholders. */ | ||
$message .= __( | ||
'###COUNT###. ###TITLE### - ###LINK### | ||
This was created on ###CREATED### and last edited on ###MODIFIED###. | ||
', | ||
'draft_concluder' | ||
); | ||
|
||
$message = str_replace( | ||
array( | ||
'###COUNT###', | ||
'###TITLE###', | ||
'###LINK###', | ||
'###CREATED###', | ||
'###MODIFIED###', | ||
), | ||
array( | ||
esc_html( $draft_count ), | ||
esc_html( $post->post_title ), | ||
esc_html( get_admin_url() . 'post.php?post=' . $post->ID . '&action=edit' ), | ||
esc_html( substr( $post->post_date, 0, strlen( $post->post_date ) - 3 ) ), | ||
esc_html( substr( $post->post_modified, 0, strlen( $post->post_modified ) - 3 ) ), | ||
), | ||
$message | ||
); | ||
} | ||
} | ||
|
||
// Add a header to the email content. A different message is used dependant on whether there is 1 or more drafts. | ||
|
||
if ( 0 < $draft_count ) { | ||
|
||
if ( 1 == $draft_count ) { | ||
|
||
/* translators: Do not translate WHEN: this is a placeholder. */ | ||
$header = __( | ||
'Howdy! | ||
This is your ###WHEN### reminder that you have an outstanding draft that requires your attention: | ||
', | ||
'draft_concluder' | ||
); | ||
|
||
} else { | ||
|
||
/* translators: Do not translate WHEN or NUMBER: those are placeholders. */ | ||
$header = __( | ||
'Howdy! | ||
This is your ###WHEN### reminder that you have ###NUMBER### outstanding drafts that require your attention: | ||
', | ||
'draft_concluder' | ||
); | ||
} | ||
|
||
$header = str_replace( | ||
array( | ||
'###WHEN###', | ||
'###NUMBER###', | ||
), | ||
array( | ||
esc_html( $when ), | ||
esc_html( $draft_count ), | ||
), | ||
$header | ||
); | ||
|
||
if ( 1 == $draft_count ) { | ||
/* translators: %1$s: name of blog */ | ||
$subject = sprintf( __( '[%1$s] You have an outstanding draft', 'draft-concluder' ), get_bloginfo( 'name' ) ); | ||
} else { | ||
/* translators: %1$s: name of blog, %2$s: number of drafts */ | ||
$subject = sprintf( __( '[%1$s] You have %2$s outstanding drafts', 'draft-concluder' ), get_bloginfo( 'name' ), $draft_count ); | ||
} | ||
$body = $header . $message; | ||
|
||
$display_out = '<p>' . esc_html__( 'To: ', 'draft_concluder' ) . esc_html( $email_addy ) . '<br/>' . esc_html__( 'Subject: ', 'draft_concluder' ) . esc_html( $subject ) . '<br/><br/>' . nl2br( esc_html( $body ) ) . '</p>'; | ||
$output['emails'] .= $display_out; | ||
|
||
// If debugging, output to screen - otherwise, email the results. | ||
|
||
if ( $debug ) { | ||
echo wp_kses( | ||
$display_out, | ||
array( | ||
'br' => array(), | ||
'p' => array(), | ||
) | ||
); | ||
} else { | ||
// phpcs:ignore -- ignoring from PHPCS as this is only being used for a small number of mails | ||
$mail_rc = wp_mail( $email_addy, $subject, $body ); | ||
if ( ! $mail_rc ) { | ||
$errors++; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Update the saved output for the last run. | ||
|
||
if ( ! $debug ) { | ||
$output['errors'] = $errors; | ||
$output['timestamp'] = time(); | ||
update_option( 'draft_concluder_output', $output ); | ||
} | ||
} |
Oops, something went wrong.