(string) get_option( 'admin_email' ), 'sender_name' => '', 'sender_email' => '', 'submissions_per_hour' => 10, 'auto_delete_days' => 0, 'delete_on_uninstall' => false, 'turnstile_site_key' => '', 'turnstile_secret_key' => '', 'hcaptcha_site_key' => '', 'hcaptcha_secret_key' => '', 'spam_method' => '', 'spam_questions' => '', 'spam_blocklist' => '', 'spam_max_links' => 3, 'spam_min_seconds' => 2, ); } function pubforms_get_settings() { $defaults = pubforms_settings_defaults(); return array( 'default_notify_email' => (string) get_option( 'pubforms_default_notify_email', $defaults['default_notify_email'] ), 'sender_name' => (string) get_option( 'pubforms_sender_name', '' ), 'sender_email' => (string) get_option( 'pubforms_sender_email', '' ), 'submissions_per_hour' => (int) get_option( 'pubforms_submissions_per_hour', $defaults['submissions_per_hour'] ), 'auto_delete_days' => (int) get_option( 'pubforms_auto_delete_days', 0 ), 'delete_on_uninstall' => (bool) get_option( 'pubforms_delete_on_uninstall', false ), 'turnstile_site_key' => (string) get_option( 'pubforms_turnstile_site_key', '' ), 'turnstile_secret_key' => (string) get_option( 'pubforms_turnstile_secret_key', '' ), 'hcaptcha_site_key' => (string) get_option( 'pubforms_hcaptcha_site_key', '' ), 'hcaptcha_secret_key' => (string) get_option( 'pubforms_hcaptcha_secret_key', '' ), 'spam_method' => pubforms_site_spam_method(), 'spam_questions' => (string) get_option( 'pubforms_spam_questions', '' ), 'spam_blocklist' => (string) get_option( 'pubforms_spam_blocklist', '' ), 'spam_max_links' => (int) get_option( 'pubforms_spam_max_links', $defaults['spam_max_links'] ), 'spam_min_seconds' => (int) get_option( 'pubforms_spam_min_seconds', $defaults['spam_min_seconds'] ), ); } /** * Says how notification emails will be delivered. PubForms always sends with wp_mail(), so a mail * plugin that takes over WordPress email (such as PubMail) handles form emails with no extra setup. */ function pubforms_render_mail_status() { if ( function_exists( 'pubmail_configured' ) ) { if ( pubmail_configured() ) { echo '

' . esc_html__( 'PubMail is set up, so form notifications and auto-replies are sent through it.', 'pubforms' ) . '

'; } else { $url = admin_url( 'admin.php?page=pubmail' ); echo '

' . wp_kses_post( sprintf( /* translators: %s: link to the PubMail settings */ __( 'PubMail is active but not set up yet. Connect it to your mail service and form emails will go through it.', 'pubforms' ), esc_url( $url ) ) ) . '

'; } return; } echo '

' . esc_html__( 'Form emails use your site\'s normal WordPress mail. If notifications do not arrive, connect a mail plugin (such as PubMail or any SMTP plugin); PubForms will send through it automatically.', 'pubforms' ) . '

'; } /** * A write-only field for a secret. The saved value is never sent to the browser: the box is a password * input that starts empty, leaving it empty keeps the saved secret, and a checkbox removes it. */ function pubforms_render_secret_field( $key, $saved, $label ) { $name = 'pubforms_settings[' . $key . ']'; ?>

__( 'The secret key is wrong. Re-enter it and save.', 'pubforms' ), 'missing-input-secret' => __( 'No secret key is saved.', 'pubforms' ), 'invalid-or-already-seen-response' => __( 'That token was already used. Run the test again.', 'pubforms' ), 'timeout-or-duplicate' => __( 'That token expired or was already used. Run the test again.', 'pubforms' ), 'invalid-input-response' => __( 'The provider rejected the token. Check that the site key and secret key belong to the same widget.', 'pubforms' ), 'missing-input-response' => __( 'No token was received from the widget.', 'pubforms' ), 'sitekey-secret-mismatch' => __( 'The site key and secret key do not belong together.', 'pubforms' ), 'not-using-dummy-passcode' => __( 'The keys are test keys that do not match.', 'pubforms' ), ); $out = array(); foreach ( (array) $codes as $code ) { $out[] = $known[ $code ] ?? $code; } return implode( ' ', $out ); } add_action( 'wp_ajax_pubforms_test_captcha', function () { check_ajax_referer( 'pubforms_test_captcha', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'You do not have permission to do that.', 'pubforms' ) ), 403 ); } $provider = sanitize_key( wp_unslash( $_POST['provider'] ?? '' ) ); $token = sanitize_text_field( wp_unslash( $_POST['token'] ?? '' ) ); if ( ! in_array( $provider, array( 'turnstile', 'hcaptcha' ), true ) || '' === $token ) { wp_send_json_error( array( 'message' => __( 'Nothing to check.', 'pubforms' ) ) ); } $check = pubforms_siteverify( $provider, $token ); if ( $check['unreachable'] ) { /* translators: %s: error from the HTTP request */ wp_send_json_error( array( 'message' => sprintf( __( 'Could not reach the provider to verify the token: %s', 'pubforms' ), implode( ' ', $check['errors'] ) ) ) ); } if ( ! $check['success'] ) { $reason = pubforms_captcha_error_text( $check['errors'] ); wp_send_json_error( array( 'message' => '' !== $reason ? $reason : __( 'The provider rejected the token.', 'pubforms' ) ) ); } $host = (string) wp_parse_url( home_url(), PHP_URL_HOST ); $message = __( 'Working. The widget loaded on this domain and your secret key verified it.', 'pubforms' ); if ( '' !== $check['hostname'] && '' !== $host && strtolower( $check['hostname'] ) !== strtolower( $host ) ) { /* translators: 1: hostname the provider reports, 2: this site's hostname */ $message .= ' ' . sprintf( __( 'Note: the provider reports the hostname "%1$s", while this site is "%2$s".', 'pubforms' ), $check['hostname'], $host ); } wp_send_json_success( array( 'message' => $message ) ); } ); add_action( 'admin_enqueue_scripts', function ( $hook ) { if ( 'pubforms_form_page_pubforms-settings' !== $hook ) { return; } wp_enqueue_script( 'pubforms-settings', PUBFORMS_URL . 'assets/admin-settings.js', array(), pubforms_asset_version( 'admin-settings.js' ), true ); wp_localize_script( 'pubforms-settings', 'pubformsTest', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'pubforms_test_captcha' ), 'keys' => array( 'turnstile' => pubforms_spam_keys( 'turnstile' )['site'], 'hcaptcha' => pubforms_spam_keys( 'hcaptcha' )['site'], ), 'i18n' => array( 'loading' => __( 'Loading the widget…', 'pubforms' ), 'solve' => __( 'Complete the check above to finish the test.', 'pubforms' ), 'verify' => __( 'Verifying with the provider…', 'pubforms' ), 'failed' => __( 'The widget could not run on this domain. Check that this domain is allowed for the site key in your provider dashboard.', 'pubforms' ), 'network' => __( 'The request failed. Check your connection and try again.', 'pubforms' ), ), ) ); } ); function pubforms_suggested_privacy_text() { $text = __( 'Forms built with PubForms store what visitors type in your WordPress database so you can read it in your dashboard. No visitor IP address or browser details are collected. You can export or delete a person\'s submissions using the built-in privacy tools under Settings → Privacy → Personal Data. If enabled, entries are also deleted automatically after a set number of days. Files that visitors upload and signatures they draw are stored in a private folder and are only available to signed-in users who can edit the form. If a form is set to save unfinished answers, what a visitor has typed may be saved when they leave the page without submitting, and the form says so.', 'pubforms' ); $method = pubforms_site_spam_method(); if ( 'turnstile' === $method || 'hcaptcha' === $method ) { /* translators: %s: provider name, Cloudflare Turnstile or hCaptcha */ $text .= ' ' . sprintf( __( 'Forms on this site use %s to block spam. When a visitor opens such a form, their browser connects to that provider to complete a check, which is subject to the provider\'s own privacy policy.', 'pubforms' ), pubforms_spam_methods()[ $method ] ); } return $text; } // Offer the same wording in the WordPress privacy-policy guide (Settings → Privacy). add_action( 'admin_init', function () { if ( function_exists( 'wp_add_privacy_policy_content' ) ) { wp_add_privacy_policy_content( 'PubForms', wp_kses_post( wpautop( pubforms_suggested_privacy_text() ) ) ); } } ); function pubforms_render_settings_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to access this page.', 'pubforms' ) ); } $s = pubforms_get_settings(); ?>


