Drafts Scheduler - Version 1.8

Version Description

  • NEW: Select a custom post type to schedule! Thanks for the suggestion everyone!
  • Remove most use of $wpdb, so overall it's more "WordPress-y" in function. Yay.
  • Update & tested with WordPress 4.0
  • Bug fixes
Download this release

Release Info

Developer talus
Plugin Icon wp plugin Drafts Scheduler
Version 1.8
Comparing to
See all releases

Code changes from version 1.7 to 1.8

Files changed (2) hide show
  1. draft-scheduler.php +535 -477
  2. readme.txt +8 -7
draft-scheduler.php CHANGED
@@ -2,17 +2,17 @@
2
  /*
3
  Plugin Name: Drafts Scheduler
4
  Plugin URI: http://www.installedforyou.com/draftscheduler
5
- Contributors: talus, beezeee
6
  Description: Allows WordPress admins to bulk schedule posts currently saved as drafts
7
  Author: Jeff Rose
8
- Version: 1.7
9
  Author URI: http://www.installedforyou.com
10
  Tags: drafts, schedule, posts
11
  License: GPL2
12
 
13
  */
14
 
15
- /* Copyright 2010 Jeff Rose (email : info@installedforyou.com)
16
 
17
  This program is free software; you can redistribute it and/or modify
18
  it under the terms of the GNU General Public License, version 2, as
@@ -28,491 +28,549 @@ License: GPL2
28
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
  */
30
 
