Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
demountable
/
wp-content
/
plugins
/
sureforms
/
admin
:
analytics-20251105103201.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php /** * Analytics class helps to connect BSFAnalytics. * * @package sureforms. */ namespace SRFM\Admin; use SRFM\Inc\Database\Tables\Entries; use SRFM\Inc\Helper; use SRFM\Inc\Traits\Get_Instance; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Analytics class. * * @since 1.4.0 */ class Analytics { use Get_Instance; /** * Class constructor. * * @return void * @since 1.4.0 */ public function __construct() { /* * BSF Analytics. */ if ( ! class_exists( 'BSF_Analytics_Loader' ) ) { require_once SRFM_DIR . 'inc/lib/bsf-analytics/class-bsf-analytics-loader.php'; } if ( ! class_exists( 'Astra_Notices' ) ) { require_once SRFM_DIR . 'inc/lib/astra-notices/class-astra-notices.php'; } add_filter( 'uds_survey_allowed_screens', static function () { return [ 'plugins' ]; } ); $srfm_bsf_analytics = \BSF_Analytics_Loader::get_instance(); $srfm_bsf_analytics->set_entity( [ 'sureforms' => [ 'product_name' => 'SureForms', 'path' => SRFM_DIR . 'inc/lib/bsf-analytics', 'author' => 'SureForms', 'time_to_display' => '+24 hours', 'deactivation_survey' => apply_filters( 'srfm_deactivation_survey_data', [ [ 'id' => 'deactivation-survey-sureforms', 'popup_logo' => SRFM_URL . 'admin/assets/sureforms-logo.png', 'plugin_slug' => 'sureforms', 'popup_title' => 'Quick Feedback', 'support_url' => 'https://sureforms.com/contact/', 'popup_description' => 'If you have a moment, please share why you are deactivating SureForms:', 'show_on_screens' => [ 'plugins' ], 'plugin_version' => SRFM_VER, ], ] ), 'hide_optin_checkbox' => true, ], ] ); add_filter( 'bsf_core_stats', [ $this, 'add_srfm_analytics_data' ] ); } /** * Callback function to add SureForms specific analytics data. * * @param array $stats_data existing stats_data. * @since 1.4.0 * @return array */ public function add_srfm_analytics_data( $stats_data ) { $stats_data['plugin_data']['sureforms'] = [ 'free_version' => SRFM_VER, 'site_language' => get_locale(), 'most_used_anti_spam' => $this->most_used_anti_spam(), 'user_status' => $this->user_status(), 'pointer_popup_clicked' => $this->pointer_popup_clicked(), ]; $stats_data['plugin_data']['sureforms']['numeric_values'] = [ 'total_forms' => wp_count_posts( SRFM_FORMS_POST_TYPE )->publish ?? 0, 'instant_forms_enabled' => $this->instant_forms_enabled(), 'forms_using_custom_css' => $this->forms_using_custom_css(), 'ai_generated_forms' => $this->ai_generated_forms(), 'total_entries' => Entries::get_total_entries_by_status(), 'restricted_forms' => $this->get_restricted_forms(), ]; $stats_data['plugin_data']['sureforms'] = array_merge_recursive( $stats_data['plugin_data']['sureforms'], $this->global_settings_data() ); // Add onboarding analytics data. $stats_data['plugin_data']['sureforms'] = array_merge_recursive( $stats_data['plugin_data']['sureforms'], $this->onboarding_analytics_data() ); return $stats_data; } /** * Return total number of forms using instant forms. * * @since 1.4.0 * @return int */ public function instant_forms_enabled() { $meta_query = [ [ 'key' => '_srfm_instant_form_settings', 'value' => '"enable_instant_form";b:1;', 'compare' => 'LIKE', ], ]; return $this->custom_wp_query_total_posts( $meta_query ); } /** * Return total number of ai generated forms. * * @since 1.4.0 * @return int */ public function ai_generated_forms() { $meta_query = [ [ 'key' => '_srfm_is_ai_generated', 'value' => '', 'compare' => '!=', // Checks if the value is NOT empty. ], ]; return $this->custom_wp_query_total_posts( $meta_query ); } /** * Return most used anti-spam type on this site. * * @since 1.4.4 * @return int */ public function most_used_anti_spam() { global $wpdb; // Attempt to get from cache first. $cache_key = 'most_used_anti_spam'; $cached_result = wp_cache_get( $cache_key, 'sureforms' ); if ( false !== $cached_result ) { return $cached_result; } $meta_key = '_srfm_captcha_security_type'; // Query to get the most used captcha type. // PHPCS: Ignore direct database query warning, as there is no built-in alternative. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $result = $wpdb->get_row( $wpdb->prepare( " SELECT meta_value, COUNT(meta_value) as count FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value != '' GROUP BY meta_value ORDER BY count DESC LIMIT 1 ", $meta_key ), ARRAY_A ); $output = ''; if ( $result && ! empty( $result['meta_value'] ) ) { switch ( $result['meta_value'] ) { case 'g-recaptcha': $output = 'Google reCAPTCHA'; break; case 'cf-turnstile': $output = 'CloudFlare Turnstile'; break; case 'hcaptcha': $output = 'hCaptcha'; break; default: $output = ''; break; } } // Store result in cache for 1 hour. wp_cache_set( $cache_key, $output, 'sureforms', HOUR_IN_SECONDS ); return $output; } /** * Returns total number of forms using custom css. * * @since 1.4.0 * @return int */ public function forms_using_custom_css() { $meta_query = [ [ 'key' => '_srfm_form_custom_css', 'value' => '', 'compare' => '!=', // Checks if the value is NOT empty. ], ]; return $this->custom_wp_query_total_posts( $meta_query ); } /** * Return total number of restricted forms. * * @since 1.10.1 * @return int */ public function get_restricted_forms() { $meta_query = [ [ 'key' => '_srfm_form_restriction', 'value' => '"status":true', 'compare' => 'LIKE', ], ]; return $this->custom_wp_query_total_posts( $meta_query ); } /** * Generates global setting data for analytics * * @since 1.4.0 * @return array */ public function global_settings_data() { $global_data = []; $security_settings = get_option( 'srfm_security_settings_options', [] ); $global_data['boolean_values']['honeypot_enabled'] = isset( $security_settings['srfm_honeypot'] ) && true === $security_settings['srfm_honeypot']; $email_summary_data = get_option( 'srfm_email_summary_settings_options', [] ); $global_data['boolean_values']['email_summary_enabled'] = isset( $email_summary_data['srfm_email_summary'] ) && true === $email_summary_data['srfm_email_summary']; $global_data['boolean_values']['suretriggers_active'] = is_plugin_active( 'suretriggers/suretriggers.php' ); $bsf_internal_referrer = get_option( 'bsf_product_referers', [] ); if ( ! empty( $bsf_internal_referrer['sureforms'] ) ) { $global_data['internal_referer'] = $bsf_internal_referrer['sureforms']; } else { $global_data['internal_referer'] = ''; } $general_settings = get_option( 'srfm_general_settings_options', [] ); $global_data['boolean_values']['ip_logging_enabled'] = ! empty( $general_settings['srfm_ip_log'] ); $validation_messages = get_option( 'srfm_default_dynamic_block_option', [] ); $global_data['boolean_values']['custom_validation_message'] = ! empty( $validation_messages ) && is_array( $validation_messages ); return $global_data; } /** * Generates onboarding analytics data * * @since 1.9.1 * @return array */ public function onboarding_analytics_data() { $onboarding_data = []; $analytics_option = Helper::get_srfm_option( 'onboarding_analytics', [] ); if ( empty( $analytics_option ) ) { return $onboarding_data; } // Process skipped steps - store as an array. if ( ! empty( $analytics_option['skippedSteps'] ) && is_array( $analytics_option['skippedSteps'] ) ) { // Map step keys to more descriptive names. $step_mapping = [ 'welcome' => 'Welcome', 'connect' => 'Connect', 'emailDelivery' => 'SureMail', 'premiumFeatures' => 'Features', 'done' => 'Done', ]; // Transform the step keys to their descriptive names. $mapped_steps = array_map( static function( $step ) use ( $step_mapping ) { return $step_mapping[ $step ] ?? $step; }, $analytics_option['skippedSteps'] ); // Store as an array. $onboarding_data['onboarding_skipped_steps'] = $mapped_steps; } // SureMail Installation Status. if ( isset( $analytics_option['suremailInstalled'] ) ) { $onboarding_data['boolean_values']['onboarding_suremail_installed'] = (bool) $analytics_option['suremailInstalled']; } // Account Connection Status. if ( isset( $analytics_option['accountConnected'] ) ) { $onboarding_data['boolean_values']['onboarding_account_connected'] = (bool) $analytics_option['accountConnected']; } // Onboarding Completion Status. if ( isset( $analytics_option['completed'] ) ) { $onboarding_data['boolean_values']['onboarding_completed'] = (bool) $analytics_option['completed']; } // Onboarding Early Exit Status. if ( isset( $analytics_option['exitedEarly'] ) ) { $onboarding_data['boolean_values']['onboarding_exited_early'] = (bool) $analytics_option['exitedEarly']; } // Onboarding Selected Premium Features. if ( ! empty( $analytics_option['premiumFeatures'] ) && ! empty( $analytics_option['premiumFeatures']['selectedFeatures'] ) ) { // Map feature IDs to more descriptive names - exclude free features. $feature_mapping = [ // Starter features. 'multi_step_form' => 'Multi-step Forms', 'conditional_logic' => 'Conditional Fields', 'webhooks' => 'Webhooks', 'advanced_fields' => 'Advanced Fields', // Pro features. 'conversational_forms' => 'Conversational Forms', 'digital_signatures' => 'Digital Signatures', // Business features. 'calculations' => 'Calculators', 'user_registration' => 'User Registration and Login', 'custom_app' => 'Custom App', 'pdf_generation' => 'PDF Generation', ]; // Filter out any free features that might have been included. $premium_features = array_filter( $analytics_option['premiumFeatures']['selectedFeatures'], static function( $feature ) { // Exclude free features (ai-form-generation and entries). return 'ai-form-generation' !== $feature && 'entries' !== $feature; } ); // Transform the feature IDs to their descriptive names. $mapped_features = array_map( static function( $feature ) use ( $feature_mapping ) { return $feature_mapping[ $feature ] ?? $feature; }, $premium_features ); // Store as an array. $onboarding_data['onboarding_selected_premium_features'] = $mapped_features; } return $onboarding_data; } /** * Returns user status. * * @since 1.8.0 * @return string */ public function user_status() { // First, check if user_active is already set in srfm_options. if ( Helper::get_srfm_option( 'user_active', false ) ) { return 'active'; } // Get up to 10 published SureForms. $forms = get_posts( [ 'post_type' => SRFM_FORMS_POST_TYPE, 'posts_per_page' => 10, 'post_status' => 'publish', ] ); if ( empty( $forms ) ) { return 'inactive'; } foreach ( $forms as $form ) { if ( ! get_post_meta( $form->ID, '_astra_sites_imported_post', true ) ) { // Mark user as active in srfm_options. Helper::update_srfm_option( 'user_active', true ); return 'active'; } } return 'inactive'; } /** * Return pointer popup clicked status. * * @return string pointer click status. * @since 1.8.0 */ public function pointer_popup_clicked() { // Get both values from srfm_options. $accepted = Helper::get_srfm_option( 'pointer_popup_accepted', false ); $dismissed = Helper::get_srfm_option( 'pointer_popup_dismissed', false ); // If neither action has occurred. if ( ! $accepted && ! $dismissed ) { return ''; } // If both are set, return the most recent one. if ( $accepted && $dismissed ) { return $accepted > $dismissed ? 'accepted' : 'dismissed'; } // If only one is set, return it. return $accepted ? 'accepted' : 'dismissed'; } /** * Runs custom WP_Query to fetch data as per requirement * * @param array $meta_query meta query array for WP_Query. * @since 1.4.0 * @return int */ private function custom_wp_query_total_posts( $meta_query ) { $args = [ 'post_type' => SRFM_FORMS_POST_TYPE, 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_query' => $meta_query, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Meta query required as we need to fetch count of nested data. ]; $query = new \WP_Query( $args ); $posts_count = $query->found_posts; wp_reset_postdata(); return $posts_count; } }