'pubforms_form', 'page' => 'pubforms-settings', 'updated' => '1' ), admin_url( 'edit.php' ) ) ); exit; } ); /* ---------------------------------------------------- Privacy tools */ add_filter( 'wp_privacy_personal_data_exporters', function ( $exporters ) { $exporters['pubforms'] = array( 'exporter_friendly_name' => __( 'PubForms submissions', 'pubforms' ), 'callback' => function ( $email ) { $data = array(); foreach ( pubforms_entries_by_email( $email ) as $entry ) { $items = array(); foreach ( $entry->items as $item ) { $items[] = array( 'name' => (string) ( $item['label'] ?? '' ), 'value' => (string) ( $item['value'] ?? '' ) ); } array_unshift( $items, array( 'name' => __( 'Submitted', 'pubforms' ), 'value' => $entry->created_at, ) ); $data[] = array( 'group_id' => 'pubforms', 'group_label' => __( 'PubForms submissions', 'pubforms' ), 'item_id' => 'pubforms-entry-' . $entry->id, 'data' => $items, ); } return array( 'data' => $data, 'done' => true ); }, ); return $exporters; } ); add_filter( 'wp_privacy_personal_data_erasers', function ( $erasers ) { $erasers['pubforms'] = array( 'eraser_friendly_name' => __( 'PubForms submissions', 'pubforms' ), 'callback' => function ( $email ) { $count = 0; foreach ( pubforms_entries_by_email( $email ) as $entry ) { if ( pubforms_delete_entry( $entry->id ) ) { $count++; } } return array( 'items_removed' => $count, 'items_retained' => 0, 'messages' => array(), 'done' => true ); }, ); return $erasers; } ); /* ------------------------------------------- Automatic entry deletion */ add_action( 'pubforms_purge_entries', function () { pubforms_delete_entries_older_than( (int) get_option( 'pubforms_auto_delete_days', 0 ) ); } ); add_action( 'admin_init', function () { $days = (int) get_option( 'pubforms_auto_delete_days', 0 ); $next = wp_next_scheduled( 'pubforms_purge_entries' ); if ( $days > 0 && ! $next ) { wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'pubforms_purge_entries' ); } elseif ( $days <= 0 && $next ) { wp_unschedule_event( $next, 'pubforms_purge_entries' ); } } );