function et_pb_before_main_editor($post) { if (!in_array($post->post_type, et_builder_get_builder_post_types())) { return; } $_et_builder_use_builder = get_post_meta($post->ID, '_et_pb_use_builder', true); $is_builder_used = 'on' === $_et_builder_use_builder ? true : false; $_et_builder_use_ab_testing = get_post_meta($post->ID, '_et_pb_use_ab_testing', true); $_et_builder_ab_stats_refresh_interval = et_pb_ab_get_refresh_interval($post->ID); $_et_builder_ab_subjects = get_post_meta($post->ID, '_et_pb_ab_subjects', true); $_et_builder_ab_goal_module = et_pb_ab_get_goal_module($post->ID); $builder_always_enabled = apply_filters('et_builder_always_enabled', false, $post->post_type, $post); if ($builder_always_enabled || 'et_pb_layout' === $post->post_type) { $is_builder_used = true; $_et_builder_use_builder = 'on'; } // Add button only if current user is allowed to use it otherwise display placeholder with all required data if (et_pb_is_allowed('divi_builder_control')) { printf('<div class="et_pb_toggle_builder_wrapper%5$s"><a href="#" id="et_pb_toggle_builder" data-builder="%2$s" data-editor="%3$s" class="button button-primary button-large%5$s%6$s">%1$s</a></div><div id="et_pb_main_editor_wrap"%4$s>', $is_builder_used ? esc_html__('Use Default Editor', 'et_builder') : esc_html__('Use The Divi Builder', 'et_builder'), esc_html__('Use The Divi Builder', 'et_builder'), esc_html__('Use Default Editor', 'et_builder'), $is_builder_used ? ' class="et_pb_hidden"' : '', $is_builder_used ? ' et_pb_builder_is_used' : '', $builder_always_enabled ? ' et_pb_hidden' : ''); } else { printf('<div class="et_pb_toggle_builder_wrapper%2$s"></div><div id="et_pb_main_editor_wrap"%1$s>', $is_builder_used ? ' class="et_pb_hidden"' : '', $is_builder_used ? ' et_pb_builder_is_used' : ''); } ?> <p class="et_pb_page_settings" style="display: none;"> <?php wp_nonce_field(basename(__FILE__), 'et_pb_settings_nonce'); ?> <input type="hidden" id="et_pb_use_builder" name="et_pb_use_builder" value="<?php echo esc_attr($_et_builder_use_builder); ?> " /> <input type="hidden" autocomplete="off" id="et_pb_use_ab_testing" name="et_pb_use_ab_testing" value="<?php echo esc_attr($_et_builder_use_ab_testing); ?> "> <input type="hidden" autocomplete="off" id="et_pb_ab_stats_refresh_interval" name="et_pb_ab_stats_refresh_interval" value="<?php echo esc_attr($_et_builder_ab_stats_refresh_interval); ?> "> <input type="hidden" autocomplete="off" id="et_pb_ab_subjects" name="et_pb_ab_subjects" value="<?php echo esc_attr($_et_builder_ab_subjects); ?> "> <input type="hidden" autocomplete="off" id="et_pb_ab_goal_module" name="et_pb_ab_goal_module" value="<?php echo esc_attr($_et_builder_ab_goal_module); ?> "> <?php et_pb_builder_settings_hidden_inputs($post->ID); ?> <textarea id="et_pb_old_content" name="et_pb_old_content"><?php echo esc_attr(get_post_meta($post->ID, '_et_pb_old_content', true)); ?> </textarea> </p> <?php }
/** * Get formatted stats data that is used by builder's Split testing stats * * @param int post ID * @param string day|week|month|all duration of stats * @param string has to be in Y-m-d H:i:s format * @return array stats data */ function et_pb_ab_get_stats_data($post_id, $duration = 'week', $time = false, $force_update = false) { global $wpdb; $post_id = intval($post_id); $goal_slug = et_pb_ab_get_goal_module($post_id); $rank_metrics = in_array($goal_slug, et_pb_ab_get_modules_have_conversions()) ? 'conversions' : 'clicks'; // Get subjects $subjects = et_pb_ab_get_subjects($post_id, 'array', 'subject_'); $subjects_id = et_pb_ab_get_subjects($post_id, 'array'); // Get cached data $cached_data = get_transient('et_pb_ab_' . $post_id . '_stats_' . $duration); // Get rank coloring scheme $subject_rank_colors = et_pb_ab_get_subject_rank_colors(); // return cached logs if exist and if force_update == false if ($cached_data && !$force_update) { // Remove inactive subjects if (isset($cached_data['subjects_id']) && !empty($cached_data['subjects_id'])) { foreach ($cached_data['subjects_id'] as $subject_id_key => $subject_id_value) { if (!in_array($subject_id_value, $subjects_id)) { unset($cached_data['subjects_id'][$subject_id_key]); } } } if (isset($cached_data['subjects_logs']) && !empty($cached_data['subjects_logs'])) { foreach ($cached_data['subjects_logs'] as $subject_log_id => $subject_logs) { if (!in_array($subject_log_id, $subjects)) { unset($cached_data['subjects_logs'][$subject_log_id]); } } } if (isset($cached_data['subjects_analysis']) && !empty($cached_data['subjects_analysis'])) { foreach ($cached_data['subjects_analysis'] as $subject_analysis_id => $subject_analysis) { if (!in_array($subject_analysis_id, $subjects)) { unset($cached_data['subjects_analysis'][$subject_analysis_id]); } } } if (isset($cached_data['subjects_totals']) && !empty($cached_data['subjects_totals'])) { $subject_totals_index = 0; foreach ($cached_data['subjects_totals'] as $subject_total_id => $subject_totals) { if (!in_array($subject_total_id, $subjects)) { unset($cached_data['subjects_totals'][$subject_total_id]); continue; } } // Rank by engagement $cached_subjects_ranks = wp_list_pluck($cached_data['subjects_totals'], $rank_metrics); $cached_subjects_ranks_index = 0; // Sort from high to low, mantain keys arsort($cached_subjects_ranks); // Push color data foreach ($cached_subjects_ranks as $subject_rank_id => $subject_rank_value) { $cached_data['subjects_totals'][$subject_rank_id]['color'] = isset($subject_rank_colors[$cached_subjects_ranks_index]) ? $subject_rank_colors[$cached_subjects_ranks_index] : '#7E0000'; $cached_subjects_ranks_index++; } } return $cached_data; } $table_name = $wpdb->prefix . 'et_divi_ab_testing_stats'; // do nothing if no stats table exists in current WP if (!$wpdb->get_var("SHOW TABLES LIKE '{$table_name}'") == $table_name) { return false; } // Main placeholder $event_types = et_pb_ab_get_event_types(); $analysis_types = et_pb_ab_get_analysis_types(); $analysis_formulas = et_pb_ab_get_analysis_formulas(); $time = $time ? $time : date('Y-m-d H:i:s', current_time('timestamp')); $stats = array('subjects_id' => $subjects_id, 'subjects_logs' => array(), 'subjects_analysis' => array(), 'subjects_totals' => array(), 'events_totals' => array(), 'dates' => array()); // Get all logs in test switch ($duration) { case 'all': $date_range_interval = 'week'; $query = $wpdb->prepare("SELECT subject_id, event, YEARWEEK(record_date) AS 'date', COUNT(id) AS 'count' FROM {$table_name} WHERE test_id = %d GROUP BY subject_id, YEARWEEK(record_date), event", $post_id); break; case 'month': $date_range_interval = 'day'; $query = $wpdb->prepare("SELECT subject_id, event, DATE(record_date) AS 'date', COUNT(id) AS 'count' FROM {$table_name} WHERE test_id = %d AND record_date <= %s AND record_date > DATE_SUB( %s, INTERVAL 1 MONTH ) GROUP BY subject_id, DAYOFMONTH(record_date), event", $post_id, $time, $time); break; case 'day': $date_range_interval = 'hour'; $query = $wpdb->prepare("SELECT subject_id, event, DATE_FORMAT(record_date, %s) AS 'date', COUNT(id) AS 'count' FROM {$table_name} WHERE test_id = %d AND record_date <= %s AND record_date > DATE_SUB( %s, INTERVAL 1 DAY ) GROUP BY subject_id, HOUR(record_date), event", '%Y-%m-%d %H:00', $post_id, $time, $time); break; default: $date_range_interval = 'day'; $query = $wpdb->prepare("SELECT subject_id, event, DATE(record_date) AS 'date', COUNT(id) AS 'count' FROM {$table_name} WHERE test_id = %d AND record_date <= %s AND record_date > DATE_SUB( %s, INTERVAL 1 WEEK ) GROUP BY subject_id, DAYOFMONTH(record_date), event", $post_id, $time, $time); break; } $results = $wpdb->get_results($query); if (!empty($results)) { // Get min and max timestamp based on query result $min_max_date = et_pb_ab_get_min_max_timestamp($results, $date_range_interval); // Create default list $date_list = et_pb_ab_get_date_range($min_max_date['min'], $min_max_date['max'], $date_range_interval); // Insert date list to main placeholder $stats['dates'] = $date_list; // Format YYYYWW format on all-time stats into human-readable format (M jS) foreach ($stats['dates'] as $date_key => $date_time) { if ('all' === $duration) { $stats['dates'][$date_key] = date('M jS', strtotime(substr($date_time, 0, 4) . 'W' . substr($date_time, 4, 2))); } else { if ('day' === $duration) { $stats['dates'][$date_key] = date('H:i', strtotime($date_time)); } else { $stats['dates'][$date_key] = date('M jS', strtotime($date_time)); } } } // Fill subject logs placeholder with proper default $stats['subjects_logs'] = array_fill_keys($subjects, array_fill_keys($event_types, array_fill_keys($date_list, 0))); // Loop query result and place into placeholder foreach ($results as $log) { if (!in_array($log->subject_id, $subjects_id)) { continue; } $stats['subjects_logs']["subject_{$log->subject_id}"][$log->event][$log->date] = $log->count; } // Determine logs' totals and run analysis foreach ($stats['subjects_logs'] as $subject_log_id => $subject_log) { // Push stats total data foreach ($subject_log as $log_type => $logs) { $stats['subjects_totals'][$subject_log_id][$log_type] = array_sum($logs); } // Run analysis for stats' total data foreach ($analysis_types as $analysis_type) { $numerator_event = $analysis_formulas[$analysis_type]['numerator']; $denominator_event = $analysis_formulas[$analysis_type]['denominator']; $numerator = isset($stats['subjects_totals'][$subject_log_id][$numerator_event]) ? $stats['subjects_totals'][$subject_log_id][$numerator_event] : 0; $denominator = isset($stats['subjects_totals'][$subject_log_id][$denominator_event]) ? $stats['subjects_totals'][$subject_log_id][$denominator_event] : 0; $analysis = $denominator === 0 ? 0 : floatval(number_format($numerator / $denominator * 100, 2)); if ($analysis_formulas[$analysis_type]['inverse']) { $analysis = 100 - $analysis; } $stats['subjects_totals'][$subject_log_id][$analysis_type] = $analysis; } // Run analysis for each log date foreach ($date_list as $log_date) { // Run analysis per analysis type foreach ($analysis_types as $analysis_type) { $numerator_event = $analysis_formulas[$analysis_type]['numerator']; $denominator_event = $analysis_formulas[$analysis_type]['denominator']; $numerator = isset($stats['subjects_logs'][$subject_log_id][$numerator_event][$log_date]) ? intval($stats['subjects_logs'][$subject_log_id][$numerator_event][$log_date]) : 0; $denominator = isset($stats['subjects_logs'][$subject_log_id][$denominator_event][$log_date]) ? intval($stats['subjects_logs'][$subject_log_id][$denominator_event][$log_date]) : 0; $analysis = $denominator === 0 ? 0 : floatval(number_format($numerator / $denominator * 100, 2)); if ($analysis_formulas[$analysis_type]['inverse']) { $analysis = 100 - $analysis; } $stats['subjects_analysis'][$subject_log_id][$analysis_type][$log_date] = $analysis; } } } // Push total events data foreach ($event_types as $event_type) { $stats['events_totals'][$event_type] = array_sum(wp_list_pluck($stats['subjects_totals'], $event_type)); } foreach ($analysis_types as $analysis_type) { $analysis_data = wp_list_pluck($stats['subjects_totals'], $analysis_type); $analysis_count = count($analysis_data); $stats['events_totals'][$analysis_type] = floatval(number_format(array_sum($analysis_data) / $analysis_count, 2)); } // Rank by engagement $subjects_ranks = wp_list_pluck($stats['subjects_totals'], $rank_metrics); $subjects_ranks_index = 0; // Sort from high to low, mantain keys arsort($subjects_ranks); // Push color data foreach ($subjects_ranks as $subject_rank_id => $subject_rank_value) { $stats['subjects_totals'][$subject_rank_id]['color'] = isset($subject_rank_colors[$subjects_ranks_index]) ? $subject_rank_colors[$subjects_ranks_index] : '#7E0000'; $subjects_ranks_index++; } // update cache set_transient('et_pb_ab_' . $post_id . '_stats_' . $duration, $stats, DAY_IN_SECONDS); } else { // remove the cache if no logs found delete_transient('et_pb_ab_' . $post_id . '_stats_' . $duration); return false; } return $stats; }