logger = $logger; $this->get_logger()->debug( 'Initializing AJAX handlers', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, ] ); add_action( 'wp_ajax_f12_doi_details', [ $this, 'getDetails' ] ); add_action( 'wp_ajax_f12_doi_templateloader', [ $this, 'getTemplate' ] ); $this->get_logger()->info( 'AJAX handlers registered', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, ] ); } public function get_logger() { return $this->logger; } /** * Load and get the template we need. */ public function getTemplate() { // A nonce proves intent, not authorization — gate on capability too. if ( ! current_user_can( 'manage_options' ) ) { wp_die( -1, 403 ); } $this->get_logger()->debug( 'getTemplate called', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'post' => $_POST, ] ); $content = ''; if ( isset( $_POST['template'] ) && wp_verify_nonce( wp_unslash( $_POST['nonce'] ), 'f12_doi_templateloader' ) ) { // Use sanitize_file_name() to prevent path traversal attacks $template_name = sanitize_file_name( wp_unslash( $_POST['template'] ) ); $mails_dir = plugin_dir_path( dirname( __FILE__ ) ) . 'mails/'; $template_path = $mails_dir . $template_name . '.html'; // Verify the resolved path is within the allowed directory (prevent path traversal) $real_template_path = realpath( $template_path ); $real_mails_dir = realpath( $mails_dir ); if ( $real_template_path && $real_mails_dir && strpos( $real_template_path, $real_mails_dir ) === 0 && file_exists( $real_template_path ) ) { $this->get_logger()->debug( 'Template file found, loading content', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'template_path' => $template_path, ] ); $content = file_get_contents( $real_template_path ); } else { $this->get_logger()->warning( 'Template file not found', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'template_path' => $template_path, ] ); } } else { $this->get_logger()->warning( 'Invalid or missing nonce/template parameter', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'post' => $_POST, ] ); } echo wp_json_encode( [ 'status' => 200, 'content' => $content ] ); wp_die(); } /** * Return the Popup for the HASH DOI */ public function getDetails() { // Exposes opt-in PII (email, IPs, all form fields). A nonce proves // intent, not authorization — require the capability explicitly. if ( ! current_user_can( 'manage_options' ) ) { wp_die( -1, 403 ); } $this->get_logger()->debug( 'getDetails called', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'post' => $_POST, ] ); if ( isset( $_POST['hash'] ) && wp_verify_nonce( wp_unslash( $_POST['nonce'] ), 'f12_doi_details' ) ) { global $wpdb; $tableName = $wpdb->prefix . 'f12_cf7_doubleoptin'; $hash = sanitize_text_field( $_POST['hash'] ); $this->get_logger()->debug( 'Looking up OptIn by hash', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'hash' => $hash, ] ); $OptIn = OptIn::get_by_hash( $hash ); if ( null == $OptIn ) { $this->get_logger()->warning( 'OptIn not found for hash', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'hash' => $hash, ] ); ob_start(); ?>
200, 'content' => $content ] ); wp_die(); } $this->get_logger()->info( 'OptIn found', [ 'plugin' => 'double-opt-in', 'class' => __CLASS__, 'method' => __METHOD__, 'optin' => [ 'id' => $OptIn->get_id(), 'hash' => $OptIn->get_hash(), 'email' => $OptIn->get_email(), ], ] ); $formfields = maybe_unserialize( $OptIn->get_content() ); // Handle nested content structure (e.g., Avada stores {data: {...}, field_labels: {...}, ...}) if ( is_array( $formfields ) && isset( $formfields['data'] ) && is_array( $formfields['data'] ) && ! isset( $formfields['fields'] ) ) { $formfields = $formfields['data']; } ob_start(); ?>
| get_id() ); ?> | |
| get_cf_form_id() ); ?> | |
| get_createtime( 'formatted' ) ); ?> | |
| get_ipaddr_register() ); ?> | |
| is_confirmed() ) { echo esc_html( $OptIn->get_updatetime( 'formatted' ) ); } ?> | |
| get_ipaddr_confirmation() ); ?> |