/**
  * 	Additional admin hooks.
  *
  *  @access public
  *  @return void
  */
 public static function additional_payflow_pro_admin_hooks()
 {
     // Is admin and not in M-Mode ?
     if (is_admin() && !EE_Maintenance_Mode::instance()->level()) {
         add_filter('plugin_action_links', array('EE_Payflow_Pro_Gateway', 'plugin_actions'), 10, 2);
     }
 }
 /**
  * 	additional_admin_hooks
  *
  *  @access 	public
  *  @return 	void
  */
 public function additional_admin_hooks()
 {
     // is admin and not in M-Mode ?
     if (is_admin() && !EE_Maintenance_Mode::instance()->level()) {
         add_filter('plugin_action_links', array($this, 'plugin_actions'), 10, 2);
     }
 }
 /**
  * 	additional_admin_hooks
  *
  *  @access 	public
  *  @return 	void
  */
 public function additional_admin_hooks()
 {
     // is admin and not in M-Mode ?
     if (is_admin() && !EE_Maintenance_Mode::instance()->level()) {
         add_filter('plugin_action_links', array($this, 'plugin_actions'), 10, 2);
         add_action('action_hook_espresso_featured_image_add_to_meta_box', array($this, 'add_to_featured_image_meta_box'));
     }
 }
 protected function _whats_new()
 {
     $steps = EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance ? $this->_get_started_steps() : FALSE;
     $steps = $steps !== FALSE ? $steps : '';
     $this->_admin_page_title = sprintf(__('Welcome to Event Espresso %s', 'event_espresso'), EVENT_ESPRESSO_VERSION);
     $settings_message = $steps;
     $this->_template_args['admin_page_subtitle'] = __('Thank you for choosing Event Espresso, the most powerful Event Management plugin for WordPress.', 'event_espresso') . $settings_message;
     $template = is_readable(EE_ABOUT_CAF_TEMPLATE_PATH . 'whats_new.template.php') ? EE_ABOUT_CAF_TEMPLATE_PATH . 'whats_new.template.php' : EE_ABOUT_TEMPLATE_PATH . 'whats_new.template.php';
     $this->_template_args['about_admin_page_content'] = EEH_Template::display_template($template, $this->_template_args, TRUE);
     $this->display_about_admin_page();
 }
 /**
  * tests that EE_Maintenance_Mode::level() correctly pretend a site is
  * NOT in maintenance mode for admin users only on frontend and ajax requests
  * @global type $current_user
  */
 public function test_maintenance_level()
 {
     global $current_user;
     $this->assertFalse(is_admin());
     $this->assertFalse(current_user_can('administrator'));
     EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_1_frontend_only_maintenance);
     $this->assertEquals(EE_Maintenance_Mode::level_1_frontend_only_maintenance, EE_Maintenance_Mode::instance()->level());
     //now make the current user an admin, and maintenance mode shoudl be detected as 0
     $current_user = $this->factory->user->create_and_get(array('role' => 'administrator'));
     $this->assertEquals(EE_Maintenance_Mode::level_0_not_in_maintenance, EE_Maintenance_Mode::instance()->level());
 }
    /**
     * Checks if we're in maintenance mode, and if so we notify the admin adn tell them how to take the site OUT of maintenance mode
     */
    public function check_maintenance_mode()
    {
        if (EE_Maintenance_Mode::instance()->level()) {
            $maintenance_page_url = EE_Admin_Page::add_query_args_and_nonce(array(), EE_MAINTENANCE_ADMIN_URL);
            switch (EE_Maintenance_Mode::instance()->level()) {
                case EE_Maintenance_Mode::level_1_frontend_only_maintenance:
                    echo '<div class="updated">
						<p>' . sprintf(__("Event Espresso is in Frontend-Only MAINTENANCE MODE. This means the front-end (ie, non-wp-admin pages) is disabled for ALL users except site admins. Visit the %s Maintenance Page %s to disable maintenance mode.", "event_espresso"), "<a href='{$maintenance_page_url}'>", "</a>") . '</div>';
                    break;
                case EE_Maintenance_Mode::level_2_complete_maintenance:
                    echo '<div class="error">
						<p>' . sprintf(__("As part of the process for updating Event Espresso, your database also\nneeds to be updated. Event Espresso is in COMPLETE MAINTENANCE MODE (both WordPress admin pages and front-end event registration pages are disabled) until you run the database update script. %s Visit the Maintenance Page to get started,%s it only takes a moment.", "event_espresso"), "<a href='{$maintenance_page_url}'>", "</a>") . '</div>';
                    break;
            }
        }
    }
    /**
     * Checks that there is at least one active gateway. If not, add a notice
     */
    public function check_payment_gateway_setup()
    {
        //ONLY do this check if models can query
        //and avoid a bug where when we nuke EE4's data that this causes a fatal error
        //because the tables are deleted just before this request runs. see https://events.codebasehq.com/projects/event-espresso/tickets/7539
        if (!EE_Maintenance_Mode::instance()->models_can_query() || !EEH_Activation::table_exists(EEM_Payment_Method::instance()->table())) {
            return;
        }
        // ensure Payment_Method model is loaded
        EE_Registry::instance()->load_model('Payment_Method');
        $actives = EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart);
        if ($actives < 1) {
            $url = EE_Admin_Page::add_query_args_and_nonce(array(), EE_PAYMENTS_ADMIN_URL);
            echo '<div class="error">
				 <p>' . sprintf(__("There are no Active Payment Methods setup for Event Espresso. Please %s activate at least one.%s", "event_espresso"), "<a href='{$url}'>", "</a>") . '</p>
			 </div>';
        }
    }
 /**
  * Overrides parent to dynamically set some defaults, but only when the form is requested
  * @return EE_Form_Section_Proper
  */
 public function generate_new_settings_form()
 {
     if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
         $organization = EE_Registry::instance()->CFG->organization;
         $organization_name = $organization->get_pretty('name');
         $default_address = $organization->address_1 != '' ? $organization->get_pretty('address_1') . '<br />' : '';
         $default_address .= $organization->address_2 != '' ? $organization->get_pretty('address_2') . '<br />' : '';
         $default_address .= $organization->city != '' ? $organization->get_pretty('city') : '';
         $default_address .= $organization->city != '' && $organization->STA_ID != '' ? ', ' : '<br />';
         $state = EE_Registry::instance()->load_model('State')->get_one_by_ID($organization->STA_ID);
         $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($organization->CNT_ISO);
         $default_address .= $state ? $state->name() . '<br />' : '';
         $default_address .= $country ? $country->name() . '<br />' : '';
         $default_address .= $organization->zip != '' ? $organization->get_pretty('zip') : '';
     } else {
         $default_address = 'unknown';
         $organization_name = 'unknown';
     }
     return new EE_Payment_Method_Form(array('extra_meta_inputs' => array('check_title' => new EE_Text_Input(array('html_label_text' => sprintf(__("Title %s", "event_espresso"), $this->get_help_tab_link()), 'default' => __("Check/Money Order Payments", 'event_espresso'))), 'payment_instructions' => new EE_Text_Area_Input(array('html_label_text' => sprintf(__("Instructions %s", "event_espresso"), $this->get_help_tab_link()), 'default' => __("Please send Check/Money Order to the address below. Payment must be received within 48 hours of event date.", 'event_espresso'), 'validation_strategies' => array(new EE_Full_HTML_Validation_Strategy()))), 'payable_to' => new EE_Text_Input(array('html_label_text' => sprintf(__("Payable To %s", "event_espresso"), $this->get_help_tab_link()), 'default' => $organization_name)), 'address_to_send_payment' => new EE_Text_Area_Input(array('html_label_text' => sprintf(__("Address Payable %s", "event_espresso"), $this->get_help_tab_link()), 'default' => $default_address, 'validation_strategies' => array(new EE_Full_HTML_Validation_Strategy())))), 'exclude' => array('PMD_debug_mode')));
 }
 /**
  *    fallback_shortcode_processor - create instance and call process_shortcode
  *    NOTE: shortcode may not function perfectly dues to missing assets, but it's better than not having things work at all
  *
  * @access 	public
  * @param 	$attributes
  * @return 	mixed
  */
 public static final function fallback_shortcode_processor($attributes)
 {
     if (EE_Maintenance_Mode::disable_frontend_for_maintenance()) {
         return null;
     }
     // what shortcode was actually parsed ?
     $shortcode_class = get_called_class();
     // notify rest of system that fallback processor was triggered
     add_filter('FHEE__fallback_shortcode_processor__' . $shortcode_class, '__return_true');
     // get instance of actual shortcode
     $shortcode_obj = self::instance($shortcode_class);
     // verify class
     if ($shortcode_obj instanceof EES_Shortcode) {
         global $wp;
         $shortcode_obj->run($wp);
         // set attributes and run the shortcode
         $shortcode_obj->_attributes = (array) $attributes;
         return $shortcode_obj->process_shortcode($shortcode_obj->_attributes);
     } else {
         return NULL;
     }
 }
 /**
  * Returns whether or not this migration script is being used as part of an actual migration
  * @return boolean
  */
 protected function _currently_migrating()
 {
     //we want to know if we are currently performing a migration. We could just believe what was set on the _migrating property, but let's double-check (ie the script should apply and we should be in MM)
     return $this->_migrating && $this->can_migrate_from_version(EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set()) && EE_Maintenance_Mode::instance()->real_level() == EE_Maintenance_Mode::level_2_complete_maintenance;
 }
 /**
  * Calculates all the EE routes and saves it to a wordpress option so we don't
  * need to calculate it on every request
  * @return void
  */
 public static function save_ee_routes()
 {
     if (EE_Maintenance_Mode::instance()->models_can_query()) {
         $instance = self::instance();
         $routes = apply_filters('EED_Core_Rest_Api__save_ee_routes__routes', array_replace_recursive($instance->_register_config_routes(), $instance->_register_meta_routes(), $instance->_register_model_routes(), $instance->_register_rpc_routes()));
         update_option(self::saved_routes_option_names, $routes, true);
     }
 }
 /**
  *	pre_get_posts
  *
  * If this query (not just "main" queries (ie, for WP's infamous "loop")) is for an EE CPT, then we want to supercharge the get_posts query
  * to add our EE stuff (like joining to our tables, selecting extra columns, and adding
  * EE objects to the post to facilitate further querying of related data etc)
  *
  * @access public
  * @param WP_Query $WP_Query
  * @return void
  */
 public function pre_get_posts($WP_Query)
 {
     // check that post-type is set
     if (!$WP_Query instanceof WP_Query) {
         return;
     }
     // add our conditionals
     $this->_set_EE_tags_on_WP_Query($WP_Query);
     // check for terms
     $this->_set_post_type_for_terms($WP_Query);
     // make sure paging is always set
     $this->_set_paging($WP_Query);
     // is a taxonomy set ?
     if ($WP_Query->is_tax) {
         // loop thru our taxonomies
         foreach ($this->_CPT_taxonomies as $CPT_taxonomy => $CPT_taxonomy_details) {
             // check if one of our taxonomies is set as a query var
             if (isset($WP_Query->query[$CPT_taxonomy])) {
                 // but which CPT does that correspond to??? hmmm... guess we gotta go looping
                 foreach ($this->_CPTs as $post_type => $CPT) {
                     // verify our CPT has args, is public and has taxonomies set
                     if (isset($CPT['args']) && $CPT['args']['public'] && !empty($CPT['args']['taxonomies'])) {
                         // does the captured taxonomy belong to this CPT ?
                         if (in_array($CPT_taxonomy, $CPT['args']['taxonomies'])) {
                             // if so, then add this CPT post_type to the current query's array of post_types'
                             $WP_Query->query_vars['post_type'] = isset($WP_Query->query_vars['post_type']) ? (array) $WP_Query->query_vars['post_type'] : array();
                             $WP_Query->query_vars['post_type'][] = $post_type;
                             switch ($post_type) {
                                 case 'espresso_events':
                                     $WP_Query->is_espresso_event_taxonomy = TRUE;
                                     break;
                                 case 'espresso_venues':
                                     $WP_Query->is_espresso_venue_taxonomy = TRUE;
                                     break;
                             }
                         }
                     }
                 }
             }
         }
     }
     //		d( $this->_CPTs );
     //		d( $CPT_taxonomy );
     //		d( $WP_Query );
     if (isset($WP_Query->query_vars['post_type'])) {
         // loop thru post_types as array
         foreach ((array) $WP_Query->query_vars['post_type'] as $post_type) {
             // is current query for an EE CPT ?
             if (isset($this->_CPTs[$post_type])) {
                 // is EE on or off ?
                 if (EE_Maintenance_Mode::instance()->level()) {
                     // reroute CPT template view to maintenance_mode.template.php
                     if (!has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) {
                         add_filter('template_include', array('EE_Maintenance_Mode', 'template_include'), 99999);
                     }
                     if (has_filter('the_content', array(EE_Maintenance_Mode::instance(), 'the_content'))) {
                         add_filter('the_content', array($this, 'inject_EE_shortcode_placeholder'), 1);
                     }
                     return;
                 }
                 // load EE_Request_Handler (this was added as a result of https://events.codebasehq.com/projects/event-espresso/tickets/9037
                 EE_Registry::instance()->load_core('Request_Handler');
                 // grab details for the CPT the current query is for
                 $this->CPT = $this->_CPTs[$post_type];
                 // set post type
                 $this->CPT['post_type'] = $post_type;
                 // set taxonomies
                 $this->_set_CPT_taxonomies();
                 // the post or category or term that is triggering EE
                 $this->CPT['espresso_page'] = EE_Registry::instance()->REQ->is_espresso_page();
                 // requested post name
                 $this->CPT['post_name'] = EE_Registry::instance()->REQ->get('post_name');
                 //d( $this->CPT );
                 // add support for viewing 'private', 'draft', or 'pending' posts
                 if (is_user_logged_in() && isset($WP_Query->query_vars['p']) && $WP_Query->query_vars['p'] != 0 && current_user_can('edit_post', $WP_Query->query_vars['p'])) {
                     // we can just inject directly into the WP_Query object
                     $WP_Query->query['post_status'] = array('publish', 'private', 'draft', 'pending');
                     // now set the main 'ee' request var so that the appropriate module can load the appropriate template(s)
                     EE_Registry::instance()->REQ->set('ee', $this->CPT['singular_slug']);
                 }
                 $this->_possibly_set_ee_request_var();
                 // convert post_type to model name
                 $model_name = str_replace('EE_', '', $this->CPT['class_name']);
                 // get CPT table data via CPT Model
                 $this->CPT_model = EE_Registry::instance()->load_model($model_name);
                 $this->CPT['tables'] = $this->CPT_model->get_tables();
                 // is there a Meta Table for this CPT?
                 $this->CPT['meta_table'] = isset($this->CPT['tables'][$model_name . '_Meta']) ? $this->CPT['tables'][$model_name . '_Meta'] : FALSE;
                 // creates classname like:  CPT_Event_Strategy
                 $CPT_Strategy_class_name = 'CPT_' . $model_name . '_Strategy';
                 // load and instantiate
                 $CPT_Strategy = EE_Registry::instance()->load_core($CPT_Strategy_class_name, array('WP_Query' => $WP_Query, 'CPT' => $this->CPT));
                 // !!!!!!!!!!  IMPORTANT !!!!!!!!!!!!
                 // here's the list of available filters in the WP_Query object
                 // 'posts_where_paged'
                 // 'posts_groupby'
                 // 'posts_join_paged'
                 // 'posts_orderby'
                 // 'posts_distinct'
                 // 'post_limits'
                 // 'posts_fields'
                 // 'posts_join'
                 add_filter('posts_fields', array($this, 'posts_fields'));
                 add_filter('posts_join', array($this, 'posts_join'));
                 add_filter('get_' . $this->CPT['post_type'] . '_metadata', array($CPT_Strategy, 'get_EE_post_type_metadata'), 1, 4);
                 add_filter('the_posts', array($this, 'the_posts'), 1, 1);
                 add_filter('get_edit_post_link', array($this, 'get_edit_post_link'), 10, 2);
                 $this->_do_template_filters($WP_Query);
             }
         }
     }
 }
 /**
  * This sets the meta caps property.
  * @since 4.5.0
  *
  * @return void
  */
 private function _set_meta_caps()
 {
     //make sure we're only ever initializing the default _meta_caps array once if it's empty.
     $this->_meta_caps = $this->_get_default_meta_caps_array();
     $this->_meta_caps = apply_filters('FHEE__EE_Capabilities___set_meta_caps__meta_caps', $this->_meta_caps);
     //add filter for map_meta_caps but only if models can query.
     if (EE_Maintenance_Mode::instance()->models_can_query() && !has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
         add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
     }
 }
 /**
  * Adds EE metadata to the index
  * @param \WP_REST_Response $rest_response_obj
  * @return \WP_REST_Response
  */
 public static function filter_ee_metadata_into_index(\WP_REST_Response $rest_response_obj)
 {
     $response_data = $rest_response_obj->get_data();
     $addons = array();
     foreach (\EE_Registry::instance()->addons as $addon) {
         $addon_json = array('name' => $addon->name(), 'version' => $addon->version());
         $addons[$addon_json['name']] = $addon_json;
     }
     $response_data['ee'] = array('version' => \EEM_System_Status::instance()->get_ee_version(), 'addons' => $addons, 'maintenance_mode' => \EE_Maintenance_Mode::instance()->real_level(), 'served_core_versions' => array_keys(\EED_Core_Rest_Api::versions_served()));
     $rest_response_obj->set_data($response_data);
     return $rest_response_obj;
 }
 /**
  * tests that we're detecting request types correctly on normal requests (ie, NOT an activation request)
  * A new install would only occur on a non-activation request because the site was previously in maintenance mode
  *
  */
 function test_detect_req_type_given_activation_history__on_normal_requests()
 {
     $activation_history = array();
     //detect brand new activation BUT we're in maintenance mode, so it will be basically ignored
     EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
     $this->assertEquals(EE_System::req_type_new_activation, EE_System::detect_req_type_given_activation_history($activation_history, '', '1.0.0.dev.000'));
     EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
     //detect brand new activation
     $this->assertEquals(EE_System::req_type_new_activation, EE_System::detect_req_type_given_activation_history($activation_history, '', '1.0.0.dev.000'));
     $activation_history['1.0.0.dev.000'] = array(date('Y-m-d H:i:s'));
     //detect upgrade to NEW version
     $this->assertEquals(EE_System::req_type_upgrade, EE_System::detect_req_type_given_activation_history($activation_history, '', '1.2.0.dev.000'));
     $activation_history['1.2.0.dev.000'] = array(date('Y-m-d H:i:s', time() + 1));
     //detect normal request
     $this->assertEquals(EE_System::req_type_normal, EE_System::detect_req_type_given_activation_history($activation_history, '', '1.2.0.dev.000'));
     //detect downgrade to NEW version
     $this->assertEquals(EE_System::req_type_downgrade, EE_System::detect_req_type_given_activation_history($activation_history, '', '1.1.0.dev.000'));
     $activation_history['1.1.0.dev.000'] = array(date('Y-m-d H:i:s', time() + 2));
     //detect downgrade to KNOWN version
     $this->assertEquals(EE_System::req_type_downgrade, EE_System::detect_req_type_given_activation_history($activation_history, '', '1.0.0.dev.000'));
     $activation_history['1.0.0.dev.000'][] = date('Y-m-d H:i:s', time() + 3);
     //detect upgrade to KNOWN version
     $this->assertEquals(EE_System::req_type_upgrade, EE_System::detect_req_type_given_activation_history($activation_history, '', '1.1.0.dev.000'));
     $activation_history['1.1.0.dev.000'][] = date('Y-m-d H:i:s', time() + 4);
 }
 /**
  * Checks that even though the addon was upgraded, because it happened during
  * maintenance mode, we couldn't do any of its setup logic. (SO it should be run
  * later, when the site is taken out of MM by the migration manager)
  * @group 6910
  */
 public function test_detect_actiavtions_or_upgrade__upgrade_during_maintenance_mode()
 {
     global $wp_actions;
     //pretend an older version of this addon was activated a while ago
     $addon_activation_history = array('0.9.0.dev.000' => array(date('Y-m-d H:i:s', current_time('timestamp') - DAY_IN_SECONDS * 10)));
     update_option($this->_addon->get_activation_history_option_name(), $addon_activation_history);
     //and it also shouldn't be in the current db state
     $current_db_state = get_option(EE_Data_Migration_Manager::current_database_state);
     //just for assurance, make sure New Addon is the only existing addon
     unset($current_db_state[$this->_addon_name]);
     update_option(EE_Data_Migration_Manager::current_database_state, $current_db_state);
     $times_reactivation_hook_fired_before = isset($wp_actions["AHEE__{$this->_addon_classname}__upgrade"]) ? $wp_actions["AHEE__{$this->_addon_classname}__upgrade"] : 0;
     //lastly, and imporatntly SET MAINTENANCE MODE LEVEL 2
     $this->_add_mock_dms();
     //now check for activations/upgrades in addons
     EE_System::reset();
     $this->assertEquals(EE_Maintenance_Mode::level_2_complete_maintenance, EE_Maintenance_Mode::instance()->level());
     $this->assertEquals(EE_System::req_type_upgrade, $this->_addon->detect_req_type());
     $this->assertEquals($times_reactivation_hook_fired_before + 1, isset($wp_actions["AHEE__{$this->_addon_classname}__upgrade"]) ? $wp_actions["AHEE__{$this->_addon_classname}__upgrade"] : 0);
     $this->assertArrayContains('New_Addon', EE_Data_Migration_Manager::instance()->get_db_initialization_queue());
     $addon_activation_history = $this->_addon->get_activation_history();
     $this->assertArrayHasKey('0.9.0.dev.000', $addon_activation_history);
     $this->assertArrayHasKey('1.0.0.dev.000', $addon_activation_history);
     $this->assertTableDoesNotExist('esp_new_addon_thing');
     //ok, now let's pretend the site was teaken out of MM because migrations were finished
     $this->_remove_mock_dms();
     EE_Maintenance_Mode::reset()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
     EE_Data_Migration_Manager::instance()->initialize_db_for_enqueued_ee_plugins();
     //now we also want to check that the addon will have created the necessary table
     //that it needed upon new activation
     $this->assertEquals(array(), EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts());
     $this->assertEquals(EE_Maintenance_Mode::level_0_not_in_maintenance, EE_Maintenance_Mode::instance()->real_level());
     $this->assertTableExists('esp_new_addon_thing');
     //check for activations/upgrades again. It should be a normal request
     EE_System::reset();
     $this->assertEquals(EE_System::req_type_normal, $this->_addon->detect_req_type());
     $this->assertEquals($times_reactivation_hook_fired_before + 1, $wp_actions["AHEE__{$this->_addon_classname}__upgrade"]);
     $this->assertWPOptionDoesNotExist($this->_addon->get_activation_indicator_option_name());
 }