31
- if (!class_exists('DraftScheduler')) {
32
-
33
- define ('IFDS_VERSION', '1.5');
34
- define('DraftScheduler_root', WP_PLUGIN_URL . '/drafts-scheduler/');
35
-
36
- class DraftScheduler {
37
-
38
- private $ifds_option = 'IFDS_UNDO';
39
-
40
- /*
41
- * function DraftScheduler
42
- * Constructor for the class
43
- * Primarily connects the WP hooks
44
- */
45
- function DraftScheduler() {
46
-
47
- add_action('admin_menu', array(&$this,'draftScheduler_Admin'));
48
- }
49
-
50
- /*
51
- * function draftScheduler_Admin
52
- * Sets up the Admin page for the user to schedule draft posts
53
- */
54
- function draftScheduler_Admin() {
55
- add_posts_page('Draft Scheduler', 'Draft Scheduler', 'administrator', 'draft_scheduler', array(&$this, 'draftScheduler_manage_page'));
56
- }
57
-
58
- /*
59
- * function draftScheduler_Scheduler
60
- * The supposed workhorse - this applies the chosen parameters
61
- * to the posts
62
- */
63
- function draftScheduler_Scheduler(){
64
- GLOBAL $wpdb;
65
-
66
- $draftList = $wpdb->get_results("SELECT * from $wpdb->posts WHERE status='draft'");
67
- }
68
-
69
- /*
70
- * function draft_manage_page
71
- * Check to see if page was posted, display messages, then display page
72
- */
73
- function draftScheduler_manage_page() {
74
- $ifds_msg = '';
75
- $ifds_msg = $this->ifdsManagePg();
76
- if ( trim($ifds_msg) != '' ) {
77
- echo '<div id="message" class="updated fade"><p><strong>'.$ifds_msg.'</strong></p></div>';
78
  }
79
- echo '<div class="wrap">';
80
- $this->draftScheduler_admin_page();
81
- echo '</div>';
82
- }
83
-
84
- /*
85
- * function ifdsManagePg
86
- * Process the form post and do the work.
87
- */
88
- function ifdsManagePg() {
89
- global $wpdb;
90
- if ( (!empty( $_POST["action"] ) && $_POST["action"] ==="undo" ) && check_admin_referer( 'do-undo-schedule' ) ){
91
- $undoList = get_option( $this->ifds_option );
92
- if ( !empty( $undoList ) ){
93
- foreach ($undoList as $undoPost) {
94
- $thisPost = get_post( $undoPost );
95
- if ( "future" == $thisPost->post_status){
96
- $wpdb->update( $wpdb->posts, array(
97
- 'post_status' => 'draft'
98
- ),
99
- array( 'ID' => $undoPost )
100
- );
101
- wp_transition_post_status("draft", "future" , $thisPost );
102
- }
103
- }
104
- }
105
- delete_option( $this->ifds_option );
106
- $msg = "Posts un-scheduled.";
107
- }
108
-
109
- if ( !empty( $_POST ) && $_POST["action"] !="undo" && check_admin_referer( 'do-schedule-drafts' ) ) {
110
- $msg = '';
111
- if ( !$_POST["action"] == "schedule_drafts" ) {
112
- /*
113
- * No action set, so just return
114
- */
115
- return $msg;
116
- } else {
117
- if ( !j_is_date( $_POST['startDate'] ) ) {
118
- $msg = 'Please enter a valid date to start posting';
119
- return $msg;
120
- }
121
-
122
- $startDate = $_POST['startDate'];
123
- $startTime = $_POST['startTime'];
124
- $endTime = $_POST['endTime'];
125
- $dayweekmonth = $_POST['dayweekmonth'];
126
-
127
- $dailyMax = $_POST['postsperday'];
128
- $exactPosts = $_POST['exactPosts'];
129
-
130
- $intHours = $_POST['intHours'];
131
- $intMins = $_POST['intMins'];
132
-
133
- if ( $_POST['randomness'] == "sequential" || $_POST['randomness'] == "random" ) {
134
- if ( !is_numeric( $intHours ) || ( $intHours =='' ) || ( 24 < $intHours ) || (0 > $intHours ) ) {
135
- $msg = 'Please enter a valid Post Interval';
136
- return $msg;
137
- }
138
- if ( !is_numeric( $intMins ) || ( $intMins =='' ) || ( 60 < $intMins ) || 0 > $intMins ) {
139
- $msg = 'Please enter a valid Post Interval';
140
- return $msg;
141
- }
142
- } else {
143
-
144
- if ( !j_is_date( $startTime ) || ( $startTime == '' ) ) {
145
- $msg = 'Please enter a valid start time';
146
- return $msg;
147
- }
148
- if ( !j_is_date( $endTime ) || ( $endTime == '' ) ) {
149
- $msg = 'Please enter a valid end time';
150
- return $msg;
151
- }
152
-
153
- if ( strtotime( $startTime ) > strtotime( $endTime ) ) {
154
- $msg = 'Ensure the start time is before the end time.';
155
- return $msg;
156
- }
157
- }
158
-
159
- if ( $_POST['randomness'] == "sequential" ){
160
-
161
- $msg = $this->draftScheduler_sequential_post_by_interval( $startDate, $intHours, $intMins );
162
-
163
- } else if ( $_POST['randomness'] == "random" ) {
164
-
165
- $msg = $this->draftScheduler_random_post_by_interval( $startDate, $intHours, $intMins );
166
-
167
- } else {
168
-
169
- $msg = $this->draftScheduler_randomize_drafts( $startDate, $startTime, $endTime, $dailyMax, $exactPosts, $dayweekmonth );
170
- }
171
-
172
- return $msg;
173
- } // end check for post action
174
- } // end check admin referrer
175
- }
176
-
177
- /*
178
- * function print_admin_page
179
- * Display the amdin options page
180
- */
181
- function draftScheduler_admin_page() {
182
- ?>
183
- <script type="text/javascript" src="<?php echo DraftScheduler_root ?>js/jquery-ui-1.7.2.custom.min.js"></script>
184
- <link rel="stylesheet" type="text/css" href="<?php echo DraftScheduler_root ?>css/sunny/jquery-ui-1.7.2.custom.css" />
185
- <script type="text/javascript">
186
- jQuery(document).ready(function(jQuery) {
187
- jQuery("#datepicker").datepicker({dateFormat: 'yy-mm-dd', altField: '#startDate', altFormat: 'MM d, yy', defaultDate: '<?php echo $startDate; ?>'});
188
- });
189
- </script>
190
-
191
- <h2>Draft Scheduler</h2>
192
- <?php
193
- $undoavail = get_option( $this->ifds_option );
194
- if ( isset ( $undoavail ) && "" != $undoavail ){
195
- ?>
196
- <table class="form-table">
197
- <tr valign="top">
198
- <th scope="row">Undo last schedule?</th>
199
- <td>
200
- <form method="post">
201
- <input type="submit" name="undoNow" value="Undo schedule" />
202
- <input type="hidden" name="action" value="undo" />
203
- <?php wp_nonce_field('do-undo-schedule'); ?>
204
- </form>
205
- This will allow you to un-schedule any posts from your most recent schedule that have NOT yet been posted.
206
- </td>
207
- </tr>
208
- </table>
209
- <?php
210
- }
211
- $draftCount = $this->draftScheduler_check_for_drafts();
212
- if ( 0 != $draftCount ){
213
- ?>
214
- <form method="post">
215
- <?php wp_nonce_field('do-schedule-drafts'); ?>
216
- <table class="form-table">
217
- <tr valign="top">
218
- <th scope="row">Schedule Start Date</th>
219
- <td>
220
- <div id="datepicker"></div>
221
- <input type="text" name="startDate" id="startDate" size="31" value="<?php if( isset( $_POST['startDate'] ) ) echo $_POST['startDate']; ?>" />
222
- <br />
223
- Note: if you schedule starts "Today" then posting will start from midnight, including before "now."<br />You may wish to start tomorrow.
224
- </td>
225
- </tr>
226
- <tr valign="top">
227
- <th scope="row">Posting order</th>
228
- <td>
229
- <input type="radio" name="randomness" value="random" <?php if ($_POST['randomness'] == "random" || $_POST['randomness'] == "") echo " checked " ?>> Randomly grab any draft in any order<br />
230
- <input type="radio" name="randomness" value="sequential" <?php if ($_POST['randomness'] == "sequential") echo " checked " ?>> Sequentially schedule drafts from oldest to newest in order
231
- </td>
232
- </tr>
233
- <tr valign="top">
234
- <th scope="row">Post interval</th>
235
- <td>
236
- <input type="text" name="intHours" id="intHours" size="4" maxlength="2" value="<?php echo $_POST['intHours']; ?>" /><strong>hrs</strong>
237
- <input type="text" name="intMins" id="intMins" size="4" maxlength="2" value="<?php echo $_POST['intMins']; ?>" /><strong>mins</strong>
238
- </td>
239
- </tr>
240
-
241
- <tr valign="top">
242
- <th scope="row">&nbsp;&nbsp;&nbsp; - OR -</th>
243
- <td><hr style="width:400px; float: left;"/></td>
244
- </tr>
245
- <tr valign="top">
246
- <th scope="row">Post Randomly</th>
247
- <td>
248
- <input type="radio" name="randomness" value="fullrandom" <?php if ($_POST['randomness'] == "fullrandom") echo " checked " ?>> Surprise me <em>(posts entirely randomly after the date above, but within the times below)</em><br />
249
- Post up to <input type="text" name="postsperday" id="postsperda" value="<?php echo $_POST['postsperday']; ?>" size="3" maxlength="3" /> posts per
250
- <select name="dayweekmonth">
251
- <option value="day">day</option>
252
- <option value="week">week</option>
253
- <option value="month">month</option>
254
- </select> <strong>OR</strong>
255
- Post exactly <input type="text" name="exactPosts" id="exactPosts" value="<?php echo $_POST['exactPosts']; ?>" size="3" maxlength="3" /> posts per day<br />
256
- Randomly after:
257
- <select name="startTime" id="startTime">
258
- <option value="">Choose a time</option>
259
- <?php echo self::createDateTimeDropDowns($_POST['startTime']); ?>
260
- </select><br />
261
- And before:
262
- <select name="endTime" id="endTime">
263
- <option value="">Choose a time</option>
264
- <?php echo self::createDateTimeDropDowns($_POST['endTime']); ?>
265
- </select><br />
266
- </td>
267
- </tr>
268
-
269
- </table>
270
- <input type="hidden" name="action" value="schedule_drafts">
271
- <p class="submit">
272
- <input type="submit" class="button-primary" value="<?php _e('Schedule Drafts') ?>" />
273
- </p>
274
- </form>
275
- <?php
276
- } else {
277
- ?>
278
- <div id="message" class="updated fade"><p>Sorry, there are no posts in DRAFT status</p></div>
279
- <?php
280
- }
281
- } // End Function print_admin_page
282
-
283
- /*
284
- * function draftScheduler_randomize_drafts
285
- *
286
- */
287
- function draftScheduler_randomize_drafts($startDate, $startTime, $endTime, $dailyMax = "", $exactPosts = "", $dayweekmonth ) {
288
-
289
- global $wpdb;
290
-
291
- if ( "" == $exactPosts ){
292
- $postsToday = rand( 0, $dailyMax * 100 ) / 100;
293
- } else {
294
- $postsToday = $exactPosts;
295
- }
296
-
297
- $startPosts = date_i18n( 'Y-n-j G:i:s', strtotime($startDate . ' ' . $startTime));
298
-
299
- $randInterval = (strtotime($endTime) - strtotime($startTime));
300
-
301
- $findDrafts = "SELECT ID FROM " .$wpdb->prefix . "posts WHERE post_status = 'draft' AND post_type = 'post' ORDER BY rand()";
302
-
303
- $draftList = $wpdb->get_results($findDrafts);
304
-
305
- $this->draftScheduler_add_undo( $draftList );
306
-
307
- if ( empty($draftList) ) {
308
- return "No drafts were found";
309
- }
310
-
311
- $finished = false;
312
-
313
- while ( ! $finished ):
314
- if ( $dayweekmonth == 'month' ) {
315
- $weekSplit = floor( 30/$dailyMax );
316
- $weightedAdd = rand( 0, 3 );
317
- if ( $weightedAdd != 3 ) $weekSplit = $weekSplit + $weightedAdd;
318
- $weekSplit <= 1 ? $incrementDays = '+1 day' : $incrementDays = "+$weekSplit days";
319
- $startPosts = date_i18n( 'Y-n-j G:i:s', strtotime( $incrementDays, strtotime( $startPosts ) ) );
320
- } elseif ($dayweekmonth == 'week') {
321
- $weekSplit = floor( 7/$dailyMax );
322
- $weekSplit = $weekSplit + rand( 0, 1 );
323
- $weekSplit <= 1 ? $incrementDays = '+1 day' : $incrementDays = "+$weekSplit days";
324
- $startPosts = date_i18n( 'Y-n-j G:i:s', strtotime( $incrementDays, strtotime( $startPosts ) ) );
325
- } else {
326
- if ( 0 >= $postsToday ){
327
- if ( "" <> $dailyMax ){
328
- $postsToday = rand( 0, $dailyMax * 100 ) / 100;
329
- $startPosts = date_i18n( 'Y-n-j G:i:s', strtotime( "+1 day", strtotime( $startPosts ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  } else {
331
- $postsToday = $exactPosts;
332
- $startPosts = date_i18n( 'Y-n-j G:i:s', strtotime( "+1 day", strtotime( $startPosts ) ) );
333
  }
334
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
336
 
337
- $thisDraft = array_pop( $draftList );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
- $postRandom = rand( 0, $randInterval );
340
- $postTime = date_i18n( 'Y-n-j G:i:s', strtotime( "+" . $postRandom . " seconds", strtotime( $startPosts ) ) );
341
 
342
- $this->update_post_details( strtotime( $postTime ), $thisDraft->ID );
343
- $whole_post = get_post( $thisDraft->ID );
344
- wp_transition_post_status( 'draft', 'future', $whole_post );
345
- check_and_publish_future_post( $thisDraft->ID );
346
 
347
- if ( 0 == count( $draftList ) ){
348
- $finished = true;
349
- }
350
- $postsToday --;
351
- endwhile;
352
-
353
- return "Drafts updated!";
354
- //return $query;
355
- }
356
-
357
- /*
358
- * function draftScheduler_random_post_by_interval
359
- * Schedule drafts in random order, based on an interval
360
- */
361
- function draftScheduler_random_post_by_interval( $startDate, $intvHours, $intvMins) {
362
- global $wpdb;
363
-
364
- /*
365
- * $intvSecs, convert hours and minutes to seconds for the
366
- * sql query
367
- */
368
-
369
- $intvSecs = ( $intvHours * 60 * 60 ) + ( $intvMins * 60 );
370
-
371
- $findDrafts = "SELECT * FROM " .$wpdb->posts . " WHERE post_status = 'draft' AND post_type = 'post' ORDER BY rand()";
372
-
373
- $draftList = $wpdb->get_results( $findDrafts );
374
-
375
- $this->draftScheduler_add_undo( $draftList );
376
-
377
- if ( empty( $draftList ) ) {
378
- return "No drafts were found";
379
- }
380
-
381
- $startDate = $startDate;
382
-
383
- $ds_postDate = strtotime( $startDate );
384
-
385
- foreach ( $draftList as $thisDraft ){
386
-
387
- $this->update_post_details( $ds_postDate, $thisDraft->ID );
388
- $whole_post = get_post( $thisDraft->ID );
389
- wp_transition_post_status( 'draft', 'future', $whole_post );
390
- check_and_publish_future_post( $thisDraft->ID );
391
-
392
- $ds_postDate += $intvSecs;
393
- }
394
- //$query = "update";
395
- return "Drafts updated!";
396
- } // End Function draftScheduler_random_post_by_interval
397
-
398
- /*
399
- * function draftScheduler_sequential_post_by_interval
400
- * Schedule drafts in sequential order, based on an interval
401
- */
402
- function draftScheduler_sequential_post_by_interval( $startDate, $intvHours, $intvMins) {
403
- global $wpdb;
404
-
405
- /*
406
- * $intvSecs, convert hours and minutes to seconds for the
407
- * sql query
408
- */
409
- $intvSecs = ( $intvHours * 60 * 60 ) + ( $intvMins * 60 );
410
-
411
- $findDrafts = "SELECT ID FROM " .$wpdb->posts . " WHERE post_status = 'draft' AND post_type = 'post' ORDER BY id ASC";
412
-
413
- $draftList = $wpdb->get_results( $findDrafts );
414
- $this->draftScheduler_add_undo( $draftList );
415
- if ( empty( $draftList ) ) {
416
- return "No drafts were found";
417
- }
418
-
419
- $ds_postDate = strtotime( $startDate );
420
-
421
- foreach ( $draftList as $thisDraft ){
422
-
423
- $this->update_post_details( $ds_postDate, $thisDraft->ID );
424
- $whole_post = get_post( $thisDraft->ID );
425
- wp_transition_post_status( 'draft', 'future', $whole_post );
426
- check_and_publish_future_post( $thisDraft->ID );
427
-
428
- $ds_postDate += $intvSecs;
429
- }
430
- return "Drafts updated!";
431
-
432
- } // End Function draftScheduler_sequential_post_by_interval
433
-
434
- function update_post_details( $ds_postDate, $draftID ){
435
- global $wpdb;
436
- $ds_gmt = get_gmt_from_date( date( 'Y-n-j G:i:s', $ds_postDate ) );
437
-
438
- $update_date = array(
439
- 'ID' => $draftID,
440
- 'post_date' => date_i18n( 'Y-n-j G:i:s', $ds_postDate ),
441
- 'post_date_gmt' => $ds_gmt,
442
- 'post_status' => 'future',
443
- 'edit_date' => true
444
- );
445
-
446
- wp_update_post( $update_date );
447
- }
448
-
449
- /*
450
- * function createDateTimeDropDowns
451
- * generate a dropdown select list for 30 minute intervals
452
- */
453
- function createDateTimeDropDowns ( $selected ) {
454
- //$outputHTML = '<option value=""></option>';
455
- for ($i = 0; $i <= 23; $i ++) {
456
- if($i < 10 ) {
457
- $hourTime = "0" . $i;
458
- } else {
459
- $hourTime = $i;
460
- }
461
- $outputHTML .= '<option value="'.$hourTime.':00"';
462
- if ($hourTime . ":00" == $selected) {
463
- $outputHTML .= " selected='selected' ";
464
- }
465
- $outputHTML .= '>'.$hourTime.':00</option>';
466
- $outputHTML .= '<option value="'.$hourTime.':30"';
467
- if ($hourTime . ":30" == $selected) {
468
- $outputHTML .= " selected='selected' ";
469
- }
470
- $outputHTML .= '>'.$hourTime.':30</option>';
471
- }
472
- return $outputHTML;
473
- } // End Function createDateTimeDropDowns
474
-
475
- function draftScheduler_add_undo( $draftList ){
476
- if ( is_array( $draftList ) ){
477
- foreach ( $draftList as $draft ){
478
- $undoList[] = $draft->ID;
479
- }
480
- update_option( $this->ifds_option, $undoList );
481
- }
482
- }
483
-
484
- function draftScheduler_check_for_drafts(){
485
- global $wpdb;
486
-
487
- $findDrafts = "SELECT COUNT(ID) FROM " .$wpdb->prefix . "posts WHERE post_status = 'draft' AND post_type = 'post'";
488
-
489
- $draftCount = $wpdb->get_var( $findDrafts );
490
-
491
- return $draftCount;
492
- }
493
- } // End Class DraftScheduler
494
  } // End If
495
 
496
  $draftScheduler = new DraftScheduler();
497
 
498
- function j_is_date( $str )
499
- {
500
- $stamp = strtotime( $str );
501
-
502
- if (!is_numeric($stamp))
503
- {
504
- return FALSE;
505
- }
506
- $month = date( 'm', $stamp );
507
- $day = date( 'd', $stamp );
508
- $year = date( 'Y', $stamp );
509
-
510
- if (checkdate($month, $day, $year))
511
- {
512
- return TRUE;
513
- }
514
-
515
- return FALSE;
516
- }
517
 
518
  ?>
2
  /*
3
  Plugin Name: Drafts Scheduler
4
  Plugin URI: http://www.installedforyou.com/draftscheduler
5
+ Contributors: talus
6
  Description: Allows WordPress admins to bulk schedule posts currently saved as drafts
7
  Author: Jeff Rose
8
+ Version: 1.8
9
  Author URI: http://www.installedforyou.com
10
  Tags: drafts, schedule, posts
11
  License: GPL2
12
 
13
  */
14
 
15
+ /* Copyright 2010 - 2014 Jeff Rose (email : info@installedforyou.com)
16
 
17
  This program is free software; you can redistribute it and/or modify
18
  it under the terms of the GNU General Public License, version 2, as
28
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
  */
30
 
31
+ if ( ! class_exists( 'DraftScheduler' ) ) {
32
+
33
+ define ( 'IFDS_VERSION', '1.8' );
34
+ define( 'DraftScheduler_root', WP_PLUGIN_URL . '/drafts-scheduler/' );
35
+
36
+ class DraftScheduler{
37
+
38
+ private $ifds_option = 'IFDS_UNDO';
39
+
40
+ /*
41
+ * function DraftScheduler
42
+ * Constructor for the class
43
+ * Primarily connects the WP hooks
44
+ */
45
+ function DraftScheduler() {
46
+
47
+ add_action( 'admin_menu', array( &$this, 'draftScheduler_Admin' ) );
48
+ add_action( 'admin_print_styles-posts_page_draft_scheduler', array( &$this, 'register_scripts' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
+
51
+ function register_scripts() {
52
+ wp_enqueue_style( 'ds-sunny', plugins_url( 'css/sunny/jquery-ui-1.7.2.custom.css', __FILE__ ) );
53
+ }
54
+
55
+ /*
56
+ * function draftScheduler_Admin
57
+ * Sets up the Admin page for the user to schedule draft posts
58
+ */
59
+ function draftScheduler_Admin() {
60
+ $page = add_posts_page( 'Draft Scheduler', 'Draft Scheduler', 'manage_options', 'draft_scheduler', array( &$this, 'draftScheduler_manage_page' ) );
61
+ }
62
+
63
+ /*
64
+ * function draftScheduler_Scheduler
65
+ * The supposed workhorse - this applies the chosen parameters
66
+ * to the posts
67
+ */
68
+ function draftScheduler_Scheduler( $post_type = 'post', $order_by = 'post_date' ) {
69
+ $args = array(
70
+ 'posts_per_page' => - 1,
71
+ 'post_type' => $post_type,
72
+ 'post_status' => 'draft',
73
+ 'orderby' => $order_by,
74
+ );
75
+
76
+ if ( 'post_date' == $order_by ) {
77
+ $args['order'] = 'desc';
78
+ }
79
+
80
+ $draftList = get_posts( $args );
81
+
82
+ return $draftList;
83
+ }
84
+
85
+ /*
86
+ * function draft_manage_page
87
+ * Check to see if page was posted, display messages, then display page
88
+ */
89
+ function draftScheduler_manage_page() {
90
+ $ifds_msg = $this->ifdsManagePg();
91
+ if ( trim( $ifds_msg ) != '' ) {
92
+ echo '<div id="message" class="updated fade"><p><strong>' . $ifds_msg . '</strong></p></div>';
93
+ }
94
+ echo '<div class="wrap">';
95
+ $this->draftScheduler_admin_page();
96
+ echo '</div>';
97
+ }
98
+
99
+ /*
100
+ * function ifdsManagePg
101
+ * Process the form post and do the work.
102
+ */
103
+ function ifdsManagePg() {
104
+ global $wpdb;
105
+ $msg = '';
106
+ if ( ( ! empty( $_POST["action"] ) && $_POST["action"] === "undo" ) && check_admin_referer( 'do-undo-schedule' ) ) {
107
+ $undoList = get_option( $this->ifds_option );
108
+ if ( ! empty( $undoList ) ) {
109
+ foreach ( $undoList as $undoPost ) {
110
+ $thisPost = get_post( $undoPost );
111
+ if ( "future" == $thisPost->post_status ) {
112
+ $wpdb->update( $wpdb->posts, array(
113
+ 'post_status' => 'draft'
114
+ ), array( 'ID' => $undoPost ) );
115
+ wp_transition_post_status( "draft", "future", $thisPost );
116
+ }
117
+ }
118
+ }
119
+ delete_option( $this->ifds_option );
120
+ $msg = "Posts un-scheduled.";
121
+ }
122
+
123
+ if ( ! empty( $_POST ) && $_POST["action"] != "undo" && check_admin_referer( 'do-schedule-drafts' ) ) {
124
+ $msg = '';
125
+ if ( ! $_POST["action"] == "schedule_drafts" ) {
126
+ /*
127
+ * No action set, so just return
128
+ */
129
+ return $msg;
130
+ } else {
131
+ if ( ! j_is_date( $_POST['startDate'] ) ) {
132
+ $msg = 'Please enter a valid date to start posting';
133
+
134
+ return $msg;
135
+ }
136
+
137
+ $startDate = $_POST['startDate'];
138
+ $startTime = $_POST['startTime'];
139
+ $endTime = $_POST['endTime'];
140
+ $dayweekmonth = $_POST['dayweekmonth'];
141
+
142
+ $dailyMax = $_POST['postsperday'];
143
+ $exactPosts = $_POST['exactPosts'];
144
+
145
+ $intHours = $_POST['intHours'];
146
+ $intMins = $_POST['intMins'];
147
+
148
+ if ( $_POST['randomness'] == "sequential" || $_POST['randomness'] == "random" ) {
149
+ if ( ! is_numeric( $intHours ) || ( $intHours == '' ) || ( 24 < $intHours ) || ( 0 > $intHours ) ) {
150
+ $msg = 'Please enter a valid Post Interval';
151
+
152
+ return $msg;
153
+ }
154
+ if ( ! is_numeric( $intMins ) || ( $intMins == '' ) || ( 60 < $intMins ) || 0 > $intMins ) {
155
+ $msg = 'Please enter a valid Post Interval';
156
+
157
+ return $msg;
158
+ }
159
+ } else {
160
+
161
+ if ( ! j_is_date( $startTime ) || ( $startTime == '' ) ) {
162
+ $msg = 'Please enter a valid start time';
163
+
164
+ return $msg;
165
+ }
166
+ if ( ! j_is_date( $endTime ) || ( $endTime == '' ) ) {
167
+ $msg = 'Please enter a valid end time';
168
+
169
+ return $msg;
170
+ }
171
+
172
+ if ( strtotime( $startTime ) > strtotime( $endTime ) ) {
173
+ $msg = 'Ensure the start time is before the end time.';
174
+
175
+ return $msg;
176
+ }
177
+ }
178
+
179
+ if ( $_POST['randomness'] == "sequential" ) {
180
+
181
+ $msg = $this->draftScheduler_sequential_post_by_interval( $startDate, $intHours, $intMins );
182
+
183
+ } else if ( $_POST['randomness'] == "random" ) {
184
+
185
+ $msg = $this->draftScheduler_random_post_by_interval( $startDate, $intHours, $intMins );
186
+
187
+ } else {
188
+
189
+ $msg = $this->draftScheduler_randomize_drafts( $startDate, $startTime, $endTime, $dailyMax, $exactPosts, $dayweekmonth );
190
+ }
191
+
192
+ } // end check for post action
193
+ } // end check admin referrer
194
+ return $msg;
195
+ }
196
+
197
+ /*
198
+ * function print_admin_page
199
+ * Display the amdin options page
200
+ */
201
+ function draftScheduler_admin_page() {
202
+ ?>
203
+ <script type="text/javascript">
204
+ jQuery(document).ready(function (jQuery) {
205
+ jQuery("#datepicker").datepicker({dateFormat: 'yy-mm-dd', altField: '#startDate', altFormat: 'MM d, yy'});
206
+ });
207
+ </script>
208
+
209
+ <h2>Draft Scheduler</h2>
210
+ <?php
211
+ $undoavail = get_option( $this->ifds_option );
212
+ if ( isset ( $undoavail ) && "" != $undoavail ) {
213
+ ?>
214
+ <table class="form-table">
215
+ <tr valign="top">
216
+ <th scope="row">Undo last schedule?</th>
217
+ <td>
218
+ <form method="post">
219
+ <input type="submit" name="undoNow" value="Undo schedule"/>
220
+ <input type="hidden" name="action" value="undo"/>
221
+ <?php wp_nonce_field( 'do-undo-schedule' ); ?>
222
+ </form>
223
+ This will allow you to un-schedule any posts from your most recent schedule that have NOT yet been posted.
224
+ </td>
225
+ </tr>
226
+ </table>
227
+ <?php
228
+ }
229
+ $draftCount = $this->draftScheduler_check_for_drafts();
230
+ if ( 0 != $draftCount ) {
231
+ ?>
232
+ <form method="post">
233
+ <?php wp_nonce_field( 'do-schedule-drafts' ); ?>
234
+ <table class="form-table">
235
+ <tr valign="top">
236
+ <th scope="row">Post type to schedule</th>
237
+ <td>
238
+ <?php echo $this->select_with_post_types(); ?>
239
+ </td>
240
+ </tr>
241
+ <tr valign="top">
242
+ <th scope="row">Schedule Start Date</th>
243
+ <td>
244
+ <div id="datepicker"></div>
245
+ <input type="text" name="startDate" id="startDate" size="31" value="<?php echo $_POST['startDate']; ?>"/>
246
+ <br/>
247
+ Note: if your schedule starts "Today" then posting will start from midnight, including before "now."<br/>You may wish to start tomorrow.
248
+ </td>
249
+ </tr>
250
+ <tr valign="top">
251
+ <th scope="row">Posting order</th>
252
+ <td>
253
+ <input type="radio" name="randomness" value="random" <?php checked( $_POST['randomness'], 'random', true );
254
+ checked( $_POST['randomness'], '', true ); ?>> Randomly grab any draft in any order<br/>
255
+ <input type="radio" name="randomness" value="sequential" <?php checked( $_POST['randomness'], 'sequential', true ); ?>> Sequentially schedule drafts from oldest to
256
+ newest in order
257
+ </td>
258
+ </tr>
259
+ <tr valign="top">
260
+ <th scope="row">Post interval</th>
261
+ <td>
262
+ <input type="text" name="intHours" id="intHours" size="4" maxlength="2" value="<?php echo $_POST['intHours']; ?>"/><strong>hrs</strong>
263
+ <input type="text" name="intMins" id="intMins" size="4" maxlength="2" value="<?php echo $_POST['intMins']; ?>"/><strong>mins</strong>
264
+ </td>
265
+ </tr>
266
+
267
+ <tr valign="top">
268
+ <th scope="row">&nbsp;&nbsp;&nbsp; - OR -</th>
269
+ <td>
270
+ <hr style="width:400px; float: left;"/>
271
+ </td>
272
+ </tr>
273
+ <tr valign="top">
274
+ <th scope="row">Post Randomly</th>
275
+ <td>
276
+ <input type="radio" name="randomness" value="fullrandom" <?php if ( $_POST['randomness'] == "fullrandom" ) {
277
+ echo " checked ";
278
+ } ?>> Surprise me <em>(posts entirely randomly after the date above, but within the times below)</em><br/>
279
+ Post up to <input type="text" name="postsperday" id="postsperda" value="<?php echo $_POST['postsperday']; ?>" size="3" maxlength="3"/> posts per
280
+ <select name="dayweekmonth">
281
+ <option value="day">day</option>
282
+ <option value="week">week</option>
283
+ <option value="month">month</option>
284
+ </select> <strong>OR</strong>
285
+ Post exactly <input type="text" name="exactPosts" id="exactPosts" value="<?php echo $_POST['exactPosts']; ?>" size="3" maxlength="3"/> posts per day<br/>
286
+ Randomly after:
287
+ <select name="startTime" id="startTime">
288
+ <option value="">Choose a time</option>
289
+ <?php echo self::createDateTimeDropDowns( $_POST['startTime'] ); ?>
290
+ </select><br/>
291
+ And before:
292
+ <select name="endTime" id="endTime">
293
+ <option value="">Choose a time</option>
294
+ <?php echo self::createDateTimeDropDowns( $_POST['endTime'] ); ?>
295
+ </select><br/>
296
+ </td>
297
+ </tr>
298
+
299
+ </table>
300
+ <input type="hidden" name="action" value="schedule_drafts">
301
+
302
+ <p class="submit">
303
+ <input type="submit" class="button-primary" value="<?php _e( 'Schedule Drafts' ) ?>"/>
304
+ </p>
305
+ </form>
306
+ <?php
307
+ } else {
308
+ ?>
309
+ <div id="message" class="updated fade"><p>Sorry, there are no posts in DRAFT status</p></div>
310
+ <?php
311
+ }
312
+ } // End Function print_admin_page
313
+
314
+ /*
315
+ * function draftScheduler_randomize_drafts
316
+ *
317
+ */
318
+ function draftScheduler_randomize_drafts( $startDate, $startTime, $endTime, $dailyMax = "", $exactPosts = "", $dayweekmonth ) {
319
+ if ( "" == $exactPosts ) {
320
+ $postsToday = rand( 0, $dailyMax * 100 ) / 100;
321
+ } else {
322
+ $postsToday = $exactPosts;
323
+ }
324
+
325
+ $startPosts = date_i18n( 'Y-n-j g:i:s', strtotime( $startDate . ' ' . $startTime ) );
326
+
327
+ $randInterval = ( strtotime( $endTime ) - strtotime( $startTime ) );
328
+
329
+ if ( isset( $_POST['draft_post_type'] ) ) {
330
+ $post_type = esc_attr( $_POST['draft_post_type'] );
331
  } else {
332
+ $post_type = 'post';
 
333
  }
334
+
335
+ $draftList = $this->draftScheduler_Scheduler( $post_type, 'rand' );
336
+
337
+ $this->draftScheduler_add_undo( $draftList );
338
+
339
+ if ( empty( $draftList ) ) {
340
+ return "No drafts were found";
341
+ }
342
+
343
+ $finished = false;
344
+
345
+ while ( ! $finished ):
346
+ if ( $dayweekmonth == 'month' ) {
347
+ $weekSplit = floor( 30 / $dailyMax );
348
+ $weightedAdd = rand( 0, 3 );
349
+ if ( $weightedAdd != 3 ) {
350
+ $weekSplit = $weekSplit + $weightedAdd;
351
+ }
352
+ $weekSplit <= 1 ? $incrementDays = '+1 day' : $incrementDays = "+$weekSplit days";
353
+ $startPosts = date_i18n( 'Y-n-j g:i:s', strtotime( $incrementDays, strtotime( $startPosts ) ) );
354
+ } elseif ( $dayweekmonth == 'week' ) {
355
+ $weekSplit = floor( 7 / $dailyMax );
356
+ $weekSplit = $weekSplit + rand( 0, 1 );
357
+ $weekSplit <= 1 ? $incrementDays = '+1 day' : $incrementDays = "+$weekSplit days";
358
+ $startPosts = date_i18n( 'Y-n-j g:i:s', strtotime( $incrementDays, strtotime( $startPosts ) ) );
359
+ } else {
360
+ if ( 0 >= $postsToday ) {
361
+ if ( "" <> $dailyMax ) {
362
+ $postsToday = rand( 0, $dailyMax * 100 ) / 100;
363
+ $startPosts = date_i18n( 'Y-n-j g:i:s', strtotime( "+1 day", strtotime( $startPosts ) ) );
364
+ } else {
365
+ $postsToday = $exactPosts;
366
+ $startPosts = date_i18n( 'Y-n-j g:i:s', strtotime( "+1 day", strtotime( $startPosts ) ) );
367
+ }
368
+ }
369
+ }
370
+
371
+ $thisDraft = array_pop( $draftList );
372
+
373
+ $postRandom = rand( 0, $randInterval );
374
+ $postTime = date_i18n( 'Y-n-j G:i:s', strtotime( "+" . $postRandom . " seconds", strtotime( $startPosts ) ) );
375
+
376
+ $this->update_post_details( strtotime( $postTime ), $thisDraft->ID );
377
+ $whole_post = get_post( $thisDraft->ID );
378
+ wp_transition_post_status( 'draft', 'future', $whole_post );
379
+ check_and_publish_future_post( $thisDraft->ID );
380
+
381
+ if ( 0 == count( $draftList ) ) {
382
+ $finished = true;
383
+ }
384
+ $postsToday --;
385
+ endwhile;
386
+
387
+ return "Drafts updated!";
388
+ //return $query;
389
  }
390
 
391
+ /*
392
+ * function draftScheduler_random_post_by_interval
393
+ * Schedule drafts in random order, based on an interval
394
+ */
395
+ function draftScheduler_random_post_by_interval( $startDate, $intvHours, $intvMins ) {
396
+ /*
397
+ * $intvSecs, convert hours and minutes to seconds for the
398
+ * sql query
399
+ */
400
+
401
+ $intvSecs = ( $intvHours * 60 * 60 ) + ( $intvMins * 60 );
402
+
403
+ if ( isset( $_POST['draft_post_type'] ) ) {
404
+ $post_type = esc_attr( $_POST['draft_post_type'] );
405
+ } else {
406
+ $post_type = 'post';
407
+ }
408
+
409
+ $draftList = $this->draftScheduler_Scheduler( $post_type, 'rand' );
410
+
411
+ $this->draftScheduler_add_undo( $draftList );
412
+
413
+ if ( empty( $draftList ) ) {
414
+ return "No drafts were found";
415
+ }
416
+
417
+ $startDate = $startDate;
418
+
419
+ $ds_postDate = strtotime( $startDate );
420
+
421
+ foreach ( $draftList as $thisDraft ) {
422
+
423
+ $this->update_post_details( $ds_postDate, $thisDraft->ID );
424
+ $whole_post = get_post( $thisDraft->ID );
425
+ wp_transition_post_status( 'draft', 'future', $whole_post );
426
+ check_and_publish_future_post( $thisDraft->ID );
427
+
428
+ $ds_postDate += $intvSecs;
429
+ }
430
+
431
+ //$query = "update";
432
+ return "Drafts updated!";
433
+ } // End Function draftScheduler_random_post_by_interval
434
+
435
+ /*
436
+ * function draftScheduler_sequential_post_by_interval
437
+ * Schedule drafts in sequential order, based on an interval
438
+ */
439
+ function draftScheduler_sequential_post_by_interval( $startDate, $intvHours, $intvMins ) {
440
+ /*
441
+ * $intvSecs, convert hours and minutes to seconds for the
442
+ * sql query
443
+ */
444
+ $intvSecs = ( $intvHours * 60 * 60 ) + ( $intvMins * 60 );
445
+
446
+ if ( isset( $_POST['draft_post_type'] ) ) {
447
+ $post_type = esc_attr( $_POST['draft_post_type'] );
448
+ } else {
449
+ $post_type = 'post';
450
+ }
451
+
452
+ $draftList = $this->draftScheduler_Scheduler( $post_type, 'id' );
453
+ $this->draftScheduler_add_undo( $draftList );
454
+ if ( empty( $draftList ) ) {
455
+ return "No drafts were found";
456
+ }
457
+
458
+ $ds_postDate = strtotime( $startDate );
459
 
460
+ foreach ( $draftList as $thisDraft ) {
 
461
 
462
+ $this->update_post_details( $ds_postDate, $thisDraft->ID );
463
+ $whole_post = get_post( $thisDraft->ID );
464
+ wp_transition_post_status( 'draft', 'future', $whole_post );
465
+ check_and_publish_future_post( $thisDraft->ID );
466
 
467
+ $ds_postDate += $intvSecs;
468
+ }
469
+
470
+ return "Drafts updated!";
471
+
472
+ } // End Function draftScheduler_sequential_post_by_interval
473
+
474
+ function update_post_details( $ds_postDate, $draftID ) {
475
+ $ds_gmt = get_gmt_from_date( date( 'Y-n-j G:i:s', $ds_postDate ) );
476
+
477
+ $update_date = array(
478
+ 'ID' => $draftID,
479
+ 'post_date' => date_i18n( 'Y-n-j G:i:s', $ds_postDate ),
480
+ 'post_date_gmt' => $ds_gmt,
481
+ 'post_status' => 'future',
482
+ 'edit_date' => true
483
+ );
484
+
485
+ wp_update_post( $update_date );
486
+ }
487
+
488
+ /*
489
+ * function createDateTimeDropDowns
490
+ * generate a dropdown select list for 30 minute intervals
491
+ */
492
+ function createDateTimeDropDowns( $selected ) {
493
+ $outputHTML = '';
494
+ for ( $i = 0; $i <= 23; $i ++ ) {
495
+ if ( $i < 10 ) {
496
+ $hourTime = "0" . $i;
497
+ } else {
498
+ $hourTime = $i;
499
+ }
500
+ $outputHTML .= '<option value="' . $hourTime . ':00"';
501
+ if ( $hourTime . ":00" == $selected ) {
502
+ $outputHTML .= " selected='selected' ";
503
+ }
504
+ $outputHTML .= '>' . $hourTime . ':00</option>';
505
+ $outputHTML .= '<option value="' . $hourTime . ':30"';
506
+ if ( $hourTime . ":30" == $selected ) {
507
+ $outputHTML .= " selected='selected' ";
508
+ }
509
+ $outputHTML .= '>' . $hourTime . ':30</option>';
510
+ }
511
+
512
+ return $outputHTML;
513
+ } // End Function createDateTimeDropDowns
514
+
515
+ function draftScheduler_add_undo( $draftList ) {
516
+ if ( is_array( $draftList ) ) {
517
+ foreach ( $draftList as $draft ) {
518
+ $undoList[] = $draft->ID;
519
+ }
520
+ update_option( $this->ifds_option, $undoList );
521
+ }
522
+ }
523
+
524
+ function draftScheduler_check_for_drafts() {
525
+ if ( isset( $_POST['draft_post_type'] ) ) {
526
+ $post_type = esc_attr( $_POST['draft_post_type'] );
527
+ } else {
528
+ $post_type = 'post';
529
+ }
530
+ $draftCount = $this->draftScheduler_Scheduler( $post_type );
531
+
532
+ return $draftCount;
533
+ }
534
+
535
+ function select_with_post_types() {
536
+ $args = array(
537
+ 'public' => true,
538
+ );
539
+
540
+ $post_types = get_post_types( $args, 'objects' );
541
+
542
+ if ( ! ( empty( $post_types ) ) ) {
543
+ $type_select = '<select name="draft_post_type">';
544
+ foreach ( $post_types as $type ) {
545
+ if ( 'attachment' != $type->name ) {
546
+ $type_select .= '<option value="' . esc_attr( $type->name ) . '">' . $type->labels->name . '</option>';
547
+ }
548
+ }
549
+ $type_select .= '</select>';
550
+ }
551
+
552
+ return $type_select;
553
+ }
554
+ } // End Class DraftScheduler
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  } // End If
556
 
557
  $draftScheduler = new DraftScheduler();
558
 
559
+ function j_is_date( $str ) {
560
+ $stamp = strtotime( $str );
561
+
562
+ if ( ! is_numeric( $stamp ) ) {
563
+ return false;
564
+ }
565
+ $month = date( 'm', $stamp );
566
+ $day = date( 'd', $stamp );
567
+ $year = date( 'Y', $stamp );
568
+
569
+ if ( checkdate( $month, $day, $year ) ) {
570
+ return true;
571
+ }
572
+
573
+ return false;
574
+ }
 
 
 
575
 
576
  ?>
readme.txt CHANGED
@@ -3,14 +3,12 @@ Contributors: talus
3
  Donate link: http://www.installedforyou.com/wordpress/drafts-scheduler-plugin/
4
  Tags: drafts, scheduling, posts, schedule
5
  Requires at least: 2.8
6
- Tested up to: 3.3
7
- Stable tag: 1.7
8
 
9
  Sequentially or randomly schedule ALL draft posts for posting.
10
 
11
  == Description ==
12
- Last updated to 1.7 on Jan 2, 2012. Ignore the date on the right.
13
-
14
  Ever imported or written a whole bunch of posts in draft status, then realized you needed to post them all over time?
15
 
16
  If you've tried to do this manually, you know it takes a LONG time even using the Quick Edit.
@@ -48,7 +46,7 @@ Sorry, not in this version. In the future, it would be easy to add.
48
 
49
  = Can I schedule posts in my Custom Post Type? =
50
 
51
- Sorry, not in this version. In the future, it would be possible to add.
52
 
53
  = Ok, can I set drafts to a status other than Future? =
54
 
@@ -58,8 +56,11 @@ Again, sorry, not in this version. In the future, it would be easy to add.
58
 
59
 
60
  == Changelog ==
61
- = 1.7 =
62
- - Fixed the bug where random posts where only posting in the AM.
 
 
 
63
 
64
  = 1.6 =
65
  - Added Brian Zeligson's code contribution allowing randomly posting a number of posts per WEEK or per MONTH instead of just per DAY.
3
  Donate link: http://www.installedforyou.com/wordpress/drafts-scheduler-plugin/
4
  Tags: drafts, scheduling, posts, schedule
5
  Requires at least: 2.8
6
+ Tested up to: 4.0
7
+ Stable tag: 1.8
8
 
9
  Sequentially or randomly schedule ALL draft posts for posting.
10
 
11
  == Description ==
 
 
12
  Ever imported or written a whole bunch of posts in draft status, then realized you needed to post them all over time?
13
 
14
  If you've tried to do this manually, you know it takes a LONG time even using the Quick Edit.
46
 
47
  = Can I schedule posts in my Custom Post Type? =
48
 
49
+ Yes! This was added in version 1.8
50
 
51
  = Ok, can I set drafts to a status other than Future? =
52
 
56
 
57
 
58
  == Changelog ==
59
+ = 1.8 =
60
+ - NEW: Select a custom post type to schedule! Thanks for the suggestion everyone!
61
+ - Remove most use of $wpdb, so overall it's more "WordPress-y" in function. Yay.
62
+ - Update & tested with WordPress 4.0
63
+ - Bug fixes
64
 
65
  = 1.6 =
66
  - Added Brian Zeligson's code contribution allowing randomly posting a number of posts per WEEK or per MONTH instead of just per DAY.