private function print_table_of_registered_sites() { $sites = array(); $other_sites = array(); $this_url = get_option('siteurl'); $this_id = NelioABAccountSettings::get_site_id(); $reg_name = false; foreach ($this->sites as $site) { if ($site->get_id() != $this_id || $this->current_site_status != NelioABSite::ACTIVE) { array_push($other_sites, $site); } else { $reg_name = $site->get_url(); } } if ($this->current_site_status == NelioABSite::ACTIVE) { $live = false === $reg_name ? 'live' : 'staging'; array_push($sites, array('this_site' => true, 'name' => $this_url, 'reg_name' => $reg_name, 'live' => $live)); } foreach ($other_sites as $site) { array_push($sites, array('this_site' => false, 'name' => $site->get_url(), 'goto_link' => $site->get_url())); } for ($i = count($sites); $i < $this->max_sites; ++$i) { array_push($sites, array('this_site' => false, 'name' => __('Empty Slot', 'nelioab'))); } echo '<div id="registered-sites-table" style="margin-left:2em;">'; $aux = new NelioABRegisteredSitesTable($sites); $aux->prepare_items(); $aux->display(); echo '</div>'; }
public function save() { // 1. UPDATE OR CREATE THE EXPERIMENT // ------------------------------------------------------------------------- if ($this->get_id() < 0) { $url = sprintf(NELIOAB_BACKEND_URL . '/site/%s/exp/post', NelioABAccountSettings::get_site_id()); } else { $url = sprintf(NELIOAB_BACKEND_URL . '/exp/post/%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(), 'originalPost' => $this->get_originals_id(), 'postType' => $this->get_post_type(), 'status' => $this->get_status(), 'kind' => $this->get_textual_type(), 'showHeatmap' => $this->are_heatmaps_tracked(), 'finalizationMode' => $this->get_finalization_mode(), 'finalizationModeValue' => $this->get_finalization_value()); $result = NelioABBackend::remote_post($url, $body); $exp_id = $this->get_id(); if ($exp_id < 0) { if (is_wp_error($result)) { return; } $json = json_decode($result['body']); $exp_id = $json->key->id; $this->id = $exp_id; } // 1.1 SAVE GOALS // ------------------------------------------------------------------------- $this->make_goals_persistent(); // 2. UPDATE THE ALTERNATIVES // ------------------------------------------------------------------------- // 2.1. UPDATE CHANGES ON ALREADY EXISTING APPSPOT ALTERNATIVES foreach ($this->get_appspot_alternatives() as $alt) { /** @var NelioABAlternative $alt */ if ($alt->was_removed() || !$alt->is_dirty()) { continue; } $body = array('name' => $alt->get_name(), 'value' => $alt->get_value()); NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/update', $alt->get_id()), $body); } // 2.2. REMOVE FROM APPSPOT THE REMOVED ALTERNATIVES foreach ($this->get_appspot_alternatives() as $alt) { if (!$alt->was_removed()) { continue; } $url = sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/delete', $alt->get_id()); NelioABBackend::remote_post($url); } // 2.3. CREATE LOCAL ALTERNATIVES IN APPSPOT /** @var array $ori_post */ $ori_post = get_post($this->get_originals_id(), ARRAY_A); foreach ($this->get_local_alternatives() as $alt) { if ($alt->was_removed()) { continue; } if ($this->get_type() != NelioABExperiment::HEADLINE_ALT_EXP) { if ($alt->is_based_on_another_element()) { $new_id = $this->create_alternative_copying_content($alt->get_name(), $alt->get_base_element(), $ori_post); if ($new_id) { $alt->set_value($new_id); } else { continue; } } else { $new_id = $this->create_empty_alternative($alt->get_name(), $this->get_type(), $this->get_post_type()); if ($new_id) { $alt->set_value($new_id); } else { continue; } } } $body = array('name' => $alt->get_name(), 'value' => $alt->get_value(), 'kind' => NelioABExperiment::get_textual_type()); try { /** @var int $result */ $result = NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/exp/post/%s/alternative', $exp_id), $body); $alt->set_id($result); } catch (Exception $e) { // If I could not add an alternative... remove the associated page wp_delete_post($alt->get_value()); } } // 2.3 REMOVE THE PAGES THAT BELONGED TO AN ALTERNATIVE THAT HAS BEEN DELETED $all_alternatives = array_merge($this->get_appspot_alternatives(), $this->get_local_alternatives()); foreach ($all_alternatives as $alt) { if ($alt->was_removed()) { // Delete permanently (skipping Trash) if ($alt->get_value()) { wp_delete_post($alt->get_value(), true); } } } // 2.4 SET META "_is_nelioab_alternative" WITH THE ID OF THE EXPERIMENT foreach ($this->get_alternatives() as $alt) { $pid = $alt->get_value(); if (is_int($pid) && $pid > 0) { $value = $this->get_id() . ',' . $this->get_status(); update_post_meta($pid, "_is_nelioab_alternative", $value); } } require_once NELIOAB_MODELS_DIR . '/experiments-manager.php'; NelioABExperimentsManager::update_experiment($this); }
/** * 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; }
/** * 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. } } }
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(); }
/** * Removes this site from the account of our customer. * * @return void * * @throws Exception an exception triggered by AppEngine. * * @since 2.1.0 */ public static function deregister_this_site() { try { NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/site/%s/deactivate', NelioABAccountSettings::get_site_id()), array(), true); } catch (Exception $e) { throw $e; } self::update_nelioab_option('has_a_configured_site', false); }
/** * 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; }
public function save() { // 1. UPDATE OR CREATE THE EXPERIMENT // ------------------------------------------------------------------------- /** @var string $url */ if ($this->get_id() < 0) { $url = sprintf(NELIOAB_BACKEND_URL . '/site/%s/exp/hm', NelioABAccountSettings::get_site_id()); } else { $url = sprintf(NELIOAB_BACKEND_URL . '/exp/hm/%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(), 'post' => $this->get_post_id(), 'status' => $this->get_status(), 'kind' => $this->get_textual_type(), 'finalizationMode' => $this->get_finalization_mode(), 'finalizationModeValue' => $this->get_finalization_value()); $result = NelioABBackend::remote_post($url, $body); $exp_id = $this->get_id(); if ($exp_id < 0) { if (is_wp_error($result)) { return; } $json = json_decode($result['body']); $exp_id = $json->key->id; $this->id = $exp_id; } require_once NELIOAB_MODELS_DIR . '/experiments-manager.php'; NelioABExperimentsManager::update_experiment($this); }
public function save() { // 1. UPDATE OR CREATE THE EXPERIMENT // ------------------------------------------------------------------------- if ($this->get_id() < 0) { $url = sprintf(NELIOAB_BACKEND_URL . '/site/%s/exp/post', NelioABAccountSettings::get_site_id()); } else { $url = sprintf(NELIOAB_BACKEND_URL . '/exp/post/%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(), 'originalPost' => $this->get_originals_id(), 'status' => $this->get_status(), 'kind' => $this->get_textual_type(), 'showHeatmap' => $this->are_heatmaps_tracked(), 'finalizationMode' => $this->get_finalization_mode(), 'finalizationModeValue' => $this->get_finalization_value()); $result = NelioABBackend::remote_post($url, $body); $exp_id = $this->get_id(); if ($exp_id < 0) { if (is_wp_error($result)) { return; } $json = json_decode($result['body']); $exp_id = $json->key->id; $this->id = $exp_id; } // 1.1 SAVE GOALS // ------------------------------------------------------------------------- $this->make_goals_persistent(); // 2. UPDATE THE ALTERNATIVES // ------------------------------------------------------------------------- // 2.1. UPDATE CHANGES ON ALREADY EXISTING APPSPOT ALTERNATIVES foreach ($this->get_appspot_alternatives() as $alt) { /** @var NelioABHeadlineAlternative $alt */ if ($alt->was_removed() || !$alt->is_dirty()) { continue; } $body = array('name' => $alt->get_name(), 'value' => json_encode($this->fix_image_id_in_value($alt->get_value()))); NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/update', $alt->get_id()), $body); } // 2.2. REMOVE FROM APPSPOT THE REMOVED ALTERNATIVES foreach ($this->get_appspot_alternatives() as $alt) { if (!$alt->was_removed()) { continue; } $url = sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/delete', $alt->get_id()); NelioABBackend::remote_post($url); } // 2.3. CREATE LOCAL ALTERNATIVES IN APPSPOT foreach ($this->get_local_alternatives() as $alt) { if ($alt->was_removed()) { continue; } $body = array('name' => $alt->get_name(), 'value' => json_encode($this->fix_image_id_in_value($alt->get_value())), 'kind' => $this->get_textual_type()); try { /** @var int $result */ $result = NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/exp/post/%s/alternative', $exp_id), $body); $alt->set_id($result); } catch (Exception $e) { } } require_once NELIOAB_MODELS_DIR . '/experiments-manager.php'; NelioABExperimentsManager::update_experiment($this); }
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 * * @return array PHPDOC * * @since PHPDOC */ public static function make_credential() { // Creating the credential $result = array(); $aux = NelioABAccountSettings::get_customer_id(); if ($aux) { $result['customerId'] = $aux; } $aux = NelioABAccountSettings::get_reg_num(); if ($aux) { $result['registrationNumber'] = $aux; } $aux = NelioABAccountSettings::get_site_id(); if ($aux) { $result['siteId'] = $aux; } $result['siteUrl'] = get_option('siteurl'); return $result; }
/** * This function registers Nelio tracking scripts. * * Our tracking scripts are: * * * `nelioab_appengine_script`: a script pointing to Google Cloud Storage, * with all the information about running experiments. * * `nelioab_tracking_script`: our tracking script. * * It also initializes some params that will be used by our tracking * script. They'll be available by means of the object `NelioABParams`. * * @return void * * @see self::load_tracking_script * * @since 3.3.2 */ public function register_tracking_script() { wp_register_script('nelioab_appengine_script', '//storage.googleapis.com/' . NELIOAB_BACKEND_NAME . '/' . NelioABAccountSettings::get_site_id() . '.js', array(), NELIOAB_PLUGIN_VERSION); wp_register_script('nelioab_tracking_script', nelioab_asset_link('/js/tracking.min.js', false), array('jquery', 'nelioab_appengine_script'), NELIOAB_PLUGIN_VERSION); // Prepare some information for our tracking script (such as the page we're in) /** @var $aux NelioABAlternativeExperimentController */ $aux = $this->controllers['alt-exp']; $current_id = $this->get_queried_post_id(); if ($aux->is_post_in_a_post_alt_exp($current_id)) { $current_actual_id = intval($aux->get_post_alternative($current_id)); } elseif ($aux->is_post_in_a_headline_alt_exp($current_id)) { $headline_data = $aux->get_headline_experiment_and_alternative($current_id); /** @var NelioABAlternative $alternative */ $alternative = $headline_data['alt']; $val = $alternative->get_value(); $current_actual_id = $val['id']; } else { $current_actual_id = $current_id; } $current_page_ids = array('currentId' => $current_id, 'currentActualId' => $current_actual_id); // OUTWARDS NAVIGATIONS USING TARGET="_BLANK" $misc['useOutwardsNavigationsBlank'] = NelioABSettings::use_outwards_navigations_blank(); $this->tracking_script_params = array('ajaxurl' => admin_url('admin-ajax.php', is_ssl() ? 'https' : 'http'), 'version' => NELIOAB_PLUGIN_VERSION, 'customer' => NelioABAccountSettings::get_customer_id(), 'site' => NelioABAccountSettings::get_site_id(), 'backend' => array('domain' => NELIOAB_BACKEND_DOMAIN, 'version' => NELIOAB_BACKEND_VERSION), 'misc' => $misc, 'sync' => array('headlines' => array()), 'info' => $current_page_ids, 'ieUrl' => preg_replace('/^https?:/', '', NELIOAB_URL . '/ajax/iesupport.php'), 'wasPostRequest' => 'POST' === $_SERVER['REQUEST_METHOD']); }