Example #17
0
 /**
  * EE Core detected that this addon has been upgraded. We should check if there
  * are any new migration scripts, and if so put the site into maintenance mode until
  * they're ran
  * @return mixed
  */
 public function upgrade()
 {
     $classname = get_class($this);
     do_action("AHEE__{$classname}__upgrade");
     EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
 }
 /**
  * Constructor.
  *
  * @since 4.4.0
  *
  * @param  array $menu_args  An array of arguments used to setup the menu
  *                           		properties on construct.
  * @param  array $required   	An array of keys that should be in the $menu_args, this
  *                            		is used to validate that the items that should be defined
  *                            		are present.
  * @return void
  */
 public function __construct($menu_args, $required)
 {
     //verify that required keys are present in the incoming array.
     $missing = array_diff((array) $required, array_keys((array) $menu_args));
     if (!empty($missing)) {
         throw new EE_Error(sprintf(__('%s is missing some expected keys in the argument array.  The following keys are missing: %s', 'event_espresso'), get_class($this), implode(', ', $missing)));
     }
     //made it here okay, so let's set the properties!
     foreach ($menu_args as $prop => $value) {
         switch ($prop) {
             case 'show_on_menu':
                 $value = (bool) $value;
                 break;
             case 'admin_init_page':
                 if (in_array('admin_init_page', $required) && !$value instanceof EE_Admin_Page_Init) {
                     throw new EE_Error(sprintf(__('The value for the "admin_init_page" argument must be an instance of an EE_Admin_Page_Init object.  Instead %s was given as the value.', 'event_espresso'), print_r($value, TRUE)));
                 }
                 break;
             case 'menu_callback':
                 break;
             default:
                 $value = (string) $value;
                 break;
         }
         if (!EEH_Class_Tools::has_property($this, $prop)) {
             throw new EE_Error(sprintf(__('The $menu_args coming into %s has a index key (%s) representing a property that is not defined by the class.  Perhaps there is a typo?', 'event_espresso'), get_class($this), $prop));
         }
         $this->{$prop} = $value;
     }
     //filter capabilities (both static and dynamic)
     $this->capability = apply_filters('FHEE_management_capability', $this->capability, NULL);
     $this->capability = apply_filters('FHEE_' . $this->menu_slug . '_capability', $this->capability, NULL);
     //Might need to change parent slug depending on maintenance mode.
     if (!empty($this->maintenance_mode_parent) && EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance) {
         $this->parent_slug = $this->maintenance_mode_parent;
     }
     //if empty menu_callback let's set default (but only if we have admin page init object)
     if (empty($this->menu_callback) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
         $this->menu_callback = array($this->admin_init_page, 'initialize_admin_page');
     }
 }
 public static function clean_out_junk_transactions()
 {
     if (EE_Maintenance_Mode::instance()->models_can_query()) {
         EEM_Transaction::instance('')->delete_junk_transactions();
         EEM_Registration::instance('')->delete_registrations_with_no_transaction();
         EEM_Line_Item::instance('')->delete_line_items_with_no_transaction();
     }
 }
 /**
  *    class constructor
  *
  * @access    public
  * @param string $CNT_ISO
  * @return \EE_Currency_Config
  */
 public function __construct($CNT_ISO = '')
 {
     // get country code from organization settings or use default
     $ORG_CNT = isset(EE_Registry::instance()->CFG->organization) && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config ? EE_Registry::instance()->CFG->organization->CNT_ISO : '';
     // but override if requested
     $CNT_ISO = !empty($CNT_ISO) ? $CNT_ISO : $ORG_CNT;
     // so if that all went well, and we are not in M-Mode (cuz you can't query the db in M-Mode) and double-check the countries table exists
     if (!empty($CNT_ISO) && EE_Maintenance_Mode::instance()->models_can_query() && EEH_Activation::table_exists(EE_Registry::instance()->load_model('Country')->table())) {
         // retrieve the country settings from the db, just in case they have been customized
         $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
         if ($country instanceof EE_Country) {
             $this->code = $country->currency_code();
             // currency code: USD, CAD, EUR
             $this->name = $country->currency_name_single();
             // Dollar
             $this->plural = $country->currency_name_plural();
             // Dollars
             $this->sign = $country->currency_sign();
             // currency sign: $
             $this->sign_b4 = $country->currency_sign_before();
             // currency sign before or after: $TRUE  or  FALSE$
             $this->dec_plc = $country->currency_decimal_places();
             // decimal places: 2 = 0.00  3 = 0.000
             $this->dec_mrk = $country->currency_decimal_mark();
             // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
             $this->thsnds = $country->currency_thousands_separator();
             // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
         }
     }
     // fallback to hardcoded defaults, in case the above failed
     if (empty($this->code)) {
         // set default currency settings
         $this->code = 'USD';
         // currency code: USD, CAD, EUR
         $this->name = __('Dollar', 'event_espresso');
         // Dollar
         $this->plural = __('Dollars', 'event_espresso');
         // Dollars
         $this->sign = '$';
         // currency sign: $
         $this->sign_b4 = true;
         // currency sign before or after: $TRUE  or  FALSE$
         $this->dec_plc = 2;
         // decimal places: 2 = 0.00  3 = 0.000
         $this->dec_mrk = '.';
         // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
         $this->thsnds = ',';
         // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
     }
 }
 /**
  *    disable_frontend_for_maintenance
  *
  *   returns TRUE if M-Mode is engaged and the current request is not for the admin
  *
  * @access    public
  * @return    string
  */
 public static function disable_frontend_for_maintenance()
 {
     return !is_admin() && EE_Maintenance_Mode::instance()->level() ? TRUE : FALSE;
 }
 /**
  * init- should fire after shortcode, module,  addon, other plugin (default priority), and even EE_Front_Controller's init phases have run
  *
  * @access public
  * @return void
  */
 public function init()
 {
     //only enable most of the EE_Admin IF we're not in full maintenance mode
     if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
         //ok so we want to enable the entire admin
         add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismiss_ee_nag_notice_callback'));
         add_action('save_post', array('EE_Admin', 'parse_post_content_on_save'), 100, 2);
         add_action('update_option', array($this, 'reset_page_for_posts_on_change'), 100, 3);
         add_filter('content_save_pre', array($this, 'its_eSpresso'), 10, 1);
         add_action('admin_notices', array($this, 'get_persistent_admin_notices'), 9);
         add_action('network_admin_notices', array($this, 'get_persistent_admin_notices'), 9);
         //at a glance dashboard widget
         add_filter('dashboard_glance_items', array($this, 'dashboard_glance_items'), 10);
         //filter for get_edit_post_link used on comments for custom post types
         add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
     }
     // run the admin page factory but ONLY if we are doing an ee admin ajax request
     if (!defined('DOING_AJAX') || EE_ADMIN_AJAX) {
         try {
             //this loads the controller for the admin pages which will setup routing etc
             EE_Registry::instance()->load_core('Admin_Page_Loader');
         } catch (EE_Error $e) {
             $e->get_error();
         }
     }
     //make sure our CPTs and custom taxonomy metaboxes get shown for first time users
     add_action('admin_head', array($this, 'enable_hidden_ee_nav_menu_metaboxes'), 10);
     add_action('admin_head', array($this, 'register_custom_nav_menu_boxes'), 10);
     //exclude EE critical pages from all nav menus and wp_list_pages
     add_filter('nav_menu_meta_box_object', array($this, 'remove_pages_from_nav_menu'), 10);
 }
 /**
  * sets up EE4 to rerun the migrations from ee3 to ee4
  */
 public function _rerun_migration_from_ee3()
 {
     EE_Registry::instance()->load_helper('Activation');
     EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
     EEH_Activation::delete_all_espresso_cpt_data();
     EEH_Activation::delete_all_espresso_tables_and_data(false);
     //set the db state to something that will require migrations
     update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
     EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
     $this->_redirect_after_action(true, __("Database", 'event_espresso'), __("reset", 'event_espresso'));
 }
					<th align="left">
						<label for="maintenance_mode_level_off"><?php 
    _e('Maintenance Mode OFF', 'event_espresso');
    ?>
