feat(06-02): create scheduler helper class for email batch actions
- Created DDHH_JM_Scheduler class with static setup_hooks() method - Added schedule_mentor_notification_batch() method with 50-user batching - Uses as_enqueue_async_action() with unique flag and email-notifications group - Initialized in main plugin file and job manager class - Ready for Phase 06-03 to register async action callbacks
This commit is contained in:
@@ -42,6 +42,8 @@ require_once DDHH_JM_PLUGIN_DIR . 'includes/class-access-control.php';
|
||||
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-notifications.php';
|
||||
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-archive.php';
|
||||
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-admin-ui.php';
|
||||
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-user-preferences.php';
|
||||
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-scheduler.php';
|
||||
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-ddhh-job-manager.php';
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,5 +72,11 @@ class DDHH_JM_Job_Manager {
|
||||
if ( is_admin() ) {
|
||||
add_action( 'init', array( 'DDHH_JM_Admin_UI', 'setup_hooks' ) );
|
||||
}
|
||||
|
||||
// Initialize user preferences
|
||||
add_action( 'init', array( 'DDHH_JM_User_Preferences', 'setup_hooks' ) );
|
||||
|
||||
// Initialize scheduler for async email processing
|
||||
add_action( 'init', array( 'DDHH_JM_Scheduler', 'setup_hooks' ) );
|
||||
}
|
||||
}
|
||||
|
||||
84
includes/class-scheduler.php
Normal file
84
includes/class-scheduler.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* Action Scheduler Helper Class
|
||||
*
|
||||
* Manages async background jobs for email batch processing.
|
||||
*
|
||||
* @package DDHH_Job_Manager
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class DDHH_JM_Scheduler
|
||||
*
|
||||
* Provides API for scheduling async email batch processing via Action Scheduler.
|
||||
*/
|
||||
class DDHH_JM_Scheduler {
|
||||
|
||||
/**
|
||||
* Initialize hooks.
|
||||
*/
|
||||
public static function setup_hooks() {
|
||||
// Phase 06-03 will register async action callbacks here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule mentor notification batch processing.
|
||||
*
|
||||
* Chunks user IDs into batches of 50 and schedules async actions for each batch.
|
||||
* This prevents email provider limits and timeouts when sending to many mentors.
|
||||
*
|
||||
* @param array $user_ids Array of user IDs to notify.
|
||||
* @param int $job_id Job post ID for the notification.
|
||||
* @return int Number of batches scheduled.
|
||||
*/
|
||||
public static function schedule_mentor_notification_batch( $user_ids, $job_id ) {
|
||||
if ( empty( $user_ids ) || empty( $job_id ) ) {
|
||||
error_log( 'DDHH_JM_Scheduler: Cannot schedule batch - missing user IDs or job ID' );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Chunk user IDs into batches of 50.
|
||||
$batches = array_chunk( $user_ids, 50 );
|
||||
$batch_count = 0;
|
||||
|
||||
foreach ( $batches as $batch ) {
|
||||
// Enqueue async action for this batch.
|
||||
// Hook: ddhh_jm_send_mentor_notification_batch
|
||||
// Args: batch of user IDs and job ID
|
||||
// Group: email-notifications (for organization)
|
||||
// Unique: true (prevents duplicate scheduling)
|
||||
// Priority: 10 (standard priority)
|
||||
as_enqueue_async_action(
|
||||
'ddhh_jm_send_mentor_notification_batch',
|
||||
array(
|
||||
'user_ids' => $batch,
|
||||
'job_id' => $job_id,
|
||||
),
|
||||
'email-notifications',
|
||||
true,
|
||||
10
|
||||
);
|
||||
|
||||
$batch_count++;
|
||||
error_log( sprintf(
|
||||
'DDHH_JM_Scheduler: Scheduled batch %d with %d users for job ID %d',
|
||||
$batch_count,
|
||||
count( $batch ),
|
||||
$job_id
|
||||
) );
|
||||
}
|
||||
|
||||
error_log( sprintf(
|
||||
'DDHH_JM_Scheduler: Scheduled %d total batches for %d users for job ID %d',
|
||||
$batch_count,
|
||||
count( $user_ids ),
|
||||
$job_id
|
||||
) );
|
||||
|
||||
return $batch_count;
|
||||
}
|
||||
}
|
||||
138
includes/class-user-preferences.php
Normal file
138
includes/class-user-preferences.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* User preferences management
|
||||
*
|
||||
* @package DDHH_Job_Manager
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* User Preferences Class
|
||||
*
|
||||
* Manages user preferences including notification opt-in.
|
||||
*/
|
||||
class DDHH_JM_User_Preferences {
|
||||
|
||||
/**
|
||||
* User meta key for notification preference
|
||||
*/
|
||||
const META_KEY_NOTIFY = 'ddhh_jm_notify_new_jobs';
|
||||
|
||||
/**
|
||||
* Nonce action for preference saving
|
||||
*/
|
||||
const NONCE_ACTION = 'ddhh_jm_save_user_preferences';
|
||||
|
||||
/**
|
||||
* Setup hooks
|
||||
*/
|
||||
public static function setup_hooks() {
|
||||
// Display notification toggle on user profile
|
||||
add_action( 'show_user_profile', array( __CLASS__, 'show_notification_toggle' ) );
|
||||
add_action( 'edit_user_profile', array( __CLASS__, 'show_notification_toggle' ) );
|
||||
|
||||
// Save notification preference
|
||||
add_action( 'personal_options_update', array( __CLASS__, 'save_notification_preference' ) );
|
||||
add_action( 'edit_user_profile_update', array( __CLASS__, 'save_notification_preference' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display notification toggle on user profile
|
||||
*
|
||||
* @param WP_User $user User object.
|
||||
*/
|
||||
public static function show_notification_toggle( $user ) {
|
||||
// Only show for subscribers (mentors)
|
||||
if ( ! in_array( 'subscriber', $user->roles, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current preference
|
||||
$notify_enabled = get_user_meta( $user->ID, self::META_KEY_NOTIFY, true );
|
||||
|
||||
// Create nonce for security
|
||||
wp_nonce_field( self::NONCE_ACTION, 'ddhh_jm_user_preferences_nonce' );
|
||||
|
||||
?>
|
||||
<h2>Benachrichtigungen</h2>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">Stellenangebote</th>
|
||||
<td>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="ddhh_jm_notify_new_jobs"
|
||||
value="1"
|
||||
<?php checked( $notify_enabled, '1' ); ?>
|
||||
/>
|
||||
Benachrichtigungen über neue Stellenangebote erhalten
|
||||
</label>
|
||||
<p class="description">
|
||||
Sie erhalten eine E-Mail, wenn ein neues Stellenangebot veröffentlicht wird.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save notification preference
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
*/
|
||||
public static function save_notification_preference( $user_id ) {
|
||||
// Verify nonce
|
||||
if ( ! isset( $_POST['ddhh_jm_user_preferences_nonce'] ) ||
|
||||
! wp_verify_nonce( $_POST['ddhh_jm_user_preferences_nonce'], self::NONCE_ACTION ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check user capabilities
|
||||
if ( ! current_user_can( 'edit_user', $user_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get user to verify they're a subscriber
|
||||
$user = get_userdata( $user_id );
|
||||
if ( ! $user || ! in_array( 'subscriber', $user->roles, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save preference (checkbox pattern: isset = '1', not set = '0')
|
||||
$notify_value = isset( $_POST['ddhh_jm_notify_new_jobs'] ) ? '1' : '0';
|
||||
update_user_meta( $user_id, self::META_KEY_NOTIFY, $notify_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of user IDs who have opted in to notifications
|
||||
*
|
||||
* @return array Array of user IDs.
|
||||
*/
|
||||
public static function get_opted_in_mentors() {
|
||||
$args = array(
|
||||
'role' => 'subscriber',
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => self::META_KEY_NOTIFY,
|
||||
'value' => '1',
|
||||
),
|
||||
),
|
||||
'fields' => 'ID',
|
||||
);
|
||||
|
||||
$user_query = new WP_User_Query( $args );
|
||||
$user_ids = $user_query->get_results();
|
||||
|
||||
// Log if query fails
|
||||
if ( empty( $user_ids ) && ! is_array( $user_ids ) ) {
|
||||
error_log( 'DDHH Job Manager: Failed to query opted-in mentors' );
|
||||
return array();
|
||||
}
|
||||
|
||||
return is_array( $user_ids ) ? $user_ids : array();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user