Current File : /home/mdkeenpw/shafqattraders.com/wp-content/plugins/sureforms/admin/analytics.php
<?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;
	}
}