api = $api; add_shortcode( 'woolist_newsletter', [ $this, 'render_shortcode' ] ); // Register AJAX handlers for logged-in and guest visitors. add_action( 'wp_ajax_woolist_newsletter_submit', [ $this, 'handle_ajax' ] ); add_action( 'wp_ajax_nopriv_woolist_newsletter_submit', [ $this, 'handle_ajax' ] ); // Enqueue front-end assets. add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_assets' ] ); } /** * Enqueue CSS and JS for the newsletter form. */ public function enqueue_assets(): void { wp_enqueue_style( 'woolist-public', WOOLIST_URL . 'assets/css/woolist-public.css', [], WOOLIST_VERSION ); wp_enqueue_script( 'woolist-public', WOOLIST_URL . 'assets/js/woolist-public.js', [ 'jquery' ], WOOLIST_VERSION, true ); wp_localize_script( 'woolist-public', 'woolist', [ 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'woolist_newsletter_nonce' ), 'i18n' => [ 'subscribing' => __( 'Subscribing…', 'woolist-phplist' ), 'subscribe' => __( 'Subscribe', 'woolist-phplist' ), 'error' => __( 'Something went wrong. Please try again.', 'woolist-phplist' ), ], ] ); } /** * Render the [woolist_newsletter] shortcode. * * @return string HTML output. */ public function render_shortcode(): string { if ( get_option( 'woolist_sync_newsletter' ) !== 'yes' ) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG && current_user_can( 'manage_options' ) ) { return ''; } return ''; } ob_start(); ?>
__( 'Security check failed. Please refresh and try again.', 'woolist-phplist' ) ], 403 ); } // 2. Validate email. $email = isset( $_POST['woolist_email'] ) ? sanitize_email( wp_unslash( $_POST['woolist_email'] ) ) : ''; if ( ! is_email( $email ) ) { WooList_Logger::debug( 'Newsletter AJAX: invalid email submitted' ); wp_send_json_error( [ 'message' => __( 'Please enter a valid email address.', 'woolist-phplist' ) ], 400 ); } WooList_Logger::debug( 'Newsletter AJAX: submission received email=' . $email ); // 3. Get list ID. $list_id = (int) get_option( 'woolist_newsletter_list_id', 0 ); if ( $list_id < 1 ) { WooList_Logger::error( 'Newsletter AJAX: no list ID configured' ); wp_send_json_error( [ 'message' => __( 'Newsletter is not configured. Please contact the site administrator.', 'woolist-phplist' ) ], 500 ); } // 4. Subscribe email to phpList. $result = $this->api->subscribe_email_to_list( $email, $list_id ); if ( ! $result['success'] ) { WooList_Logger::error( 'Newsletter AJAX: subscription failed email=' . $email ); wp_send_json_error( [ 'message' => __( 'Could not subscribe your email. Please try again later.', 'woolist-phplist' ) ], 500 ); } // 5. Handle coupon generation. $coupon_code = ''; $thankyou_msg = get_option( 'woolist_newsletter_thankyou', __( 'Thank you for subscribing!', 'woolist-phplist' ) ); if ( get_option( 'woolist_newsletter_enable_coupon' ) === 'yes' ) { $coupon_mode = get_option( 'woolist_coupon_mode', 'fixed' ); if ( $coupon_mode === 'fixed' ) { $coupon_code = sanitize_text_field( get_option( 'woolist_coupon_fixed_code', '' ) ); WooList_Logger::debug( 'Newsletter AJAX: using fixed coupon code=' . $coupon_code ); } else { $coupon_code = $this->generate_coupon( $email ); WooList_Logger::info( 'Newsletter AJAX: generated coupon code=' . $coupon_code . ' email=' . $email ); } } // Replace {coupon} placeholder in the thank-you message. $thankyou_msg = str_replace( '{coupon}', esc_html( $coupon_code ), $thankyou_msg ); WooList_Logger::info( 'Newsletter AJAX: success email=' . $email ); wp_send_json_success( [ 'message' => wp_kses_post( $thankyou_msg ), 'coupon' => $coupon_code, ] ); } /** * Generate a unique WooCommerce percentage coupon for the subscriber. * * @param string $email Subscriber email. * @return string Generated coupon code, or empty string on failure. */ private function generate_coupon( string $email ): string { if ( ! class_exists( 'WC_Coupon' ) ) { WooList_Logger::error( 'WC_Coupon class not available; cannot generate coupon.' ); return ''; } $discount_pct = (int) get_option( 'woolist_coupon_discount_pct', 10 ); $expiry_days = (int) get_option( 'woolist_coupon_expiry_days', 30 ); $coupon_code = 'WOOLIST-' . strtoupper( substr( md5( $email . time() ), 0, 8 ) ); WooList_Logger::debug( 'Generating coupon code=' . $coupon_code . ' discount=' . $discount_pct . '% expiry_days=' . $expiry_days ); $expiry_date = ''; if ( $expiry_days > 0 ) { $expiry_date = gmdate( 'Y-m-d', strtotime( '+' . $expiry_days . ' days' ) ); } $post_id = wp_insert_post( [ 'post_title' => $coupon_code, 'post_name' => $coupon_code, 'post_status' => 'publish', 'post_type' => 'shop_coupon', 'post_excerpt' => 'WooList newsletter signup coupon for ' . $email, ], true ); if ( is_wp_error( $post_id ) ) { WooList_Logger::error( 'Failed to create coupon post error=' . $post_id->get_error_message() ); return ''; } update_post_meta( $post_id, 'discount_type', 'percent' ); update_post_meta( $post_id, 'coupon_amount', (string) $discount_pct ); update_post_meta( $post_id, 'usage_limit', '1' ); update_post_meta( $post_id, 'usage_limit_per_user', '1' ); update_post_meta( $post_id, 'individual_use', 'yes' ); update_post_meta( $post_id, 'customer_email', [ $email ] ); if ( $expiry_date ) { update_post_meta( $post_id, 'date_expires', strtotime( $expiry_date ) ); } WooList_Logger::debug( 'Coupon created post_id=' . $post_id . ' code=' . $coupon_code . ' expires=' . ( $expiry_date ?: 'never' ) ); return $coupon_code; } }