</label>
				   		<p class='description' style="font-weight: normal;">
					   		<?php 
    _e("This is the normal operating mode for Event Espresso and allows all functionality to be viewed by all site visitors.", "event_espresso");
    ?>
				   		</p>
					</th>
				</tr>
				<tr>
					<td width="40px" align="center">
						<input type="radio" id="maintenance_mode_level_on" name="maintenance_mode_level" value="1" <?php 
    echo EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_1_frontend_only_maintenance ? 'checked="checked"' : '';
    ?>
>
					</td>
					<th align="left">
						<label for="maintenance_mode_level_on">
							<?php 
    _e('Maintenance Mode ON', 'event_espresso');
    ?>
						</label>
				   		<p class='description' style="font-weight: normal;">
					   		<?php 
    _e("This disables Event Espresso frontend functionality for all site visitors that are not administrators, and allows you to configure and/or test things on the frontend of your website before others can see.", "event_espresso");
    ?>
				   		</p>
					</th>
?>
		<?php 
$ver = explode('.', EVENT_ESPRESSO_VERSION);
array_pop($ver);
$ver = implode('.', $ver);
?>
		<?php 
printf(__('For more information, see <a href="%s">the release notes</a>.'), 'http://eventespresso.com/wiki/ee4-changelog/#' . $ver);
?>
 	</p>
