/**
  * Does the traditional work of setting up the plugin's database and adding default data.
  * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
  * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
  * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
  * so that it will be done when migrations are finished
  *
  * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
  * @param boolean $verify_schema if true will re-check the database tables have the correct schema.
  *                               This is a resource-intensive job
  * so we prefer to only do it when necessary
  * @return void
  */
 public function initialize_db_if_no_migrations_required($initialize_addons_too = FALSE, $verify_schema = true)
 {
     $request_type = $this->detect_req_type();
     //only initialize system if we're not in maintenance mode.
     if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
         update_option('ee_flush_rewrite_rules', TRUE);
         if ($verify_schema) {
             EEH_Activation::initialize_db_and_folders();
         }
         EEH_Activation::initialize_db_content();
         EEH_Activation::system_initialization();
         if ($initialize_addons_too) {
             $this->initialize_addons();
         }
     } else {
         EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
     }
     if ($request_type == EE_System::req_type_new_activation || $request_type == EE_System::req_type_reactivation || $request_type == EE_System::req_type_upgrade) {
         add_action('AHEE__EE_System__load_CPTs_and_session__start', array($this, 'redirect_to_about_ee'), 9);
     }
 }
 /**
  * Does the traditional work of setting up the plugin's database and adding default data.
  * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
  * NOTE: does nothing if we're in maintenance mode (which would be the case if we detect there are data
  * migration scripts that need to be run)
  * @return void
  */
 public function initialize_db_if_no_migrations_required()
 {
     $request_type = $this->detect_req_type();
     //only initialize system if we're not in maintenance mode.
     if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
         // set flag for flushing rewrite rules
         update_option('ee_flush_rewrite_rules', TRUE);
         EEH_Activation::system_initialization();
         EEH_Activation::initialize_db_and_folders();
         EEH_Activation::initialize_db_content();
         //foreach registered addon, make sure its db is up-to-date too
         foreach (EE_Registry::instance()->addons as $addon) {
             $addon->initialize_db_if_no_migrations_required();
         }
     }
     if ($request_type == EE_System::req_type_new_activation || $request_type == EE_System::req_type_reactivation || $request_type == EE_System::req_type_upgrade) {
         add_action('AHEE__EE_System__load_CPTs_and_session__start', array($this, 'redirect_to_about_ee'), 9);
     }
 }
 /**
  * Takes care of double-checking that we're not in maintenance mode, and then
  * initializing this addon's necessary initial data. This is called by default on new activations
  * and reactivations
  * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
  * This is a resource-intensive job so we prefer to only do it when necessary
  * @return void
  */
 public function initialize_db_if_no_migrations_required($verify_schema = true)
 {
     if ($verify_schema === '') {
         //wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
         //(ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
         //calls them with an argument of an empty string (ie ""), which evaluates to false
         //so we need to treat the empty string as if nothing had been passed, and should instead use the default
         $verify_schema = true;
     }
     if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
         if ($verify_schema) {
             $this->initialize_db();
         }
         $this->initialize_default_data();
         //@todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
         EE_Data_Migration_Manager::instance()->update_current_database_state_to(array('slug' => $this->name(), 'version' => $this->version()));
         /* make sure core's data is a-ok
          * (at the time of writing, we especially want to verify all the caps are present
          * because payment method type capabilities are added dynamically, and it's
          * possible this addon added a payment method. But it's also possible
          * other data needs to be verified)
          */
         EEH_Activation::initialize_db_content();
         update_option('ee_flush_rewrite_rules', TRUE);
         //in case there are lots of addons being activated at once, let's force garbage collection
         //to help avoid memory limit errors
         //EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
         gc_collect_cycles();
     } else {
         //ask the data migration manager to init this addon's data
         //when migrations are finished because we can't do it now
         EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
     }
 }
 /**
  * Runs the data migration scripts (well, each request to this method calls one of the
  * data migration scripts' migration_step() functions).
  * @return array, where the first item is one EE_Data_Migration_Script_Base's stati, and the second
  * item is a string describing what was done
  */
 public function migration_step()
 {
     try {
         $currently_executing_script = $this->get_last_ran_script();
         if (!$currently_executing_script) {
             //Find the next script that needs to execute
             $scripts = $this->check_for_applicable_data_migration_scripts();
             if (!$scripts) {
                 //huh, no more scripts to run... apparently we're done!
                 //but dont forget to make sure intial data is there
                 EE_Registry::instance()->load_helper('Activation');
                 //we should be good to allow them to exit maintenance mode now
                 EE_Maintenance_Mode::instance()->set_maintenance_level(intval(EE_Maintenance_Mode::level_0_not_in_maintenance));
                 EEH_Activation::system_initialization();
                 EEH_Activation::create_upload_directories();
                 EEH_Activation::initialize_db_content();
                 //make sure the datetime and ticket total sold are correct
                 $this->_save_migrations_ran();
                 return array('records_to_migrate' => 1, 'records_migrated' => 1, 'status' => self::status_no_more_migration_scripts, 'script' => __("Data Migration Completed Successfully", "event_espresso"), 'message' => __("All done!", "event_espresso"));
             }
             $currently_executing_script = array_shift($scripts);
             //and add to the array/wp option showing the scripts ran
             //				$this->_data_migrations_ran[$this->script_migrates_to_version(get_class($currently_executing_script))] = $currently_executing_script;
             $migrates_to = $this->script_migrates_to_version(get_class($currently_executing_script));
             $plugin_slug = $migrates_to['slug'];
             $version = $migrates_to['version'];
             $this->_data_migrations_ran[$plugin_slug][$version] = $currently_executing_script;
         }
         $current_script_name = get_class($currently_executing_script);
     } catch (Exception $e) {
         //an exception occurred while trying to get migration scripts
         $message = sprintf(__("Error Message: %s<br>Stack Trace:%s", "event_espresso"), $e->getMessage(), $e->getTraceAsString());
         //record it on the array of data mgiration scripts ran. This will be overwritten next time we try and try to run data migrations
         //but thats ok-- it's just an FYI to support that we coudln't even run any data migrations
         $this->add_error_to_migrations_ran(sprintf(__("Could not run data migrations because: %s", "event_espresso"), $message));
         return array('records_to_migrate' => 1, 'records_migrated' => 0, 'status' => self::status_fatal_error, 'script' => __("Error loading data migration scripts", "event_espresso"), 'message' => $message);
     }
     //ok so we definitely have a data migration script
     try {
         //how big of a bite do we want to take? Allow users to easily override via their wp-config
         $step_size = defined('EE_MIGRATION_STEP_SIZE') ? EE_MIGRATION_STEP_SIZE : EE_Data_Migration_Manager::step_size;
         //do what we came to do!
         $currently_executing_script->migration_step($step_size);
         switch ($currently_executing_script->get_status()) {
             case EE_Data_Migration_Manager::status_continue:
                 $response_array = array('records_to_migrate' => $currently_executing_script->count_records_to_migrate(), 'records_migrated' => $currently_executing_script->count_records_migrated(), 'status' => EE_Data_Migration_Manager::status_continue, 'message' => $currently_executing_script->get_feedback_message(), 'script' => $currently_executing_script->pretty_name());
                 break;
             case EE_Data_Migration_Manager::status_completed:
                 //ok so THAT script has completed
                 $this->update_current_database_state_to($this->script_migrates_to_version($current_script_name));
                 $response_array = array('records_to_migrate' => $currently_executing_script->count_records_to_migrate(), 'records_migrated' => $currently_executing_script->count_records_migrated(), 'status' => EE_Data_Migration_Manager::status_completed, 'message' => $currently_executing_script->get_feedback_message(), 'script' => sprintf(__("%s Completed", 'event_espresso'), $currently_executing_script->pretty_name()));
                 //check if there are any more after this one.
                 $scripts_remaining = $this->check_for_applicable_data_migration_scripts();
                 if (!$scripts_remaining) {
                     //we should be good to allow them to exit maintenance mode now
                     EE_Maintenance_Mode::instance()->set_maintenance_level(intval(EE_Maintenance_Mode::level_0_not_in_maintenance));
                     ////huh, no more scripts to run... apparently we're done!
                     //but dont forget to make sure intial data is there
                     EE_Registry::instance()->load_helper('Activation');
                     EEH_Activation::system_initialization();
                     EEH_Activation::create_upload_directories();
                     EEH_Activation::initialize_db_content();
                     $response_array['status'] = self::status_no_more_migration_scripts;
                 }
                 break;
             default:
                 $response_array = array('records_to_migrate' => $currently_executing_script->count_records_to_migrate(), 'records_migrated' => $currently_executing_script->count_records_migrated(), 'status' => $currently_executing_script->get_status(), 'message' => sprintf(__("Minor errors occurred during %s: %s", "event_espresso"), $currently_executing_script->pretty_name(), implode(", ", $currently_executing_script->get_errors())), 'script' => $currently_executing_script->pretty_name());
                 break;
         }
     } catch (Exception $e) {
         //ok so some exception was thrown which killed the data migration script
         //double-check we have a real script
         if ($currently_executing_script instanceof EE_Data_Migration_Script_Base) {
             $script_name = $currently_executing_script->pretty_name();
             $currently_executing_script->set_borked();
             $currently_executing_script->add_error($e->getMessage());
         } else {
             $script_name = __("Error getting Migration Script", "event_espresso");
         }
         $response_array = array('records_to_migrate' => 1, 'records_migrated' => 0, 'status' => self::status_fatal_error, 'message' => sprintf(__("A fatal error occurred during the migration: %s", "event_espresso"), $e->getMessage()), 'script' => $script_name);
     }
     $succesful_save = $this->_save_migrations_ran();
     if ($succesful_save !== TRUE) {
         //ok so the current wp option didn't save. that's tricky, because we'd like to update it
         //and mark it as having a fatal error, but remember- WE CAN'T SAVE THIS WP OPTION!
         //however, if we throw an exception, and return that, then the next request
         //won't have as much info in it, and it may be able to save
         throw new EE_Error(sprintf(__("The error '%s' occurred updating the status of the migration. This is a FATAL ERROR, but the error is preventing the system from remembering that. Please contact event espresso support.", "event_espresso"), $succesful_save));
     }
     return $response_array;
 }