'off', 'fb_pixel_id' => '', 'fb_access_token' => '', 'fb_test_event_code' => '', 'ga_source' => $ga_source_default, 'ga_measurement_id' => $legacy_ga4, 'ga_api_secret' => '', 'ga_send_browser' => 'yes', 'ga_send_server' => 'no', 'google_tag_mode' => 'off', 'gtm_container_id' => '', 'ads_conversion_id' => '', 'ads_conversion_label' => '', 'ads_server_ec' => 'no', 'ads_developer_token' => '', 'ads_customer_id' => '', 'ads_login_customer_id' => '', 'ads_oauth_client_id' => '', 'ads_oauth_client_secret' => '', 'ads_oauth_refresh_token' => '', 'ads_conversion_action_id' => '', 'tiktok_mode' => 'off', 'tiktok_pixel_id' => '', 'tiktok_access_token' => '', 'tiktok_test_event_code' => '', 'openai_mode' => 'off', 'openai_pixel_id' => '', 'openai_access_token' => '', 'openai_validate_only' => 'no', 'server_event_blocking' => 'no', ), $stored ); } public function register_hooks() { add_action( 'wp_ajax_aieo_dmm_conversions_save', array( $this, 'ajax_save' ) ); self::pys_import_class(); AIEO_Meta_PYS_Import::bootstrap(); } private static function pys_import_class() { if ( ! class_exists( 'AIEO_Meta_PYS_Import' ) ) { require_once AIEO_DIR . 'includes/server-events/class-aieo-meta-pys-import.php'; } } public function render_subtab() { self::pys_import_class(); AIEO_Meta_PYS_Import::import(); $this->render_template( 'conversions.php', array( 'settings' => $this->get_settings(), 'sitekit_active' => $this->is_sitekit_active(), 'openai_conflict' => $this->openai_conflict(), 'recent_events' => $this->get_recent_events( 15 ), ) ); } public function get_recent_events( $limit = 15 ) { global $wpdb; $t = $wpdb->prefix . 'aieo_server_events_log'; if ( (string) $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $t ) ) !== $t ) { return array(); } return (array) $wpdb->get_results( $wpdb->prepare( "SELECT event_id, platform, event_name, order_id, status, http_code, fbtrace_id, value, currency, test_mode, created_at FROM `{$t}` ORDER BY id DESC LIMIT %d", max( 1, (int) $limit ) ), ARRAY_A ); } private function is_sitekit_active() { if ( ! function_exists( 'is_plugin_active' ) ) { include_once ABSPATH . 'wp-admin/includes/plugin.php'; } return function_exists( 'is_plugin_active' ) && is_plugin_active( 'google-site-kit/google-site-kit.php' ); } public function openai_conflict() { $out = array( 'active' => false, 'ids' => array(), 'same' => false ); if ( ! function_exists( 'PixelYourSite\OpenAI' ) ) { return $out; } $pys = call_user_func( 'PixelYourSite\OpenAI' ); if ( ! is_object( $pys ) || ! method_exists( $pys, 'configured' ) || ! $pys->configured() ) { return $out; } $out['active'] = true; if ( method_exists( $pys, 'getPixelIDs' ) ) { $out['ids'] = array_values( array_filter( (array) $pys->getPixelIDs() ) ); } $ours = (string) ( isset( $this->get_settings()['openai_pixel_id'] ) ? $this->get_settings()['openai_pixel_id'] : '' ); if ( '' !== $ours ) { $out['same'] = in_array( $ours, $out['ids'], true ); } return $out; } public static function pys_pixels() { if ( ! function_exists( 'PixelYourSite\Facebook' ) ) { return array(); } try { $fb = call_user_func( 'PixelYourSite\Facebook' ); if ( ! is_object( $fb ) ) { return array(); } if ( method_exists( $fb, 'enabled' ) && ! $fb->enabled() ) { return array(); } if ( method_exists( $fb, 'configured' ) && ! $fb->configured() ) { return array(); } $ids = method_exists( $fb, 'getPixelIDs' ) ? (array) $fb->getPixelIDs() : array(); $out = array(); foreach ( $ids as $id ) { $id = is_scalar( $id ) ? trim( (string) $id ) : ''; if ( '' !== $id && ! in_array( $id, $out, true ) ) { $out[] = $id; } } return $out; } catch ( \Throwable $e ) { return array(); } } public static function meta_on() { $mode = (string) ( self::get_config()['fb_mode'] ?? 'off' ); return in_array( $mode, array( 'browser', 'capi', 'both' ), true ); } public static function pys_evidence( $detected ) { $ids = array_values( array_filter( array_map( 'strval', (array) $detected ) ) ); if ( empty( $ids ) ) { return array(); } $theirs = implode( ', ', $ids ); if ( ! self::meta_on() ) { return array( sprintf( __( 'PixelYourSite is configured with pixel %s; Rooster One\'s Meta tracking is off', 'ai-eshop-optimizer' ), $theirs ) ); } $ours = class_exists( 'AIEO_CAPI_Sender' ) && method_exists( 'AIEO_CAPI_Sender', 'resolve_credentials' ) ? (string) AIEO_CAPI_Sender::resolve_credentials( self::get_config() )['pixel_id'] : (string) ( self::get_config()['fb_pixel_id'] ?? '' ); $lines = array( sprintf( __( 'PixelYourSite is configured with pixel %1$s; Rooster One sends to %2$s', 'ai-eshop-optimizer' ), $theirs, '' !== $ours ? $ours : __( 'no pixel yet', 'ai-eshop-optimizer' ) ), ); if ( '' !== $ours && in_array( $ours, $ids, true ) ) { $lines[] = __( 'The same pixel: every purchase reaches it twice while both are on', 'ai-eshop-optimizer' ); } return $lines; } public function ajax_save() { AIEO_DMM::verify_ajax_request(); self::pys_import_class(); AIEO_Meta_PYS_Import::import(); $current = $this->get_settings(); $fb_modes = array( 'off', 'browser', 'capi', 'both' ); $ga_sources = array( 'off', 'aieo', 'sitekit' ); $fb_mode = isset( $_POST['fb_mode'] ) ? sanitize_text_field( wp_unslash( $_POST['fb_mode'] ) ) : 'off'; if ( ! in_array( $fb_mode, $fb_modes, true ) ) { $fb_mode = 'off'; } $ga_source = isset( $_POST['ga_source'] ) ? sanitize_text_field( wp_unslash( $_POST['ga_source'] ) ) : 'off'; if ( ! in_array( $ga_source, $ga_sources, true ) ) { $ga_source = 'off'; } $fb_token = isset( $_POST['fb_access_token'] ) ? sanitize_text_field( wp_unslash( $_POST['fb_access_token'] ) ) : ''; if ( '' === trim( str_replace( "\u{2022}", '', $fb_token ) ) ) { $fb_token = (string) $current['fb_access_token']; } $ga_secret = isset( $_POST['ga_api_secret'] ) ? sanitize_text_field( wp_unslash( $_POST['ga_api_secret'] ) ) : ''; if ( '' === trim( str_replace( "\u{2022}", '', $ga_secret ) ) ) { $ga_secret = (string) $current['ga_api_secret']; } $ga_measurement_id = isset( $_POST['ga_measurement_id'] ) ? sanitize_text_field( wp_unslash( $_POST['ga_measurement_id'] ) ) : ''; $tag_modes = array( 'off', 'gtag', 'gtm' ); $tag_mode = isset( $_POST['google_tag_mode'] ) ? sanitize_text_field( wp_unslash( $_POST['google_tag_mode'] ) ) : 'off'; if ( ! in_array( $tag_mode, $tag_modes, true ) ) { $tag_mode = 'off'; } $keep = function ( $key ) use ( $current ) { $v = isset( $_POST[ $key ] ) ? sanitize_text_field( wp_unslash( $_POST[ $key ] ) ) : ''; return '' === trim( str_replace( "\u{2022}", '', $v ) ) ? (string) ( isset( $current[ $key ] ) ? $current[ $key ] : '' ) : $v; }; $tt_modes = array( 'off', 'browser', 'server', 'both' ); $tt_mode = isset( $_POST['tiktok_mode'] ) ? sanitize_text_field( wp_unslash( $_POST['tiktok_mode'] ) ) : 'off'; if ( ! in_array( $tt_mode, $tt_modes, true ) ) { $tt_mode = 'off'; } $tt_token = isset( $_POST['tiktok_access_token'] ) ? sanitize_text_field( wp_unslash( $_POST['tiktok_access_token'] ) ) : ''; if ( '' === trim( str_replace( "\u{2022}", '', $tt_token ) ) ) { $tt_token = (string) ( isset( $current['tiktok_access_token'] ) ? $current['tiktok_access_token'] : '' ); } $patch = array( 'fb_mode' => $fb_mode, 'fb_pixel_id' => isset( $_POST['fb_pixel_id'] ) ? preg_replace( '/[^0-9]/', '', (string) wp_unslash( $_POST['fb_pixel_id'] ) ) : '', 'fb_access_token' => $fb_token, 'fb_test_event_code' => isset( $_POST['fb_test_event_code'] ) ? sanitize_text_field( wp_unslash( $_POST['fb_test_event_code'] ) ) : '', 'ga_source' => $ga_source, 'ga_measurement_id' => $ga_measurement_id, 'ga_api_secret' => $ga_secret, 'ga_send_browser' => ! empty( $_POST['ga_send_browser'] ) ? 'yes' : 'no', 'ga_send_server' => ! empty( $_POST['ga_send_server'] ) ? 'yes' : 'no', 'google_tag_mode' => $tag_mode, 'gtm_container_id' => isset( $_POST['gtm_container_id'] ) ? sanitize_text_field( wp_unslash( $_POST['gtm_container_id'] ) ) : '', 'ads_conversion_id' => isset( $_POST['ads_conversion_id'] ) ? sanitize_text_field( wp_unslash( $_POST['ads_conversion_id'] ) ) : '', 'ads_conversion_label' => isset( $_POST['ads_conversion_label'] ) ? sanitize_text_field( wp_unslash( $_POST['ads_conversion_label'] ) ) : '', 'ads_server_ec' => ! empty( $_POST['ads_server_ec'] ) ? 'yes' : 'no', 'ads_developer_token' => $keep( 'ads_developer_token' ), 'ads_customer_id' => isset( $_POST['ads_customer_id'] ) ? preg_replace( '/[^0-9]/', '', (string) wp_unslash( $_POST['ads_customer_id'] ) ) : '', 'ads_login_customer_id' => isset( $_POST['ads_login_customer_id'] ) ? preg_replace( '/[^0-9]/', '', (string) wp_unslash( $_POST['ads_login_customer_id'] ) ) : '', 'ads_oauth_client_id' => isset( $_POST['ads_oauth_client_id'] ) ? sanitize_text_field( wp_unslash( $_POST['ads_oauth_client_id'] ) ) : '', 'ads_oauth_client_secret' => $keep( 'ads_oauth_client_secret' ), 'ads_oauth_refresh_token' => $keep( 'ads_oauth_refresh_token' ), 'ads_conversion_action_id' => isset( $_POST['ads_conversion_action_id'] ) ? preg_replace( '/[^0-9]/', '', (string) wp_unslash( $_POST['ads_conversion_action_id'] ) ) : '', 'tiktok_mode' => $tt_mode, 'tiktok_pixel_id' => isset( $_POST['tiktok_pixel_id'] ) ? sanitize_text_field( wp_unslash( $_POST['tiktok_pixel_id'] ) ) : '', 'tiktok_access_token' => $tt_token, 'tiktok_test_event_code' => isset( $_POST['tiktok_test_event_code'] ) ? sanitize_text_field( wp_unslash( $_POST['tiktok_test_event_code'] ) ) : '', 'openai_mode' => in_array( (string) ( isset( $_POST['openai_mode'] ) ? wp_unslash( $_POST['openai_mode'] ) : '' ), array( 'off', 'browser', 'server', 'both' ), true ) ? sanitize_key( wp_unslash( $_POST['openai_mode'] ) ) : 'off', 'openai_pixel_id' => isset( $_POST['openai_pixel_id'] ) ? sanitize_text_field( wp_unslash( $_POST['openai_pixel_id'] ) ) : '', 'openai_access_token' => $keep( 'openai_access_token' ), 'openai_validate_only' => ! empty( $_POST['openai_validate_only'] ) ? 'yes' : 'no', 'server_event_blocking' => empty( $_POST['server_event_async'] ) ? 'yes' : 'no', ); update_option( self::OPTION_KEY, $patch, false ); if ( 'aieo' === $ga_source ) { update_option( 'aieo_google_ga4', $ga_measurement_id ); } wp_send_json_success( array( 'message' => __( 'Conversion settings saved.', 'ai-eshop-optimizer' ) ) ); } }