public function save()
 {
     $exp_id = parent::save();
     // 2. UPDATE THE ALTERNATIVES
     // -------------------------------------------------------------------------
     // 2.1 REUSE ALL APPSPOT ALTERNATIVES
     $i = 0;
     while ($i < count($this->appspot_ids) && $i < count($this->selected_themes)) {
         $theme = $this->selected_themes[$i];
         $body = array('name' => $theme->name, 'value' => $theme->value);
         $url = sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/update', $this->appspot_ids[$i]);
         NelioABBackend::remote_post($url, $body);
         $i++;
     }
     // 2.2 CREATE NEW APPSPOT ALTERNATIVES (IF REQUIRED)
     while ($i < count($this->selected_themes)) {
         $theme = $this->selected_themes[$i];
         $body = array('name' => $theme->name, 'value' => $theme->value, 'kind' => NelioABExperiment::THEME_ALT_EXP_STR);
         try {
             $result = NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/exp/global/%s/alternative', $exp_id), $body);
             array_push($this->appspot_ids, $result);
         } catch (Exception $e) {
         }
         $i++;
     }
     // 2.3 REMOVE UNUSED APPSPOT ALTERNATIVES (IF REQUIRED)
     $last_valid = $i;
     while ($i < count($this->appspot_ids)) {
         $id = $this->appspot_ids[$i];
         $url = sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/delete', $id);
         NelioABBackend::remote_post($url);
         $i++;
     }
     $aux = $this->appspot_ids;
     $this->appspot_ids = array();
     for ($i = 0; $i < $last_valid; ++$i) {
         array_push($this->appspot_ids, $aux[$i]);
     }
     require_once NELIOAB_MODELS_DIR . '/experiments-manager.php';
     NelioABExperimentsManager::update_experiment($this);
 }
 public function save()
 {
     // 0. WE CHECK WHETHER THE EXPERIMENT IS COMPLETELY NEW OR NOT
     // -------------------------------------------------------------------------
     $is_new = $this->get_id() < 0;
     // 1. SAVE THE EXPERIMENT AND ITS GOALS
     // -------------------------------------------------------------------------
     $exp_id = parent::save();
     // 2. UPDATE THE ALTERNATIVES
     // -------------------------------------------------------------------------
     // 2.0. FIRST OF ALL, WE CREATE A FAKE ORIGINAL FOR NEW EXPERIMENTS
     /** @var NelioABAlternative $original */
     $original = $this->get_original();
     if ($is_new && $original->get_id() < 0) {
         $body = array('name' => $original->get_name(), 'content' => '', 'kind' => NelioABExperiment::get_textual_type());
         try {
             /** @var int $result */
             $result = NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/exp/global/%s/alternative', $exp_id), $body);
             $original->set_id($result);
         } catch (Exception $e) {
         }
     }
     // 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());
         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) {
         /** @var NelioABAlternative $alt */
         if (!$alt->was_removed()) {
             continue;
         }
         $url = sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/delete', $alt->get_id());
         try {
             NelioABBackend::remote_post($url);
         } catch (Exception $e) {
         }
     }
     // 2.3. CREATE LOCAL ALTERNATIVES IN APPSPOT
     $this->new_ids = array();
     foreach ($this->get_local_alternatives() as $alt) {
         /** @var NelioABAlternative $alt */
         if ($alt->was_removed()) {
             continue;
         }
         $body = array('name' => $alt->get_name(), 'content' => '', 'kind' => NelioABExperiment::get_textual_type());
         try {
             /** @var object|array $result */
             $result = NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/exp/global/%s/alternative', $exp_id), $body);
             $result = json_decode($result['body']);
             $this->new_ids[$alt->get_id()] = $result->key->id;
         } catch (Exception $e) {
         }
     }
     require_once NELIOAB_MODELS_DIR . '/experiments-manager.php';
     NelioABExperimentsManager::update_experiment($this);
 }
 public function save()
 {
     require_once NELIOAB_EXP_CONTROLLERS_DIR . '/menu-experiment-controller.php';
     $controller = NelioABMenuExpAdminController::get_instance();
     // 1. SAVE THE EXPERIMENT AND ITS GOALS
     // -------------------------------------------------------------------------
     $exp_id = parent::save();
     // 2. UPDATE THE ALTERNATIVES
     // -------------------------------------------------------------------------
     // 2.0. FIRST OF ALL, WE CREATE A FAKE ORIGINAL FOR NEW EXPERIMENTS
     /** @var NelioABAlternative $original */
     $original = $this->get_original();
     if ($original->get_id() < 0) {
         $body = array('name' => $original->get_name(), 'value' => $original->get_value(), 'kind' => $this->get_textual_type());
         try {
             /** @var int $result */
             $result = NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/exp/global/%s/alternative', $exp_id), $body);
             $original->set_id($result);
         } catch (Exception $e) {
         }
     } else {
         $body = array('value' => $original->get_value());
         try {
             NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/update', $original->get_id()), $body);
         } catch (Exception $e) {
         }
     }
     // 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());
         try {
             NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/update', $alt->get_id()), $body);
         } catch (Exception $e) {
         }
     }
     // 2.2. REMOVE FROM APPSPOT THE REMOVED ALTERNATIVES
     $controller->begin();
     foreach ($this->get_appspot_alternatives() as $alt) {
         /** @var NelioABAlternative $alt */
         if (!$alt->was_removed()) {
             continue;
         }
         $url = sprintf(NELIOAB_BACKEND_URL . '/alternative/%s/delete', $alt->get_id());
         try {
             NelioABBackend::remote_post($url);
             $controller->remove_alternative_menu($alt->get_value());
         } catch (Exception $e) {
         }
     }
     $controller->commit();
     // 2.3. CREATE LOCAL ALTERNATIVES IN APPSPOT
     $this->new_ids = array();
     $controller->begin();
     foreach ($this->get_local_alternatives() as $alt) {
         /** @var NelioABAlternative $alt */
         if ($alt->was_removed()) {
             continue;
         }
         if ($alt->is_based_on_another_element()) {
             $menu_id = $controller->duplicate_menu_and_create_alternative($alt->get_base_element(), $this->get_id());
         } else {
             $menu_id = $controller->create_alternative_menu($this->get_id());
         }
         $alt->set_value($menu_id);
         $body = array('name' => $alt->get_name(), 'value' => $alt->get_value(), 'kind' => $this->get_textual_type());
         try {
             /** @var object|array $result */
             $result = NelioABBackend::remote_post(sprintf(NELIOAB_BACKEND_URL . '/exp/global/%s/alternative', $exp_id), $body);
             $result = json_decode($result['body']);
             $this->new_ids[$alt->get_id()] = $result->key->id;
             $alt->set_id($result->key->id);
             $controller->link_menu_to_experiment($menu_id, $this->get_id(), $alt->get_id());
         } catch (Exception $e) {
         }
     }
     $controller->commit();
     require_once NELIOAB_MODELS_DIR . '/experiments-manager.php';
     NelioABExperimentsManager::update_experiment($this);
 }