YT Post Publish Scheduler
Schedule posts to automatically unpublish and republish at specified dates. Perfect for seasonal content, time-limited offers, and recurring announcements. Uses WordPress cron for reliable scheduling.
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/krasenslavov/yt-post-publish-scheduler/archive/refs/heads/main.zipA single-file WordPress plugin that automatically schedules posts to unpublish and republish at specified dates. Perfect for seasonal content, time-limited offers, and recurring announcements. Built following WordPress Coding Standards (WPCS).
Features
- Automatic Scheduling: Set unpublish and republish dates for any post type
- WordPress Cron: Uses built-in WP-Cron for reliable scheduling
- Activity Logging: Track all scheduling actions in a dedicated database table
- Email Notifications: Get notified when posts are unpublished/republished
- Flexible Post Types: Enable scheduling for posts, pages, and custom post types
- Admin Columns: See schedule information directly in the post list
- Meta Box UI: Easy-to-use datetime picker in the post editor
- Settings Page: Comprehensive admin settings with scheduled posts overview
- WPCS Compliant: Follows WordPress Coding Standards
- Secure: Proper sanitization, validation, escaping, and nonce verification
- Translation Ready: Full i18n/l10n support
- Single File: All code in one ~1055-line PHP file
Installation
- Download
class-yt-post-publish-scheduler.php - Upload to
/wp-content/plugins/directory - Activate through the 'Plugins' menu in WordPress
- Navigate to Settings → Publish Scheduler to configure
Quick Start
Basic Usage
- Edit any post (or enabled post type)
- Find the "Publish Schedule" meta box in the sidebar
- Set an Unpublish Date (when the post should be hidden)
- Optionally set a Republish Date (when it should go live again)
- Save/Update the post
The plugin will automatically handle the rest using WordPress cron!
Settings Configuration
Navigate to Settings → Publish Scheduler to configure:
- Enabled Post Types: Choose which post types support scheduling
- Unpublish Status: Select status for unpublished posts (draft, pending, private)
- Email Notifications: Enable/disable and set notification recipient
- Activity Logging: Track all scheduling actions
- Past Dates: Allow or prevent scheduling in the past (useful for testing)
- Timezone Display: Show dates in site timezone or UTC
Use Cases
Seasonal Content
Blog Post: "Summer Sale 2025"
├─ Unpublish Date: 2025-09-01 00:00
└─ Republish Date: 2026-06-01 00:00
Perfect for holiday content, seasonal promotions, or recurring events.
Time-Limited Offers
Landing Page: "Black Friday Deal"
├─ Unpublish Date: 2025-11-30 23:59
└─ Republish Date: (leave empty)
Automatically hide expired offers without manual intervention.
Content Rotation
Featured Post: "Monthly Spotlight"
├─ Unpublish Date: 2025-02-01 00:00
└─ Republish Date: 2025-03-01 00:00
Rotate featured content or announcements automatically.
File Structure
class-yt-post-publish-scheduler.php # Main plugin file (all code)
README.md # This documentation
Plugin Architecture
Constants Defined
YT_PPS_VERSION // Plugin version: 1.0.0
YT_PPS_BASENAME // Plugin basename
YT_PPS_PATH // Plugin directory path
YT_PPS_URL // Plugin directory URL
Database Structure
Creates table: wp_pps_logs
| Column | Type | Description |
|---|---|---|
| id | bigint(20) | Primary key |
| post_id | bigint(20) | Post ID |
| action | varchar(20) | unpublish or republish |
| old_status | varchar(20) | Previous post status |
| new_status | varchar(20) | New post status |
| scheduled_date | datetime | When action was scheduled |
| executed_date | datetime | When action was executed |
| success | tinyint(1) | Success flag |
| message | text | Optional error/info |
Post Meta Keys
_yt_pps_unpublish_date- Stores unpublish datetime (MySQL format)_yt_pps_republish_date- Stores republish datetime (MySQL format)
Cron Hooks
yt_pps_unpublish_post- Triggered when unpublish date arrivesyt_pps_republish_post- Triggered when republish date arrives
Main Class Methods
Core Methods
get_instance()- Singleton instance retrieval (class-yt-post-publish-scheduler.php:56)__construct()- Initialize plugin (class-yt-post-publish-scheduler.php:66)init_hooks()- Register WordPress hooks (class-yt-post-publish-scheduler.php:92)load_textdomain()- Load translations (class-yt-post-publish-scheduler.php:222)
Lifecycle Methods
activate()- Create database table and default settings (class-yt-post-publish-scheduler.php:129)deactivate()- Clear all scheduled events (class-yt-post-publish-scheduler.php:155)create_log_table()- Create activity log table (class-yt-post-publish-scheduler.php:165)clear_all_schedules()- Remove all cron events (class-yt-post-publish-scheduler.php:194)
Admin UI Methods
add_settings_page()- Add settings page to menu (class-yt-post-publish-scheduler.php:290)render_settings_page()- Display settings page (class-yt-post-publish-scheduler.php:343)register_settings()- Register plugin options (class-yt-post-publish-scheduler.php:303)sanitize_options()- Sanitize user input (class-yt-post-publish-scheduler.php:320)enqueue_admin_assets()- Load CSS/JS on admin pages (class-yt-post-publish-scheduler.php:235)
Meta Box Methods
add_meta_box()- Register meta box for enabled post types (class-yt-post-publish-scheduler.php:598)render_meta_box()- Display scheduling UI in post editor (class-yt-post-publish-scheduler.php:616)save_meta_box()- Save scheduling data and register cron events (class-yt-post-publish-scheduler.php:684)
Scheduling Methods
unpublish_post()- Change post status to configured unpublish status (class-yt-post-publish-scheduler.php:754)republish_post()- Change post status back to publish (class-yt-post-publish-scheduler.php:795)log_action()- Record action in database log (class-yt-post-publish-scheduler.php:840)send_notification()- Send email notification (class-yt-post-publish-scheduler.php:869)
Display Methods
add_admin_columns()- Add schedule column to post list (class-yt-post-publish-scheduler.php:919)render_admin_columns()- Display schedule info in column (class-yt-post-publish-scheduler.php:930)render_scheduled_posts_table()- Show all scheduled posts (class-yt-post-publish-scheduler.php:475)render_activity_log()- Show recent activity log (class-yt-post-publish-scheduler.php:515)
AJAX Handlers
ajax_clear_schedule()- Clear scheduling via AJAX (class-yt-post-publish-scheduler.php:988)ajax_get_scheduled_posts()- Fetch scheduled posts via AJAX (class-yt-post-publish-scheduler.php:1015)
Utility Methods
format_date()- Format datetime for display (class-yt-post-publish-scheduler.php:905)get_scheduled_posts()- Query all posts with schedules (class-yt-post-publish-scheduler.php:574)
Admin Interface
Settings Page
Located at Settings → Publish Scheduler
Configuration Options:
- Select enabled post types
- Choose unpublish status (draft/pending/private)
- Configure email notifications
- Enable/disable activity logging
- Allow past dates for testing
- Set timezone display preference
Overview Sections:
- Scheduled Posts Table: View all posts with active schedules
- Recent Activity Log: See last 50 scheduling actions (if logging enabled)
Post Editor Meta Box
Located in the sidebar of the post editor (for enabled post types).
Fields:
- Unpublish Date: datetime-local input
- Republish Date: datetime-local input
- Clear Schedule: Button to remove scheduling
Shows current schedule status with clock icons.
Admin Columns
A new "Schedule" column appears in the post list showing:
- ↓ Unpublish date (down arrow)
- ↑ Republish date (up arrow)
Security Features
✅ Implemented Security Measures:
- Direct file access prevention (
ABSPATHcheck) - Capability checks (
manage_options,edit_post) - Nonce verification for form submissions and AJAX
- Input sanitization (
sanitize_text_field(),sanitize_email(),sanitize_key()) - Output escaping (
esc_html(),esc_attr(),esc_url()) - SQL injection prevention (proper
$wpdbusage with types) - AJAX nonce verification
- Post type validation
Developer Hooks
Actions
// Before unpublishing (custom hook - add to plugin if needed)
do_action( 'yt_pps_before_unpublish', $post_id );
// Before republishing (custom hook - add to plugin if needed)
do_action( 'yt_pps_before_republish', $post_id );
Filters
// Modify unpublish status
add_filter( 'yt_pps_unpublish_status', function( $status, $post_id ) {
return 'private'; // Force private instead of draft
}, 10, 2 );
// Modify notification email
add_filter( 'yt_pps_notification_email', function( $email, $post_id, $action ) {
return 'custom@example.com';
}, 10, 3 );
Programmatic Access
// Get plugin instance
$scheduler = YT_Post_Publish_Scheduler::get_instance();
// Schedule a post programmatically
$post_id = 123;
update_post_meta( $post_id, '_yt_pps_unpublish_date', '2025-12-31 23:59:59' );
update_post_meta( $post_id, '_yt_pps_republish_date', '2026-01-01 00:00:00' );
$unpublish_timestamp = strtotime( get_gmt_from_date( '2025-12-31 23:59:59' ) );
$republish_timestamp = strtotime( get_gmt_from_date( '2026-01-01 00:00:00' ) );
wp_schedule_single_event( $unpublish_timestamp, 'yt_pps_unpublish_post', array( $post_id ) );
wp_schedule_single_event( $republish_timestamp, 'yt_pps_republish_post', array( $post_id ) );
// Clear a schedule
wp_clear_scheduled_hook( 'yt_pps_unpublish_post', array( $post_id ) );
wp_clear_scheduled_hook( 'yt_pps_republish_post', array( $post_id ) );
delete_post_meta( $post_id, '_yt_pps_unpublish_date' );
delete_post_meta( $post_id, '_yt_pps_republish_date' );
Troubleshooting
Scheduled Posts Not Executing
Problem: Posts aren't unpublishing/republishing at the scheduled time.
Solutions:
- Check WP-Cron: WordPress cron requires site traffic or a real cron job
# Add to system cron (recommended for production) */15 * * * * wget -q -O - https://yoursite.com/wp-cron.php?doing_wp_cron - Disable WP-Cron and use system cron in
wp-config.php:define('DISABLE_WP_CRON', true); - Check scheduled events using a plugin like "WP Crontrol"
- Verify server timezone matches WordPress timezone
Past Dates Not Working
Problem: Can't select dates in the past.
Solution: Enable "Allow Past Dates" in Settings → Publish Scheduler. This is disabled by default to prevent accidental backdating.
Email Notifications Not Sending
Problem: Not receiving email notifications.
Solutions:
- Verify email address in plugin settings
- Check spam/junk folders
- Test WordPress email functionality with a plugin like "Check Email"
- Configure SMTP plugin (WP Mail SMTP recommended)
Activity Log Not Showing
Problem: Activity log is empty.
Solution: Enable "Log Actions" in plugin settings. Historical actions won't be logged retroactively.
Testing Checklist
- [x] Plugin activates without errors
- [x] Settings page displays correctly
- [x] Settings save properly with validation
- [x] Meta box appears on enabled post types
- [x] Unpublish schedule executes correctly
- [x] Republish schedule executes correctly
- [x] Email notifications send successfully
- [x] Activity log records actions
- [x] Admin columns display schedule info
- [x] AJAX clear schedule works
- [x] Cron events clear on deactivation
- [x] No PHP warnings or notices
- [x] Compatible with WordPress 5.8+
- [x] Works with PHP 7.4+
WPCS Validation
Run PHP_CodeSniffer with WordPress standards:
phpcs --standard=WordPress class-yt-post-publish-scheduler.php
Requirements
- WordPress: 5.8 or higher
- PHP: 7.4 or higher
- Database: MySQL 5.6+ or MariaDB 10.1+
License
GPL v2 or later
Author
Krasen Slavov
Credits
Built following WordPress Plugin Handbook and WPCS guidelines.
Support
For issues and feature requests, visit:
Releases
2 releases.
These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.