settings = get_option('alertify_options', array()); // Schedule cron job add_action('init', array($this, 'schedule_cron')); add_action('alertify_send_notifications', array($this, 'process_notifications')); // Add settings add_action('admin_init', array($this, 'register_settings')); } public function register_settings() { register_setting( 'alertify_email_options', 'alertify_options', array( 'type' => 'array', 'sanitize_callback' => array($this, 'sanitize_email_settings'), 'default' => array( 'emails_per_hour' => 50, 'email_template' => $this->get_default_template() ) ) ); add_settings_section( 'alertify_email_settings', esc_html__('Email Settings', 'alertify'), null, 'alertify_email_options' ); add_settings_field( 'emails_per_hour', esc_html__('Emails Per Hour', 'alertify'), array($this, 'render_emails_per_hour_field'), 'alertify_email_options', 'alertify_email_settings' ); add_settings_field( 'email_template', esc_html__('Email Template', 'alertify'), array($this, 'render_email_template_field'), 'alertify_email_options', 'alertify_email_settings' ); } public function render_emails_per_hour_field() { $value = isset($this->settings['emails_per_hour']) ? $this->settings['emails_per_hour'] : 50; ?>

get_default_template(); $value = isset($this->settings['email_template']) ? $this->settings['email_template'] : $default_template; ?>


{customer_name} -
{product_name} -
{product_link} -
{site_name} -
{product_price} -
{product_sku} -
{product_image} -
{unsubscribe_link} -

settings['emails_per_hour']) ? intval($this->settings['emails_per_hour']) : 50; $email_template = isset($this->settings['email_template']) ? $this->settings['email_template'] : $this->get_default_template(); // Try to get notifications from cache first $notifications = wp_cache_get('alertify_pending_notifications', 'alertify'); if (false === $notifications) { // Cache miss - get from database // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery $notifications = $wpdb->get_results( $wpdb->prepare( "SELECT s.*, p.post_title as product_name FROM {$wpdb->prefix}alertify_subscriptions s JOIN {$wpdb->posts} p ON s.product_id = p.ID WHERE s.status = 'pending' AND EXISTS ( SELECT 1 FROM {$wpdb->postmeta} WHERE post_id = s.product_id AND meta_key = '_stock_status' AND meta_value = 'instock' ) LIMIT %d", $emails_per_hour ) ); // Cache the results for 5 minutes wp_cache_set('alertify_pending_notifications', $notifications, 'alertify', 5 * MINUTE_IN_SECONDS); } foreach ($notifications as $notification) { $product = wc_get_product($notification->product_id); if (!$product) continue; // Get product image $image = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'medium'); $image_html = $image ? '' : ''; // Generate unsubscribe link $unsubscribe_link = add_query_arg(array( 'alertify_unsubscribe' => base64_encode($notification->email), 'token' => wp_create_nonce('alertify_unsubscribe_' . $notification->email) ), home_url()); $replacements = array( '{customer_name}' => $notification->name, '{product_name}' => $product->get_name(), '{product_link}' => $product->get_permalink(), '{site_name}' => get_bloginfo('name'), '{product_price}' => wc_price($product->get_price()), '{product_sku}' => $product->get_sku(), '{product_image}' => $image_html, '{unsubscribe_link}' => $unsubscribe_link ); $email_content = str_replace( array_keys($replacements), array_values($replacements), $email_template ); $headers = array('Content-Type: text/html; charset=UTF-8'); $subject = sprintf( /* translators: 1: Site name, 2: Product name - Email subject when product is back in stock */ esc_html__('[%1$s] %2$s is back in stock', 'alertify'), get_bloginfo('name'), $product->get_name() ); $sent = wp_mail( $notification->email, $subject, $email_content, $headers ); if ($sent) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery $wpdb->update( $wpdb->prefix . 'alertify_subscriptions', array( 'status' => 'notified', 'notified_at' => current_time('mysql') ), array('id' => $notification->id), array('%s', '%s'), array('%d') ); } } } public function test_email($email) { $template = isset($this->settings['email_template']) ? $this->settings['email_template'] : $this->get_default_template(); // Get a sample product for test $products = wc_get_products(array('limit' => 1)); $product = !empty($products) ? $products[0] : null; if ($product) { $image = wp_get_attachment_image_src(get_post_thumbnail_id($product->get_id()), 'medium'); $image_html = $image ? '' : ''; } // Generate test unsubscribe link $unsubscribe_link = add_query_arg(array( 'alertify_unsubscribe' => base64_encode($email), 'token' => wp_create_nonce('alertify_unsubscribe_' . $email) ), home_url()); $replacements = array( '{customer_name}' => 'Test User', '{product_name}' => $product ? $product->get_name() : 'Test Product', '{product_link}' => $product ? $product->get_permalink() : site_url(), '{site_name}' => get_bloginfo('name'), '{product_price}' => $product ? wc_price($product->get_price()) : wc_price(99.99), '{product_sku}' => $product ? $product->get_sku() : 'TEST-SKU-123', '{product_image}' => isset($image_html) ? $image_html : '', '{unsubscribe_link}' => $unsubscribe_link ); $email_content = str_replace( array_keys($replacements), array_values($replacements), $template ); $headers = array('Content-Type: text/html; charset=UTF-8'); $subject = sprintf( /* translators: %s: Site name - Test email subject */ esc_html__('[%s] Test Back in Stock Notification', 'alertify'), get_bloginfo('name') ); return wp_mail($email, $subject, $email_content, $headers); } public function sanitize_email_settings($input) { if (!is_array($input)) { return array(); } $sanitized = array(); // Sanitize emails per hour $sanitized['emails_per_hour'] = isset($input['emails_per_hour']) ? absint($input['emails_per_hour']) : 50; // Ensure emails_per_hour is between 1 and 100 $sanitized['emails_per_hour'] = min(100, max(1, $sanitized['emails_per_hour'])); // Sanitize email template $sanitized['email_template'] = isset($input['email_template']) ? wp_kses_post($input['email_template']) : $this->get_default_template(); return $sanitized; } } new ALERTIFY_Email();