</div>

<div class="changelog">
	<?php 
//maintenance mode on?
if (EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance) {
    ?>
		<div class="ee-attention">
			<h2 class="ee-maintenance-mode-callout"><?php 
    _e('Event Espresso is in full maintenance mode.', 'event_espresso');
    ?>
</h2>
			<p>
			<?php 
    printf(__('A previous version of Event Espresso has detected. But before anything else can happen, we need to know whether or not to migrate (copy over) your existing event data so that it can be utilized by EE4. For more instructions on what to do, please visit the %sEvent Espresso Maintenance%s page.', 'event_espresso'), '<a href="admin.php?page=espresso_maintenance_settings">', '</a>');
    ?>
			</p>
		</div>
		<?php 
}
?>
 /**
  * Runs the data migration scripts (well, each request to this method calls one of the
  * data migration scripts' migration_step() functions).
  *
  * @param int $step_size
  * @throws EE_Error
  * @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
  *    	@type int $records_to_migrate from the current migration script
  *    	@type int $records_migrated
  * 		@type string $status one of EE_Data_Migration_Manager::status_*
  * 		@type string $script verbose name of the current DMS
  * 		@type string $message string describing what was done during this step
  * }
  */
 public function migration_step($step_size = 0)
 {
     //bandaid fix for issue https://events.codebasehq.com/projects/event-espresso/tickets/7535
     if (class_exists('EE_CPT_Strategy')) {
         remove_action('pre_get_posts', array(EE_CPT_Strategy::instance(), 'pre_get_posts'), 5);
     }
     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 initial data is there
                 //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));
                 //saving migrations ran should actually be unnecessary, but leaving in place just in case
                 //remember this migration was finished (even if we timeout initing db for core and plugins)
                 $this->_save_migrations_ran();
                 //make sure DB was updated AFTER we've recorded the migration was done
                 $this->initialize_db_for_enqueued_ee_plugins();
                 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: %sStack Trace:%s", "event_espresso"), $e->getMessage() . '<br>', $e->getTraceAsString());
         //record it on the array of data migration scripts ran. This will be overwritten next time we try and try to run data migrations
         //but that's ok-- it's just an FYI to support that we couldn'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
         if (!absint($step_size) > 0) {
             $step_size = defined('EE_MIGRATION_STEP_SIZE') && absint(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);
         //can we wrap it up and verify default data?
         $init_dbs = false;
         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 initial data is there
                     $init_dbs = true;
                     $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_broken();
             $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);
     }
     $successful_save = $this->_save_migrations_ran();
     if ($successful_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"), $successful_save));
     }
     //if we're all done, initialize EE plugins' default data etc.
     if ($init_dbs) {
         $this->initialize_db_for_enqueued_ee_plugins();
     }
     return $response_array;
 }
 /**
  * Just calls the specified method on $wpdb with the given arguments
  * Consolidates a little extra error handling code
  * @param string $wpdb_method
  * @param array  $arguments_to_provide
  * @throws EE_Error
  * @global wpdb $wpdb
  * @return mixed
  */
 protected function _do_wpdb_query($wpdb_method, $arguments_to_provide)
 {
     //if we're in maintenance mode level 2, DON'T run any queries
     //because level 2 indicates the database needs updating and
     //is probably out of sync with the code
     if (!EE_Maintenance_Mode::instance()->models_can_query()) {
         throw new EE_Error(sprintf(__("Event Espresso Level 2 Maintenance mode is active. That means EE can not run ANY database queries until the necessary migration scripts have run which will take EE out of maintenance mode level 2. Please inform support of this error.", "event_espresso")));
     }
     /** @type WPDB $wpdb */
     global $wpdb;
     if (!method_exists($wpdb, $wpdb_method)) {
         throw new EE_Error(sprintf(__('There is no method named "%s" on Wordpress\' $wpdb object', 'event_espresso'), $wpdb_method));
     }
     if (WP_DEBUG) {
         $old_show_errors_value = $wpdb->show_errors;
         $wpdb->show_errors(FALSE);
     }
     $result = $this->_process_wpdb_query($wpdb_method, $arguments_to_provide);
     $this->show_db_query_if_previously_requested($wpdb->last_query);
     if (WP_DEBUG) {
         $wpdb->show_errors($old_show_errors_value);
         if (!empty($wpdb->last_error)) {
             throw new EE_Error(sprintf(__('WPDB Error: "%s"', 'event_espresso'), $wpdb->last_error));
         } elseif ($result === false) {
             throw new EE_Error(sprintf(__('WPDB Error occurred, but no error message was logged by wpdb! The wpdb method called was "%1$s" and the arguments were "%2$s"', 'event_espresso'), $wpdb_method, var_export($arguments_to_provide, true)));
         }
     } elseif ($result === false) {
         EE_Error::add_error(sprintf(__('A database error has occurred. Turn on WP_DEBUG for more information.', 'event_espresso')), __FILE__, __FUNCTION__, __LINE__);
     }
     return $result;
 }
 /**
  * _prep_pages
  * sets the _prepped_menu_maps property
  *
  * @access private
  * @throws EE_Error
  * @return void
  */
 private function _prep_pages()
 {
     $pages_array = array();
     //rearrange _admin_menu_groups to be indexed by group slug.
     $menu_groups = $this->_rearrange_menu_groups();
     foreach ($this->_installed_pages as $page) {
         if ($page instanceof EE_Admin_page_Init) {
             $page_map = $page->get_menu_map();
             //if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
             if (is_array($page_map) || empty($page_map)) {
                 EE_Error::add_persistent_admin_notice('menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION, sprintf(__('The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.', 'event_espresso'), $page->label));
                 continue;
             }
             //if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
             if (!$page_map instanceof EE_Admin_Page_Menu_Map) {
                 throw new EE_Error(sprintf(__('The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.', 'event_espresso'), $page->label, $page_map));
             }
             //use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
             if (empty($page_map->maintenance_mode_parent) && EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance) {
                 continue;
             }
             //assign to group (remember $page_map has the admin page stored in it).
             $pages_array[$page_map->menu_group][] = $page_map;
         }
     }
     if (empty($pages_array)) {
         throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
     }
     //let's sort the groups, make sure it's a valid group, add header (if to show).
     foreach ($pages_array as $group => $menu_maps) {
         //valid_group?
         if (!array_key_exists($group, $menu_groups)) {
             continue;
         }
         //sort pages.
         usort($menu_maps, array($this, '_sort_menu_maps'));
         //prepend header
         array_unshift($menu_maps, $menu_groups[$group]);
         //reset $pages_array with prepped data
         $pages_array[$group] = $menu_maps;
     }
     //now let's setup the _prepped_menu_maps property
     foreach ($menu_groups as $group => $group_objs) {
         if (isset($pages_array[$group])) {
             $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
         }
     }
     /**/
 }
 /**
  *    espresso_toolbar_items
  *
  * @access public
  * @param  WP_Admin_Bar $admin_bar
  * @return void
  */
 public function espresso_toolbar_items(WP_Admin_Bar $admin_bar)
 {
     // if in full M-Mode, or its an AJAX request, or user is NOT an admin
     if (EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance || defined('DOING_AJAX') || !$this->registry->CAP->current_user_can('ee_read_ee', 'ee_admin_bar_menu_top_level')) {
         return;
     }
     do_action('AHEE_log', __FILE__, __FUNCTION__, '');
     $menu_class = 'espresso_menu_item_class';
     //we don't use the constants EVENTS_ADMIN_URL or REG_ADMIN_URL
     //because they're only defined in each of their respective constructors
     //and this might be a frontend request, in which case they aren't available
     $events_admin_url = admin_url("admin.php?page=espresso_events");
     $reg_admin_url = admin_url("admin.php?page=espresso_registrations");
     $extensions_admin_url = admin_url("admin.php?page=espresso_packages");
     //Top Level
     $admin_bar->add_menu(array('id' => 'espresso-toolbar', 'title' => '<span class="ee-icon ee-icon-ee-cup-thick ee-icon-size-20"></span><span class="ab-label">' . _x('Event Espresso', 'admin bar menu group label', 'event_espresso') . '</span>', 'href' => $events_admin_url, 'meta' => array('title' => __('Event Espresso', 'event_espresso'), 'class' => $menu_class . 'first')));
     //Events
     if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-events', 'parent' => 'espresso-toolbar', 'title' => __('Events', 'event_espresso'), 'href' => $events_admin_url, 'meta' => array('title' => __('Events', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     if ($this->registry->CAP->current_user_can('ee_edit_events', 'ee_admin_bar_menu_espresso-toolbar-events-new')) {
         //Events Add New
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-events-new', 'parent' => 'espresso-toolbar-events', 'title' => __('Add New', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'create_new'), $events_admin_url), 'meta' => array('title' => __('Add New', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     if (is_single() && get_post_type() == 'espresso_events') {
         //Current post
         global $post;
         if ($this->registry->CAP->current_user_can('ee_edit_event', 'ee_admin_bar_menu_espresso-toolbar-events-edit', $post->ID)) {
             //Events Edit Current Event
             $admin_bar->add_menu(array('id' => 'espresso-toolbar-events-edit', 'parent' => 'espresso-toolbar-events', 'title' => __('Edit Event', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'edit', 'post' => $post->ID), $events_admin_url), 'meta' => array('title' => __('Edit Event', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
         }
     }
     //Events View
     if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-view')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-events-view', 'parent' => 'espresso-toolbar-events', 'title' => __('View', 'event_espresso'), 'href' => $events_admin_url, 'meta' => array('title' => __('View', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-all')) {
         //Events View All
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-events-all', 'parent' => 'espresso-toolbar-events-view', 'title' => __('All', 'event_espresso'), 'href' => $events_admin_url, 'meta' => array('title' => __('All', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-today')) {
         //Events View Today
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-events-today', 'parent' => 'espresso-toolbar-events-view', 'title' => __('Today', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'), $events_admin_url), 'meta' => array('title' => __('Today', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-month')) {
         //Events View This Month
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-events-month', 'parent' => 'espresso-toolbar-events-view', 'title' => __('This Month', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'), $events_admin_url), 'meta' => array('title' => __('This Month', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations', 'parent' => 'espresso-toolbar', 'title' => __('Registrations', 'event_espresso'), 'href' => $reg_admin_url, 'meta' => array('title' => __('Registrations', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview Today
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-today')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-today', 'parent' => 'espresso-toolbar-registrations', 'title' => __('Today', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'), $reg_admin_url), 'meta' => array('title' => __('Today', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview Today Completed
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-today-approved')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-today-approved', 'parent' => 'espresso-toolbar-registrations-today', 'title' => __('Approved', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today', '_reg_status' => EEM_Registration::status_id_approved), $reg_admin_url), 'meta' => array('title' => __('Approved', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview Today Pending\
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-today-pending')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-today-pending', 'parent' => 'espresso-toolbar-registrations-today', 'title' => __('Pending', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today', 'reg_status' => EEM_Registration::status_id_pending_payment), $reg_admin_url), 'meta' => array('title' => __('Pending Payment', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview Today Incomplete
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-today-not-approved')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-today-not-approved', 'parent' => 'espresso-toolbar-registrations-today', 'title' => __('Not Approved', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today', '_reg_status' => EEM_Registration::status_id_not_approved), $reg_admin_url), 'meta' => array('title' => __('Not Approved', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview Today Incomplete
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-today-cancelled')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-today-cancelled', 'parent' => 'espresso-toolbar-registrations-today', 'title' => __('Cancelled', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today', '_reg_status' => EEM_Registration::status_id_cancelled), $reg_admin_url), 'meta' => array('title' => __('Cancelled', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview This Month
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-month')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-month', 'parent' => 'espresso-toolbar-registrations', 'title' => __('This Month', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'), $reg_admin_url), 'meta' => array('title' => __('This Month', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview This Month Approved
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-month-approved')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-month-approved', 'parent' => 'espresso-toolbar-registrations-month', 'title' => __('Approved', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month', '_reg_status' => EEM_Registration::status_id_approved), $reg_admin_url), 'meta' => array('title' => __('Approved', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview This Month Pending
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-month-pending')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-month-pending', 'parent' => 'espresso-toolbar-registrations-month', 'title' => __('Pending', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month', '_reg_status' => EEM_Registration::status_id_pending_payment), $reg_admin_url), 'meta' => array('title' => __('Pending', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview This Month Not Approved
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-month-not-approved')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-month-not-approved', 'parent' => 'espresso-toolbar-registrations-month', 'title' => __('Not Approved', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month', '_reg_status' => EEM_Registration::status_id_not_approved), $reg_admin_url), 'meta' => array('title' => __('Not Approved', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Registration Overview This Month Cancelled
     if ($this->registry->CAP->current_user_can('ee_read_registrations', 'ee_admin_bar_menu_espresso-toolbar-registrations-month-cancelled')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-registrations-month-cancelled', 'parent' => 'espresso-toolbar-registrations-month', 'title' => __('Cancelled', 'event_espresso'), 'href' => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month', '_reg_status' => EEM_Registration::status_id_cancelled), $reg_admin_url), 'meta' => array('title' => __('Cancelled', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
     //Extensions & Services
     if ($this->registry->CAP->current_user_can('ee_read_ee', 'ee_admin_bar_menu_espresso-toolbar-extensions-and-services')) {
         $admin_bar->add_menu(array('id' => 'espresso-toolbar-extensions-and-services', 'parent' => 'espresso-toolbar', 'title' => __('Extensions & Services', 'event_espresso'), 'href' => $extensions_admin_url, 'meta' => array('title' => __('Extensions & Services', 'event_espresso'), 'target' => '', 'class' => $menu_class)));
     }
 }
 /**
 * sets hooks used in the admin
 *
 *@return string
 */
 public function admin_init()
 {
     // is admin and not in M-Mode ?
     if (is_admin() && !EE_Maintenance_Mode::instance()->level()) {
         add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
         add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
     }
 }