Edit File by line
/home/barbar84/www/wp-conte.../themes/Divi/includes/builder
File: ab-testing.php
<?php
[0] Fix | Delete
/**
[1] Fix | Delete
* Builder ab testing.
[2] Fix | Delete
*
[3] Fix | Delete
* @package Divi
[4] Fix | Delete
* @subpackage Builder
[5] Fix | Delete
* @since 4.6.2
[6] Fix | Delete
*/
[7] Fix | Delete
[8] Fix | Delete
// Prevent file from being loaded directly.
[9] Fix | Delete
if ( ! defined( 'ABSPATH' ) ) {
[10] Fix | Delete
die( -1 );
[11] Fix | Delete
}
[12] Fix | Delete
[13] Fix | Delete
if ( ! defined( 'ET_PB_AB_DB_VERSION' ) ) {
[14] Fix | Delete
define( 'ET_PB_AB_DB_VERSION', '1.1' );
[15] Fix | Delete
}
[16] Fix | Delete
[17] Fix | Delete
/**
[18] Fix | Delete
* AB Testing related data
[19] Fix | Delete
*
[20] Fix | Delete
* @param integer $post_id Post id.
[21] Fix | Delete
*
[22] Fix | Delete
* @return mixed|void {array} AB Testing related data
[23] Fix | Delete
*/
[24] Fix | Delete
function et_builder_ab_options( $post_id ) {
[25] Fix | Delete
$ab_options = array(
[26] Fix | Delete
'db_status' => true === et_pb_db_status_up_to_date() ? 'on' : 'off',
[27] Fix | Delete
'test_id' => $post_id,
[28] Fix | Delete
'has_report' => et_pb_ab_has_report( $post_id ),
[29] Fix | Delete
'has_permission' => et_pb_is_allowed( 'ab_testing' ),
[30] Fix | Delete
'refresh_interval_duration' => et_pb_ab_get_refresh_interval_duration( $post_id ),
[31] Fix | Delete
'refresh_interval_durations' => et_pb_ab_refresh_interval_durations(),
[32] Fix | Delete
'analysis_formula' => et_pb_ab_get_analysis_formulas(),
[33] Fix | Delete
'have_conversions' => et_pb_ab_get_modules_have_conversions(),
[34] Fix | Delete
'sales_title' => esc_html__( 'Sales', 'et_builder' ),
[35] Fix | Delete
'total_title' => esc_html__( 'Total', 'et_builder' ),
[36] Fix | Delete
[37] Fix | Delete
// Saved data.
[38] Fix | Delete
'subjects_rank' => ( 'on' === get_post_meta( $post_id, '_et_pb_use_builder', true ) ) ? et_pb_ab_get_saved_subjects_ranks( $post_id ) : false,
[39] Fix | Delete
[40] Fix | Delete
// Rank color.
[41] Fix | Delete
'subjects_rank_color' => et_pb_ab_get_subject_rank_colors(),
[42] Fix | Delete
);
[43] Fix | Delete
return apply_filters( 'et_builder_ab_options', $ab_options );
[44] Fix | Delete
}
[45] Fix | Delete
[46] Fix | Delete
/**
[47] Fix | Delete
* Filterable AB Testing labels
[48] Fix | Delete
*
[49] Fix | Delete
* @return {array} AB Testing labels
[50] Fix | Delete
*/
[51] Fix | Delete
function et_builder_ab_labels() {
[52] Fix | Delete
$ab_settings = array(
[53] Fix | Delete
'alert_modal_defaults' => array(
[54] Fix | Delete
'proceed_label' => esc_html__( 'Ok', 'et_builder' ),
[55] Fix | Delete
),
[56] Fix | Delete
'select_subject' => array(
[57] Fix | Delete
'title' => esc_html__( 'Select Split Testing Subject', 'et_builder' ),
[58] Fix | Delete
'desc' => esc_html__( 'You have activated the Divi Leads Split Testing System. Using split testing, you can create different element variations on your page to find out which variation most positively affects the conversion rate of your desired goal. After closing this window, please click on the section, row or module that you would like to split test.', 'et_builder' ),
[59] Fix | Delete
),
[60] Fix | Delete
'select_goal' => array(
[61] Fix | Delete
'title' => esc_html__( 'Select Your Goal', 'et_builder' ),
[62] Fix | Delete
'desc' => esc_html__( 'Congratulations, you have selected a split testing subject! Next you need to select your goal. After closing this window, please click the section, row or module that you want to use as your goal. Depending on the element you choose, Divi will track relevant conversion rates for clicks, reads or sales. For example, if you select a Call To Action module as your goal, then Divi will track how variations in your test subjects affect how often visitors read and click the button in your Call To Action module. The test subject itself can also be selected as your goal.', 'et_builder' ),
[63] Fix | Delete
'proceed_label' => esc_html__( 'Ok', 'et_builder' ),
[64] Fix | Delete
),
[65] Fix | Delete
'configure_alternative' => array(
[66] Fix | Delete
'title' => esc_html__( 'Configure Subject Variations', 'et_builder' ),
[67] Fix | Delete
'desc' => esc_html__( 'Congratulations, your split test is ready to go! You will notice that your split testing subject has been duplicated. Each split testing variation will be displayed to your visitors and statistics will be collected to figure out which variation results in the highest goal conversion rate. Your test will begin when you save this page.', 'et_builder' ),
[68] Fix | Delete
'proceed_label' => esc_html__( 'Ok', 'et_builder' ),
[69] Fix | Delete
),
[70] Fix | Delete
'select_winner_first' => array(
[71] Fix | Delete
'title' => esc_html__( 'Select Split Testing Winner', 'et_builder' ),
[72] Fix | Delete
'desc' => esc_html__( 'Before ending your split test, you must choose which split testing variation to keep. Please select your favorite or highest converting subject. Alternative split testing subjects will be removed and stats will be cleared.', 'et_builder' ),
[73] Fix | Delete
),
[74] Fix | Delete
'select_subject_first' => array(
[75] Fix | Delete
'title' => esc_html__( 'Select Split Testing Subject', 'et_builder' ),
[76] Fix | Delete
'desc' => esc_html__( 'You need to select a split testing subject first.', 'et_builder' ),
[77] Fix | Delete
),
[78] Fix | Delete
'select_goal_first' => array(
[79] Fix | Delete
'title' => esc_html__( 'Select Split Testing Goal', 'et_builder' ),
[80] Fix | Delete
'desc' => esc_html__( 'You need to select a split testing goal first. ', 'et_builder' ),
[81] Fix | Delete
),
[82] Fix | Delete
'cannot_select_subject_parent_as_goal' => array(
[83] Fix | Delete
'title' => esc_html__( 'Select A Different Goal', 'et_builder' ),
[84] Fix | Delete
'desc' => esc_html__( 'This element cannot be used as a your split testing goal. Please select a different module, or section.', 'et_builder' ),
[85] Fix | Delete
'proceed_label' => esc_html__( 'Ok', 'et_builder' ),
[86] Fix | Delete
),
[87] Fix | Delete
'cannot_select_global_children_as_subject' => array(
[88] Fix | Delete
'title' => esc_html__( 'Select a Different Subject', 'et_builder' ),
[89] Fix | Delete
'desc' => esc_html__( 'This element cannot be used as split testing subject because it is part of global module. Please select different module, row, or section', 'et_builder' ),
[90] Fix | Delete
),
[91] Fix | Delete
'cannot_select_global_children_as_goal' => array(
[92] Fix | Delete
'title' => esc_html__( 'Select a Different Goal', 'et_builder' ),
[93] Fix | Delete
'desc' => esc_html__( 'This element cannot be used as split testing goal because it is part of global module. Please select different module, row, or section', 'et_builder' ),
[94] Fix | Delete
),
[95] Fix | Delete
'cannot_publish_finish_configuration_first' => array(
[96] Fix | Delete
'title' => esc_html__( 'Setup Split Test First', 'et_builder' ),
[97] Fix | Delete
'desc' => esc_html__( 'You cannot publish the layout right now because you have incomplete split test configuration. Please finish the split test configuration first, then try saving again.', 'et_builder' ),
[98] Fix | Delete
'proceed_label' => esc_html__( 'Ok', 'et_builder' ),
[99] Fix | Delete
),
[100] Fix | Delete
'cannot_save_draft_finish_configuration_first' => array(
[101] Fix | Delete
'title' => esc_html__( 'Setup Split Test First', 'et_builder' ),
[102] Fix | Delete
'desc' => esc_html__( 'You cannot save the layout right now because you have incomplete split test configuration. Please finish the split test configuration first, then try save draft again.', 'et_builder' ),
[103] Fix | Delete
'proceed_label' => esc_html__( 'Ok', 'et_builder' ),
[104] Fix | Delete
),
[105] Fix | Delete
'view_stats_thead_titles' => array(
[106] Fix | Delete
'clicks' => array(
[107] Fix | Delete
esc_html__( 'ID', 'et_builder' ),
[108] Fix | Delete
esc_html__( 'Subject', 'et_builder' ),
[109] Fix | Delete
esc_html__( 'Impressions', 'et_builder' ),
[110] Fix | Delete
esc_html__( 'Clicks', 'et_builder' ),
[111] Fix | Delete
esc_html__( 'Clickthrough Rate', 'et_builder' ),
[112] Fix | Delete
),
[113] Fix | Delete
'reads' => array(
[114] Fix | Delete
esc_html__( 'ID', 'et_builder' ),
[115] Fix | Delete
esc_html__( 'Subject', 'et_builder' ),
[116] Fix | Delete
esc_html__( 'Impressions', 'et_builder' ),
[117] Fix | Delete
esc_html__( 'Reads', 'et_builder' ),
[118] Fix | Delete
esc_html__( 'Reading Rate', 'et_builder' ),
[119] Fix | Delete
),
[120] Fix | Delete
'bounces' => array(
[121] Fix | Delete
esc_html__( 'ID', 'et_builder' ),
[122] Fix | Delete
esc_html__( 'Subject', 'et_builder' ),
[123] Fix | Delete
esc_html__( 'Impressions', 'et_builder' ),
[124] Fix | Delete
esc_html__( 'Stays', 'et_builder' ),
[125] Fix | Delete
esc_html__( 'Bounce Rate', 'et_builder' ),
[126] Fix | Delete
),
[127] Fix | Delete
'engagements' => array(
[128] Fix | Delete
esc_html__( 'ID', 'et_builder' ),
[129] Fix | Delete
esc_html__( 'Subject', 'et_builder' ),
[130] Fix | Delete
esc_html__( 'Goal Views', 'et_builder' ),
[131] Fix | Delete
esc_html__( 'Goal Reads', 'et_builder' ),
[132] Fix | Delete
esc_html__( 'Engagement Rate', 'et_builder' ),
[133] Fix | Delete
),
[134] Fix | Delete
'conversions' => array(
[135] Fix | Delete
esc_html__( 'ID', 'et_builder' ),
[136] Fix | Delete
esc_html__( 'Subject', 'et_builder' ),
[137] Fix | Delete
esc_html__( 'Impressions', 'et_builder' ),
[138] Fix | Delete
esc_html__( 'Conversion Goals', 'et_builder' ),
[139] Fix | Delete
esc_html__( 'Conversion Rate', 'et_builder' ),
[140] Fix | Delete
),
[141] Fix | Delete
'shortcode_conversions' => array(
[142] Fix | Delete
esc_html__( 'ID', 'et_builder' ),
[143] Fix | Delete
esc_html__( 'Subject', 'et_builder' ),
[144] Fix | Delete
esc_html__( 'Impressions', 'et_builder' ),
[145] Fix | Delete
esc_html__( 'Shortcode Conversions', 'et_builder' ),
[146] Fix | Delete
esc_html__( 'Conversion Rate', 'et_builder' ),
[147] Fix | Delete
),
[148] Fix | Delete
),
[149] Fix | Delete
[150] Fix | Delete
// Save to Library.
[151] Fix | Delete
'cannot_save_app_layout_has_ab_testing' => array(
[152] Fix | Delete
'title' => esc_html__( 'Can\'t Save Layout', 'et_builder' ),
[153] Fix | Delete
'desc' => esc_html__( 'You cannot save layout while a split test is running. Please end your split test and then try again.', 'et_builder' ),
[154] Fix | Delete
),
[155] Fix | Delete
[156] Fix | Delete
'cannot_save_section_layout_has_ab_testing' => array(
[157] Fix | Delete
'title' => esc_html__( 'Can\'t Save Section', 'et_builder' ),
[158] Fix | Delete
'desc' => esc_html__( 'You cannot save this section while a split test is running. Please end your split test and then try again.', 'et_builder' ),
[159] Fix | Delete
),
[160] Fix | Delete
[161] Fix | Delete
'cannot_save_row_layout_has_ab_testing' => array(
[162] Fix | Delete
'title' => esc_html__( 'Can\'t Save Row', 'et_builder' ),
[163] Fix | Delete
'desc' => esc_html__( 'You cannot save this row while a split test is running. Please end your split test and then try again.', 'et_builder' ),
[164] Fix | Delete
),
[165] Fix | Delete
[166] Fix | Delete
'cannot_save_row_inner_layout_has_ab_testing' => array(
[167] Fix | Delete
'title' => esc_html__( 'Can\'t Save Row', 'et_builder' ),
[168] Fix | Delete
'desc' => esc_html__( 'You cannot save this row while a split test is running. Please end your split test and then try again.', 'et_builder' ),
[169] Fix | Delete
),
[170] Fix | Delete
[171] Fix | Delete
'cannot_save_module_layout_has_ab_testing' => array(
[172] Fix | Delete
'title' => esc_html__( 'Can\'t Save Module', 'et_builder' ),
[173] Fix | Delete
'desc' => esc_html__( 'You cannot save this module while a split test is running. Please end your split test and then try again.', 'et_builder' ),
[174] Fix | Delete
),
[175] Fix | Delete
[176] Fix | Delete
// Load / Clear Layout.
[177] Fix | Delete
'cannot_load_layout_has_ab_testing' => array(
[178] Fix | Delete
'title' => esc_html__( 'Can\'t Load Layout', 'et_builder' ),
[179] Fix | Delete
'desc' => esc_html__( 'You cannot load a new layout while a split test is running. Please end your split test and then try again.', 'et_builder' ),
[180] Fix | Delete
),
[181] Fix | Delete
'cannot_clear_layout_has_ab_testing' => array(
[182] Fix | Delete
'title' => esc_html__( 'Can\'t Clear Layout', 'et_builder' ),
[183] Fix | Delete
'desc' => esc_html__( 'You cannot clear your layout while a split testing is running. Please end your split test before clearing your layout.', 'et_builder' ),
[184] Fix | Delete
),
[185] Fix | Delete
[186] Fix | Delete
// Cannot Import / Export Layout (Portability).
[187] Fix | Delete
'cannot_import_export_layout_has_ab_testing' => array(
[188] Fix | Delete
'title' => esc_html__( 'Can\'t Import/Export Layout', 'et_builder' ),
[189] Fix | Delete
'desc' => esc_html__( 'You cannot import or export a layout while a split test is running. Please end your split test and then try again.', 'et_builder' ),
[190] Fix | Delete
),
[191] Fix | Delete
[192] Fix | Delete
// Moving Goal / Subject.
[193] Fix | Delete
'cannot_move_module_goal_out_from_subject' => array(
[194] Fix | Delete
'title' => esc_html__( 'Can\'t Move Goal', 'et_builder' ),
[195] Fix | Delete
'desc' => esc_html__( 'Once set, a goal that has been placed inside a split testing subject cannot be moved outside the split testing subject. You can end your split test and start a new one if you would like to make this change.', 'et_builder' ),
[196] Fix | Delete
),
[197] Fix | Delete
'cannot_move_row_goal_out_from_subject' => array(
[198] Fix | Delete
'title' => esc_html__( 'Can\'t Move Goal', 'et_builder' ),
[199] Fix | Delete
'desc' => esc_html__( 'Once set, a goal that has been placed inside a split testing subject cannot be moved outside the split testing subject. You can end your split test and start a new one if you would like to make this change.', 'et_builder' ),
[200] Fix | Delete
),
[201] Fix | Delete
'cannot_move_goal_into_subject' => array(
[202] Fix | Delete
'title' => esc_html__( 'Can\'t Move Goal', 'et_builder' ),
[203] Fix | Delete
'desc' => esc_html__( 'A split testing goal cannot be moved inside of a split testing subject. To perform this action you must first end your split test.', 'et_builder' ),
[204] Fix | Delete
),
[205] Fix | Delete
'cannot_move_subject_into_goal' => array(
[206] Fix | Delete
'title' => esc_html__( 'Can\'t Move Subject', 'et_builder' ),
[207] Fix | Delete
'desc' => esc_html__( 'A split testing subject cannot be moved inside of a split testing goal. To perform this action you must first end your split test.', 'et_builder' ),
[208] Fix | Delete
),
[209] Fix | Delete
[210] Fix | Delete
// Cannot Paste Goal / Subject.
[211] Fix | Delete
'cannot_paste_goal' => array(
[212] Fix | Delete
'title' => esc_html__( 'Can\'t Paste Goal', 'et_builder' ),
[213] Fix | Delete
'desc' => esc_html__( 'A split testing goal cannot be copied, cut, and pasted. To perform this action you must first end your split test.', 'et_builder' ),
[214] Fix | Delete
),
[215] Fix | Delete
'cannot_paste_row_has_subject_into_goal' => array(
[216] Fix | Delete
'title' => esc_html__( 'Can\'t Paste Row', 'et_builder' ),
[217] Fix | Delete
'desc' => esc_html__( 'Row that has split testing subject cannot be pasted inside a split testing goal. To perform this action you must first end your split test.', 'et_builder' ),
[218] Fix | Delete
),
[219] Fix | Delete
'cannot_paste_subject_into_goal' => array(
[220] Fix | Delete
'title' => esc_html__( 'Can\'t Paste Subject', 'et_builder' ),
[221] Fix | Delete
'desc' => esc_html__( 'A split testing subject cannot be pasted inside a split testing goal. To perform this action you must first end your split test.', 'et_builder' ),
[222] Fix | Delete
),
[223] Fix | Delete
[224] Fix | Delete
// Removing + Has Goal.
[225] Fix | Delete
'cannot_remove_section_has_goal' => array(
[226] Fix | Delete
'title' => esc_html__( 'Can\'t Remove Section', 'et_builder' ),
[227] Fix | Delete
'desc' => esc_html__( 'This section cannot be removed because it contains a split testing goal. Goals cannot be deleted. You must first end your split test before performing this action.', 'et_builder' ),
[228] Fix | Delete
),
[229] Fix | Delete
'cannot_remove_row_has_goal' => array(
[230] Fix | Delete
'title' => esc_html__( 'Can\'t Remove Row', 'et_builder' ),
[231] Fix | Delete
'desc' => esc_html__( 'This row cannot be removed because it contains a split testing goal. Goals cannot be deleted. You must first end your split test before performing this action.', 'et_builder' ),
[232] Fix | Delete
),
[233] Fix | Delete
[234] Fix | Delete
// Removing + Has Unremovable Subjects.
[235] Fix | Delete
'cannot_remove_section_has_unremovable_subject' => array(
[236] Fix | Delete
'title' => esc_html__( 'Can\'t Remove Section', 'et_builder' ),
[237] Fix | Delete
'desc' => esc_html__( 'Split testing requires at least 2 subject variations. This variation cannot be removed until additional variations have been added.', 'et_builder' ),
[238] Fix | Delete
),
[239] Fix | Delete
'cannot_remove_row_has_unremovable_subject' => array(
[240] Fix | Delete
'title' => esc_html__( 'Can\'t Remove Row', 'et_builder' ),
[241] Fix | Delete
'desc' => esc_html__( 'Split testing requires at least 2 subject variations. This variation cannot be removed until additional variations have been added', 'et_builder' ),
[242] Fix | Delete
),
[243] Fix | Delete
[244] Fix | Delete
// Cloning + Has Goal.
[245] Fix | Delete
'cannot_clone_section_has_goal' => array(
[246] Fix | Delete
'title' => esc_html__( 'Can\'t Clone Section', 'et_builder' ),
[247] Fix | Delete
'desc' => esc_html__( 'This section cannot be duplicated because it contains a split testing goal. Goals cannot be duplicated. You must first end your split test before performing this action.', 'et_builder' ),
[248] Fix | Delete
),
[249] Fix | Delete
'cannot_clone_row_has_goal' => array(
[250] Fix | Delete
'title' => esc_html__( 'Can\'t Clone Row', 'et_builder' ),
[251] Fix | Delete
'desc' => esc_html__( 'This row cannot be duplicated because it contains a split testing goal. Goals cannot be duplicated. You must first end your split test before performing this action.', 'et_builder' ),
[252] Fix | Delete
),
[253] Fix | Delete
[254] Fix | Delete
// Copy + Has Goal.
[255] Fix | Delete
'cannot_copy_section_has_goal' => array(
[256] Fix | Delete
'title' => esc_html__( 'Can\'t Copy Section', 'et_builder' ),
[257] Fix | Delete
'desc' => esc_html__( 'This section cannot be copied because it contains a split testing goal. Goals cannot be duplicated. You must first end your split test before performing this action.', 'et_builder' ),
[258] Fix | Delete
),
[259] Fix | Delete
'cannot_copy_row_has_goal' => array(
[260] Fix | Delete
'title' => esc_html__( 'Can\'t Copy Row', 'et_builder' ),
[261] Fix | Delete
'desc' => esc_html__( 'This row cannot be copied because it contains a split testing goal. Goals cannot be duplicated. You must first end your split test before performing this action.', 'et_builder' ),
[262] Fix | Delete
),
[263] Fix | Delete
[264] Fix | Delete
// Copy Goal.
[265] Fix | Delete
'cannot_copy_goal' => array(
[266] Fix | Delete
'title' => esc_html__( 'Can\'t Copy Goal', 'et_builder' ),
[267] Fix | Delete
'desc' => esc_html__( 'Goal cannot be copied. You must first end your split test before performing this action.', 'et_builder' ),
[268] Fix | Delete
),
[269] Fix | Delete
[270] Fix | Delete
// No AB Testing Permission.
[271] Fix | Delete
'has_no_ab_permission' => array(
[272] Fix | Delete
'title' => esc_html__( 'Can\'t Edit Split Test', 'default' ),
[273] Fix | Delete
'desc' => esc_html__( 'You do not have permission to edit the module, row or section in this split test.', 'et_builder' ),
[274] Fix | Delete
),
[275] Fix | Delete
[276] Fix | Delete
// No AB Testing Report Yet.
[277] Fix | Delete
'no_report' => array(
[278] Fix | Delete
'title' => esc_html__( 'Statistics are being collected', 'et_builder' ),
[279] Fix | Delete
'desc' => esc_html__( 'Stats will be displayed upon sufficient data collection', 'et_builder' ), // 10
[280] Fix | Delete
),
[281] Fix | Delete
[282] Fix | Delete
// Set Global Winner Status.
[283] Fix | Delete
'set_global_winner_status' => array(
[284] Fix | Delete
'title' => esc_html__( 'Set Winner Status', 'et_builder' ),
[285] Fix | Delete
'desc' => esc_html__( 'You were using global item as split testing winner. Consequently, you have to choose between:', 'et_builder' ),
[286] Fix | Delete
'option_1' => esc_html__( 'Save winner as global item (selected subject will be synced and your global item will be updated in the Divi Library)', 'et_builder' ),
[287] Fix | Delete
'option_2' => esc_html__( 'Save winner as non-global item (selected subject will no longer be a global item and your changes will not modify the global item)', 'et_builder' ),
[288] Fix | Delete
'cancel' => esc_html__( 'Save as Global Item', 'et_builder' ),
[289] Fix | Delete
'proceed' => esc_html__( 'Save', 'et_builder' ),
[290] Fix | Delete
),
[291] Fix | Delete
[292] Fix | Delete
);
[293] Fix | Delete
return apply_filters( 'et_builder_ab_settings', $ab_settings );
[294] Fix | Delete
}
[295] Fix | Delete
[296] Fix | Delete
/**
[297] Fix | Delete
* AJAX endpoint for builder data
[298] Fix | Delete
*
[299] Fix | Delete
* @return void
[300] Fix | Delete
*/
[301] Fix | Delete
function et_pb_ab_builder_data() {
[302] Fix | Delete
// Verify nonce.
[303] Fix | Delete
// phpcs:ignore ET.Sniffs.ValidatedSanitizedInput -- `wp_verify_nonce()` does not store or display the nonce value, therefor XSS safe.
[304] Fix | Delete
if ( ! isset( $_POST['et_pb_ab_nonce'] ) || ! wp_verify_nonce( $_POST['et_pb_ab_nonce'], 'ab_testing_builder_nonce' ) ) {
[305] Fix | Delete
die( -1 );
[306] Fix | Delete
}
[307] Fix | Delete
[308] Fix | Delete
$defaults = array(
[309] Fix | Delete
'et_pb_ab_test_id' => '',
[310] Fix | Delete
'et_pb_ab_duration' => 'week',
[311] Fix | Delete
);
[312] Fix | Delete
[313] Fix | Delete
$_post = wp_parse_args( $_POST, $defaults );
[314] Fix | Delete
[315] Fix | Delete
$_post['et_pb_ab_test_id'] = ! empty( $_post['et_pb_ab_test_id'] ) ? intval( $_post['et_pb_ab_test_id'] ) : '';
[316] Fix | Delete
[317] Fix | Delete
// Verify user permission.
[318] Fix | Delete
if ( empty( $_post['et_pb_ab_test_id'] ) || ! current_user_can( 'edit_post', $_post['et_pb_ab_test_id'] ) || ! et_pb_is_allowed( 'ab_testing' ) ) {
[319] Fix | Delete
die( -1 );
[320] Fix | Delete
}
[321] Fix | Delete
[322] Fix | Delete
// Allowlist the duration value.
[323] Fix | Delete
$duration = in_array( $_post['et_pb_ab_duration'], et_pb_ab_get_stats_data_duration(), true ) ? $_post['et_pb_ab_duration'] : $defaults['et_pb_ab_duration'];
[324] Fix | Delete
[325] Fix | Delete
// Get data.
[326] Fix | Delete
$output = et_pb_ab_get_stats_data( intval( $_post['et_pb_ab_test_id'] ), $duration );
[327] Fix | Delete
[328] Fix | Delete
// Print output.
[329] Fix | Delete
die( et_core_esc_previously( wp_json_encode( $output ) ) );
[330] Fix | Delete
}
[331] Fix | Delete
add_action( 'wp_ajax_et_pb_ab_builder_data', 'et_pb_ab_builder_data' );
[332] Fix | Delete
[333] Fix | Delete
/**
[334] Fix | Delete
* Get AB Testing subject ranking data
[335] Fix | Delete
*
[336] Fix | Delete
* @param integer $post_id Post id.
[337] Fix | Delete
*
[338] Fix | Delete
* @return array
[339] Fix | Delete
*/
[340] Fix | Delete
function et_pb_ab_get_saved_subjects_ranks( $post_id ) {
[341] Fix | Delete
global $post;
[342] Fix | Delete
[343] Fix | Delete
// Make sure that there are $post_id.
[344] Fix | Delete
if ( ! isset( $post_id ) && isset( $post->ID ) ) {
[345] Fix | Delete
$post_id = $post->ID;
[346] Fix | Delete
}
[347] Fix | Delete
[348] Fix | Delete
// Get list of subjects.
[349] Fix | Delete
$subject_list = get_post_meta( $post_id, '_et_pb_ab_subjects', true );
[350] Fix | Delete
$subjects_ids = explode( ',', $subject_list );
[351] Fix | Delete
$subjects = array();
[352] Fix | Delete
$goal_slug = et_pb_ab_get_goal_module( $post_id );
[353] Fix | Delete
$rank_metrics = in_array( $goal_slug, et_pb_ab_get_modules_have_conversions(), true ) ? 'conversions' : 'clicks';
[354] Fix | Delete
[355] Fix | Delete
if ( ! empty( $subjects_ids ) ) {
[356] Fix | Delete
// Get conversion rate data.
[357] Fix | Delete
$subjects_ranks = et_pb_ab_get_subjects_ranks( $post_id, $rank_metrics, 'all' );
[358] Fix | Delete
[359] Fix | Delete
// Sort from high to low and mantain key association.
[360] Fix | Delete
arsort( $subjects_ranks );
[361] Fix | Delete
[362] Fix | Delete
// Loop saved subject ids.
[363] Fix | Delete
foreach ( $subjects_ids as $subject_id ) {
[364] Fix | Delete
$subject_key = 'subject_' . $subject_id;
[365] Fix | Delete
$subject_rank = isset( $subjects_ranks[ $subject_key ] ) ? array_search( $subjects_ranks[ $subject_key ], array_values( $subjects_ranks ), true ) + 1 : false;
[366] Fix | Delete
[367] Fix | Delete
// Check whether current subject has saved conversion rate data or not.
[368] Fix | Delete
if ( $subject_rank ) {
[369] Fix | Delete
$subjects[ $subject_key ] = array(
[370] Fix | Delete
'percentage' => esc_html( $subjects_ranks[ $subject_key ] . '%' ),
[371] Fix | Delete
'rank' => esc_attr( $subject_rank ),
[372] Fix | Delete
);
[373] Fix | Delete
}
[374] Fix | Delete
}
[375] Fix | Delete
}
[376] Fix | Delete
[377] Fix | Delete
return $subjects;
[378] Fix | Delete
}
[379] Fix | Delete
[380] Fix | Delete
/**
[381] Fix | Delete
* Define ranking-based subject color
[382] Fix | Delete
*
[383] Fix | Delete
* @return array
[384] Fix | Delete
*/
[385] Fix | Delete
function et_pb_ab_get_subject_rank_colors() {
[386] Fix | Delete
$subject_rank_colors = array(
[387] Fix | Delete
'#F3CB57',
[388] Fix | Delete
'#F8B852',
[389] Fix | Delete
'#F8A653',
[390] Fix | Delete
'#F88F55',
[391] Fix | Delete
'#F87356',
[392] Fix | Delete
'#F95A57',
[393] Fix | Delete
'#EA5552',
[394] Fix | Delete
'#DB514F',
[395] Fix | Delete
'#CE4441',
[396] Fix | Delete
'#BF2F2C',
[397] Fix | Delete
'#AA201C',
[398] Fix | Delete
'#920E08',
[399] Fix | Delete
'#7E0000',
[400] Fix | Delete
);
[401] Fix | Delete
return array_map( 'et_sanitize_alpha_color', apply_filters( 'et_pb_ab_get_subject_rank_colors', $subject_rank_colors ) );
[402] Fix | Delete
}
[403] Fix | Delete
[404] Fix | Delete
/**
[405] Fix | Delete
* Print AB Testing subject-ranking color scheme
[406] Fix | Delete
*
[407] Fix | Delete
* @return string inline CSS styling for subject rank
[408] Fix | Delete
*/
[409] Fix | Delete
function et_pb_ab_get_subject_rank_colors_style() {
[410] Fix | Delete
$style = '';
[411] Fix | Delete
$colors = et_pb_ab_get_subject_rank_colors();
[412] Fix | Delete
$index = 1;
[413] Fix | Delete
[414] Fix | Delete
foreach ( $colors as $color ) {
[415] Fix | Delete
$style .= sprintf(
[416] Fix | Delete
'.et_pb_ab_subject.rank-%1$s .et_pb_module_block,
[417] Fix | Delete
.et_pb_ab_subject.rank-%1$s.et_pb_section .et-pb-controls,
[418] Fix | Delete
.et_pb_ab_subject.rank-%1$s.et_pb_row .et-pb-controls,
[419] Fix | Delete
.et_pb_ab_subject.rank-%1$s.et_pb_module_block {
[420] Fix | Delete
background: %2$s;
[421] Fix | Delete
}',
[422] Fix | Delete
esc_html( $index ),
[423] Fix | Delete
esc_html( $color )
[424] Fix | Delete
);
[425] Fix | Delete
$index++;
[426] Fix | Delete
}
[427] Fix | Delete
[428] Fix | Delete
return $style;
[429] Fix | Delete
}
[430] Fix | Delete
[431] Fix | Delete
/**
[432] Fix | Delete
* Get subjects' ranks
[433] Fix | Delete
*
[434] Fix | Delete
* @param int $post_id post ID.
[435] Fix | Delete
* @param string $ranking_basis ranking basis. This can be any value on data's subjects_totals
[436] Fix | Delete
* view_page|read_page|view_goal|read_goal|click_goal|con_goal|clicks|reads|bounces|engagements|conversions.
[437] Fix | Delete
* @param string $duration duration of the data that is used.
[438] Fix | Delete
* @return array key = `subject_` + subject_id as key and the value as value, sorted in ascending
[439] Fix | Delete
*/
[440] Fix | Delete
function et_pb_ab_get_subjects_ranks( $post_id, $ranking_basis = 'engagements', $duration = 'week' ) {
[441] Fix | Delete
$data = et_pb_ab_get_stats_data( $post_id, $duration );
[442] Fix | Delete
$subjects = et_pb_ab_get_subjects( $post_id, 'array', 'subject_' );
[443] Fix | Delete
[444] Fix | Delete
if ( isset( $data['subjects_totals'] ) && ! empty( $data['subjects_totals'] ) && ! empty( $subjects ) ) {
[445] Fix | Delete
// Pluck data.
[446] Fix | Delete
$ranks = wp_list_pluck( $data['subjects_totals'], $ranking_basis );
[447] Fix | Delete
[448] Fix | Delete
// Remove inactive subjects from ranks.
[449] Fix | Delete
foreach ( $ranks as $rank_key => $rank_value ) {
[450] Fix | Delete
if ( ! in_array( $rank_key, $subjects, true ) ) {
[451] Fix | Delete
unset( $ranks[ $rank_key ] );
[452] Fix | Delete
}
[453] Fix | Delete
}
[454] Fix | Delete
[455] Fix | Delete
// Sort rank.
[456] Fix | Delete
arsort( $ranks );
[457] Fix | Delete
} else {
[458] Fix | Delete
$ranks = array();
[459] Fix | Delete
}
[460] Fix | Delete
[461] Fix | Delete
return $ranks;
[462] Fix | Delete
}
[463] Fix | Delete
[464] Fix | Delete
/**
[465] Fix | Delete
* Get formatted stats data that is used by builder's AB Testing stats
[466] Fix | Delete
*
[467] Fix | Delete
* @param int $post_id post ID.
[468] Fix | Delete
* @param string $duration day|week|month|all duration of stats.
[469] Fix | Delete
* @param bool $time has to be in Y-m-d H:i:s format.
[470] Fix | Delete
* @param bool $force_update Whether to force stats update.
[471] Fix | Delete
* @param bool $is_cron_task Is it a cron task.
[472] Fix | Delete
*
[473] Fix | Delete
* @return array stats data
[474] Fix | Delete
*/
[475] Fix | Delete
function et_pb_ab_get_stats_data( $post_id, $duration = 'week', $time = false, $force_update = false, $is_cron_task = false ) {
[476] Fix | Delete
global $wpdb;
[477] Fix | Delete
[478] Fix | Delete
$post_id = intval( $post_id );
[479] Fix | Delete
$goal_slug = et_pb_ab_get_goal_module( $post_id );
[480] Fix | Delete
$rank_metrics = in_array( $goal_slug, et_pb_ab_get_modules_have_conversions(), true ) ? 'conversions' : 'clicks';
[481] Fix | Delete
[482] Fix | Delete
// Get subjects.
[483] Fix | Delete
$subjects = et_pb_ab_get_subjects( $post_id, 'array', 'subject_', $is_cron_task );
[484] Fix | Delete
$subjects_id = et_pb_ab_get_subjects( $post_id, 'array', false, $is_cron_task );
[485] Fix | Delete
[486] Fix | Delete
// Get cached data.
[487] Fix | Delete
$cached_data = get_transient( 'et_pb_ab_' . $post_id . '_stats_' . $duration );
[488] Fix | Delete
[489] Fix | Delete
// Get rank coloring scheme.
[490] Fix | Delete
$subject_rank_colors = et_pb_ab_get_subject_rank_colors();
[491] Fix | Delete
[492] Fix | Delete
// return cached logs if exist and if force_update == false.
[493] Fix | Delete
if ( $cached_data && ! $force_update ) {
[494] Fix | Delete
// Remove inactive subjects.
[495] Fix | Delete
if ( isset( $cached_data['subjects_id'] ) && ! empty( $cached_data['subjects_id'] ) ) {
[496] Fix | Delete
foreach ( $cached_data['subjects_id'] as $subject_id_key => $subject_id_value ) {
[497] Fix | Delete
if ( ! in_array( $subject_id_value, $subjects_id, true ) ) {
[498] Fix | Delete
unset( $cached_data['subjects_id'][ $subject_id_key ] );
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function