public static function load($id) { $json_data = NelioABBackend::remote_get(NELIOAB_BACKEND_URL . '/exp/post/' . $id); $json_data = json_decode($json_data['body']); $exp = new NelioABHeadlineAlternativeExperiment($json_data->key->id); $exp->set_name($json_data->name); if (isset($json_data->description)) { $exp->set_description($json_data->description); } $exp->set_type_using_text($json_data->kind); $exp->set_original($json_data->originalPost); $exp->set_status($json_data->status); $exp->set_finalization_mode($json_data->finalizationMode); if (isset($json_data->finalizationModeValue)) { $exp->set_finalization_value($json_data->finalizationModeValue); } $exp->track_heatmaps(false); if (isset($json_data->showHeatmap) && $json_data->showHeatmap) { $exp->track_heatmaps($json_data->showHeatmap); } if (isset($json_data->goals)) { NelioABExperiment::load_goals_from_json($exp, $json_data->goals); } $alternatives = array(); if (isset($json_data->alternatives)) { foreach ($json_data->alternatives as $json_alt) { $alt = new NelioABHeadlineAlternative($json_alt->key->id); $alt->set_name($json_alt->name); $alt->set_value(json_decode($json_alt->value, true)); array_push($alternatives, $alt); } } $exp->set_appspot_alternatives($alternatives); return $exp; }
public static function load($id) { $json_data = NelioABBackend::remote_get(NELIOAB_BACKEND_URL . '/exp/global/' . $id); $json_data = json_decode($json_data['body']); $exp = new NelioABWidgetAlternativeExperiment($json_data->key->id); $exp->set_type_using_text($json_data->kind); $exp->set_name($json_data->name); if (isset($json_data->description)) { $exp->set_description($json_data->description); } $exp->set_status($json_data->status); $exp->set_finalization_mode($json_data->finalizationMode); if (isset($json_data->finalizationModeValue)) { $exp->set_finalization_value($json_data->finalizationModeValue); } if (isset($json_data->start)) { $exp->set_start_date($json_data->start); } if (isset($json_data->finalization)) { $exp->set_end_date($json_data->finalization); } if (isset($json_data->goals)) { NelioABExperiment::load_goals_from_json($exp, $json_data->goals); } $alternatives = array(); if (isset($json_data->alternatives)) { foreach ($json_data->alternatives as $json_alt) { $alt = new NelioABAlternative($json_alt->key->id); $alt->set_name($json_alt->name); if (isset($json_alt->content)) { $alt->set_value($json_alt->content->value); } else { $alt->set_value(''); } array_push($alternatives, $alt); } } $exp->set_appspot_alternatives($alternatives); return $exp; }
/** * Sanitizes all settings and stores some of them in AppEngine. * * This function parses the settings recovered from the form in the * Settings Page and sanitizes all string values to their appropriate * types. Also, it synchronizes some of these settings with AppEngine. * * @param array $input all settings as recovered from the form in the Settings page. * * @return array the same value as $input, but with the appropriate types. * * @since 2.1.0 */ public static function sanitize($input) { $new_input = array(); if (isset($input['reset_settings']) && 'do_reset' == $input['reset_settings']) { return $new_input; } $new_input['def_conv_value'] = self::DEFAULT_CONVERSION_VALUE; if (isset($input['def_conv_value'])) { $new_input['def_conv_value'] = sanitize_text_field($input['def_conv_value']); } $new_input['plugin_available_to'] = self::DEFAULT_PLUGIN_AVAILABLE_TO; if (isset($input['plugin_available_to'])) { $new_input['plugin_available_to'] = sanitize_text_field($input['plugin_available_to']); } $new_input['conv_unit'] = self::DEFAULT_CONVERSION_UNIT; if (isset($input['conv_unit'])) { $new_input['conv_unit'] = sanitize_text_field($input['conv_unit']); } $new_input['use_colorblind'] = self::DEFAULT_USE_COLORBLIND_PALETTE; if (isset($input['use_colorblind'])) { $new_input['use_colorblind'] = sanitize_text_field($input['use_colorblind']); $new_input['use_colorblind'] = $new_input['use_colorblind'] == '1'; } $new_input['theme_landing_page'] = self::DEFAULT_THEME_LANDING_PAGE; if (isset($input['theme_landing_page'])) { $new_input['theme_landing_page'] = sanitize_text_field($input['theme_landing_page']); $new_input['theme_landing_page'] = $new_input['theme_landing_page'] == '1'; } $new_input['on_blank'] = self::DEFAULT_OUTWARDS_NAVIGATION_BLANK; if (isset($input['on_blank'])) { $new_input['on_blank'] = sanitize_text_field($input['on_blank']); $new_input['on_blank'] = $new_input['on_blank'] == '1'; } $new_input['show_finished_experiments'] = self::DEFAULT_SHOW_FINISHED_EXPERIMENTS; if (isset($input['show_finished_experiments'])) { $new_input['show_finished_experiments'] = intval($input['show_finished_experiments']); } $new_input['min_confidence_for_significance'] = self::DEFAULT_CONFIDENCE_FOR_SIGNIFICANCE; if (isset($input['min_confidence_for_significance'])) { $new_input['min_confidence_for_significance'] = intval($input['min_confidence_for_significance']); } if (100 == $new_input['min_confidence_for_significance']) { $new_input['min_confidence_for_significance'] = 99; } $new_input['menu_location'] = self::DEFAULT_MENU_LOCATION; if (isset($input['menu_location'])) { $new_input['menu_location'] = intval($input['menu_location']); } $new_input['menu_in_admin_bar'] = self::DEFAULT_MENU_IN_ADMIN_BAR; if (isset($input['menu_in_admin_bar'])) { $new_input['menu_in_admin_bar'] = intval($input['menu_in_admin_bar']) == 1; } $new_input['headlines_quota_mode'] = self::HEADLINES_QUOTA_MODE_ALWAYS; if (isset($input['headlines_quota_mode'])) { $new_input['headlines_quota_mode'] = intval($input['headlines_quota_mode']); } // SYNC SOME SETTINGS WITH GOOGLE APP ENGINE try { $algorithm = self::ALGORITHM_PURE_RANDOM; if (isset($input['algorithm'])) { $algorithm = sanitize_text_field($input['algorithm']); } $make_site_consistent = self::DEFAULT_MAKE_SITE_CONSISTENT; if (isset($input['make_site_consistent'])) { $make_site_consistent = sanitize_text_field($input['make_site_consistent']); $make_site_consistent = $make_site_consistent == '1'; } $expl_ratio = self::DEFAULT_EXPL_RATIO; if (isset($input['expl_ratio'])) { $expl_ratio = intval($input['expl_ratio']); } $get_params_visibility = self::DEFAULT_GET_PARAMS_VISIBILITY; if (isset($input['get_params_visibility'])) { $get_params_visibility = sanitize_text_field($input['get_params_visibility']); } $hm_tracking_mode = self::DEFAULT_HEATMAP_TRACKING_MODE; if (isset($input['hm_tracking_mode'])) { $hm_tracking_mode = sanitize_text_field($input['hm_tracking_mode']); } $user_split = self::DEFAULT_USER_SPLIT; if (isset($input['user_split'])) { $user_split = sanitize_text_field($input['user_split']); } $ori_perc = self::DEFAULT_ORIGINAL_PERCENTAGE; if (isset($input['ori_perc'])) { $ori_perc = intval($input['ori_perc']); } $perc_of_tested_users = self::DEFAULT_PERCENTAGE_OF_TESTED_USERS; if (isset($input['perc_of_tested_users'])) { $perc_of_tested_users = intval($input['perc_of_tested_users']); } $limit = self::get_quota_limit_per_exp(); if (isset($input['quota_limit_per_exp'])) { $limit = intval($input['quota_limit_per_exp']); } $email = ''; if (isset($input['notification_email'])) { $email = trim($input['notification_email']); } $notifications = ' '; if (isset($input['notify_exp_finalization']) && 'on' == $input['notify_exp_finalization']) { $notifications .= self::NOTIFICATION_EXP_FINALIZATION . ' '; } // Attributes to control if sync was OK $new_input['algorithm'] = self::get_algorithm(); $new_input['make_site_consistent'] = self::make_site_consistent(); $new_input['expl_ratio'] = self::get_exploitation_percentage(); $new_input['get_params_visibility'] = self::get_params_visibility(); $new_input['hm_tracking_mode'] = self::get_heatmap_tracking_mode(); $new_input['user_split'] = self::get_split_user_mode(); $new_input['ori_perc'] = self::get_original_percentage(); $new_input['perc_of_tested_users'] = self::get_percentage_of_tested_users(); $new_input['quota_limit_per_exp'] = self::get_quota_limit_per_exp(); $new_input['notification_email'] = self::get_notification_email(); $new_input['notifications'] = self::get_notifications(); $new_input['try_algorithm'] = $algorithm; $new_input['try_make_site_consistent'] = $make_site_consistent; $new_input['try_expl_ratio'] = $expl_ratio; $new_input['try_get_params_visibility'] = $get_params_visibility; $new_input['try_hm_tracking_mode'] = $hm_tracking_mode; $new_input['try_user_split'] = $user_split; $new_input['try_ori_perc'] = $ori_perc; $new_input['try_perc_of_tested_users'] = $perc_of_tested_users; $new_input['try_quota_limit_per_exp'] = $limit; $new_input['try_notification_email'] = $email; $new_input['try_notifications'] = $notifications; // Send data to Google $url = sprintf(NELIOAB_BACKEND_URL . '/site/%s/settings', NelioABAccountSettings::get_site_id()); $object = array('algorithm' => $algorithm, 'consistency' => $make_site_consistent, 'exploitPerc' => $expl_ratio, 'hideParams' => $get_params_visibility, 'hmMode' => $hm_tracking_mode, 'mode' => $user_split, 'partChance' => $perc_of_tested_users, 'oriPrio' => $ori_perc, 'notificationEmail' => $email, 'notifications' => $notifications, 'quotaLimit' => $limit); NelioABBackend::remote_post($url, $object); $new_input['algorithm'] = $algorithm; $new_input['make_site_consistent'] = $make_site_consistent; $new_input['expl_ratio'] = $expl_ratio; $new_input['get_params_visibility'] = $get_params_visibility; $new_input['hm_tracking_mode'] = $hm_tracking_mode; $new_input['user_split'] = $user_split; $new_input['ori_perc'] = $ori_perc; $new_input['perc_of_tested_users'] = $perc_of_tested_users; $new_input['quota_limit_per_exp'] = $limit; $new_input['notification_email'] = $email; $new_input['notifications'] = $notifications; } catch (Exception $e) { } return $new_input; }
public function save() { // 1. UPDATE OR CREATE THE EXPERIMENT if ($this->get_id() < 0) { $url = sprintf(NELIOAB_BACKEND_URL . '/site/%s/exp/global', NelioABAccountSettings::get_site_id()); } else { $url = sprintf(NELIOAB_BACKEND_URL . '/exp/global/%s/update', $this->get_id()); } if ($this->get_status() != NelioABExperiment::STATUS_PAUSED && $this->get_status() != NelioABExperiment::STATUS_RUNNING && $this->get_status() != NelioABExperiment::STATUS_FINISHED && $this->get_status() != NelioABExperiment::STATUS_TRASH) { $this->set_status($this->determine_proper_status()); } $body = array('name' => $this->get_name(), 'description' => $this->get_description(), 'origin' => $this->get_origins(), 'status' => $this->get_status(), 'kind' => $this->get_textual_type(), 'finalizationMode' => $this->get_finalization_mode(), 'finalizationModeValue' => $this->get_finalization_value()); /** @var array $result */ $result = NelioABBackend::remote_post($url, $body); $exp_id = $this->get_id(); if ($exp_id < 0) { if (is_wp_error($result)) { return 0; } $json = json_decode($result['body']); $exp_id = $json->key->id; $this->id = $exp_id; } // 1.1 SAVE GOALS // ------------------------------------------------------------------------- $this->make_goals_persistent(); return $this->get_id(); }
/** * PHPDOC * * @return void * * @since PHPDOC */ public function update_winning_alternative_from_appengine() { $this->winning_alternative = false; try { require_once NELIOAB_UTILS_DIR . '/backend.php'; $json_data = NelioABBackend::remote_get(sprintf(NELIOAB_BACKEND_URL . '/exp/%s/%s/winner', $this->get_exp_kind_url_fragment(), $this->get_id())); $json_data = json_decode($json_data['body']); if (isset($json_data->winner) && $json_data->winner != 'NO_WINNER') { $this->set_winning_alternative_using_id($json_data->winner); } } catch (Exception $e) { } }
/** * It duplicates the experiment in AppEngine and returns the new ID. * * This function should be extended by concrete subclasses, because, as it * is defined in this abstract class, it only duplicates all the the * information of the experiment in AppEngine. Any additional data that is * stored in WordPress, has to be duplicated by the overwriting methods. * * @param string $new_name the new name of the duplicated experiment. * * @return int the ID of the new experiment (if successfully duplicated) or -1 otherwise. * * @since 3.4.0 */ public function duplicate($new_name) { // If the experiment is not running, or finished, or ready... // then it cannot be duplicated if ($this->get_status() != NelioABExperiment::STATUS_RUNNING && $this->get_status() != NelioABExperiment::STATUS_FINISHED && $this->get_status() != NelioABExperiment::STATUS_READY) { return -1; } require_once NELIOAB_UTILS_DIR . '/backend.php'; $url = sprintf(NELIOAB_BACKEND_URL . '/exp/%s/%s/duplicate', $this->get_exp_kind_url_fragment(), $this->get_id()); $body = array('name' => $new_name); $result = NelioABBackend::remote_post($url, $body); $result = json_decode($result['body']); return $result->id; }
/** * PHPDOC * * @return NelioABAltExpGoalResult PHPDOC * * @since PHPDOC */ public function get_results() { $results = new NelioABAltExpGoalResult(); /** @var NelioABAlternativeExperiment $experiment */ $experiment = $this->get_experiment(); $url = sprintf(NELIOAB_BACKEND_URL . '/goal/alternativeexp/%s/result', $this->get_id()); $json_data = null; $json_data = NelioABBackend::remote_get($url); $json_data = json_decode($json_data['body'], true); $results->set_total_visitors($json_data['totalVisitors']); $results->set_total_conversions($json_data['totalConversions']); $results->set_total_conversion_rate($json_data['totalConversionRate']); $results->set_visitors_history($json_data['historyVisitors']); $results->set_conversions_history($json_data['historyConversions']); $results->set_first_update($json_data['firstUpdate']); $results->set_last_update($json_data['lastUpdate']); $confidence = 0; if (isset($json_data['resultStatus'])) { $confidence = $json_data['confidenceInResultStatus']; } $results->set_summary_status(NelioABGTest::get_result_status_from_str($json_data['resultStatus']), $confidence); $alt_res = new NelioABAltStats(true); // Original $alt_res->set_name(__('Original', 'nelioab')); $alt_res->set_alt_id($json_data['originalStats']['altId']); $alt_res->set_num_of_visitors($json_data['originalStats']['visitors']); $alt_res->set_num_of_conversions($json_data['originalStats']['conversions']); $alt_res->set_conversion_rate($json_data['originalStats']['conversionRate']); if (isset($json_data['originalStats']['historyVisitors'])) { $alt_res->set_visitors_history($json_data['originalStats']['historyVisitors']); } if (isset($json_data['originalStats']['historyConversions'])) { $alt_res->set_conversions_history($json_data['originalStats']['historyConversions']); } $results->add_alternative_results($alt_res); if (is_array($json_data['alternativeStats'])) { foreach ($json_data['alternativeStats'] as $json_alt) { $alt_res = new NelioABAltStats(); $alternative = null; foreach ($experiment->get_alternatives() as $alt) { /** @var NelioABAlternative $alt */ if ($alt->get_id() == $json_alt['altId']) { $alternative = $alt; } } if ($alternative == null) { foreach ($experiment->get_alternatives() as $alt) { if ($alt->applies_to_post_id($json_alt['altId'])) { $alternative = $alt; } } } if ($alternative == null) { continue; } $alt_res->set_name($alternative->get_name()); $alt_res->set_alt_id($json_alt['altId']); $alt_res->set_num_of_visitors($json_alt['visitors']); $alt_res->set_num_of_conversions($json_alt['conversions']); $alt_res->set_conversion_rate($json_alt['conversionRate']); $alt_res->set_improvement_factor($json_alt['improvementFactor']); if (isset($json_alt['historyVisitors'])) { $alt_res->set_visitors_history($json_alt['historyVisitors']); } if (isset($json_alt['historyConversions'])) { $alt_res->set_conversions_history($json_alt['historyConversions']); } $results->add_alternative_results($alt_res); } } if (is_array($json_data['gTests'])) { foreach ($json_data['gTests'] as $stats) { $g = new NelioABGTest($stats['message'], $experiment->get_originals_id()); $min_ver = NULL; if (isset($stats['minVersion'])) { $min_ver = $stats['minVersion']; $g->set_min($min_ver); } $max_ver = NULL; if (isset($stats['maxVersion'])) { $max_ver = $stats['maxVersion']; $g->set_max($max_ver); } if (isset($stats['gtest'])) { $g->set_gtest($stats['gtest']); } if (isset($stats['pvalue'])) { $g->set_pvalue($stats['pvalue']); } if (isset($stats['certainty'])) { $g->set_certainty($stats['certainty']); } $g->set_min_name(__('Unknown', 'nelioab')); $g->set_max_name(__('Unknown', 'nelioab')); $alts = $experiment->get_alternatives(); for ($i = 0; $i < count($alts); ++$i) { $alt = $alts[$i]; $short_name = sprintf(__('Alternative %s', 'nelioab'), $i + 1); if ($alt->get_identifiable_value() == $min_ver || $alt->get_id() == $min_ver) { $g->set_min_name($short_name, $alt->get_name()); } if ($alt->get_identifiable_value() == $max_ver || $alt->get_id() == $max_ver) { $g->set_max_name($short_name, $alt->get_name()); } } if ($experiment->get_originals_id() == $min_ver) { $g->set_min_name(__('Original', 'nelioab')); } if ($experiment->get_originals_id() == $max_ver) { $g->set_max_name(__('Original', 'nelioab')); } $results->add_gtest($g); } } return $results; }
if ($exp_type == NelioABExperiment::HEATMAP_EXP) { $url = sprintf(NELIOAB_BACKEND_URL . '/exp/hm/%s/result', $exp->get_id()); $post_id = $exp->get_post_id(); global $nelioab_controller; if ($post_id == NelioABController::FRONT_PAGE__YOUR_LATEST_POSTS) { $post_id = false; } } else { if (!isset($_GET['post'])) { $err = NelioABErrCodes::TOO_FEW_PARAMETERS; throw new Exception(NelioABErrCodes::to_string($err), $err); } $url = sprintf(NELIOAB_BACKEND_URL . '/exp/post/%s/hm/%s/result', $exp->get_id(), $_GET['post']); $post_id = $_GET['post']; } $result = NelioABBackend::remote_get($url); $result = json_decode($result['body']); $counter = 0; if (isset($result->data)) { foreach ($result->data as $heatmap) { if (isset($heatmap->value)) { $value = json_decode($heatmap->value); $counter += $value->max; } } } if ($counter == 0) { if ($exp->get_status() == NelioABExperiment::STATUS_RUNNING) { $err = NelioABErrCodes::NO_HEATMAPS_AVAILABLE; throw new Exception(NelioABErrCodes::to_string($err), $err); } else {
/** * PHPDOC * * @param string $type PHPDOC * @param int $form_id PHPDOC * * @return void * * @since PHPDOC */ private function send_form_action_if_required($type, $form_id) { require_once NELIOAB_MODELS_DIR . '/goals/actions/form-submission-action.php'; require_once NELIOAB_MODELS_DIR . '/goals/actions/action.php'; require_once NELIOAB_UTILS_DIR . '/backend.php'; $kap = NelioABFormSubmissionAction::type_to_kind_and_plugin($type); if (!$kap) { return; } $f = 'nelioab_current_id'; if (!isset($_POST[$f])) { return; } $f = 'nelioab_current_actual_id'; if (!isset($_POST[$f])) { return; } $f = 'nelioab_userid'; if (!isset($_POST[$f]) || strlen(trim($_POST[$f])) === 0) { return; } // Constructing FORM EVENT object: $page = $_POST['nelioab_current_id']; $actual_page = $_POST['nelioab_current_actual_id']; $ev = array('kind' => $kap['kind'], 'form' => $form_id, 'plugin' => $kap['plugin'], 'page' => $page, 'actualPage' => $actual_page, 'user' => $_POST['nelioab_userid']); $the_theme = NelioABVisitor::get_alternative_for_global_alt_exp(NelioABExperiment::THEME_ALT_EXP); if ($the_theme) { $ev['activeTheme'] = $the_theme->get_id(); } $the_css = NelioABVisitor::get_alternative_for_global_alt_exp(NelioABExperiment::CSS_ALT_EXP); if ($the_css) { $ev['activeCSS'] = $the_css->get_id(); } $the_widget = NelioABVisitor::get_alternative_for_global_alt_exp(NelioABExperiment::WIDGET_ALT_EXP); if ($the_widget) { $ev['activeWidget'] = '' . $the_widget->get_id(); } $the_menu = NelioABVisitor::get_alternative_for_global_alt_exp(NelioABExperiment::MENU_ALT_EXP); if ($the_menu) { $ev['activeMenu'] = $the_menu->get_id(); } // Check if there's one experiment at least with a form submission action, // which corresponds to the given form, then send the event. Otherwise, // get out! require_once NELIOAB_MODELS_DIR . '/experiments-manager.php'; $send_form_event = false; $running_exps = NelioABExperimentsManager::get_relevant_running_experiments_from_cache(); foreach ($running_exps as $exp) { /** @var NelioABExperiment $exp */ foreach ($exp->get_goals() as $goal) { /** @var NelioABAltExpGoal $goal */ foreach ($goal->get_actions() as $action) { /** @var NelioABFormSubmissionAction $action */ if ($action->get_type() == $type && $action->get_form_id() == $ev['form']) { // If this action uses the form, then we have to check whether // it accepts submissions from anywhere or only from the tested // page. if ($action->accepts_submissions_from_any_page()) { $send_form_event = true; break; } if ($exp->get_originals_id() == $ev['page']) { $send_form_event = true; break; } } } if ($send_form_event) { break; } } if ($send_form_event) { break; } } if (!$send_form_event) { return; } $url = sprintf(NELIOAB_BACKEND_URL . '/site/%s/form', NelioABAccountSettings::get_site_id()); $data = NelioABBackend::build_json_object_with_credentials($ev); $data['timeout'] = 50; for ($attemp = 0; $attemp < 5; ++$attemp) { try { NelioABBackend::remote_post_raw($url, $data); break; } catch (Exception $e) { // If the form submission event could not be sent, it may be that's // because there is no more quota available if ($e->getCode() == NelioABErrCodes::NO_MORE_QUOTA) { // If that was the case, simply leave break; } // If there was another error... we just keep trying (attemp) up to 5 // times. } } }
/** * Returns the most relevant information of Nelio A/B Testing (to be displayed in the dashboard). * * @return array { * Most relevant information of Nelio A/B Testing (to be displayed in the dashboard). * * @type array $exps List of running experiments. * @type array $quota Two integers: the amount of `used` quota and the `total` quota available. * } * * @since 3.4.4 */ public static function get_dashboard_summary() { // This function is used in the Dashboard require_once NELIOAB_UTILS_DIR . '/backend.php'; $json_data = NelioABBackend::remote_get(sprintf(NELIOAB_BACKEND_URL . '/site/%s/exp/summary', NelioABAccountSettings::get_site_id())); // Including types of experiments... require_once NELIOAB_MODELS_DIR . '/summaries/alt-exp-summary.php'; require_once NELIOAB_MODELS_DIR . '/summaries/heatmap-exp-summary.php'; $json_data = json_decode($json_data['body']); $result = array('exps' => array(), 'quota' => array('regular' => 5000, 'monthly' => 5000, 'extra' => 0)); if (isset($json_data->quota)) { $result['quota']['regular'] = $json_data->quota + $json_data->quotaExtra; } if (isset($json_data->quotaPerMonth)) { $result['quota']['monthly'] = $json_data->quotaPerMonth; } if ($result['quota']['regular'] > $result['quota']['monthly']) { $diff = $result['quota']['regular'] - $result['quota']['monthly']; $result['quota']['extra'] += $diff; $result['quota']['regular'] = $result['quota']['monthly']; } if (isset($json_data->items)) { foreach ($json_data->items as $item) { /** @var NelioABExperimentSummary $exp */ switch ($item->kind) { case NelioABExperiment::HEATMAP_EXP_STR: $exp = new NelioABHeatmapExpSummary($item->key->id); break; default: $exp = new NelioABAltExpSummary($item->key->id); } if ($exp) { $exp->load_json4ae($item); array_push($result['exps'], $exp); } } } return $result; }
/** * PHPDOC * * @return void * * @since 4.1.3 */ public static function process_free_trial_promo() { if (!isset($_POST['promo'])) { echo 'NO_PROMO_SPECIFIED'; die; } $url = sprintf(NELIOAB_BACKEND_URL . '/customer/%s/promo', self::get_customer_id()); $data = array('promo' => $_POST['promo']); switch ($_POST['promo']) { case 'basic-info': if (!isset($_POST['name']) || !isset($_POST['email'])) { break; } $value = array('name' => $_POST['name'], 'mail' => $_POST['email']); $data['value'] = json_encode($value); try { NelioABBackend::remote_post($url, $data); self::complete_promo_action('basic-info'); self::update_nelioab_option('free_trial_name', $value['name']); self::update_nelioab_option('free_trial_mail', $value['mail']); echo 'OK'; die; } catch (Exception $e) { } break; case 'basic-info-check': try { $url = sprintf(NELIOAB_BACKEND_URL . '/customer/%s/check', self::get_customer_id()); $res = NelioABBackend::remote_get($url); $res = json_decode($res['body']); if (isset($res->confirmed) && 1 == $res->confirmed) { self::complete_promo_action('basic-info-check'); echo 'OK'; die; } } catch (Exception $e) { } break; case 'site-info': if (!isset($_POST['type']) || !isset($_POST['sector'])) { break; } $data['value'] = $_POST['type'] . ',' . $_POST['sector']; try { NelioABBackend::remote_post($url, $data); self::complete_promo_action('site-info'); echo 'OK'; die; } catch (Exception $e) { } break; case 'goals': if (!isset($_POST['goal']) || !isset($_POST['success'])) { break; } $value = array('goal' => $_POST['goal'], 'success' => $_POST['success']); $data['value'] = json_encode($value); try { NelioABBackend::remote_post($url, $data); self::complete_promo_action('goals'); echo 'OK'; die; } catch (Exception $e) { } break; case 'connect': case 'tweet': try { NelioABBackend::remote_post($url, $data); self::complete_promo_action($_POST['promo']); echo 'OK'; die; } catch (Exception $e) { } break; case 'recommend': if (!isset($_POST['value'])) { break; } $data['value'] = $_POST['value']; try { NelioABBackend::remote_post($url, $data); self::complete_promo_action('recommend'); echo 'OK'; die; } catch (Exception $e) { } break; default: echo 'UNKNOWN_PROMO'; die; } echo 'FAIL'; die; }
public static function load($id) { $json_data = NelioABBackend::remote_get(NELIOAB_BACKEND_URL . '/exp/hm/' . $id); $json_data = json_decode($json_data['body']); $exp = new NelioABHeatmapExperiment($json_data->key->id); $exp->set_type_using_text($json_data->kind); $exp->set_name($json_data->name); $exp->set_post_id($json_data->post); if (isset($json_data->description)) { $exp->set_description($json_data->description); } $exp->set_status($json_data->status); $exp->set_finalization_mode($json_data->finalizationMode); if (isset($json_data->finalizationModeValue)) { $exp->set_finalization_value($json_data->finalizationModeValue); } if (isset($json_data->goals)) { NelioABExperiment::load_goals_from_json($exp, $json_data->goals); } return $exp; }
public static function generate_html_content() { require_once NELIOAB_ADMIN_DIR . '/views/account-page.php'; // Check data against APPENGINE $email = NelioABAccountSettings::get_email(); $reg_num = NelioABAccountSettings::get_reg_num(); if (NelioABAccountSettings::is_using_free_trial()) { $email = ''; $reg_num = ''; } $sites = array(); $max_sites = 1; try { NelioABAccountSettings::check_account_status('now'); } catch (Exception $e) { } $current_site_status = NelioABSite::NOT_REGISTERED; $error_retrieving_registered_sites = false; try { $sites_info = NelioABAccountSettings::get_registered_sites_information(); $max_sites = $sites_info->get_max_sites(); $sites = $sites_info->get_registered_sites(); // CHECKING WHETHER WE HAVE INFORMATION ABOUT THIS SITE BEING REGISTERED, // EITHER BY ID OR BY URL // 1. We check if this user has a registered site whose URL is this site's url $registered_site_based_on_url = false; foreach ($sites as $site) { if ($site->get_url() == get_option('siteurl')) { $registered_site_based_on_url = $site->get_id(); } } // 2. We check if the WP installation has a SITE_ID // If it does, but it's none of the user's regitered sites, // we have a problem, and we'll say the status is INVALID_ID. if (NelioABAccountSettings::has_a_configured_site()) { $site_id = NelioABAccountSettings::get_site_id(); $current_site_status = NelioABSite::INVALID_ID; foreach ($sites as $site) { if ($site->get_id() == $site_id) { $current_site_status = NelioABSite::ACTIVE; } } } // POSSIBLE RESULTS OF THE PREVIOUS CHECKS: // (a) The site is properly registered (== it has a valid ID) //if ( NelioABSite::ACTIVE == $current_site_status ) // Nothing to do here // (b) We have information about an ID that the user, in AE, does not have if (NelioABSite::INVALID_ID == $current_site_status) { $current_site_status = NelioABSite::NOT_REGISTERED; NelioABAccountSettings::fix_registration_info('not-registered'); } // (c) The site is not registered if (NelioABSite::NOT_REGISTERED == $current_site_status) { if ($registered_site_based_on_url) { $current_site_status = NelioABSite::ACTIVE; NelioABAccountSettings::fix_registration_info('registered', $registered_site_based_on_url); } } // (d) Other scenarios are: // - INACTIVE. We don't care. // - NON_MATCHING_URLS. We no longer use it. } catch (Exception $e) { $error_retrieving_registered_sites = true; } // Querying account information $user_info = array(); try { $customer_id = NelioABAccountSettings::get_customer_id(); if (strlen($customer_id) > 0) { $url = sprintf(NELIOAB_BACKEND_URL . '/customer/%s', $customer_id); $json = NelioABBackend::remote_get($url, true); $json = json_decode($json['body']); if (isset($user_info['firstname'])) { $user_info['firstname'] = $json->firstname; } else { $user_info['firstname'] = ''; } $user_info['subscription_url'] = $json->subscriptionUrl; $user_info['subscription_plan'] = $json->subscriptionPlan; $user_info['status'] = $json->status; $user_info['total_quota'] = intval($json->quotaPerMonth); $user_info['quota'] = intval($json->quota + $json->quotaExtra); } // Agency stuff if (isset($json->hasAgency) && $json->hasAgency) { $user_info['agency'] = true; $user_info['agencyname'] = $json->agencyName; $user_info['agencymail'] = $json->agencyEmail; } else { $user_info['agency'] = false; $user_info['agencyname'] = 'Agency Name'; $user_info['agencymail'] = '*****@*****.**'; } } catch (Exception $e) { } // Render content $title = __('My Account', 'nelioab'); $view = new NelioABAccountPage($title); $view->set_email($email); $view->set_email_validity(NelioABAccountSettings::is_email_valid()); $view->set_reg_num($reg_num); $view->set_reg_num_validity(NelioABAccountSettings::is_reg_num_valid()); $view->set_tac_checked(NelioABAccountSettings::are_terms_and_conditions_accepted()); $view->set_registered_sites($sites); $view->set_max_sites($max_sites); $view->set_current_site_status($current_site_status); $view->set_user_info($user_info); if ($error_retrieving_registered_sites) { $view->set_error_retrieving_registered_sites(); } $view->render_content(); die; }
/** * PHPDOC * * @param int $order_id PHPDOC * * @return void * * @since PHPDOC */ public function sync_order_completed($order_id) { $order = wc_get_order($order_id); $items = $order->get_items(); $user = get_post_meta($order_id, '_nelioab_userid', true); $env = get_post_meta($order_id, '_nelioab_form_env', true); if (!$user) { return; } require_once NELIOAB_MODELS_DIR . '/experiments-manager.php'; $running_experiments = NelioABExperimentsManager::get_running_experiments_from_cache(); // Let's start by selecting the relevant experiments. // A relevant experiment is a running experiment that was in the environment // that was active during the purchase AND that has at least one conversion // action in its goals that tracks an "Order Completed" event. $relevant_experiments = array(); $relevant_conversion_actions = array(); foreach ($env as $id => $alt) { foreach ($running_experiments as $exp) { if ($exp->get_id() != $id) { continue; } foreach ($exp->get_goals() as $goal) { if ($goal->get_kind() != NelioABGoal::ALTERNATIVE_EXPERIMENT_GOAL) { continue; } foreach ($goal->get_actions() as $action) { echo "Considering {$action->get_id()}... "; if ($action->get_type() != NelioABAction::WC_ORDER_COMPLETED) { echo "NO<br>"; continue; } echo "YES<br>"; // Once we've found a Order Complete conversion action, we save: // a) the experiment // b) the product controlled by that conversion action if (!in_array($exp, $relevant_experiments)) { array_push($relevant_experiments, $exp); } array_push($relevant_conversion_actions, $action); } } } } // Now we need to see if products are being tested and, if they are, // the IDs of the concrete alternatives the visitor saw. $relevant_products = array(); foreach ($relevant_experiments as $exp) { if ($exp->get_type() != NelioABExperiment::WC_PRODUCT_SUMMARY_ALT_EXP) { continue; } $alt_num = false; foreach ($env as $id => $alt) { if ($exp->get_id() == $id) { $alt_num = $alt; break; } } if ($alt_num !== false) { if (0 == $alt_num) { // We use "-1" because it's the ID we use for the "original alternative" object // (which doesn't exist in AE). $alt = -1; } else { $alts = $exp->get_alternatives(); if ($alt_num > count($alts)) { continue; } $alt = $alts[$alt_num - 1]; $alt = $alt->get_id(); } $relevant_products[$exp->get_originals_id()] = $alt; break; } } // Once we have the list of PRODUCT_ID => ACTUAL_PRODUCT_ID, we need to // include all the other relevant product IDs: foreach ($relevant_conversion_actions as $action) { $product_id = $action->get_product_id(); if (!isset($relevant_products[$product_id])) { $relevant_products[$product_id] = $product_id; } } // Now we need to get information about the global experiments: $css_alt = false; $menu_alt = false; $theme_alt = false; $widget_alt = false; foreach ($relevant_experiments as $exp) { foreach ($env as $id => $alt_num) { if ($exp->get_id() != $id) { continue; } $alt = false; switch ($exp->get_type()) { case NelioABExperiment::CSS_ALT_EXP: case NelioABExperiment::MENU_ALT_EXP: case NelioABExperiment::THEME_ALT_EXP: case NelioABExperiment::WIDGET_ALT_EXP: if (0 == $alt_num) { $alt = $exp->get_original(); } else { $alts = $exp->get_alternatives(); if ($alt_num > count($alts)) { continue; } $alt = $alts[$alt_num - 1]; } $alt = $alt->get_id(); break; } if ($alt) { switch ($exp->get_type()) { case NelioABExperiment::CSS_ALT_EXP: $css_alt = $alt; break; case NelioABExperiment::MENU_ALT_EXP: $menu_alt = $alt; break; case NelioABExperiment::THEME_ALT_EXP: $theme_alt = $alt; break; case NelioABExperiment::WIDGET_ALT_EXP: $widget_alt = $alt; break; } } } } // Finally, we can create the result object $result = array('products' => array()); foreach ($relevant_products as $product_id => $actual_product_id) { $product_found = false; foreach ($items as $item) { if (isset($item['product_id']) && $item['product_id'] == $product_id) { $product_found = true; break; } } if ($product_found) { array_push($result['products'], $product_id . ':' . $actual_product_id); } } if (count($result['products']) > 0) { $result['kind'] = 'OrderComplete'; $result['products'] = implode(',', $result['products']); $result['user'] = $user; if ($css_alt) { $result['activeCSS'] = $css_alt; } if ($menu_alt) { $result['activeMenu'] = $menu_alt; } if ($theme_alt) { $result['activeTheme'] = $theme_alt; } if ($widget_alt) { $result['activeWidget'] = $widget_alt; } $url = sprintf(NELIOAB_BACKEND_URL . '/site/%s/productevent', NelioABAccountSettings::get_site_id()); $data = NelioABBackend::build_json_object_with_credentials($result); $data['timeout'] = 50; for ($attemp = 0; $attemp < 5; ++$attemp) { try { NelioABBackend::remote_post_raw($url, $data); break; } catch (Exception $e) { // If the form submission event could not be sent, it may be that's // because there is no more quota available if ($e->getCode() == NelioABErrCodes::NO_MORE_QUOTA) { // If that was the case, simply leave break; } // If there was another error... we just keep trying (attemp) up to 5 // times. } } } }
/** * Deactivates our plugin. * * This function is called by the "registed_deactivation_hook". Alternatives * are regular pages or posts (draft status) with a special metaoption that * is used to hide them from the admin menu. When the plugin is deactivated, * no one hides the alternatives... In order to prevent them from appearing, * we change their post_type to a fake type. * * @return void * * @since PHPDOC */ function nelioab_deactivate_plugin() { /** @var wpdb $wpdb */ global $wpdb; require_once NELIOAB_EXP_CONTROLLERS_DIR . '/widget-experiment-controller.php'; require_once NELIOAB_EXP_CONTROLLERS_DIR . '/menu-experiment-controller.php'; if (isset($_GET['action']) && 'clean-and-deactivate' == $_GET['action']) { // Remove all alternative widgets NelioABWidgetExpAdminController::clean_all_alternative_widgets(); // Remove all alternative menus NelioABMenuExpAdminController::clean_all_alternative_menus(); // Remove all alternative pages and posts $query = '' . 'DELETE FROM ' . $wpdb->posts . ' WHERE ' . 'id IN (' . 'SELECT post_id FROM ' . $wpdb->postmeta . ' WHERE ' . 'meta_key = \'_is_nelioab_alternative\' ' . ')'; $wpdb->query($query); // Clean all experiments in AE require_once NELIOAB_UTILS_DIR . '/backend.php'; for ($i = 0; $i < 5; ++$i) { try { NelioABBackend::remote_get(sprintf(NELIOAB_BACKEND_URL . '/site/%s/clean', NelioABAccountSettings::get_site_id())); break; } catch (Exception $e) { } } // Remove all Nelio options $query = 'DELETE FROM ' . $wpdb->postmeta . ' WHERE meta_key LIKE \'%nelioab%\''; $wpdb->query($query); $query = 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE \'%nelioab%\''; $wpdb->query($query); } else { // Hiding alternative posts $query = '' . 'UPDATE ' . $wpdb->posts . ' SET post_type = %s WHERE ' . 'id IN (' . 'SELECT post_id FROM ' . $wpdb->postmeta . ' WHERE ' . 'meta_key = \'_is_nelioab_alternative\' ' . ') AND ' . 'post_type = %s'; // recover post type names require_once NELIOAB_UTILS_DIR . '/wp-helper.php'; $cpts = NelioABWpHelper::get_custom_post_types(); $post_types = array('post', 'page'); foreach ($cpts as $post_type) { array_push($post_types, $post_type->name); } // execute the query foreach ($post_types as $post_type) { $wpdb->query($wpdb->prepare($query, 'nelioab_alt_' . $post_type, $post_type)); } // Hiding widget alternatives NelioABWidgetExpAdminController::backup_alternative_widgets(); // Hiding menu alternatives NelioABMenuExpAdminController::backup_alternative_menus(); } }
/** * PHPDOC * * @param string $url PHPDOC * @param boolean $skip_status_check PHPDOC * * @return WP_Error|array The response or WP_Error on failure. * * @throws Exception with the appropriate error code. * * @since PHPDOC */ public static function remote_get($url, $skip_status_check = false) { return NelioABBackend::remote_post($url, array(), $skip_status_check); }