@@ -43,7 +43,7 @@ discard block |
||
| 43 | 43 | public static function instance() |
| 44 | 44 | { |
| 45 | 45 | // check if class object is instantiated |
| 46 | - if (! self::$_instance instanceof EE_Admin) { |
|
| 46 | + if ( ! self::$_instance instanceof EE_Admin) { |
|
| 47 | 47 | self::$_instance = new self(); |
| 48 | 48 | } |
| 49 | 49 | return self::$_instance; |
@@ -104,11 +104,11 @@ discard block |
||
| 104 | 104 | */ |
| 105 | 105 | private function _define_all_constants() |
| 106 | 106 | { |
| 107 | - if (! defined('EE_ADMIN_URL')) { |
|
| 108 | - define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/'); |
|
| 109 | - define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/'); |
|
| 110 | - define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS); |
|
| 111 | - define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/'); |
|
| 107 | + if ( ! defined('EE_ADMIN_URL')) { |
|
| 108 | + define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL.'core/admin/'); |
|
| 109 | + define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL.'admin_pages/'); |
|
| 110 | + define('EE_ADMIN_TEMPLATE', EE_ADMIN.'templates'.DS); |
|
| 111 | + define('WP_ADMIN_PATH', ABSPATH.'wp-admin/'); |
|
| 112 | 112 | define('WP_AJAX_URL', admin_url('admin-ajax.php')); |
| 113 | 113 | } |
| 114 | 114 | } |
@@ -126,7 +126,7 @@ discard block |
||
| 126 | 126 | // set $main_file in stone |
| 127 | 127 | static $main_file; |
| 128 | 128 | // if $main_file is not set yet |
| 129 | - if (! $main_file) { |
|
| 129 | + if ( ! $main_file) { |
|
| 130 | 130 | $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE); |
| 131 | 131 | } |
| 132 | 132 | if ($plugin === $main_file) { |
@@ -177,9 +177,9 @@ discard block |
||
| 177 | 177 | public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array()) |
| 178 | 178 | { |
| 179 | 179 | return array( |
| 180 | - 'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS, |
|
| 181 | - 'about' => EE_ADMIN_PAGES . 'about' . DS, |
|
| 182 | - 'support' => EE_ADMIN_PAGES . 'support' . DS, |
|
| 180 | + 'maintenance' => EE_ADMIN_PAGES.'maintenance'.DS, |
|
| 181 | + 'about' => EE_ADMIN_PAGES.'about'.DS, |
|
| 182 | + 'support' => EE_ADMIN_PAGES.'support'.DS, |
|
| 183 | 183 | ); |
| 184 | 184 | } |
| 185 | 185 | |
@@ -203,7 +203,7 @@ discard block |
||
| 203 | 203 | $this->initModelsReady(); |
| 204 | 204 | } |
| 205 | 205 | // run the admin page factory but ONLY if we are doing an ee admin ajax request |
| 206 | - if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
| 206 | + if ( ! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
| 207 | 207 | try { |
| 208 | 208 | // this loads the controller for the admin pages which will setup routing etc |
| 209 | 209 | EE_Registry::instance()->load_core('Admin_Page_Loader'); |
@@ -229,7 +229,7 @@ discard block |
||
| 229 | 229 | */ |
| 230 | 230 | protected function getLoader() |
| 231 | 231 | { |
| 232 | - if (! $this->loader instanceof LoaderInterface) { |
|
| 232 | + if ( ! $this->loader instanceof LoaderInterface) { |
|
| 233 | 233 | $this->loader = LoaderFactory::getLoader(); |
| 234 | 234 | } |
| 235 | 235 | return $this->loader; |
@@ -296,13 +296,13 @@ discard block |
||
| 296 | 296 | '</strong>', |
| 297 | 297 | '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">', |
| 298 | 298 | '</a>', |
| 299 | - '<a href="' . EE_Admin_Page::add_query_args_and_nonce( |
|
| 299 | + '<a href="'.EE_Admin_Page::add_query_args_and_nonce( |
|
| 300 | 300 | array( |
| 301 | 301 | 'page' => 'espresso_maintenance_settings', |
| 302 | 302 | 'action' => 'datetime_tools', |
| 303 | 303 | ), |
| 304 | 304 | admin_url('admin.php') |
| 305 | - ) . '">' |
|
| 305 | + ).'">' |
|
| 306 | 306 | ), |
| 307 | 307 | false, |
| 308 | 308 | 'manage_options', |
@@ -348,7 +348,7 @@ discard block |
||
| 348 | 348 | public function enable_hidden_ee_nav_menu_metaboxes() |
| 349 | 349 | { |
| 350 | 350 | global $wp_meta_boxes, $pagenow; |
| 351 | - if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
| 351 | + if ( ! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
| 352 | 352 | return; |
| 353 | 353 | } |
| 354 | 354 | $user = wp_get_current_user(); |
@@ -377,7 +377,7 @@ discard block |
||
| 377 | 377 | if (is_array($hidden_meta_boxes)) { |
| 378 | 378 | foreach ($hidden_meta_boxes as $key => $meta_box_id) { |
| 379 | 379 | if (in_array($meta_box_id, $initial_meta_boxes, true)) { |
| 380 | - unset($hidden_meta_boxes[ $key ]); |
|
| 380 | + unset($hidden_meta_boxes[$key]); |
|
| 381 | 381 | } |
| 382 | 382 | } |
| 383 | 383 | } |
@@ -417,7 +417,7 @@ discard block |
||
| 417 | 417 | */ |
| 418 | 418 | public function modify_edit_post_link($link, $id) |
| 419 | 419 | { |
| 420 | - if (! $post = get_post($id)) { |
|
| 420 | + if ( ! $post = get_post($id)) { |
|
| 421 | 421 | return $link; |
| 422 | 422 | } |
| 423 | 423 | if ($post->post_type === 'espresso_attendees') { |
@@ -564,7 +564,7 @@ discard block |
||
| 564 | 564 | ); |
| 565 | 565 | |
| 566 | 566 | foreach ($keys as $key => $value) { |
| 567 | - $menu_item->{$key} = isset($menu_item_values[ $key ]) ? $menu_item_values[ $key ] : $value; |
|
| 567 | + $menu_item->{$key} = isset($menu_item_values[$key]) ? $menu_item_values[$key] : $value; |
|
| 568 | 568 | } |
| 569 | 569 | return $menu_item; |
| 570 | 570 | } |
@@ -662,10 +662,10 @@ discard block |
||
| 662 | 662 | |
| 663 | 663 | // loop through to remove any critical pages from the array. |
| 664 | 664 | foreach ($critical_pages as $page_id) { |
| 665 | - $needle = 'value="' . $page_id . '"'; |
|
| 665 | + $needle = 'value="'.$page_id.'"'; |
|
| 666 | 666 | foreach ($split_output as $key => $haystack) { |
| 667 | 667 | if (strpos($haystack, $needle) !== false) { |
| 668 | - unset($split_output[ $key ]); |
|
| 668 | + unset($split_output[$key]); |
|
| 669 | 669 | } |
| 670 | 670 | } |
| 671 | 671 | } |
@@ -686,7 +686,7 @@ discard block |
||
| 686 | 686 | // calls. |
| 687 | 687 | wp_enqueue_script( |
| 688 | 688 | 'ee-inject-wp', |
| 689 | - EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
| 689 | + EE_ADMIN_URL.'assets/ee-cpt-wp-injects.js', |
|
| 690 | 690 | array('jquery'), |
| 691 | 691 | EVENT_ESPRESSO_VERSION, |
| 692 | 692 | true |
@@ -694,7 +694,7 @@ discard block |
||
| 694 | 694 | // register cookie script for future dependencies |
| 695 | 695 | wp_register_script( |
| 696 | 696 | 'jquery-cookie', |
| 697 | - EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
| 697 | + EE_THIRD_PARTY_URL.'joyride/jquery.cookie.js', |
|
| 698 | 698 | array('jquery'), |
| 699 | 699 | '2.1', |
| 700 | 700 | true |
@@ -703,16 +703,16 @@ discard block |
||
| 703 | 703 | // via: add_filter('FHEE_load_joyride', '__return_true' ); |
| 704 | 704 | if (apply_filters('FHEE_load_joyride', false)) { |
| 705 | 705 | // joyride style |
| 706 | - wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1'); |
|
| 706 | + wp_register_style('joyride-css', EE_THIRD_PARTY_URL.'joyride/joyride-2.1.css', array(), '2.1'); |
|
| 707 | 707 | wp_register_style( |
| 708 | 708 | 'ee-joyride-css', |
| 709 | - EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
| 709 | + EE_GLOBAL_ASSETS_URL.'css/ee-joyride-styles.css', |
|
| 710 | 710 | array('joyride-css'), |
| 711 | 711 | EVENT_ESPRESSO_VERSION |
| 712 | 712 | ); |
| 713 | 713 | wp_register_script( |
| 714 | 714 | 'joyride-modernizr', |
| 715 | - EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
| 715 | + EE_THIRD_PARTY_URL.'joyride/modernizr.mq.js', |
|
| 716 | 716 | array(), |
| 717 | 717 | '2.1', |
| 718 | 718 | true |
@@ -720,7 +720,7 @@ discard block |
||
| 720 | 720 | // joyride JS |
| 721 | 721 | wp_register_script( |
| 722 | 722 | 'jquery-joyride', |
| 723 | - EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
| 723 | + EE_THIRD_PARTY_URL.'joyride/jquery.joyride-2.1.js', |
|
| 724 | 724 | array('jquery-cookie', 'joyride-modernizr'), |
| 725 | 725 | '2.1', |
| 726 | 726 | true |
@@ -782,7 +782,7 @@ discard block |
||
| 782 | 782 | |
| 783 | 783 | foreach ($items as $type => $item_properties) { |
| 784 | 784 | $elements[] = sprintf( |
| 785 | - '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>', |
|
| 785 | + '<a class="ee-dashboard-link-'.$type.'" href="%s" title="%s">%s</a>', |
|
| 786 | 786 | $item_properties['url'], |
| 787 | 787 | $item_properties['title'], |
| 788 | 788 | $item_properties['text'] |
@@ -807,10 +807,10 @@ discard block |
||
| 807 | 807 | // check for date_format or time_format |
| 808 | 808 | switch ($option) { |
| 809 | 809 | case 'date_format': |
| 810 | - $date_time_format = $value . ' ' . get_option('time_format'); |
|
| 810 | + $date_time_format = $value.' '.get_option('time_format'); |
|
| 811 | 811 | break; |
| 812 | 812 | case 'time_format': |
| 813 | - $date_time_format = get_option('date_format') . ' ' . $value; |
|
| 813 | + $date_time_format = get_option('date_format').' '.$value; |
|
| 814 | 814 | break; |
| 815 | 815 | default: |
| 816 | 816 | $date_time_format = false; |
@@ -833,7 +833,7 @@ discard block |
||
| 833 | 833 | |
| 834 | 834 | |
| 835 | 835 | foreach ($error_msg as $error) { |
| 836 | - $msg .= '<li>' . $error . '</li>'; |
|
| 836 | + $msg .= '<li>'.$error.'</li>'; |
|
| 837 | 837 | } |
| 838 | 838 | |
| 839 | 839 | $msg .= '</ul></p><p>' |
@@ -1024,7 +1024,7 @@ discard block |
||
| 1024 | 1024 | public function displayStateForCriticalPages($post_states, $post) |
| 1025 | 1025 | { |
| 1026 | 1026 | $post_states = (array) $post_states; |
| 1027 | - if (! $post instanceof WP_Post || $post->post_type !== 'page') { |
|
| 1027 | + if ( ! $post instanceof WP_Post || $post->post_type !== 'page') { |
|
| 1028 | 1028 | return $post_states; |
| 1029 | 1029 | } |
| 1030 | 1030 | /** @var EE_Core_Config $config */ |
@@ -20,488 +20,488 @@ discard block |
||
| 20 | 20 | final class EE_Admin implements InterminableInterface |
| 21 | 21 | { |
| 22 | 22 | |
| 23 | - /** |
|
| 24 | - * @var EE_Admin $_instance |
|
| 25 | - */ |
|
| 26 | - private static $_instance; |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * @var PersistentAdminNoticeManager $persistent_admin_notice_manager |
|
| 30 | - */ |
|
| 31 | - private $persistent_admin_notice_manager; |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * @var LoaderInterface |
|
| 35 | - */ |
|
| 36 | - protected $loader; |
|
| 37 | - |
|
| 38 | - /** |
|
| 39 | - * @singleton method used to instantiate class object |
|
| 40 | - * @return EE_Admin |
|
| 41 | - * @throws EE_Error |
|
| 42 | - */ |
|
| 43 | - public static function instance() |
|
| 44 | - { |
|
| 45 | - // check if class object is instantiated |
|
| 46 | - if (! self::$_instance instanceof EE_Admin) { |
|
| 47 | - self::$_instance = new self(); |
|
| 48 | - } |
|
| 49 | - return self::$_instance; |
|
| 50 | - } |
|
| 51 | - |
|
| 52 | - |
|
| 53 | - /** |
|
| 54 | - * @return EE_Admin |
|
| 55 | - * @throws EE_Error |
|
| 56 | - */ |
|
| 57 | - public static function reset() |
|
| 58 | - { |
|
| 59 | - self::$_instance = null; |
|
| 60 | - return self::instance(); |
|
| 61 | - } |
|
| 62 | - |
|
| 63 | - |
|
| 64 | - /** |
|
| 65 | - * class constructor |
|
| 66 | - * |
|
| 67 | - * @throws EE_Error |
|
| 68 | - * @throws InvalidDataTypeException |
|
| 69 | - * @throws InvalidInterfaceException |
|
| 70 | - * @throws InvalidArgumentException |
|
| 71 | - */ |
|
| 72 | - protected function __construct() |
|
| 73 | - { |
|
| 74 | - // define global EE_Admin constants |
|
| 75 | - $this->_define_all_constants(); |
|
| 76 | - // set autoloaders for our admin page classes based on included path information |
|
| 77 | - EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_ADMIN); |
|
| 78 | - // admin hooks |
|
| 79 | - add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2); |
|
| 80 | - // load EE_Request_Handler early |
|
| 81 | - add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'get_request')); |
|
| 82 | - add_action('AHEE__EE_System__initialize_last', array($this, 'init')); |
|
| 83 | - add_action('AHEE__EE_Admin_Page__route_admin_request', array($this, 'route_admin_request'), 100, 2); |
|
| 84 | - add_action('wp_loaded', array($this, 'wp_loaded'), 100); |
|
| 85 | - add_action('admin_init', array($this, 'admin_init'), 100); |
|
| 86 | - add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'), 20); |
|
| 87 | - add_action('admin_notices', array($this, 'display_admin_notices'), 10); |
|
| 88 | - add_action('network_admin_notices', array($this, 'display_admin_notices'), 10); |
|
| 89 | - add_filter('pre_update_option', array($this, 'check_for_invalid_datetime_formats'), 100, 2); |
|
| 90 | - add_filter('admin_footer_text', array($this, 'espresso_admin_footer')); |
|
| 91 | - add_action('load-plugins.php', array($this, 'hookIntoWpPluginsPage')); |
|
| 92 | - add_action('display_post_states', array($this, 'displayStateForCriticalPages'), 10, 2); |
|
| 93 | - add_filter('plugin_row_meta', array($this, 'addLinksToPluginRowMeta'), 10, 2); |
|
| 94 | - // reset Environment config (we only do this on admin page loads); |
|
| 95 | - EE_Registry::instance()->CFG->environment->recheck_values(); |
|
| 96 | - do_action('AHEE__EE_Admin__loaded'); |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - |
|
| 100 | - /** |
|
| 101 | - * _define_all_constants |
|
| 102 | - * define constants that are set globally for all admin pages |
|
| 103 | - * |
|
| 104 | - * @return void |
|
| 105 | - */ |
|
| 106 | - private function _define_all_constants() |
|
| 107 | - { |
|
| 108 | - if (! defined('EE_ADMIN_URL')) { |
|
| 109 | - define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/'); |
|
| 110 | - define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/'); |
|
| 111 | - define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS); |
|
| 112 | - define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/'); |
|
| 113 | - define('WP_AJAX_URL', admin_url('admin-ajax.php')); |
|
| 114 | - } |
|
| 115 | - } |
|
| 116 | - |
|
| 117 | - |
|
| 118 | - /** |
|
| 119 | - * filter_plugin_actions - adds links to the Plugins page listing |
|
| 120 | - * |
|
| 121 | - * @param array $links |
|
| 122 | - * @param string $plugin |
|
| 123 | - * @return array |
|
| 124 | - */ |
|
| 125 | - public function filter_plugin_actions($links, $plugin) |
|
| 126 | - { |
|
| 127 | - // set $main_file in stone |
|
| 128 | - static $main_file; |
|
| 129 | - // if $main_file is not set yet |
|
| 130 | - if (! $main_file) { |
|
| 131 | - $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE); |
|
| 132 | - } |
|
| 133 | - if ($plugin === $main_file) { |
|
| 134 | - // compare current plugin to this one |
|
| 135 | - if (EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
| 136 | - $maintenance_link = '<a href="admin.php?page=espresso_maintenance_settings"' |
|
| 137 | - . ' title="Event Espresso is in maintenance mode. Click this link to learn why.">' |
|
| 138 | - . esc_html__('Maintenance Mode Active', 'event_espresso') |
|
| 139 | - . '</a>'; |
|
| 140 | - array_unshift($links, $maintenance_link); |
|
| 141 | - } else { |
|
| 142 | - $org_settings_link = '<a href="admin.php?page=espresso_general_settings">' |
|
| 143 | - . esc_html__('Settings', 'event_espresso') |
|
| 144 | - . '</a>'; |
|
| 145 | - $events_link = '<a href="admin.php?page=espresso_events">' |
|
| 146 | - . esc_html__('Events', 'event_espresso') |
|
| 147 | - . '</a>'; |
|
| 148 | - // add before other links |
|
| 149 | - array_unshift($links, $org_settings_link, $events_link); |
|
| 150 | - } |
|
| 151 | - } |
|
| 152 | - return $links; |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - |
|
| 156 | - /** |
|
| 157 | - * _get_request |
|
| 158 | - * |
|
| 159 | - * @return void |
|
| 160 | - * @throws EE_Error |
|
| 161 | - * @throws InvalidArgumentException |
|
| 162 | - * @throws InvalidDataTypeException |
|
| 163 | - * @throws InvalidInterfaceException |
|
| 164 | - * @throws ReflectionException |
|
| 165 | - */ |
|
| 166 | - public function get_request() |
|
| 167 | - { |
|
| 168 | - EE_Registry::instance()->load_core('Request_Handler'); |
|
| 169 | - } |
|
| 170 | - |
|
| 171 | - |
|
| 172 | - /** |
|
| 173 | - * hide_admin_pages_except_maintenance_mode |
|
| 174 | - * |
|
| 175 | - * @param array $admin_page_folder_names |
|
| 176 | - * @return array |
|
| 177 | - */ |
|
| 178 | - public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array()) |
|
| 179 | - { |
|
| 180 | - return array( |
|
| 181 | - 'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS, |
|
| 182 | - 'about' => EE_ADMIN_PAGES . 'about' . DS, |
|
| 183 | - 'support' => EE_ADMIN_PAGES . 'support' . DS, |
|
| 184 | - ); |
|
| 185 | - } |
|
| 186 | - |
|
| 187 | - |
|
| 188 | - /** |
|
| 189 | - * init- should fire after shortcode, module, addon, other plugin (default priority), and even |
|
| 190 | - * EE_Front_Controller's init phases have run |
|
| 191 | - * |
|
| 192 | - * @return void |
|
| 193 | - * @throws EE_Error |
|
| 194 | - * @throws InvalidArgumentException |
|
| 195 | - * @throws InvalidDataTypeException |
|
| 196 | - * @throws InvalidInterfaceException |
|
| 197 | - * @throws ReflectionException |
|
| 198 | - * @throws ServiceNotFoundException |
|
| 199 | - */ |
|
| 200 | - public function init() |
|
| 201 | - { |
|
| 202 | - // only enable most of the EE_Admin IF we're not in full maintenance mode |
|
| 203 | - if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
| 204 | - $this->initModelsReady(); |
|
| 205 | - } |
|
| 206 | - // run the admin page factory but ONLY if we are doing an ee admin ajax request |
|
| 207 | - if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
| 208 | - try { |
|
| 209 | - // this loads the controller for the admin pages which will setup routing etc |
|
| 210 | - EE_Registry::instance()->load_core('Admin_Page_Loader'); |
|
| 211 | - } catch (EE_Error $e) { |
|
| 212 | - $e->get_error(); |
|
| 213 | - } |
|
| 214 | - } |
|
| 215 | - add_filter('content_save_pre', array($this, 'its_eSpresso'), 10, 1); |
|
| 216 | - // make sure our CPTs and custom taxonomy metaboxes get shown for first time users |
|
| 217 | - add_action('admin_head', array($this, 'enable_hidden_ee_nav_menu_metaboxes'), 10); |
|
| 218 | - add_action('admin_head', array($this, 'register_custom_nav_menu_boxes'), 10); |
|
| 219 | - // exclude EE critical pages from all nav menus and wp_list_pages |
|
| 220 | - add_filter('nav_menu_meta_box_object', array($this, 'remove_pages_from_nav_menu'), 10); |
|
| 221 | - } |
|
| 222 | - |
|
| 223 | - |
|
| 224 | - /** |
|
| 225 | - * Gets the loader (and if it wasn't previously set, sets it) |
|
| 226 | - * @return LoaderInterface |
|
| 227 | - * @throws InvalidArgumentException |
|
| 228 | - * @throws InvalidDataTypeException |
|
| 229 | - * @throws InvalidInterfaceException |
|
| 230 | - */ |
|
| 231 | - protected function getLoader() |
|
| 232 | - { |
|
| 233 | - if (! $this->loader instanceof LoaderInterface) { |
|
| 234 | - $this->loader = LoaderFactory::getLoader(); |
|
| 235 | - } |
|
| 236 | - return $this->loader; |
|
| 237 | - } |
|
| 238 | - |
|
| 239 | - |
|
| 240 | - /** |
|
| 241 | - * Method that's fired on admin requests (including admin ajax) but only when the models are usable |
|
| 242 | - * (ie, the site isn't in maintenance mode) |
|
| 243 | - * @since 4.9.63.p |
|
| 244 | - * @return void |
|
| 245 | - */ |
|
| 246 | - protected function initModelsReady() |
|
| 247 | - { |
|
| 248 | - // ok so we want to enable the entire admin |
|
| 249 | - $this->persistent_admin_notice_manager = $this->getLoader()->getShared( |
|
| 250 | - 'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
| 251 | - ); |
|
| 252 | - $this->persistent_admin_notice_manager->setReturnUrl( |
|
| 253 | - EE_Admin_Page::add_query_args_and_nonce( |
|
| 254 | - array( |
|
| 255 | - 'page' => EE_Registry::instance()->REQ->get('page', ''), |
|
| 256 | - 'action' => EE_Registry::instance()->REQ->get('action', ''), |
|
| 257 | - ), |
|
| 258 | - EE_ADMIN_URL |
|
| 259 | - ) |
|
| 260 | - ); |
|
| 261 | - $this->maybeSetDatetimeWarningNotice(); |
|
| 262 | - // at a glance dashboard widget |
|
| 263 | - add_filter('dashboard_glance_items', array($this, 'dashboard_glance_items'), 10); |
|
| 264 | - // filter for get_edit_post_link used on comments for custom post types |
|
| 265 | - add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2); |
|
| 266 | - } |
|
| 267 | - |
|
| 268 | - |
|
| 269 | - /** |
|
| 270 | - * get_persistent_admin_notices |
|
| 271 | - * |
|
| 272 | - * @access public |
|
| 273 | - * @return void |
|
| 274 | - * @throws EE_Error |
|
| 275 | - * @throws InvalidArgumentException |
|
| 276 | - * @throws InvalidDataTypeException |
|
| 277 | - * @throws InvalidInterfaceException |
|
| 278 | - */ |
|
| 279 | - public function maybeSetDatetimeWarningNotice() |
|
| 280 | - { |
|
| 281 | - // add dismissable notice for datetime changes. Only valid if site does not have a timezone_string set. |
|
| 282 | - // @todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version |
|
| 283 | - // with this. But after enough time (indeterminate at this point) we can just remove this notice. |
|
| 284 | - // this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626 |
|
| 285 | - if (apply_filters('FHEE__EE_Admin__maybeSetDatetimeWarningNotice', true) |
|
| 286 | - && ! get_option('timezone_string') |
|
| 287 | - && EEM_Event::instance()->count() > 0 |
|
| 288 | - ) { |
|
| 289 | - new PersistentAdminNotice( |
|
| 290 | - 'datetime_fix_notice', |
|
| 291 | - sprintf( |
|
| 292 | - esc_html__( |
|
| 293 | - '%1$sImportant announcement related to your install of Event Espresso%2$s: There are some changes made to your site that could affect how dates display for your events and other related items with dates and times. Read more about it %3$shere%4$s. If your dates and times are displaying incorrectly (incorrect offset), you can fix it using the tool on %5$sthis page%4$s.', |
|
| 294 | - 'event_espresso' |
|
| 295 | - ), |
|
| 296 | - '<strong>', |
|
| 297 | - '</strong>', |
|
| 298 | - '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">', |
|
| 299 | - '</a>', |
|
| 300 | - '<a href="' . EE_Admin_Page::add_query_args_and_nonce( |
|
| 301 | - array( |
|
| 302 | - 'page' => 'espresso_maintenance_settings', |
|
| 303 | - 'action' => 'datetime_tools', |
|
| 304 | - ), |
|
| 305 | - admin_url('admin.php') |
|
| 306 | - ) . '">' |
|
| 307 | - ), |
|
| 308 | - false, |
|
| 309 | - 'manage_options', |
|
| 310 | - 'datetime_fix_persistent_notice' |
|
| 311 | - ); |
|
| 312 | - } |
|
| 313 | - } |
|
| 314 | - |
|
| 315 | - |
|
| 316 | - /** |
|
| 317 | - * this simply hooks into the nav menu setup of pages metabox and makes sure that we remove EE critical pages from |
|
| 318 | - * the list of options. the wp function "wp_nav_menu_item_post_type_meta_box" found in |
|
| 319 | - * wp-admin/includes/nav-menu.php looks for the "_default_query" property on the post_type object and it uses that |
|
| 320 | - * to override any queries found in the existing query for the given post type. Note that _default_query is not a |
|
| 321 | - * normal property on the post_type object. It's found ONLY in this particular context. |
|
| 322 | - * |
|
| 323 | - * @param WP_Post $post_type WP post type object |
|
| 324 | - * @return WP_Post |
|
| 325 | - * @throws InvalidArgumentException |
|
| 326 | - * @throws InvalidDataTypeException |
|
| 327 | - * @throws InvalidInterfaceException |
|
| 328 | - */ |
|
| 329 | - public function remove_pages_from_nav_menu($post_type) |
|
| 330 | - { |
|
| 331 | - // if this isn't the "pages" post type let's get out |
|
| 332 | - if ($post_type->name !== 'page') { |
|
| 333 | - return $post_type; |
|
| 334 | - } |
|
| 335 | - $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
| 336 | - $post_type->_default_query = array( |
|
| 337 | - 'post__not_in' => $critical_pages, |
|
| 338 | - ); |
|
| 339 | - return $post_type; |
|
| 340 | - } |
|
| 341 | - |
|
| 342 | - |
|
| 343 | - /** |
|
| 344 | - * WP by default only shows three metaboxes in "nav-menus.php" for first times users. We want to make sure our |
|
| 345 | - * metaboxes get shown as well |
|
| 346 | - * |
|
| 347 | - * @return void |
|
| 348 | - */ |
|
| 349 | - public function enable_hidden_ee_nav_menu_metaboxes() |
|
| 350 | - { |
|
| 351 | - global $wp_meta_boxes, $pagenow; |
|
| 352 | - if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
| 353 | - return; |
|
| 354 | - } |
|
| 355 | - $user = wp_get_current_user(); |
|
| 356 | - // has this been done yet? |
|
| 357 | - if (get_user_option('ee_nav_menu_initialized', $user->ID)) { |
|
| 358 | - return; |
|
| 359 | - } |
|
| 360 | - |
|
| 361 | - $hidden_meta_boxes = get_user_option('metaboxhidden_nav-menus', $user->ID); |
|
| 362 | - $initial_meta_boxes = apply_filters( |
|
| 363 | - 'FHEE__EE_Admin__enable_hidden_ee_nav_menu_boxes__initial_meta_boxes', |
|
| 364 | - array( |
|
| 365 | - 'nav-menu-theme-locations', |
|
| 366 | - 'add-page', |
|
| 367 | - 'add-custom-links', |
|
| 368 | - 'add-category', |
|
| 369 | - 'add-espresso_events', |
|
| 370 | - 'add-espresso_venues', |
|
| 371 | - 'add-espresso_event_categories', |
|
| 372 | - 'add-espresso_venue_categories', |
|
| 373 | - 'add-post-type-post', |
|
| 374 | - 'add-post-type-page', |
|
| 375 | - ) |
|
| 376 | - ); |
|
| 377 | - |
|
| 378 | - if (is_array($hidden_meta_boxes)) { |
|
| 379 | - foreach ($hidden_meta_boxes as $key => $meta_box_id) { |
|
| 380 | - if (in_array($meta_box_id, $initial_meta_boxes, true)) { |
|
| 381 | - unset($hidden_meta_boxes[ $key ]); |
|
| 382 | - } |
|
| 383 | - } |
|
| 384 | - } |
|
| 385 | - update_user_option($user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true); |
|
| 386 | - update_user_option($user->ID, 'ee_nav_menu_initialized', 1, true); |
|
| 387 | - } |
|
| 388 | - |
|
| 389 | - |
|
| 390 | - /** |
|
| 391 | - * This method simply registers custom nav menu boxes for "nav_menus.php route" |
|
| 392 | - * Currently EE is using this to make sure there are menu options for our CPT archive page routes. |
|
| 393 | - * |
|
| 394 | - * @todo modify this so its more dynamic and automatic for all ee CPTs and setups and can also be hooked into by |
|
| 395 | - * addons etc. |
|
| 396 | - * @return void |
|
| 397 | - */ |
|
| 398 | - public function register_custom_nav_menu_boxes() |
|
| 399 | - { |
|
| 400 | - add_meta_box( |
|
| 401 | - 'add-extra-nav-menu-pages', |
|
| 402 | - esc_html__('Event Espresso Pages', 'event_espresso'), |
|
| 403 | - array($this, 'ee_cpt_archive_pages'), |
|
| 404 | - 'nav-menus', |
|
| 405 | - 'side', |
|
| 406 | - 'core' |
|
| 407 | - ); |
|
| 408 | - } |
|
| 409 | - |
|
| 410 | - |
|
| 411 | - /** |
|
| 412 | - * Use this to edit the post link for our cpts so that the edit link points to the correct page. |
|
| 413 | - * |
|
| 414 | - * @since 4.3.0 |
|
| 415 | - * @param string $link the original link generated by wp |
|
| 416 | - * @param int $id post id |
|
| 417 | - * @return string the (maybe) modified link |
|
| 418 | - */ |
|
| 419 | - public function modify_edit_post_link($link, $id) |
|
| 420 | - { |
|
| 421 | - if (! $post = get_post($id)) { |
|
| 422 | - return $link; |
|
| 423 | - } |
|
| 424 | - if ($post->post_type === 'espresso_attendees') { |
|
| 425 | - $query_args = array( |
|
| 426 | - 'action' => 'edit_attendee', |
|
| 427 | - 'post' => $id, |
|
| 428 | - ); |
|
| 429 | - return EEH_URL::add_query_args_and_nonce( |
|
| 430 | - $query_args, |
|
| 431 | - admin_url('admin.php?page=espresso_registrations') |
|
| 432 | - ); |
|
| 433 | - } |
|
| 434 | - return $link; |
|
| 435 | - } |
|
| 436 | - |
|
| 437 | - |
|
| 438 | - public function ee_cpt_archive_pages() |
|
| 439 | - { |
|
| 440 | - global $nav_menu_selected_id; |
|
| 441 | - $db_fields = false; |
|
| 442 | - $walker = new Walker_Nav_Menu_Checklist($db_fields); |
|
| 443 | - $current_tab = 'event-archives'; |
|
| 444 | - $removed_args = array( |
|
| 445 | - 'action', |
|
| 446 | - 'customlink-tab', |
|
| 447 | - 'edit-menu-item', |
|
| 448 | - 'menu-item', |
|
| 449 | - 'page-tab', |
|
| 450 | - '_wpnonce', |
|
| 451 | - ); |
|
| 452 | - ?> |
|
| 23 | + /** |
|
| 24 | + * @var EE_Admin $_instance |
|
| 25 | + */ |
|
| 26 | + private static $_instance; |
|
| 27 | + |
|
| 28 | + /** |
|
| 29 | + * @var PersistentAdminNoticeManager $persistent_admin_notice_manager |
|
| 30 | + */ |
|
| 31 | + private $persistent_admin_notice_manager; |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * @var LoaderInterface |
|
| 35 | + */ |
|
| 36 | + protected $loader; |
|
| 37 | + |
|
| 38 | + /** |
|
| 39 | + * @singleton method used to instantiate class object |
|
| 40 | + * @return EE_Admin |
|
| 41 | + * @throws EE_Error |
|
| 42 | + */ |
|
| 43 | + public static function instance() |
|
| 44 | + { |
|
| 45 | + // check if class object is instantiated |
|
| 46 | + if (! self::$_instance instanceof EE_Admin) { |
|
| 47 | + self::$_instance = new self(); |
|
| 48 | + } |
|
| 49 | + return self::$_instance; |
|
| 50 | + } |
|
| 51 | + |
|
| 52 | + |
|
| 53 | + /** |
|
| 54 | + * @return EE_Admin |
|
| 55 | + * @throws EE_Error |
|
| 56 | + */ |
|
| 57 | + public static function reset() |
|
| 58 | + { |
|
| 59 | + self::$_instance = null; |
|
| 60 | + return self::instance(); |
|
| 61 | + } |
|
| 62 | + |
|
| 63 | + |
|
| 64 | + /** |
|
| 65 | + * class constructor |
|
| 66 | + * |
|
| 67 | + * @throws EE_Error |
|
| 68 | + * @throws InvalidDataTypeException |
|
| 69 | + * @throws InvalidInterfaceException |
|
| 70 | + * @throws InvalidArgumentException |
|
| 71 | + */ |
|
| 72 | + protected function __construct() |
|
| 73 | + { |
|
| 74 | + // define global EE_Admin constants |
|
| 75 | + $this->_define_all_constants(); |
|
| 76 | + // set autoloaders for our admin page classes based on included path information |
|
| 77 | + EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_ADMIN); |
|
| 78 | + // admin hooks |
|
| 79 | + add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2); |
|
| 80 | + // load EE_Request_Handler early |
|
| 81 | + add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'get_request')); |
|
| 82 | + add_action('AHEE__EE_System__initialize_last', array($this, 'init')); |
|
| 83 | + add_action('AHEE__EE_Admin_Page__route_admin_request', array($this, 'route_admin_request'), 100, 2); |
|
| 84 | + add_action('wp_loaded', array($this, 'wp_loaded'), 100); |
|
| 85 | + add_action('admin_init', array($this, 'admin_init'), 100); |
|
| 86 | + add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'), 20); |
|
| 87 | + add_action('admin_notices', array($this, 'display_admin_notices'), 10); |
|
| 88 | + add_action('network_admin_notices', array($this, 'display_admin_notices'), 10); |
|
| 89 | + add_filter('pre_update_option', array($this, 'check_for_invalid_datetime_formats'), 100, 2); |
|
| 90 | + add_filter('admin_footer_text', array($this, 'espresso_admin_footer')); |
|
| 91 | + add_action('load-plugins.php', array($this, 'hookIntoWpPluginsPage')); |
|
| 92 | + add_action('display_post_states', array($this, 'displayStateForCriticalPages'), 10, 2); |
|
| 93 | + add_filter('plugin_row_meta', array($this, 'addLinksToPluginRowMeta'), 10, 2); |
|
| 94 | + // reset Environment config (we only do this on admin page loads); |
|
| 95 | + EE_Registry::instance()->CFG->environment->recheck_values(); |
|
| 96 | + do_action('AHEE__EE_Admin__loaded'); |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + |
|
| 100 | + /** |
|
| 101 | + * _define_all_constants |
|
| 102 | + * define constants that are set globally for all admin pages |
|
| 103 | + * |
|
| 104 | + * @return void |
|
| 105 | + */ |
|
| 106 | + private function _define_all_constants() |
|
| 107 | + { |
|
| 108 | + if (! defined('EE_ADMIN_URL')) { |
|
| 109 | + define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/'); |
|
| 110 | + define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/'); |
|
| 111 | + define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS); |
|
| 112 | + define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/'); |
|
| 113 | + define('WP_AJAX_URL', admin_url('admin-ajax.php')); |
|
| 114 | + } |
|
| 115 | + } |
|
| 116 | + |
|
| 117 | + |
|
| 118 | + /** |
|
| 119 | + * filter_plugin_actions - adds links to the Plugins page listing |
|
| 120 | + * |
|
| 121 | + * @param array $links |
|
| 122 | + * @param string $plugin |
|
| 123 | + * @return array |
|
| 124 | + */ |
|
| 125 | + public function filter_plugin_actions($links, $plugin) |
|
| 126 | + { |
|
| 127 | + // set $main_file in stone |
|
| 128 | + static $main_file; |
|
| 129 | + // if $main_file is not set yet |
|
| 130 | + if (! $main_file) { |
|
| 131 | + $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE); |
|
| 132 | + } |
|
| 133 | + if ($plugin === $main_file) { |
|
| 134 | + // compare current plugin to this one |
|
| 135 | + if (EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
| 136 | + $maintenance_link = '<a href="admin.php?page=espresso_maintenance_settings"' |
|
| 137 | + . ' title="Event Espresso is in maintenance mode. Click this link to learn why.">' |
|
| 138 | + . esc_html__('Maintenance Mode Active', 'event_espresso') |
|
| 139 | + . '</a>'; |
|
| 140 | + array_unshift($links, $maintenance_link); |
|
| 141 | + } else { |
|
| 142 | + $org_settings_link = '<a href="admin.php?page=espresso_general_settings">' |
|
| 143 | + . esc_html__('Settings', 'event_espresso') |
|
| 144 | + . '</a>'; |
|
| 145 | + $events_link = '<a href="admin.php?page=espresso_events">' |
|
| 146 | + . esc_html__('Events', 'event_espresso') |
|
| 147 | + . '</a>'; |
|
| 148 | + // add before other links |
|
| 149 | + array_unshift($links, $org_settings_link, $events_link); |
|
| 150 | + } |
|
| 151 | + } |
|
| 152 | + return $links; |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + |
|
| 156 | + /** |
|
| 157 | + * _get_request |
|
| 158 | + * |
|
| 159 | + * @return void |
|
| 160 | + * @throws EE_Error |
|
| 161 | + * @throws InvalidArgumentException |
|
| 162 | + * @throws InvalidDataTypeException |
|
| 163 | + * @throws InvalidInterfaceException |
|
| 164 | + * @throws ReflectionException |
|
| 165 | + */ |
|
| 166 | + public function get_request() |
|
| 167 | + { |
|
| 168 | + EE_Registry::instance()->load_core('Request_Handler'); |
|
| 169 | + } |
|
| 170 | + |
|
| 171 | + |
|
| 172 | + /** |
|
| 173 | + * hide_admin_pages_except_maintenance_mode |
|
| 174 | + * |
|
| 175 | + * @param array $admin_page_folder_names |
|
| 176 | + * @return array |
|
| 177 | + */ |
|
| 178 | + public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array()) |
|
| 179 | + { |
|
| 180 | + return array( |
|
| 181 | + 'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS, |
|
| 182 | + 'about' => EE_ADMIN_PAGES . 'about' . DS, |
|
| 183 | + 'support' => EE_ADMIN_PAGES . 'support' . DS, |
|
| 184 | + ); |
|
| 185 | + } |
|
| 186 | + |
|
| 187 | + |
|
| 188 | + /** |
|
| 189 | + * init- should fire after shortcode, module, addon, other plugin (default priority), and even |
|
| 190 | + * EE_Front_Controller's init phases have run |
|
| 191 | + * |
|
| 192 | + * @return void |
|
| 193 | + * @throws EE_Error |
|
| 194 | + * @throws InvalidArgumentException |
|
| 195 | + * @throws InvalidDataTypeException |
|
| 196 | + * @throws InvalidInterfaceException |
|
| 197 | + * @throws ReflectionException |
|
| 198 | + * @throws ServiceNotFoundException |
|
| 199 | + */ |
|
| 200 | + public function init() |
|
| 201 | + { |
|
| 202 | + // only enable most of the EE_Admin IF we're not in full maintenance mode |
|
| 203 | + if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
| 204 | + $this->initModelsReady(); |
|
| 205 | + } |
|
| 206 | + // run the admin page factory but ONLY if we are doing an ee admin ajax request |
|
| 207 | + if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
| 208 | + try { |
|
| 209 | + // this loads the controller for the admin pages which will setup routing etc |
|
| 210 | + EE_Registry::instance()->load_core('Admin_Page_Loader'); |
|
| 211 | + } catch (EE_Error $e) { |
|
| 212 | + $e->get_error(); |
|
| 213 | + } |
|
| 214 | + } |
|
| 215 | + add_filter('content_save_pre', array($this, 'its_eSpresso'), 10, 1); |
|
| 216 | + // make sure our CPTs and custom taxonomy metaboxes get shown for first time users |
|
| 217 | + add_action('admin_head', array($this, 'enable_hidden_ee_nav_menu_metaboxes'), 10); |
|
| 218 | + add_action('admin_head', array($this, 'register_custom_nav_menu_boxes'), 10); |
|
| 219 | + // exclude EE critical pages from all nav menus and wp_list_pages |
|
| 220 | + add_filter('nav_menu_meta_box_object', array($this, 'remove_pages_from_nav_menu'), 10); |
|
| 221 | + } |
|
| 222 | + |
|
| 223 | + |
|
| 224 | + /** |
|
| 225 | + * Gets the loader (and if it wasn't previously set, sets it) |
|
| 226 | + * @return LoaderInterface |
|
| 227 | + * @throws InvalidArgumentException |
|
| 228 | + * @throws InvalidDataTypeException |
|
| 229 | + * @throws InvalidInterfaceException |
|
| 230 | + */ |
|
| 231 | + protected function getLoader() |
|
| 232 | + { |
|
| 233 | + if (! $this->loader instanceof LoaderInterface) { |
|
| 234 | + $this->loader = LoaderFactory::getLoader(); |
|
| 235 | + } |
|
| 236 | + return $this->loader; |
|
| 237 | + } |
|
| 238 | + |
|
| 239 | + |
|
| 240 | + /** |
|
| 241 | + * Method that's fired on admin requests (including admin ajax) but only when the models are usable |
|
| 242 | + * (ie, the site isn't in maintenance mode) |
|
| 243 | + * @since 4.9.63.p |
|
| 244 | + * @return void |
|
| 245 | + */ |
|
| 246 | + protected function initModelsReady() |
|
| 247 | + { |
|
| 248 | + // ok so we want to enable the entire admin |
|
| 249 | + $this->persistent_admin_notice_manager = $this->getLoader()->getShared( |
|
| 250 | + 'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
| 251 | + ); |
|
| 252 | + $this->persistent_admin_notice_manager->setReturnUrl( |
|
| 253 | + EE_Admin_Page::add_query_args_and_nonce( |
|
| 254 | + array( |
|
| 255 | + 'page' => EE_Registry::instance()->REQ->get('page', ''), |
|
| 256 | + 'action' => EE_Registry::instance()->REQ->get('action', ''), |
|
| 257 | + ), |
|
| 258 | + EE_ADMIN_URL |
|
| 259 | + ) |
|
| 260 | + ); |
|
| 261 | + $this->maybeSetDatetimeWarningNotice(); |
|
| 262 | + // at a glance dashboard widget |
|
| 263 | + add_filter('dashboard_glance_items', array($this, 'dashboard_glance_items'), 10); |
|
| 264 | + // filter for get_edit_post_link used on comments for custom post types |
|
| 265 | + add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2); |
|
| 266 | + } |
|
| 267 | + |
|
| 268 | + |
|
| 269 | + /** |
|
| 270 | + * get_persistent_admin_notices |
|
| 271 | + * |
|
| 272 | + * @access public |
|
| 273 | + * @return void |
|
| 274 | + * @throws EE_Error |
|
| 275 | + * @throws InvalidArgumentException |
|
| 276 | + * @throws InvalidDataTypeException |
|
| 277 | + * @throws InvalidInterfaceException |
|
| 278 | + */ |
|
| 279 | + public function maybeSetDatetimeWarningNotice() |
|
| 280 | + { |
|
| 281 | + // add dismissable notice for datetime changes. Only valid if site does not have a timezone_string set. |
|
| 282 | + // @todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version |
|
| 283 | + // with this. But after enough time (indeterminate at this point) we can just remove this notice. |
|
| 284 | + // this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626 |
|
| 285 | + if (apply_filters('FHEE__EE_Admin__maybeSetDatetimeWarningNotice', true) |
|
| 286 | + && ! get_option('timezone_string') |
|
| 287 | + && EEM_Event::instance()->count() > 0 |
|
| 288 | + ) { |
|
| 289 | + new PersistentAdminNotice( |
|
| 290 | + 'datetime_fix_notice', |
|
| 291 | + sprintf( |
|
| 292 | + esc_html__( |
|
| 293 | + '%1$sImportant announcement related to your install of Event Espresso%2$s: There are some changes made to your site that could affect how dates display for your events and other related items with dates and times. Read more about it %3$shere%4$s. If your dates and times are displaying incorrectly (incorrect offset), you can fix it using the tool on %5$sthis page%4$s.', |
|
| 294 | + 'event_espresso' |
|
| 295 | + ), |
|
| 296 | + '<strong>', |
|
| 297 | + '</strong>', |
|
| 298 | + '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">', |
|
| 299 | + '</a>', |
|
| 300 | + '<a href="' . EE_Admin_Page::add_query_args_and_nonce( |
|
| 301 | + array( |
|
| 302 | + 'page' => 'espresso_maintenance_settings', |
|
| 303 | + 'action' => 'datetime_tools', |
|
| 304 | + ), |
|
| 305 | + admin_url('admin.php') |
|
| 306 | + ) . '">' |
|
| 307 | + ), |
|
| 308 | + false, |
|
| 309 | + 'manage_options', |
|
| 310 | + 'datetime_fix_persistent_notice' |
|
| 311 | + ); |
|
| 312 | + } |
|
| 313 | + } |
|
| 314 | + |
|
| 315 | + |
|
| 316 | + /** |
|
| 317 | + * this simply hooks into the nav menu setup of pages metabox and makes sure that we remove EE critical pages from |
|
| 318 | + * the list of options. the wp function "wp_nav_menu_item_post_type_meta_box" found in |
|
| 319 | + * wp-admin/includes/nav-menu.php looks for the "_default_query" property on the post_type object and it uses that |
|
| 320 | + * to override any queries found in the existing query for the given post type. Note that _default_query is not a |
|
| 321 | + * normal property on the post_type object. It's found ONLY in this particular context. |
|
| 322 | + * |
|
| 323 | + * @param WP_Post $post_type WP post type object |
|
| 324 | + * @return WP_Post |
|
| 325 | + * @throws InvalidArgumentException |
|
| 326 | + * @throws InvalidDataTypeException |
|
| 327 | + * @throws InvalidInterfaceException |
|
| 328 | + */ |
|
| 329 | + public function remove_pages_from_nav_menu($post_type) |
|
| 330 | + { |
|
| 331 | + // if this isn't the "pages" post type let's get out |
|
| 332 | + if ($post_type->name !== 'page') { |
|
| 333 | + return $post_type; |
|
| 334 | + } |
|
| 335 | + $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
| 336 | + $post_type->_default_query = array( |
|
| 337 | + 'post__not_in' => $critical_pages, |
|
| 338 | + ); |
|
| 339 | + return $post_type; |
|
| 340 | + } |
|
| 341 | + |
|
| 342 | + |
|
| 343 | + /** |
|
| 344 | + * WP by default only shows three metaboxes in "nav-menus.php" for first times users. We want to make sure our |
|
| 345 | + * metaboxes get shown as well |
|
| 346 | + * |
|
| 347 | + * @return void |
|
| 348 | + */ |
|
| 349 | + public function enable_hidden_ee_nav_menu_metaboxes() |
|
| 350 | + { |
|
| 351 | + global $wp_meta_boxes, $pagenow; |
|
| 352 | + if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
| 353 | + return; |
|
| 354 | + } |
|
| 355 | + $user = wp_get_current_user(); |
|
| 356 | + // has this been done yet? |
|
| 357 | + if (get_user_option('ee_nav_menu_initialized', $user->ID)) { |
|
| 358 | + return; |
|
| 359 | + } |
|
| 360 | + |
|
| 361 | + $hidden_meta_boxes = get_user_option('metaboxhidden_nav-menus', $user->ID); |
|
| 362 | + $initial_meta_boxes = apply_filters( |
|
| 363 | + 'FHEE__EE_Admin__enable_hidden_ee_nav_menu_boxes__initial_meta_boxes', |
|
| 364 | + array( |
|
| 365 | + 'nav-menu-theme-locations', |
|
| 366 | + 'add-page', |
|
| 367 | + 'add-custom-links', |
|
| 368 | + 'add-category', |
|
| 369 | + 'add-espresso_events', |
|
| 370 | + 'add-espresso_venues', |
|
| 371 | + 'add-espresso_event_categories', |
|
| 372 | + 'add-espresso_venue_categories', |
|
| 373 | + 'add-post-type-post', |
|
| 374 | + 'add-post-type-page', |
|
| 375 | + ) |
|
| 376 | + ); |
|
| 377 | + |
|
| 378 | + if (is_array($hidden_meta_boxes)) { |
|
| 379 | + foreach ($hidden_meta_boxes as $key => $meta_box_id) { |
|
| 380 | + if (in_array($meta_box_id, $initial_meta_boxes, true)) { |
|
| 381 | + unset($hidden_meta_boxes[ $key ]); |
|
| 382 | + } |
|
| 383 | + } |
|
| 384 | + } |
|
| 385 | + update_user_option($user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true); |
|
| 386 | + update_user_option($user->ID, 'ee_nav_menu_initialized', 1, true); |
|
| 387 | + } |
|
| 388 | + |
|
| 389 | + |
|
| 390 | + /** |
|
| 391 | + * This method simply registers custom nav menu boxes for "nav_menus.php route" |
|
| 392 | + * Currently EE is using this to make sure there are menu options for our CPT archive page routes. |
|
| 393 | + * |
|
| 394 | + * @todo modify this so its more dynamic and automatic for all ee CPTs and setups and can also be hooked into by |
|
| 395 | + * addons etc. |
|
| 396 | + * @return void |
|
| 397 | + */ |
|
| 398 | + public function register_custom_nav_menu_boxes() |
|
| 399 | + { |
|
| 400 | + add_meta_box( |
|
| 401 | + 'add-extra-nav-menu-pages', |
|
| 402 | + esc_html__('Event Espresso Pages', 'event_espresso'), |
|
| 403 | + array($this, 'ee_cpt_archive_pages'), |
|
| 404 | + 'nav-menus', |
|
| 405 | + 'side', |
|
| 406 | + 'core' |
|
| 407 | + ); |
|
| 408 | + } |
|
| 409 | + |
|
| 410 | + |
|
| 411 | + /** |
|
| 412 | + * Use this to edit the post link for our cpts so that the edit link points to the correct page. |
|
| 413 | + * |
|
| 414 | + * @since 4.3.0 |
|
| 415 | + * @param string $link the original link generated by wp |
|
| 416 | + * @param int $id post id |
|
| 417 | + * @return string the (maybe) modified link |
|
| 418 | + */ |
|
| 419 | + public function modify_edit_post_link($link, $id) |
|
| 420 | + { |
|
| 421 | + if (! $post = get_post($id)) { |
|
| 422 | + return $link; |
|
| 423 | + } |
|
| 424 | + if ($post->post_type === 'espresso_attendees') { |
|
| 425 | + $query_args = array( |
|
| 426 | + 'action' => 'edit_attendee', |
|
| 427 | + 'post' => $id, |
|
| 428 | + ); |
|
| 429 | + return EEH_URL::add_query_args_and_nonce( |
|
| 430 | + $query_args, |
|
| 431 | + admin_url('admin.php?page=espresso_registrations') |
|
| 432 | + ); |
|
| 433 | + } |
|
| 434 | + return $link; |
|
| 435 | + } |
|
| 436 | + |
|
| 437 | + |
|
| 438 | + public function ee_cpt_archive_pages() |
|
| 439 | + { |
|
| 440 | + global $nav_menu_selected_id; |
|
| 441 | + $db_fields = false; |
|
| 442 | + $walker = new Walker_Nav_Menu_Checklist($db_fields); |
|
| 443 | + $current_tab = 'event-archives'; |
|
| 444 | + $removed_args = array( |
|
| 445 | + 'action', |
|
| 446 | + 'customlink-tab', |
|
| 447 | + 'edit-menu-item', |
|
| 448 | + 'menu-item', |
|
| 449 | + 'page-tab', |
|
| 450 | + '_wpnonce', |
|
| 451 | + ); |
|
| 452 | + ?> |
|
| 453 | 453 | <div id="posttype-extra-nav-menu-pages" class="posttypediv"> |
| 454 | 454 | <ul id="posttype-extra-nav-menu-pages-tabs" class="posttype-tabs add-menu-item-tabs"> |
| 455 | 455 | <li <?php echo('event-archives' === $current_tab ? ' class="tabs"' : ''); ?>> |
| 456 | 456 | <a class="nav-tab-link" data-type="tabs-panel-posttype-extra-nav-menu-pages-event-archives" |
| 457 | 457 | href="<?php |
| 458 | - if ($nav_menu_selected_id) { |
|
| 459 | - echo esc_url( |
|
| 460 | - add_query_arg( |
|
| 461 | - 'extra-nav-menu-pages-tab', |
|
| 462 | - 'event-archives', |
|
| 463 | - remove_query_arg($removed_args) |
|
| 464 | - ) |
|
| 465 | - ); |
|
| 466 | - } |
|
| 467 | - ?>#tabs-panel-posttype-extra-nav-menu-pages-event-archives"> |
|
| 458 | + if ($nav_menu_selected_id) { |
|
| 459 | + echo esc_url( |
|
| 460 | + add_query_arg( |
|
| 461 | + 'extra-nav-menu-pages-tab', |
|
| 462 | + 'event-archives', |
|
| 463 | + remove_query_arg($removed_args) |
|
| 464 | + ) |
|
| 465 | + ); |
|
| 466 | + } |
|
| 467 | + ?>#tabs-panel-posttype-extra-nav-menu-pages-event-archives"> |
|
| 468 | 468 | <?php esc_html_e('Event Archive Pages', 'event_espresso'); ?> |
| 469 | 469 | </a> |
| 470 | 470 | </li> |
| 471 | 471 | </ul><!-- .posttype-tabs --> |
| 472 | 472 | |
| 473 | 473 | <div id="tabs-panel-posttype-extra-nav-menu-pages-event-archives" class="tabs-panel <?php |
| 474 | - echo('event-archives' === $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive'); |
|
| 475 | - ?>"> |
|
| 474 | + echo('event-archives' === $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive'); |
|
| 475 | + ?>"> |
|
| 476 | 476 | <ul id="extra-nav-menu-pageschecklist-event-archives" class="categorychecklist form-no-clear"> |
| 477 | 477 | <?php |
| 478 | - $pages = $this->_get_extra_nav_menu_pages_items(); |
|
| 479 | - $args['walker'] = $walker; |
|
| 480 | - echo walk_nav_menu_tree( |
|
| 481 | - array_map( |
|
| 482 | - array($this, '_setup_extra_nav_menu_pages_items'), |
|
| 483 | - $pages |
|
| 484 | - ), |
|
| 485 | - 0, |
|
| 486 | - (object) $args |
|
| 487 | - ); |
|
| 488 | - ?> |
|
| 478 | + $pages = $this->_get_extra_nav_menu_pages_items(); |
|
| 479 | + $args['walker'] = $walker; |
|
| 480 | + echo walk_nav_menu_tree( |
|
| 481 | + array_map( |
|
| 482 | + array($this, '_setup_extra_nav_menu_pages_items'), |
|
| 483 | + $pages |
|
| 484 | + ), |
|
| 485 | + 0, |
|
| 486 | + (object) $args |
|
| 487 | + ); |
|
| 488 | + ?> |
|
| 489 | 489 | </ul> |
| 490 | 490 | </div><!-- /.tabs-panel --> |
| 491 | 491 | |
| 492 | 492 | <p class="button-controls"> |
| 493 | 493 | <span class="list-controls"> |
| 494 | 494 | <a href="<?php |
| 495 | - echo esc_url( |
|
| 496 | - add_query_arg( |
|
| 497 | - array( |
|
| 498 | - 'extra-nav-menu-pages-tab' => 'event-archives', |
|
| 499 | - 'selectall' => 1, |
|
| 500 | - ), |
|
| 501 | - remove_query_arg($removed_args) |
|
| 502 | - ) |
|
| 503 | - ); |
|
| 504 | - ?>#posttype-extra-nav-menu-pages" class="select-all"><?php esc_html_e('Select All', 'event_espresso'); ?></a> |
|
| 495 | + echo esc_url( |
|
| 496 | + add_query_arg( |
|
| 497 | + array( |
|
| 498 | + 'extra-nav-menu-pages-tab' => 'event-archives', |
|
| 499 | + 'selectall' => 1, |
|
| 500 | + ), |
|
| 501 | + remove_query_arg($removed_args) |
|
| 502 | + ) |
|
| 503 | + ); |
|
| 504 | + ?>#posttype-extra-nav-menu-pages" class="select-all"><?php esc_html_e('Select All', 'event_espresso'); ?></a> |
|
| 505 | 505 | </span> |
| 506 | 506 | <span class="add-to-menu"> |
| 507 | 507 | <input type="submit"<?php wp_nav_menu_disabled_check($nav_menu_selected_id); ?> |
@@ -514,566 +514,566 @@ discard block |
||
| 514 | 514 | |
| 515 | 515 | </div><!-- /.posttypediv --> |
| 516 | 516 | <?php |
| 517 | - } |
|
| 518 | - |
|
| 519 | - |
|
| 520 | - /** |
|
| 521 | - * Returns an array of event archive nav items. |
|
| 522 | - * |
|
| 523 | - * @todo for now this method is just in place so when it gets abstracted further we can substitute in whatever |
|
| 524 | - * method we use for getting the extra nav menu items |
|
| 525 | - * @return array |
|
| 526 | - */ |
|
| 527 | - private function _get_extra_nav_menu_pages_items() |
|
| 528 | - { |
|
| 529 | - $menuitems[] = array( |
|
| 530 | - 'title' => esc_html__('Event List', 'event_espresso'), |
|
| 531 | - 'url' => get_post_type_archive_link('espresso_events'), |
|
| 532 | - 'description' => esc_html__('Archive page for all events.', 'event_espresso'), |
|
| 533 | - ); |
|
| 534 | - return apply_filters('FHEE__EE_Admin__get_extra_nav_menu_pages_items', $menuitems); |
|
| 535 | - } |
|
| 536 | - |
|
| 537 | - |
|
| 538 | - /** |
|
| 539 | - * Setup nav menu walker item for usage in the event archive nav menu metabox. It receives a menu_item array with |
|
| 540 | - * the properties and converts it to the menu item object. |
|
| 541 | - * |
|
| 542 | - * @see wp_setup_nav_menu_item() in wp-includes/nav-menu.php |
|
| 543 | - * @param $menu_item_values |
|
| 544 | - * @return stdClass |
|
| 545 | - */ |
|
| 546 | - private function _setup_extra_nav_menu_pages_items($menu_item_values) |
|
| 547 | - { |
|
| 548 | - $menu_item = new stdClass(); |
|
| 549 | - $keys = array( |
|
| 550 | - 'ID' => 0, |
|
| 551 | - 'db_id' => 0, |
|
| 552 | - 'menu_item_parent' => 0, |
|
| 553 | - 'object_id' => -1, |
|
| 554 | - 'post_parent' => 0, |
|
| 555 | - 'type' => 'custom', |
|
| 556 | - 'object' => '', |
|
| 557 | - 'type_label' => esc_html__('Extra Nav Menu Item', 'event_espresso'), |
|
| 558 | - 'title' => '', |
|
| 559 | - 'url' => '', |
|
| 560 | - 'target' => '', |
|
| 561 | - 'attr_title' => '', |
|
| 562 | - 'description' => '', |
|
| 563 | - 'classes' => array(), |
|
| 564 | - 'xfn' => '', |
|
| 565 | - ); |
|
| 566 | - |
|
| 567 | - foreach ($keys as $key => $value) { |
|
| 568 | - $menu_item->{$key} = isset($menu_item_values[ $key ]) ? $menu_item_values[ $key ] : $value; |
|
| 569 | - } |
|
| 570 | - return $menu_item; |
|
| 571 | - } |
|
| 572 | - |
|
| 573 | - |
|
| 574 | - /** |
|
| 575 | - * This is the action hook for the AHEE__EE_Admin_Page__route_admin_request hook that fires off right before an |
|
| 576 | - * EE_Admin_Page route is called. |
|
| 577 | - * |
|
| 578 | - * @return void |
|
| 579 | - */ |
|
| 580 | - public function route_admin_request() |
|
| 581 | - { |
|
| 582 | - } |
|
| 583 | - |
|
| 584 | - |
|
| 585 | - /** |
|
| 586 | - * wp_loaded should fire on the WordPress wp_loaded hook. This fires on a VERY late priority. |
|
| 587 | - * |
|
| 588 | - * @return void |
|
| 589 | - */ |
|
| 590 | - public function wp_loaded() |
|
| 591 | - { |
|
| 592 | - } |
|
| 593 | - |
|
| 594 | - |
|
| 595 | - /** |
|
| 596 | - * admin_init |
|
| 597 | - * |
|
| 598 | - * @return void |
|
| 599 | - * @throws EE_Error |
|
| 600 | - * @throws InvalidArgumentException |
|
| 601 | - * @throws InvalidDataTypeException |
|
| 602 | - * @throws InvalidInterfaceException |
|
| 603 | - * @throws ReflectionException |
|
| 604 | - */ |
|
| 605 | - public function admin_init() |
|
| 606 | - { |
|
| 607 | - /** |
|
| 608 | - * our cpt models must be instantiated on WordPress post processing routes (wp-admin/post.php), |
|
| 609 | - * so any hooking into core WP routes is taken care of. So in this next few lines of code: |
|
| 610 | - * - check if doing post processing. |
|
| 611 | - * - check if doing post processing of one of EE CPTs |
|
| 612 | - * - instantiate the corresponding EE CPT model for the post_type being processed. |
|
| 613 | - */ |
|
| 614 | - if (isset($_POST['action'], $_POST['post_type']) && $_POST['action'] === 'editpost') { |
|
| 615 | - /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */ |
|
| 616 | - $custom_post_types = $this->getLoader()->getShared( |
|
| 617 | - 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' |
|
| 618 | - ); |
|
| 619 | - $custom_post_types->getCustomPostTypeModels($_POST['post_type']); |
|
| 620 | - } |
|
| 621 | - |
|
| 622 | - |
|
| 623 | - /** |
|
| 624 | - * This code excludes EE critical pages anywhere `wp_dropdown_pages` is used to create a dropdown for selecting |
|
| 625 | - * critical pages. The only place critical pages need included in a generated dropdown is on the "Critical |
|
| 626 | - * Pages" tab in the EE General Settings Admin page. |
|
| 627 | - * This is for user-proofing. |
|
| 628 | - */ |
|
| 629 | - add_filter('wp_dropdown_pages', array($this, 'modify_dropdown_pages')); |
|
| 630 | - if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
| 631 | - $this->adminInitModelsReady(); |
|
| 632 | - } |
|
| 633 | - } |
|
| 634 | - |
|
| 635 | - |
|
| 636 | - /** |
|
| 637 | - * Runs on admin_init but only if models are usable (ie, we're not in maintenanc emode) |
|
| 638 | - */ |
|
| 639 | - protected function adminInitModelsReady() |
|
| 640 | - { |
|
| 641 | - if (function_exists('wp_add_privacy_policy_content')) { |
|
| 642 | - $this->getLoader()->getShared('EventEspresso\core\services\privacy\policy\PrivacyPolicyManager'); |
|
| 643 | - } |
|
| 644 | - } |
|
| 645 | - |
|
| 646 | - |
|
| 647 | - /** |
|
| 648 | - * Callback for wp_dropdown_pages hook to remove ee critical pages from the dropdown selection. |
|
| 649 | - * |
|
| 650 | - * @param string $output Current output. |
|
| 651 | - * @return string |
|
| 652 | - * @throws InvalidArgumentException |
|
| 653 | - * @throws InvalidDataTypeException |
|
| 654 | - * @throws InvalidInterfaceException |
|
| 655 | - */ |
|
| 656 | - public function modify_dropdown_pages($output) |
|
| 657 | - { |
|
| 658 | - // get critical pages |
|
| 659 | - $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
| 660 | - |
|
| 661 | - // split current output by line break for easier parsing. |
|
| 662 | - $split_output = explode("\n", $output); |
|
| 663 | - |
|
| 664 | - // loop through to remove any critical pages from the array. |
|
| 665 | - foreach ($critical_pages as $page_id) { |
|
| 666 | - $needle = 'value="' . $page_id . '"'; |
|
| 667 | - foreach ($split_output as $key => $haystack) { |
|
| 668 | - if (strpos($haystack, $needle) !== false) { |
|
| 669 | - unset($split_output[ $key ]); |
|
| 670 | - } |
|
| 671 | - } |
|
| 672 | - } |
|
| 673 | - // replace output with the new contents |
|
| 674 | - return implode("\n", $split_output); |
|
| 675 | - } |
|
| 676 | - |
|
| 677 | - |
|
| 678 | - /** |
|
| 679 | - * enqueue all admin scripts that need loaded for admin pages |
|
| 680 | - * |
|
| 681 | - * @return void |
|
| 682 | - */ |
|
| 683 | - public function enqueue_admin_scripts() |
|
| 684 | - { |
|
| 685 | - // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js. |
|
| 686 | - // Note: the intention of this script is to only do TARGETED injections. I.E, only injecting on certain script |
|
| 687 | - // calls. |
|
| 688 | - wp_enqueue_script( |
|
| 689 | - 'ee-inject-wp', |
|
| 690 | - EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
| 691 | - array('jquery'), |
|
| 692 | - EVENT_ESPRESSO_VERSION, |
|
| 693 | - true |
|
| 694 | - ); |
|
| 695 | - // register cookie script for future dependencies |
|
| 696 | - wp_register_script( |
|
| 697 | - 'jquery-cookie', |
|
| 698 | - EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
| 699 | - array('jquery'), |
|
| 700 | - '2.1', |
|
| 701 | - true |
|
| 702 | - ); |
|
| 703 | - // joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, can be turned back on again |
|
| 704 | - // via: add_filter('FHEE_load_joyride', '__return_true' ); |
|
| 705 | - if (apply_filters('FHEE_load_joyride', false)) { |
|
| 706 | - // joyride style |
|
| 707 | - wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1'); |
|
| 708 | - wp_register_style( |
|
| 709 | - 'ee-joyride-css', |
|
| 710 | - EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
| 711 | - array('joyride-css'), |
|
| 712 | - EVENT_ESPRESSO_VERSION |
|
| 713 | - ); |
|
| 714 | - wp_register_script( |
|
| 715 | - 'joyride-modernizr', |
|
| 716 | - EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
| 717 | - array(), |
|
| 718 | - '2.1', |
|
| 719 | - true |
|
| 720 | - ); |
|
| 721 | - // joyride JS |
|
| 722 | - wp_register_script( |
|
| 723 | - 'jquery-joyride', |
|
| 724 | - EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
| 725 | - array('jquery-cookie', 'joyride-modernizr'), |
|
| 726 | - '2.1', |
|
| 727 | - true |
|
| 728 | - ); |
|
| 729 | - // wanna go for a joyride? |
|
| 730 | - wp_enqueue_style('ee-joyride-css'); |
|
| 731 | - wp_enqueue_script('jquery-joyride'); |
|
| 732 | - } |
|
| 733 | - } |
|
| 734 | - |
|
| 735 | - |
|
| 736 | - /** |
|
| 737 | - * display_admin_notices |
|
| 738 | - * |
|
| 739 | - * @return void |
|
| 740 | - */ |
|
| 741 | - public function display_admin_notices() |
|
| 742 | - { |
|
| 743 | - echo EE_Error::get_notices(); |
|
| 744 | - } |
|
| 745 | - |
|
| 746 | - |
|
| 747 | - /** |
|
| 748 | - * @param array $elements |
|
| 749 | - * @return array |
|
| 750 | - * @throws EE_Error |
|
| 751 | - * @throws InvalidArgumentException |
|
| 752 | - * @throws InvalidDataTypeException |
|
| 753 | - * @throws InvalidInterfaceException |
|
| 754 | - */ |
|
| 755 | - public function dashboard_glance_items($elements) |
|
| 756 | - { |
|
| 757 | - $elements = is_array($elements) ? $elements : array($elements); |
|
| 758 | - $events = EEM_Event::instance()->count(); |
|
| 759 | - $items['events']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
| 760 | - array('page' => 'espresso_events'), |
|
| 761 | - admin_url('admin.php') |
|
| 762 | - ); |
|
| 763 | - $items['events']['text'] = sprintf( |
|
| 764 | - esc_html( |
|
| 765 | - _n('%s Event', '%s Events', $events, 'event_espresso') |
|
| 766 | - ), |
|
| 767 | - number_format_i18n($events) |
|
| 768 | - ); |
|
| 769 | - $items['events']['title'] = esc_html__('Click to view all Events', 'event_espresso'); |
|
| 770 | - $registrations = EEM_Registration::instance()->count( |
|
| 771 | - array( |
|
| 772 | - array( |
|
| 773 | - 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
| 774 | - ), |
|
| 775 | - ) |
|
| 776 | - ); |
|
| 777 | - $items['registrations']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
| 778 | - array('page' => 'espresso_registrations'), |
|
| 779 | - admin_url('admin.php') |
|
| 780 | - ); |
|
| 781 | - $items['registrations']['text'] = sprintf( |
|
| 782 | - esc_html( |
|
| 783 | - _n('%s Registration', '%s Registrations', $registrations, 'event_espresso') |
|
| 784 | - ), |
|
| 785 | - number_format_i18n($registrations) |
|
| 786 | - ); |
|
| 787 | - $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso'); |
|
| 788 | - |
|
| 789 | - $items = (array) apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items); |
|
| 790 | - |
|
| 791 | - foreach ($items as $type => $item_properties) { |
|
| 792 | - $elements[] = sprintf( |
|
| 793 | - '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>', |
|
| 794 | - $item_properties['url'], |
|
| 795 | - $item_properties['title'], |
|
| 796 | - $item_properties['text'] |
|
| 797 | - ); |
|
| 798 | - } |
|
| 799 | - return $elements; |
|
| 800 | - } |
|
| 801 | - |
|
| 802 | - |
|
| 803 | - /** |
|
| 804 | - * check_for_invalid_datetime_formats |
|
| 805 | - * if an admin changes their date or time format settings on the WP General Settings admin page, verify that |
|
| 806 | - * their selected format can be parsed by PHP |
|
| 807 | - * |
|
| 808 | - * @param $value |
|
| 809 | - * @param $option |
|
| 810 | - * @throws EE_Error |
|
| 811 | - * @return string |
|
| 812 | - */ |
|
| 813 | - public function check_for_invalid_datetime_formats($value, $option) |
|
| 814 | - { |
|
| 815 | - // check for date_format or time_format |
|
| 816 | - switch ($option) { |
|
| 817 | - case 'date_format': |
|
| 818 | - $date_time_format = $value . ' ' . get_option('time_format'); |
|
| 819 | - break; |
|
| 820 | - case 'time_format': |
|
| 821 | - $date_time_format = get_option('date_format') . ' ' . $value; |
|
| 822 | - break; |
|
| 823 | - default: |
|
| 824 | - $date_time_format = false; |
|
| 825 | - } |
|
| 826 | - // do we have a date_time format to check ? |
|
| 827 | - if ($date_time_format) { |
|
| 828 | - $error_msg = EEH_DTT_Helper::validate_format_string($date_time_format); |
|
| 829 | - |
|
| 830 | - if (is_array($error_msg)) { |
|
| 831 | - $msg = '<p>' |
|
| 832 | - . sprintf( |
|
| 833 | - esc_html__( |
|
| 834 | - 'The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:', |
|
| 835 | - 'event_espresso' |
|
| 836 | - ), |
|
| 837 | - date($date_time_format), |
|
| 838 | - $date_time_format |
|
| 839 | - ) |
|
| 840 | - . '</p><p><ul>'; |
|
| 841 | - |
|
| 842 | - |
|
| 843 | - foreach ($error_msg as $error) { |
|
| 844 | - $msg .= '<li>' . $error . '</li>'; |
|
| 845 | - } |
|
| 846 | - |
|
| 847 | - $msg .= '</ul></p><p>' |
|
| 848 | - . sprintf( |
|
| 849 | - esc_html__( |
|
| 850 | - '%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s', |
|
| 851 | - 'event_espresso' |
|
| 852 | - ), |
|
| 853 | - '<span style="color:#D54E21;">', |
|
| 854 | - '</span>' |
|
| 855 | - ) |
|
| 856 | - . '</p>'; |
|
| 857 | - |
|
| 858 | - // trigger WP settings error |
|
| 859 | - add_settings_error( |
|
| 860 | - 'date_format', |
|
| 861 | - 'date_format', |
|
| 862 | - $msg |
|
| 863 | - ); |
|
| 864 | - |
|
| 865 | - // set format to something valid |
|
| 866 | - switch ($option) { |
|
| 867 | - case 'date_format': |
|
| 868 | - $value = 'F j, Y'; |
|
| 869 | - break; |
|
| 870 | - case 'time_format': |
|
| 871 | - $value = 'g:i a'; |
|
| 872 | - break; |
|
| 873 | - } |
|
| 874 | - } |
|
| 875 | - } |
|
| 876 | - return $value; |
|
| 877 | - } |
|
| 878 | - |
|
| 879 | - |
|
| 880 | - /** |
|
| 881 | - * its_eSpresso - converts the less commonly used spelling of "Expresso" to "Espresso" |
|
| 882 | - * |
|
| 883 | - * @param $content |
|
| 884 | - * @return string |
|
| 885 | - */ |
|
| 886 | - public function its_eSpresso($content) |
|
| 887 | - { |
|
| 888 | - return str_replace('[EXPRESSO_', '[ESPRESSO_', $content); |
|
| 889 | - } |
|
| 890 | - |
|
| 891 | - |
|
| 892 | - /** |
|
| 893 | - * espresso_admin_footer |
|
| 894 | - * |
|
| 895 | - * @return string |
|
| 896 | - */ |
|
| 897 | - public function espresso_admin_footer() |
|
| 898 | - { |
|
| 899 | - return \EEH_Template::powered_by_event_espresso('aln-cntr', '', array('utm_content' => 'admin_footer')); |
|
| 900 | - } |
|
| 901 | - |
|
| 902 | - |
|
| 903 | - /** |
|
| 904 | - * static method for registering ee admin page. |
|
| 905 | - * This method is deprecated in favor of the new location in EE_Register_Admin_Page::register. |
|
| 906 | - * |
|
| 907 | - * @since 4.3.0 |
|
| 908 | - * @deprecated 4.3.0 Use EE_Register_Admin_Page::register() instead |
|
| 909 | - * @see EE_Register_Admin_Page::register() |
|
| 910 | - * @param $page_basename |
|
| 911 | - * @param $page_path |
|
| 912 | - * @param array $config |
|
| 913 | - * @return void |
|
| 914 | - * @throws EE_Error |
|
| 915 | - */ |
|
| 916 | - public static function register_ee_admin_page($page_basename, $page_path, $config = array()) |
|
| 917 | - { |
|
| 918 | - EE_Error::doing_it_wrong( |
|
| 919 | - __METHOD__, |
|
| 920 | - sprintf( |
|
| 921 | - esc_html__( |
|
| 922 | - 'Usage is deprecated. Use EE_Register_Admin_Page::register() for registering the %s admin page.', |
|
| 923 | - 'event_espresso' |
|
| 924 | - ), |
|
| 925 | - $page_basename |
|
| 926 | - ), |
|
| 927 | - '4.3' |
|
| 928 | - ); |
|
| 929 | - if (class_exists('EE_Register_Admin_Page')) { |
|
| 930 | - $config['page_path'] = $page_path; |
|
| 931 | - } |
|
| 932 | - EE_Register_Admin_Page::register($page_basename, $config); |
|
| 933 | - } |
|
| 934 | - |
|
| 935 | - |
|
| 936 | - /** |
|
| 937 | - * @deprecated 4.8.41 |
|
| 938 | - * @param int $post_ID |
|
| 939 | - * @param \WP_Post $post |
|
| 940 | - * @return void |
|
| 941 | - */ |
|
| 942 | - public static function parse_post_content_on_save($post_ID, $post) |
|
| 943 | - { |
|
| 944 | - EE_Error::doing_it_wrong( |
|
| 945 | - __METHOD__, |
|
| 946 | - esc_html__('Usage is deprecated', 'event_espresso'), |
|
| 947 | - '4.8.41' |
|
| 948 | - ); |
|
| 949 | - } |
|
| 950 | - |
|
| 951 | - |
|
| 952 | - /** |
|
| 953 | - * @deprecated 4.8.41 |
|
| 954 | - * @param $option |
|
| 955 | - * @param $old_value |
|
| 956 | - * @param $value |
|
| 957 | - * @return void |
|
| 958 | - */ |
|
| 959 | - public function reset_page_for_posts_on_change($option, $old_value, $value) |
|
| 960 | - { |
|
| 961 | - EE_Error::doing_it_wrong( |
|
| 962 | - __METHOD__, |
|
| 963 | - esc_html__('Usage is deprecated', 'event_espresso'), |
|
| 964 | - '4.8.41' |
|
| 965 | - ); |
|
| 966 | - } |
|
| 967 | - |
|
| 968 | - |
|
| 969 | - /** |
|
| 970 | - * @deprecated 4.9.27 |
|
| 971 | - * @return void |
|
| 972 | - */ |
|
| 973 | - public function get_persistent_admin_notices() |
|
| 974 | - { |
|
| 975 | - EE_Error::doing_it_wrong( |
|
| 976 | - __METHOD__, |
|
| 977 | - sprintf( |
|
| 978 | - esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
| 979 | - '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
| 980 | - ), |
|
| 981 | - '4.9.27' |
|
| 982 | - ); |
|
| 983 | - } |
|
| 984 | - |
|
| 985 | - |
|
| 986 | - /** |
|
| 987 | - * @deprecated 4.9.27 |
|
| 988 | - * @throws InvalidInterfaceException |
|
| 989 | - * @throws InvalidDataTypeException |
|
| 990 | - * @throws DomainException |
|
| 991 | - */ |
|
| 992 | - public function dismiss_ee_nag_notice_callback() |
|
| 993 | - { |
|
| 994 | - EE_Error::doing_it_wrong( |
|
| 995 | - __METHOD__, |
|
| 996 | - sprintf( |
|
| 997 | - esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
| 998 | - '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
| 999 | - ), |
|
| 1000 | - '4.9.27' |
|
| 1001 | - ); |
|
| 1002 | - $this->persistent_admin_notice_manager->dismissNotice(); |
|
| 1003 | - } |
|
| 1004 | - |
|
| 1005 | - |
|
| 1006 | - /** |
|
| 1007 | - * Callback on load-plugins.php hook for setting up anything hooking into the wp plugins page. |
|
| 1008 | - * |
|
| 1009 | - * @throws InvalidArgumentException |
|
| 1010 | - * @throws InvalidDataTypeException |
|
| 1011 | - * @throws InvalidInterfaceException |
|
| 1012 | - */ |
|
| 1013 | - public function hookIntoWpPluginsPage() |
|
| 1014 | - { |
|
| 1015 | - $this->getLoader()->getShared('EventEspresso\core\domain\services\admin\ExitModal'); |
|
| 1016 | - $this->getLoader() |
|
| 1017 | - ->getShared('EventEspresso\core\domain\services\admin\PluginUpsells') |
|
| 1018 | - ->decafUpsells(); |
|
| 1019 | - } |
|
| 1020 | - |
|
| 1021 | - |
|
| 1022 | - /** |
|
| 1023 | - * Hooks into the "post states" filter in a wp post type list table. |
|
| 1024 | - * |
|
| 1025 | - * @param array $post_states |
|
| 1026 | - * @param WP_Post $post |
|
| 1027 | - * @return array |
|
| 1028 | - * @throws InvalidArgumentException |
|
| 1029 | - * @throws InvalidDataTypeException |
|
| 1030 | - * @throws InvalidInterfaceException |
|
| 1031 | - */ |
|
| 1032 | - public function displayStateForCriticalPages($post_states, $post) |
|
| 1033 | - { |
|
| 1034 | - $post_states = (array) $post_states; |
|
| 1035 | - if (! $post instanceof WP_Post || $post->post_type !== 'page') { |
|
| 1036 | - return $post_states; |
|
| 1037 | - } |
|
| 1038 | - /** @var EE_Core_Config $config */ |
|
| 1039 | - $config = $this->getLoader()->getShared('EE_Config')->core; |
|
| 1040 | - if (in_array($post->ID, $config->get_critical_pages_array(), true)) { |
|
| 1041 | - $post_states[] = sprintf( |
|
| 1042 | - /* Translators: Using company name - Event Espresso Critical Page */ |
|
| 1043 | - esc_html__('%s Critical Page', 'event_espresso'), |
|
| 1044 | - 'Event Espresso' |
|
| 1045 | - ); |
|
| 1046 | - } |
|
| 1047 | - return $post_states; |
|
| 1048 | - } |
|
| 1049 | - |
|
| 1050 | - |
|
| 1051 | - /** |
|
| 1052 | - * Show documentation links on the plugins page |
|
| 1053 | - * |
|
| 1054 | - * @param mixed $meta Plugin Row Meta |
|
| 1055 | - * @param mixed $file Plugin Base file |
|
| 1056 | - * @return array |
|
| 1057 | - */ |
|
| 1058 | - public function addLinksToPluginRowMeta($meta, $file) |
|
| 1059 | - { |
|
| 1060 | - if (EE_PLUGIN_BASENAME === $file) { |
|
| 1061 | - $row_meta = array( |
|
| 1062 | - 'docs' => '<a href="https://eventespresso.com/support/documentation/versioned-docs/?doc_ver=ee4"' |
|
| 1063 | - . ' aria-label="' |
|
| 1064 | - . esc_attr__('View Event Espresso documentation', 'event_espresso') |
|
| 1065 | - . '">' |
|
| 1066 | - . esc_html__('Docs', 'event_espresso') |
|
| 1067 | - . '</a>', |
|
| 1068 | - 'api' => '<a href="https://github.com/eventespresso/event-espresso-core/tree/master/docs/C--REST-API"' |
|
| 1069 | - . ' aria-label="' |
|
| 1070 | - . esc_attr__('View Event Espresso API docs', 'event_espresso') |
|
| 1071 | - . '">' |
|
| 1072 | - . esc_html__('API docs', 'event_espresso') |
|
| 1073 | - . '</a>', |
|
| 1074 | - ); |
|
| 1075 | - return array_merge($meta, $row_meta); |
|
| 1076 | - } |
|
| 1077 | - return (array) $meta; |
|
| 1078 | - } |
|
| 517 | + } |
|
| 518 | + |
|
| 519 | + |
|
| 520 | + /** |
|
| 521 | + * Returns an array of event archive nav items. |
|
| 522 | + * |
|
| 523 | + * @todo for now this method is just in place so when it gets abstracted further we can substitute in whatever |
|
| 524 | + * method we use for getting the extra nav menu items |
|
| 525 | + * @return array |
|
| 526 | + */ |
|
| 527 | + private function _get_extra_nav_menu_pages_items() |
|
| 528 | + { |
|
| 529 | + $menuitems[] = array( |
|
| 530 | + 'title' => esc_html__('Event List', 'event_espresso'), |
|
| 531 | + 'url' => get_post_type_archive_link('espresso_events'), |
|
| 532 | + 'description' => esc_html__('Archive page for all events.', 'event_espresso'), |
|
| 533 | + ); |
|
| 534 | + return apply_filters('FHEE__EE_Admin__get_extra_nav_menu_pages_items', $menuitems); |
|
| 535 | + } |
|
| 536 | + |
|
| 537 | + |
|
| 538 | + /** |
|
| 539 | + * Setup nav menu walker item for usage in the event archive nav menu metabox. It receives a menu_item array with |
|
| 540 | + * the properties and converts it to the menu item object. |
|
| 541 | + * |
|
| 542 | + * @see wp_setup_nav_menu_item() in wp-includes/nav-menu.php |
|
| 543 | + * @param $menu_item_values |
|
| 544 | + * @return stdClass |
|
| 545 | + */ |
|
| 546 | + private function _setup_extra_nav_menu_pages_items($menu_item_values) |
|
| 547 | + { |
|
| 548 | + $menu_item = new stdClass(); |
|
| 549 | + $keys = array( |
|
| 550 | + 'ID' => 0, |
|
| 551 | + 'db_id' => 0, |
|
| 552 | + 'menu_item_parent' => 0, |
|
| 553 | + 'object_id' => -1, |
|
| 554 | + 'post_parent' => 0, |
|
| 555 | + 'type' => 'custom', |
|
| 556 | + 'object' => '', |
|
| 557 | + 'type_label' => esc_html__('Extra Nav Menu Item', 'event_espresso'), |
|
| 558 | + 'title' => '', |
|
| 559 | + 'url' => '', |
|
| 560 | + 'target' => '', |
|
| 561 | + 'attr_title' => '', |
|
| 562 | + 'description' => '', |
|
| 563 | + 'classes' => array(), |
|
| 564 | + 'xfn' => '', |
|
| 565 | + ); |
|
| 566 | + |
|
| 567 | + foreach ($keys as $key => $value) { |
|
| 568 | + $menu_item->{$key} = isset($menu_item_values[ $key ]) ? $menu_item_values[ $key ] : $value; |
|
| 569 | + } |
|
| 570 | + return $menu_item; |
|
| 571 | + } |
|
| 572 | + |
|
| 573 | + |
|
| 574 | + /** |
|
| 575 | + * This is the action hook for the AHEE__EE_Admin_Page__route_admin_request hook that fires off right before an |
|
| 576 | + * EE_Admin_Page route is called. |
|
| 577 | + * |
|
| 578 | + * @return void |
|
| 579 | + */ |
|
| 580 | + public function route_admin_request() |
|
| 581 | + { |
|
| 582 | + } |
|
| 583 | + |
|
| 584 | + |
|
| 585 | + /** |
|
| 586 | + * wp_loaded should fire on the WordPress wp_loaded hook. This fires on a VERY late priority. |
|
| 587 | + * |
|
| 588 | + * @return void |
|
| 589 | + */ |
|
| 590 | + public function wp_loaded() |
|
| 591 | + { |
|
| 592 | + } |
|
| 593 | + |
|
| 594 | + |
|
| 595 | + /** |
|
| 596 | + * admin_init |
|
| 597 | + * |
|
| 598 | + * @return void |
|
| 599 | + * @throws EE_Error |
|
| 600 | + * @throws InvalidArgumentException |
|
| 601 | + * @throws InvalidDataTypeException |
|
| 602 | + * @throws InvalidInterfaceException |
|
| 603 | + * @throws ReflectionException |
|
| 604 | + */ |
|
| 605 | + public function admin_init() |
|
| 606 | + { |
|
| 607 | + /** |
|
| 608 | + * our cpt models must be instantiated on WordPress post processing routes (wp-admin/post.php), |
|
| 609 | + * so any hooking into core WP routes is taken care of. So in this next few lines of code: |
|
| 610 | + * - check if doing post processing. |
|
| 611 | + * - check if doing post processing of one of EE CPTs |
|
| 612 | + * - instantiate the corresponding EE CPT model for the post_type being processed. |
|
| 613 | + */ |
|
| 614 | + if (isset($_POST['action'], $_POST['post_type']) && $_POST['action'] === 'editpost') { |
|
| 615 | + /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */ |
|
| 616 | + $custom_post_types = $this->getLoader()->getShared( |
|
| 617 | + 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' |
|
| 618 | + ); |
|
| 619 | + $custom_post_types->getCustomPostTypeModels($_POST['post_type']); |
|
| 620 | + } |
|
| 621 | + |
|
| 622 | + |
|
| 623 | + /** |
|
| 624 | + * This code excludes EE critical pages anywhere `wp_dropdown_pages` is used to create a dropdown for selecting |
|
| 625 | + * critical pages. The only place critical pages need included in a generated dropdown is on the "Critical |
|
| 626 | + * Pages" tab in the EE General Settings Admin page. |
|
| 627 | + * This is for user-proofing. |
|
| 628 | + */ |
|
| 629 | + add_filter('wp_dropdown_pages', array($this, 'modify_dropdown_pages')); |
|
| 630 | + if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
| 631 | + $this->adminInitModelsReady(); |
|
| 632 | + } |
|
| 633 | + } |
|
| 634 | + |
|
| 635 | + |
|
| 636 | + /** |
|
| 637 | + * Runs on admin_init but only if models are usable (ie, we're not in maintenanc emode) |
|
| 638 | + */ |
|
| 639 | + protected function adminInitModelsReady() |
|
| 640 | + { |
|
| 641 | + if (function_exists('wp_add_privacy_policy_content')) { |
|
| 642 | + $this->getLoader()->getShared('EventEspresso\core\services\privacy\policy\PrivacyPolicyManager'); |
|
| 643 | + } |
|
| 644 | + } |
|
| 645 | + |
|
| 646 | + |
|
| 647 | + /** |
|
| 648 | + * Callback for wp_dropdown_pages hook to remove ee critical pages from the dropdown selection. |
|
| 649 | + * |
|
| 650 | + * @param string $output Current output. |
|
| 651 | + * @return string |
|
| 652 | + * @throws InvalidArgumentException |
|
| 653 | + * @throws InvalidDataTypeException |
|
| 654 | + * @throws InvalidInterfaceException |
|
| 655 | + */ |
|
| 656 | + public function modify_dropdown_pages($output) |
|
| 657 | + { |
|
| 658 | + // get critical pages |
|
| 659 | + $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
| 660 | + |
|
| 661 | + // split current output by line break for easier parsing. |
|
| 662 | + $split_output = explode("\n", $output); |
|
| 663 | + |
|
| 664 | + // loop through to remove any critical pages from the array. |
|
| 665 | + foreach ($critical_pages as $page_id) { |
|
| 666 | + $needle = 'value="' . $page_id . '"'; |
|
| 667 | + foreach ($split_output as $key => $haystack) { |
|
| 668 | + if (strpos($haystack, $needle) !== false) { |
|
| 669 | + unset($split_output[ $key ]); |
|
| 670 | + } |
|
| 671 | + } |
|
| 672 | + } |
|
| 673 | + // replace output with the new contents |
|
| 674 | + return implode("\n", $split_output); |
|
| 675 | + } |
|
| 676 | + |
|
| 677 | + |
|
| 678 | + /** |
|
| 679 | + * enqueue all admin scripts that need loaded for admin pages |
|
| 680 | + * |
|
| 681 | + * @return void |
|
| 682 | + */ |
|
| 683 | + public function enqueue_admin_scripts() |
|
| 684 | + { |
|
| 685 | + // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js. |
|
| 686 | + // Note: the intention of this script is to only do TARGETED injections. I.E, only injecting on certain script |
|
| 687 | + // calls. |
|
| 688 | + wp_enqueue_script( |
|
| 689 | + 'ee-inject-wp', |
|
| 690 | + EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
| 691 | + array('jquery'), |
|
| 692 | + EVENT_ESPRESSO_VERSION, |
|
| 693 | + true |
|
| 694 | + ); |
|
| 695 | + // register cookie script for future dependencies |
|
| 696 | + wp_register_script( |
|
| 697 | + 'jquery-cookie', |
|
| 698 | + EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
| 699 | + array('jquery'), |
|
| 700 | + '2.1', |
|
| 701 | + true |
|
| 702 | + ); |
|
| 703 | + // joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, can be turned back on again |
|
| 704 | + // via: add_filter('FHEE_load_joyride', '__return_true' ); |
|
| 705 | + if (apply_filters('FHEE_load_joyride', false)) { |
|
| 706 | + // joyride style |
|
| 707 | + wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1'); |
|
| 708 | + wp_register_style( |
|
| 709 | + 'ee-joyride-css', |
|
| 710 | + EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
| 711 | + array('joyride-css'), |
|
| 712 | + EVENT_ESPRESSO_VERSION |
|
| 713 | + ); |
|
| 714 | + wp_register_script( |
|
| 715 | + 'joyride-modernizr', |
|
| 716 | + EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
| 717 | + array(), |
|
| 718 | + '2.1', |
|
| 719 | + true |
|
| 720 | + ); |
|
| 721 | + // joyride JS |
|
| 722 | + wp_register_script( |
|
| 723 | + 'jquery-joyride', |
|
| 724 | + EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
| 725 | + array('jquery-cookie', 'joyride-modernizr'), |
|
| 726 | + '2.1', |
|
| 727 | + true |
|
| 728 | + ); |
|
| 729 | + // wanna go for a joyride? |
|
| 730 | + wp_enqueue_style('ee-joyride-css'); |
|
| 731 | + wp_enqueue_script('jquery-joyride'); |
|
| 732 | + } |
|
| 733 | + } |
|
| 734 | + |
|
| 735 | + |
|
| 736 | + /** |
|
| 737 | + * display_admin_notices |
|
| 738 | + * |
|
| 739 | + * @return void |
|
| 740 | + */ |
|
| 741 | + public function display_admin_notices() |
|
| 742 | + { |
|
| 743 | + echo EE_Error::get_notices(); |
|
| 744 | + } |
|
| 745 | + |
|
| 746 | + |
|
| 747 | + /** |
|
| 748 | + * @param array $elements |
|
| 749 | + * @return array |
|
| 750 | + * @throws EE_Error |
|
| 751 | + * @throws InvalidArgumentException |
|
| 752 | + * @throws InvalidDataTypeException |
|
| 753 | + * @throws InvalidInterfaceException |
|
| 754 | + */ |
|
| 755 | + public function dashboard_glance_items($elements) |
|
| 756 | + { |
|
| 757 | + $elements = is_array($elements) ? $elements : array($elements); |
|
| 758 | + $events = EEM_Event::instance()->count(); |
|
| 759 | + $items['events']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
| 760 | + array('page' => 'espresso_events'), |
|
| 761 | + admin_url('admin.php') |
|
| 762 | + ); |
|
| 763 | + $items['events']['text'] = sprintf( |
|
| 764 | + esc_html( |
|
| 765 | + _n('%s Event', '%s Events', $events, 'event_espresso') |
|
| 766 | + ), |
|
| 767 | + number_format_i18n($events) |
|
| 768 | + ); |
|
| 769 | + $items['events']['title'] = esc_html__('Click to view all Events', 'event_espresso'); |
|
| 770 | + $registrations = EEM_Registration::instance()->count( |
|
| 771 | + array( |
|
| 772 | + array( |
|
| 773 | + 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
| 774 | + ), |
|
| 775 | + ) |
|
| 776 | + ); |
|
| 777 | + $items['registrations']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
| 778 | + array('page' => 'espresso_registrations'), |
|
| 779 | + admin_url('admin.php') |
|
| 780 | + ); |
|
| 781 | + $items['registrations']['text'] = sprintf( |
|
| 782 | + esc_html( |
|
| 783 | + _n('%s Registration', '%s Registrations', $registrations, 'event_espresso') |
|
| 784 | + ), |
|
| 785 | + number_format_i18n($registrations) |
|
| 786 | + ); |
|
| 787 | + $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso'); |
|
| 788 | + |
|
| 789 | + $items = (array) apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items); |
|
| 790 | + |
|
| 791 | + foreach ($items as $type => $item_properties) { |
|
| 792 | + $elements[] = sprintf( |
|
| 793 | + '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>', |
|
| 794 | + $item_properties['url'], |
|
| 795 | + $item_properties['title'], |
|
| 796 | + $item_properties['text'] |
|
| 797 | + ); |
|
| 798 | + } |
|
| 799 | + return $elements; |
|
| 800 | + } |
|
| 801 | + |
|
| 802 | + |
|
| 803 | + /** |
|
| 804 | + * check_for_invalid_datetime_formats |
|
| 805 | + * if an admin changes their date or time format settings on the WP General Settings admin page, verify that |
|
| 806 | + * their selected format can be parsed by PHP |
|
| 807 | + * |
|
| 808 | + * @param $value |
|
| 809 | + * @param $option |
|
| 810 | + * @throws EE_Error |
|
| 811 | + * @return string |
|
| 812 | + */ |
|
| 813 | + public function check_for_invalid_datetime_formats($value, $option) |
|
| 814 | + { |
|
| 815 | + // check for date_format or time_format |
|
| 816 | + switch ($option) { |
|
| 817 | + case 'date_format': |
|
| 818 | + $date_time_format = $value . ' ' . get_option('time_format'); |
|
| 819 | + break; |
|
| 820 | + case 'time_format': |
|
| 821 | + $date_time_format = get_option('date_format') . ' ' . $value; |
|
| 822 | + break; |
|
| 823 | + default: |
|
| 824 | + $date_time_format = false; |
|
| 825 | + } |
|
| 826 | + // do we have a date_time format to check ? |
|
| 827 | + if ($date_time_format) { |
|
| 828 | + $error_msg = EEH_DTT_Helper::validate_format_string($date_time_format); |
|
| 829 | + |
|
| 830 | + if (is_array($error_msg)) { |
|
| 831 | + $msg = '<p>' |
|
| 832 | + . sprintf( |
|
| 833 | + esc_html__( |
|
| 834 | + 'The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:', |
|
| 835 | + 'event_espresso' |
|
| 836 | + ), |
|
| 837 | + date($date_time_format), |
|
| 838 | + $date_time_format |
|
| 839 | + ) |
|
| 840 | + . '</p><p><ul>'; |
|
| 841 | + |
|
| 842 | + |
|
| 843 | + foreach ($error_msg as $error) { |
|
| 844 | + $msg .= '<li>' . $error . '</li>'; |
|
| 845 | + } |
|
| 846 | + |
|
| 847 | + $msg .= '</ul></p><p>' |
|
| 848 | + . sprintf( |
|
| 849 | + esc_html__( |
|
| 850 | + '%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s', |
|
| 851 | + 'event_espresso' |
|
| 852 | + ), |
|
| 853 | + '<span style="color:#D54E21;">', |
|
| 854 | + '</span>' |
|
| 855 | + ) |
|
| 856 | + . '</p>'; |
|
| 857 | + |
|
| 858 | + // trigger WP settings error |
|
| 859 | + add_settings_error( |
|
| 860 | + 'date_format', |
|
| 861 | + 'date_format', |
|
| 862 | + $msg |
|
| 863 | + ); |
|
| 864 | + |
|
| 865 | + // set format to something valid |
|
| 866 | + switch ($option) { |
|
| 867 | + case 'date_format': |
|
| 868 | + $value = 'F j, Y'; |
|
| 869 | + break; |
|
| 870 | + case 'time_format': |
|
| 871 | + $value = 'g:i a'; |
|
| 872 | + break; |
|
| 873 | + } |
|
| 874 | + } |
|
| 875 | + } |
|
| 876 | + return $value; |
|
| 877 | + } |
|
| 878 | + |
|
| 879 | + |
|
| 880 | + /** |
|
| 881 | + * its_eSpresso - converts the less commonly used spelling of "Expresso" to "Espresso" |
|
| 882 | + * |
|
| 883 | + * @param $content |
|
| 884 | + * @return string |
|
| 885 | + */ |
|
| 886 | + public function its_eSpresso($content) |
|
| 887 | + { |
|
| 888 | + return str_replace('[EXPRESSO_', '[ESPRESSO_', $content); |
|
| 889 | + } |
|
| 890 | + |
|
| 891 | + |
|
| 892 | + /** |
|
| 893 | + * espresso_admin_footer |
|
| 894 | + * |
|
| 895 | + * @return string |
|
| 896 | + */ |
|
| 897 | + public function espresso_admin_footer() |
|
| 898 | + { |
|
| 899 | + return \EEH_Template::powered_by_event_espresso('aln-cntr', '', array('utm_content' => 'admin_footer')); |
|
| 900 | + } |
|
| 901 | + |
|
| 902 | + |
|
| 903 | + /** |
|
| 904 | + * static method for registering ee admin page. |
|
| 905 | + * This method is deprecated in favor of the new location in EE_Register_Admin_Page::register. |
|
| 906 | + * |
|
| 907 | + * @since 4.3.0 |
|
| 908 | + * @deprecated 4.3.0 Use EE_Register_Admin_Page::register() instead |
|
| 909 | + * @see EE_Register_Admin_Page::register() |
|
| 910 | + * @param $page_basename |
|
| 911 | + * @param $page_path |
|
| 912 | + * @param array $config |
|
| 913 | + * @return void |
|
| 914 | + * @throws EE_Error |
|
| 915 | + */ |
|
| 916 | + public static function register_ee_admin_page($page_basename, $page_path, $config = array()) |
|
| 917 | + { |
|
| 918 | + EE_Error::doing_it_wrong( |
|
| 919 | + __METHOD__, |
|
| 920 | + sprintf( |
|
| 921 | + esc_html__( |
|
| 922 | + 'Usage is deprecated. Use EE_Register_Admin_Page::register() for registering the %s admin page.', |
|
| 923 | + 'event_espresso' |
|
| 924 | + ), |
|
| 925 | + $page_basename |
|
| 926 | + ), |
|
| 927 | + '4.3' |
|
| 928 | + ); |
|
| 929 | + if (class_exists('EE_Register_Admin_Page')) { |
|
| 930 | + $config['page_path'] = $page_path; |
|
| 931 | + } |
|
| 932 | + EE_Register_Admin_Page::register($page_basename, $config); |
|
| 933 | + } |
|
| 934 | + |
|
| 935 | + |
|
| 936 | + /** |
|
| 937 | + * @deprecated 4.8.41 |
|
| 938 | + * @param int $post_ID |
|
| 939 | + * @param \WP_Post $post |
|
| 940 | + * @return void |
|
| 941 | + */ |
|
| 942 | + public static function parse_post_content_on_save($post_ID, $post) |
|
| 943 | + { |
|
| 944 | + EE_Error::doing_it_wrong( |
|
| 945 | + __METHOD__, |
|
| 946 | + esc_html__('Usage is deprecated', 'event_espresso'), |
|
| 947 | + '4.8.41' |
|
| 948 | + ); |
|
| 949 | + } |
|
| 950 | + |
|
| 951 | + |
|
| 952 | + /** |
|
| 953 | + * @deprecated 4.8.41 |
|
| 954 | + * @param $option |
|
| 955 | + * @param $old_value |
|
| 956 | + * @param $value |
|
| 957 | + * @return void |
|
| 958 | + */ |
|
| 959 | + public function reset_page_for_posts_on_change($option, $old_value, $value) |
|
| 960 | + { |
|
| 961 | + EE_Error::doing_it_wrong( |
|
| 962 | + __METHOD__, |
|
| 963 | + esc_html__('Usage is deprecated', 'event_espresso'), |
|
| 964 | + '4.8.41' |
|
| 965 | + ); |
|
| 966 | + } |
|
| 967 | + |
|
| 968 | + |
|
| 969 | + /** |
|
| 970 | + * @deprecated 4.9.27 |
|
| 971 | + * @return void |
|
| 972 | + */ |
|
| 973 | + public function get_persistent_admin_notices() |
|
| 974 | + { |
|
| 975 | + EE_Error::doing_it_wrong( |
|
| 976 | + __METHOD__, |
|
| 977 | + sprintf( |
|
| 978 | + esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
| 979 | + '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
| 980 | + ), |
|
| 981 | + '4.9.27' |
|
| 982 | + ); |
|
| 983 | + } |
|
| 984 | + |
|
| 985 | + |
|
| 986 | + /** |
|
| 987 | + * @deprecated 4.9.27 |
|
| 988 | + * @throws InvalidInterfaceException |
|
| 989 | + * @throws InvalidDataTypeException |
|
| 990 | + * @throws DomainException |
|
| 991 | + */ |
|
| 992 | + public function dismiss_ee_nag_notice_callback() |
|
| 993 | + { |
|
| 994 | + EE_Error::doing_it_wrong( |
|
| 995 | + __METHOD__, |
|
| 996 | + sprintf( |
|
| 997 | + esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
| 998 | + '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
| 999 | + ), |
|
| 1000 | + '4.9.27' |
|
| 1001 | + ); |
|
| 1002 | + $this->persistent_admin_notice_manager->dismissNotice(); |
|
| 1003 | + } |
|
| 1004 | + |
|
| 1005 | + |
|
| 1006 | + /** |
|
| 1007 | + * Callback on load-plugins.php hook for setting up anything hooking into the wp plugins page. |
|
| 1008 | + * |
|
| 1009 | + * @throws InvalidArgumentException |
|
| 1010 | + * @throws InvalidDataTypeException |
|
| 1011 | + * @throws InvalidInterfaceException |
|
| 1012 | + */ |
|
| 1013 | + public function hookIntoWpPluginsPage() |
|
| 1014 | + { |
|
| 1015 | + $this->getLoader()->getShared('EventEspresso\core\domain\services\admin\ExitModal'); |
|
| 1016 | + $this->getLoader() |
|
| 1017 | + ->getShared('EventEspresso\core\domain\services\admin\PluginUpsells') |
|
| 1018 | + ->decafUpsells(); |
|
| 1019 | + } |
|
| 1020 | + |
|
| 1021 | + |
|
| 1022 | + /** |
|
| 1023 | + * Hooks into the "post states" filter in a wp post type list table. |
|
| 1024 | + * |
|
| 1025 | + * @param array $post_states |
|
| 1026 | + * @param WP_Post $post |
|
| 1027 | + * @return array |
|
| 1028 | + * @throws InvalidArgumentException |
|
| 1029 | + * @throws InvalidDataTypeException |
|
| 1030 | + * @throws InvalidInterfaceException |
|
| 1031 | + */ |
|
| 1032 | + public function displayStateForCriticalPages($post_states, $post) |
|
| 1033 | + { |
|
| 1034 | + $post_states = (array) $post_states; |
|
| 1035 | + if (! $post instanceof WP_Post || $post->post_type !== 'page') { |
|
| 1036 | + return $post_states; |
|
| 1037 | + } |
|
| 1038 | + /** @var EE_Core_Config $config */ |
|
| 1039 | + $config = $this->getLoader()->getShared('EE_Config')->core; |
|
| 1040 | + if (in_array($post->ID, $config->get_critical_pages_array(), true)) { |
|
| 1041 | + $post_states[] = sprintf( |
|
| 1042 | + /* Translators: Using company name - Event Espresso Critical Page */ |
|
| 1043 | + esc_html__('%s Critical Page', 'event_espresso'), |
|
| 1044 | + 'Event Espresso' |
|
| 1045 | + ); |
|
| 1046 | + } |
|
| 1047 | + return $post_states; |
|
| 1048 | + } |
|
| 1049 | + |
|
| 1050 | + |
|
| 1051 | + /** |
|
| 1052 | + * Show documentation links on the plugins page |
|
| 1053 | + * |
|
| 1054 | + * @param mixed $meta Plugin Row Meta |
|
| 1055 | + * @param mixed $file Plugin Base file |
|
| 1056 | + * @return array |
|
| 1057 | + */ |
|
| 1058 | + public function addLinksToPluginRowMeta($meta, $file) |
|
| 1059 | + { |
|
| 1060 | + if (EE_PLUGIN_BASENAME === $file) { |
|
| 1061 | + $row_meta = array( |
|
| 1062 | + 'docs' => '<a href="https://eventespresso.com/support/documentation/versioned-docs/?doc_ver=ee4"' |
|
| 1063 | + . ' aria-label="' |
|
| 1064 | + . esc_attr__('View Event Espresso documentation', 'event_espresso') |
|
| 1065 | + . '">' |
|
| 1066 | + . esc_html__('Docs', 'event_espresso') |
|
| 1067 | + . '</a>', |
|
| 1068 | + 'api' => '<a href="https://github.com/eventespresso/event-espresso-core/tree/master/docs/C--REST-API"' |
|
| 1069 | + . ' aria-label="' |
|
| 1070 | + . esc_attr__('View Event Espresso API docs', 'event_espresso') |
|
| 1071 | + . '">' |
|
| 1072 | + . esc_html__('API docs', 'event_espresso') |
|
| 1073 | + . '</a>', |
|
| 1074 | + ); |
|
| 1075 | + return array_merge($meta, $row_meta); |
|
| 1076 | + } |
|
| 1077 | + return (array) $meta; |
|
| 1078 | + } |
|
| 1079 | 1079 | } |
@@ -24,1046 +24,1046 @@ |
||
| 24 | 24 | { |
| 25 | 25 | |
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * @var array |
|
| 29 | - */ |
|
| 30 | - private $_status; |
|
| 27 | + /** |
|
| 28 | + * @var array |
|
| 29 | + */ |
|
| 30 | + private $_status; |
|
| 31 | 31 | |
| 32 | 32 | |
| 33 | - /** |
|
| 34 | - * An array of transaction details for the related transaction to the registration being processed. |
|
| 35 | - * This is set via the _set_related_details method. |
|
| 36 | - * |
|
| 37 | - * @var array |
|
| 38 | - */ |
|
| 39 | - protected $_transaction_details = array(); |
|
| 33 | + /** |
|
| 34 | + * An array of transaction details for the related transaction to the registration being processed. |
|
| 35 | + * This is set via the _set_related_details method. |
|
| 36 | + * |
|
| 37 | + * @var array |
|
| 38 | + */ |
|
| 39 | + protected $_transaction_details = array(); |
|
| 40 | 40 | |
| 41 | 41 | |
| 42 | - /** |
|
| 43 | - * An array of event details for the related event to the registration being processed. |
|
| 44 | - * This is set via the _set_related_details method. |
|
| 45 | - * |
|
| 46 | - * @var array |
|
| 47 | - */ |
|
| 48 | - protected $_event_details = array(); |
|
| 42 | + /** |
|
| 43 | + * An array of event details for the related event to the registration being processed. |
|
| 44 | + * This is set via the _set_related_details method. |
|
| 45 | + * |
|
| 46 | + * @var array |
|
| 47 | + */ |
|
| 48 | + protected $_event_details = array(); |
|
| 49 | 49 | |
| 50 | 50 | |
| 51 | - /** |
|
| 52 | - * @param \Registrations_Admin_Page $admin_page |
|
| 53 | - */ |
|
| 54 | - public function __construct(Registrations_Admin_Page $admin_page) |
|
| 55 | - { |
|
| 56 | - if (! empty($_GET['event_id'])) { |
|
| 57 | - $extra_query_args = array(); |
|
| 58 | - foreach ($admin_page->get_views() as $key => $view_details) { |
|
| 59 | - $extra_query_args[ $view_details['slug'] ] = array('event_id' => $_GET['event_id']); |
|
| 60 | - } |
|
| 61 | - $this->_views = $admin_page->get_list_table_view_RLs($extra_query_args); |
|
| 62 | - } |
|
| 63 | - parent::__construct($admin_page); |
|
| 64 | - $this->_status = $this->_admin_page->get_registration_status_array(); |
|
| 65 | - } |
|
| 51 | + /** |
|
| 52 | + * @param \Registrations_Admin_Page $admin_page |
|
| 53 | + */ |
|
| 54 | + public function __construct(Registrations_Admin_Page $admin_page) |
|
| 55 | + { |
|
| 56 | + if (! empty($_GET['event_id'])) { |
|
| 57 | + $extra_query_args = array(); |
|
| 58 | + foreach ($admin_page->get_views() as $key => $view_details) { |
|
| 59 | + $extra_query_args[ $view_details['slug'] ] = array('event_id' => $_GET['event_id']); |
|
| 60 | + } |
|
| 61 | + $this->_views = $admin_page->get_list_table_view_RLs($extra_query_args); |
|
| 62 | + } |
|
| 63 | + parent::__construct($admin_page); |
|
| 64 | + $this->_status = $this->_admin_page->get_registration_status_array(); |
|
| 65 | + } |
|
| 66 | 66 | |
| 67 | 67 | |
| 68 | - /** |
|
| 69 | - * _setup_data |
|
| 70 | - * |
|
| 71 | - * @access protected |
|
| 72 | - * @return void |
|
| 73 | - */ |
|
| 74 | - protected function _setup_data() |
|
| 75 | - { |
|
| 76 | - $this->_data = $this->_admin_page->get_registrations($this->_per_page); |
|
| 77 | - $this->_all_data_count = $this->_admin_page->get_registrations($this->_per_page, true, false, false); |
|
| 78 | - } |
|
| 68 | + /** |
|
| 69 | + * _setup_data |
|
| 70 | + * |
|
| 71 | + * @access protected |
|
| 72 | + * @return void |
|
| 73 | + */ |
|
| 74 | + protected function _setup_data() |
|
| 75 | + { |
|
| 76 | + $this->_data = $this->_admin_page->get_registrations($this->_per_page); |
|
| 77 | + $this->_all_data_count = $this->_admin_page->get_registrations($this->_per_page, true, false, false); |
|
| 78 | + } |
|
| 79 | 79 | |
| 80 | 80 | |
| 81 | - /** |
|
| 82 | - * _set_properties |
|
| 83 | - * |
|
| 84 | - * @access protected |
|
| 85 | - * @return void |
|
| 86 | - */ |
|
| 87 | - protected function _set_properties() |
|
| 88 | - { |
|
| 89 | - $this->_wp_list_args = array( |
|
| 90 | - 'singular' => __('registration', 'event_espresso'), |
|
| 91 | - 'plural' => __('registrations', 'event_espresso'), |
|
| 92 | - 'ajax' => true, |
|
| 93 | - 'screen' => $this->_admin_page->get_current_screen()->id, |
|
| 94 | - ); |
|
| 95 | - $ID_column_name = __('ID', 'event_espresso'); |
|
| 96 | - $ID_column_name .= ' : <span class="show-on-mobile-view-only" style="float:none">'; |
|
| 97 | - $ID_column_name .= __('Registrant Name', 'event_espresso'); |
|
| 98 | - $ID_column_name .= '</span> '; |
|
| 99 | - if (isset($_GET['event_id'])) { |
|
| 100 | - $this->_columns = array( |
|
| 101 | - 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text |
|
| 102 | - '_REG_ID' => $ID_column_name, |
|
| 103 | - 'ATT_fname' => __('Name', 'event_espresso'), |
|
| 104 | - 'ATT_email' => __('Email', 'event_espresso'), |
|
| 105 | - '_REG_date' => __('Reg Date', 'event_espresso'), |
|
| 106 | - 'PRC_amount' => __('TKT Price', 'event_espresso'), |
|
| 107 | - '_REG_final_price' => __('Final Price', 'event_espresso'), |
|
| 108 | - 'TXN_total' => __('Total Txn', 'event_espresso'), |
|
| 109 | - 'TXN_paid' => __('Paid', 'event_espresso'), |
|
| 110 | - 'actions' => __('Actions', 'event_espresso'), |
|
| 111 | - ); |
|
| 112 | - $this->_bottom_buttons = array( |
|
| 113 | - 'report' => array( |
|
| 114 | - 'route' => 'registrations_report', |
|
| 115 | - 'extra_request' => array( |
|
| 116 | - 'EVT_ID' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 117 | - 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
| 118 | - ), |
|
| 119 | - ), |
|
| 120 | - ); |
|
| 121 | - } else { |
|
| 122 | - $this->_columns = array( |
|
| 123 | - 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text |
|
| 124 | - '_REG_ID' => $ID_column_name, |
|
| 125 | - 'ATT_fname' => __('Name', 'event_espresso'), |
|
| 126 | - '_REG_date' => __('TXN Date', 'event_espresso'), |
|
| 127 | - 'event_name' => __('Event', 'event_espresso'), |
|
| 128 | - 'DTT_EVT_start' => __('Event Date', 'event_espresso'), |
|
| 129 | - '_REG_final_price' => __('Price', 'event_espresso'), |
|
| 130 | - '_REG_paid' => __('Paid', 'event_espresso'), |
|
| 131 | - 'actions' => __('Actions', 'event_espresso'), |
|
| 132 | - ); |
|
| 133 | - $this->_bottom_buttons = array( |
|
| 134 | - 'report_all' => array( |
|
| 135 | - 'route' => 'registrations_report', |
|
| 136 | - 'extra_request' => array( |
|
| 137 | - 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
| 138 | - ), |
|
| 139 | - ), |
|
| 140 | - ); |
|
| 141 | - } |
|
| 142 | - $this->_bottom_buttons['report_filtered'] = array( |
|
| 143 | - 'route' => 'registrations_report', |
|
| 144 | - 'extra_request' => array( |
|
| 145 | - 'use_filters' => true, |
|
| 146 | - 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
| 147 | - ), |
|
| 148 | - ); |
|
| 149 | - $filters = array_diff_key( |
|
| 150 | - $this->_req_data, |
|
| 151 | - array_flip( |
|
| 152 | - array( |
|
| 153 | - 'page', |
|
| 154 | - 'action', |
|
| 155 | - 'default_nonce', |
|
| 156 | - ) |
|
| 157 | - ) |
|
| 158 | - ); |
|
| 159 | - if (!empty($filters)) { |
|
| 160 | - $this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters; |
|
| 161 | - } |
|
| 162 | - $this->_primary_column = '_REG_ID'; |
|
| 163 | - $this->_sortable_columns = array( |
|
| 164 | - '_REG_date' => array('_REG_date' => true), // true means its already sorted |
|
| 165 | - /** |
|
| 166 | - * Allows users to change the default sort if they wish. |
|
| 167 | - * Returning a falsey on this filter will result in the default sort to be by firstname rather than last |
|
| 168 | - * name. |
|
| 169 | - */ |
|
| 170 | - 'ATT_fname' => array( |
|
| 171 | - 'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name', |
|
| 172 | - true, |
|
| 173 | - $this, |
|
| 174 | - ) |
|
| 175 | - ? array('ATT_lname' => false) |
|
| 176 | - : array('ATT_fname' => false), |
|
| 177 | - 'event_name' => array('event_name' => false), |
|
| 178 | - 'DTT_EVT_start' => array('DTT_EVT_start' => false), |
|
| 179 | - '_REG_ID' => array('_REG_ID' => false), |
|
| 180 | - ); |
|
| 181 | - $this->_hidden_columns = array(); |
|
| 182 | - } |
|
| 81 | + /** |
|
| 82 | + * _set_properties |
|
| 83 | + * |
|
| 84 | + * @access protected |
|
| 85 | + * @return void |
|
| 86 | + */ |
|
| 87 | + protected function _set_properties() |
|
| 88 | + { |
|
| 89 | + $this->_wp_list_args = array( |
|
| 90 | + 'singular' => __('registration', 'event_espresso'), |
|
| 91 | + 'plural' => __('registrations', 'event_espresso'), |
|
| 92 | + 'ajax' => true, |
|
| 93 | + 'screen' => $this->_admin_page->get_current_screen()->id, |
|
| 94 | + ); |
|
| 95 | + $ID_column_name = __('ID', 'event_espresso'); |
|
| 96 | + $ID_column_name .= ' : <span class="show-on-mobile-view-only" style="float:none">'; |
|
| 97 | + $ID_column_name .= __('Registrant Name', 'event_espresso'); |
|
| 98 | + $ID_column_name .= '</span> '; |
|
| 99 | + if (isset($_GET['event_id'])) { |
|
| 100 | + $this->_columns = array( |
|
| 101 | + 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text |
|
| 102 | + '_REG_ID' => $ID_column_name, |
|
| 103 | + 'ATT_fname' => __('Name', 'event_espresso'), |
|
| 104 | + 'ATT_email' => __('Email', 'event_espresso'), |
|
| 105 | + '_REG_date' => __('Reg Date', 'event_espresso'), |
|
| 106 | + 'PRC_amount' => __('TKT Price', 'event_espresso'), |
|
| 107 | + '_REG_final_price' => __('Final Price', 'event_espresso'), |
|
| 108 | + 'TXN_total' => __('Total Txn', 'event_espresso'), |
|
| 109 | + 'TXN_paid' => __('Paid', 'event_espresso'), |
|
| 110 | + 'actions' => __('Actions', 'event_espresso'), |
|
| 111 | + ); |
|
| 112 | + $this->_bottom_buttons = array( |
|
| 113 | + 'report' => array( |
|
| 114 | + 'route' => 'registrations_report', |
|
| 115 | + 'extra_request' => array( |
|
| 116 | + 'EVT_ID' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 117 | + 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
| 118 | + ), |
|
| 119 | + ), |
|
| 120 | + ); |
|
| 121 | + } else { |
|
| 122 | + $this->_columns = array( |
|
| 123 | + 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text |
|
| 124 | + '_REG_ID' => $ID_column_name, |
|
| 125 | + 'ATT_fname' => __('Name', 'event_espresso'), |
|
| 126 | + '_REG_date' => __('TXN Date', 'event_espresso'), |
|
| 127 | + 'event_name' => __('Event', 'event_espresso'), |
|
| 128 | + 'DTT_EVT_start' => __('Event Date', 'event_espresso'), |
|
| 129 | + '_REG_final_price' => __('Price', 'event_espresso'), |
|
| 130 | + '_REG_paid' => __('Paid', 'event_espresso'), |
|
| 131 | + 'actions' => __('Actions', 'event_espresso'), |
|
| 132 | + ); |
|
| 133 | + $this->_bottom_buttons = array( |
|
| 134 | + 'report_all' => array( |
|
| 135 | + 'route' => 'registrations_report', |
|
| 136 | + 'extra_request' => array( |
|
| 137 | + 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
| 138 | + ), |
|
| 139 | + ), |
|
| 140 | + ); |
|
| 141 | + } |
|
| 142 | + $this->_bottom_buttons['report_filtered'] = array( |
|
| 143 | + 'route' => 'registrations_report', |
|
| 144 | + 'extra_request' => array( |
|
| 145 | + 'use_filters' => true, |
|
| 146 | + 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
| 147 | + ), |
|
| 148 | + ); |
|
| 149 | + $filters = array_diff_key( |
|
| 150 | + $this->_req_data, |
|
| 151 | + array_flip( |
|
| 152 | + array( |
|
| 153 | + 'page', |
|
| 154 | + 'action', |
|
| 155 | + 'default_nonce', |
|
| 156 | + ) |
|
| 157 | + ) |
|
| 158 | + ); |
|
| 159 | + if (!empty($filters)) { |
|
| 160 | + $this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters; |
|
| 161 | + } |
|
| 162 | + $this->_primary_column = '_REG_ID'; |
|
| 163 | + $this->_sortable_columns = array( |
|
| 164 | + '_REG_date' => array('_REG_date' => true), // true means its already sorted |
|
| 165 | + /** |
|
| 166 | + * Allows users to change the default sort if they wish. |
|
| 167 | + * Returning a falsey on this filter will result in the default sort to be by firstname rather than last |
|
| 168 | + * name. |
|
| 169 | + */ |
|
| 170 | + 'ATT_fname' => array( |
|
| 171 | + 'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name', |
|
| 172 | + true, |
|
| 173 | + $this, |
|
| 174 | + ) |
|
| 175 | + ? array('ATT_lname' => false) |
|
| 176 | + : array('ATT_fname' => false), |
|
| 177 | + 'event_name' => array('event_name' => false), |
|
| 178 | + 'DTT_EVT_start' => array('DTT_EVT_start' => false), |
|
| 179 | + '_REG_ID' => array('_REG_ID' => false), |
|
| 180 | + ); |
|
| 181 | + $this->_hidden_columns = array(); |
|
| 182 | + } |
|
| 183 | 183 | |
| 184 | 184 | |
| 185 | - /** |
|
| 186 | - * This simply sets up the row class for the table rows. |
|
| 187 | - * Allows for easier overriding of child methods for setting up sorting. |
|
| 188 | - * |
|
| 189 | - * @param EE_Registration $item the current item |
|
| 190 | - * @return string |
|
| 191 | - */ |
|
| 192 | - protected function _get_row_class($item) |
|
| 193 | - { |
|
| 194 | - $class = parent::_get_row_class($item); |
|
| 195 | - // add status class |
|
| 196 | - $class .= ' ee-status-strip reg-status-' . $item->status_ID(); |
|
| 197 | - if ($this->_has_checkbox_column) { |
|
| 198 | - $class .= ' has-checkbox-column'; |
|
| 199 | - } |
|
| 200 | - return $class; |
|
| 201 | - } |
|
| 185 | + /** |
|
| 186 | + * This simply sets up the row class for the table rows. |
|
| 187 | + * Allows for easier overriding of child methods for setting up sorting. |
|
| 188 | + * |
|
| 189 | + * @param EE_Registration $item the current item |
|
| 190 | + * @return string |
|
| 191 | + */ |
|
| 192 | + protected function _get_row_class($item) |
|
| 193 | + { |
|
| 194 | + $class = parent::_get_row_class($item); |
|
| 195 | + // add status class |
|
| 196 | + $class .= ' ee-status-strip reg-status-' . $item->status_ID(); |
|
| 197 | + if ($this->_has_checkbox_column) { |
|
| 198 | + $class .= ' has-checkbox-column'; |
|
| 199 | + } |
|
| 200 | + return $class; |
|
| 201 | + } |
|
| 202 | 202 | |
| 203 | 203 | |
| 204 | - /** |
|
| 205 | - * Set the $_transaction_details property if not set yet. |
|
| 206 | - * |
|
| 207 | - * @param EE_Registration $registration |
|
| 208 | - * @throws EE_Error |
|
| 209 | - * @throws InvalidArgumentException |
|
| 210 | - * @throws ReflectionException |
|
| 211 | - * @throws InvalidDataTypeException |
|
| 212 | - * @throws InvalidInterfaceException |
|
| 213 | - */ |
|
| 214 | - protected function _set_related_details(EE_Registration $registration) |
|
| 215 | - { |
|
| 216 | - $transaction = $registration->get_first_related('Transaction'); |
|
| 217 | - $status = $transaction instanceof EE_Transaction ? $transaction->status_ID() |
|
| 218 | - : EEM_Transaction::failed_status_code; |
|
| 219 | - $this->_transaction_details = array( |
|
| 220 | - 'transaction' => $transaction, |
|
| 221 | - 'status' => $status, |
|
| 222 | - 'id' => $transaction instanceof EE_Transaction ? $transaction->ID() : 0, |
|
| 223 | - 'title_attr' => sprintf( |
|
| 224 | - __('View Transaction Details (%s)', 'event_espresso'), |
|
| 225 | - EEH_Template::pretty_status($status, false, 'sentence') |
|
| 226 | - ), |
|
| 227 | - ); |
|
| 228 | - try { |
|
| 229 | - $event = $registration->event(); |
|
| 230 | - } catch (EntityNotFoundException $e) { |
|
| 231 | - $event = null; |
|
| 232 | - } |
|
| 233 | - $status = $event instanceof EE_Event ? $event->get_active_status() : EE_Datetime::inactive; |
|
| 234 | - $this->_event_details = array( |
|
| 235 | - 'event' => $event, |
|
| 236 | - 'status' => $status, |
|
| 237 | - 'id' => $event instanceof EE_Event ? $event->ID() : 0, |
|
| 238 | - 'title_attr' => sprintf( |
|
| 239 | - __('Edit Event (%s)', 'event_espresso'), |
|
| 240 | - EEH_Template::pretty_status($status, false, 'sentence') |
|
| 241 | - ), |
|
| 242 | - ); |
|
| 243 | - } |
|
| 204 | + /** |
|
| 205 | + * Set the $_transaction_details property if not set yet. |
|
| 206 | + * |
|
| 207 | + * @param EE_Registration $registration |
|
| 208 | + * @throws EE_Error |
|
| 209 | + * @throws InvalidArgumentException |
|
| 210 | + * @throws ReflectionException |
|
| 211 | + * @throws InvalidDataTypeException |
|
| 212 | + * @throws InvalidInterfaceException |
|
| 213 | + */ |
|
| 214 | + protected function _set_related_details(EE_Registration $registration) |
|
| 215 | + { |
|
| 216 | + $transaction = $registration->get_first_related('Transaction'); |
|
| 217 | + $status = $transaction instanceof EE_Transaction ? $transaction->status_ID() |
|
| 218 | + : EEM_Transaction::failed_status_code; |
|
| 219 | + $this->_transaction_details = array( |
|
| 220 | + 'transaction' => $transaction, |
|
| 221 | + 'status' => $status, |
|
| 222 | + 'id' => $transaction instanceof EE_Transaction ? $transaction->ID() : 0, |
|
| 223 | + 'title_attr' => sprintf( |
|
| 224 | + __('View Transaction Details (%s)', 'event_espresso'), |
|
| 225 | + EEH_Template::pretty_status($status, false, 'sentence') |
|
| 226 | + ), |
|
| 227 | + ); |
|
| 228 | + try { |
|
| 229 | + $event = $registration->event(); |
|
| 230 | + } catch (EntityNotFoundException $e) { |
|
| 231 | + $event = null; |
|
| 232 | + } |
|
| 233 | + $status = $event instanceof EE_Event ? $event->get_active_status() : EE_Datetime::inactive; |
|
| 234 | + $this->_event_details = array( |
|
| 235 | + 'event' => $event, |
|
| 236 | + 'status' => $status, |
|
| 237 | + 'id' => $event instanceof EE_Event ? $event->ID() : 0, |
|
| 238 | + 'title_attr' => sprintf( |
|
| 239 | + __('Edit Event (%s)', 'event_espresso'), |
|
| 240 | + EEH_Template::pretty_status($status, false, 'sentence') |
|
| 241 | + ), |
|
| 242 | + ); |
|
| 243 | + } |
|
| 244 | 244 | |
| 245 | 245 | |
| 246 | - /** |
|
| 247 | - * _get_table_filters |
|
| 248 | - * |
|
| 249 | - * @access protected |
|
| 250 | - * @return array |
|
| 251 | - */ |
|
| 252 | - protected function _get_table_filters() |
|
| 253 | - { |
|
| 254 | - $filters = array(); |
|
| 255 | - // todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as |
|
| 256 | - // methods. |
|
| 257 | - $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : ''; |
|
| 258 | - $cur_category = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1; |
|
| 259 | - $reg_status = isset($this->_req_data['_reg_status']) ? $this->_req_data['_reg_status'] : ''; |
|
| 260 | - $filters[] = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category); |
|
| 261 | - $filters[] = EEH_Form_Fields::generate_event_category_dropdown($cur_category); |
|
| 262 | - $status = array(); |
|
| 263 | - $status[] = array('id' => 0, 'text' => __('Select Status', 'event_espresso')); |
|
| 264 | - foreach ($this->_status as $key => $value) { |
|
| 265 | - $status[] = array('id' => $key, 'text' => $value); |
|
| 266 | - } |
|
| 267 | - if ($this->_view !== 'incomplete') { |
|
| 268 | - $filters[] = EEH_Form_Fields::select_input( |
|
| 269 | - '_reg_status', |
|
| 270 | - $status, |
|
| 271 | - isset($this->_req_data['_reg_status']) ? strtoupper(sanitize_key($this->_req_data['_reg_status'])) |
|
| 272 | - : '' |
|
| 273 | - ); |
|
| 274 | - } |
|
| 275 | - if (isset($this->_req_data['event_id'])) { |
|
| 276 | - $filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id'); |
|
| 277 | - } |
|
| 278 | - return $filters; |
|
| 279 | - } |
|
| 246 | + /** |
|
| 247 | + * _get_table_filters |
|
| 248 | + * |
|
| 249 | + * @access protected |
|
| 250 | + * @return array |
|
| 251 | + */ |
|
| 252 | + protected function _get_table_filters() |
|
| 253 | + { |
|
| 254 | + $filters = array(); |
|
| 255 | + // todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as |
|
| 256 | + // methods. |
|
| 257 | + $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : ''; |
|
| 258 | + $cur_category = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1; |
|
| 259 | + $reg_status = isset($this->_req_data['_reg_status']) ? $this->_req_data['_reg_status'] : ''; |
|
| 260 | + $filters[] = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category); |
|
| 261 | + $filters[] = EEH_Form_Fields::generate_event_category_dropdown($cur_category); |
|
| 262 | + $status = array(); |
|
| 263 | + $status[] = array('id' => 0, 'text' => __('Select Status', 'event_espresso')); |
|
| 264 | + foreach ($this->_status as $key => $value) { |
|
| 265 | + $status[] = array('id' => $key, 'text' => $value); |
|
| 266 | + } |
|
| 267 | + if ($this->_view !== 'incomplete') { |
|
| 268 | + $filters[] = EEH_Form_Fields::select_input( |
|
| 269 | + '_reg_status', |
|
| 270 | + $status, |
|
| 271 | + isset($this->_req_data['_reg_status']) ? strtoupper(sanitize_key($this->_req_data['_reg_status'])) |
|
| 272 | + : '' |
|
| 273 | + ); |
|
| 274 | + } |
|
| 275 | + if (isset($this->_req_data['event_id'])) { |
|
| 276 | + $filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id'); |
|
| 277 | + } |
|
| 278 | + return $filters; |
|
| 279 | + } |
|
| 280 | 280 | |
| 281 | 281 | |
| 282 | - /** |
|
| 283 | - * _add_view_counts |
|
| 284 | - * |
|
| 285 | - * @access protected |
|
| 286 | - * @return void |
|
| 287 | - * @throws EE_Error |
|
| 288 | - * @throws InvalidArgumentException |
|
| 289 | - * @throws InvalidDataTypeException |
|
| 290 | - * @throws InvalidInterfaceException |
|
| 291 | - */ |
|
| 292 | - protected function _add_view_counts() |
|
| 293 | - { |
|
| 294 | - $this->_views['all']['count'] = $this->_total_registrations(); |
|
| 295 | - $this->_views['month']['count'] = $this->_total_registrations_this_month(); |
|
| 296 | - $this->_views['today']['count'] = $this->_total_registrations_today(); |
|
| 297 | - if (EE_Registry::instance()->CAP->current_user_can( |
|
| 298 | - 'ee_delete_registrations', |
|
| 299 | - 'espresso_registrations_trash_registrations' |
|
| 300 | - )) { |
|
| 301 | - $this->_views['incomplete']['count'] = $this->_total_registrations('incomplete'); |
|
| 302 | - $this->_views['trash']['count'] = $this->_total_registrations('trash'); |
|
| 303 | - } |
|
| 304 | - } |
|
| 282 | + /** |
|
| 283 | + * _add_view_counts |
|
| 284 | + * |
|
| 285 | + * @access protected |
|
| 286 | + * @return void |
|
| 287 | + * @throws EE_Error |
|
| 288 | + * @throws InvalidArgumentException |
|
| 289 | + * @throws InvalidDataTypeException |
|
| 290 | + * @throws InvalidInterfaceException |
|
| 291 | + */ |
|
| 292 | + protected function _add_view_counts() |
|
| 293 | + { |
|
| 294 | + $this->_views['all']['count'] = $this->_total_registrations(); |
|
| 295 | + $this->_views['month']['count'] = $this->_total_registrations_this_month(); |
|
| 296 | + $this->_views['today']['count'] = $this->_total_registrations_today(); |
|
| 297 | + if (EE_Registry::instance()->CAP->current_user_can( |
|
| 298 | + 'ee_delete_registrations', |
|
| 299 | + 'espresso_registrations_trash_registrations' |
|
| 300 | + )) { |
|
| 301 | + $this->_views['incomplete']['count'] = $this->_total_registrations('incomplete'); |
|
| 302 | + $this->_views['trash']['count'] = $this->_total_registrations('trash'); |
|
| 303 | + } |
|
| 304 | + } |
|
| 305 | 305 | |
| 306 | 306 | |
| 307 | - /** |
|
| 308 | - * _total_registrations |
|
| 309 | - * |
|
| 310 | - * @access protected |
|
| 311 | - * @param string $view |
|
| 312 | - * @return int |
|
| 313 | - * @throws EE_Error |
|
| 314 | - * @throws InvalidArgumentException |
|
| 315 | - * @throws InvalidDataTypeException |
|
| 316 | - * @throws InvalidInterfaceException |
|
| 317 | - */ |
|
| 318 | - protected function _total_registrations($view = '') |
|
| 319 | - { |
|
| 320 | - $_where = array(); |
|
| 321 | - $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
| 322 | - if ($EVT_ID) { |
|
| 323 | - $_where['EVT_ID'] = $EVT_ID; |
|
| 324 | - } |
|
| 325 | - switch ($view) { |
|
| 326 | - case 'trash': |
|
| 327 | - return EEM_Registration::instance()->count_deleted(array($_where)); |
|
| 328 | - break; |
|
| 329 | - case 'incomplete': |
|
| 330 | - $_where['STS_ID'] = EEM_Registration::status_id_incomplete; |
|
| 331 | - break; |
|
| 332 | - default: |
|
| 333 | - $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete); |
|
| 334 | - } |
|
| 335 | - return EEM_Registration::instance()->count(array($_where)); |
|
| 336 | - } |
|
| 307 | + /** |
|
| 308 | + * _total_registrations |
|
| 309 | + * |
|
| 310 | + * @access protected |
|
| 311 | + * @param string $view |
|
| 312 | + * @return int |
|
| 313 | + * @throws EE_Error |
|
| 314 | + * @throws InvalidArgumentException |
|
| 315 | + * @throws InvalidDataTypeException |
|
| 316 | + * @throws InvalidInterfaceException |
|
| 317 | + */ |
|
| 318 | + protected function _total_registrations($view = '') |
|
| 319 | + { |
|
| 320 | + $_where = array(); |
|
| 321 | + $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
| 322 | + if ($EVT_ID) { |
|
| 323 | + $_where['EVT_ID'] = $EVT_ID; |
|
| 324 | + } |
|
| 325 | + switch ($view) { |
|
| 326 | + case 'trash': |
|
| 327 | + return EEM_Registration::instance()->count_deleted(array($_where)); |
|
| 328 | + break; |
|
| 329 | + case 'incomplete': |
|
| 330 | + $_where['STS_ID'] = EEM_Registration::status_id_incomplete; |
|
| 331 | + break; |
|
| 332 | + default: |
|
| 333 | + $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete); |
|
| 334 | + } |
|
| 335 | + return EEM_Registration::instance()->count(array($_where)); |
|
| 336 | + } |
|
| 337 | 337 | |
| 338 | 338 | |
| 339 | - /** |
|
| 340 | - * _total_registrations_this_month |
|
| 341 | - * |
|
| 342 | - * @access protected |
|
| 343 | - * @return int |
|
| 344 | - * @throws EE_Error |
|
| 345 | - * @throws InvalidArgumentException |
|
| 346 | - * @throws InvalidDataTypeException |
|
| 347 | - * @throws InvalidInterfaceException |
|
| 348 | - */ |
|
| 349 | - protected function _total_registrations_this_month() |
|
| 350 | - { |
|
| 351 | - $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
| 352 | - $_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array(); |
|
| 353 | - $this_year_r = date('Y', current_time('timestamp')); |
|
| 354 | - $time_start = ' 00:00:00'; |
|
| 355 | - $time_end = ' 23:59:59'; |
|
| 356 | - $this_month_r = date('m', current_time('timestamp')); |
|
| 357 | - $days_this_month = date('t', current_time('timestamp')); |
|
| 358 | - // setup date query. |
|
| 359 | - $beginning_string = EEM_Registration::instance()->convert_datetime_for_query( |
|
| 360 | - 'REG_date', |
|
| 361 | - $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start, |
|
| 362 | - 'Y-m-d H:i:s' |
|
| 363 | - ); |
|
| 364 | - $end_string = EEM_Registration::instance()->convert_datetime_for_query( |
|
| 365 | - 'REG_date', |
|
| 366 | - $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end, |
|
| 367 | - 'Y-m-d H:i:s' |
|
| 368 | - ); |
|
| 369 | - $_where['REG_date'] = array( |
|
| 370 | - 'BETWEEN', |
|
| 371 | - array( |
|
| 372 | - $beginning_string, |
|
| 373 | - $end_string, |
|
| 374 | - ), |
|
| 375 | - ); |
|
| 376 | - $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete); |
|
| 377 | - return EEM_Registration::instance()->count(array($_where)); |
|
| 378 | - } |
|
| 339 | + /** |
|
| 340 | + * _total_registrations_this_month |
|
| 341 | + * |
|
| 342 | + * @access protected |
|
| 343 | + * @return int |
|
| 344 | + * @throws EE_Error |
|
| 345 | + * @throws InvalidArgumentException |
|
| 346 | + * @throws InvalidDataTypeException |
|
| 347 | + * @throws InvalidInterfaceException |
|
| 348 | + */ |
|
| 349 | + protected function _total_registrations_this_month() |
|
| 350 | + { |
|
| 351 | + $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
| 352 | + $_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array(); |
|
| 353 | + $this_year_r = date('Y', current_time('timestamp')); |
|
| 354 | + $time_start = ' 00:00:00'; |
|
| 355 | + $time_end = ' 23:59:59'; |
|
| 356 | + $this_month_r = date('m', current_time('timestamp')); |
|
| 357 | + $days_this_month = date('t', current_time('timestamp')); |
|
| 358 | + // setup date query. |
|
| 359 | + $beginning_string = EEM_Registration::instance()->convert_datetime_for_query( |
|
| 360 | + 'REG_date', |
|
| 361 | + $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start, |
|
| 362 | + 'Y-m-d H:i:s' |
|
| 363 | + ); |
|
| 364 | + $end_string = EEM_Registration::instance()->convert_datetime_for_query( |
|
| 365 | + 'REG_date', |
|
| 366 | + $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end, |
|
| 367 | + 'Y-m-d H:i:s' |
|
| 368 | + ); |
|
| 369 | + $_where['REG_date'] = array( |
|
| 370 | + 'BETWEEN', |
|
| 371 | + array( |
|
| 372 | + $beginning_string, |
|
| 373 | + $end_string, |
|
| 374 | + ), |
|
| 375 | + ); |
|
| 376 | + $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete); |
|
| 377 | + return EEM_Registration::instance()->count(array($_where)); |
|
| 378 | + } |
|
| 379 | 379 | |
| 380 | 380 | |
| 381 | - /** |
|
| 382 | - * _total_registrations_today |
|
| 383 | - * |
|
| 384 | - * @access protected |
|
| 385 | - * @return int |
|
| 386 | - * @throws EE_Error |
|
| 387 | - * @throws InvalidArgumentException |
|
| 388 | - * @throws InvalidDataTypeException |
|
| 389 | - * @throws InvalidInterfaceException |
|
| 390 | - */ |
|
| 391 | - protected function _total_registrations_today() |
|
| 392 | - { |
|
| 393 | - $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
| 394 | - $_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array(); |
|
| 395 | - $current_date = date('Y-m-d', current_time('timestamp')); |
|
| 396 | - $time_start = ' 00:00:00'; |
|
| 397 | - $time_end = ' 23:59:59'; |
|
| 398 | - $_where['REG_date'] = array( |
|
| 399 | - 'BETWEEN', |
|
| 400 | - array( |
|
| 401 | - EEM_Registration::instance()->convert_datetime_for_query( |
|
| 402 | - 'REG_date', |
|
| 403 | - $current_date . $time_start, |
|
| 404 | - 'Y-m-d H:i:s' |
|
| 405 | - ), |
|
| 406 | - EEM_Registration::instance()->convert_datetime_for_query( |
|
| 407 | - 'REG_date', |
|
| 408 | - $current_date . $time_end, |
|
| 409 | - 'Y-m-d H:i:s' |
|
| 410 | - ), |
|
| 411 | - ), |
|
| 412 | - ); |
|
| 413 | - $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete); |
|
| 414 | - return EEM_Registration::instance()->count(array($_where)); |
|
| 415 | - } |
|
| 381 | + /** |
|
| 382 | + * _total_registrations_today |
|
| 383 | + * |
|
| 384 | + * @access protected |
|
| 385 | + * @return int |
|
| 386 | + * @throws EE_Error |
|
| 387 | + * @throws InvalidArgumentException |
|
| 388 | + * @throws InvalidDataTypeException |
|
| 389 | + * @throws InvalidInterfaceException |
|
| 390 | + */ |
|
| 391 | + protected function _total_registrations_today() |
|
| 392 | + { |
|
| 393 | + $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
| 394 | + $_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array(); |
|
| 395 | + $current_date = date('Y-m-d', current_time('timestamp')); |
|
| 396 | + $time_start = ' 00:00:00'; |
|
| 397 | + $time_end = ' 23:59:59'; |
|
| 398 | + $_where['REG_date'] = array( |
|
| 399 | + 'BETWEEN', |
|
| 400 | + array( |
|
| 401 | + EEM_Registration::instance()->convert_datetime_for_query( |
|
| 402 | + 'REG_date', |
|
| 403 | + $current_date . $time_start, |
|
| 404 | + 'Y-m-d H:i:s' |
|
| 405 | + ), |
|
| 406 | + EEM_Registration::instance()->convert_datetime_for_query( |
|
| 407 | + 'REG_date', |
|
| 408 | + $current_date . $time_end, |
|
| 409 | + 'Y-m-d H:i:s' |
|
| 410 | + ), |
|
| 411 | + ), |
|
| 412 | + ); |
|
| 413 | + $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete); |
|
| 414 | + return EEM_Registration::instance()->count(array($_where)); |
|
| 415 | + } |
|
| 416 | 416 | |
| 417 | 417 | |
| 418 | - /** |
|
| 419 | - * column_cb |
|
| 420 | - * |
|
| 421 | - * @access public |
|
| 422 | - * @param \EE_Registration $item |
|
| 423 | - * @return string |
|
| 424 | - * @throws EE_Error |
|
| 425 | - * @throws InvalidArgumentException |
|
| 426 | - * @throws InvalidDataTypeException |
|
| 427 | - * @throws InvalidInterfaceException |
|
| 428 | - * @throws ReflectionException |
|
| 429 | - */ |
|
| 430 | - public function column_cb($item) |
|
| 431 | - { |
|
| 432 | - /** checkbox/lock **/ |
|
| 433 | - $transaction = $item->get_first_related('Transaction'); |
|
| 434 | - $payment_count = $transaction instanceof EE_Transaction |
|
| 435 | - ? $transaction->count_related('Payment') |
|
| 436 | - : 0; |
|
| 437 | - return $payment_count > 0 |
|
| 438 | - || ! EE_Registry::instance()->CAP->current_user_can( |
|
| 439 | - 'ee_edit_registration', |
|
| 440 | - 'registration_list_table_checkbox_input', |
|
| 441 | - $item->ID() |
|
| 442 | - ) |
|
| 443 | - ? sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID()) |
|
| 444 | - . '<span class="ee-lock-icon"></span>' |
|
| 445 | - : sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID()); |
|
| 446 | - } |
|
| 418 | + /** |
|
| 419 | + * column_cb |
|
| 420 | + * |
|
| 421 | + * @access public |
|
| 422 | + * @param \EE_Registration $item |
|
| 423 | + * @return string |
|
| 424 | + * @throws EE_Error |
|
| 425 | + * @throws InvalidArgumentException |
|
| 426 | + * @throws InvalidDataTypeException |
|
| 427 | + * @throws InvalidInterfaceException |
|
| 428 | + * @throws ReflectionException |
|
| 429 | + */ |
|
| 430 | + public function column_cb($item) |
|
| 431 | + { |
|
| 432 | + /** checkbox/lock **/ |
|
| 433 | + $transaction = $item->get_first_related('Transaction'); |
|
| 434 | + $payment_count = $transaction instanceof EE_Transaction |
|
| 435 | + ? $transaction->count_related('Payment') |
|
| 436 | + : 0; |
|
| 437 | + return $payment_count > 0 |
|
| 438 | + || ! EE_Registry::instance()->CAP->current_user_can( |
|
| 439 | + 'ee_edit_registration', |
|
| 440 | + 'registration_list_table_checkbox_input', |
|
| 441 | + $item->ID() |
|
| 442 | + ) |
|
| 443 | + ? sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID()) |
|
| 444 | + . '<span class="ee-lock-icon"></span>' |
|
| 445 | + : sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID()); |
|
| 446 | + } |
|
| 447 | 447 | |
| 448 | 448 | |
| 449 | - /** |
|
| 450 | - * column__REG_ID |
|
| 451 | - * |
|
| 452 | - * @access public |
|
| 453 | - * @param \EE_Registration $item |
|
| 454 | - * @return string |
|
| 455 | - * @throws EE_Error |
|
| 456 | - * @throws InvalidArgumentException |
|
| 457 | - * @throws InvalidDataTypeException |
|
| 458 | - * @throws InvalidInterfaceException |
|
| 459 | - * @throws ReflectionException |
|
| 460 | - */ |
|
| 461 | - public function column__REG_ID(EE_Registration $item) |
|
| 462 | - { |
|
| 463 | - $attendee = $item->attendee(); |
|
| 464 | - $content = $item->ID(); |
|
| 465 | - $content .= '<div class="show-on-mobile-view-only">'; |
|
| 466 | - $content .= '<br>'; |
|
| 467 | - $content .= $attendee instanceof EE_Attendee ? $attendee->full_name() : ''; |
|
| 468 | - $content .= ' ' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 469 | - $content .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 470 | - $content .= '</div>'; |
|
| 471 | - return $content; |
|
| 472 | - } |
|
| 449 | + /** |
|
| 450 | + * column__REG_ID |
|
| 451 | + * |
|
| 452 | + * @access public |
|
| 453 | + * @param \EE_Registration $item |
|
| 454 | + * @return string |
|
| 455 | + * @throws EE_Error |
|
| 456 | + * @throws InvalidArgumentException |
|
| 457 | + * @throws InvalidDataTypeException |
|
| 458 | + * @throws InvalidInterfaceException |
|
| 459 | + * @throws ReflectionException |
|
| 460 | + */ |
|
| 461 | + public function column__REG_ID(EE_Registration $item) |
|
| 462 | + { |
|
| 463 | + $attendee = $item->attendee(); |
|
| 464 | + $content = $item->ID(); |
|
| 465 | + $content .= '<div class="show-on-mobile-view-only">'; |
|
| 466 | + $content .= '<br>'; |
|
| 467 | + $content .= $attendee instanceof EE_Attendee ? $attendee->full_name() : ''; |
|
| 468 | + $content .= ' ' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 469 | + $content .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 470 | + $content .= '</div>'; |
|
| 471 | + return $content; |
|
| 472 | + } |
|
| 473 | 473 | |
| 474 | 474 | |
| 475 | - /** |
|
| 476 | - * column__REG_date |
|
| 477 | - * |
|
| 478 | - * @access public |
|
| 479 | - * @param \EE_Registration $item |
|
| 480 | - * @return string |
|
| 481 | - * @throws EE_Error |
|
| 482 | - * @throws InvalidArgumentException |
|
| 483 | - * @throws InvalidDataTypeException |
|
| 484 | - * @throws InvalidInterfaceException |
|
| 485 | - * @throws ReflectionException |
|
| 486 | - */ |
|
| 487 | - public function column__REG_date(EE_Registration $item) |
|
| 488 | - { |
|
| 489 | - $this->_set_related_details($item); |
|
| 490 | - // Build row actions |
|
| 491 | - $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 492 | - array( |
|
| 493 | - 'action' => 'view_transaction', |
|
| 494 | - 'TXN_ID' => $this->_transaction_details['id'], |
|
| 495 | - ), |
|
| 496 | - TXN_ADMIN_URL |
|
| 497 | - ); |
|
| 498 | - $view_link = EE_Registry::instance()->CAP->current_user_can( |
|
| 499 | - 'ee_read_transaction', |
|
| 500 | - 'espresso_transactions_view_transaction' |
|
| 501 | - ) |
|
| 502 | - ? '<a class="ee-status-color-' |
|
| 503 | - . $this->_transaction_details['status'] |
|
| 504 | - . '" href="' |
|
| 505 | - . $view_lnk_url |
|
| 506 | - . '" title="' |
|
| 507 | - . esc_attr($this->_transaction_details['title_attr']) |
|
| 508 | - . '">' |
|
| 509 | - . $item->get_i18n_datetime('REG_date') |
|
| 510 | - . '</a>' : $item->get_i18n_datetime('REG_date'); |
|
| 511 | - $view_link .= '<br><span class="ee-status-text-small">' |
|
| 512 | - . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence') |
|
| 513 | - . '</span>'; |
|
| 514 | - return $view_link; |
|
| 515 | - } |
|
| 475 | + /** |
|
| 476 | + * column__REG_date |
|
| 477 | + * |
|
| 478 | + * @access public |
|
| 479 | + * @param \EE_Registration $item |
|
| 480 | + * @return string |
|
| 481 | + * @throws EE_Error |
|
| 482 | + * @throws InvalidArgumentException |
|
| 483 | + * @throws InvalidDataTypeException |
|
| 484 | + * @throws InvalidInterfaceException |
|
| 485 | + * @throws ReflectionException |
|
| 486 | + */ |
|
| 487 | + public function column__REG_date(EE_Registration $item) |
|
| 488 | + { |
|
| 489 | + $this->_set_related_details($item); |
|
| 490 | + // Build row actions |
|
| 491 | + $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 492 | + array( |
|
| 493 | + 'action' => 'view_transaction', |
|
| 494 | + 'TXN_ID' => $this->_transaction_details['id'], |
|
| 495 | + ), |
|
| 496 | + TXN_ADMIN_URL |
|
| 497 | + ); |
|
| 498 | + $view_link = EE_Registry::instance()->CAP->current_user_can( |
|
| 499 | + 'ee_read_transaction', |
|
| 500 | + 'espresso_transactions_view_transaction' |
|
| 501 | + ) |
|
| 502 | + ? '<a class="ee-status-color-' |
|
| 503 | + . $this->_transaction_details['status'] |
|
| 504 | + . '" href="' |
|
| 505 | + . $view_lnk_url |
|
| 506 | + . '" title="' |
|
| 507 | + . esc_attr($this->_transaction_details['title_attr']) |
|
| 508 | + . '">' |
|
| 509 | + . $item->get_i18n_datetime('REG_date') |
|
| 510 | + . '</a>' : $item->get_i18n_datetime('REG_date'); |
|
| 511 | + $view_link .= '<br><span class="ee-status-text-small">' |
|
| 512 | + . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence') |
|
| 513 | + . '</span>'; |
|
| 514 | + return $view_link; |
|
| 515 | + } |
|
| 516 | 516 | |
| 517 | 517 | |
| 518 | - /** |
|
| 519 | - * column_event_name |
|
| 520 | - * |
|
| 521 | - * @access public |
|
| 522 | - * @param \EE_Registration $item |
|
| 523 | - * @return string |
|
| 524 | - * @throws EE_Error |
|
| 525 | - * @throws InvalidArgumentException |
|
| 526 | - * @throws InvalidDataTypeException |
|
| 527 | - * @throws InvalidInterfaceException |
|
| 528 | - * @throws ReflectionException |
|
| 529 | - */ |
|
| 530 | - public function column_event_name(EE_Registration $item) |
|
| 531 | - { |
|
| 532 | - $this->_set_related_details($item); |
|
| 533 | - // page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62 |
|
| 534 | - $EVT_ID = $item->event_ID(); |
|
| 535 | - $event_name = $item->event_name(); |
|
| 536 | - $event_name = $event_name ? $event_name : __("No Associated Event", 'event_espresso'); |
|
| 537 | - $event_name = wp_trim_words($event_name, 30, '...'); |
|
| 538 | - if ($EVT_ID) { |
|
| 539 | - $edit_event_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 540 | - array('action' => 'edit', 'post' => $EVT_ID), |
|
| 541 | - EVENTS_ADMIN_URL |
|
| 542 | - ); |
|
| 543 | - $edit_event = EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID) |
|
| 544 | - ? '<a class="ee-status-color-' |
|
| 545 | - . $this->_event_details['status'] |
|
| 546 | - . '" href="' |
|
| 547 | - . $edit_event_url |
|
| 548 | - . '" title="' |
|
| 549 | - . esc_attr($this->_event_details['title_attr']) |
|
| 550 | - . '">' |
|
| 551 | - . $event_name |
|
| 552 | - . '</a>' : $event_name; |
|
| 553 | - $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(array('event_id' => $EVT_ID), REG_ADMIN_URL); |
|
| 554 | - $actions['event_filter'] = '<a href="' . $edit_event_url . '" title="'; |
|
| 555 | - $actions['event_filter'] .= sprintf( |
|
| 556 | - esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'), |
|
| 557 | - $event_name |
|
| 558 | - ); |
|
| 559 | - $actions['event_filter'] .= '">' . __('View Registrations', 'event_espresso') . '</a>'; |
|
| 560 | - } else { |
|
| 561 | - $edit_event = $event_name; |
|
| 562 | - $actions['event_filter'] = ''; |
|
| 563 | - } |
|
| 564 | - return sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions)); |
|
| 565 | - } |
|
| 518 | + /** |
|
| 519 | + * column_event_name |
|
| 520 | + * |
|
| 521 | + * @access public |
|
| 522 | + * @param \EE_Registration $item |
|
| 523 | + * @return string |
|
| 524 | + * @throws EE_Error |
|
| 525 | + * @throws InvalidArgumentException |
|
| 526 | + * @throws InvalidDataTypeException |
|
| 527 | + * @throws InvalidInterfaceException |
|
| 528 | + * @throws ReflectionException |
|
| 529 | + */ |
|
| 530 | + public function column_event_name(EE_Registration $item) |
|
| 531 | + { |
|
| 532 | + $this->_set_related_details($item); |
|
| 533 | + // page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62 |
|
| 534 | + $EVT_ID = $item->event_ID(); |
|
| 535 | + $event_name = $item->event_name(); |
|
| 536 | + $event_name = $event_name ? $event_name : __("No Associated Event", 'event_espresso'); |
|
| 537 | + $event_name = wp_trim_words($event_name, 30, '...'); |
|
| 538 | + if ($EVT_ID) { |
|
| 539 | + $edit_event_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 540 | + array('action' => 'edit', 'post' => $EVT_ID), |
|
| 541 | + EVENTS_ADMIN_URL |
|
| 542 | + ); |
|
| 543 | + $edit_event = EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID) |
|
| 544 | + ? '<a class="ee-status-color-' |
|
| 545 | + . $this->_event_details['status'] |
|
| 546 | + . '" href="' |
|
| 547 | + . $edit_event_url |
|
| 548 | + . '" title="' |
|
| 549 | + . esc_attr($this->_event_details['title_attr']) |
|
| 550 | + . '">' |
|
| 551 | + . $event_name |
|
| 552 | + . '</a>' : $event_name; |
|
| 553 | + $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(array('event_id' => $EVT_ID), REG_ADMIN_URL); |
|
| 554 | + $actions['event_filter'] = '<a href="' . $edit_event_url . '" title="'; |
|
| 555 | + $actions['event_filter'] .= sprintf( |
|
| 556 | + esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'), |
|
| 557 | + $event_name |
|
| 558 | + ); |
|
| 559 | + $actions['event_filter'] .= '">' . __('View Registrations', 'event_espresso') . '</a>'; |
|
| 560 | + } else { |
|
| 561 | + $edit_event = $event_name; |
|
| 562 | + $actions['event_filter'] = ''; |
|
| 563 | + } |
|
| 564 | + return sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions)); |
|
| 565 | + } |
|
| 566 | 566 | |
| 567 | 567 | |
| 568 | - /** |
|
| 569 | - * column_DTT_EVT_start |
|
| 570 | - * |
|
| 571 | - * @access public |
|
| 572 | - * @param \EE_Registration $item |
|
| 573 | - * @return string |
|
| 574 | - * @throws EE_Error |
|
| 575 | - * @throws InvalidArgumentException |
|
| 576 | - * @throws InvalidDataTypeException |
|
| 577 | - * @throws InvalidInterfaceException |
|
| 578 | - * @throws ReflectionException |
|
| 579 | - */ |
|
| 580 | - public function column_DTT_EVT_start(EE_Registration $item) |
|
| 581 | - { |
|
| 582 | - $datetime_strings = array(); |
|
| 583 | - $ticket = $item->ticket(true); |
|
| 584 | - if ($ticket instanceof EE_Ticket) { |
|
| 585 | - $remove_defaults = array('default_where_conditions' => 'none'); |
|
| 586 | - $datetimes = $ticket->datetimes($remove_defaults); |
|
| 587 | - foreach ($datetimes as $datetime) { |
|
| 588 | - $datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start'); |
|
| 589 | - } |
|
| 590 | - return $this->generateDisplayForDatetimes($datetime_strings); |
|
| 591 | - } |
|
| 592 | - return __('There is no ticket on this registration', 'event_espresso'); |
|
| 593 | - } |
|
| 568 | + /** |
|
| 569 | + * column_DTT_EVT_start |
|
| 570 | + * |
|
| 571 | + * @access public |
|
| 572 | + * @param \EE_Registration $item |
|
| 573 | + * @return string |
|
| 574 | + * @throws EE_Error |
|
| 575 | + * @throws InvalidArgumentException |
|
| 576 | + * @throws InvalidDataTypeException |
|
| 577 | + * @throws InvalidInterfaceException |
|
| 578 | + * @throws ReflectionException |
|
| 579 | + */ |
|
| 580 | + public function column_DTT_EVT_start(EE_Registration $item) |
|
| 581 | + { |
|
| 582 | + $datetime_strings = array(); |
|
| 583 | + $ticket = $item->ticket(true); |
|
| 584 | + if ($ticket instanceof EE_Ticket) { |
|
| 585 | + $remove_defaults = array('default_where_conditions' => 'none'); |
|
| 586 | + $datetimes = $ticket->datetimes($remove_defaults); |
|
| 587 | + foreach ($datetimes as $datetime) { |
|
| 588 | + $datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start'); |
|
| 589 | + } |
|
| 590 | + return $this->generateDisplayForDatetimes($datetime_strings); |
|
| 591 | + } |
|
| 592 | + return __('There is no ticket on this registration', 'event_espresso'); |
|
| 593 | + } |
|
| 594 | 594 | |
| 595 | 595 | |
| 596 | - /** |
|
| 597 | - * Receives an array of datetime strings to display and converts them to the html container for the column. |
|
| 598 | - * |
|
| 599 | - * @param array $datetime_strings |
|
| 600 | - * @return string |
|
| 601 | - */ |
|
| 602 | - public function generateDisplayForDateTimes(array $datetime_strings) |
|
| 603 | - { |
|
| 604 | - $content = '<div class="ee-registration-event-datetimes-container">'; |
|
| 605 | - $expand_toggle = count($datetime_strings) > 1 |
|
| 606 | - ? ' <span title="' . esc_attr__('Click to view all dates', 'event_espresso') |
|
| 607 | - . '" class="ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>' |
|
| 608 | - : ''; |
|
| 609 | - // get first item for initial visibility |
|
| 610 | - $content .= '<div class="left">' . array_shift($datetime_strings) . '</div>'; |
|
| 611 | - $content .= $expand_toggle; |
|
| 612 | - if ($datetime_strings) { |
|
| 613 | - $content .= '<div style="clear:both"></div>'; |
|
| 614 | - $content .= '<div class="ee-registration-event-datetimes-container more-items hidden">'; |
|
| 615 | - $content .= implode("<br />", $datetime_strings); |
|
| 616 | - $content .= '</div>'; |
|
| 617 | - } |
|
| 618 | - $content .= '</div>'; |
|
| 619 | - return $content; |
|
| 620 | - } |
|
| 596 | + /** |
|
| 597 | + * Receives an array of datetime strings to display and converts them to the html container for the column. |
|
| 598 | + * |
|
| 599 | + * @param array $datetime_strings |
|
| 600 | + * @return string |
|
| 601 | + */ |
|
| 602 | + public function generateDisplayForDateTimes(array $datetime_strings) |
|
| 603 | + { |
|
| 604 | + $content = '<div class="ee-registration-event-datetimes-container">'; |
|
| 605 | + $expand_toggle = count($datetime_strings) > 1 |
|
| 606 | + ? ' <span title="' . esc_attr__('Click to view all dates', 'event_espresso') |
|
| 607 | + . '" class="ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>' |
|
| 608 | + : ''; |
|
| 609 | + // get first item for initial visibility |
|
| 610 | + $content .= '<div class="left">' . array_shift($datetime_strings) . '</div>'; |
|
| 611 | + $content .= $expand_toggle; |
|
| 612 | + if ($datetime_strings) { |
|
| 613 | + $content .= '<div style="clear:both"></div>'; |
|
| 614 | + $content .= '<div class="ee-registration-event-datetimes-container more-items hidden">'; |
|
| 615 | + $content .= implode("<br />", $datetime_strings); |
|
| 616 | + $content .= '</div>'; |
|
| 617 | + } |
|
| 618 | + $content .= '</div>'; |
|
| 619 | + return $content; |
|
| 620 | + } |
|
| 621 | 621 | |
| 622 | 622 | |
| 623 | - /** |
|
| 624 | - * column_ATT_fname |
|
| 625 | - * |
|
| 626 | - * @access public |
|
| 627 | - * @param \EE_Registration $item |
|
| 628 | - * @return string |
|
| 629 | - * @throws EE_Error |
|
| 630 | - * @throws InvalidArgumentException |
|
| 631 | - * @throws InvalidDataTypeException |
|
| 632 | - * @throws InvalidInterfaceException |
|
| 633 | - * @throws ReflectionException |
|
| 634 | - */ |
|
| 635 | - public function column_ATT_fname(EE_Registration $item) |
|
| 636 | - { |
|
| 637 | - $attendee = $item->attendee(); |
|
| 638 | - $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 639 | - array( |
|
| 640 | - 'action' => 'view_registration', |
|
| 641 | - '_REG_ID' => $item->ID(), |
|
| 642 | - ), |
|
| 643 | - REG_ADMIN_URL |
|
| 644 | - ); |
|
| 645 | - $attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : ''; |
|
| 646 | - $link = EE_Registry::instance()->CAP->current_user_can( |
|
| 647 | - 'ee_read_registration', |
|
| 648 | - 'espresso_registrations_view_registration', |
|
| 649 | - $item->ID() |
|
| 650 | - ) |
|
| 651 | - ? '<a href="' |
|
| 652 | - . $edit_lnk_url |
|
| 653 | - . '" title="' |
|
| 654 | - . esc_attr__('View Registration Details', 'event_espresso') |
|
| 655 | - . '">' |
|
| 656 | - . $attendee_name |
|
| 657 | - . '</a>' : $attendee_name; |
|
| 658 | - $link .= $item->count() === 1 |
|
| 659 | - ? ' <sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>' : ''; |
|
| 660 | - $t = $item->get_first_related('Transaction'); |
|
| 661 | - $payment_count = $t instanceof EE_Transaction ? $t->count_related('Payment') : 0; |
|
| 662 | - // append group count to name |
|
| 663 | - $link .= ' ' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 664 | - // append reg_code |
|
| 665 | - $link .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 666 | - // reg status text for accessibility |
|
| 667 | - $link .= '<br><span class="ee-status-text-small">' |
|
| 668 | - . EEH_Template::pretty_status($item->status_ID(), false, 'sentence') |
|
| 669 | - . '</span>'; |
|
| 670 | - $action = [ '_REG_ID' => $item->ID() ]; |
|
| 671 | - if (isset($this->_req_data['event_id'])) { |
|
| 672 | - $action['event_id'] = $item->event_ID(); |
|
| 673 | - } |
|
| 674 | - // trash/restore/delete actions |
|
| 675 | - $actions = array(); |
|
| 676 | - if ($this->_view !== 'trash' |
|
| 677 | - && $payment_count === 0 |
|
| 678 | - && EE_Registry::instance()->CAP->current_user_can( |
|
| 679 | - 'ee_delete_registration', |
|
| 680 | - 'espresso_registrations_trash_registrations', |
|
| 681 | - $item->ID() |
|
| 682 | - )) { |
|
| 683 | - $action['action'] = 'trash_registrations'; |
|
| 684 | - $trash_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 685 | - $action, |
|
| 686 | - REG_ADMIN_URL |
|
| 687 | - ); |
|
| 688 | - $actions['trash'] = '<a href="' |
|
| 689 | - . $trash_lnk_url |
|
| 690 | - . '" title="' |
|
| 691 | - . esc_attr__('Trash Registration', 'event_espresso') |
|
| 692 | - . '">' . __('Trash', 'event_espresso') . '</a>'; |
|
| 693 | - } elseif ($this->_view === 'trash') { |
|
| 694 | - // restore registration link |
|
| 695 | - if (EE_Registry::instance()->CAP->current_user_can( |
|
| 696 | - 'ee_delete_registration', |
|
| 697 | - 'espresso_registrations_restore_registrations', |
|
| 698 | - $item->ID() |
|
| 699 | - )) { |
|
| 700 | - $action['action'] = 'restore_registrations'; |
|
| 701 | - $restore_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 702 | - $action, |
|
| 703 | - REG_ADMIN_URL |
|
| 704 | - ); |
|
| 705 | - $actions['restore'] = '<a href="' |
|
| 706 | - . $restore_lnk_url |
|
| 707 | - . '" title="' |
|
| 708 | - . esc_attr__('Restore Registration', 'event_espresso') . '">' |
|
| 709 | - . __('Restore', 'event_espresso') . '</a>'; |
|
| 710 | - } |
|
| 711 | - if (EE_Registry::instance()->CAP->current_user_can( |
|
| 712 | - 'ee_delete_registration', |
|
| 713 | - 'espresso_registrations_ee_delete_registrations', |
|
| 714 | - $item->ID() |
|
| 715 | - )) { |
|
| 716 | - $action['action'] = 'delete_registrations'; |
|
| 717 | - $delete_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 718 | - $action, |
|
| 719 | - REG_ADMIN_URL |
|
| 720 | - ); |
|
| 721 | - $actions['delete'] = '<a href="' |
|
| 722 | - . $delete_lnk_url |
|
| 723 | - . '" title="' |
|
| 724 | - . esc_attr__('Delete Registration Permanently', 'event_espresso') |
|
| 725 | - . '">' |
|
| 726 | - . __('Delete', 'event_espresso') |
|
| 727 | - . '</a>'; |
|
| 728 | - } |
|
| 729 | - } |
|
| 730 | - return sprintf('%1$s %2$s', $link, $this->row_actions($actions)); |
|
| 731 | - } |
|
| 623 | + /** |
|
| 624 | + * column_ATT_fname |
|
| 625 | + * |
|
| 626 | + * @access public |
|
| 627 | + * @param \EE_Registration $item |
|
| 628 | + * @return string |
|
| 629 | + * @throws EE_Error |
|
| 630 | + * @throws InvalidArgumentException |
|
| 631 | + * @throws InvalidDataTypeException |
|
| 632 | + * @throws InvalidInterfaceException |
|
| 633 | + * @throws ReflectionException |
|
| 634 | + */ |
|
| 635 | + public function column_ATT_fname(EE_Registration $item) |
|
| 636 | + { |
|
| 637 | + $attendee = $item->attendee(); |
|
| 638 | + $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 639 | + array( |
|
| 640 | + 'action' => 'view_registration', |
|
| 641 | + '_REG_ID' => $item->ID(), |
|
| 642 | + ), |
|
| 643 | + REG_ADMIN_URL |
|
| 644 | + ); |
|
| 645 | + $attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : ''; |
|
| 646 | + $link = EE_Registry::instance()->CAP->current_user_can( |
|
| 647 | + 'ee_read_registration', |
|
| 648 | + 'espresso_registrations_view_registration', |
|
| 649 | + $item->ID() |
|
| 650 | + ) |
|
| 651 | + ? '<a href="' |
|
| 652 | + . $edit_lnk_url |
|
| 653 | + . '" title="' |
|
| 654 | + . esc_attr__('View Registration Details', 'event_espresso') |
|
| 655 | + . '">' |
|
| 656 | + . $attendee_name |
|
| 657 | + . '</a>' : $attendee_name; |
|
| 658 | + $link .= $item->count() === 1 |
|
| 659 | + ? ' <sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>' : ''; |
|
| 660 | + $t = $item->get_first_related('Transaction'); |
|
| 661 | + $payment_count = $t instanceof EE_Transaction ? $t->count_related('Payment') : 0; |
|
| 662 | + // append group count to name |
|
| 663 | + $link .= ' ' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 664 | + // append reg_code |
|
| 665 | + $link .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 666 | + // reg status text for accessibility |
|
| 667 | + $link .= '<br><span class="ee-status-text-small">' |
|
| 668 | + . EEH_Template::pretty_status($item->status_ID(), false, 'sentence') |
|
| 669 | + . '</span>'; |
|
| 670 | + $action = [ '_REG_ID' => $item->ID() ]; |
|
| 671 | + if (isset($this->_req_data['event_id'])) { |
|
| 672 | + $action['event_id'] = $item->event_ID(); |
|
| 673 | + } |
|
| 674 | + // trash/restore/delete actions |
|
| 675 | + $actions = array(); |
|
| 676 | + if ($this->_view !== 'trash' |
|
| 677 | + && $payment_count === 0 |
|
| 678 | + && EE_Registry::instance()->CAP->current_user_can( |
|
| 679 | + 'ee_delete_registration', |
|
| 680 | + 'espresso_registrations_trash_registrations', |
|
| 681 | + $item->ID() |
|
| 682 | + )) { |
|
| 683 | + $action['action'] = 'trash_registrations'; |
|
| 684 | + $trash_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 685 | + $action, |
|
| 686 | + REG_ADMIN_URL |
|
| 687 | + ); |
|
| 688 | + $actions['trash'] = '<a href="' |
|
| 689 | + . $trash_lnk_url |
|
| 690 | + . '" title="' |
|
| 691 | + . esc_attr__('Trash Registration', 'event_espresso') |
|
| 692 | + . '">' . __('Trash', 'event_espresso') . '</a>'; |
|
| 693 | + } elseif ($this->_view === 'trash') { |
|
| 694 | + // restore registration link |
|
| 695 | + if (EE_Registry::instance()->CAP->current_user_can( |
|
| 696 | + 'ee_delete_registration', |
|
| 697 | + 'espresso_registrations_restore_registrations', |
|
| 698 | + $item->ID() |
|
| 699 | + )) { |
|
| 700 | + $action['action'] = 'restore_registrations'; |
|
| 701 | + $restore_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 702 | + $action, |
|
| 703 | + REG_ADMIN_URL |
|
| 704 | + ); |
|
| 705 | + $actions['restore'] = '<a href="' |
|
| 706 | + . $restore_lnk_url |
|
| 707 | + . '" title="' |
|
| 708 | + . esc_attr__('Restore Registration', 'event_espresso') . '">' |
|
| 709 | + . __('Restore', 'event_espresso') . '</a>'; |
|
| 710 | + } |
|
| 711 | + if (EE_Registry::instance()->CAP->current_user_can( |
|
| 712 | + 'ee_delete_registration', |
|
| 713 | + 'espresso_registrations_ee_delete_registrations', |
|
| 714 | + $item->ID() |
|
| 715 | + )) { |
|
| 716 | + $action['action'] = 'delete_registrations'; |
|
| 717 | + $delete_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 718 | + $action, |
|
| 719 | + REG_ADMIN_URL |
|
| 720 | + ); |
|
| 721 | + $actions['delete'] = '<a href="' |
|
| 722 | + . $delete_lnk_url |
|
| 723 | + . '" title="' |
|
| 724 | + . esc_attr__('Delete Registration Permanently', 'event_espresso') |
|
| 725 | + . '">' |
|
| 726 | + . __('Delete', 'event_espresso') |
|
| 727 | + . '</a>'; |
|
| 728 | + } |
|
| 729 | + } |
|
| 730 | + return sprintf('%1$s %2$s', $link, $this->row_actions($actions)); |
|
| 731 | + } |
|
| 732 | 732 | |
| 733 | 733 | |
| 734 | - /** |
|
| 735 | - * column_ATT_email |
|
| 736 | - * |
|
| 737 | - * @access public |
|
| 738 | - * @param \EE_Registration $item |
|
| 739 | - * @return string |
|
| 740 | - * @throws EE_Error |
|
| 741 | - * @throws InvalidArgumentException |
|
| 742 | - * @throws InvalidDataTypeException |
|
| 743 | - * @throws InvalidInterfaceException |
|
| 744 | - * @throws ReflectionException |
|
| 745 | - */ |
|
| 746 | - public function column_ATT_email(EE_Registration $item) |
|
| 747 | - { |
|
| 748 | - $attendee = $item->get_first_related('Attendee'); |
|
| 749 | - return ! $attendee instanceof EE_Attendee ? __('No attached contact record.', 'event_espresso') |
|
| 750 | - : $attendee->email(); |
|
| 751 | - } |
|
| 734 | + /** |
|
| 735 | + * column_ATT_email |
|
| 736 | + * |
|
| 737 | + * @access public |
|
| 738 | + * @param \EE_Registration $item |
|
| 739 | + * @return string |
|
| 740 | + * @throws EE_Error |
|
| 741 | + * @throws InvalidArgumentException |
|
| 742 | + * @throws InvalidDataTypeException |
|
| 743 | + * @throws InvalidInterfaceException |
|
| 744 | + * @throws ReflectionException |
|
| 745 | + */ |
|
| 746 | + public function column_ATT_email(EE_Registration $item) |
|
| 747 | + { |
|
| 748 | + $attendee = $item->get_first_related('Attendee'); |
|
| 749 | + return ! $attendee instanceof EE_Attendee ? __('No attached contact record.', 'event_espresso') |
|
| 750 | + : $attendee->email(); |
|
| 751 | + } |
|
| 752 | 752 | |
| 753 | 753 | |
| 754 | - /** |
|
| 755 | - * column__REG_count |
|
| 756 | - * |
|
| 757 | - * @access public |
|
| 758 | - * @param \EE_Registration $item |
|
| 759 | - * @return string |
|
| 760 | - */ |
|
| 761 | - public function column__REG_count(EE_Registration $item) |
|
| 762 | - { |
|
| 763 | - return sprintf(__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 764 | - } |
|
| 754 | + /** |
|
| 755 | + * column__REG_count |
|
| 756 | + * |
|
| 757 | + * @access public |
|
| 758 | + * @param \EE_Registration $item |
|
| 759 | + * @return string |
|
| 760 | + */ |
|
| 761 | + public function column__REG_count(EE_Registration $item) |
|
| 762 | + { |
|
| 763 | + return sprintf(__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 764 | + } |
|
| 765 | 765 | |
| 766 | 766 | |
| 767 | - /** |
|
| 768 | - * column_PRC_amount |
|
| 769 | - * |
|
| 770 | - * @access public |
|
| 771 | - * @param \EE_Registration $item |
|
| 772 | - * @return string |
|
| 773 | - * @throws EE_Error |
|
| 774 | - */ |
|
| 775 | - public function column_PRC_amount(EE_Registration $item) |
|
| 776 | - { |
|
| 777 | - $ticket = $item->ticket(); |
|
| 778 | - $content = isset($_GET['event_id']) && $ticket instanceof EE_Ticket ? '<span class="TKT_name">' |
|
| 779 | - . $ticket->name() |
|
| 780 | - . '</span><br />' : ''; |
|
| 781 | - if ($item->final_price() > 0) { |
|
| 782 | - $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>'; |
|
| 783 | - } else { |
|
| 784 | - // free event |
|
| 785 | - $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">' |
|
| 786 | - . __('free', 'event_espresso') |
|
| 787 | - . '</span>'; |
|
| 788 | - } |
|
| 789 | - return $content; |
|
| 790 | - } |
|
| 767 | + /** |
|
| 768 | + * column_PRC_amount |
|
| 769 | + * |
|
| 770 | + * @access public |
|
| 771 | + * @param \EE_Registration $item |
|
| 772 | + * @return string |
|
| 773 | + * @throws EE_Error |
|
| 774 | + */ |
|
| 775 | + public function column_PRC_amount(EE_Registration $item) |
|
| 776 | + { |
|
| 777 | + $ticket = $item->ticket(); |
|
| 778 | + $content = isset($_GET['event_id']) && $ticket instanceof EE_Ticket ? '<span class="TKT_name">' |
|
| 779 | + . $ticket->name() |
|
| 780 | + . '</span><br />' : ''; |
|
| 781 | + if ($item->final_price() > 0) { |
|
| 782 | + $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>'; |
|
| 783 | + } else { |
|
| 784 | + // free event |
|
| 785 | + $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">' |
|
| 786 | + . __('free', 'event_espresso') |
|
| 787 | + . '</span>'; |
|
| 788 | + } |
|
| 789 | + return $content; |
|
| 790 | + } |
|
| 791 | 791 | |
| 792 | 792 | |
| 793 | - /** |
|
| 794 | - * column__REG_final_price |
|
| 795 | - * |
|
| 796 | - * @access public |
|
| 797 | - * @param \EE_Registration $item |
|
| 798 | - * @return string |
|
| 799 | - * @throws EE_Error |
|
| 800 | - */ |
|
| 801 | - public function column__REG_final_price(EE_Registration $item) |
|
| 802 | - { |
|
| 803 | - $ticket = $item->ticket(); |
|
| 804 | - $content = isset($_GET['event_id']) || ! $ticket instanceof EE_Ticket |
|
| 805 | - ? '' |
|
| 806 | - : '<span class="TKT_name">' |
|
| 807 | - . $ticket->name() |
|
| 808 | - . '</span><br />'; |
|
| 809 | - $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>'; |
|
| 810 | - return $content; |
|
| 811 | - } |
|
| 793 | + /** |
|
| 794 | + * column__REG_final_price |
|
| 795 | + * |
|
| 796 | + * @access public |
|
| 797 | + * @param \EE_Registration $item |
|
| 798 | + * @return string |
|
| 799 | + * @throws EE_Error |
|
| 800 | + */ |
|
| 801 | + public function column__REG_final_price(EE_Registration $item) |
|
| 802 | + { |
|
| 803 | + $ticket = $item->ticket(); |
|
| 804 | + $content = isset($_GET['event_id']) || ! $ticket instanceof EE_Ticket |
|
| 805 | + ? '' |
|
| 806 | + : '<span class="TKT_name">' |
|
| 807 | + . $ticket->name() |
|
| 808 | + . '</span><br />'; |
|
| 809 | + $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>'; |
|
| 810 | + return $content; |
|
| 811 | + } |
|
| 812 | 812 | |
| 813 | 813 | |
| 814 | - /** |
|
| 815 | - * column__REG_paid |
|
| 816 | - * |
|
| 817 | - * @access public |
|
| 818 | - * @param \EE_Registration $item |
|
| 819 | - * @return string |
|
| 820 | - * @throws EE_Error |
|
| 821 | - */ |
|
| 822 | - public function column__REG_paid(EE_Registration $item) |
|
| 823 | - { |
|
| 824 | - $payment_method = $item->payment_method(); |
|
| 825 | - $payment_method_name = $payment_method instanceof EE_Payment_Method ? $payment_method->admin_name() |
|
| 826 | - : __('Unknown', 'event_espresso'); |
|
| 827 | - $content = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>'; |
|
| 828 | - if ($item->paid() > 0) { |
|
| 829 | - $content .= '<br><span class="ee-status-text-small">' |
|
| 830 | - . sprintf( |
|
| 831 | - __('...via %s', 'event_espresso'), |
|
| 832 | - $payment_method_name |
|
| 833 | - ) |
|
| 834 | - . '</span>'; |
|
| 835 | - } |
|
| 836 | - return $content; |
|
| 837 | - } |
|
| 814 | + /** |
|
| 815 | + * column__REG_paid |
|
| 816 | + * |
|
| 817 | + * @access public |
|
| 818 | + * @param \EE_Registration $item |
|
| 819 | + * @return string |
|
| 820 | + * @throws EE_Error |
|
| 821 | + */ |
|
| 822 | + public function column__REG_paid(EE_Registration $item) |
|
| 823 | + { |
|
| 824 | + $payment_method = $item->payment_method(); |
|
| 825 | + $payment_method_name = $payment_method instanceof EE_Payment_Method ? $payment_method->admin_name() |
|
| 826 | + : __('Unknown', 'event_espresso'); |
|
| 827 | + $content = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>'; |
|
| 828 | + if ($item->paid() > 0) { |
|
| 829 | + $content .= '<br><span class="ee-status-text-small">' |
|
| 830 | + . sprintf( |
|
| 831 | + __('...via %s', 'event_espresso'), |
|
| 832 | + $payment_method_name |
|
| 833 | + ) |
|
| 834 | + . '</span>'; |
|
| 835 | + } |
|
| 836 | + return $content; |
|
| 837 | + } |
|
| 838 | 838 | |
| 839 | 839 | |
| 840 | - /** |
|
| 841 | - * column_TXN_total |
|
| 842 | - * |
|
| 843 | - * @access public |
|
| 844 | - * @param \EE_Registration $item |
|
| 845 | - * @return string |
|
| 846 | - * @throws EE_Error |
|
| 847 | - * @throws EntityNotFoundException |
|
| 848 | - * @throws InvalidArgumentException |
|
| 849 | - * @throws InvalidDataTypeException |
|
| 850 | - * @throws InvalidInterfaceException |
|
| 851 | - */ |
|
| 852 | - public function column_TXN_total(EE_Registration $item) |
|
| 853 | - { |
|
| 854 | - if ($item->transaction()) { |
|
| 855 | - $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 856 | - array( |
|
| 857 | - 'action' => 'view_transaction', |
|
| 858 | - 'TXN_ID' => $item->transaction_ID(), |
|
| 859 | - ), |
|
| 860 | - TXN_ADMIN_URL |
|
| 861 | - ); |
|
| 862 | - return EE_Registry::instance()->CAP->current_user_can( |
|
| 863 | - 'ee_read_transaction', |
|
| 864 | - 'espresso_transactions_view_transaction', |
|
| 865 | - $item->transaction_ID() |
|
| 866 | - ) |
|
| 867 | - ? '<span class="reg-pad-rght"><a class="status-' |
|
| 868 | - . $item->transaction()->status_ID() |
|
| 869 | - . '" href="' |
|
| 870 | - . $view_txn_lnk_url |
|
| 871 | - . '" title="' |
|
| 872 | - . esc_attr__('View Transaction', 'event_espresso') |
|
| 873 | - . '">' |
|
| 874 | - . $item->transaction()->pretty_total() |
|
| 875 | - . '</a></span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>'; |
|
| 876 | - } else { |
|
| 877 | - return __("None", "event_espresso"); |
|
| 878 | - } |
|
| 879 | - } |
|
| 840 | + /** |
|
| 841 | + * column_TXN_total |
|
| 842 | + * |
|
| 843 | + * @access public |
|
| 844 | + * @param \EE_Registration $item |
|
| 845 | + * @return string |
|
| 846 | + * @throws EE_Error |
|
| 847 | + * @throws EntityNotFoundException |
|
| 848 | + * @throws InvalidArgumentException |
|
| 849 | + * @throws InvalidDataTypeException |
|
| 850 | + * @throws InvalidInterfaceException |
|
| 851 | + */ |
|
| 852 | + public function column_TXN_total(EE_Registration $item) |
|
| 853 | + { |
|
| 854 | + if ($item->transaction()) { |
|
| 855 | + $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 856 | + array( |
|
| 857 | + 'action' => 'view_transaction', |
|
| 858 | + 'TXN_ID' => $item->transaction_ID(), |
|
| 859 | + ), |
|
| 860 | + TXN_ADMIN_URL |
|
| 861 | + ); |
|
| 862 | + return EE_Registry::instance()->CAP->current_user_can( |
|
| 863 | + 'ee_read_transaction', |
|
| 864 | + 'espresso_transactions_view_transaction', |
|
| 865 | + $item->transaction_ID() |
|
| 866 | + ) |
|
| 867 | + ? '<span class="reg-pad-rght"><a class="status-' |
|
| 868 | + . $item->transaction()->status_ID() |
|
| 869 | + . '" href="' |
|
| 870 | + . $view_txn_lnk_url |
|
| 871 | + . '" title="' |
|
| 872 | + . esc_attr__('View Transaction', 'event_espresso') |
|
| 873 | + . '">' |
|
| 874 | + . $item->transaction()->pretty_total() |
|
| 875 | + . '</a></span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>'; |
|
| 876 | + } else { |
|
| 877 | + return __("None", "event_espresso"); |
|
| 878 | + } |
|
| 879 | + } |
|
| 880 | 880 | |
| 881 | 881 | |
| 882 | - /** |
|
| 883 | - * column_TXN_paid |
|
| 884 | - * |
|
| 885 | - * @access public |
|
| 886 | - * @param \EE_Registration $item |
|
| 887 | - * @return string |
|
| 888 | - * @throws EE_Error |
|
| 889 | - * @throws EntityNotFoundException |
|
| 890 | - * @throws InvalidArgumentException |
|
| 891 | - * @throws InvalidDataTypeException |
|
| 892 | - * @throws InvalidInterfaceException |
|
| 893 | - */ |
|
| 894 | - public function column_TXN_paid(EE_Registration $item) |
|
| 895 | - { |
|
| 896 | - if ($item->count() === 1) { |
|
| 897 | - $transaction = $item->transaction() ? $item->transaction() : EE_Transaction::new_instance(); |
|
| 898 | - if ($transaction->paid() >= $transaction->total()) { |
|
| 899 | - return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>'; |
|
| 900 | - } else { |
|
| 901 | - $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 902 | - array( |
|
| 903 | - 'action' => 'view_transaction', |
|
| 904 | - 'TXN_ID' => $item->transaction_ID(), |
|
| 905 | - ), |
|
| 906 | - TXN_ADMIN_URL |
|
| 907 | - ); |
|
| 908 | - return EE_Registry::instance()->CAP->current_user_can( |
|
| 909 | - 'ee_read_transaction', |
|
| 910 | - 'espresso_transactions_view_transaction', |
|
| 911 | - $item->transaction_ID() |
|
| 912 | - ) |
|
| 913 | - ? '<span class="reg-pad-rght"><a class="status-' |
|
| 914 | - . $transaction->status_ID() |
|
| 915 | - . '" href="' |
|
| 916 | - . $view_txn_lnk_url |
|
| 917 | - . '" title="' |
|
| 918 | - . esc_attr__('View Transaction', 'event_espresso') |
|
| 919 | - . '">' |
|
| 920 | - . $item->transaction()->pretty_paid() |
|
| 921 | - . '</a><span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>'; |
|
| 922 | - } |
|
| 923 | - } |
|
| 924 | - return ' '; |
|
| 925 | - } |
|
| 882 | + /** |
|
| 883 | + * column_TXN_paid |
|
| 884 | + * |
|
| 885 | + * @access public |
|
| 886 | + * @param \EE_Registration $item |
|
| 887 | + * @return string |
|
| 888 | + * @throws EE_Error |
|
| 889 | + * @throws EntityNotFoundException |
|
| 890 | + * @throws InvalidArgumentException |
|
| 891 | + * @throws InvalidDataTypeException |
|
| 892 | + * @throws InvalidInterfaceException |
|
| 893 | + */ |
|
| 894 | + public function column_TXN_paid(EE_Registration $item) |
|
| 895 | + { |
|
| 896 | + if ($item->count() === 1) { |
|
| 897 | + $transaction = $item->transaction() ? $item->transaction() : EE_Transaction::new_instance(); |
|
| 898 | + if ($transaction->paid() >= $transaction->total()) { |
|
| 899 | + return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>'; |
|
| 900 | + } else { |
|
| 901 | + $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 902 | + array( |
|
| 903 | + 'action' => 'view_transaction', |
|
| 904 | + 'TXN_ID' => $item->transaction_ID(), |
|
| 905 | + ), |
|
| 906 | + TXN_ADMIN_URL |
|
| 907 | + ); |
|
| 908 | + return EE_Registry::instance()->CAP->current_user_can( |
|
| 909 | + 'ee_read_transaction', |
|
| 910 | + 'espresso_transactions_view_transaction', |
|
| 911 | + $item->transaction_ID() |
|
| 912 | + ) |
|
| 913 | + ? '<span class="reg-pad-rght"><a class="status-' |
|
| 914 | + . $transaction->status_ID() |
|
| 915 | + . '" href="' |
|
| 916 | + . $view_txn_lnk_url |
|
| 917 | + . '" title="' |
|
| 918 | + . esc_attr__('View Transaction', 'event_espresso') |
|
| 919 | + . '">' |
|
| 920 | + . $item->transaction()->pretty_paid() |
|
| 921 | + . '</a><span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>'; |
|
| 922 | + } |
|
| 923 | + } |
|
| 924 | + return ' '; |
|
| 925 | + } |
|
| 926 | 926 | |
| 927 | 927 | |
| 928 | - /** |
|
| 929 | - * column_actions |
|
| 930 | - * |
|
| 931 | - * @access public |
|
| 932 | - * @param \EE_Registration $item |
|
| 933 | - * @return string |
|
| 934 | - * @throws EE_Error |
|
| 935 | - * @throws InvalidArgumentException |
|
| 936 | - * @throws InvalidDataTypeException |
|
| 937 | - * @throws InvalidInterfaceException |
|
| 938 | - * @throws ReflectionException |
|
| 939 | - */ |
|
| 940 | - public function column_actions(EE_Registration $item) |
|
| 941 | - { |
|
| 942 | - $actions = array(); |
|
| 943 | - $attendee = $item->attendee(); |
|
| 944 | - $this->_set_related_details($item); |
|
| 945 | - // Build row actions |
|
| 946 | - $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 947 | - array( |
|
| 948 | - 'action' => 'view_registration', |
|
| 949 | - '_REG_ID' => $item->ID(), |
|
| 950 | - ), |
|
| 951 | - REG_ADMIN_URL |
|
| 952 | - ); |
|
| 953 | - $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 954 | - array( |
|
| 955 | - 'action' => 'edit_attendee', |
|
| 956 | - 'post' => $item->attendee_ID(), |
|
| 957 | - ), |
|
| 958 | - REG_ADMIN_URL |
|
| 959 | - ); |
|
| 960 | - // page=attendees&event_admin_reports=resend_email®istration_id=43653465634&event_id=2&form_action=resend_email |
|
| 961 | - // $resend_reg_lnk_url_params = array( 'action'=>'resend_registration', '_REG_ID'=>$item->REG_ID ); |
|
| 962 | - $resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 963 | - array( |
|
| 964 | - 'action' => 'resend_registration', |
|
| 965 | - '_REG_ID' => $item->ID(), |
|
| 966 | - ), |
|
| 967 | - REG_ADMIN_URL, |
|
| 968 | - true |
|
| 969 | - ); |
|
| 970 | - // Build row actions |
|
| 971 | - $actions['view_lnk'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 972 | - 'ee_read_registration', |
|
| 973 | - 'espresso_registrations_view_registration', |
|
| 974 | - $item->ID() |
|
| 975 | - ) ? '<li><a href="' |
|
| 976 | - . $view_lnk_url |
|
| 977 | - . '" title="' |
|
| 978 | - . esc_attr__('View Registration Details', 'event_espresso') |
|
| 979 | - . '" class="tiny-text"> |
|
| 928 | + /** |
|
| 929 | + * column_actions |
|
| 930 | + * |
|
| 931 | + * @access public |
|
| 932 | + * @param \EE_Registration $item |
|
| 933 | + * @return string |
|
| 934 | + * @throws EE_Error |
|
| 935 | + * @throws InvalidArgumentException |
|
| 936 | + * @throws InvalidDataTypeException |
|
| 937 | + * @throws InvalidInterfaceException |
|
| 938 | + * @throws ReflectionException |
|
| 939 | + */ |
|
| 940 | + public function column_actions(EE_Registration $item) |
|
| 941 | + { |
|
| 942 | + $actions = array(); |
|
| 943 | + $attendee = $item->attendee(); |
|
| 944 | + $this->_set_related_details($item); |
|
| 945 | + // Build row actions |
|
| 946 | + $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 947 | + array( |
|
| 948 | + 'action' => 'view_registration', |
|
| 949 | + '_REG_ID' => $item->ID(), |
|
| 950 | + ), |
|
| 951 | + REG_ADMIN_URL |
|
| 952 | + ); |
|
| 953 | + $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 954 | + array( |
|
| 955 | + 'action' => 'edit_attendee', |
|
| 956 | + 'post' => $item->attendee_ID(), |
|
| 957 | + ), |
|
| 958 | + REG_ADMIN_URL |
|
| 959 | + ); |
|
| 960 | + // page=attendees&event_admin_reports=resend_email®istration_id=43653465634&event_id=2&form_action=resend_email |
|
| 961 | + // $resend_reg_lnk_url_params = array( 'action'=>'resend_registration', '_REG_ID'=>$item->REG_ID ); |
|
| 962 | + $resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 963 | + array( |
|
| 964 | + 'action' => 'resend_registration', |
|
| 965 | + '_REG_ID' => $item->ID(), |
|
| 966 | + ), |
|
| 967 | + REG_ADMIN_URL, |
|
| 968 | + true |
|
| 969 | + ); |
|
| 970 | + // Build row actions |
|
| 971 | + $actions['view_lnk'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 972 | + 'ee_read_registration', |
|
| 973 | + 'espresso_registrations_view_registration', |
|
| 974 | + $item->ID() |
|
| 975 | + ) ? '<li><a href="' |
|
| 976 | + . $view_lnk_url |
|
| 977 | + . '" title="' |
|
| 978 | + . esc_attr__('View Registration Details', 'event_espresso') |
|
| 979 | + . '" class="tiny-text"> |
|
| 980 | 980 | <div class="dashicons dashicons-clipboard"></div> |
| 981 | 981 | </a> |
| 982 | 982 | </li>' |
| 983 | - : ''; |
|
| 984 | - $actions['edit_lnk'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 985 | - 'ee_edit_contacts', |
|
| 986 | - 'espresso_registrations_edit_attendee' |
|
| 987 | - ) |
|
| 988 | - && $attendee instanceof EE_Attendee |
|
| 989 | - ? ' |
|
| 983 | + : ''; |
|
| 984 | + $actions['edit_lnk'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 985 | + 'ee_edit_contacts', |
|
| 986 | + 'espresso_registrations_edit_attendee' |
|
| 987 | + ) |
|
| 988 | + && $attendee instanceof EE_Attendee |
|
| 989 | + ? ' |
|
| 990 | 990 | <li> |
| 991 | 991 | <a href="' . $edit_lnk_url . '" title="' |
| 992 | - . esc_attr__('Edit Contact Details', 'event_espresso') . '" class="tiny-text"> |
|
| 992 | + . esc_attr__('Edit Contact Details', 'event_espresso') . '" class="tiny-text"> |
|
| 993 | 993 | <div class="ee-icon ee-icon-user-edit ee-icon-size-16"></div> |
| 994 | 994 | </a> |
| 995 | 995 | </li>' : ''; |
| 996 | - $actions['resend_reg_lnk'] = $attendee instanceof EE_Attendee |
|
| 997 | - && EE_Registry::instance()->CAP->current_user_can( |
|
| 998 | - 'ee_send_message', |
|
| 999 | - 'espresso_registrations_resend_registration', |
|
| 1000 | - $item->ID() |
|
| 1001 | - ) |
|
| 1002 | - ? ' |
|
| 996 | + $actions['resend_reg_lnk'] = $attendee instanceof EE_Attendee |
|
| 997 | + && EE_Registry::instance()->CAP->current_user_can( |
|
| 998 | + 'ee_send_message', |
|
| 999 | + 'espresso_registrations_resend_registration', |
|
| 1000 | + $item->ID() |
|
| 1001 | + ) |
|
| 1002 | + ? ' |
|
| 1003 | 1003 | <li> |
| 1004 | 1004 | <a href="' |
| 1005 | - . $resend_reg_lnk_url |
|
| 1006 | - . '" title="' |
|
| 1007 | - . esc_attr__('Resend Registration Details', 'event_espresso') |
|
| 1008 | - . '" class="tiny-text"> |
|
| 1005 | + . $resend_reg_lnk_url |
|
| 1006 | + . '" title="' |
|
| 1007 | + . esc_attr__('Resend Registration Details', 'event_espresso') |
|
| 1008 | + . '" class="tiny-text"> |
|
| 1009 | 1009 | <div class="dashicons dashicons-email-alt"></div> |
| 1010 | 1010 | </a> |
| 1011 | 1011 | </li>' : ''; |
| 1012 | - // page=transactions&action=view_transaction&txn=256&_wpnonce=6414da4dbb |
|
| 1013 | - $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 1014 | - array( |
|
| 1015 | - 'action' => 'view_transaction', |
|
| 1016 | - 'TXN_ID' => $this->_transaction_details['id'], |
|
| 1017 | - ), |
|
| 1018 | - TXN_ADMIN_URL |
|
| 1019 | - ); |
|
| 1020 | - $actions['view_txn_lnk'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 1021 | - 'ee_read_transaction', |
|
| 1022 | - 'espresso_transactions_view_transaction', |
|
| 1023 | - $this->_transaction_details['id'] |
|
| 1024 | - ) |
|
| 1025 | - ? ' |
|
| 1012 | + // page=transactions&action=view_transaction&txn=256&_wpnonce=6414da4dbb |
|
| 1013 | + $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 1014 | + array( |
|
| 1015 | + 'action' => 'view_transaction', |
|
| 1016 | + 'TXN_ID' => $this->_transaction_details['id'], |
|
| 1017 | + ), |
|
| 1018 | + TXN_ADMIN_URL |
|
| 1019 | + ); |
|
| 1020 | + $actions['view_txn_lnk'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 1021 | + 'ee_read_transaction', |
|
| 1022 | + 'espresso_transactions_view_transaction', |
|
| 1023 | + $this->_transaction_details['id'] |
|
| 1024 | + ) |
|
| 1025 | + ? ' |
|
| 1026 | 1026 | <li> |
| 1027 | 1027 | <a class="ee-status-color-' |
| 1028 | - . $this->_transaction_details['status'] |
|
| 1029 | - . ' tiny-text" href="' |
|
| 1030 | - . $view_txn_lnk_url |
|
| 1031 | - . '" title="' |
|
| 1032 | - . $this->_transaction_details['title_attr'] |
|
| 1033 | - . '"> |
|
| 1028 | + . $this->_transaction_details['status'] |
|
| 1029 | + . ' tiny-text" href="' |
|
| 1030 | + . $view_txn_lnk_url |
|
| 1031 | + . '" title="' |
|
| 1032 | + . $this->_transaction_details['title_attr'] |
|
| 1033 | + . '"> |
|
| 1034 | 1034 | <div class="dashicons dashicons-cart"></div> |
| 1035 | 1035 | </a> |
| 1036 | 1036 | </li>' : ''; |
| 1037 | - // invoice link |
|
| 1038 | - $actions['dl_invoice_lnk'] = ''; |
|
| 1039 | - $dl_invoice_lnk_url = $item->invoice_url(); |
|
| 1040 | - // only show invoice link if message type is active. |
|
| 1041 | - if ($attendee instanceof EE_Attendee |
|
| 1042 | - && $item->is_primary_registrant() |
|
| 1043 | - && EEH_MSG_Template::is_mt_active('invoice') |
|
| 1044 | - ) { |
|
| 1045 | - $actions['dl_invoice_lnk'] = ' |
|
| 1037 | + // invoice link |
|
| 1038 | + $actions['dl_invoice_lnk'] = ''; |
|
| 1039 | + $dl_invoice_lnk_url = $item->invoice_url(); |
|
| 1040 | + // only show invoice link if message type is active. |
|
| 1041 | + if ($attendee instanceof EE_Attendee |
|
| 1042 | + && $item->is_primary_registrant() |
|
| 1043 | + && EEH_MSG_Template::is_mt_active('invoice') |
|
| 1044 | + ) { |
|
| 1045 | + $actions['dl_invoice_lnk'] = ' |
|
| 1046 | 1046 | <li> |
| 1047 | 1047 | <a title="' |
| 1048 | - . esc_attr__('View Transaction Invoice', 'event_espresso') |
|
| 1049 | - . '" target="_blank" href="' |
|
| 1050 | - . $dl_invoice_lnk_url |
|
| 1051 | - . '" class="tiny-text"> |
|
| 1048 | + . esc_attr__('View Transaction Invoice', 'event_espresso') |
|
| 1049 | + . '" target="_blank" href="' |
|
| 1050 | + . $dl_invoice_lnk_url |
|
| 1051 | + . '" class="tiny-text"> |
|
| 1052 | 1052 | <span class="dashicons dashicons-media-spreadsheet ee-icon-size-18"></span> |
| 1053 | 1053 | </a> |
| 1054 | 1054 | </li>'; |
| 1055 | - } |
|
| 1056 | - $actions['filtered_messages_link'] = ''; |
|
| 1057 | - // message list table link (filtered by REG_ID |
|
| 1058 | - if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) { |
|
| 1059 | - $actions['filtered_messages_link'] = '<li>' |
|
| 1060 | - . EEH_MSG_Template::get_message_action_link( |
|
| 1061 | - 'see_notifications_for', |
|
| 1062 | - null, |
|
| 1063 | - array('_REG_ID' => $item->ID()) |
|
| 1064 | - ) . '</li>'; |
|
| 1065 | - } |
|
| 1066 | - $actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this); |
|
| 1067 | - return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul'); |
|
| 1068 | - } |
|
| 1055 | + } |
|
| 1056 | + $actions['filtered_messages_link'] = ''; |
|
| 1057 | + // message list table link (filtered by REG_ID |
|
| 1058 | + if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) { |
|
| 1059 | + $actions['filtered_messages_link'] = '<li>' |
|
| 1060 | + . EEH_MSG_Template::get_message_action_link( |
|
| 1061 | + 'see_notifications_for', |
|
| 1062 | + null, |
|
| 1063 | + array('_REG_ID' => $item->ID()) |
|
| 1064 | + ) . '</li>'; |
|
| 1065 | + } |
|
| 1066 | + $actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this); |
|
| 1067 | + return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul'); |
|
| 1068 | + } |
|
| 1069 | 1069 | } |
@@ -53,10 +53,10 @@ discard block |
||
| 53 | 53 | */ |
| 54 | 54 | public function __construct(Registrations_Admin_Page $admin_page) |
| 55 | 55 | { |
| 56 | - if (! empty($_GET['event_id'])) { |
|
| 56 | + if ( ! empty($_GET['event_id'])) { |
|
| 57 | 57 | $extra_query_args = array(); |
| 58 | 58 | foreach ($admin_page->get_views() as $key => $view_details) { |
| 59 | - $extra_query_args[ $view_details['slug'] ] = array('event_id' => $_GET['event_id']); |
|
| 59 | + $extra_query_args[$view_details['slug']] = array('event_id' => $_GET['event_id']); |
|
| 60 | 60 | } |
| 61 | 61 | $this->_views = $admin_page->get_list_table_view_RLs($extra_query_args); |
| 62 | 62 | } |
@@ -156,12 +156,12 @@ discard block |
||
| 156 | 156 | ) |
| 157 | 157 | ) |
| 158 | 158 | ); |
| 159 | - if (!empty($filters)) { |
|
| 159 | + if ( ! empty($filters)) { |
|
| 160 | 160 | $this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters; |
| 161 | 161 | } |
| 162 | 162 | $this->_primary_column = '_REG_ID'; |
| 163 | 163 | $this->_sortable_columns = array( |
| 164 | - '_REG_date' => array('_REG_date' => true), // true means its already sorted |
|
| 164 | + '_REG_date' => array('_REG_date' => true), // true means its already sorted |
|
| 165 | 165 | /** |
| 166 | 166 | * Allows users to change the default sort if they wish. |
| 167 | 167 | * Returning a falsey on this filter will result in the default sort to be by firstname rather than last |
@@ -193,7 +193,7 @@ discard block |
||
| 193 | 193 | { |
| 194 | 194 | $class = parent::_get_row_class($item); |
| 195 | 195 | // add status class |
| 196 | - $class .= ' ee-status-strip reg-status-' . $item->status_ID(); |
|
| 196 | + $class .= ' ee-status-strip reg-status-'.$item->status_ID(); |
|
| 197 | 197 | if ($this->_has_checkbox_column) { |
| 198 | 198 | $class .= ' has-checkbox-column'; |
| 199 | 199 | } |
@@ -358,12 +358,12 @@ discard block |
||
| 358 | 358 | // setup date query. |
| 359 | 359 | $beginning_string = EEM_Registration::instance()->convert_datetime_for_query( |
| 360 | 360 | 'REG_date', |
| 361 | - $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start, |
|
| 361 | + $this_year_r.'-'.$this_month_r.'-01'.' '.$time_start, |
|
| 362 | 362 | 'Y-m-d H:i:s' |
| 363 | 363 | ); |
| 364 | 364 | $end_string = EEM_Registration::instance()->convert_datetime_for_query( |
| 365 | 365 | 'REG_date', |
| 366 | - $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end, |
|
| 366 | + $this_year_r.'-'.$this_month_r.'-'.$days_this_month.' '.$time_end, |
|
| 367 | 367 | 'Y-m-d H:i:s' |
| 368 | 368 | ); |
| 369 | 369 | $_where['REG_date'] = array( |
@@ -400,12 +400,12 @@ discard block |
||
| 400 | 400 | array( |
| 401 | 401 | EEM_Registration::instance()->convert_datetime_for_query( |
| 402 | 402 | 'REG_date', |
| 403 | - $current_date . $time_start, |
|
| 403 | + $current_date.$time_start, |
|
| 404 | 404 | 'Y-m-d H:i:s' |
| 405 | 405 | ), |
| 406 | 406 | EEM_Registration::instance()->convert_datetime_for_query( |
| 407 | 407 | 'REG_date', |
| 408 | - $current_date . $time_end, |
|
| 408 | + $current_date.$time_end, |
|
| 409 | 409 | 'Y-m-d H:i:s' |
| 410 | 410 | ), |
| 411 | 411 | ), |
@@ -465,8 +465,8 @@ discard block |
||
| 465 | 465 | $content .= '<div class="show-on-mobile-view-only">'; |
| 466 | 466 | $content .= '<br>'; |
| 467 | 467 | $content .= $attendee instanceof EE_Attendee ? $attendee->full_name() : ''; |
| 468 | - $content .= ' ' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 469 | - $content .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 468 | + $content .= ' '.sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 469 | + $content .= '<br>'.sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 470 | 470 | $content .= '</div>'; |
| 471 | 471 | return $content; |
| 472 | 472 | } |
@@ -551,12 +551,12 @@ discard block |
||
| 551 | 551 | . $event_name |
| 552 | 552 | . '</a>' : $event_name; |
| 553 | 553 | $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(array('event_id' => $EVT_ID), REG_ADMIN_URL); |
| 554 | - $actions['event_filter'] = '<a href="' . $edit_event_url . '" title="'; |
|
| 554 | + $actions['event_filter'] = '<a href="'.$edit_event_url.'" title="'; |
|
| 555 | 555 | $actions['event_filter'] .= sprintf( |
| 556 | 556 | esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'), |
| 557 | 557 | $event_name |
| 558 | 558 | ); |
| 559 | - $actions['event_filter'] .= '">' . __('View Registrations', 'event_espresso') . '</a>'; |
|
| 559 | + $actions['event_filter'] .= '">'.__('View Registrations', 'event_espresso').'</a>'; |
|
| 560 | 560 | } else { |
| 561 | 561 | $edit_event = $event_name; |
| 562 | 562 | $actions['event_filter'] = ''; |
@@ -603,11 +603,11 @@ discard block |
||
| 603 | 603 | { |
| 604 | 604 | $content = '<div class="ee-registration-event-datetimes-container">'; |
| 605 | 605 | $expand_toggle = count($datetime_strings) > 1 |
| 606 | - ? ' <span title="' . esc_attr__('Click to view all dates', 'event_espresso') |
|
| 606 | + ? ' <span title="'.esc_attr__('Click to view all dates', 'event_espresso') |
|
| 607 | 607 | . '" class="ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>' |
| 608 | 608 | : ''; |
| 609 | 609 | // get first item for initial visibility |
| 610 | - $content .= '<div class="left">' . array_shift($datetime_strings) . '</div>'; |
|
| 610 | + $content .= '<div class="left">'.array_shift($datetime_strings).'</div>'; |
|
| 611 | 611 | $content .= $expand_toggle; |
| 612 | 612 | if ($datetime_strings) { |
| 613 | 613 | $content .= '<div style="clear:both"></div>'; |
@@ -660,14 +660,14 @@ discard block |
||
| 660 | 660 | $t = $item->get_first_related('Transaction'); |
| 661 | 661 | $payment_count = $t instanceof EE_Transaction ? $t->count_related('Payment') : 0; |
| 662 | 662 | // append group count to name |
| 663 | - $link .= ' ' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 663 | + $link .= ' '.sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
| 664 | 664 | // append reg_code |
| 665 | - $link .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 665 | + $link .= '<br>'.sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code')); |
|
| 666 | 666 | // reg status text for accessibility |
| 667 | 667 | $link .= '<br><span class="ee-status-text-small">' |
| 668 | 668 | . EEH_Template::pretty_status($item->status_ID(), false, 'sentence') |
| 669 | 669 | . '</span>'; |
| 670 | - $action = [ '_REG_ID' => $item->ID() ]; |
|
| 670 | + $action = ['_REG_ID' => $item->ID()]; |
|
| 671 | 671 | if (isset($this->_req_data['event_id'])) { |
| 672 | 672 | $action['event_id'] = $item->event_ID(); |
| 673 | 673 | } |
@@ -689,7 +689,7 @@ discard block |
||
| 689 | 689 | . $trash_lnk_url |
| 690 | 690 | . '" title="' |
| 691 | 691 | . esc_attr__('Trash Registration', 'event_espresso') |
| 692 | - . '">' . __('Trash', 'event_espresso') . '</a>'; |
|
| 692 | + . '">'.__('Trash', 'event_espresso').'</a>'; |
|
| 693 | 693 | } elseif ($this->_view === 'trash') { |
| 694 | 694 | // restore registration link |
| 695 | 695 | if (EE_Registry::instance()->CAP->current_user_can( |
@@ -705,8 +705,8 @@ discard block |
||
| 705 | 705 | $actions['restore'] = '<a href="' |
| 706 | 706 | . $restore_lnk_url |
| 707 | 707 | . '" title="' |
| 708 | - . esc_attr__('Restore Registration', 'event_espresso') . '">' |
|
| 709 | - . __('Restore', 'event_espresso') . '</a>'; |
|
| 708 | + . esc_attr__('Restore Registration', 'event_espresso').'">' |
|
| 709 | + . __('Restore', 'event_espresso').'</a>'; |
|
| 710 | 710 | } |
| 711 | 711 | if (EE_Registry::instance()->CAP->current_user_can( |
| 712 | 712 | 'ee_delete_registration', |
@@ -779,7 +779,7 @@ discard block |
||
| 779 | 779 | . $ticket->name() |
| 780 | 780 | . '</span><br />' : ''; |
| 781 | 781 | if ($item->final_price() > 0) { |
| 782 | - $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>'; |
|
| 782 | + $content .= '<span class="reg-pad-rght">'.$item->pretty_final_price().'</span>'; |
|
| 783 | 783 | } else { |
| 784 | 784 | // free event |
| 785 | 785 | $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">' |
@@ -806,7 +806,7 @@ discard block |
||
| 806 | 806 | : '<span class="TKT_name">' |
| 807 | 807 | . $ticket->name() |
| 808 | 808 | . '</span><br />'; |
| 809 | - $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>'; |
|
| 809 | + $content .= '<span class="reg-pad-rght">'.$item->pretty_final_price().'</span>'; |
|
| 810 | 810 | return $content; |
| 811 | 811 | } |
| 812 | 812 | |
@@ -824,7 +824,7 @@ discard block |
||
| 824 | 824 | $payment_method = $item->payment_method(); |
| 825 | 825 | $payment_method_name = $payment_method instanceof EE_Payment_Method ? $payment_method->admin_name() |
| 826 | 826 | : __('Unknown', 'event_espresso'); |
| 827 | - $content = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>'; |
|
| 827 | + $content = '<span class="reg-pad-rght">'.$item->pretty_paid().'</span>'; |
|
| 828 | 828 | if ($item->paid() > 0) { |
| 829 | 829 | $content .= '<br><span class="ee-status-text-small">' |
| 830 | 830 | . sprintf( |
@@ -872,7 +872,7 @@ discard block |
||
| 872 | 872 | . esc_attr__('View Transaction', 'event_espresso') |
| 873 | 873 | . '">' |
| 874 | 874 | . $item->transaction()->pretty_total() |
| 875 | - . '</a></span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>'; |
|
| 875 | + . '</a></span>' : '<span class="reg-pad-rght">'.$item->transaction()->pretty_total().'</span>'; |
|
| 876 | 876 | } else { |
| 877 | 877 | return __("None", "event_espresso"); |
| 878 | 878 | } |
@@ -918,7 +918,7 @@ discard block |
||
| 918 | 918 | . esc_attr__('View Transaction', 'event_espresso') |
| 919 | 919 | . '">' |
| 920 | 920 | . $item->transaction()->pretty_paid() |
| 921 | - . '</a><span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>'; |
|
| 921 | + . '</a><span>' : '<span class="reg-pad-rght">'.$item->transaction()->pretty_paid().'</span>'; |
|
| 922 | 922 | } |
| 923 | 923 | } |
| 924 | 924 | return ' '; |
@@ -988,8 +988,8 @@ discard block |
||
| 988 | 988 | && $attendee instanceof EE_Attendee |
| 989 | 989 | ? ' |
| 990 | 990 | <li> |
| 991 | - <a href="' . $edit_lnk_url . '" title="' |
|
| 992 | - . esc_attr__('Edit Contact Details', 'event_espresso') . '" class="tiny-text"> |
|
| 991 | + <a href="' . $edit_lnk_url.'" title="' |
|
| 992 | + . esc_attr__('Edit Contact Details', 'event_espresso').'" class="tiny-text"> |
|
| 993 | 993 | <div class="ee-icon ee-icon-user-edit ee-icon-size-16"></div> |
| 994 | 994 | </a> |
| 995 | 995 | </li>' : ''; |
@@ -1061,7 +1061,7 @@ discard block |
||
| 1061 | 1061 | 'see_notifications_for', |
| 1062 | 1062 | null, |
| 1063 | 1063 | array('_REG_ID' => $item->ID()) |
| 1064 | - ) . '</li>'; |
|
| 1064 | + ).'</li>'; |
|
| 1065 | 1065 | } |
| 1066 | 1066 | $actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this); |
| 1067 | 1067 | return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul'); |
@@ -157,9 +157,9 @@ discard block |
||
| 157 | 157 | 'ee_delete_checkins', |
| 158 | 158 | 'espresso_registrations_delete_checkin_row' |
| 159 | 159 | ) |
| 160 | - ? '<a href="' . $delete_url . '" title="' |
|
| 161 | - . esc_attr__('Click here to delete this check-in record', 'event_espresso') . '">' |
|
| 162 | - . __('Delete', 'event_espresso') . '</a>' |
|
| 160 | + ? '<a href="'.$delete_url.'" title="' |
|
| 161 | + . esc_attr__('Click here to delete this check-in record', 'event_espresso').'">' |
|
| 162 | + . __('Delete', 'event_espresso').'</a>' |
|
| 163 | 163 | : ''; |
| 164 | 164 | |
| 165 | 165 | return sprintf( |
@@ -188,7 +188,7 @@ discard block |
||
| 188 | 188 | $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : false; |
| 189 | 189 | |
| 190 | 190 | // if user does not have the capability for the checkins for this registration then get out! |
| 191 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 191 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
| 192 | 192 | 'ee_read_checkin', |
| 193 | 193 | 'espresso_registrations_registration_checkins', |
| 194 | 194 | $REG_ID |
@@ -219,7 +219,7 @@ discard block |
||
| 219 | 219 | ? $this->_req_data['perpage'] |
| 220 | 220 | : $per_page; |
| 221 | 221 | $limit = null; |
| 222 | - if (! $count) { |
|
| 222 | + if ( ! $count) { |
|
| 223 | 223 | $offset = ($current_page - 1) * $per_page; |
| 224 | 224 | $limit = array($offset, $per_page); |
| 225 | 225 | } |
@@ -18,226 +18,226 @@ |
||
| 18 | 18 | class EE_Registration_CheckIn_List_Table extends EE_Admin_List_Table |
| 19 | 19 | { |
| 20 | 20 | |
| 21 | - /** |
|
| 22 | - * EE_Registration_CheckIn_List_Table constructor. |
|
| 23 | - * |
|
| 24 | - * @param EE_Admin_Page $admin_page |
|
| 25 | - */ |
|
| 26 | - public function __construct($admin_page) |
|
| 27 | - { |
|
| 28 | - parent::__construct($admin_page); |
|
| 29 | - } |
|
| 30 | - |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * @throws EE_Error |
|
| 34 | - */ |
|
| 35 | - protected function _setup_data() |
|
| 36 | - { |
|
| 37 | - $this->_data = $this->_get_checkins($this->_per_page); |
|
| 38 | - $this->_all_data_count = $this->_get_checkins($this->_per_page, true); |
|
| 39 | - } |
|
| 40 | - |
|
| 41 | - |
|
| 42 | - /** |
|
| 43 | - * Sets up the properties for the list table. |
|
| 44 | - */ |
|
| 45 | - protected function _set_properties() |
|
| 46 | - { |
|
| 47 | - $this->_wp_list_args = array( |
|
| 48 | - 'singular' => __('check-in', 'event_espresso'), |
|
| 49 | - 'plural' => __('check-ins', 'event_espresso'), |
|
| 50 | - 'ajax' => true, |
|
| 51 | - 'screen' => $this->_admin_page->get_current_screen()->id, |
|
| 52 | - ); |
|
| 53 | - |
|
| 54 | - $this->_columns = array( |
|
| 55 | - 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text |
|
| 56 | - 'CHK_in' => __('Check-In', 'event_espresso'), |
|
| 57 | - 'CHK_timestamp' => __('Timestamp', 'event_espresso'), |
|
| 58 | - ); |
|
| 59 | - |
|
| 60 | - $this->_sortable_columns = array( |
|
| 61 | - 'CHK_timestamp' => array('CHK_timestamp' => true), |
|
| 62 | - ); |
|
| 63 | - |
|
| 64 | - $this->_primary_column = 'CHK_in'; |
|
| 65 | - |
|
| 66 | - $this->_hidden_columns = array(); |
|
| 67 | - } |
|
| 68 | - |
|
| 69 | - |
|
| 70 | - /** |
|
| 71 | - * @return array |
|
| 72 | - */ |
|
| 73 | - protected function _get_table_filters() |
|
| 74 | - { |
|
| 75 | - return []; |
|
| 76 | - } |
|
| 77 | - |
|
| 78 | - |
|
| 79 | - /** |
|
| 80 | - * Returning an empty string to remove the search box for this view. |
|
| 81 | - * |
|
| 82 | - * @param string $text |
|
| 83 | - * @param string $input_id |
|
| 84 | - * @return string |
|
| 85 | - */ |
|
| 86 | - public function search_box($text, $input_id) |
|
| 87 | - { |
|
| 88 | - return ''; |
|
| 89 | - } |
|
| 90 | - |
|
| 91 | - |
|
| 92 | - /** |
|
| 93 | - * @throws EE_Error |
|
| 94 | - */ |
|
| 95 | - protected function _add_view_counts() |
|
| 96 | - { |
|
| 97 | - $this->_views['all']['count'] = $this->_get_checkins(null, true); |
|
| 98 | - } |
|
| 99 | - |
|
| 100 | - |
|
| 101 | - /** |
|
| 102 | - * @param EE_Checkin $item |
|
| 103 | - * @return string |
|
| 104 | - * @throws EE_Error |
|
| 105 | - * @throws InvalidArgumentException |
|
| 106 | - * @throws ReflectionException |
|
| 107 | - * @throws InvalidDataTypeException |
|
| 108 | - * @throws InvalidInterfaceException |
|
| 109 | - */ |
|
| 110 | - public function column_cb($item) |
|
| 111 | - { |
|
| 112 | - return sprintf('<input type="checkbox" name="checkbox[%1$s]" />', $item->ID()); |
|
| 113 | - } |
|
| 114 | - |
|
| 115 | - |
|
| 116 | - /** |
|
| 117 | - * @param EE_Checkin $item |
|
| 118 | - * @return string |
|
| 119 | - * @throws EE_Error |
|
| 120 | - * @throws InvalidArgumentException |
|
| 121 | - * @throws InvalidDataTypeException |
|
| 122 | - * @throws InvalidInterfaceException |
|
| 123 | - * @throws ReflectionException |
|
| 124 | - */ |
|
| 125 | - public function column_CHK_in(EE_Checkin $item) |
|
| 126 | - { |
|
| 127 | - $checkin_status_dashicon = CheckinStatusDashicon::fromCheckin($item); |
|
| 128 | - return '<span class="' |
|
| 129 | - . $checkin_status_dashicon->cssClasses() |
|
| 130 | - . '"></span><span class="show-on-mobile-view-only">' |
|
| 131 | - . $item->get_datetime('CHK_timestamp') |
|
| 132 | - . '</span>'; |
|
| 133 | - } |
|
| 134 | - |
|
| 135 | - |
|
| 136 | - /** |
|
| 137 | - * @param EE_Checkin $item |
|
| 138 | - * @return string |
|
| 139 | - * @throws EE_Error |
|
| 140 | - * @throws InvalidArgumentException |
|
| 141 | - * @throws InvalidDataTypeException |
|
| 142 | - * @throws InvalidInterfaceException |
|
| 143 | - * @throws ReflectionException |
|
| 144 | - */ |
|
| 145 | - public function column_CHK_timestamp(EE_Checkin $item) |
|
| 146 | - { |
|
| 147 | - $actions = array(); |
|
| 148 | - $delete_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 149 | - array( |
|
| 150 | - 'action' => 'delete_checkin_row', |
|
| 151 | - 'DTT_ID' => $this->_req_data['DTT_ID'], |
|
| 152 | - '_REG_ID' => $this->_req_data['_REG_ID'], |
|
| 153 | - 'CHK_ID' => $item->ID(), |
|
| 154 | - ) |
|
| 155 | - ); |
|
| 156 | - $actions['delete_checkin'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 157 | - 'ee_delete_checkins', |
|
| 158 | - 'espresso_registrations_delete_checkin_row' |
|
| 159 | - ) |
|
| 160 | - ? '<a href="' . $delete_url . '" title="' |
|
| 161 | - . esc_attr__('Click here to delete this check-in record', 'event_espresso') . '">' |
|
| 162 | - . __('Delete', 'event_espresso') . '</a>' |
|
| 163 | - : ''; |
|
| 164 | - |
|
| 165 | - return sprintf( |
|
| 166 | - '%1$s %2$s', |
|
| 167 | - $item->get_datetime('CHK_timestamp', '', 'H:i:s a'), |
|
| 168 | - $this->row_actions($actions) |
|
| 169 | - ); |
|
| 170 | - } |
|
| 171 | - |
|
| 172 | - |
|
| 173 | - /** |
|
| 174 | - * This retrieves all the Check-ins for the given parameters. |
|
| 175 | - * experimenting with having the query for the table values within the list table. |
|
| 176 | - * |
|
| 177 | - * @param int $per_page How many to retrieve per page |
|
| 178 | - * @param bool $count Whether to return a count or not |
|
| 179 | - * @return EE_Checkin[]|int |
|
| 180 | - * @throws EE_Error |
|
| 181 | - * @throws InvalidArgumentException |
|
| 182 | - * @throws InvalidDataTypeException |
|
| 183 | - * @throws InvalidInterfaceException |
|
| 184 | - */ |
|
| 185 | - protected function _get_checkins($per_page = 10, $count = false) |
|
| 186 | - { |
|
| 187 | - $REG_ID = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : false; |
|
| 188 | - $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : false; |
|
| 189 | - |
|
| 190 | - // if user does not have the capability for the checkins for this registration then get out! |
|
| 191 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 192 | - 'ee_read_checkin', |
|
| 193 | - 'espresso_registrations_registration_checkins', |
|
| 194 | - $REG_ID |
|
| 195 | - )) { |
|
| 196 | - return $count ? 0 : array(); |
|
| 197 | - } |
|
| 198 | - |
|
| 199 | - // if no reg id then get out cause need a reg id |
|
| 200 | - if (empty($REG_ID) || empty($DTT_ID)) { |
|
| 201 | - throw new EE_Error( |
|
| 202 | - __( |
|
| 203 | - 'This route cannot be viewed unless registration and datetime IDs are included in the request (via REG_ID and DTT_ID parameters)', |
|
| 204 | - 'event_espresso' |
|
| 205 | - ) |
|
| 206 | - ); |
|
| 207 | - } |
|
| 208 | - |
|
| 209 | - // set orderby |
|
| 210 | - // note that with this table we're only providing the option to orderby the timestamp value. |
|
| 211 | - $orderby = 'CHK_timestamp'; |
|
| 212 | - |
|
| 213 | - $order = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 214 | - |
|
| 215 | - $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged']) |
|
| 216 | - ? $this->_req_data['paged'] |
|
| 217 | - : 1; |
|
| 218 | - $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage']) |
|
| 219 | - ? $this->_req_data['perpage'] |
|
| 220 | - : $per_page; |
|
| 221 | - $limit = null; |
|
| 222 | - if (! $count) { |
|
| 223 | - $offset = ($current_page - 1) * $per_page; |
|
| 224 | - $limit = array($offset, $per_page); |
|
| 225 | - } |
|
| 226 | - |
|
| 227 | - $_where = array( |
|
| 228 | - 'REG_ID' => $REG_ID, |
|
| 229 | - 'DTT_ID' => $DTT_ID, |
|
| 230 | - ); |
|
| 231 | - |
|
| 232 | - $query_params = array($_where, 'order_by' => array($orderby => $order), 'limit' => $limit); |
|
| 233 | - |
|
| 234 | - // if no per_page value then we just want to return a count of all Check-ins |
|
| 235 | - if ($count) { |
|
| 236 | - return EEM_Checkin::instance()->count(array($_where)); |
|
| 237 | - } |
|
| 238 | - |
|
| 239 | - return $count |
|
| 240 | - ? EEM_Checkin::instance()->count(array($_where)) |
|
| 241 | - : EEM_Checkin::instance()->get_all($query_params); |
|
| 242 | - } |
|
| 21 | + /** |
|
| 22 | + * EE_Registration_CheckIn_List_Table constructor. |
|
| 23 | + * |
|
| 24 | + * @param EE_Admin_Page $admin_page |
|
| 25 | + */ |
|
| 26 | + public function __construct($admin_page) |
|
| 27 | + { |
|
| 28 | + parent::__construct($admin_page); |
|
| 29 | + } |
|
| 30 | + |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * @throws EE_Error |
|
| 34 | + */ |
|
| 35 | + protected function _setup_data() |
|
| 36 | + { |
|
| 37 | + $this->_data = $this->_get_checkins($this->_per_page); |
|
| 38 | + $this->_all_data_count = $this->_get_checkins($this->_per_page, true); |
|
| 39 | + } |
|
| 40 | + |
|
| 41 | + |
|
| 42 | + /** |
|
| 43 | + * Sets up the properties for the list table. |
|
| 44 | + */ |
|
| 45 | + protected function _set_properties() |
|
| 46 | + { |
|
| 47 | + $this->_wp_list_args = array( |
|
| 48 | + 'singular' => __('check-in', 'event_espresso'), |
|
| 49 | + 'plural' => __('check-ins', 'event_espresso'), |
|
| 50 | + 'ajax' => true, |
|
| 51 | + 'screen' => $this->_admin_page->get_current_screen()->id, |
|
| 52 | + ); |
|
| 53 | + |
|
| 54 | + $this->_columns = array( |
|
| 55 | + 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text |
|
| 56 | + 'CHK_in' => __('Check-In', 'event_espresso'), |
|
| 57 | + 'CHK_timestamp' => __('Timestamp', 'event_espresso'), |
|
| 58 | + ); |
|
| 59 | + |
|
| 60 | + $this->_sortable_columns = array( |
|
| 61 | + 'CHK_timestamp' => array('CHK_timestamp' => true), |
|
| 62 | + ); |
|
| 63 | + |
|
| 64 | + $this->_primary_column = 'CHK_in'; |
|
| 65 | + |
|
| 66 | + $this->_hidden_columns = array(); |
|
| 67 | + } |
|
| 68 | + |
|
| 69 | + |
|
| 70 | + /** |
|
| 71 | + * @return array |
|
| 72 | + */ |
|
| 73 | + protected function _get_table_filters() |
|
| 74 | + { |
|
| 75 | + return []; |
|
| 76 | + } |
|
| 77 | + |
|
| 78 | + |
|
| 79 | + /** |
|
| 80 | + * Returning an empty string to remove the search box for this view. |
|
| 81 | + * |
|
| 82 | + * @param string $text |
|
| 83 | + * @param string $input_id |
|
| 84 | + * @return string |
|
| 85 | + */ |
|
| 86 | + public function search_box($text, $input_id) |
|
| 87 | + { |
|
| 88 | + return ''; |
|
| 89 | + } |
|
| 90 | + |
|
| 91 | + |
|
| 92 | + /** |
|
| 93 | + * @throws EE_Error |
|
| 94 | + */ |
|
| 95 | + protected function _add_view_counts() |
|
| 96 | + { |
|
| 97 | + $this->_views['all']['count'] = $this->_get_checkins(null, true); |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + |
|
| 101 | + /** |
|
| 102 | + * @param EE_Checkin $item |
|
| 103 | + * @return string |
|
| 104 | + * @throws EE_Error |
|
| 105 | + * @throws InvalidArgumentException |
|
| 106 | + * @throws ReflectionException |
|
| 107 | + * @throws InvalidDataTypeException |
|
| 108 | + * @throws InvalidInterfaceException |
|
| 109 | + */ |
|
| 110 | + public function column_cb($item) |
|
| 111 | + { |
|
| 112 | + return sprintf('<input type="checkbox" name="checkbox[%1$s]" />', $item->ID()); |
|
| 113 | + } |
|
| 114 | + |
|
| 115 | + |
|
| 116 | + /** |
|
| 117 | + * @param EE_Checkin $item |
|
| 118 | + * @return string |
|
| 119 | + * @throws EE_Error |
|
| 120 | + * @throws InvalidArgumentException |
|
| 121 | + * @throws InvalidDataTypeException |
|
| 122 | + * @throws InvalidInterfaceException |
|
| 123 | + * @throws ReflectionException |
|
| 124 | + */ |
|
| 125 | + public function column_CHK_in(EE_Checkin $item) |
|
| 126 | + { |
|
| 127 | + $checkin_status_dashicon = CheckinStatusDashicon::fromCheckin($item); |
|
| 128 | + return '<span class="' |
|
| 129 | + . $checkin_status_dashicon->cssClasses() |
|
| 130 | + . '"></span><span class="show-on-mobile-view-only">' |
|
| 131 | + . $item->get_datetime('CHK_timestamp') |
|
| 132 | + . '</span>'; |
|
| 133 | + } |
|
| 134 | + |
|
| 135 | + |
|
| 136 | + /** |
|
| 137 | + * @param EE_Checkin $item |
|
| 138 | + * @return string |
|
| 139 | + * @throws EE_Error |
|
| 140 | + * @throws InvalidArgumentException |
|
| 141 | + * @throws InvalidDataTypeException |
|
| 142 | + * @throws InvalidInterfaceException |
|
| 143 | + * @throws ReflectionException |
|
| 144 | + */ |
|
| 145 | + public function column_CHK_timestamp(EE_Checkin $item) |
|
| 146 | + { |
|
| 147 | + $actions = array(); |
|
| 148 | + $delete_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 149 | + array( |
|
| 150 | + 'action' => 'delete_checkin_row', |
|
| 151 | + 'DTT_ID' => $this->_req_data['DTT_ID'], |
|
| 152 | + '_REG_ID' => $this->_req_data['_REG_ID'], |
|
| 153 | + 'CHK_ID' => $item->ID(), |
|
| 154 | + ) |
|
| 155 | + ); |
|
| 156 | + $actions['delete_checkin'] = EE_Registry::instance()->CAP->current_user_can( |
|
| 157 | + 'ee_delete_checkins', |
|
| 158 | + 'espresso_registrations_delete_checkin_row' |
|
| 159 | + ) |
|
| 160 | + ? '<a href="' . $delete_url . '" title="' |
|
| 161 | + . esc_attr__('Click here to delete this check-in record', 'event_espresso') . '">' |
|
| 162 | + . __('Delete', 'event_espresso') . '</a>' |
|
| 163 | + : ''; |
|
| 164 | + |
|
| 165 | + return sprintf( |
|
| 166 | + '%1$s %2$s', |
|
| 167 | + $item->get_datetime('CHK_timestamp', '', 'H:i:s a'), |
|
| 168 | + $this->row_actions($actions) |
|
| 169 | + ); |
|
| 170 | + } |
|
| 171 | + |
|
| 172 | + |
|
| 173 | + /** |
|
| 174 | + * This retrieves all the Check-ins for the given parameters. |
|
| 175 | + * experimenting with having the query for the table values within the list table. |
|
| 176 | + * |
|
| 177 | + * @param int $per_page How many to retrieve per page |
|
| 178 | + * @param bool $count Whether to return a count or not |
|
| 179 | + * @return EE_Checkin[]|int |
|
| 180 | + * @throws EE_Error |
|
| 181 | + * @throws InvalidArgumentException |
|
| 182 | + * @throws InvalidDataTypeException |
|
| 183 | + * @throws InvalidInterfaceException |
|
| 184 | + */ |
|
| 185 | + protected function _get_checkins($per_page = 10, $count = false) |
|
| 186 | + { |
|
| 187 | + $REG_ID = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : false; |
|
| 188 | + $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : false; |
|
| 189 | + |
|
| 190 | + // if user does not have the capability for the checkins for this registration then get out! |
|
| 191 | + if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 192 | + 'ee_read_checkin', |
|
| 193 | + 'espresso_registrations_registration_checkins', |
|
| 194 | + $REG_ID |
|
| 195 | + )) { |
|
| 196 | + return $count ? 0 : array(); |
|
| 197 | + } |
|
| 198 | + |
|
| 199 | + // if no reg id then get out cause need a reg id |
|
| 200 | + if (empty($REG_ID) || empty($DTT_ID)) { |
|
| 201 | + throw new EE_Error( |
|
| 202 | + __( |
|
| 203 | + 'This route cannot be viewed unless registration and datetime IDs are included in the request (via REG_ID and DTT_ID parameters)', |
|
| 204 | + 'event_espresso' |
|
| 205 | + ) |
|
| 206 | + ); |
|
| 207 | + } |
|
| 208 | + |
|
| 209 | + // set orderby |
|
| 210 | + // note that with this table we're only providing the option to orderby the timestamp value. |
|
| 211 | + $orderby = 'CHK_timestamp'; |
|
| 212 | + |
|
| 213 | + $order = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 214 | + |
|
| 215 | + $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged']) |
|
| 216 | + ? $this->_req_data['paged'] |
|
| 217 | + : 1; |
|
| 218 | + $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage']) |
|
| 219 | + ? $this->_req_data['perpage'] |
|
| 220 | + : $per_page; |
|
| 221 | + $limit = null; |
|
| 222 | + if (! $count) { |
|
| 223 | + $offset = ($current_page - 1) * $per_page; |
|
| 224 | + $limit = array($offset, $per_page); |
|
| 225 | + } |
|
| 226 | + |
|
| 227 | + $_where = array( |
|
| 228 | + 'REG_ID' => $REG_ID, |
|
| 229 | + 'DTT_ID' => $DTT_ID, |
|
| 230 | + ); |
|
| 231 | + |
|
| 232 | + $query_params = array($_where, 'order_by' => array($orderby => $order), 'limit' => $limit); |
|
| 233 | + |
|
| 234 | + // if no per_page value then we just want to return a count of all Check-ins |
|
| 235 | + if ($count) { |
|
| 236 | + return EEM_Checkin::instance()->count(array($_where)); |
|
| 237 | + } |
|
| 238 | + |
|
| 239 | + return $count |
|
| 240 | + ? EEM_Checkin::instance()->count(array($_where)) |
|
| 241 | + : EEM_Checkin::instance()->get_all($query_params); |
|
| 242 | + } |
|
| 243 | 243 | } |
@@ -14,27 +14,27 @@ |
||
| 14 | 14 | class EE_Admin_File_Uploader_Input extends EE_Form_Input_Base |
| 15 | 15 | { |
| 16 | 16 | |
| 17 | - /** |
|
| 18 | - * @param array $input_settings |
|
| 19 | - * @throws InvalidArgumentException |
|
| 20 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 21 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 22 | - */ |
|
| 23 | - public function __construct($input_settings = array()) |
|
| 24 | - { |
|
| 25 | - $this->_set_display_strategy(new EE_Admin_File_Uploader_Display_Strategy()); |
|
| 26 | - $this->_set_normalization_strategy(new EE_Text_Normalization()); |
|
| 27 | - $this->_add_validation_strategy( |
|
| 28 | - LoaderFactory::getLoader()->getNew( |
|
| 29 | - 'EE_URL_Validation_Strategy', |
|
| 30 | - array( |
|
| 31 | - isset($input_settings['validation_error_message']) |
|
| 32 | - ? $input_settings['validation_error_message'] |
|
| 33 | - : null, |
|
| 34 | - false |
|
| 35 | - ) |
|
| 36 | - ) |
|
| 37 | - ); |
|
| 38 | - parent::__construct($input_settings); |
|
| 39 | - } |
|
| 17 | + /** |
|
| 18 | + * @param array $input_settings |
|
| 19 | + * @throws InvalidArgumentException |
|
| 20 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 21 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 22 | + */ |
|
| 23 | + public function __construct($input_settings = array()) |
|
| 24 | + { |
|
| 25 | + $this->_set_display_strategy(new EE_Admin_File_Uploader_Display_Strategy()); |
|
| 26 | + $this->_set_normalization_strategy(new EE_Text_Normalization()); |
|
| 27 | + $this->_add_validation_strategy( |
|
| 28 | + LoaderFactory::getLoader()->getNew( |
|
| 29 | + 'EE_URL_Validation_Strategy', |
|
| 30 | + array( |
|
| 31 | + isset($input_settings['validation_error_message']) |
|
| 32 | + ? $input_settings['validation_error_message'] |
|
| 33 | + : null, |
|
| 34 | + false |
|
| 35 | + ) |
|
| 36 | + ) |
|
| 37 | + ); |
|
| 38 | + parent::__construct($input_settings); |
|
| 39 | + } |
|
| 40 | 40 | } |
@@ -17,4111 +17,4111 @@ |
||
| 17 | 17 | abstract class EE_Admin_Page extends EE_Base implements InterminableInterface |
| 18 | 18 | { |
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * @var LoaderInterface $loader |
|
| 22 | - */ |
|
| 23 | - protected $loader; |
|
| 20 | + /** |
|
| 21 | + * @var LoaderInterface $loader |
|
| 22 | + */ |
|
| 23 | + protected $loader; |
|
| 24 | 24 | |
| 25 | - // set in _init_page_props() |
|
| 26 | - public $page_slug; |
|
| 25 | + // set in _init_page_props() |
|
| 26 | + public $page_slug; |
|
| 27 | 27 | |
| 28 | - public $page_label; |
|
| 28 | + public $page_label; |
|
| 29 | 29 | |
| 30 | - public $page_folder; |
|
| 30 | + public $page_folder; |
|
| 31 | 31 | |
| 32 | - // set in define_page_props() |
|
| 33 | - protected $_admin_base_url; |
|
| 32 | + // set in define_page_props() |
|
| 33 | + protected $_admin_base_url; |
|
| 34 | 34 | |
| 35 | - protected $_admin_base_path; |
|
| 35 | + protected $_admin_base_path; |
|
| 36 | 36 | |
| 37 | - protected $_admin_page_title; |
|
| 37 | + protected $_admin_page_title; |
|
| 38 | 38 | |
| 39 | - protected $_labels; |
|
| 39 | + protected $_labels; |
|
| 40 | 40 | |
| 41 | 41 | |
| 42 | - // set early within EE_Admin_Init |
|
| 43 | - protected $_wp_page_slug; |
|
| 42 | + // set early within EE_Admin_Init |
|
| 43 | + protected $_wp_page_slug; |
|
| 44 | 44 | |
| 45 | - // navtabs |
|
| 46 | - protected $_nav_tabs; |
|
| 45 | + // navtabs |
|
| 46 | + protected $_nav_tabs; |
|
| 47 | 47 | |
| 48 | - protected $_default_nav_tab_name; |
|
| 48 | + protected $_default_nav_tab_name; |
|
| 49 | 49 | |
| 50 | - /** |
|
| 51 | - * @var array $_help_tour |
|
| 52 | - */ |
|
| 53 | - protected $_help_tour = array(); |
|
| 50 | + /** |
|
| 51 | + * @var array $_help_tour |
|
| 52 | + */ |
|
| 53 | + protected $_help_tour = array(); |
|
| 54 | 54 | |
| 55 | 55 | |
| 56 | - // template variables (used by templates) |
|
| 57 | - protected $_template_path; |
|
| 56 | + // template variables (used by templates) |
|
| 57 | + protected $_template_path; |
|
| 58 | 58 | |
| 59 | - protected $_column_template_path; |
|
| 59 | + protected $_column_template_path; |
|
| 60 | 60 | |
| 61 | - /** |
|
| 62 | - * @var array $_template_args |
|
| 63 | - */ |
|
| 64 | - protected $_template_args = array(); |
|
| 61 | + /** |
|
| 62 | + * @var array $_template_args |
|
| 63 | + */ |
|
| 64 | + protected $_template_args = array(); |
|
| 65 | 65 | |
| 66 | - /** |
|
| 67 | - * this will hold the list table object for a given view. |
|
| 68 | - * |
|
| 69 | - * @var EE_Admin_List_Table $_list_table_object |
|
| 70 | - */ |
|
| 71 | - protected $_list_table_object; |
|
| 66 | + /** |
|
| 67 | + * this will hold the list table object for a given view. |
|
| 68 | + * |
|
| 69 | + * @var EE_Admin_List_Table $_list_table_object |
|
| 70 | + */ |
|
| 71 | + protected $_list_table_object; |
|
| 72 | 72 | |
| 73 | - // bools |
|
| 74 | - protected $_is_UI_request = null; // this starts at null so we can have no header routes progress through two states. |
|
| 73 | + // bools |
|
| 74 | + protected $_is_UI_request = null; // this starts at null so we can have no header routes progress through two states. |
|
| 75 | 75 | |
| 76 | - protected $_routing; |
|
| 76 | + protected $_routing; |
|
| 77 | 77 | |
| 78 | - // list table args |
|
| 79 | - protected $_view; |
|
| 78 | + // list table args |
|
| 79 | + protected $_view; |
|
| 80 | 80 | |
| 81 | - protected $_views; |
|
| 81 | + protected $_views; |
|
| 82 | 82 | |
| 83 | 83 | |
| 84 | - // action => method pairs used for routing incoming requests |
|
| 85 | - protected $_page_routes; |
|
| 84 | + // action => method pairs used for routing incoming requests |
|
| 85 | + protected $_page_routes; |
|
| 86 | 86 | |
| 87 | - /** |
|
| 88 | - * @var array $_page_config |
|
| 89 | - */ |
|
| 90 | - protected $_page_config; |
|
| 87 | + /** |
|
| 88 | + * @var array $_page_config |
|
| 89 | + */ |
|
| 90 | + protected $_page_config; |
|
| 91 | 91 | |
| 92 | - /** |
|
| 93 | - * the current page route and route config |
|
| 94 | - * |
|
| 95 | - * @var string $_route |
|
| 96 | - */ |
|
| 97 | - protected $_route; |
|
| 92 | + /** |
|
| 93 | + * the current page route and route config |
|
| 94 | + * |
|
| 95 | + * @var string $_route |
|
| 96 | + */ |
|
| 97 | + protected $_route; |
|
| 98 | 98 | |
| 99 | - /** |
|
| 100 | - * @var string $_cpt_route |
|
| 101 | - */ |
|
| 102 | - protected $_cpt_route; |
|
| 99 | + /** |
|
| 100 | + * @var string $_cpt_route |
|
| 101 | + */ |
|
| 102 | + protected $_cpt_route; |
|
| 103 | 103 | |
| 104 | - /** |
|
| 105 | - * @var array $_route_config |
|
| 106 | - */ |
|
| 107 | - protected $_route_config; |
|
| 108 | - |
|
| 109 | - /** |
|
| 110 | - * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out |
|
| 111 | - * actions. |
|
| 112 | - * |
|
| 113 | - * @since 4.6.x |
|
| 114 | - * @var array. |
|
| 115 | - */ |
|
| 116 | - protected $_default_route_query_args; |
|
| 117 | - |
|
| 118 | - // set via request page and action args. |
|
| 119 | - protected $_current_page; |
|
| 120 | - |
|
| 121 | - protected $_current_view; |
|
| 122 | - |
|
| 123 | - protected $_current_page_view_url; |
|
| 124 | - |
|
| 125 | - // sanitized request action (and nonce) |
|
| 126 | - |
|
| 127 | - /** |
|
| 128 | - * @var string $_req_action |
|
| 129 | - */ |
|
| 130 | - protected $_req_action; |
|
| 131 | - |
|
| 132 | - /** |
|
| 133 | - * @var string $_req_nonce |
|
| 134 | - */ |
|
| 135 | - protected $_req_nonce; |
|
| 136 | - |
|
| 137 | - // search related |
|
| 138 | - protected $_search_btn_label; |
|
| 139 | - |
|
| 140 | - protected $_search_box_callback; |
|
| 141 | - |
|
| 142 | - /** |
|
| 143 | - * WP Current Screen object |
|
| 144 | - * |
|
| 145 | - * @var WP_Screen |
|
| 146 | - */ |
|
| 147 | - protected $_current_screen; |
|
| 148 | - |
|
| 149 | - // for holding EE_Admin_Hooks object when needed (set via set_hook_object()) |
|
| 150 | - protected $_hook_obj; |
|
| 151 | - |
|
| 152 | - // for holding incoming request data |
|
| 153 | - protected $_req_data; |
|
| 154 | - |
|
| 155 | - // yes / no array for admin form fields |
|
| 156 | - protected $_yes_no_values = array(); |
|
| 157 | - |
|
| 158 | - // some default things shared by all child classes |
|
| 159 | - protected $_default_espresso_metaboxes; |
|
| 160 | - |
|
| 161 | - /** |
|
| 162 | - * EE_Registry Object |
|
| 163 | - * |
|
| 164 | - * @var EE_Registry |
|
| 165 | - */ |
|
| 166 | - protected $EE = null; |
|
| 167 | - |
|
| 168 | - |
|
| 169 | - /** |
|
| 170 | - * This is just a property that flags whether the given route is a caffeinated route or not. |
|
| 171 | - * |
|
| 172 | - * @var boolean |
|
| 173 | - */ |
|
| 174 | - protected $_is_caf = false; |
|
| 175 | - |
|
| 176 | - |
|
| 177 | - /** |
|
| 178 | - * @Constructor |
|
| 179 | - * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object. |
|
| 180 | - * @throws EE_Error |
|
| 181 | - * @throws InvalidArgumentException |
|
| 182 | - * @throws ReflectionException |
|
| 183 | - * @throws InvalidDataTypeException |
|
| 184 | - * @throws InvalidInterfaceException |
|
| 185 | - */ |
|
| 186 | - public function __construct($routing = true) |
|
| 187 | - { |
|
| 188 | - $this->loader = LoaderFactory::getLoader(); |
|
| 189 | - if (strpos($this->_get_dir(), 'caffeinated') !== false) { |
|
| 190 | - $this->_is_caf = true; |
|
| 191 | - } |
|
| 192 | - $this->_yes_no_values = array( |
|
| 193 | - array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')), |
|
| 194 | - array('id' => false, 'text' => esc_html__('No', 'event_espresso')), |
|
| 195 | - ); |
|
| 196 | - // set the _req_data property. |
|
| 197 | - $this->_req_data = array_merge($_GET, $_POST); |
|
| 198 | - // routing enabled? |
|
| 199 | - $this->_routing = $routing; |
|
| 200 | - // set initial page props (child method) |
|
| 201 | - $this->_init_page_props(); |
|
| 202 | - // set global defaults |
|
| 203 | - $this->_set_defaults(); |
|
| 204 | - // set early because incoming requests could be ajax related and we need to register those hooks. |
|
| 205 | - $this->_global_ajax_hooks(); |
|
| 206 | - $this->_ajax_hooks(); |
|
| 207 | - // other_page_hooks have to be early too. |
|
| 208 | - $this->_do_other_page_hooks(); |
|
| 209 | - // This just allows us to have extending classes do something specific |
|
| 210 | - // before the parent constructor runs _page_setup(). |
|
| 211 | - if (method_exists($this, '_before_page_setup')) { |
|
| 212 | - $this->_before_page_setup(); |
|
| 213 | - } |
|
| 214 | - // set up page dependencies |
|
| 215 | - $this->_page_setup(); |
|
| 216 | - } |
|
| 217 | - |
|
| 218 | - |
|
| 219 | - /** |
|
| 220 | - * _init_page_props |
|
| 221 | - * Child classes use to set at least the following properties: |
|
| 222 | - * $page_slug. |
|
| 223 | - * $page_label. |
|
| 224 | - * |
|
| 225 | - * @abstract |
|
| 226 | - * @return void |
|
| 227 | - */ |
|
| 228 | - abstract protected function _init_page_props(); |
|
| 229 | - |
|
| 230 | - |
|
| 231 | - /** |
|
| 232 | - * _ajax_hooks |
|
| 233 | - * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here. |
|
| 234 | - * Note: within the ajax callback methods. |
|
| 235 | - * |
|
| 236 | - * @abstract |
|
| 237 | - * @return void |
|
| 238 | - */ |
|
| 239 | - abstract protected function _ajax_hooks(); |
|
| 240 | - |
|
| 241 | - |
|
| 242 | - /** |
|
| 243 | - * _define_page_props |
|
| 244 | - * child classes define page properties in here. Must include at least: |
|
| 245 | - * $_admin_base_url = base_url for all admin pages |
|
| 246 | - * $_admin_page_title = default admin_page_title for admin pages |
|
| 247 | - * $_labels = array of default labels for various automatically generated elements: |
|
| 248 | - * array( |
|
| 249 | - * 'buttons' => array( |
|
| 250 | - * 'add' => esc_html__('label for add new button'), |
|
| 251 | - * 'edit' => esc_html__('label for edit button'), |
|
| 252 | - * 'delete' => esc_html__('label for delete button') |
|
| 253 | - * ) |
|
| 254 | - * ) |
|
| 255 | - * |
|
| 256 | - * @abstract |
|
| 257 | - * @return void |
|
| 258 | - */ |
|
| 259 | - abstract protected function _define_page_props(); |
|
| 260 | - |
|
| 261 | - |
|
| 262 | - /** |
|
| 263 | - * _set_page_routes |
|
| 264 | - * child classes use this to define the page routes for all subpages handled by the class. Page routes are |
|
| 265 | - * assigned to a action => method pairs in an array and to the $_page_routes property. Each page route must also |
|
| 266 | - * have a 'default' route. Here's the format |
|
| 267 | - * $this->_page_routes = array( |
|
| 268 | - * 'default' => array( |
|
| 269 | - * 'func' => '_default_method_handling_route', |
|
| 270 | - * 'args' => array('array','of','args'), |
|
| 271 | - * 'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e. |
|
| 272 | - * ajax request, backend processing) |
|
| 273 | - * 'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a |
|
| 274 | - * headers route after. The string you enter here should match the defined route reference for a |
|
| 275 | - * headers sent route. |
|
| 276 | - * 'capability' => 'route_capability', //indicate a string for minimum capability required to access |
|
| 277 | - * this route. |
|
| 278 | - * 'obj_id' => 10 // if this route has an object id, then this can include it (used for capability |
|
| 279 | - * checks). |
|
| 280 | - * ), |
|
| 281 | - * 'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a |
|
| 282 | - * handling method. |
|
| 283 | - * ) |
|
| 284 | - * ) |
|
| 285 | - * |
|
| 286 | - * @abstract |
|
| 287 | - * @return void |
|
| 288 | - */ |
|
| 289 | - abstract protected function _set_page_routes(); |
|
| 290 | - |
|
| 291 | - |
|
| 292 | - /** |
|
| 293 | - * _set_page_config |
|
| 294 | - * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the |
|
| 295 | - * array corresponds to the page_route for the loaded page. Format: |
|
| 296 | - * $this->_page_config = array( |
|
| 297 | - * 'default' => array( |
|
| 298 | - * 'labels' => array( |
|
| 299 | - * 'buttons' => array( |
|
| 300 | - * 'add' => esc_html__('label for adding item'), |
|
| 301 | - * 'edit' => esc_html__('label for editing item'), |
|
| 302 | - * 'delete' => esc_html__('label for deleting item') |
|
| 303 | - * ), |
|
| 304 | - * 'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso') |
|
| 305 | - * ), //optional an array of custom labels for various automatically generated elements to use on the |
|
| 306 | - * page. If this isn't present then the defaults will be used as set for the $this->_labels in |
|
| 307 | - * _define_page_props() method |
|
| 308 | - * 'nav' => array( |
|
| 309 | - * 'label' => esc_html__('Label for Tab', 'event_espresso'). |
|
| 310 | - * 'url' => 'http://someurl', //automatically generated UNLESS you define |
|
| 311 | - * 'css_class' => 'css-class', //automatically generated UNLESS you define |
|
| 312 | - * 'order' => 10, //required to indicate tab position. |
|
| 313 | - * 'persistent' => false //if you want the nav tab to ONLY display when the specific route is |
|
| 314 | - * displayed then add this parameter. |
|
| 315 | - * 'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page. |
|
| 316 | - * 'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load |
|
| 317 | - * metaboxes set for eventespresso admin pages. |
|
| 318 | - * 'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have |
|
| 319 | - * metaboxes. Typically this is used if the 'metaboxes' index is not used because metaboxes are added |
|
| 320 | - * later. We just use this flag to make sure the necessary js gets enqueued on page load. |
|
| 321 | - * 'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the |
|
| 322 | - * given route has help popups setup and if it does then we need to make sure thickbox is enqueued. |
|
| 323 | - * 'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes). The |
|
| 324 | - * array indicates the max number of columns (4) and the default number of columns on page load (2). |
|
| 325 | - * There is an option in the "screen_options" dropdown that is setup so users can pick what columns they |
|
| 326 | - * want to display. |
|
| 327 | - * 'help_tabs' => array( //this is used for adding help tabs to a page |
|
| 328 | - * 'tab_id' => array( |
|
| 329 | - * 'title' => 'tab_title', |
|
| 330 | - * 'filename' => 'name_of_file_containing_content', //this is the primary method for setting |
|
| 331 | - * help tab content. The fallback if it isn't present is to try a the callback. Filename |
|
| 332 | - * should match a file in the admin folder's "help_tabs" dir (ie.. |
|
| 333 | - * events/help_tabs/name_of_file_containing_content.help_tab.php) |
|
| 334 | - * 'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will |
|
| 335 | - * attempt to use the callback which should match the name of a method in the class |
|
| 336 | - * ), |
|
| 337 | - * 'tab2_id' => array( |
|
| 338 | - * 'title' => 'tab2 title', |
|
| 339 | - * 'filename' => 'file_name_2' |
|
| 340 | - * 'callback' => 'callback_method_for_content', |
|
| 341 | - * ), |
|
| 342 | - * 'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the |
|
| 343 | - * help tab area on an admin page. @link |
|
| 344 | - * http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/ |
|
| 345 | - * 'help_tour' => array( |
|
| 346 | - * 'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located |
|
| 347 | - * in a folder for this admin page named "help_tours", a file name matching the key given here |
|
| 348 | - * (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class) |
|
| 349 | - * ), |
|
| 350 | - * 'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is |
|
| 351 | - * true if it isn't present). To remove the requirement for a nonce check when this route is visited |
|
| 352 | - * just set |
|
| 353 | - * 'require_nonce' to FALSE |
|
| 354 | - * ) |
|
| 355 | - * ) |
|
| 356 | - * |
|
| 357 | - * @abstract |
|
| 358 | - * @return void |
|
| 359 | - */ |
|
| 360 | - abstract protected function _set_page_config(); |
|
| 361 | - |
|
| 362 | - |
|
| 363 | - |
|
| 364 | - |
|
| 365 | - |
|
| 366 | - /** end sample help_tour methods **/ |
|
| 367 | - /** |
|
| 368 | - * _add_screen_options |
|
| 369 | - * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for |
|
| 370 | - * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options |
|
| 371 | - * to a particular view. |
|
| 372 | - * |
|
| 373 | - * @link http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/ |
|
| 374 | - * see also WP_Screen object documents... |
|
| 375 | - * @link http://codex.wordpress.org/Class_Reference/WP_Screen |
|
| 376 | - * @abstract |
|
| 377 | - * @return void |
|
| 378 | - */ |
|
| 379 | - abstract protected function _add_screen_options(); |
|
| 380 | - |
|
| 381 | - |
|
| 382 | - /** |
|
| 383 | - * _add_feature_pointers |
|
| 384 | - * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js). |
|
| 385 | - * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a |
|
| 386 | - * particular view. Note: this is just a placeholder for now. Implementation will come down the road See: |
|
| 387 | - * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be |
|
| 388 | - * extended) also see: |
|
| 389 | - * |
|
| 390 | - * @link http://eamann.com/tech/wordpress-portland/ |
|
| 391 | - * @abstract |
|
| 392 | - * @return void |
|
| 393 | - */ |
|
| 394 | - abstract protected function _add_feature_pointers(); |
|
| 395 | - |
|
| 396 | - |
|
| 397 | - /** |
|
| 398 | - * load_scripts_styles |
|
| 399 | - * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for |
|
| 400 | - * their pages/subpages. Note this is for all pages/subpages of the system. You can also load only specific |
|
| 401 | - * scripts/styles per view by putting them in a dynamic function in this format |
|
| 402 | - * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg) |
|
| 403 | - * |
|
| 404 | - * @abstract |
|
| 405 | - * @return void |
|
| 406 | - */ |
|
| 407 | - abstract public function load_scripts_styles(); |
|
| 408 | - |
|
| 409 | - |
|
| 410 | - /** |
|
| 411 | - * admin_init |
|
| 412 | - * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here. This will apply to |
|
| 413 | - * all pages/views loaded by child class. |
|
| 414 | - * |
|
| 415 | - * @abstract |
|
| 416 | - * @return void |
|
| 417 | - */ |
|
| 418 | - abstract public function admin_init(); |
|
| 419 | - |
|
| 420 | - |
|
| 421 | - /** |
|
| 422 | - * admin_notices |
|
| 423 | - * Anything triggered by the 'admin_notices' WP hook should be put in here. This particular method will apply to |
|
| 424 | - * all pages/views loaded by child class. |
|
| 425 | - * |
|
| 426 | - * @abstract |
|
| 427 | - * @return void |
|
| 428 | - */ |
|
| 429 | - abstract public function admin_notices(); |
|
| 430 | - |
|
| 431 | - |
|
| 432 | - /** |
|
| 433 | - * admin_footer_scripts |
|
| 434 | - * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method |
|
| 435 | - * will apply to all pages/views loaded by child class. |
|
| 436 | - * |
|
| 437 | - * @return void |
|
| 438 | - */ |
|
| 439 | - abstract public function admin_footer_scripts(); |
|
| 440 | - |
|
| 441 | - |
|
| 442 | - /** |
|
| 443 | - * admin_footer |
|
| 444 | - * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will |
|
| 445 | - * apply to all pages/views loaded by child class. |
|
| 446 | - * |
|
| 447 | - * @return void |
|
| 448 | - */ |
|
| 449 | - public function admin_footer() |
|
| 450 | - { |
|
| 451 | - } |
|
| 452 | - |
|
| 453 | - |
|
| 454 | - /** |
|
| 455 | - * _global_ajax_hooks |
|
| 456 | - * all global add_action('wp_ajax_{name_of_hook}') hooks in here. |
|
| 457 | - * Note: within the ajax callback methods. |
|
| 458 | - * |
|
| 459 | - * @abstract |
|
| 460 | - * @return void |
|
| 461 | - */ |
|
| 462 | - protected function _global_ajax_hooks() |
|
| 463 | - { |
|
| 464 | - // for lazy loading of metabox content |
|
| 465 | - add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10); |
|
| 466 | - } |
|
| 467 | - |
|
| 468 | - |
|
| 469 | - public function ajax_metabox_content() |
|
| 470 | - { |
|
| 471 | - $contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : ''; |
|
| 472 | - $url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : ''; |
|
| 473 | - self::cached_rss_display($contentid, $url); |
|
| 474 | - wp_die(); |
|
| 475 | - } |
|
| 476 | - |
|
| 477 | - |
|
| 478 | - /** |
|
| 479 | - * _page_setup |
|
| 480 | - * Makes sure any things that need to be loaded early get handled. We also escape early here if the page requested |
|
| 481 | - * doesn't match the object. |
|
| 482 | - * |
|
| 483 | - * @final |
|
| 484 | - * @return void |
|
| 485 | - * @throws EE_Error |
|
| 486 | - * @throws InvalidArgumentException |
|
| 487 | - * @throws ReflectionException |
|
| 488 | - * @throws InvalidDataTypeException |
|
| 489 | - * @throws InvalidInterfaceException |
|
| 490 | - */ |
|
| 491 | - final protected function _page_setup() |
|
| 492 | - { |
|
| 493 | - // requires? |
|
| 494 | - // admin_init stuff - global - we're setting this REALLY early so if EE_Admin pages have to hook into other WP pages they can. But keep in mind, not everything is available from the EE_Admin Page object at this point. |
|
| 495 | - add_action('admin_init', array($this, 'admin_init_global'), 5); |
|
| 496 | - // next verify if we need to load anything... |
|
| 497 | - $this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : ''; |
|
| 498 | - $this->page_folder = strtolower( |
|
| 499 | - str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this)) |
|
| 500 | - ); |
|
| 501 | - global $ee_menu_slugs; |
|
| 502 | - $ee_menu_slugs = (array) $ee_menu_slugs; |
|
| 503 | - if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) { |
|
| 504 | - return; |
|
| 505 | - } |
|
| 506 | - // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first |
|
| 507 | - if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') { |
|
| 508 | - $this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1' |
|
| 509 | - ? $this->_req_data['action2'] |
|
| 510 | - : $this->_req_data['action']; |
|
| 511 | - } |
|
| 512 | - // then set blank or -1 action values to 'default' |
|
| 513 | - $this->_req_action = isset($this->_req_data['action']) |
|
| 514 | - && ! empty($this->_req_data['action']) |
|
| 515 | - && $this->_req_data['action'] !== '-1' |
|
| 516 | - ? sanitize_key($this->_req_data['action']) |
|
| 517 | - : 'default'; |
|
| 518 | - // if action is 'default' after the above BUT we have 'route' var set, then let's use the route as the action. |
|
| 519 | - // This covers cases where we're coming in from a list table that isn't on the default route. |
|
| 520 | - $this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route']) |
|
| 521 | - ? $this->_req_data['route'] : $this->_req_action; |
|
| 522 | - // however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be |
|
| 523 | - $this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route']) |
|
| 524 | - ? $this->_req_data['route'] |
|
| 525 | - : $this->_req_action; |
|
| 526 | - $this->_current_view = $this->_req_action; |
|
| 527 | - $this->_req_nonce = $this->_req_action . '_nonce'; |
|
| 528 | - $this->_define_page_props(); |
|
| 529 | - $this->_current_page_view_url = add_query_arg( |
|
| 530 | - array('page' => $this->_current_page, 'action' => $this->_current_view), |
|
| 531 | - $this->_admin_base_url |
|
| 532 | - ); |
|
| 533 | - // default things |
|
| 534 | - $this->_default_espresso_metaboxes = array( |
|
| 535 | - '_espresso_news_post_box', |
|
| 536 | - '_espresso_links_post_box', |
|
| 537 | - '_espresso_ratings_request', |
|
| 538 | - '_espresso_sponsors_post_box', |
|
| 539 | - ); |
|
| 540 | - // set page configs |
|
| 541 | - $this->_set_page_routes(); |
|
| 542 | - $this->_set_page_config(); |
|
| 543 | - // let's include any referrer data in our default_query_args for this route for "stickiness". |
|
| 544 | - if (isset($this->_req_data['wp_referer'])) { |
|
| 545 | - $this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer']; |
|
| 546 | - } |
|
| 547 | - // for caffeinated and other extended functionality. |
|
| 548 | - // If there is a _extend_page_config method |
|
| 549 | - // then let's run that to modify the all the various page configuration arrays |
|
| 550 | - if (method_exists($this, '_extend_page_config')) { |
|
| 551 | - $this->_extend_page_config(); |
|
| 552 | - } |
|
| 553 | - // for CPT and other extended functionality. |
|
| 554 | - // If there is an _extend_page_config_for_cpt |
|
| 555 | - // then let's run that to modify all the various page configuration arrays. |
|
| 556 | - if (method_exists($this, '_extend_page_config_for_cpt')) { |
|
| 557 | - $this->_extend_page_config_for_cpt(); |
|
| 558 | - } |
|
| 559 | - // filter routes and page_config so addons can add their stuff. Filtering done per class |
|
| 560 | - $this->_page_routes = apply_filters( |
|
| 561 | - 'FHEE__' . get_class($this) . '__page_setup__page_routes', |
|
| 562 | - $this->_page_routes, |
|
| 563 | - $this |
|
| 564 | - ); |
|
| 565 | - $this->_page_config = apply_filters( |
|
| 566 | - 'FHEE__' . get_class($this) . '__page_setup__page_config', |
|
| 567 | - $this->_page_config, |
|
| 568 | - $this |
|
| 569 | - ); |
|
| 570 | - // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present |
|
| 571 | - // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action |
|
| 572 | - if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) { |
|
| 573 | - add_action( |
|
| 574 | - 'AHEE__EE_Admin_Page__route_admin_request', |
|
| 575 | - array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view), |
|
| 576 | - 10, |
|
| 577 | - 2 |
|
| 578 | - ); |
|
| 579 | - } |
|
| 580 | - // next route only if routing enabled |
|
| 581 | - if ($this->_routing && ! defined('DOING_AJAX')) { |
|
| 582 | - $this->_verify_routes(); |
|
| 583 | - // next let's just check user_access and kill if no access |
|
| 584 | - $this->check_user_access(); |
|
| 585 | - if ($this->_is_UI_request) { |
|
| 586 | - // admin_init stuff - global, all views for this page class, specific view |
|
| 587 | - add_action('admin_init', array($this, 'admin_init'), 10); |
|
| 588 | - if (method_exists($this, 'admin_init_' . $this->_current_view)) { |
|
| 589 | - add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15); |
|
| 590 | - } |
|
| 591 | - } else { |
|
| 592 | - // hijack regular WP loading and route admin request immediately |
|
| 593 | - @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT)); |
|
| 594 | - $this->route_admin_request(); |
|
| 595 | - } |
|
| 596 | - } |
|
| 597 | - } |
|
| 598 | - |
|
| 599 | - |
|
| 600 | - /** |
|
| 601 | - * Provides a way for related child admin pages to load stuff on the loaded admin page. |
|
| 602 | - * |
|
| 603 | - * @return void |
|
| 604 | - * @throws ReflectionException |
|
| 605 | - * @throws EE_Error |
|
| 606 | - */ |
|
| 607 | - private function _do_other_page_hooks() |
|
| 608 | - { |
|
| 609 | - $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array()); |
|
| 610 | - foreach ($registered_pages as $page) { |
|
| 611 | - // now let's setup the file name and class that should be present |
|
| 612 | - $classname = str_replace('.class.php', '', $page); |
|
| 613 | - // autoloaders should take care of loading file |
|
| 614 | - if (! class_exists($classname)) { |
|
| 615 | - $error_msg[] = sprintf( |
|
| 616 | - esc_html__( |
|
| 617 | - 'Something went wrong with loading the %s admin hooks page.', |
|
| 618 | - 'event_espresso' |
|
| 619 | - ), |
|
| 620 | - $page |
|
| 621 | - ); |
|
| 622 | - $error_msg[] = $error_msg[0] |
|
| 623 | - . "\r\n" |
|
| 624 | - . sprintf( |
|
| 625 | - esc_html__( |
|
| 626 | - 'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class', |
|
| 627 | - 'event_espresso' |
|
| 628 | - ), |
|
| 629 | - $page, |
|
| 630 | - '<br />', |
|
| 631 | - '<strong>' . $classname . '</strong>' |
|
| 632 | - ); |
|
| 633 | - throw new EE_Error(implode('||', $error_msg)); |
|
| 634 | - } |
|
| 635 | - $a = new ReflectionClass($classname); |
|
| 636 | - // notice we are passing the instance of this class to the hook object. |
|
| 637 | - $hookobj[] = $a->newInstance($this); |
|
| 638 | - } |
|
| 639 | - } |
|
| 640 | - |
|
| 641 | - |
|
| 642 | - public function load_page_dependencies() |
|
| 643 | - { |
|
| 644 | - try { |
|
| 645 | - $this->_load_page_dependencies(); |
|
| 646 | - } catch (EE_Error $e) { |
|
| 647 | - $e->get_error(); |
|
| 648 | - } |
|
| 649 | - } |
|
| 650 | - |
|
| 651 | - |
|
| 652 | - /** |
|
| 653 | - * load_page_dependencies |
|
| 654 | - * loads things specific to this page class when its loaded. Really helps with efficiency. |
|
| 655 | - * |
|
| 656 | - * @return void |
|
| 657 | - * @throws DomainException |
|
| 658 | - * @throws EE_Error |
|
| 659 | - * @throws InvalidArgumentException |
|
| 660 | - * @throws InvalidDataTypeException |
|
| 661 | - * @throws InvalidInterfaceException |
|
| 662 | - * @throws ReflectionException |
|
| 663 | - */ |
|
| 664 | - protected function _load_page_dependencies() |
|
| 665 | - { |
|
| 666 | - // let's set the current_screen and screen options to override what WP set |
|
| 667 | - $this->_current_screen = get_current_screen(); |
|
| 668 | - // load admin_notices - global, page class, and view specific |
|
| 669 | - add_action('admin_notices', array($this, 'admin_notices_global'), 5); |
|
| 670 | - add_action('admin_notices', array($this, 'admin_notices'), 10); |
|
| 671 | - if (method_exists($this, 'admin_notices_' . $this->_current_view)) { |
|
| 672 | - add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15); |
|
| 673 | - } |
|
| 674 | - // load network admin_notices - global, page class, and view specific |
|
| 675 | - add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5); |
|
| 676 | - if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) { |
|
| 677 | - add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view)); |
|
| 678 | - } |
|
| 679 | - // this will save any per_page screen options if they are present |
|
| 680 | - $this->_set_per_page_screen_options(); |
|
| 681 | - // setup list table properties |
|
| 682 | - $this->_set_list_table(); |
|
| 683 | - // child classes can "register" a metabox to be automatically handled via the _page_config array property. |
|
| 684 | - // However in some cases the metaboxes will need to be added within a route handling callback. |
|
| 685 | - $this->_add_registered_meta_boxes(); |
|
| 686 | - $this->_add_screen_columns(); |
|
| 687 | - // add screen options - global, page child class, and view specific |
|
| 688 | - $this->_add_global_screen_options(); |
|
| 689 | - $this->_add_screen_options(); |
|
| 690 | - $add_screen_options = "_add_screen_options_{$this->_current_view}"; |
|
| 691 | - if (method_exists($this, $add_screen_options)) { |
|
| 692 | - $this->{$add_screen_options}(); |
|
| 693 | - } |
|
| 694 | - // add help tab(s) and tours- set via page_config and qtips. |
|
| 695 | - $this->_add_help_tour(); |
|
| 696 | - $this->_add_help_tabs(); |
|
| 697 | - $this->_add_qtips(); |
|
| 698 | - // add feature_pointers - global, page child class, and view specific |
|
| 699 | - $this->_add_feature_pointers(); |
|
| 700 | - $this->_add_global_feature_pointers(); |
|
| 701 | - $add_feature_pointer = "_add_feature_pointer_{$this->_current_view}"; |
|
| 702 | - if (method_exists($this, $add_feature_pointer)) { |
|
| 703 | - $this->{$add_feature_pointer}(); |
|
| 704 | - } |
|
| 705 | - // enqueue scripts/styles - global, page class, and view specific |
|
| 706 | - add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5); |
|
| 707 | - add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10); |
|
| 708 | - if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) { |
|
| 709 | - add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15); |
|
| 710 | - } |
|
| 711 | - add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100); |
|
| 712 | - // admin_print_footer_scripts - global, page child class, and view specific. |
|
| 713 | - // NOTE, despite the name, whenever possible, scripts should NOT be loaded using this. |
|
| 714 | - // In most cases that's doing_it_wrong(). But adding hidden container elements etc. |
|
| 715 | - // is a good use case. Notice the late priority we're giving these |
|
| 716 | - add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99); |
|
| 717 | - add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100); |
|
| 718 | - if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) { |
|
| 719 | - add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101); |
|
| 720 | - } |
|
| 721 | - // admin footer scripts |
|
| 722 | - add_action('admin_footer', array($this, 'admin_footer_global'), 99); |
|
| 723 | - add_action('admin_footer', array($this, 'admin_footer'), 100); |
|
| 724 | - if (method_exists($this, "admin_footer_{$this->_current_view}")) { |
|
| 725 | - add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101); |
|
| 726 | - } |
|
| 727 | - do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug); |
|
| 728 | - // targeted hook |
|
| 729 | - do_action( |
|
| 730 | - "FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}" |
|
| 731 | - ); |
|
| 732 | - } |
|
| 733 | - |
|
| 734 | - |
|
| 735 | - /** |
|
| 736 | - * _set_defaults |
|
| 737 | - * This sets some global defaults for class properties. |
|
| 738 | - */ |
|
| 739 | - private function _set_defaults() |
|
| 740 | - { |
|
| 741 | - $this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null; |
|
| 742 | - $this->_event = $this->_template_path = $this->_column_template_path = null; |
|
| 743 | - $this->_nav_tabs = $this->_views = $this->_page_routes = array(); |
|
| 744 | - $this->_page_config = $this->_default_route_query_args = array(); |
|
| 745 | - $this->_default_nav_tab_name = 'overview'; |
|
| 746 | - // init template args |
|
| 747 | - $this->_template_args = array( |
|
| 748 | - 'admin_page_header' => '', |
|
| 749 | - 'admin_page_content' => '', |
|
| 750 | - 'post_body_content' => '', |
|
| 751 | - 'before_list_table' => '', |
|
| 752 | - 'after_list_table' => '', |
|
| 753 | - ); |
|
| 754 | - } |
|
| 755 | - |
|
| 756 | - |
|
| 757 | - /** |
|
| 758 | - * route_admin_request |
|
| 759 | - * |
|
| 760 | - * @see _route_admin_request() |
|
| 761 | - * @return exception|void error |
|
| 762 | - * @throws InvalidArgumentException |
|
| 763 | - * @throws InvalidInterfaceException |
|
| 764 | - * @throws InvalidDataTypeException |
|
| 765 | - * @throws EE_Error |
|
| 766 | - * @throws ReflectionException |
|
| 767 | - */ |
|
| 768 | - public function route_admin_request() |
|
| 769 | - { |
|
| 770 | - try { |
|
| 771 | - $this->_route_admin_request(); |
|
| 772 | - } catch (EE_Error $e) { |
|
| 773 | - $e->get_error(); |
|
| 774 | - } |
|
| 775 | - } |
|
| 776 | - |
|
| 777 | - |
|
| 778 | - public function set_wp_page_slug($wp_page_slug) |
|
| 779 | - { |
|
| 780 | - $this->_wp_page_slug = $wp_page_slug; |
|
| 781 | - // if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls... |
|
| 782 | - if (is_network_admin()) { |
|
| 783 | - $this->_wp_page_slug .= '-network'; |
|
| 784 | - } |
|
| 785 | - } |
|
| 786 | - |
|
| 787 | - |
|
| 788 | - /** |
|
| 789 | - * _verify_routes |
|
| 790 | - * All this method does is verify the incoming request and make sure that routes exist for it. We do this early so |
|
| 791 | - * we know if we need to drop out. |
|
| 792 | - * |
|
| 793 | - * @return bool |
|
| 794 | - * @throws EE_Error |
|
| 795 | - */ |
|
| 796 | - protected function _verify_routes() |
|
| 797 | - { |
|
| 798 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 799 | - if (! $this->_current_page && ! defined('DOING_AJAX')) { |
|
| 800 | - return false; |
|
| 801 | - } |
|
| 802 | - $this->_route = false; |
|
| 803 | - // check that the page_routes array is not empty |
|
| 804 | - if (empty($this->_page_routes)) { |
|
| 805 | - // user error msg |
|
| 806 | - $error_msg = sprintf( |
|
| 807 | - esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'), |
|
| 808 | - $this->_admin_page_title |
|
| 809 | - ); |
|
| 810 | - // developer error msg |
|
| 811 | - $error_msg .= '||' . $error_msg |
|
| 812 | - . esc_html__( |
|
| 813 | - ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.', |
|
| 814 | - 'event_espresso' |
|
| 815 | - ); |
|
| 816 | - throw new EE_Error($error_msg); |
|
| 817 | - } |
|
| 818 | - // and that the requested page route exists |
|
| 819 | - if (array_key_exists($this->_req_action, $this->_page_routes)) { |
|
| 820 | - $this->_route = $this->_page_routes[ $this->_req_action ]; |
|
| 821 | - $this->_route_config = isset($this->_page_config[ $this->_req_action ]) |
|
| 822 | - ? $this->_page_config[ $this->_req_action ] : array(); |
|
| 823 | - } else { |
|
| 824 | - // user error msg |
|
| 825 | - $error_msg = sprintf( |
|
| 826 | - esc_html__( |
|
| 827 | - 'The requested page route does not exist for the %s admin page.', |
|
| 828 | - 'event_espresso' |
|
| 829 | - ), |
|
| 830 | - $this->_admin_page_title |
|
| 831 | - ); |
|
| 832 | - // developer error msg |
|
| 833 | - $error_msg .= '||' . $error_msg |
|
| 834 | - . sprintf( |
|
| 835 | - esc_html__( |
|
| 836 | - ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.', |
|
| 837 | - 'event_espresso' |
|
| 838 | - ), |
|
| 839 | - $this->_req_action |
|
| 840 | - ); |
|
| 841 | - throw new EE_Error($error_msg); |
|
| 842 | - } |
|
| 843 | - // and that a default route exists |
|
| 844 | - if (! array_key_exists('default', $this->_page_routes)) { |
|
| 845 | - // user error msg |
|
| 846 | - $error_msg = sprintf( |
|
| 847 | - esc_html__( |
|
| 848 | - 'A default page route has not been set for the % admin page.', |
|
| 849 | - 'event_espresso' |
|
| 850 | - ), |
|
| 851 | - $this->_admin_page_title |
|
| 852 | - ); |
|
| 853 | - // developer error msg |
|
| 854 | - $error_msg .= '||' . $error_msg |
|
| 855 | - . esc_html__( |
|
| 856 | - ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.', |
|
| 857 | - 'event_espresso' |
|
| 858 | - ); |
|
| 859 | - throw new EE_Error($error_msg); |
|
| 860 | - } |
|
| 861 | - // first lets' catch if the UI request has EVER been set. |
|
| 862 | - if ($this->_is_UI_request === null) { |
|
| 863 | - // lets set if this is a UI request or not. |
|
| 864 | - $this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true; |
|
| 865 | - // wait a minute... we might have a noheader in the route array |
|
| 866 | - $this->_is_UI_request = is_array($this->_route) |
|
| 867 | - && isset($this->_route['noheader']) |
|
| 868 | - && $this->_route['noheader'] ? false : $this->_is_UI_request; |
|
| 869 | - } |
|
| 870 | - $this->_set_current_labels(); |
|
| 871 | - return true; |
|
| 872 | - } |
|
| 873 | - |
|
| 874 | - |
|
| 875 | - /** |
|
| 876 | - * this method simply verifies a given route and makes sure its an actual route available for the loaded page |
|
| 877 | - * |
|
| 878 | - * @param string $route the route name we're verifying |
|
| 879 | - * @return mixed (bool|Exception) we'll throw an exception if this isn't a valid route. |
|
| 880 | - * @throws EE_Error |
|
| 881 | - */ |
|
| 882 | - protected function _verify_route($route) |
|
| 883 | - { |
|
| 884 | - if (array_key_exists($this->_req_action, $this->_page_routes)) { |
|
| 885 | - return true; |
|
| 886 | - } |
|
| 887 | - // user error msg |
|
| 888 | - $error_msg = sprintf( |
|
| 889 | - esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'), |
|
| 890 | - $this->_admin_page_title |
|
| 891 | - ); |
|
| 892 | - // developer error msg |
|
| 893 | - $error_msg .= '||' . $error_msg |
|
| 894 | - . sprintf( |
|
| 895 | - esc_html__( |
|
| 896 | - ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property', |
|
| 897 | - 'event_espresso' |
|
| 898 | - ), |
|
| 899 | - $route |
|
| 900 | - ); |
|
| 901 | - throw new EE_Error($error_msg); |
|
| 902 | - } |
|
| 903 | - |
|
| 904 | - |
|
| 905 | - /** |
|
| 906 | - * perform nonce verification |
|
| 907 | - * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces |
|
| 908 | - * using this method (and save retyping!) |
|
| 909 | - * |
|
| 910 | - * @param string $nonce The nonce sent |
|
| 911 | - * @param string $nonce_ref The nonce reference string (name0) |
|
| 912 | - * @return void |
|
| 913 | - * @throws EE_Error |
|
| 914 | - */ |
|
| 915 | - protected function _verify_nonce($nonce, $nonce_ref) |
|
| 916 | - { |
|
| 917 | - // verify nonce against expected value |
|
| 918 | - if (! wp_verify_nonce($nonce, $nonce_ref)) { |
|
| 919 | - // these are not the droids you are looking for !!! |
|
| 920 | - $msg = sprintf( |
|
| 921 | - esc_html__('%sNonce Fail.%s', 'event_espresso'), |
|
| 922 | - '<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">', |
|
| 923 | - '</a>' |
|
| 924 | - ); |
|
| 925 | - if (WP_DEBUG) { |
|
| 926 | - $msg .= "\n " |
|
| 927 | - . sprintf( |
|
| 928 | - esc_html__( |
|
| 929 | - 'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!', |
|
| 930 | - 'event_espresso' |
|
| 931 | - ), |
|
| 932 | - __CLASS__ |
|
| 933 | - ); |
|
| 934 | - } |
|
| 935 | - if (! defined('DOING_AJAX')) { |
|
| 936 | - wp_die($msg); |
|
| 937 | - } else { |
|
| 938 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 939 | - $this->_return_json(); |
|
| 940 | - } |
|
| 941 | - } |
|
| 942 | - } |
|
| 943 | - |
|
| 944 | - |
|
| 945 | - /** |
|
| 946 | - * _route_admin_request() |
|
| 947 | - * Meat and potatoes of the class. Basically, this dude checks out what's being requested and sees if theres are |
|
| 948 | - * some doodads to work the magic and handle the flingjangy. Translation: Checks if the requested action is listed |
|
| 949 | - * in the page routes and then will try to load the corresponding method. |
|
| 950 | - * |
|
| 951 | - * @return void |
|
| 952 | - * @throws EE_Error |
|
| 953 | - * @throws InvalidArgumentException |
|
| 954 | - * @throws InvalidDataTypeException |
|
| 955 | - * @throws InvalidInterfaceException |
|
| 956 | - * @throws ReflectionException |
|
| 957 | - */ |
|
| 958 | - protected function _route_admin_request() |
|
| 959 | - { |
|
| 960 | - if (! $this->_is_UI_request) { |
|
| 961 | - $this->_verify_routes(); |
|
| 962 | - } |
|
| 963 | - $nonce_check = isset($this->_route_config['require_nonce']) |
|
| 964 | - ? $this->_route_config['require_nonce'] |
|
| 965 | - : true; |
|
| 966 | - if ($this->_req_action !== 'default' && $nonce_check) { |
|
| 967 | - // set nonce from post data |
|
| 968 | - $nonce = isset($this->_req_data[ $this->_req_nonce ]) |
|
| 969 | - ? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) |
|
| 970 | - : ''; |
|
| 971 | - $this->_verify_nonce($nonce, $this->_req_nonce); |
|
| 972 | - } |
|
| 973 | - // set the nav_tabs array but ONLY if this is UI_request |
|
| 974 | - if ($this->_is_UI_request) { |
|
| 975 | - $this->_set_nav_tabs(); |
|
| 976 | - } |
|
| 977 | - // grab callback function |
|
| 978 | - $func = is_array($this->_route) ? $this->_route['func'] : $this->_route; |
|
| 979 | - // check if callback has args |
|
| 980 | - $args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array(); |
|
| 981 | - $error_msg = ''; |
|
| 982 | - // action right before calling route |
|
| 983 | - // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request') |
|
| 984 | - if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) { |
|
| 985 | - do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this); |
|
| 986 | - } |
|
| 987 | - // right before calling the route, let's remove _wp_http_referer from the |
|
| 988 | - // $_SERVER[REQUEST_URI] global (its now in _req_data for route processing). |
|
| 989 | - $_SERVER['REQUEST_URI'] = remove_query_arg( |
|
| 990 | - '_wp_http_referer', |
|
| 991 | - wp_unslash($_SERVER['REQUEST_URI']) |
|
| 992 | - ); |
|
| 993 | - if (! empty($func)) { |
|
| 994 | - if (is_array($func)) { |
|
| 995 | - list($class, $method) = $func; |
|
| 996 | - } elseif (strpos($func, '::') !== false) { |
|
| 997 | - list($class, $method) = explode('::', $func); |
|
| 998 | - } else { |
|
| 999 | - $class = $this; |
|
| 1000 | - $method = $func; |
|
| 1001 | - } |
|
| 1002 | - if (! (is_object($class) && $class === $this)) { |
|
| 1003 | - // send along this admin page object for access by addons. |
|
| 1004 | - $args['admin_page_object'] = $this; |
|
| 1005 | - } |
|
| 1006 | - if (// is it a method on a class that doesn't work? |
|
| 1007 | - ( |
|
| 1008 | - ( |
|
| 1009 | - method_exists($class, $method) |
|
| 1010 | - && call_user_func_array(array($class, $method), $args) === false |
|
| 1011 | - ) |
|
| 1012 | - && ( |
|
| 1013 | - // is it a standalone function that doesn't work? |
|
| 1014 | - function_exists($method) |
|
| 1015 | - && call_user_func_array( |
|
| 1016 | - $func, |
|
| 1017 | - array_merge(array('admin_page_object' => $this), $args) |
|
| 1018 | - ) === false |
|
| 1019 | - ) |
|
| 1020 | - ) |
|
| 1021 | - || ( |
|
| 1022 | - // is it neither a class method NOR a standalone function? |
|
| 1023 | - ! method_exists($class, $method) |
|
| 1024 | - && ! function_exists($method) |
|
| 1025 | - ) |
|
| 1026 | - ) { |
|
| 1027 | - // user error msg |
|
| 1028 | - $error_msg = esc_html__( |
|
| 1029 | - 'An error occurred. The requested page route could not be found.', |
|
| 1030 | - 'event_espresso' |
|
| 1031 | - ); |
|
| 1032 | - // developer error msg |
|
| 1033 | - $error_msg .= '||'; |
|
| 1034 | - $error_msg .= sprintf( |
|
| 1035 | - esc_html__( |
|
| 1036 | - 'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.', |
|
| 1037 | - 'event_espresso' |
|
| 1038 | - ), |
|
| 1039 | - $method |
|
| 1040 | - ); |
|
| 1041 | - } |
|
| 1042 | - if (! empty($error_msg)) { |
|
| 1043 | - throw new EE_Error($error_msg); |
|
| 1044 | - } |
|
| 1045 | - } |
|
| 1046 | - // if we've routed and this route has a no headers route AND a sent_headers_route, |
|
| 1047 | - // then we need to reset the routing properties to the new route. |
|
| 1048 | - // now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent. |
|
| 1049 | - if ($this->_is_UI_request === false |
|
| 1050 | - && is_array($this->_route) |
|
| 1051 | - && ! empty($this->_route['headers_sent_route']) |
|
| 1052 | - ) { |
|
| 1053 | - $this->_reset_routing_properties($this->_route['headers_sent_route']); |
|
| 1054 | - } |
|
| 1055 | - } |
|
| 1056 | - |
|
| 1057 | - |
|
| 1058 | - /** |
|
| 1059 | - * This method just allows the resetting of page properties in the case where a no headers |
|
| 1060 | - * route redirects to a headers route in its route config. |
|
| 1061 | - * |
|
| 1062 | - * @since 4.3.0 |
|
| 1063 | - * @param string $new_route New (non header) route to redirect to. |
|
| 1064 | - * @return void |
|
| 1065 | - * @throws ReflectionException |
|
| 1066 | - * @throws InvalidArgumentException |
|
| 1067 | - * @throws InvalidInterfaceException |
|
| 1068 | - * @throws InvalidDataTypeException |
|
| 1069 | - * @throws EE_Error |
|
| 1070 | - */ |
|
| 1071 | - protected function _reset_routing_properties($new_route) |
|
| 1072 | - { |
|
| 1073 | - $this->_is_UI_request = true; |
|
| 1074 | - // now we set the current route to whatever the headers_sent_route is set at |
|
| 1075 | - $this->_req_data['action'] = $new_route; |
|
| 1076 | - // rerun page setup |
|
| 1077 | - $this->_page_setup(); |
|
| 1078 | - } |
|
| 1079 | - |
|
| 1080 | - |
|
| 1081 | - /** |
|
| 1082 | - * _add_query_arg |
|
| 1083 | - * adds nonce to array of arguments then calls WP add_query_arg function |
|
| 1084 | - *(internally just uses EEH_URL's function with the same name) |
|
| 1085 | - * |
|
| 1086 | - * @param array $args |
|
| 1087 | - * @param string $url |
|
| 1088 | - * @param bool $sticky if true, then the existing Request params will be appended to the |
|
| 1089 | - * generated url in an associative array indexed by the key 'wp_referer'; |
|
| 1090 | - * Example usage: If the current page is: |
|
| 1091 | - * http://mydomain.com/wp-admin/admin.php?page=espresso_registrations |
|
| 1092 | - * &action=default&event_id=20&month_range=March%202015 |
|
| 1093 | - * &_wpnonce=5467821 |
|
| 1094 | - * and you call: |
|
| 1095 | - * EE_Admin_Page::add_query_args_and_nonce( |
|
| 1096 | - * array( |
|
| 1097 | - * 'action' => 'resend_something', |
|
| 1098 | - * 'page=>espresso_registrations' |
|
| 1099 | - * ), |
|
| 1100 | - * $some_url, |
|
| 1101 | - * true |
|
| 1102 | - * ); |
|
| 1103 | - * It will produce a url in this structure: |
|
| 1104 | - * http://{$some_url}/?page=espresso_registrations&action=resend_something |
|
| 1105 | - * &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[ |
|
| 1106 | - * month_range]=March%202015 |
|
| 1107 | - * @param bool $exclude_nonce If true, the the nonce will be excluded from the generated nonce. |
|
| 1108 | - * @return string |
|
| 1109 | - */ |
|
| 1110 | - public static function add_query_args_and_nonce( |
|
| 1111 | - $args = array(), |
|
| 1112 | - $url = false, |
|
| 1113 | - $sticky = false, |
|
| 1114 | - $exclude_nonce = false |
|
| 1115 | - ) { |
|
| 1116 | - // if there is a _wp_http_referer include the values from the request but only if sticky = true |
|
| 1117 | - if ($sticky) { |
|
| 1118 | - $request = $_REQUEST; |
|
| 1119 | - unset($request['_wp_http_referer']); |
|
| 1120 | - unset($request['wp_referer']); |
|
| 1121 | - foreach ($request as $key => $value) { |
|
| 1122 | - // do not add nonces |
|
| 1123 | - if (strpos($key, 'nonce') !== false) { |
|
| 1124 | - continue; |
|
| 1125 | - } |
|
| 1126 | - $args[ 'wp_referer[' . $key . ']' ] = $value; |
|
| 1127 | - } |
|
| 1128 | - } |
|
| 1129 | - return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce); |
|
| 1130 | - } |
|
| 1131 | - |
|
| 1132 | - |
|
| 1133 | - /** |
|
| 1134 | - * This returns a generated link that will load the related help tab. |
|
| 1135 | - * |
|
| 1136 | - * @param string $help_tab_id the id for the connected help tab |
|
| 1137 | - * @param string $icon_style (optional) include css class for the style you want to use for the help icon. |
|
| 1138 | - * @param string $help_text (optional) send help text you want to use for the link if default not to be used |
|
| 1139 | - * @uses EEH_Template::get_help_tab_link() |
|
| 1140 | - * @return string generated link |
|
| 1141 | - */ |
|
| 1142 | - protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '') |
|
| 1143 | - { |
|
| 1144 | - return EEH_Template::get_help_tab_link( |
|
| 1145 | - $help_tab_id, |
|
| 1146 | - $this->page_slug, |
|
| 1147 | - $this->_req_action, |
|
| 1148 | - $icon_style, |
|
| 1149 | - $help_text |
|
| 1150 | - ); |
|
| 1151 | - } |
|
| 1152 | - |
|
| 1153 | - |
|
| 1154 | - /** |
|
| 1155 | - * _add_help_tabs |
|
| 1156 | - * Note child classes define their help tabs within the page_config array. |
|
| 1157 | - * |
|
| 1158 | - * @link http://codex.wordpress.org/Function_Reference/add_help_tab |
|
| 1159 | - * @return void |
|
| 1160 | - * @throws DomainException |
|
| 1161 | - * @throws EE_Error |
|
| 1162 | - */ |
|
| 1163 | - protected function _add_help_tabs() |
|
| 1164 | - { |
|
| 1165 | - $tour_buttons = ''; |
|
| 1166 | - if (isset($this->_page_config[ $this->_req_action ])) { |
|
| 1167 | - $config = $this->_page_config[ $this->_req_action ]; |
|
| 1168 | - // is there a help tour for the current route? if there is let's setup the tour buttons |
|
| 1169 | - if (isset($this->_help_tour[ $this->_req_action ])) { |
|
| 1170 | - $tb = array(); |
|
| 1171 | - $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">'; |
|
| 1172 | - foreach ($this->_help_tour['tours'] as $tour) { |
|
| 1173 | - // if this is the end tour then we don't need to setup a button |
|
| 1174 | - if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) { |
|
| 1175 | - continue; |
|
| 1176 | - } |
|
| 1177 | - $tb[] = '<button id="trigger-tour-' |
|
| 1178 | - . $tour->get_slug() |
|
| 1179 | - . '" class="button-primary trigger-ee-help-tour">' |
|
| 1180 | - . $tour->get_label() |
|
| 1181 | - . '</button>'; |
|
| 1182 | - } |
|
| 1183 | - $tour_buttons .= implode('<br />', $tb); |
|
| 1184 | - $tour_buttons .= '</div></div>'; |
|
| 1185 | - } |
|
| 1186 | - // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well. |
|
| 1187 | - if (is_array($config) && isset($config['help_sidebar'])) { |
|
| 1188 | - // check that the callback given is valid |
|
| 1189 | - if (! method_exists($this, $config['help_sidebar'])) { |
|
| 1190 | - throw new EE_Error( |
|
| 1191 | - sprintf( |
|
| 1192 | - esc_html__( |
|
| 1193 | - 'The _page_config array has a callback set for the "help_sidebar" option. However the callback given (%s) is not a valid callback. Doublecheck the spelling and make sure this method exists for the class %s', |
|
| 1194 | - 'event_espresso' |
|
| 1195 | - ), |
|
| 1196 | - $config['help_sidebar'], |
|
| 1197 | - get_class($this) |
|
| 1198 | - ) |
|
| 1199 | - ); |
|
| 1200 | - } |
|
| 1201 | - $content = apply_filters( |
|
| 1202 | - 'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar', |
|
| 1203 | - $this->{$config['help_sidebar']}() |
|
| 1204 | - ); |
|
| 1205 | - $content .= $tour_buttons; // add help tour buttons. |
|
| 1206 | - // do we have any help tours setup? Cause if we do we want to add the buttons |
|
| 1207 | - $this->_current_screen->set_help_sidebar($content); |
|
| 1208 | - } |
|
| 1209 | - // if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar. |
|
| 1210 | - if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) { |
|
| 1211 | - $this->_current_screen->set_help_sidebar($tour_buttons); |
|
| 1212 | - } |
|
| 1213 | - // handle if no help_tabs are set so the sidebar will still show for the help tour buttons |
|
| 1214 | - if (! isset($config['help_tabs']) && ! empty($tour_buttons)) { |
|
| 1215 | - $_ht['id'] = $this->page_slug; |
|
| 1216 | - $_ht['title'] = esc_html__('Help Tours', 'event_espresso'); |
|
| 1217 | - $_ht['content'] = '<p>' |
|
| 1218 | - . esc_html__( |
|
| 1219 | - 'The buttons to the right allow you to start/restart any help tours available for this page', |
|
| 1220 | - 'event_espresso' |
|
| 1221 | - ) . '</p>'; |
|
| 1222 | - $this->_current_screen->add_help_tab($_ht); |
|
| 1223 | - } |
|
| 1224 | - if (! isset($config['help_tabs'])) { |
|
| 1225 | - return; |
|
| 1226 | - } //no help tabs for this route |
|
| 1227 | - foreach ((array) $config['help_tabs'] as $tab_id => $cfg) { |
|
| 1228 | - // we're here so there ARE help tabs! |
|
| 1229 | - // make sure we've got what we need |
|
| 1230 | - if (! isset($cfg['title'])) { |
|
| 1231 | - throw new EE_Error( |
|
| 1232 | - esc_html__( |
|
| 1233 | - 'The _page_config array is not set up properly for help tabs. It is missing a title', |
|
| 1234 | - 'event_espresso' |
|
| 1235 | - ) |
|
| 1236 | - ); |
|
| 1237 | - } |
|
| 1238 | - if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) { |
|
| 1239 | - throw new EE_Error( |
|
| 1240 | - esc_html__( |
|
| 1241 | - 'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab', |
|
| 1242 | - 'event_espresso' |
|
| 1243 | - ) |
|
| 1244 | - ); |
|
| 1245 | - } |
|
| 1246 | - // first priority goes to content. |
|
| 1247 | - if (! empty($cfg['content'])) { |
|
| 1248 | - $content = ! empty($cfg['content']) ? $cfg['content'] : null; |
|
| 1249 | - // second priority goes to filename |
|
| 1250 | - } elseif (! empty($cfg['filename'])) { |
|
| 1251 | - $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php'; |
|
| 1252 | - // it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too) |
|
| 1253 | - $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES |
|
| 1254 | - . basename($this->_get_dir()) |
|
| 1255 | - . '/help_tabs/' |
|
| 1256 | - . $cfg['filename'] |
|
| 1257 | - . '.help_tab.php' : $file_path; |
|
| 1258 | - // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error. |
|
| 1259 | - if (! isset($cfg['callback']) && ! is_readable($file_path)) { |
|
| 1260 | - EE_Error::add_error( |
|
| 1261 | - sprintf( |
|
| 1262 | - esc_html__( |
|
| 1263 | - 'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content. Please check that the string you set for the help tab on this route (%s) is the correct spelling. The file should be in %s', |
|
| 1264 | - 'event_espresso' |
|
| 1265 | - ), |
|
| 1266 | - $tab_id, |
|
| 1267 | - key($config), |
|
| 1268 | - $file_path |
|
| 1269 | - ), |
|
| 1270 | - __FILE__, |
|
| 1271 | - __FUNCTION__, |
|
| 1272 | - __LINE__ |
|
| 1273 | - ); |
|
| 1274 | - return; |
|
| 1275 | - } |
|
| 1276 | - $template_args['admin_page_obj'] = $this; |
|
| 1277 | - $content = EEH_Template::display_template( |
|
| 1278 | - $file_path, |
|
| 1279 | - $template_args, |
|
| 1280 | - true |
|
| 1281 | - ); |
|
| 1282 | - } else { |
|
| 1283 | - $content = ''; |
|
| 1284 | - } |
|
| 1285 | - // check if callback is valid |
|
| 1286 | - if (empty($content) && ( |
|
| 1287 | - ! isset($cfg['callback']) || ! method_exists($this, $cfg['callback']) |
|
| 1288 | - ) |
|
| 1289 | - ) { |
|
| 1290 | - EE_Error::add_error( |
|
| 1291 | - sprintf( |
|
| 1292 | - esc_html__( |
|
| 1293 | - 'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content. Check the spelling or make sure the method is present.', |
|
| 1294 | - 'event_espresso' |
|
| 1295 | - ), |
|
| 1296 | - $cfg['title'] |
|
| 1297 | - ), |
|
| 1298 | - __FILE__, |
|
| 1299 | - __FUNCTION__, |
|
| 1300 | - __LINE__ |
|
| 1301 | - ); |
|
| 1302 | - return; |
|
| 1303 | - } |
|
| 1304 | - // setup config array for help tab method |
|
| 1305 | - $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id; |
|
| 1306 | - $_ht = array( |
|
| 1307 | - 'id' => $id, |
|
| 1308 | - 'title' => $cfg['title'], |
|
| 1309 | - 'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null, |
|
| 1310 | - 'content' => $content, |
|
| 1311 | - ); |
|
| 1312 | - $this->_current_screen->add_help_tab($_ht); |
|
| 1313 | - } |
|
| 1314 | - } |
|
| 1315 | - } |
|
| 1316 | - |
|
| 1317 | - |
|
| 1318 | - /** |
|
| 1319 | - * This basically checks loaded $_page_config property to see if there are any help_tours defined. "help_tours" is |
|
| 1320 | - * an array with properties for setting up usage of the joyride plugin |
|
| 1321 | - * |
|
| 1322 | - * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin |
|
| 1323 | - * @see instructions regarding the format and construction of the "help_tour" array element is found in the |
|
| 1324 | - * _set_page_config() comments |
|
| 1325 | - * @return void |
|
| 1326 | - * @throws EE_Error |
|
| 1327 | - * @throws InvalidArgumentException |
|
| 1328 | - * @throws InvalidDataTypeException |
|
| 1329 | - * @throws InvalidInterfaceException |
|
| 1330 | - */ |
|
| 1331 | - protected function _add_help_tour() |
|
| 1332 | - { |
|
| 1333 | - $tours = array(); |
|
| 1334 | - $this->_help_tour = array(); |
|
| 1335 | - // exit early if help tours are turned off globally |
|
| 1336 | - if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS) |
|
| 1337 | - || ! EE_Registry::instance()->CFG->admin->help_tour_activation |
|
| 1338 | - ) { |
|
| 1339 | - return; |
|
| 1340 | - } |
|
| 1341 | - // loop through _page_config to find any help_tour defined |
|
| 1342 | - foreach ($this->_page_config as $route => $config) { |
|
| 1343 | - // we're only going to set things up for this route |
|
| 1344 | - if ($route !== $this->_req_action) { |
|
| 1345 | - continue; |
|
| 1346 | - } |
|
| 1347 | - if (isset($config['help_tour'])) { |
|
| 1348 | - foreach ($config['help_tour'] as $tour) { |
|
| 1349 | - $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php'; |
|
| 1350 | - // let's see if we can get that file... |
|
| 1351 | - // if not its possible this is a decaf route not set in caffeinated |
|
| 1352 | - // so lets try and get the caffeinated equivalent |
|
| 1353 | - $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES |
|
| 1354 | - . basename($this->_get_dir()) |
|
| 1355 | - . '/help_tours/' |
|
| 1356 | - . $tour |
|
| 1357 | - . '.class.php' : $file_path; |
|
| 1358 | - // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error. |
|
| 1359 | - if (! is_readable($file_path)) { |
|
| 1360 | - EE_Error::add_error( |
|
| 1361 | - sprintf( |
|
| 1362 | - esc_html__( |
|
| 1363 | - 'The file path given for the help tour (%s) is not a valid path. Please check that the string you set for the help tour on this route (%s) is the correct spelling', |
|
| 1364 | - 'event_espresso' |
|
| 1365 | - ), |
|
| 1366 | - $file_path, |
|
| 1367 | - $tour |
|
| 1368 | - ), |
|
| 1369 | - __FILE__, |
|
| 1370 | - __FUNCTION__, |
|
| 1371 | - __LINE__ |
|
| 1372 | - ); |
|
| 1373 | - return; |
|
| 1374 | - } |
|
| 1375 | - require_once $file_path; |
|
| 1376 | - if (! class_exists($tour)) { |
|
| 1377 | - $error_msg[] = sprintf( |
|
| 1378 | - esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'), |
|
| 1379 | - $tour |
|
| 1380 | - ); |
|
| 1381 | - $error_msg[] = $error_msg[0] . "\r\n" |
|
| 1382 | - . sprintf( |
|
| 1383 | - esc_html__( |
|
| 1384 | - 'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.', |
|
| 1385 | - 'event_espresso' |
|
| 1386 | - ), |
|
| 1387 | - $tour, |
|
| 1388 | - '<br />', |
|
| 1389 | - $tour, |
|
| 1390 | - $this->_req_action, |
|
| 1391 | - get_class($this) |
|
| 1392 | - ); |
|
| 1393 | - throw new EE_Error(implode('||', $error_msg)); |
|
| 1394 | - } |
|
| 1395 | - $tour_obj = new $tour($this->_is_caf); |
|
| 1396 | - $tours[] = $tour_obj; |
|
| 1397 | - $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj); |
|
| 1398 | - } |
|
| 1399 | - // let's inject the end tour stop element common to all pages... this will only get seen once per machine. |
|
| 1400 | - $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf); |
|
| 1401 | - $tours[] = $end_stop_tour; |
|
| 1402 | - $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour); |
|
| 1403 | - } |
|
| 1404 | - } |
|
| 1405 | - if (! empty($tours)) { |
|
| 1406 | - $this->_help_tour['tours'] = $tours; |
|
| 1407 | - } |
|
| 1408 | - // that's it! Now that the $_help_tours property is set (or not) |
|
| 1409 | - // the scripts and html should be taken care of automatically. |
|
| 1410 | - } |
|
| 1411 | - |
|
| 1412 | - |
|
| 1413 | - /** |
|
| 1414 | - * This simply sets up any qtips that have been defined in the page config |
|
| 1415 | - * |
|
| 1416 | - * @return void |
|
| 1417 | - */ |
|
| 1418 | - protected function _add_qtips() |
|
| 1419 | - { |
|
| 1420 | - if (isset($this->_route_config['qtips'])) { |
|
| 1421 | - $qtips = (array) $this->_route_config['qtips']; |
|
| 1422 | - // load qtip loader |
|
| 1423 | - $path = array( |
|
| 1424 | - $this->_get_dir() . '/qtips/', |
|
| 1425 | - EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/', |
|
| 1426 | - ); |
|
| 1427 | - EEH_Qtip_Loader::instance()->register($qtips, $path); |
|
| 1428 | - } |
|
| 1429 | - } |
|
| 1430 | - |
|
| 1431 | - |
|
| 1432 | - /** |
|
| 1433 | - * _set_nav_tabs |
|
| 1434 | - * This sets up the nav tabs from the page_routes array. This method can be overwritten by child classes if you |
|
| 1435 | - * wish to add additional tabs or modify accordingly. |
|
| 1436 | - * |
|
| 1437 | - * @return void |
|
| 1438 | - * @throws InvalidArgumentException |
|
| 1439 | - * @throws InvalidInterfaceException |
|
| 1440 | - * @throws InvalidDataTypeException |
|
| 1441 | - */ |
|
| 1442 | - protected function _set_nav_tabs() |
|
| 1443 | - { |
|
| 1444 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1445 | - $i = 0; |
|
| 1446 | - foreach ($this->_page_config as $slug => $config) { |
|
| 1447 | - if (! is_array($config) |
|
| 1448 | - || ( |
|
| 1449 | - is_array($config) |
|
| 1450 | - && ( |
|
| 1451 | - (isset($config['nav']) && ! $config['nav']) |
|
| 1452 | - || ! isset($config['nav']) |
|
| 1453 | - ) |
|
| 1454 | - ) |
|
| 1455 | - ) { |
|
| 1456 | - continue; |
|
| 1457 | - } |
|
| 1458 | - // no nav tab for this config |
|
| 1459 | - // check for persistent flag |
|
| 1460 | - if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) { |
|
| 1461 | - // nav tab is only to appear when route requested. |
|
| 1462 | - continue; |
|
| 1463 | - } |
|
| 1464 | - if (! $this->check_user_access($slug, true)) { |
|
| 1465 | - // no nav tab because current user does not have access. |
|
| 1466 | - continue; |
|
| 1467 | - } |
|
| 1468 | - $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : ''; |
|
| 1469 | - $this->_nav_tabs[ $slug ] = array( |
|
| 1470 | - 'url' => isset($config['nav']['url']) |
|
| 1471 | - ? $config['nav']['url'] |
|
| 1472 | - : self::add_query_args_and_nonce( |
|
| 1473 | - array('action' => $slug), |
|
| 1474 | - $this->_admin_base_url |
|
| 1475 | - ), |
|
| 1476 | - 'link_text' => isset($config['nav']['label']) |
|
| 1477 | - ? $config['nav']['label'] |
|
| 1478 | - : ucwords( |
|
| 1479 | - str_replace('_', ' ', $slug) |
|
| 1480 | - ), |
|
| 1481 | - 'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class, |
|
| 1482 | - 'order' => isset($config['nav']['order']) ? $config['nav']['order'] : $i, |
|
| 1483 | - ); |
|
| 1484 | - $i++; |
|
| 1485 | - } |
|
| 1486 | - // if $this->_nav_tabs is empty then lets set the default |
|
| 1487 | - if (empty($this->_nav_tabs)) { |
|
| 1488 | - $this->_nav_tabs[ $this->_default_nav_tab_name ] = array( |
|
| 1489 | - 'url' => $this->_admin_base_url, |
|
| 1490 | - 'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)), |
|
| 1491 | - 'css_class' => 'nav-tab-active', |
|
| 1492 | - 'order' => 10, |
|
| 1493 | - ); |
|
| 1494 | - } |
|
| 1495 | - // now let's sort the tabs according to order |
|
| 1496 | - usort($this->_nav_tabs, array($this, '_sort_nav_tabs')); |
|
| 1497 | - } |
|
| 1498 | - |
|
| 1499 | - |
|
| 1500 | - /** |
|
| 1501 | - * _set_current_labels |
|
| 1502 | - * This method modifies the _labels property with any optional specific labels indicated in the _page_routes |
|
| 1503 | - * property array |
|
| 1504 | - * |
|
| 1505 | - * @return void |
|
| 1506 | - */ |
|
| 1507 | - private function _set_current_labels() |
|
| 1508 | - { |
|
| 1509 | - if (is_array($this->_route_config) && isset($this->_route_config['labels'])) { |
|
| 1510 | - foreach ($this->_route_config['labels'] as $label => $text) { |
|
| 1511 | - if (is_array($text)) { |
|
| 1512 | - foreach ($text as $sublabel => $subtext) { |
|
| 1513 | - $this->_labels[ $label ][ $sublabel ] = $subtext; |
|
| 1514 | - } |
|
| 1515 | - } else { |
|
| 1516 | - $this->_labels[ $label ] = $text; |
|
| 1517 | - } |
|
| 1518 | - } |
|
| 1519 | - } |
|
| 1520 | - } |
|
| 1521 | - |
|
| 1522 | - |
|
| 1523 | - /** |
|
| 1524 | - * verifies user access for this admin page |
|
| 1525 | - * |
|
| 1526 | - * @param string $route_to_check if present then the capability for the route matching this string is checked. |
|
| 1527 | - * @param bool $verify_only Default is FALSE which means if user check fails then wp_die(). Otherwise just |
|
| 1528 | - * return false if verify fail. |
|
| 1529 | - * @return bool |
|
| 1530 | - * @throws InvalidArgumentException |
|
| 1531 | - * @throws InvalidDataTypeException |
|
| 1532 | - * @throws InvalidInterfaceException |
|
| 1533 | - */ |
|
| 1534 | - public function check_user_access($route_to_check = '', $verify_only = false) |
|
| 1535 | - { |
|
| 1536 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1537 | - $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check; |
|
| 1538 | - $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ]) |
|
| 1539 | - && is_array( |
|
| 1540 | - $this->_page_routes[ $route_to_check ] |
|
| 1541 | - ) |
|
| 1542 | - && ! empty($this->_page_routes[ $route_to_check ]['capability']) |
|
| 1543 | - ? $this->_page_routes[ $route_to_check ]['capability'] : null; |
|
| 1544 | - if (empty($capability) && empty($route_to_check)) { |
|
| 1545 | - $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options' |
|
| 1546 | - : $this->_route['capability']; |
|
| 1547 | - } else { |
|
| 1548 | - $capability = empty($capability) ? 'manage_options' : $capability; |
|
| 1549 | - } |
|
| 1550 | - $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0; |
|
| 1551 | - if (! defined('DOING_AJAX') |
|
| 1552 | - && ( |
|
| 1553 | - ! function_exists('is_admin') |
|
| 1554 | - || ! EE_Registry::instance()->CAP->current_user_can( |
|
| 1555 | - $capability, |
|
| 1556 | - $this->page_slug |
|
| 1557 | - . '_' |
|
| 1558 | - . $route_to_check, |
|
| 1559 | - $id |
|
| 1560 | - ) |
|
| 1561 | - ) |
|
| 1562 | - ) { |
|
| 1563 | - if ($verify_only) { |
|
| 1564 | - return false; |
|
| 1565 | - } |
|
| 1566 | - if (is_user_logged_in()) { |
|
| 1567 | - wp_die(__('You do not have access to this route.', 'event_espresso')); |
|
| 1568 | - } else { |
|
| 1569 | - return false; |
|
| 1570 | - } |
|
| 1571 | - } |
|
| 1572 | - return true; |
|
| 1573 | - } |
|
| 1574 | - |
|
| 1575 | - |
|
| 1576 | - /** |
|
| 1577 | - * admin_init_global |
|
| 1578 | - * This runs all the code that we want executed within the WP admin_init hook. |
|
| 1579 | - * This method executes for ALL EE Admin pages. |
|
| 1580 | - * |
|
| 1581 | - * @return void |
|
| 1582 | - */ |
|
| 1583 | - public function admin_init_global() |
|
| 1584 | - { |
|
| 1585 | - } |
|
| 1586 | - |
|
| 1587 | - |
|
| 1588 | - /** |
|
| 1589 | - * wp_loaded_global |
|
| 1590 | - * This runs all the code that we want executed within the WP wp_loaded hook. This method is optional for an |
|
| 1591 | - * EE_Admin page and will execute on every EE Admin Page load |
|
| 1592 | - * |
|
| 1593 | - * @return void |
|
| 1594 | - */ |
|
| 1595 | - public function wp_loaded() |
|
| 1596 | - { |
|
| 1597 | - } |
|
| 1598 | - |
|
| 1599 | - |
|
| 1600 | - /** |
|
| 1601 | - * admin_notices |
|
| 1602 | - * Anything triggered by the 'admin_notices' WP hook should be put in here. This particular method will apply on |
|
| 1603 | - * ALL EE_Admin pages. |
|
| 1604 | - * |
|
| 1605 | - * @return void |
|
| 1606 | - */ |
|
| 1607 | - public function admin_notices_global() |
|
| 1608 | - { |
|
| 1609 | - $this->_display_no_javascript_warning(); |
|
| 1610 | - $this->_display_espresso_notices(); |
|
| 1611 | - } |
|
| 1612 | - |
|
| 1613 | - |
|
| 1614 | - public function network_admin_notices_global() |
|
| 1615 | - { |
|
| 1616 | - $this->_display_no_javascript_warning(); |
|
| 1617 | - $this->_display_espresso_notices(); |
|
| 1618 | - } |
|
| 1619 | - |
|
| 1620 | - |
|
| 1621 | - /** |
|
| 1622 | - * admin_footer_scripts_global |
|
| 1623 | - * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method |
|
| 1624 | - * will apply on ALL EE_Admin pages. |
|
| 1625 | - * |
|
| 1626 | - * @return void |
|
| 1627 | - */ |
|
| 1628 | - public function admin_footer_scripts_global() |
|
| 1629 | - { |
|
| 1630 | - $this->_add_admin_page_ajax_loading_img(); |
|
| 1631 | - $this->_add_admin_page_overlay(); |
|
| 1632 | - // if metaboxes are present we need to add the nonce field |
|
| 1633 | - if (isset($this->_route_config['metaboxes']) |
|
| 1634 | - || isset($this->_route_config['list_table']) |
|
| 1635 | - || (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes']) |
|
| 1636 | - ) { |
|
| 1637 | - wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false); |
|
| 1638 | - wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false); |
|
| 1639 | - } |
|
| 1640 | - } |
|
| 1641 | - |
|
| 1642 | - |
|
| 1643 | - /** |
|
| 1644 | - * admin_footer_global |
|
| 1645 | - * Anything triggered by the wp 'admin_footer' wp hook should be put in here. This particular method will apply on |
|
| 1646 | - * ALL EE_Admin Pages. |
|
| 1647 | - * |
|
| 1648 | - * @return void |
|
| 1649 | - * @throws EE_Error |
|
| 1650 | - */ |
|
| 1651 | - public function admin_footer_global() |
|
| 1652 | - { |
|
| 1653 | - // dialog container for dialog helper |
|
| 1654 | - $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n"; |
|
| 1655 | - $d_cont .= '<div class="ee-notices"></div>'; |
|
| 1656 | - $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>'; |
|
| 1657 | - $d_cont .= '</div>'; |
|
| 1658 | - echo $d_cont; |
|
| 1659 | - // help tour stuff? |
|
| 1660 | - if (isset($this->_help_tour[ $this->_req_action ])) { |
|
| 1661 | - echo implode('<br />', $this->_help_tour[ $this->_req_action ]); |
|
| 1662 | - } |
|
| 1663 | - // current set timezone for timezone js |
|
| 1664 | - echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>'; |
|
| 1665 | - } |
|
| 1666 | - |
|
| 1667 | - |
|
| 1668 | - /** |
|
| 1669 | - * This function sees if there is a method for help popup content existing for the given route. If there is then |
|
| 1670 | - * we'll use the retrieved array to output the content using the template. For child classes: If you want to have |
|
| 1671 | - * help popups then in your templates or your content you set "triggers" for the content using the |
|
| 1672 | - * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method |
|
| 1673 | - * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup |
|
| 1674 | - * method for the content in the format "_help_popup_content_{route_name}()" So if you are setting help content |
|
| 1675 | - * for the |
|
| 1676 | - * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined |
|
| 1677 | - * "help_popup_content_..." method. You must prepare and return an array in the following format array( |
|
| 1678 | - * 'help_trigger_id' => array( |
|
| 1679 | - * 'title' => esc_html__('localized title for popup', 'event_espresso'), |
|
| 1680 | - * 'content' => esc_html__('localized content for popup', 'event_espresso') |
|
| 1681 | - * ) |
|
| 1682 | - * ); |
|
| 1683 | - * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route. |
|
| 1684 | - * |
|
| 1685 | - * @param array $help_array |
|
| 1686 | - * @param bool $display |
|
| 1687 | - * @return string content |
|
| 1688 | - * @throws DomainException |
|
| 1689 | - * @throws EE_Error |
|
| 1690 | - */ |
|
| 1691 | - protected function _set_help_popup_content($help_array = array(), $display = false) |
|
| 1692 | - { |
|
| 1693 | - $content = ''; |
|
| 1694 | - $help_array = empty($help_array) ? $this->_get_help_content() : $help_array; |
|
| 1695 | - // loop through the array and setup content |
|
| 1696 | - foreach ($help_array as $trigger => $help) { |
|
| 1697 | - // make sure the array is setup properly |
|
| 1698 | - if (! isset($help['title']) || ! isset($help['content'])) { |
|
| 1699 | - throw new EE_Error( |
|
| 1700 | - esc_html__( |
|
| 1701 | - 'Does not look like the popup content array has been setup correctly. Might want to double check that. Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class', |
|
| 1702 | - 'event_espresso' |
|
| 1703 | - ) |
|
| 1704 | - ); |
|
| 1705 | - } |
|
| 1706 | - // we're good so let'd setup the template vars and then assign parsed template content to our content. |
|
| 1707 | - $template_args = array( |
|
| 1708 | - 'help_popup_id' => $trigger, |
|
| 1709 | - 'help_popup_title' => $help['title'], |
|
| 1710 | - 'help_popup_content' => $help['content'], |
|
| 1711 | - ); |
|
| 1712 | - $content .= EEH_Template::display_template( |
|
| 1713 | - EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php', |
|
| 1714 | - $template_args, |
|
| 1715 | - true |
|
| 1716 | - ); |
|
| 1717 | - } |
|
| 1718 | - if ($display) { |
|
| 1719 | - echo $content; |
|
| 1720 | - return ''; |
|
| 1721 | - } |
|
| 1722 | - return $content; |
|
| 1723 | - } |
|
| 1724 | - |
|
| 1725 | - |
|
| 1726 | - /** |
|
| 1727 | - * All this does is retrieve the help content array if set by the EE_Admin_Page child |
|
| 1728 | - * |
|
| 1729 | - * @return array properly formatted array for help popup content |
|
| 1730 | - * @throws EE_Error |
|
| 1731 | - */ |
|
| 1732 | - private function _get_help_content() |
|
| 1733 | - { |
|
| 1734 | - // what is the method we're looking for? |
|
| 1735 | - $method_name = '_help_popup_content_' . $this->_req_action; |
|
| 1736 | - // if method doesn't exist let's get out. |
|
| 1737 | - if (! method_exists($this, $method_name)) { |
|
| 1738 | - return array(); |
|
| 1739 | - } |
|
| 1740 | - // k we're good to go let's retrieve the help array |
|
| 1741 | - $help_array = call_user_func(array($this, $method_name)); |
|
| 1742 | - // make sure we've got an array! |
|
| 1743 | - if (! is_array($help_array)) { |
|
| 1744 | - throw new EE_Error( |
|
| 1745 | - esc_html__( |
|
| 1746 | - 'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.', |
|
| 1747 | - 'event_espresso' |
|
| 1748 | - ) |
|
| 1749 | - ); |
|
| 1750 | - } |
|
| 1751 | - return $help_array; |
|
| 1752 | - } |
|
| 1753 | - |
|
| 1754 | - |
|
| 1755 | - /** |
|
| 1756 | - * EE Admin Pages can use this to set a properly formatted trigger for a help popup. |
|
| 1757 | - * By default the trigger html is printed. Otherwise it can be returned if the $display flag is set "false" |
|
| 1758 | - * See comments made on the _set_help_content method for understanding other parts to the help popup tool. |
|
| 1759 | - * |
|
| 1760 | - * @param string $trigger_id reference for retrieving the trigger content for the popup |
|
| 1761 | - * @param boolean $display if false then we return the trigger string |
|
| 1762 | - * @param array $dimensions an array of dimensions for the box (array(h,w)) |
|
| 1763 | - * @return string |
|
| 1764 | - * @throws DomainException |
|
| 1765 | - * @throws EE_Error |
|
| 1766 | - */ |
|
| 1767 | - protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640')) |
|
| 1768 | - { |
|
| 1769 | - if (defined('DOING_AJAX')) { |
|
| 1770 | - return ''; |
|
| 1771 | - } |
|
| 1772 | - // let's check and see if there is any content set for this popup. If there isn't then we'll include a default title and content so that developers know something needs to be corrected |
|
| 1773 | - $help_array = $this->_get_help_content(); |
|
| 1774 | - $help_content = ''; |
|
| 1775 | - if (empty($help_array) || ! isset($help_array[ $trigger_id ])) { |
|
| 1776 | - $help_array[ $trigger_id ] = array( |
|
| 1777 | - 'title' => esc_html__('Missing Content', 'event_espresso'), |
|
| 1778 | - 'content' => esc_html__( |
|
| 1779 | - 'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)', |
|
| 1780 | - 'event_espresso' |
|
| 1781 | - ), |
|
| 1782 | - ); |
|
| 1783 | - $help_content = $this->_set_help_popup_content($help_array, false); |
|
| 1784 | - } |
|
| 1785 | - // let's setup the trigger |
|
| 1786 | - $content = '<a class="ee-dialog" href="?height=' |
|
| 1787 | - . $dimensions[0] |
|
| 1788 | - . '&width=' |
|
| 1789 | - . $dimensions[1] |
|
| 1790 | - . '&inlineId=' |
|
| 1791 | - . $trigger_id |
|
| 1792 | - . '" target="_blank"><span class="question ee-help-popup-question"></span></a>'; |
|
| 1793 | - $content .= $help_content; |
|
| 1794 | - if ($display) { |
|
| 1795 | - echo $content; |
|
| 1796 | - return ''; |
|
| 1797 | - } |
|
| 1798 | - return $content; |
|
| 1799 | - } |
|
| 1800 | - |
|
| 1801 | - |
|
| 1802 | - /** |
|
| 1803 | - * _add_global_screen_options |
|
| 1804 | - * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so. |
|
| 1805 | - * This particular method will add_screen_options on ALL EE_Admin Pages |
|
| 1806 | - * |
|
| 1807 | - * @link http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/ |
|
| 1808 | - * see also WP_Screen object documents... |
|
| 1809 | - * @link http://codex.wordpress.org/Class_Reference/WP_Screen |
|
| 1810 | - * @abstract |
|
| 1811 | - * @return void |
|
| 1812 | - */ |
|
| 1813 | - private function _add_global_screen_options() |
|
| 1814 | - { |
|
| 1815 | - } |
|
| 1816 | - |
|
| 1817 | - |
|
| 1818 | - /** |
|
| 1819 | - * _add_global_feature_pointers |
|
| 1820 | - * This method is used for implementing any "feature pointers" (using built-in WP styling js). |
|
| 1821 | - * This particular method will implement feature pointers for ALL EE_Admin pages. |
|
| 1822 | - * Note: this is just a placeholder for now. Implementation will come down the road |
|
| 1823 | - * |
|
| 1824 | - * @see WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be |
|
| 1825 | - * extended) also see: |
|
| 1826 | - * @link http://eamann.com/tech/wordpress-portland/ |
|
| 1827 | - * @abstract |
|
| 1828 | - * @return void |
|
| 1829 | - */ |
|
| 1830 | - private function _add_global_feature_pointers() |
|
| 1831 | - { |
|
| 1832 | - } |
|
| 1833 | - |
|
| 1834 | - |
|
| 1835 | - /** |
|
| 1836 | - * load_global_scripts_styles |
|
| 1837 | - * The scripts and styles enqueued in here will be loaded on every EE Admin page |
|
| 1838 | - * |
|
| 1839 | - * @return void |
|
| 1840 | - * @throws EE_Error |
|
| 1841 | - */ |
|
| 1842 | - public function load_global_scripts_styles() |
|
| 1843 | - { |
|
| 1844 | - /** STYLES **/ |
|
| 1845 | - // add debugging styles |
|
| 1846 | - if (WP_DEBUG) { |
|
| 1847 | - add_action('admin_head', array($this, 'add_xdebug_style')); |
|
| 1848 | - } |
|
| 1849 | - // register all styles |
|
| 1850 | - wp_register_style( |
|
| 1851 | - 'espresso-ui-theme', |
|
| 1852 | - EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', |
|
| 1853 | - array(), |
|
| 1854 | - EVENT_ESPRESSO_VERSION |
|
| 1855 | - ); |
|
| 1856 | - wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 1857 | - // helpers styles |
|
| 1858 | - wp_register_style( |
|
| 1859 | - 'ee-text-links', |
|
| 1860 | - EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css', |
|
| 1861 | - array(), |
|
| 1862 | - EVENT_ESPRESSO_VERSION |
|
| 1863 | - ); |
|
| 1864 | - /** SCRIPTS **/ |
|
| 1865 | - // register all scripts |
|
| 1866 | - wp_register_script( |
|
| 1867 | - 'ee-dialog', |
|
| 1868 | - EE_ADMIN_URL . 'assets/ee-dialog-helper.js', |
|
| 1869 | - array('jquery', 'jquery-ui-draggable'), |
|
| 1870 | - EVENT_ESPRESSO_VERSION, |
|
| 1871 | - true |
|
| 1872 | - ); |
|
| 1873 | - wp_register_script( |
|
| 1874 | - 'ee_admin_js', |
|
| 1875 | - EE_ADMIN_URL . 'assets/ee-admin-page.js', |
|
| 1876 | - array('espresso_core', 'ee-parse-uri', 'ee-dialog'), |
|
| 1877 | - EVENT_ESPRESSO_VERSION, |
|
| 1878 | - true |
|
| 1879 | - ); |
|
| 1880 | - wp_register_script( |
|
| 1881 | - 'jquery-ui-timepicker-addon', |
|
| 1882 | - EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js', |
|
| 1883 | - array('jquery-ui-datepicker', 'jquery-ui-slider'), |
|
| 1884 | - EVENT_ESPRESSO_VERSION, |
|
| 1885 | - true |
|
| 1886 | - ); |
|
| 1887 | - add_filter('FHEE_load_joyride', '__return_true'); |
|
| 1888 | - // script for sorting tables |
|
| 1889 | - wp_register_script( |
|
| 1890 | - 'espresso_ajax_table_sorting', |
|
| 1891 | - EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js', |
|
| 1892 | - array('ee_admin_js', 'jquery-ui-sortable'), |
|
| 1893 | - EVENT_ESPRESSO_VERSION, |
|
| 1894 | - true |
|
| 1895 | - ); |
|
| 1896 | - // script for parsing uri's |
|
| 1897 | - wp_register_script( |
|
| 1898 | - 'ee-parse-uri', |
|
| 1899 | - EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js', |
|
| 1900 | - array(), |
|
| 1901 | - EVENT_ESPRESSO_VERSION, |
|
| 1902 | - true |
|
| 1903 | - ); |
|
| 1904 | - // and parsing associative serialized form elements |
|
| 1905 | - wp_register_script( |
|
| 1906 | - 'ee-serialize-full-array', |
|
| 1907 | - EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js', |
|
| 1908 | - array('jquery'), |
|
| 1909 | - EVENT_ESPRESSO_VERSION, |
|
| 1910 | - true |
|
| 1911 | - ); |
|
| 1912 | - // helpers scripts |
|
| 1913 | - wp_register_script( |
|
| 1914 | - 'ee-text-links', |
|
| 1915 | - EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js', |
|
| 1916 | - array('jquery'), |
|
| 1917 | - EVENT_ESPRESSO_VERSION, |
|
| 1918 | - true |
|
| 1919 | - ); |
|
| 1920 | - wp_register_script( |
|
| 1921 | - 'ee-moment-core', |
|
| 1922 | - EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js', |
|
| 1923 | - array(), |
|
| 1924 | - EVENT_ESPRESSO_VERSION, |
|
| 1925 | - true |
|
| 1926 | - ); |
|
| 1927 | - wp_register_script( |
|
| 1928 | - 'ee-moment', |
|
| 1929 | - EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js', |
|
| 1930 | - array('ee-moment-core'), |
|
| 1931 | - EVENT_ESPRESSO_VERSION, |
|
| 1932 | - true |
|
| 1933 | - ); |
|
| 1934 | - wp_register_script( |
|
| 1935 | - 'ee-datepicker', |
|
| 1936 | - EE_ADMIN_URL . 'assets/ee-datepicker.js', |
|
| 1937 | - array('jquery-ui-timepicker-addon', 'ee-moment'), |
|
| 1938 | - EVENT_ESPRESSO_VERSION, |
|
| 1939 | - true |
|
| 1940 | - ); |
|
| 1941 | - // google charts |
|
| 1942 | - wp_register_script( |
|
| 1943 | - 'google-charts', |
|
| 1944 | - 'https://www.gstatic.com/charts/loader.js', |
|
| 1945 | - array(), |
|
| 1946 | - EVENT_ESPRESSO_VERSION, |
|
| 1947 | - false |
|
| 1948 | - ); |
|
| 1949 | - // ENQUEUE ALL BASICS BY DEFAULT |
|
| 1950 | - wp_enqueue_style('ee-admin-css'); |
|
| 1951 | - wp_enqueue_script('ee_admin_js'); |
|
| 1952 | - wp_enqueue_script('ee-accounting'); |
|
| 1953 | - wp_enqueue_script('jquery-validate'); |
|
| 1954 | - // taking care of metaboxes |
|
| 1955 | - if (empty($this->_cpt_route) |
|
| 1956 | - && (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes'])) |
|
| 1957 | - ) { |
|
| 1958 | - wp_enqueue_script('dashboard'); |
|
| 1959 | - } |
|
| 1960 | - // LOCALIZED DATA |
|
| 1961 | - // localize script for ajax lazy loading |
|
| 1962 | - $lazy_loader_container_ids = apply_filters( |
|
| 1963 | - 'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers', |
|
| 1964 | - array('espresso_news_post_box_content') |
|
| 1965 | - ); |
|
| 1966 | - wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids); |
|
| 1967 | - /** |
|
| 1968 | - * help tour stuff |
|
| 1969 | - */ |
|
| 1970 | - if (! empty($this->_help_tour)) { |
|
| 1971 | - // register the js for kicking things off |
|
| 1972 | - wp_enqueue_script( |
|
| 1973 | - 'ee-help-tour', |
|
| 1974 | - EE_ADMIN_URL . 'assets/ee-help-tour.js', |
|
| 1975 | - array('jquery-joyride'), |
|
| 1976 | - EVENT_ESPRESSO_VERSION, |
|
| 1977 | - true |
|
| 1978 | - ); |
|
| 1979 | - $tours = array(); |
|
| 1980 | - // setup tours for the js tour object |
|
| 1981 | - foreach ($this->_help_tour['tours'] as $tour) { |
|
| 1982 | - if ($tour instanceof EE_Help_Tour) { |
|
| 1983 | - $tours[] = array( |
|
| 1984 | - 'id' => $tour->get_slug(), |
|
| 1985 | - 'options' => $tour->get_options(), |
|
| 1986 | - ); |
|
| 1987 | - } |
|
| 1988 | - } |
|
| 1989 | - wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours)); |
|
| 1990 | - // admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour |
|
| 1991 | - } |
|
| 1992 | - } |
|
| 1993 | - |
|
| 1994 | - |
|
| 1995 | - /** |
|
| 1996 | - * admin_footer_scripts_eei18n_js_strings |
|
| 1997 | - * |
|
| 1998 | - * @return void |
|
| 1999 | - */ |
|
| 2000 | - public function admin_footer_scripts_eei18n_js_strings() |
|
| 2001 | - { |
|
| 2002 | - EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL; |
|
| 2003 | - EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__( |
|
| 2004 | - 'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!', |
|
| 2005 | - 'event_espresso' |
|
| 2006 | - ); |
|
| 2007 | - EE_Registry::$i18n_js_strings['January'] = esc_html__('January', 'event_espresso'); |
|
| 2008 | - EE_Registry::$i18n_js_strings['February'] = esc_html__('February', 'event_espresso'); |
|
| 2009 | - EE_Registry::$i18n_js_strings['March'] = esc_html__('March', 'event_espresso'); |
|
| 2010 | - EE_Registry::$i18n_js_strings['April'] = esc_html__('April', 'event_espresso'); |
|
| 2011 | - EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso'); |
|
| 2012 | - EE_Registry::$i18n_js_strings['June'] = esc_html__('June', 'event_espresso'); |
|
| 2013 | - EE_Registry::$i18n_js_strings['July'] = esc_html__('July', 'event_espresso'); |
|
| 2014 | - EE_Registry::$i18n_js_strings['August'] = esc_html__('August', 'event_espresso'); |
|
| 2015 | - EE_Registry::$i18n_js_strings['September'] = esc_html__('September', 'event_espresso'); |
|
| 2016 | - EE_Registry::$i18n_js_strings['October'] = esc_html__('October', 'event_espresso'); |
|
| 2017 | - EE_Registry::$i18n_js_strings['November'] = esc_html__('November', 'event_espresso'); |
|
| 2018 | - EE_Registry::$i18n_js_strings['December'] = esc_html__('December', 'event_espresso'); |
|
| 2019 | - EE_Registry::$i18n_js_strings['Jan'] = esc_html__('Jan', 'event_espresso'); |
|
| 2020 | - EE_Registry::$i18n_js_strings['Feb'] = esc_html__('Feb', 'event_espresso'); |
|
| 2021 | - EE_Registry::$i18n_js_strings['Mar'] = esc_html__('Mar', 'event_espresso'); |
|
| 2022 | - EE_Registry::$i18n_js_strings['Apr'] = esc_html__('Apr', 'event_espresso'); |
|
| 2023 | - EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso'); |
|
| 2024 | - EE_Registry::$i18n_js_strings['Jun'] = esc_html__('Jun', 'event_espresso'); |
|
| 2025 | - EE_Registry::$i18n_js_strings['Jul'] = esc_html__('Jul', 'event_espresso'); |
|
| 2026 | - EE_Registry::$i18n_js_strings['Aug'] = esc_html__('Aug', 'event_espresso'); |
|
| 2027 | - EE_Registry::$i18n_js_strings['Sep'] = esc_html__('Sep', 'event_espresso'); |
|
| 2028 | - EE_Registry::$i18n_js_strings['Oct'] = esc_html__('Oct', 'event_espresso'); |
|
| 2029 | - EE_Registry::$i18n_js_strings['Nov'] = esc_html__('Nov', 'event_espresso'); |
|
| 2030 | - EE_Registry::$i18n_js_strings['Dec'] = esc_html__('Dec', 'event_espresso'); |
|
| 2031 | - EE_Registry::$i18n_js_strings['Sunday'] = esc_html__('Sunday', 'event_espresso'); |
|
| 2032 | - EE_Registry::$i18n_js_strings['Monday'] = esc_html__('Monday', 'event_espresso'); |
|
| 2033 | - EE_Registry::$i18n_js_strings['Tuesday'] = esc_html__('Tuesday', 'event_espresso'); |
|
| 2034 | - EE_Registry::$i18n_js_strings['Wednesday'] = esc_html__('Wednesday', 'event_espresso'); |
|
| 2035 | - EE_Registry::$i18n_js_strings['Thursday'] = esc_html__('Thursday', 'event_espresso'); |
|
| 2036 | - EE_Registry::$i18n_js_strings['Friday'] = esc_html__('Friday', 'event_espresso'); |
|
| 2037 | - EE_Registry::$i18n_js_strings['Saturday'] = esc_html__('Saturday', 'event_espresso'); |
|
| 2038 | - EE_Registry::$i18n_js_strings['Sun'] = esc_html__('Sun', 'event_espresso'); |
|
| 2039 | - EE_Registry::$i18n_js_strings['Mon'] = esc_html__('Mon', 'event_espresso'); |
|
| 2040 | - EE_Registry::$i18n_js_strings['Tue'] = esc_html__('Tue', 'event_espresso'); |
|
| 2041 | - EE_Registry::$i18n_js_strings['Wed'] = esc_html__('Wed', 'event_espresso'); |
|
| 2042 | - EE_Registry::$i18n_js_strings['Thu'] = esc_html__('Thu', 'event_espresso'); |
|
| 2043 | - EE_Registry::$i18n_js_strings['Fri'] = esc_html__('Fri', 'event_espresso'); |
|
| 2044 | - EE_Registry::$i18n_js_strings['Sat'] = esc_html__('Sat', 'event_espresso'); |
|
| 2045 | - } |
|
| 2046 | - |
|
| 2047 | - |
|
| 2048 | - /** |
|
| 2049 | - * load enhanced xdebug styles for ppl with failing eyesight |
|
| 2050 | - * |
|
| 2051 | - * @return void |
|
| 2052 | - */ |
|
| 2053 | - public function add_xdebug_style() |
|
| 2054 | - { |
|
| 2055 | - echo '<style>.xdebug-error { font-size:1.5em; }</style>'; |
|
| 2056 | - } |
|
| 2057 | - |
|
| 2058 | - |
|
| 2059 | - /************************/ |
|
| 2060 | - /** LIST TABLE METHODS **/ |
|
| 2061 | - /************************/ |
|
| 2062 | - /** |
|
| 2063 | - * this sets up the list table if the current view requires it. |
|
| 2064 | - * |
|
| 2065 | - * @return void |
|
| 2066 | - * @throws EE_Error |
|
| 2067 | - */ |
|
| 2068 | - protected function _set_list_table() |
|
| 2069 | - { |
|
| 2070 | - // first is this a list_table view? |
|
| 2071 | - if (! isset($this->_route_config['list_table'])) { |
|
| 2072 | - return; |
|
| 2073 | - } //not a list_table view so get out. |
|
| 2074 | - // list table functions are per view specific (because some admin pages might have more than one list table!) |
|
| 2075 | - $list_table_view = '_set_list_table_views_' . $this->_req_action; |
|
| 2076 | - if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) { |
|
| 2077 | - // user error msg |
|
| 2078 | - $error_msg = esc_html__( |
|
| 2079 | - 'An error occurred. The requested list table views could not be found.', |
|
| 2080 | - 'event_espresso' |
|
| 2081 | - ); |
|
| 2082 | - // developer error msg |
|
| 2083 | - $error_msg .= '||' |
|
| 2084 | - . sprintf( |
|
| 2085 | - esc_html__( |
|
| 2086 | - 'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.', |
|
| 2087 | - 'event_espresso' |
|
| 2088 | - ), |
|
| 2089 | - $this->_req_action, |
|
| 2090 | - $list_table_view |
|
| 2091 | - ); |
|
| 2092 | - throw new EE_Error($error_msg); |
|
| 2093 | - } |
|
| 2094 | - // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally |
|
| 2095 | - $this->_views = apply_filters( |
|
| 2096 | - 'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action, |
|
| 2097 | - $this->_views |
|
| 2098 | - ); |
|
| 2099 | - $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views); |
|
| 2100 | - $this->_views = apply_filters('FHEE_list_table_views', $this->_views); |
|
| 2101 | - $this->_set_list_table_view(); |
|
| 2102 | - $this->_set_list_table_object(); |
|
| 2103 | - } |
|
| 2104 | - |
|
| 2105 | - |
|
| 2106 | - /** |
|
| 2107 | - * set current view for List Table |
|
| 2108 | - * |
|
| 2109 | - * @return void |
|
| 2110 | - */ |
|
| 2111 | - protected function _set_list_table_view() |
|
| 2112 | - { |
|
| 2113 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2114 | - // looking at active items or dumpster diving ? |
|
| 2115 | - if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) { |
|
| 2116 | - $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all'; |
|
| 2117 | - } else { |
|
| 2118 | - $this->_view = sanitize_key($this->_req_data['status']); |
|
| 2119 | - } |
|
| 2120 | - } |
|
| 2121 | - |
|
| 2122 | - |
|
| 2123 | - /** |
|
| 2124 | - * _set_list_table_object |
|
| 2125 | - * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of. |
|
| 2126 | - * |
|
| 2127 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 2128 | - * @throws \InvalidArgumentException |
|
| 2129 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 2130 | - * @throws EE_Error |
|
| 2131 | - * @throws InvalidInterfaceException |
|
| 2132 | - */ |
|
| 2133 | - protected function _set_list_table_object() |
|
| 2134 | - { |
|
| 2135 | - if (isset($this->_route_config['list_table'])) { |
|
| 2136 | - if (! class_exists($this->_route_config['list_table'])) { |
|
| 2137 | - throw new EE_Error( |
|
| 2138 | - sprintf( |
|
| 2139 | - esc_html__( |
|
| 2140 | - 'The %s class defined for the list table does not exist. Please check the spelling of the class ref in the $_page_config property on %s.', |
|
| 2141 | - 'event_espresso' |
|
| 2142 | - ), |
|
| 2143 | - $this->_route_config['list_table'], |
|
| 2144 | - get_class($this) |
|
| 2145 | - ) |
|
| 2146 | - ); |
|
| 2147 | - } |
|
| 2148 | - $this->_list_table_object = $this->loader->getShared( |
|
| 2149 | - $this->_route_config['list_table'], |
|
| 2150 | - array($this) |
|
| 2151 | - ); |
|
| 2152 | - } |
|
| 2153 | - } |
|
| 2154 | - |
|
| 2155 | - |
|
| 2156 | - /** |
|
| 2157 | - * get_list_table_view_RLs - get it? View RL ?? VU-RL??? URL ?? |
|
| 2158 | - * |
|
| 2159 | - * @param array $extra_query_args Optional. An array of extra query args to add to the generated |
|
| 2160 | - * urls. The array should be indexed by the view it is being |
|
| 2161 | - * added to. |
|
| 2162 | - * @return array |
|
| 2163 | - */ |
|
| 2164 | - public function get_list_table_view_RLs($extra_query_args = array()) |
|
| 2165 | - { |
|
| 2166 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2167 | - if (empty($this->_views)) { |
|
| 2168 | - $this->_views = array(); |
|
| 2169 | - } |
|
| 2170 | - // cycle thru views |
|
| 2171 | - foreach ($this->_views as $key => $view) { |
|
| 2172 | - $query_args = array(); |
|
| 2173 | - // check for current view |
|
| 2174 | - $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : ''; |
|
| 2175 | - $query_args['action'] = $this->_req_action; |
|
| 2176 | - $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce'); |
|
| 2177 | - $query_args['status'] = $view['slug']; |
|
| 2178 | - // merge any other arguments sent in. |
|
| 2179 | - if (isset($extra_query_args[ $view['slug'] ])) { |
|
| 2180 | - $query_args = array_merge($query_args, $extra_query_args[ $view['slug'] ]); |
|
| 2181 | - } |
|
| 2182 | - $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url); |
|
| 2183 | - } |
|
| 2184 | - return $this->_views; |
|
| 2185 | - } |
|
| 2186 | - |
|
| 2187 | - |
|
| 2188 | - /** |
|
| 2189 | - * _entries_per_page_dropdown |
|
| 2190 | - * generates a drop down box for selecting the number of visible rows in an admin page list table |
|
| 2191 | - * |
|
| 2192 | - * @todo : Note: ideally this should be added to the screen options dropdown as that would be consistent with how |
|
| 2193 | - * WP does it. |
|
| 2194 | - * @param int $max_entries total number of rows in the table |
|
| 2195 | - * @return string |
|
| 2196 | - */ |
|
| 2197 | - protected function _entries_per_page_dropdown($max_entries = 0) |
|
| 2198 | - { |
|
| 2199 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2200 | - $values = array(10, 25, 50, 100); |
|
| 2201 | - $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10; |
|
| 2202 | - if ($max_entries) { |
|
| 2203 | - $values[] = $max_entries; |
|
| 2204 | - sort($values); |
|
| 2205 | - } |
|
| 2206 | - $entries_per_page_dropdown = ' |
|
| 104 | + /** |
|
| 105 | + * @var array $_route_config |
|
| 106 | + */ |
|
| 107 | + protected $_route_config; |
|
| 108 | + |
|
| 109 | + /** |
|
| 110 | + * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out |
|
| 111 | + * actions. |
|
| 112 | + * |
|
| 113 | + * @since 4.6.x |
|
| 114 | + * @var array. |
|
| 115 | + */ |
|
| 116 | + protected $_default_route_query_args; |
|
| 117 | + |
|
| 118 | + // set via request page and action args. |
|
| 119 | + protected $_current_page; |
|
| 120 | + |
|
| 121 | + protected $_current_view; |
|
| 122 | + |
|
| 123 | + protected $_current_page_view_url; |
|
| 124 | + |
|
| 125 | + // sanitized request action (and nonce) |
|
| 126 | + |
|
| 127 | + /** |
|
| 128 | + * @var string $_req_action |
|
| 129 | + */ |
|
| 130 | + protected $_req_action; |
|
| 131 | + |
|
| 132 | + /** |
|
| 133 | + * @var string $_req_nonce |
|
| 134 | + */ |
|
| 135 | + protected $_req_nonce; |
|
| 136 | + |
|
| 137 | + // search related |
|
| 138 | + protected $_search_btn_label; |
|
| 139 | + |
|
| 140 | + protected $_search_box_callback; |
|
| 141 | + |
|
| 142 | + /** |
|
| 143 | + * WP Current Screen object |
|
| 144 | + * |
|
| 145 | + * @var WP_Screen |
|
| 146 | + */ |
|
| 147 | + protected $_current_screen; |
|
| 148 | + |
|
| 149 | + // for holding EE_Admin_Hooks object when needed (set via set_hook_object()) |
|
| 150 | + protected $_hook_obj; |
|
| 151 | + |
|
| 152 | + // for holding incoming request data |
|
| 153 | + protected $_req_data; |
|
| 154 | + |
|
| 155 | + // yes / no array for admin form fields |
|
| 156 | + protected $_yes_no_values = array(); |
|
| 157 | + |
|
| 158 | + // some default things shared by all child classes |
|
| 159 | + protected $_default_espresso_metaboxes; |
|
| 160 | + |
|
| 161 | + /** |
|
| 162 | + * EE_Registry Object |
|
| 163 | + * |
|
| 164 | + * @var EE_Registry |
|
| 165 | + */ |
|
| 166 | + protected $EE = null; |
|
| 167 | + |
|
| 168 | + |
|
| 169 | + /** |
|
| 170 | + * This is just a property that flags whether the given route is a caffeinated route or not. |
|
| 171 | + * |
|
| 172 | + * @var boolean |
|
| 173 | + */ |
|
| 174 | + protected $_is_caf = false; |
|
| 175 | + |
|
| 176 | + |
|
| 177 | + /** |
|
| 178 | + * @Constructor |
|
| 179 | + * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object. |
|
| 180 | + * @throws EE_Error |
|
| 181 | + * @throws InvalidArgumentException |
|
| 182 | + * @throws ReflectionException |
|
| 183 | + * @throws InvalidDataTypeException |
|
| 184 | + * @throws InvalidInterfaceException |
|
| 185 | + */ |
|
| 186 | + public function __construct($routing = true) |
|
| 187 | + { |
|
| 188 | + $this->loader = LoaderFactory::getLoader(); |
|
| 189 | + if (strpos($this->_get_dir(), 'caffeinated') !== false) { |
|
| 190 | + $this->_is_caf = true; |
|
| 191 | + } |
|
| 192 | + $this->_yes_no_values = array( |
|
| 193 | + array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')), |
|
| 194 | + array('id' => false, 'text' => esc_html__('No', 'event_espresso')), |
|
| 195 | + ); |
|
| 196 | + // set the _req_data property. |
|
| 197 | + $this->_req_data = array_merge($_GET, $_POST); |
|
| 198 | + // routing enabled? |
|
| 199 | + $this->_routing = $routing; |
|
| 200 | + // set initial page props (child method) |
|
| 201 | + $this->_init_page_props(); |
|
| 202 | + // set global defaults |
|
| 203 | + $this->_set_defaults(); |
|
| 204 | + // set early because incoming requests could be ajax related and we need to register those hooks. |
|
| 205 | + $this->_global_ajax_hooks(); |
|
| 206 | + $this->_ajax_hooks(); |
|
| 207 | + // other_page_hooks have to be early too. |
|
| 208 | + $this->_do_other_page_hooks(); |
|
| 209 | + // This just allows us to have extending classes do something specific |
|
| 210 | + // before the parent constructor runs _page_setup(). |
|
| 211 | + if (method_exists($this, '_before_page_setup')) { |
|
| 212 | + $this->_before_page_setup(); |
|
| 213 | + } |
|
| 214 | + // set up page dependencies |
|
| 215 | + $this->_page_setup(); |
|
| 216 | + } |
|
| 217 | + |
|
| 218 | + |
|
| 219 | + /** |
|
| 220 | + * _init_page_props |
|
| 221 | + * Child classes use to set at least the following properties: |
|
| 222 | + * $page_slug. |
|
| 223 | + * $page_label. |
|
| 224 | + * |
|
| 225 | + * @abstract |
|
| 226 | + * @return void |
|
| 227 | + */ |
|
| 228 | + abstract protected function _init_page_props(); |
|
| 229 | + |
|
| 230 | + |
|
| 231 | + /** |
|
| 232 | + * _ajax_hooks |
|
| 233 | + * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here. |
|
| 234 | + * Note: within the ajax callback methods. |
|
| 235 | + * |
|
| 236 | + * @abstract |
|
| 237 | + * @return void |
|
| 238 | + */ |
|
| 239 | + abstract protected function _ajax_hooks(); |
|
| 240 | + |
|
| 241 | + |
|
| 242 | + /** |
|
| 243 | + * _define_page_props |
|
| 244 | + * child classes define page properties in here. Must include at least: |
|
| 245 | + * $_admin_base_url = base_url for all admin pages |
|
| 246 | + * $_admin_page_title = default admin_page_title for admin pages |
|
| 247 | + * $_labels = array of default labels for various automatically generated elements: |
|
| 248 | + * array( |
|
| 249 | + * 'buttons' => array( |
|
| 250 | + * 'add' => esc_html__('label for add new button'), |
|
| 251 | + * 'edit' => esc_html__('label for edit button'), |
|
| 252 | + * 'delete' => esc_html__('label for delete button') |
|
| 253 | + * ) |
|
| 254 | + * ) |
|
| 255 | + * |
|
| 256 | + * @abstract |
|
| 257 | + * @return void |
|
| 258 | + */ |
|
| 259 | + abstract protected function _define_page_props(); |
|
| 260 | + |
|
| 261 | + |
|
| 262 | + /** |
|
| 263 | + * _set_page_routes |
|
| 264 | + * child classes use this to define the page routes for all subpages handled by the class. Page routes are |
|
| 265 | + * assigned to a action => method pairs in an array and to the $_page_routes property. Each page route must also |
|
| 266 | + * have a 'default' route. Here's the format |
|
| 267 | + * $this->_page_routes = array( |
|
| 268 | + * 'default' => array( |
|
| 269 | + * 'func' => '_default_method_handling_route', |
|
| 270 | + * 'args' => array('array','of','args'), |
|
| 271 | + * 'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e. |
|
| 272 | + * ajax request, backend processing) |
|
| 273 | + * 'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a |
|
| 274 | + * headers route after. The string you enter here should match the defined route reference for a |
|
| 275 | + * headers sent route. |
|
| 276 | + * 'capability' => 'route_capability', //indicate a string for minimum capability required to access |
|
| 277 | + * this route. |
|
| 278 | + * 'obj_id' => 10 // if this route has an object id, then this can include it (used for capability |
|
| 279 | + * checks). |
|
| 280 | + * ), |
|
| 281 | + * 'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a |
|
| 282 | + * handling method. |
|
| 283 | + * ) |
|
| 284 | + * ) |
|
| 285 | + * |
|
| 286 | + * @abstract |
|
| 287 | + * @return void |
|
| 288 | + */ |
|
| 289 | + abstract protected function _set_page_routes(); |
|
| 290 | + |
|
| 291 | + |
|
| 292 | + /** |
|
| 293 | + * _set_page_config |
|
| 294 | + * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the |
|
| 295 | + * array corresponds to the page_route for the loaded page. Format: |
|
| 296 | + * $this->_page_config = array( |
|
| 297 | + * 'default' => array( |
|
| 298 | + * 'labels' => array( |
|
| 299 | + * 'buttons' => array( |
|
| 300 | + * 'add' => esc_html__('label for adding item'), |
|
| 301 | + * 'edit' => esc_html__('label for editing item'), |
|
| 302 | + * 'delete' => esc_html__('label for deleting item') |
|
| 303 | + * ), |
|
| 304 | + * 'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso') |
|
| 305 | + * ), //optional an array of custom labels for various automatically generated elements to use on the |
|
| 306 | + * page. If this isn't present then the defaults will be used as set for the $this->_labels in |
|
| 307 | + * _define_page_props() method |
|
| 308 | + * 'nav' => array( |
|
| 309 | + * 'label' => esc_html__('Label for Tab', 'event_espresso'). |
|
| 310 | + * 'url' => 'http://someurl', //automatically generated UNLESS you define |
|
| 311 | + * 'css_class' => 'css-class', //automatically generated UNLESS you define |
|
| 312 | + * 'order' => 10, //required to indicate tab position. |
|
| 313 | + * 'persistent' => false //if you want the nav tab to ONLY display when the specific route is |
|
| 314 | + * displayed then add this parameter. |
|
| 315 | + * 'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page. |
|
| 316 | + * 'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load |
|
| 317 | + * metaboxes set for eventespresso admin pages. |
|
| 318 | + * 'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have |
|
| 319 | + * metaboxes. Typically this is used if the 'metaboxes' index is not used because metaboxes are added |
|
| 320 | + * later. We just use this flag to make sure the necessary js gets enqueued on page load. |
|
| 321 | + * 'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the |
|
| 322 | + * given route has help popups setup and if it does then we need to make sure thickbox is enqueued. |
|
| 323 | + * 'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes). The |
|
| 324 | + * array indicates the max number of columns (4) and the default number of columns on page load (2). |
|
| 325 | + * There is an option in the "screen_options" dropdown that is setup so users can pick what columns they |
|
| 326 | + * want to display. |
|
| 327 | + * 'help_tabs' => array( //this is used for adding help tabs to a page |
|
| 328 | + * 'tab_id' => array( |
|
| 329 | + * 'title' => 'tab_title', |
|
| 330 | + * 'filename' => 'name_of_file_containing_content', //this is the primary method for setting |
|
| 331 | + * help tab content. The fallback if it isn't present is to try a the callback. Filename |
|
| 332 | + * should match a file in the admin folder's "help_tabs" dir (ie.. |
|
| 333 | + * events/help_tabs/name_of_file_containing_content.help_tab.php) |
|
| 334 | + * 'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will |
|
| 335 | + * attempt to use the callback which should match the name of a method in the class |
|
| 336 | + * ), |
|
| 337 | + * 'tab2_id' => array( |
|
| 338 | + * 'title' => 'tab2 title', |
|
| 339 | + * 'filename' => 'file_name_2' |
|
| 340 | + * 'callback' => 'callback_method_for_content', |
|
| 341 | + * ), |
|
| 342 | + * 'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the |
|
| 343 | + * help tab area on an admin page. @link |
|
| 344 | + * http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/ |
|
| 345 | + * 'help_tour' => array( |
|
| 346 | + * 'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located |
|
| 347 | + * in a folder for this admin page named "help_tours", a file name matching the key given here |
|
| 348 | + * (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class) |
|
| 349 | + * ), |
|
| 350 | + * 'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is |
|
| 351 | + * true if it isn't present). To remove the requirement for a nonce check when this route is visited |
|
| 352 | + * just set |
|
| 353 | + * 'require_nonce' to FALSE |
|
| 354 | + * ) |
|
| 355 | + * ) |
|
| 356 | + * |
|
| 357 | + * @abstract |
|
| 358 | + * @return void |
|
| 359 | + */ |
|
| 360 | + abstract protected function _set_page_config(); |
|
| 361 | + |
|
| 362 | + |
|
| 363 | + |
|
| 364 | + |
|
| 365 | + |
|
| 366 | + /** end sample help_tour methods **/ |
|
| 367 | + /** |
|
| 368 | + * _add_screen_options |
|
| 369 | + * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for |
|
| 370 | + * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options |
|
| 371 | + * to a particular view. |
|
| 372 | + * |
|
| 373 | + * @link http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/ |
|
| 374 | + * see also WP_Screen object documents... |
|
| 375 | + * @link http://codex.wordpress.org/Class_Reference/WP_Screen |
|
| 376 | + * @abstract |
|
| 377 | + * @return void |
|
| 378 | + */ |
|
| 379 | + abstract protected function _add_screen_options(); |
|
| 380 | + |
|
| 381 | + |
|
| 382 | + /** |
|
| 383 | + * _add_feature_pointers |
|
| 384 | + * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js). |
|
| 385 | + * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a |
|
| 386 | + * particular view. Note: this is just a placeholder for now. Implementation will come down the road See: |
|
| 387 | + * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be |
|
| 388 | + * extended) also see: |
|
| 389 | + * |
|
| 390 | + * @link http://eamann.com/tech/wordpress-portland/ |
|
| 391 | + * @abstract |
|
| 392 | + * @return void |
|
| 393 | + */ |
|
| 394 | + abstract protected function _add_feature_pointers(); |
|
| 395 | + |
|
| 396 | + |
|
| 397 | + /** |
|
| 398 | + * load_scripts_styles |
|
| 399 | + * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for |
|
| 400 | + * their pages/subpages. Note this is for all pages/subpages of the system. You can also load only specific |
|
| 401 | + * scripts/styles per view by putting them in a dynamic function in this format |
|
| 402 | + * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg) |
|
| 403 | + * |
|
| 404 | + * @abstract |
|
| 405 | + * @return void |
|
| 406 | + */ |
|
| 407 | + abstract public function load_scripts_styles(); |
|
| 408 | + |
|
| 409 | + |
|
| 410 | + /** |
|
| 411 | + * admin_init |
|
| 412 | + * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here. This will apply to |
|
| 413 | + * all pages/views loaded by child class. |
|
| 414 | + * |
|
| 415 | + * @abstract |
|
| 416 | + * @return void |
|
| 417 | + */ |
|
| 418 | + abstract public function admin_init(); |
|
| 419 | + |
|
| 420 | + |
|
| 421 | + /** |
|
| 422 | + * admin_notices |
|
| 423 | + * Anything triggered by the 'admin_notices' WP hook should be put in here. This particular method will apply to |
|
| 424 | + * all pages/views loaded by child class. |
|
| 425 | + * |
|
| 426 | + * @abstract |
|
| 427 | + * @return void |
|
| 428 | + */ |
|
| 429 | + abstract public function admin_notices(); |
|
| 430 | + |
|
| 431 | + |
|
| 432 | + /** |
|
| 433 | + * admin_footer_scripts |
|
| 434 | + * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method |
|
| 435 | + * will apply to all pages/views loaded by child class. |
|
| 436 | + * |
|
| 437 | + * @return void |
|
| 438 | + */ |
|
| 439 | + abstract public function admin_footer_scripts(); |
|
| 440 | + |
|
| 441 | + |
|
| 442 | + /** |
|
| 443 | + * admin_footer |
|
| 444 | + * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will |
|
| 445 | + * apply to all pages/views loaded by child class. |
|
| 446 | + * |
|
| 447 | + * @return void |
|
| 448 | + */ |
|
| 449 | + public function admin_footer() |
|
| 450 | + { |
|
| 451 | + } |
|
| 452 | + |
|
| 453 | + |
|
| 454 | + /** |
|
| 455 | + * _global_ajax_hooks |
|
| 456 | + * all global add_action('wp_ajax_{name_of_hook}') hooks in here. |
|
| 457 | + * Note: within the ajax callback methods. |
|
| 458 | + * |
|
| 459 | + * @abstract |
|
| 460 | + * @return void |
|
| 461 | + */ |
|
| 462 | + protected function _global_ajax_hooks() |
|
| 463 | + { |
|
| 464 | + // for lazy loading of metabox content |
|
| 465 | + add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10); |
|
| 466 | + } |
|
| 467 | + |
|
| 468 | + |
|
| 469 | + public function ajax_metabox_content() |
|
| 470 | + { |
|
| 471 | + $contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : ''; |
|
| 472 | + $url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : ''; |
|
| 473 | + self::cached_rss_display($contentid, $url); |
|
| 474 | + wp_die(); |
|
| 475 | + } |
|
| 476 | + |
|
| 477 | + |
|
| 478 | + /** |
|
| 479 | + * _page_setup |
|
| 480 | + * Makes sure any things that need to be loaded early get handled. We also escape early here if the page requested |
|
| 481 | + * doesn't match the object. |
|
| 482 | + * |
|
| 483 | + * @final |
|
| 484 | + * @return void |
|
| 485 | + * @throws EE_Error |
|
| 486 | + * @throws InvalidArgumentException |
|
| 487 | + * @throws ReflectionException |
|
| 488 | + * @throws InvalidDataTypeException |
|
| 489 | + * @throws InvalidInterfaceException |
|
| 490 | + */ |
|
| 491 | + final protected function _page_setup() |
|
| 492 | + { |
|
| 493 | + // requires? |
|
| 494 | + // admin_init stuff - global - we're setting this REALLY early so if EE_Admin pages have to hook into other WP pages they can. But keep in mind, not everything is available from the EE_Admin Page object at this point. |
|
| 495 | + add_action('admin_init', array($this, 'admin_init_global'), 5); |
|
| 496 | + // next verify if we need to load anything... |
|
| 497 | + $this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : ''; |
|
| 498 | + $this->page_folder = strtolower( |
|
| 499 | + str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this)) |
|
| 500 | + ); |
|
| 501 | + global $ee_menu_slugs; |
|
| 502 | + $ee_menu_slugs = (array) $ee_menu_slugs; |
|
| 503 | + if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) { |
|
| 504 | + return; |
|
| 505 | + } |
|
| 506 | + // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first |
|
| 507 | + if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') { |
|
| 508 | + $this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1' |
|
| 509 | + ? $this->_req_data['action2'] |
|
| 510 | + : $this->_req_data['action']; |
|
| 511 | + } |
|
| 512 | + // then set blank or -1 action values to 'default' |
|
| 513 | + $this->_req_action = isset($this->_req_data['action']) |
|
| 514 | + && ! empty($this->_req_data['action']) |
|
| 515 | + && $this->_req_data['action'] !== '-1' |
|
| 516 | + ? sanitize_key($this->_req_data['action']) |
|
| 517 | + : 'default'; |
|
| 518 | + // if action is 'default' after the above BUT we have 'route' var set, then let's use the route as the action. |
|
| 519 | + // This covers cases where we're coming in from a list table that isn't on the default route. |
|
| 520 | + $this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route']) |
|
| 521 | + ? $this->_req_data['route'] : $this->_req_action; |
|
| 522 | + // however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be |
|
| 523 | + $this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route']) |
|
| 524 | + ? $this->_req_data['route'] |
|
| 525 | + : $this->_req_action; |
|
| 526 | + $this->_current_view = $this->_req_action; |
|
| 527 | + $this->_req_nonce = $this->_req_action . '_nonce'; |
|
| 528 | + $this->_define_page_props(); |
|
| 529 | + $this->_current_page_view_url = add_query_arg( |
|
| 530 | + array('page' => $this->_current_page, 'action' => $this->_current_view), |
|
| 531 | + $this->_admin_base_url |
|
| 532 | + ); |
|
| 533 | + // default things |
|
| 534 | + $this->_default_espresso_metaboxes = array( |
|
| 535 | + '_espresso_news_post_box', |
|
| 536 | + '_espresso_links_post_box', |
|
| 537 | + '_espresso_ratings_request', |
|
| 538 | + '_espresso_sponsors_post_box', |
|
| 539 | + ); |
|
| 540 | + // set page configs |
|
| 541 | + $this->_set_page_routes(); |
|
| 542 | + $this->_set_page_config(); |
|
| 543 | + // let's include any referrer data in our default_query_args for this route for "stickiness". |
|
| 544 | + if (isset($this->_req_data['wp_referer'])) { |
|
| 545 | + $this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer']; |
|
| 546 | + } |
|
| 547 | + // for caffeinated and other extended functionality. |
|
| 548 | + // If there is a _extend_page_config method |
|
| 549 | + // then let's run that to modify the all the various page configuration arrays |
|
| 550 | + if (method_exists($this, '_extend_page_config')) { |
|
| 551 | + $this->_extend_page_config(); |
|
| 552 | + } |
|
| 553 | + // for CPT and other extended functionality. |
|
| 554 | + // If there is an _extend_page_config_for_cpt |
|
| 555 | + // then let's run that to modify all the various page configuration arrays. |
|
| 556 | + if (method_exists($this, '_extend_page_config_for_cpt')) { |
|
| 557 | + $this->_extend_page_config_for_cpt(); |
|
| 558 | + } |
|
| 559 | + // filter routes and page_config so addons can add their stuff. Filtering done per class |
|
| 560 | + $this->_page_routes = apply_filters( |
|
| 561 | + 'FHEE__' . get_class($this) . '__page_setup__page_routes', |
|
| 562 | + $this->_page_routes, |
|
| 563 | + $this |
|
| 564 | + ); |
|
| 565 | + $this->_page_config = apply_filters( |
|
| 566 | + 'FHEE__' . get_class($this) . '__page_setup__page_config', |
|
| 567 | + $this->_page_config, |
|
| 568 | + $this |
|
| 569 | + ); |
|
| 570 | + // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present |
|
| 571 | + // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action |
|
| 572 | + if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) { |
|
| 573 | + add_action( |
|
| 574 | + 'AHEE__EE_Admin_Page__route_admin_request', |
|
| 575 | + array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view), |
|
| 576 | + 10, |
|
| 577 | + 2 |
|
| 578 | + ); |
|
| 579 | + } |
|
| 580 | + // next route only if routing enabled |
|
| 581 | + if ($this->_routing && ! defined('DOING_AJAX')) { |
|
| 582 | + $this->_verify_routes(); |
|
| 583 | + // next let's just check user_access and kill if no access |
|
| 584 | + $this->check_user_access(); |
|
| 585 | + if ($this->_is_UI_request) { |
|
| 586 | + // admin_init stuff - global, all views for this page class, specific view |
|
| 587 | + add_action('admin_init', array($this, 'admin_init'), 10); |
|
| 588 | + if (method_exists($this, 'admin_init_' . $this->_current_view)) { |
|
| 589 | + add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15); |
|
| 590 | + } |
|
| 591 | + } else { |
|
| 592 | + // hijack regular WP loading and route admin request immediately |
|
| 593 | + @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT)); |
|
| 594 | + $this->route_admin_request(); |
|
| 595 | + } |
|
| 596 | + } |
|
| 597 | + } |
|
| 598 | + |
|
| 599 | + |
|
| 600 | + /** |
|
| 601 | + * Provides a way for related child admin pages to load stuff on the loaded admin page. |
|
| 602 | + * |
|
| 603 | + * @return void |
|
| 604 | + * @throws ReflectionException |
|
| 605 | + * @throws EE_Error |
|
| 606 | + */ |
|
| 607 | + private function _do_other_page_hooks() |
|
| 608 | + { |
|
| 609 | + $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array()); |
|
| 610 | + foreach ($registered_pages as $page) { |
|
| 611 | + // now let's setup the file name and class that should be present |
|
| 612 | + $classname = str_replace('.class.php', '', $page); |
|
| 613 | + // autoloaders should take care of loading file |
|
| 614 | + if (! class_exists($classname)) { |
|
| 615 | + $error_msg[] = sprintf( |
|
| 616 | + esc_html__( |
|
| 617 | + 'Something went wrong with loading the %s admin hooks page.', |
|
| 618 | + 'event_espresso' |
|
| 619 | + ), |
|
| 620 | + $page |
|
| 621 | + ); |
|
| 622 | + $error_msg[] = $error_msg[0] |
|
| 623 | + . "\r\n" |
|
| 624 | + . sprintf( |
|
| 625 | + esc_html__( |
|
| 626 | + 'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class', |
|
| 627 | + 'event_espresso' |
|
| 628 | + ), |
|
| 629 | + $page, |
|
| 630 | + '<br />', |
|
| 631 | + '<strong>' . $classname . '</strong>' |
|
| 632 | + ); |
|
| 633 | + throw new EE_Error(implode('||', $error_msg)); |
|
| 634 | + } |
|
| 635 | + $a = new ReflectionClass($classname); |
|
| 636 | + // notice we are passing the instance of this class to the hook object. |
|
| 637 | + $hookobj[] = $a->newInstance($this); |
|
| 638 | + } |
|
| 639 | + } |
|
| 640 | + |
|
| 641 | + |
|
| 642 | + public function load_page_dependencies() |
|
| 643 | + { |
|
| 644 | + try { |
|
| 645 | + $this->_load_page_dependencies(); |
|
| 646 | + } catch (EE_Error $e) { |
|
| 647 | + $e->get_error(); |
|
| 648 | + } |
|
| 649 | + } |
|
| 650 | + |
|
| 651 | + |
|
| 652 | + /** |
|
| 653 | + * load_page_dependencies |
|
| 654 | + * loads things specific to this page class when its loaded. Really helps with efficiency. |
|
| 655 | + * |
|
| 656 | + * @return void |
|
| 657 | + * @throws DomainException |
|
| 658 | + * @throws EE_Error |
|
| 659 | + * @throws InvalidArgumentException |
|
| 660 | + * @throws InvalidDataTypeException |
|
| 661 | + * @throws InvalidInterfaceException |
|
| 662 | + * @throws ReflectionException |
|
| 663 | + */ |
|
| 664 | + protected function _load_page_dependencies() |
|
| 665 | + { |
|
| 666 | + // let's set the current_screen and screen options to override what WP set |
|
| 667 | + $this->_current_screen = get_current_screen(); |
|
| 668 | + // load admin_notices - global, page class, and view specific |
|
| 669 | + add_action('admin_notices', array($this, 'admin_notices_global'), 5); |
|
| 670 | + add_action('admin_notices', array($this, 'admin_notices'), 10); |
|
| 671 | + if (method_exists($this, 'admin_notices_' . $this->_current_view)) { |
|
| 672 | + add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15); |
|
| 673 | + } |
|
| 674 | + // load network admin_notices - global, page class, and view specific |
|
| 675 | + add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5); |
|
| 676 | + if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) { |
|
| 677 | + add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view)); |
|
| 678 | + } |
|
| 679 | + // this will save any per_page screen options if they are present |
|
| 680 | + $this->_set_per_page_screen_options(); |
|
| 681 | + // setup list table properties |
|
| 682 | + $this->_set_list_table(); |
|
| 683 | + // child classes can "register" a metabox to be automatically handled via the _page_config array property. |
|
| 684 | + // However in some cases the metaboxes will need to be added within a route handling callback. |
|
| 685 | + $this->_add_registered_meta_boxes(); |
|
| 686 | + $this->_add_screen_columns(); |
|
| 687 | + // add screen options - global, page child class, and view specific |
|
| 688 | + $this->_add_global_screen_options(); |
|
| 689 | + $this->_add_screen_options(); |
|
| 690 | + $add_screen_options = "_add_screen_options_{$this->_current_view}"; |
|
| 691 | + if (method_exists($this, $add_screen_options)) { |
|
| 692 | + $this->{$add_screen_options}(); |
|
| 693 | + } |
|
| 694 | + // add help tab(s) and tours- set via page_config and qtips. |
|
| 695 | + $this->_add_help_tour(); |
|
| 696 | + $this->_add_help_tabs(); |
|
| 697 | + $this->_add_qtips(); |
|
| 698 | + // add feature_pointers - global, page child class, and view specific |
|
| 699 | + $this->_add_feature_pointers(); |
|
| 700 | + $this->_add_global_feature_pointers(); |
|
| 701 | + $add_feature_pointer = "_add_feature_pointer_{$this->_current_view}"; |
|
| 702 | + if (method_exists($this, $add_feature_pointer)) { |
|
| 703 | + $this->{$add_feature_pointer}(); |
|
| 704 | + } |
|
| 705 | + // enqueue scripts/styles - global, page class, and view specific |
|
| 706 | + add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5); |
|
| 707 | + add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10); |
|
| 708 | + if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) { |
|
| 709 | + add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15); |
|
| 710 | + } |
|
| 711 | + add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100); |
|
| 712 | + // admin_print_footer_scripts - global, page child class, and view specific. |
|
| 713 | + // NOTE, despite the name, whenever possible, scripts should NOT be loaded using this. |
|
| 714 | + // In most cases that's doing_it_wrong(). But adding hidden container elements etc. |
|
| 715 | + // is a good use case. Notice the late priority we're giving these |
|
| 716 | + add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99); |
|
| 717 | + add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100); |
|
| 718 | + if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) { |
|
| 719 | + add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101); |
|
| 720 | + } |
|
| 721 | + // admin footer scripts |
|
| 722 | + add_action('admin_footer', array($this, 'admin_footer_global'), 99); |
|
| 723 | + add_action('admin_footer', array($this, 'admin_footer'), 100); |
|
| 724 | + if (method_exists($this, "admin_footer_{$this->_current_view}")) { |
|
| 725 | + add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101); |
|
| 726 | + } |
|
| 727 | + do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug); |
|
| 728 | + // targeted hook |
|
| 729 | + do_action( |
|
| 730 | + "FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}" |
|
| 731 | + ); |
|
| 732 | + } |
|
| 733 | + |
|
| 734 | + |
|
| 735 | + /** |
|
| 736 | + * _set_defaults |
|
| 737 | + * This sets some global defaults for class properties. |
|
| 738 | + */ |
|
| 739 | + private function _set_defaults() |
|
| 740 | + { |
|
| 741 | + $this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null; |
|
| 742 | + $this->_event = $this->_template_path = $this->_column_template_path = null; |
|
| 743 | + $this->_nav_tabs = $this->_views = $this->_page_routes = array(); |
|
| 744 | + $this->_page_config = $this->_default_route_query_args = array(); |
|
| 745 | + $this->_default_nav_tab_name = 'overview'; |
|
| 746 | + // init template args |
|
| 747 | + $this->_template_args = array( |
|
| 748 | + 'admin_page_header' => '', |
|
| 749 | + 'admin_page_content' => '', |
|
| 750 | + 'post_body_content' => '', |
|
| 751 | + 'before_list_table' => '', |
|
| 752 | + 'after_list_table' => '', |
|
| 753 | + ); |
|
| 754 | + } |
|
| 755 | + |
|
| 756 | + |
|
| 757 | + /** |
|
| 758 | + * route_admin_request |
|
| 759 | + * |
|
| 760 | + * @see _route_admin_request() |
|
| 761 | + * @return exception|void error |
|
| 762 | + * @throws InvalidArgumentException |
|
| 763 | + * @throws InvalidInterfaceException |
|
| 764 | + * @throws InvalidDataTypeException |
|
| 765 | + * @throws EE_Error |
|
| 766 | + * @throws ReflectionException |
|
| 767 | + */ |
|
| 768 | + public function route_admin_request() |
|
| 769 | + { |
|
| 770 | + try { |
|
| 771 | + $this->_route_admin_request(); |
|
| 772 | + } catch (EE_Error $e) { |
|
| 773 | + $e->get_error(); |
|
| 774 | + } |
|
| 775 | + } |
|
| 776 | + |
|
| 777 | + |
|
| 778 | + public function set_wp_page_slug($wp_page_slug) |
|
| 779 | + { |
|
| 780 | + $this->_wp_page_slug = $wp_page_slug; |
|
| 781 | + // if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls... |
|
| 782 | + if (is_network_admin()) { |
|
| 783 | + $this->_wp_page_slug .= '-network'; |
|
| 784 | + } |
|
| 785 | + } |
|
| 786 | + |
|
| 787 | + |
|
| 788 | + /** |
|
| 789 | + * _verify_routes |
|
| 790 | + * All this method does is verify the incoming request and make sure that routes exist for it. We do this early so |
|
| 791 | + * we know if we need to drop out. |
|
| 792 | + * |
|
| 793 | + * @return bool |
|
| 794 | + * @throws EE_Error |
|
| 795 | + */ |
|
| 796 | + protected function _verify_routes() |
|
| 797 | + { |
|
| 798 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 799 | + if (! $this->_current_page && ! defined('DOING_AJAX')) { |
|
| 800 | + return false; |
|
| 801 | + } |
|
| 802 | + $this->_route = false; |
|
| 803 | + // check that the page_routes array is not empty |
|
| 804 | + if (empty($this->_page_routes)) { |
|
| 805 | + // user error msg |
|
| 806 | + $error_msg = sprintf( |
|
| 807 | + esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'), |
|
| 808 | + $this->_admin_page_title |
|
| 809 | + ); |
|
| 810 | + // developer error msg |
|
| 811 | + $error_msg .= '||' . $error_msg |
|
| 812 | + . esc_html__( |
|
| 813 | + ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.', |
|
| 814 | + 'event_espresso' |
|
| 815 | + ); |
|
| 816 | + throw new EE_Error($error_msg); |
|
| 817 | + } |
|
| 818 | + // and that the requested page route exists |
|
| 819 | + if (array_key_exists($this->_req_action, $this->_page_routes)) { |
|
| 820 | + $this->_route = $this->_page_routes[ $this->_req_action ]; |
|
| 821 | + $this->_route_config = isset($this->_page_config[ $this->_req_action ]) |
|
| 822 | + ? $this->_page_config[ $this->_req_action ] : array(); |
|
| 823 | + } else { |
|
| 824 | + // user error msg |
|
| 825 | + $error_msg = sprintf( |
|
| 826 | + esc_html__( |
|
| 827 | + 'The requested page route does not exist for the %s admin page.', |
|
| 828 | + 'event_espresso' |
|
| 829 | + ), |
|
| 830 | + $this->_admin_page_title |
|
| 831 | + ); |
|
| 832 | + // developer error msg |
|
| 833 | + $error_msg .= '||' . $error_msg |
|
| 834 | + . sprintf( |
|
| 835 | + esc_html__( |
|
| 836 | + ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.', |
|
| 837 | + 'event_espresso' |
|
| 838 | + ), |
|
| 839 | + $this->_req_action |
|
| 840 | + ); |
|
| 841 | + throw new EE_Error($error_msg); |
|
| 842 | + } |
|
| 843 | + // and that a default route exists |
|
| 844 | + if (! array_key_exists('default', $this->_page_routes)) { |
|
| 845 | + // user error msg |
|
| 846 | + $error_msg = sprintf( |
|
| 847 | + esc_html__( |
|
| 848 | + 'A default page route has not been set for the % admin page.', |
|
| 849 | + 'event_espresso' |
|
| 850 | + ), |
|
| 851 | + $this->_admin_page_title |
|
| 852 | + ); |
|
| 853 | + // developer error msg |
|
| 854 | + $error_msg .= '||' . $error_msg |
|
| 855 | + . esc_html__( |
|
| 856 | + ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.', |
|
| 857 | + 'event_espresso' |
|
| 858 | + ); |
|
| 859 | + throw new EE_Error($error_msg); |
|
| 860 | + } |
|
| 861 | + // first lets' catch if the UI request has EVER been set. |
|
| 862 | + if ($this->_is_UI_request === null) { |
|
| 863 | + // lets set if this is a UI request or not. |
|
| 864 | + $this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true; |
|
| 865 | + // wait a minute... we might have a noheader in the route array |
|
| 866 | + $this->_is_UI_request = is_array($this->_route) |
|
| 867 | + && isset($this->_route['noheader']) |
|
| 868 | + && $this->_route['noheader'] ? false : $this->_is_UI_request; |
|
| 869 | + } |
|
| 870 | + $this->_set_current_labels(); |
|
| 871 | + return true; |
|
| 872 | + } |
|
| 873 | + |
|
| 874 | + |
|
| 875 | + /** |
|
| 876 | + * this method simply verifies a given route and makes sure its an actual route available for the loaded page |
|
| 877 | + * |
|
| 878 | + * @param string $route the route name we're verifying |
|
| 879 | + * @return mixed (bool|Exception) we'll throw an exception if this isn't a valid route. |
|
| 880 | + * @throws EE_Error |
|
| 881 | + */ |
|
| 882 | + protected function _verify_route($route) |
|
| 883 | + { |
|
| 884 | + if (array_key_exists($this->_req_action, $this->_page_routes)) { |
|
| 885 | + return true; |
|
| 886 | + } |
|
| 887 | + // user error msg |
|
| 888 | + $error_msg = sprintf( |
|
| 889 | + esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'), |
|
| 890 | + $this->_admin_page_title |
|
| 891 | + ); |
|
| 892 | + // developer error msg |
|
| 893 | + $error_msg .= '||' . $error_msg |
|
| 894 | + . sprintf( |
|
| 895 | + esc_html__( |
|
| 896 | + ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property', |
|
| 897 | + 'event_espresso' |
|
| 898 | + ), |
|
| 899 | + $route |
|
| 900 | + ); |
|
| 901 | + throw new EE_Error($error_msg); |
|
| 902 | + } |
|
| 903 | + |
|
| 904 | + |
|
| 905 | + /** |
|
| 906 | + * perform nonce verification |
|
| 907 | + * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces |
|
| 908 | + * using this method (and save retyping!) |
|
| 909 | + * |
|
| 910 | + * @param string $nonce The nonce sent |
|
| 911 | + * @param string $nonce_ref The nonce reference string (name0) |
|
| 912 | + * @return void |
|
| 913 | + * @throws EE_Error |
|
| 914 | + */ |
|
| 915 | + protected function _verify_nonce($nonce, $nonce_ref) |
|
| 916 | + { |
|
| 917 | + // verify nonce against expected value |
|
| 918 | + if (! wp_verify_nonce($nonce, $nonce_ref)) { |
|
| 919 | + // these are not the droids you are looking for !!! |
|
| 920 | + $msg = sprintf( |
|
| 921 | + esc_html__('%sNonce Fail.%s', 'event_espresso'), |
|
| 922 | + '<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">', |
|
| 923 | + '</a>' |
|
| 924 | + ); |
|
| 925 | + if (WP_DEBUG) { |
|
| 926 | + $msg .= "\n " |
|
| 927 | + . sprintf( |
|
| 928 | + esc_html__( |
|
| 929 | + 'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!', |
|
| 930 | + 'event_espresso' |
|
| 931 | + ), |
|
| 932 | + __CLASS__ |
|
| 933 | + ); |
|
| 934 | + } |
|
| 935 | + if (! defined('DOING_AJAX')) { |
|
| 936 | + wp_die($msg); |
|
| 937 | + } else { |
|
| 938 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 939 | + $this->_return_json(); |
|
| 940 | + } |
|
| 941 | + } |
|
| 942 | + } |
|
| 943 | + |
|
| 944 | + |
|
| 945 | + /** |
|
| 946 | + * _route_admin_request() |
|
| 947 | + * Meat and potatoes of the class. Basically, this dude checks out what's being requested and sees if theres are |
|
| 948 | + * some doodads to work the magic and handle the flingjangy. Translation: Checks if the requested action is listed |
|
| 949 | + * in the page routes and then will try to load the corresponding method. |
|
| 950 | + * |
|
| 951 | + * @return void |
|
| 952 | + * @throws EE_Error |
|
| 953 | + * @throws InvalidArgumentException |
|
| 954 | + * @throws InvalidDataTypeException |
|
| 955 | + * @throws InvalidInterfaceException |
|
| 956 | + * @throws ReflectionException |
|
| 957 | + */ |
|
| 958 | + protected function _route_admin_request() |
|
| 959 | + { |
|
| 960 | + if (! $this->_is_UI_request) { |
|
| 961 | + $this->_verify_routes(); |
|
| 962 | + } |
|
| 963 | + $nonce_check = isset($this->_route_config['require_nonce']) |
|
| 964 | + ? $this->_route_config['require_nonce'] |
|
| 965 | + : true; |
|
| 966 | + if ($this->_req_action !== 'default' && $nonce_check) { |
|
| 967 | + // set nonce from post data |
|
| 968 | + $nonce = isset($this->_req_data[ $this->_req_nonce ]) |
|
| 969 | + ? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) |
|
| 970 | + : ''; |
|
| 971 | + $this->_verify_nonce($nonce, $this->_req_nonce); |
|
| 972 | + } |
|
| 973 | + // set the nav_tabs array but ONLY if this is UI_request |
|
| 974 | + if ($this->_is_UI_request) { |
|
| 975 | + $this->_set_nav_tabs(); |
|
| 976 | + } |
|
| 977 | + // grab callback function |
|
| 978 | + $func = is_array($this->_route) ? $this->_route['func'] : $this->_route; |
|
| 979 | + // check if callback has args |
|
| 980 | + $args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array(); |
|
| 981 | + $error_msg = ''; |
|
| 982 | + // action right before calling route |
|
| 983 | + // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request') |
|
| 984 | + if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) { |
|
| 985 | + do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this); |
|
| 986 | + } |
|
| 987 | + // right before calling the route, let's remove _wp_http_referer from the |
|
| 988 | + // $_SERVER[REQUEST_URI] global (its now in _req_data for route processing). |
|
| 989 | + $_SERVER['REQUEST_URI'] = remove_query_arg( |
|
| 990 | + '_wp_http_referer', |
|
| 991 | + wp_unslash($_SERVER['REQUEST_URI']) |
|
| 992 | + ); |
|
| 993 | + if (! empty($func)) { |
|
| 994 | + if (is_array($func)) { |
|
| 995 | + list($class, $method) = $func; |
|
| 996 | + } elseif (strpos($func, '::') !== false) { |
|
| 997 | + list($class, $method) = explode('::', $func); |
|
| 998 | + } else { |
|
| 999 | + $class = $this; |
|
| 1000 | + $method = $func; |
|
| 1001 | + } |
|
| 1002 | + if (! (is_object($class) && $class === $this)) { |
|
| 1003 | + // send along this admin page object for access by addons. |
|
| 1004 | + $args['admin_page_object'] = $this; |
|
| 1005 | + } |
|
| 1006 | + if (// is it a method on a class that doesn't work? |
|
| 1007 | + ( |
|
| 1008 | + ( |
|
| 1009 | + method_exists($class, $method) |
|
| 1010 | + && call_user_func_array(array($class, $method), $args) === false |
|
| 1011 | + ) |
|
| 1012 | + && ( |
|
| 1013 | + // is it a standalone function that doesn't work? |
|
| 1014 | + function_exists($method) |
|
| 1015 | + && call_user_func_array( |
|
| 1016 | + $func, |
|
| 1017 | + array_merge(array('admin_page_object' => $this), $args) |
|
| 1018 | + ) === false |
|
| 1019 | + ) |
|
| 1020 | + ) |
|
| 1021 | + || ( |
|
| 1022 | + // is it neither a class method NOR a standalone function? |
|
| 1023 | + ! method_exists($class, $method) |
|
| 1024 | + && ! function_exists($method) |
|
| 1025 | + ) |
|
| 1026 | + ) { |
|
| 1027 | + // user error msg |
|
| 1028 | + $error_msg = esc_html__( |
|
| 1029 | + 'An error occurred. The requested page route could not be found.', |
|
| 1030 | + 'event_espresso' |
|
| 1031 | + ); |
|
| 1032 | + // developer error msg |
|
| 1033 | + $error_msg .= '||'; |
|
| 1034 | + $error_msg .= sprintf( |
|
| 1035 | + esc_html__( |
|
| 1036 | + 'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.', |
|
| 1037 | + 'event_espresso' |
|
| 1038 | + ), |
|
| 1039 | + $method |
|
| 1040 | + ); |
|
| 1041 | + } |
|
| 1042 | + if (! empty($error_msg)) { |
|
| 1043 | + throw new EE_Error($error_msg); |
|
| 1044 | + } |
|
| 1045 | + } |
|
| 1046 | + // if we've routed and this route has a no headers route AND a sent_headers_route, |
|
| 1047 | + // then we need to reset the routing properties to the new route. |
|
| 1048 | + // now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent. |
|
| 1049 | + if ($this->_is_UI_request === false |
|
| 1050 | + && is_array($this->_route) |
|
| 1051 | + && ! empty($this->_route['headers_sent_route']) |
|
| 1052 | + ) { |
|
| 1053 | + $this->_reset_routing_properties($this->_route['headers_sent_route']); |
|
| 1054 | + } |
|
| 1055 | + } |
|
| 1056 | + |
|
| 1057 | + |
|
| 1058 | + /** |
|
| 1059 | + * This method just allows the resetting of page properties in the case where a no headers |
|
| 1060 | + * route redirects to a headers route in its route config. |
|
| 1061 | + * |
|
| 1062 | + * @since 4.3.0 |
|
| 1063 | + * @param string $new_route New (non header) route to redirect to. |
|
| 1064 | + * @return void |
|
| 1065 | + * @throws ReflectionException |
|
| 1066 | + * @throws InvalidArgumentException |
|
| 1067 | + * @throws InvalidInterfaceException |
|
| 1068 | + * @throws InvalidDataTypeException |
|
| 1069 | + * @throws EE_Error |
|
| 1070 | + */ |
|
| 1071 | + protected function _reset_routing_properties($new_route) |
|
| 1072 | + { |
|
| 1073 | + $this->_is_UI_request = true; |
|
| 1074 | + // now we set the current route to whatever the headers_sent_route is set at |
|
| 1075 | + $this->_req_data['action'] = $new_route; |
|
| 1076 | + // rerun page setup |
|
| 1077 | + $this->_page_setup(); |
|
| 1078 | + } |
|
| 1079 | + |
|
| 1080 | + |
|
| 1081 | + /** |
|
| 1082 | + * _add_query_arg |
|
| 1083 | + * adds nonce to array of arguments then calls WP add_query_arg function |
|
| 1084 | + *(internally just uses EEH_URL's function with the same name) |
|
| 1085 | + * |
|
| 1086 | + * @param array $args |
|
| 1087 | + * @param string $url |
|
| 1088 | + * @param bool $sticky if true, then the existing Request params will be appended to the |
|
| 1089 | + * generated url in an associative array indexed by the key 'wp_referer'; |
|
| 1090 | + * Example usage: If the current page is: |
|
| 1091 | + * http://mydomain.com/wp-admin/admin.php?page=espresso_registrations |
|
| 1092 | + * &action=default&event_id=20&month_range=March%202015 |
|
| 1093 | + * &_wpnonce=5467821 |
|
| 1094 | + * and you call: |
|
| 1095 | + * EE_Admin_Page::add_query_args_and_nonce( |
|
| 1096 | + * array( |
|
| 1097 | + * 'action' => 'resend_something', |
|
| 1098 | + * 'page=>espresso_registrations' |
|
| 1099 | + * ), |
|
| 1100 | + * $some_url, |
|
| 1101 | + * true |
|
| 1102 | + * ); |
|
| 1103 | + * It will produce a url in this structure: |
|
| 1104 | + * http://{$some_url}/?page=espresso_registrations&action=resend_something |
|
| 1105 | + * &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[ |
|
| 1106 | + * month_range]=March%202015 |
|
| 1107 | + * @param bool $exclude_nonce If true, the the nonce will be excluded from the generated nonce. |
|
| 1108 | + * @return string |
|
| 1109 | + */ |
|
| 1110 | + public static function add_query_args_and_nonce( |
|
| 1111 | + $args = array(), |
|
| 1112 | + $url = false, |
|
| 1113 | + $sticky = false, |
|
| 1114 | + $exclude_nonce = false |
|
| 1115 | + ) { |
|
| 1116 | + // if there is a _wp_http_referer include the values from the request but only if sticky = true |
|
| 1117 | + if ($sticky) { |
|
| 1118 | + $request = $_REQUEST; |
|
| 1119 | + unset($request['_wp_http_referer']); |
|
| 1120 | + unset($request['wp_referer']); |
|
| 1121 | + foreach ($request as $key => $value) { |
|
| 1122 | + // do not add nonces |
|
| 1123 | + if (strpos($key, 'nonce') !== false) { |
|
| 1124 | + continue; |
|
| 1125 | + } |
|
| 1126 | + $args[ 'wp_referer[' . $key . ']' ] = $value; |
|
| 1127 | + } |
|
| 1128 | + } |
|
| 1129 | + return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce); |
|
| 1130 | + } |
|
| 1131 | + |
|
| 1132 | + |
|
| 1133 | + /** |
|
| 1134 | + * This returns a generated link that will load the related help tab. |
|
| 1135 | + * |
|
| 1136 | + * @param string $help_tab_id the id for the connected help tab |
|
| 1137 | + * @param string $icon_style (optional) include css class for the style you want to use for the help icon. |
|
| 1138 | + * @param string $help_text (optional) send help text you want to use for the link if default not to be used |
|
| 1139 | + * @uses EEH_Template::get_help_tab_link() |
|
| 1140 | + * @return string generated link |
|
| 1141 | + */ |
|
| 1142 | + protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '') |
|
| 1143 | + { |
|
| 1144 | + return EEH_Template::get_help_tab_link( |
|
| 1145 | + $help_tab_id, |
|
| 1146 | + $this->page_slug, |
|
| 1147 | + $this->_req_action, |
|
| 1148 | + $icon_style, |
|
| 1149 | + $help_text |
|
| 1150 | + ); |
|
| 1151 | + } |
|
| 1152 | + |
|
| 1153 | + |
|
| 1154 | + /** |
|
| 1155 | + * _add_help_tabs |
|
| 1156 | + * Note child classes define their help tabs within the page_config array. |
|
| 1157 | + * |
|
| 1158 | + * @link http://codex.wordpress.org/Function_Reference/add_help_tab |
|
| 1159 | + * @return void |
|
| 1160 | + * @throws DomainException |
|
| 1161 | + * @throws EE_Error |
|
| 1162 | + */ |
|
| 1163 | + protected function _add_help_tabs() |
|
| 1164 | + { |
|
| 1165 | + $tour_buttons = ''; |
|
| 1166 | + if (isset($this->_page_config[ $this->_req_action ])) { |
|
| 1167 | + $config = $this->_page_config[ $this->_req_action ]; |
|
| 1168 | + // is there a help tour for the current route? if there is let's setup the tour buttons |
|
| 1169 | + if (isset($this->_help_tour[ $this->_req_action ])) { |
|
| 1170 | + $tb = array(); |
|
| 1171 | + $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">'; |
|
| 1172 | + foreach ($this->_help_tour['tours'] as $tour) { |
|
| 1173 | + // if this is the end tour then we don't need to setup a button |
|
| 1174 | + if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) { |
|
| 1175 | + continue; |
|
| 1176 | + } |
|
| 1177 | + $tb[] = '<button id="trigger-tour-' |
|
| 1178 | + . $tour->get_slug() |
|
| 1179 | + . '" class="button-primary trigger-ee-help-tour">' |
|
| 1180 | + . $tour->get_label() |
|
| 1181 | + . '</button>'; |
|
| 1182 | + } |
|
| 1183 | + $tour_buttons .= implode('<br />', $tb); |
|
| 1184 | + $tour_buttons .= '</div></div>'; |
|
| 1185 | + } |
|
| 1186 | + // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well. |
|
| 1187 | + if (is_array($config) && isset($config['help_sidebar'])) { |
|
| 1188 | + // check that the callback given is valid |
|
| 1189 | + if (! method_exists($this, $config['help_sidebar'])) { |
|
| 1190 | + throw new EE_Error( |
|
| 1191 | + sprintf( |
|
| 1192 | + esc_html__( |
|
| 1193 | + 'The _page_config array has a callback set for the "help_sidebar" option. However the callback given (%s) is not a valid callback. Doublecheck the spelling and make sure this method exists for the class %s', |
|
| 1194 | + 'event_espresso' |
|
| 1195 | + ), |
|
| 1196 | + $config['help_sidebar'], |
|
| 1197 | + get_class($this) |
|
| 1198 | + ) |
|
| 1199 | + ); |
|
| 1200 | + } |
|
| 1201 | + $content = apply_filters( |
|
| 1202 | + 'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar', |
|
| 1203 | + $this->{$config['help_sidebar']}() |
|
| 1204 | + ); |
|
| 1205 | + $content .= $tour_buttons; // add help tour buttons. |
|
| 1206 | + // do we have any help tours setup? Cause if we do we want to add the buttons |
|
| 1207 | + $this->_current_screen->set_help_sidebar($content); |
|
| 1208 | + } |
|
| 1209 | + // if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar. |
|
| 1210 | + if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) { |
|
| 1211 | + $this->_current_screen->set_help_sidebar($tour_buttons); |
|
| 1212 | + } |
|
| 1213 | + // handle if no help_tabs are set so the sidebar will still show for the help tour buttons |
|
| 1214 | + if (! isset($config['help_tabs']) && ! empty($tour_buttons)) { |
|
| 1215 | + $_ht['id'] = $this->page_slug; |
|
| 1216 | + $_ht['title'] = esc_html__('Help Tours', 'event_espresso'); |
|
| 1217 | + $_ht['content'] = '<p>' |
|
| 1218 | + . esc_html__( |
|
| 1219 | + 'The buttons to the right allow you to start/restart any help tours available for this page', |
|
| 1220 | + 'event_espresso' |
|
| 1221 | + ) . '</p>'; |
|
| 1222 | + $this->_current_screen->add_help_tab($_ht); |
|
| 1223 | + } |
|
| 1224 | + if (! isset($config['help_tabs'])) { |
|
| 1225 | + return; |
|
| 1226 | + } //no help tabs for this route |
|
| 1227 | + foreach ((array) $config['help_tabs'] as $tab_id => $cfg) { |
|
| 1228 | + // we're here so there ARE help tabs! |
|
| 1229 | + // make sure we've got what we need |
|
| 1230 | + if (! isset($cfg['title'])) { |
|
| 1231 | + throw new EE_Error( |
|
| 1232 | + esc_html__( |
|
| 1233 | + 'The _page_config array is not set up properly for help tabs. It is missing a title', |
|
| 1234 | + 'event_espresso' |
|
| 1235 | + ) |
|
| 1236 | + ); |
|
| 1237 | + } |
|
| 1238 | + if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) { |
|
| 1239 | + throw new EE_Error( |
|
| 1240 | + esc_html__( |
|
| 1241 | + 'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab', |
|
| 1242 | + 'event_espresso' |
|
| 1243 | + ) |
|
| 1244 | + ); |
|
| 1245 | + } |
|
| 1246 | + // first priority goes to content. |
|
| 1247 | + if (! empty($cfg['content'])) { |
|
| 1248 | + $content = ! empty($cfg['content']) ? $cfg['content'] : null; |
|
| 1249 | + // second priority goes to filename |
|
| 1250 | + } elseif (! empty($cfg['filename'])) { |
|
| 1251 | + $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php'; |
|
| 1252 | + // it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too) |
|
| 1253 | + $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES |
|
| 1254 | + . basename($this->_get_dir()) |
|
| 1255 | + . '/help_tabs/' |
|
| 1256 | + . $cfg['filename'] |
|
| 1257 | + . '.help_tab.php' : $file_path; |
|
| 1258 | + // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error. |
|
| 1259 | + if (! isset($cfg['callback']) && ! is_readable($file_path)) { |
|
| 1260 | + EE_Error::add_error( |
|
| 1261 | + sprintf( |
|
| 1262 | + esc_html__( |
|
| 1263 | + 'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content. Please check that the string you set for the help tab on this route (%s) is the correct spelling. The file should be in %s', |
|
| 1264 | + 'event_espresso' |
|
| 1265 | + ), |
|
| 1266 | + $tab_id, |
|
| 1267 | + key($config), |
|
| 1268 | + $file_path |
|
| 1269 | + ), |
|
| 1270 | + __FILE__, |
|
| 1271 | + __FUNCTION__, |
|
| 1272 | + __LINE__ |
|
| 1273 | + ); |
|
| 1274 | + return; |
|
| 1275 | + } |
|
| 1276 | + $template_args['admin_page_obj'] = $this; |
|
| 1277 | + $content = EEH_Template::display_template( |
|
| 1278 | + $file_path, |
|
| 1279 | + $template_args, |
|
| 1280 | + true |
|
| 1281 | + ); |
|
| 1282 | + } else { |
|
| 1283 | + $content = ''; |
|
| 1284 | + } |
|
| 1285 | + // check if callback is valid |
|
| 1286 | + if (empty($content) && ( |
|
| 1287 | + ! isset($cfg['callback']) || ! method_exists($this, $cfg['callback']) |
|
| 1288 | + ) |
|
| 1289 | + ) { |
|
| 1290 | + EE_Error::add_error( |
|
| 1291 | + sprintf( |
|
| 1292 | + esc_html__( |
|
| 1293 | + 'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content. Check the spelling or make sure the method is present.', |
|
| 1294 | + 'event_espresso' |
|
| 1295 | + ), |
|
| 1296 | + $cfg['title'] |
|
| 1297 | + ), |
|
| 1298 | + __FILE__, |
|
| 1299 | + __FUNCTION__, |
|
| 1300 | + __LINE__ |
|
| 1301 | + ); |
|
| 1302 | + return; |
|
| 1303 | + } |
|
| 1304 | + // setup config array for help tab method |
|
| 1305 | + $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id; |
|
| 1306 | + $_ht = array( |
|
| 1307 | + 'id' => $id, |
|
| 1308 | + 'title' => $cfg['title'], |
|
| 1309 | + 'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null, |
|
| 1310 | + 'content' => $content, |
|
| 1311 | + ); |
|
| 1312 | + $this->_current_screen->add_help_tab($_ht); |
|
| 1313 | + } |
|
| 1314 | + } |
|
| 1315 | + } |
|
| 1316 | + |
|
| 1317 | + |
|
| 1318 | + /** |
|
| 1319 | + * This basically checks loaded $_page_config property to see if there are any help_tours defined. "help_tours" is |
|
| 1320 | + * an array with properties for setting up usage of the joyride plugin |
|
| 1321 | + * |
|
| 1322 | + * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin |
|
| 1323 | + * @see instructions regarding the format and construction of the "help_tour" array element is found in the |
|
| 1324 | + * _set_page_config() comments |
|
| 1325 | + * @return void |
|
| 1326 | + * @throws EE_Error |
|
| 1327 | + * @throws InvalidArgumentException |
|
| 1328 | + * @throws InvalidDataTypeException |
|
| 1329 | + * @throws InvalidInterfaceException |
|
| 1330 | + */ |
|
| 1331 | + protected function _add_help_tour() |
|
| 1332 | + { |
|
| 1333 | + $tours = array(); |
|
| 1334 | + $this->_help_tour = array(); |
|
| 1335 | + // exit early if help tours are turned off globally |
|
| 1336 | + if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS) |
|
| 1337 | + || ! EE_Registry::instance()->CFG->admin->help_tour_activation |
|
| 1338 | + ) { |
|
| 1339 | + return; |
|
| 1340 | + } |
|
| 1341 | + // loop through _page_config to find any help_tour defined |
|
| 1342 | + foreach ($this->_page_config as $route => $config) { |
|
| 1343 | + // we're only going to set things up for this route |
|
| 1344 | + if ($route !== $this->_req_action) { |
|
| 1345 | + continue; |
|
| 1346 | + } |
|
| 1347 | + if (isset($config['help_tour'])) { |
|
| 1348 | + foreach ($config['help_tour'] as $tour) { |
|
| 1349 | + $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php'; |
|
| 1350 | + // let's see if we can get that file... |
|
| 1351 | + // if not its possible this is a decaf route not set in caffeinated |
|
| 1352 | + // so lets try and get the caffeinated equivalent |
|
| 1353 | + $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES |
|
| 1354 | + . basename($this->_get_dir()) |
|
| 1355 | + . '/help_tours/' |
|
| 1356 | + . $tour |
|
| 1357 | + . '.class.php' : $file_path; |
|
| 1358 | + // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error. |
|
| 1359 | + if (! is_readable($file_path)) { |
|
| 1360 | + EE_Error::add_error( |
|
| 1361 | + sprintf( |
|
| 1362 | + esc_html__( |
|
| 1363 | + 'The file path given for the help tour (%s) is not a valid path. Please check that the string you set for the help tour on this route (%s) is the correct spelling', |
|
| 1364 | + 'event_espresso' |
|
| 1365 | + ), |
|
| 1366 | + $file_path, |
|
| 1367 | + $tour |
|
| 1368 | + ), |
|
| 1369 | + __FILE__, |
|
| 1370 | + __FUNCTION__, |
|
| 1371 | + __LINE__ |
|
| 1372 | + ); |
|
| 1373 | + return; |
|
| 1374 | + } |
|
| 1375 | + require_once $file_path; |
|
| 1376 | + if (! class_exists($tour)) { |
|
| 1377 | + $error_msg[] = sprintf( |
|
| 1378 | + esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'), |
|
| 1379 | + $tour |
|
| 1380 | + ); |
|
| 1381 | + $error_msg[] = $error_msg[0] . "\r\n" |
|
| 1382 | + . sprintf( |
|
| 1383 | + esc_html__( |
|
| 1384 | + 'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.', |
|
| 1385 | + 'event_espresso' |
|
| 1386 | + ), |
|
| 1387 | + $tour, |
|
| 1388 | + '<br />', |
|
| 1389 | + $tour, |
|
| 1390 | + $this->_req_action, |
|
| 1391 | + get_class($this) |
|
| 1392 | + ); |
|
| 1393 | + throw new EE_Error(implode('||', $error_msg)); |
|
| 1394 | + } |
|
| 1395 | + $tour_obj = new $tour($this->_is_caf); |
|
| 1396 | + $tours[] = $tour_obj; |
|
| 1397 | + $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj); |
|
| 1398 | + } |
|
| 1399 | + // let's inject the end tour stop element common to all pages... this will only get seen once per machine. |
|
| 1400 | + $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf); |
|
| 1401 | + $tours[] = $end_stop_tour; |
|
| 1402 | + $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour); |
|
| 1403 | + } |
|
| 1404 | + } |
|
| 1405 | + if (! empty($tours)) { |
|
| 1406 | + $this->_help_tour['tours'] = $tours; |
|
| 1407 | + } |
|
| 1408 | + // that's it! Now that the $_help_tours property is set (or not) |
|
| 1409 | + // the scripts and html should be taken care of automatically. |
|
| 1410 | + } |
|
| 1411 | + |
|
| 1412 | + |
|
| 1413 | + /** |
|
| 1414 | + * This simply sets up any qtips that have been defined in the page config |
|
| 1415 | + * |
|
| 1416 | + * @return void |
|
| 1417 | + */ |
|
| 1418 | + protected function _add_qtips() |
|
| 1419 | + { |
|
| 1420 | + if (isset($this->_route_config['qtips'])) { |
|
| 1421 | + $qtips = (array) $this->_route_config['qtips']; |
|
| 1422 | + // load qtip loader |
|
| 1423 | + $path = array( |
|
| 1424 | + $this->_get_dir() . '/qtips/', |
|
| 1425 | + EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/', |
|
| 1426 | + ); |
|
| 1427 | + EEH_Qtip_Loader::instance()->register($qtips, $path); |
|
| 1428 | + } |
|
| 1429 | + } |
|
| 1430 | + |
|
| 1431 | + |
|
| 1432 | + /** |
|
| 1433 | + * _set_nav_tabs |
|
| 1434 | + * This sets up the nav tabs from the page_routes array. This method can be overwritten by child classes if you |
|
| 1435 | + * wish to add additional tabs or modify accordingly. |
|
| 1436 | + * |
|
| 1437 | + * @return void |
|
| 1438 | + * @throws InvalidArgumentException |
|
| 1439 | + * @throws InvalidInterfaceException |
|
| 1440 | + * @throws InvalidDataTypeException |
|
| 1441 | + */ |
|
| 1442 | + protected function _set_nav_tabs() |
|
| 1443 | + { |
|
| 1444 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1445 | + $i = 0; |
|
| 1446 | + foreach ($this->_page_config as $slug => $config) { |
|
| 1447 | + if (! is_array($config) |
|
| 1448 | + || ( |
|
| 1449 | + is_array($config) |
|
| 1450 | + && ( |
|
| 1451 | + (isset($config['nav']) && ! $config['nav']) |
|
| 1452 | + || ! isset($config['nav']) |
|
| 1453 | + ) |
|
| 1454 | + ) |
|
| 1455 | + ) { |
|
| 1456 | + continue; |
|
| 1457 | + } |
|
| 1458 | + // no nav tab for this config |
|
| 1459 | + // check for persistent flag |
|
| 1460 | + if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) { |
|
| 1461 | + // nav tab is only to appear when route requested. |
|
| 1462 | + continue; |
|
| 1463 | + } |
|
| 1464 | + if (! $this->check_user_access($slug, true)) { |
|
| 1465 | + // no nav tab because current user does not have access. |
|
| 1466 | + continue; |
|
| 1467 | + } |
|
| 1468 | + $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : ''; |
|
| 1469 | + $this->_nav_tabs[ $slug ] = array( |
|
| 1470 | + 'url' => isset($config['nav']['url']) |
|
| 1471 | + ? $config['nav']['url'] |
|
| 1472 | + : self::add_query_args_and_nonce( |
|
| 1473 | + array('action' => $slug), |
|
| 1474 | + $this->_admin_base_url |
|
| 1475 | + ), |
|
| 1476 | + 'link_text' => isset($config['nav']['label']) |
|
| 1477 | + ? $config['nav']['label'] |
|
| 1478 | + : ucwords( |
|
| 1479 | + str_replace('_', ' ', $slug) |
|
| 1480 | + ), |
|
| 1481 | + 'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class, |
|
| 1482 | + 'order' => isset($config['nav']['order']) ? $config['nav']['order'] : $i, |
|
| 1483 | + ); |
|
| 1484 | + $i++; |
|
| 1485 | + } |
|
| 1486 | + // if $this->_nav_tabs is empty then lets set the default |
|
| 1487 | + if (empty($this->_nav_tabs)) { |
|
| 1488 | + $this->_nav_tabs[ $this->_default_nav_tab_name ] = array( |
|
| 1489 | + 'url' => $this->_admin_base_url, |
|
| 1490 | + 'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)), |
|
| 1491 | + 'css_class' => 'nav-tab-active', |
|
| 1492 | + 'order' => 10, |
|
| 1493 | + ); |
|
| 1494 | + } |
|
| 1495 | + // now let's sort the tabs according to order |
|
| 1496 | + usort($this->_nav_tabs, array($this, '_sort_nav_tabs')); |
|
| 1497 | + } |
|
| 1498 | + |
|
| 1499 | + |
|
| 1500 | + /** |
|
| 1501 | + * _set_current_labels |
|
| 1502 | + * This method modifies the _labels property with any optional specific labels indicated in the _page_routes |
|
| 1503 | + * property array |
|
| 1504 | + * |
|
| 1505 | + * @return void |
|
| 1506 | + */ |
|
| 1507 | + private function _set_current_labels() |
|
| 1508 | + { |
|
| 1509 | + if (is_array($this->_route_config) && isset($this->_route_config['labels'])) { |
|
| 1510 | + foreach ($this->_route_config['labels'] as $label => $text) { |
|
| 1511 | + if (is_array($text)) { |
|
| 1512 | + foreach ($text as $sublabel => $subtext) { |
|
| 1513 | + $this->_labels[ $label ][ $sublabel ] = $subtext; |
|
| 1514 | + } |
|
| 1515 | + } else { |
|
| 1516 | + $this->_labels[ $label ] = $text; |
|
| 1517 | + } |
|
| 1518 | + } |
|
| 1519 | + } |
|
| 1520 | + } |
|
| 1521 | + |
|
| 1522 | + |
|
| 1523 | + /** |
|
| 1524 | + * verifies user access for this admin page |
|
| 1525 | + * |
|
| 1526 | + * @param string $route_to_check if present then the capability for the route matching this string is checked. |
|
| 1527 | + * @param bool $verify_only Default is FALSE which means if user check fails then wp_die(). Otherwise just |
|
| 1528 | + * return false if verify fail. |
|
| 1529 | + * @return bool |
|
| 1530 | + * @throws InvalidArgumentException |
|
| 1531 | + * @throws InvalidDataTypeException |
|
| 1532 | + * @throws InvalidInterfaceException |
|
| 1533 | + */ |
|
| 1534 | + public function check_user_access($route_to_check = '', $verify_only = false) |
|
| 1535 | + { |
|
| 1536 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1537 | + $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check; |
|
| 1538 | + $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ]) |
|
| 1539 | + && is_array( |
|
| 1540 | + $this->_page_routes[ $route_to_check ] |
|
| 1541 | + ) |
|
| 1542 | + && ! empty($this->_page_routes[ $route_to_check ]['capability']) |
|
| 1543 | + ? $this->_page_routes[ $route_to_check ]['capability'] : null; |
|
| 1544 | + if (empty($capability) && empty($route_to_check)) { |
|
| 1545 | + $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options' |
|
| 1546 | + : $this->_route['capability']; |
|
| 1547 | + } else { |
|
| 1548 | + $capability = empty($capability) ? 'manage_options' : $capability; |
|
| 1549 | + } |
|
| 1550 | + $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0; |
|
| 1551 | + if (! defined('DOING_AJAX') |
|
| 1552 | + && ( |
|
| 1553 | + ! function_exists('is_admin') |
|
| 1554 | + || ! EE_Registry::instance()->CAP->current_user_can( |
|
| 1555 | + $capability, |
|
| 1556 | + $this->page_slug |
|
| 1557 | + . '_' |
|
| 1558 | + . $route_to_check, |
|
| 1559 | + $id |
|
| 1560 | + ) |
|
| 1561 | + ) |
|
| 1562 | + ) { |
|
| 1563 | + if ($verify_only) { |
|
| 1564 | + return false; |
|
| 1565 | + } |
|
| 1566 | + if (is_user_logged_in()) { |
|
| 1567 | + wp_die(__('You do not have access to this route.', 'event_espresso')); |
|
| 1568 | + } else { |
|
| 1569 | + return false; |
|
| 1570 | + } |
|
| 1571 | + } |
|
| 1572 | + return true; |
|
| 1573 | + } |
|
| 1574 | + |
|
| 1575 | + |
|
| 1576 | + /** |
|
| 1577 | + * admin_init_global |
|
| 1578 | + * This runs all the code that we want executed within the WP admin_init hook. |
|
| 1579 | + * This method executes for ALL EE Admin pages. |
|
| 1580 | + * |
|
| 1581 | + * @return void |
|
| 1582 | + */ |
|
| 1583 | + public function admin_init_global() |
|
| 1584 | + { |
|
| 1585 | + } |
|
| 1586 | + |
|
| 1587 | + |
|
| 1588 | + /** |
|
| 1589 | + * wp_loaded_global |
|
| 1590 | + * This runs all the code that we want executed within the WP wp_loaded hook. This method is optional for an |
|
| 1591 | + * EE_Admin page and will execute on every EE Admin Page load |
|
| 1592 | + * |
|
| 1593 | + * @return void |
|
| 1594 | + */ |
|
| 1595 | + public function wp_loaded() |
|
| 1596 | + { |
|
| 1597 | + } |
|
| 1598 | + |
|
| 1599 | + |
|
| 1600 | + /** |
|
| 1601 | + * admin_notices |
|
| 1602 | + * Anything triggered by the 'admin_notices' WP hook should be put in here. This particular method will apply on |
|
| 1603 | + * ALL EE_Admin pages. |
|
| 1604 | + * |
|
| 1605 | + * @return void |
|
| 1606 | + */ |
|
| 1607 | + public function admin_notices_global() |
|
| 1608 | + { |
|
| 1609 | + $this->_display_no_javascript_warning(); |
|
| 1610 | + $this->_display_espresso_notices(); |
|
| 1611 | + } |
|
| 1612 | + |
|
| 1613 | + |
|
| 1614 | + public function network_admin_notices_global() |
|
| 1615 | + { |
|
| 1616 | + $this->_display_no_javascript_warning(); |
|
| 1617 | + $this->_display_espresso_notices(); |
|
| 1618 | + } |
|
| 1619 | + |
|
| 1620 | + |
|
| 1621 | + /** |
|
| 1622 | + * admin_footer_scripts_global |
|
| 1623 | + * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method |
|
| 1624 | + * will apply on ALL EE_Admin pages. |
|
| 1625 | + * |
|
| 1626 | + * @return void |
|
| 1627 | + */ |
|
| 1628 | + public function admin_footer_scripts_global() |
|
| 1629 | + { |
|
| 1630 | + $this->_add_admin_page_ajax_loading_img(); |
|
| 1631 | + $this->_add_admin_page_overlay(); |
|
| 1632 | + // if metaboxes are present we need to add the nonce field |
|
| 1633 | + if (isset($this->_route_config['metaboxes']) |
|
| 1634 | + || isset($this->_route_config['list_table']) |
|
| 1635 | + || (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes']) |
|
| 1636 | + ) { |
|
| 1637 | + wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false); |
|
| 1638 | + wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false); |
|
| 1639 | + } |
|
| 1640 | + } |
|
| 1641 | + |
|
| 1642 | + |
|
| 1643 | + /** |
|
| 1644 | + * admin_footer_global |
|
| 1645 | + * Anything triggered by the wp 'admin_footer' wp hook should be put in here. This particular method will apply on |
|
| 1646 | + * ALL EE_Admin Pages. |
|
| 1647 | + * |
|
| 1648 | + * @return void |
|
| 1649 | + * @throws EE_Error |
|
| 1650 | + */ |
|
| 1651 | + public function admin_footer_global() |
|
| 1652 | + { |
|
| 1653 | + // dialog container for dialog helper |
|
| 1654 | + $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n"; |
|
| 1655 | + $d_cont .= '<div class="ee-notices"></div>'; |
|
| 1656 | + $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>'; |
|
| 1657 | + $d_cont .= '</div>'; |
|
| 1658 | + echo $d_cont; |
|
| 1659 | + // help tour stuff? |
|
| 1660 | + if (isset($this->_help_tour[ $this->_req_action ])) { |
|
| 1661 | + echo implode('<br />', $this->_help_tour[ $this->_req_action ]); |
|
| 1662 | + } |
|
| 1663 | + // current set timezone for timezone js |
|
| 1664 | + echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>'; |
|
| 1665 | + } |
|
| 1666 | + |
|
| 1667 | + |
|
| 1668 | + /** |
|
| 1669 | + * This function sees if there is a method for help popup content existing for the given route. If there is then |
|
| 1670 | + * we'll use the retrieved array to output the content using the template. For child classes: If you want to have |
|
| 1671 | + * help popups then in your templates or your content you set "triggers" for the content using the |
|
| 1672 | + * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method |
|
| 1673 | + * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup |
|
| 1674 | + * method for the content in the format "_help_popup_content_{route_name}()" So if you are setting help content |
|
| 1675 | + * for the |
|
| 1676 | + * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined |
|
| 1677 | + * "help_popup_content_..." method. You must prepare and return an array in the following format array( |
|
| 1678 | + * 'help_trigger_id' => array( |
|
| 1679 | + * 'title' => esc_html__('localized title for popup', 'event_espresso'), |
|
| 1680 | + * 'content' => esc_html__('localized content for popup', 'event_espresso') |
|
| 1681 | + * ) |
|
| 1682 | + * ); |
|
| 1683 | + * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route. |
|
| 1684 | + * |
|
| 1685 | + * @param array $help_array |
|
| 1686 | + * @param bool $display |
|
| 1687 | + * @return string content |
|
| 1688 | + * @throws DomainException |
|
| 1689 | + * @throws EE_Error |
|
| 1690 | + */ |
|
| 1691 | + protected function _set_help_popup_content($help_array = array(), $display = false) |
|
| 1692 | + { |
|
| 1693 | + $content = ''; |
|
| 1694 | + $help_array = empty($help_array) ? $this->_get_help_content() : $help_array; |
|
| 1695 | + // loop through the array and setup content |
|
| 1696 | + foreach ($help_array as $trigger => $help) { |
|
| 1697 | + // make sure the array is setup properly |
|
| 1698 | + if (! isset($help['title']) || ! isset($help['content'])) { |
|
| 1699 | + throw new EE_Error( |
|
| 1700 | + esc_html__( |
|
| 1701 | + 'Does not look like the popup content array has been setup correctly. Might want to double check that. Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class', |
|
| 1702 | + 'event_espresso' |
|
| 1703 | + ) |
|
| 1704 | + ); |
|
| 1705 | + } |
|
| 1706 | + // we're good so let'd setup the template vars and then assign parsed template content to our content. |
|
| 1707 | + $template_args = array( |
|
| 1708 | + 'help_popup_id' => $trigger, |
|
| 1709 | + 'help_popup_title' => $help['title'], |
|
| 1710 | + 'help_popup_content' => $help['content'], |
|
| 1711 | + ); |
|
| 1712 | + $content .= EEH_Template::display_template( |
|
| 1713 | + EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php', |
|
| 1714 | + $template_args, |
|
| 1715 | + true |
|
| 1716 | + ); |
|
| 1717 | + } |
|
| 1718 | + if ($display) { |
|
| 1719 | + echo $content; |
|
| 1720 | + return ''; |
|
| 1721 | + } |
|
| 1722 | + return $content; |
|
| 1723 | + } |
|
| 1724 | + |
|
| 1725 | + |
|
| 1726 | + /** |
|
| 1727 | + * All this does is retrieve the help content array if set by the EE_Admin_Page child |
|
| 1728 | + * |
|
| 1729 | + * @return array properly formatted array for help popup content |
|
| 1730 | + * @throws EE_Error |
|
| 1731 | + */ |
|
| 1732 | + private function _get_help_content() |
|
| 1733 | + { |
|
| 1734 | + // what is the method we're looking for? |
|
| 1735 | + $method_name = '_help_popup_content_' . $this->_req_action; |
|
| 1736 | + // if method doesn't exist let's get out. |
|
| 1737 | + if (! method_exists($this, $method_name)) { |
|
| 1738 | + return array(); |
|
| 1739 | + } |
|
| 1740 | + // k we're good to go let's retrieve the help array |
|
| 1741 | + $help_array = call_user_func(array($this, $method_name)); |
|
| 1742 | + // make sure we've got an array! |
|
| 1743 | + if (! is_array($help_array)) { |
|
| 1744 | + throw new EE_Error( |
|
| 1745 | + esc_html__( |
|
| 1746 | + 'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.', |
|
| 1747 | + 'event_espresso' |
|
| 1748 | + ) |
|
| 1749 | + ); |
|
| 1750 | + } |
|
| 1751 | + return $help_array; |
|
| 1752 | + } |
|
| 1753 | + |
|
| 1754 | + |
|
| 1755 | + /** |
|
| 1756 | + * EE Admin Pages can use this to set a properly formatted trigger for a help popup. |
|
| 1757 | + * By default the trigger html is printed. Otherwise it can be returned if the $display flag is set "false" |
|
| 1758 | + * See comments made on the _set_help_content method for understanding other parts to the help popup tool. |
|
| 1759 | + * |
|
| 1760 | + * @param string $trigger_id reference for retrieving the trigger content for the popup |
|
| 1761 | + * @param boolean $display if false then we return the trigger string |
|
| 1762 | + * @param array $dimensions an array of dimensions for the box (array(h,w)) |
|
| 1763 | + * @return string |
|
| 1764 | + * @throws DomainException |
|
| 1765 | + * @throws EE_Error |
|
| 1766 | + */ |
|
| 1767 | + protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640')) |
|
| 1768 | + { |
|
| 1769 | + if (defined('DOING_AJAX')) { |
|
| 1770 | + return ''; |
|
| 1771 | + } |
|
| 1772 | + // let's check and see if there is any content set for this popup. If there isn't then we'll include a default title and content so that developers know something needs to be corrected |
|
| 1773 | + $help_array = $this->_get_help_content(); |
|
| 1774 | + $help_content = ''; |
|
| 1775 | + if (empty($help_array) || ! isset($help_array[ $trigger_id ])) { |
|
| 1776 | + $help_array[ $trigger_id ] = array( |
|
| 1777 | + 'title' => esc_html__('Missing Content', 'event_espresso'), |
|
| 1778 | + 'content' => esc_html__( |
|
| 1779 | + 'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)', |
|
| 1780 | + 'event_espresso' |
|
| 1781 | + ), |
|
| 1782 | + ); |
|
| 1783 | + $help_content = $this->_set_help_popup_content($help_array, false); |
|
| 1784 | + } |
|
| 1785 | + // let's setup the trigger |
|
| 1786 | + $content = '<a class="ee-dialog" href="?height=' |
|
| 1787 | + . $dimensions[0] |
|
| 1788 | + . '&width=' |
|
| 1789 | + . $dimensions[1] |
|
| 1790 | + . '&inlineId=' |
|
| 1791 | + . $trigger_id |
|
| 1792 | + . '" target="_blank"><span class="question ee-help-popup-question"></span></a>'; |
|
| 1793 | + $content .= $help_content; |
|
| 1794 | + if ($display) { |
|
| 1795 | + echo $content; |
|
| 1796 | + return ''; |
|
| 1797 | + } |
|
| 1798 | + return $content; |
|
| 1799 | + } |
|
| 1800 | + |
|
| 1801 | + |
|
| 1802 | + /** |
|
| 1803 | + * _add_global_screen_options |
|
| 1804 | + * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so. |
|
| 1805 | + * This particular method will add_screen_options on ALL EE_Admin Pages |
|
| 1806 | + * |
|
| 1807 | + * @link http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/ |
|
| 1808 | + * see also WP_Screen object documents... |
|
| 1809 | + * @link http://codex.wordpress.org/Class_Reference/WP_Screen |
|
| 1810 | + * @abstract |
|
| 1811 | + * @return void |
|
| 1812 | + */ |
|
| 1813 | + private function _add_global_screen_options() |
|
| 1814 | + { |
|
| 1815 | + } |
|
| 1816 | + |
|
| 1817 | + |
|
| 1818 | + /** |
|
| 1819 | + * _add_global_feature_pointers |
|
| 1820 | + * This method is used for implementing any "feature pointers" (using built-in WP styling js). |
|
| 1821 | + * This particular method will implement feature pointers for ALL EE_Admin pages. |
|
| 1822 | + * Note: this is just a placeholder for now. Implementation will come down the road |
|
| 1823 | + * |
|
| 1824 | + * @see WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be |
|
| 1825 | + * extended) also see: |
|
| 1826 | + * @link http://eamann.com/tech/wordpress-portland/ |
|
| 1827 | + * @abstract |
|
| 1828 | + * @return void |
|
| 1829 | + */ |
|
| 1830 | + private function _add_global_feature_pointers() |
|
| 1831 | + { |
|
| 1832 | + } |
|
| 1833 | + |
|
| 1834 | + |
|
| 1835 | + /** |
|
| 1836 | + * load_global_scripts_styles |
|
| 1837 | + * The scripts and styles enqueued in here will be loaded on every EE Admin page |
|
| 1838 | + * |
|
| 1839 | + * @return void |
|
| 1840 | + * @throws EE_Error |
|
| 1841 | + */ |
|
| 1842 | + public function load_global_scripts_styles() |
|
| 1843 | + { |
|
| 1844 | + /** STYLES **/ |
|
| 1845 | + // add debugging styles |
|
| 1846 | + if (WP_DEBUG) { |
|
| 1847 | + add_action('admin_head', array($this, 'add_xdebug_style')); |
|
| 1848 | + } |
|
| 1849 | + // register all styles |
|
| 1850 | + wp_register_style( |
|
| 1851 | + 'espresso-ui-theme', |
|
| 1852 | + EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', |
|
| 1853 | + array(), |
|
| 1854 | + EVENT_ESPRESSO_VERSION |
|
| 1855 | + ); |
|
| 1856 | + wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 1857 | + // helpers styles |
|
| 1858 | + wp_register_style( |
|
| 1859 | + 'ee-text-links', |
|
| 1860 | + EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css', |
|
| 1861 | + array(), |
|
| 1862 | + EVENT_ESPRESSO_VERSION |
|
| 1863 | + ); |
|
| 1864 | + /** SCRIPTS **/ |
|
| 1865 | + // register all scripts |
|
| 1866 | + wp_register_script( |
|
| 1867 | + 'ee-dialog', |
|
| 1868 | + EE_ADMIN_URL . 'assets/ee-dialog-helper.js', |
|
| 1869 | + array('jquery', 'jquery-ui-draggable'), |
|
| 1870 | + EVENT_ESPRESSO_VERSION, |
|
| 1871 | + true |
|
| 1872 | + ); |
|
| 1873 | + wp_register_script( |
|
| 1874 | + 'ee_admin_js', |
|
| 1875 | + EE_ADMIN_URL . 'assets/ee-admin-page.js', |
|
| 1876 | + array('espresso_core', 'ee-parse-uri', 'ee-dialog'), |
|
| 1877 | + EVENT_ESPRESSO_VERSION, |
|
| 1878 | + true |
|
| 1879 | + ); |
|
| 1880 | + wp_register_script( |
|
| 1881 | + 'jquery-ui-timepicker-addon', |
|
| 1882 | + EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js', |
|
| 1883 | + array('jquery-ui-datepicker', 'jquery-ui-slider'), |
|
| 1884 | + EVENT_ESPRESSO_VERSION, |
|
| 1885 | + true |
|
| 1886 | + ); |
|
| 1887 | + add_filter('FHEE_load_joyride', '__return_true'); |
|
| 1888 | + // script for sorting tables |
|
| 1889 | + wp_register_script( |
|
| 1890 | + 'espresso_ajax_table_sorting', |
|
| 1891 | + EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js', |
|
| 1892 | + array('ee_admin_js', 'jquery-ui-sortable'), |
|
| 1893 | + EVENT_ESPRESSO_VERSION, |
|
| 1894 | + true |
|
| 1895 | + ); |
|
| 1896 | + // script for parsing uri's |
|
| 1897 | + wp_register_script( |
|
| 1898 | + 'ee-parse-uri', |
|
| 1899 | + EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js', |
|
| 1900 | + array(), |
|
| 1901 | + EVENT_ESPRESSO_VERSION, |
|
| 1902 | + true |
|
| 1903 | + ); |
|
| 1904 | + // and parsing associative serialized form elements |
|
| 1905 | + wp_register_script( |
|
| 1906 | + 'ee-serialize-full-array', |
|
| 1907 | + EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js', |
|
| 1908 | + array('jquery'), |
|
| 1909 | + EVENT_ESPRESSO_VERSION, |
|
| 1910 | + true |
|
| 1911 | + ); |
|
| 1912 | + // helpers scripts |
|
| 1913 | + wp_register_script( |
|
| 1914 | + 'ee-text-links', |
|
| 1915 | + EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js', |
|
| 1916 | + array('jquery'), |
|
| 1917 | + EVENT_ESPRESSO_VERSION, |
|
| 1918 | + true |
|
| 1919 | + ); |
|
| 1920 | + wp_register_script( |
|
| 1921 | + 'ee-moment-core', |
|
| 1922 | + EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js', |
|
| 1923 | + array(), |
|
| 1924 | + EVENT_ESPRESSO_VERSION, |
|
| 1925 | + true |
|
| 1926 | + ); |
|
| 1927 | + wp_register_script( |
|
| 1928 | + 'ee-moment', |
|
| 1929 | + EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js', |
|
| 1930 | + array('ee-moment-core'), |
|
| 1931 | + EVENT_ESPRESSO_VERSION, |
|
| 1932 | + true |
|
| 1933 | + ); |
|
| 1934 | + wp_register_script( |
|
| 1935 | + 'ee-datepicker', |
|
| 1936 | + EE_ADMIN_URL . 'assets/ee-datepicker.js', |
|
| 1937 | + array('jquery-ui-timepicker-addon', 'ee-moment'), |
|
| 1938 | + EVENT_ESPRESSO_VERSION, |
|
| 1939 | + true |
|
| 1940 | + ); |
|
| 1941 | + // google charts |
|
| 1942 | + wp_register_script( |
|
| 1943 | + 'google-charts', |
|
| 1944 | + 'https://www.gstatic.com/charts/loader.js', |
|
| 1945 | + array(), |
|
| 1946 | + EVENT_ESPRESSO_VERSION, |
|
| 1947 | + false |
|
| 1948 | + ); |
|
| 1949 | + // ENQUEUE ALL BASICS BY DEFAULT |
|
| 1950 | + wp_enqueue_style('ee-admin-css'); |
|
| 1951 | + wp_enqueue_script('ee_admin_js'); |
|
| 1952 | + wp_enqueue_script('ee-accounting'); |
|
| 1953 | + wp_enqueue_script('jquery-validate'); |
|
| 1954 | + // taking care of metaboxes |
|
| 1955 | + if (empty($this->_cpt_route) |
|
| 1956 | + && (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes'])) |
|
| 1957 | + ) { |
|
| 1958 | + wp_enqueue_script('dashboard'); |
|
| 1959 | + } |
|
| 1960 | + // LOCALIZED DATA |
|
| 1961 | + // localize script for ajax lazy loading |
|
| 1962 | + $lazy_loader_container_ids = apply_filters( |
|
| 1963 | + 'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers', |
|
| 1964 | + array('espresso_news_post_box_content') |
|
| 1965 | + ); |
|
| 1966 | + wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids); |
|
| 1967 | + /** |
|
| 1968 | + * help tour stuff |
|
| 1969 | + */ |
|
| 1970 | + if (! empty($this->_help_tour)) { |
|
| 1971 | + // register the js for kicking things off |
|
| 1972 | + wp_enqueue_script( |
|
| 1973 | + 'ee-help-tour', |
|
| 1974 | + EE_ADMIN_URL . 'assets/ee-help-tour.js', |
|
| 1975 | + array('jquery-joyride'), |
|
| 1976 | + EVENT_ESPRESSO_VERSION, |
|
| 1977 | + true |
|
| 1978 | + ); |
|
| 1979 | + $tours = array(); |
|
| 1980 | + // setup tours for the js tour object |
|
| 1981 | + foreach ($this->_help_tour['tours'] as $tour) { |
|
| 1982 | + if ($tour instanceof EE_Help_Tour) { |
|
| 1983 | + $tours[] = array( |
|
| 1984 | + 'id' => $tour->get_slug(), |
|
| 1985 | + 'options' => $tour->get_options(), |
|
| 1986 | + ); |
|
| 1987 | + } |
|
| 1988 | + } |
|
| 1989 | + wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours)); |
|
| 1990 | + // admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour |
|
| 1991 | + } |
|
| 1992 | + } |
|
| 1993 | + |
|
| 1994 | + |
|
| 1995 | + /** |
|
| 1996 | + * admin_footer_scripts_eei18n_js_strings |
|
| 1997 | + * |
|
| 1998 | + * @return void |
|
| 1999 | + */ |
|
| 2000 | + public function admin_footer_scripts_eei18n_js_strings() |
|
| 2001 | + { |
|
| 2002 | + EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL; |
|
| 2003 | + EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__( |
|
| 2004 | + 'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!', |
|
| 2005 | + 'event_espresso' |
|
| 2006 | + ); |
|
| 2007 | + EE_Registry::$i18n_js_strings['January'] = esc_html__('January', 'event_espresso'); |
|
| 2008 | + EE_Registry::$i18n_js_strings['February'] = esc_html__('February', 'event_espresso'); |
|
| 2009 | + EE_Registry::$i18n_js_strings['March'] = esc_html__('March', 'event_espresso'); |
|
| 2010 | + EE_Registry::$i18n_js_strings['April'] = esc_html__('April', 'event_espresso'); |
|
| 2011 | + EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso'); |
|
| 2012 | + EE_Registry::$i18n_js_strings['June'] = esc_html__('June', 'event_espresso'); |
|
| 2013 | + EE_Registry::$i18n_js_strings['July'] = esc_html__('July', 'event_espresso'); |
|
| 2014 | + EE_Registry::$i18n_js_strings['August'] = esc_html__('August', 'event_espresso'); |
|
| 2015 | + EE_Registry::$i18n_js_strings['September'] = esc_html__('September', 'event_espresso'); |
|
| 2016 | + EE_Registry::$i18n_js_strings['October'] = esc_html__('October', 'event_espresso'); |
|
| 2017 | + EE_Registry::$i18n_js_strings['November'] = esc_html__('November', 'event_espresso'); |
|
| 2018 | + EE_Registry::$i18n_js_strings['December'] = esc_html__('December', 'event_espresso'); |
|
| 2019 | + EE_Registry::$i18n_js_strings['Jan'] = esc_html__('Jan', 'event_espresso'); |
|
| 2020 | + EE_Registry::$i18n_js_strings['Feb'] = esc_html__('Feb', 'event_espresso'); |
|
| 2021 | + EE_Registry::$i18n_js_strings['Mar'] = esc_html__('Mar', 'event_espresso'); |
|
| 2022 | + EE_Registry::$i18n_js_strings['Apr'] = esc_html__('Apr', 'event_espresso'); |
|
| 2023 | + EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso'); |
|
| 2024 | + EE_Registry::$i18n_js_strings['Jun'] = esc_html__('Jun', 'event_espresso'); |
|
| 2025 | + EE_Registry::$i18n_js_strings['Jul'] = esc_html__('Jul', 'event_espresso'); |
|
| 2026 | + EE_Registry::$i18n_js_strings['Aug'] = esc_html__('Aug', 'event_espresso'); |
|
| 2027 | + EE_Registry::$i18n_js_strings['Sep'] = esc_html__('Sep', 'event_espresso'); |
|
| 2028 | + EE_Registry::$i18n_js_strings['Oct'] = esc_html__('Oct', 'event_espresso'); |
|
| 2029 | + EE_Registry::$i18n_js_strings['Nov'] = esc_html__('Nov', 'event_espresso'); |
|
| 2030 | + EE_Registry::$i18n_js_strings['Dec'] = esc_html__('Dec', 'event_espresso'); |
|
| 2031 | + EE_Registry::$i18n_js_strings['Sunday'] = esc_html__('Sunday', 'event_espresso'); |
|
| 2032 | + EE_Registry::$i18n_js_strings['Monday'] = esc_html__('Monday', 'event_espresso'); |
|
| 2033 | + EE_Registry::$i18n_js_strings['Tuesday'] = esc_html__('Tuesday', 'event_espresso'); |
|
| 2034 | + EE_Registry::$i18n_js_strings['Wednesday'] = esc_html__('Wednesday', 'event_espresso'); |
|
| 2035 | + EE_Registry::$i18n_js_strings['Thursday'] = esc_html__('Thursday', 'event_espresso'); |
|
| 2036 | + EE_Registry::$i18n_js_strings['Friday'] = esc_html__('Friday', 'event_espresso'); |
|
| 2037 | + EE_Registry::$i18n_js_strings['Saturday'] = esc_html__('Saturday', 'event_espresso'); |
|
| 2038 | + EE_Registry::$i18n_js_strings['Sun'] = esc_html__('Sun', 'event_espresso'); |
|
| 2039 | + EE_Registry::$i18n_js_strings['Mon'] = esc_html__('Mon', 'event_espresso'); |
|
| 2040 | + EE_Registry::$i18n_js_strings['Tue'] = esc_html__('Tue', 'event_espresso'); |
|
| 2041 | + EE_Registry::$i18n_js_strings['Wed'] = esc_html__('Wed', 'event_espresso'); |
|
| 2042 | + EE_Registry::$i18n_js_strings['Thu'] = esc_html__('Thu', 'event_espresso'); |
|
| 2043 | + EE_Registry::$i18n_js_strings['Fri'] = esc_html__('Fri', 'event_espresso'); |
|
| 2044 | + EE_Registry::$i18n_js_strings['Sat'] = esc_html__('Sat', 'event_espresso'); |
|
| 2045 | + } |
|
| 2046 | + |
|
| 2047 | + |
|
| 2048 | + /** |
|
| 2049 | + * load enhanced xdebug styles for ppl with failing eyesight |
|
| 2050 | + * |
|
| 2051 | + * @return void |
|
| 2052 | + */ |
|
| 2053 | + public function add_xdebug_style() |
|
| 2054 | + { |
|
| 2055 | + echo '<style>.xdebug-error { font-size:1.5em; }</style>'; |
|
| 2056 | + } |
|
| 2057 | + |
|
| 2058 | + |
|
| 2059 | + /************************/ |
|
| 2060 | + /** LIST TABLE METHODS **/ |
|
| 2061 | + /************************/ |
|
| 2062 | + /** |
|
| 2063 | + * this sets up the list table if the current view requires it. |
|
| 2064 | + * |
|
| 2065 | + * @return void |
|
| 2066 | + * @throws EE_Error |
|
| 2067 | + */ |
|
| 2068 | + protected function _set_list_table() |
|
| 2069 | + { |
|
| 2070 | + // first is this a list_table view? |
|
| 2071 | + if (! isset($this->_route_config['list_table'])) { |
|
| 2072 | + return; |
|
| 2073 | + } //not a list_table view so get out. |
|
| 2074 | + // list table functions are per view specific (because some admin pages might have more than one list table!) |
|
| 2075 | + $list_table_view = '_set_list_table_views_' . $this->_req_action; |
|
| 2076 | + if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) { |
|
| 2077 | + // user error msg |
|
| 2078 | + $error_msg = esc_html__( |
|
| 2079 | + 'An error occurred. The requested list table views could not be found.', |
|
| 2080 | + 'event_espresso' |
|
| 2081 | + ); |
|
| 2082 | + // developer error msg |
|
| 2083 | + $error_msg .= '||' |
|
| 2084 | + . sprintf( |
|
| 2085 | + esc_html__( |
|
| 2086 | + 'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.', |
|
| 2087 | + 'event_espresso' |
|
| 2088 | + ), |
|
| 2089 | + $this->_req_action, |
|
| 2090 | + $list_table_view |
|
| 2091 | + ); |
|
| 2092 | + throw new EE_Error($error_msg); |
|
| 2093 | + } |
|
| 2094 | + // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally |
|
| 2095 | + $this->_views = apply_filters( |
|
| 2096 | + 'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action, |
|
| 2097 | + $this->_views |
|
| 2098 | + ); |
|
| 2099 | + $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views); |
|
| 2100 | + $this->_views = apply_filters('FHEE_list_table_views', $this->_views); |
|
| 2101 | + $this->_set_list_table_view(); |
|
| 2102 | + $this->_set_list_table_object(); |
|
| 2103 | + } |
|
| 2104 | + |
|
| 2105 | + |
|
| 2106 | + /** |
|
| 2107 | + * set current view for List Table |
|
| 2108 | + * |
|
| 2109 | + * @return void |
|
| 2110 | + */ |
|
| 2111 | + protected function _set_list_table_view() |
|
| 2112 | + { |
|
| 2113 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2114 | + // looking at active items or dumpster diving ? |
|
| 2115 | + if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) { |
|
| 2116 | + $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all'; |
|
| 2117 | + } else { |
|
| 2118 | + $this->_view = sanitize_key($this->_req_data['status']); |
|
| 2119 | + } |
|
| 2120 | + } |
|
| 2121 | + |
|
| 2122 | + |
|
| 2123 | + /** |
|
| 2124 | + * _set_list_table_object |
|
| 2125 | + * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of. |
|
| 2126 | + * |
|
| 2127 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 2128 | + * @throws \InvalidArgumentException |
|
| 2129 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 2130 | + * @throws EE_Error |
|
| 2131 | + * @throws InvalidInterfaceException |
|
| 2132 | + */ |
|
| 2133 | + protected function _set_list_table_object() |
|
| 2134 | + { |
|
| 2135 | + if (isset($this->_route_config['list_table'])) { |
|
| 2136 | + if (! class_exists($this->_route_config['list_table'])) { |
|
| 2137 | + throw new EE_Error( |
|
| 2138 | + sprintf( |
|
| 2139 | + esc_html__( |
|
| 2140 | + 'The %s class defined for the list table does not exist. Please check the spelling of the class ref in the $_page_config property on %s.', |
|
| 2141 | + 'event_espresso' |
|
| 2142 | + ), |
|
| 2143 | + $this->_route_config['list_table'], |
|
| 2144 | + get_class($this) |
|
| 2145 | + ) |
|
| 2146 | + ); |
|
| 2147 | + } |
|
| 2148 | + $this->_list_table_object = $this->loader->getShared( |
|
| 2149 | + $this->_route_config['list_table'], |
|
| 2150 | + array($this) |
|
| 2151 | + ); |
|
| 2152 | + } |
|
| 2153 | + } |
|
| 2154 | + |
|
| 2155 | + |
|
| 2156 | + /** |
|
| 2157 | + * get_list_table_view_RLs - get it? View RL ?? VU-RL??? URL ?? |
|
| 2158 | + * |
|
| 2159 | + * @param array $extra_query_args Optional. An array of extra query args to add to the generated |
|
| 2160 | + * urls. The array should be indexed by the view it is being |
|
| 2161 | + * added to. |
|
| 2162 | + * @return array |
|
| 2163 | + */ |
|
| 2164 | + public function get_list_table_view_RLs($extra_query_args = array()) |
|
| 2165 | + { |
|
| 2166 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2167 | + if (empty($this->_views)) { |
|
| 2168 | + $this->_views = array(); |
|
| 2169 | + } |
|
| 2170 | + // cycle thru views |
|
| 2171 | + foreach ($this->_views as $key => $view) { |
|
| 2172 | + $query_args = array(); |
|
| 2173 | + // check for current view |
|
| 2174 | + $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : ''; |
|
| 2175 | + $query_args['action'] = $this->_req_action; |
|
| 2176 | + $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce'); |
|
| 2177 | + $query_args['status'] = $view['slug']; |
|
| 2178 | + // merge any other arguments sent in. |
|
| 2179 | + if (isset($extra_query_args[ $view['slug'] ])) { |
|
| 2180 | + $query_args = array_merge($query_args, $extra_query_args[ $view['slug'] ]); |
|
| 2181 | + } |
|
| 2182 | + $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url); |
|
| 2183 | + } |
|
| 2184 | + return $this->_views; |
|
| 2185 | + } |
|
| 2186 | + |
|
| 2187 | + |
|
| 2188 | + /** |
|
| 2189 | + * _entries_per_page_dropdown |
|
| 2190 | + * generates a drop down box for selecting the number of visible rows in an admin page list table |
|
| 2191 | + * |
|
| 2192 | + * @todo : Note: ideally this should be added to the screen options dropdown as that would be consistent with how |
|
| 2193 | + * WP does it. |
|
| 2194 | + * @param int $max_entries total number of rows in the table |
|
| 2195 | + * @return string |
|
| 2196 | + */ |
|
| 2197 | + protected function _entries_per_page_dropdown($max_entries = 0) |
|
| 2198 | + { |
|
| 2199 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2200 | + $values = array(10, 25, 50, 100); |
|
| 2201 | + $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10; |
|
| 2202 | + if ($max_entries) { |
|
| 2203 | + $values[] = $max_entries; |
|
| 2204 | + sort($values); |
|
| 2205 | + } |
|
| 2206 | + $entries_per_page_dropdown = ' |
|
| 2207 | 2207 | <div id="entries-per-page-dv" class="alignleft actions"> |
| 2208 | 2208 | <label class="hide-if-no-js"> |
| 2209 | 2209 | Show |
| 2210 | 2210 | <select id="entries-per-page-slct" name="entries-per-page-slct">'; |
| 2211 | - foreach ($values as $value) { |
|
| 2212 | - if ($value < $max_entries) { |
|
| 2213 | - $selected = $value === $per_page ? ' selected="' . $per_page . '"' : ''; |
|
| 2214 | - $entries_per_page_dropdown .= ' |
|
| 2211 | + foreach ($values as $value) { |
|
| 2212 | + if ($value < $max_entries) { |
|
| 2213 | + $selected = $value === $per_page ? ' selected="' . $per_page . '"' : ''; |
|
| 2214 | + $entries_per_page_dropdown .= ' |
|
| 2215 | 2215 | <option value="' . $value . '"' . $selected . '>' . $value . ' </option>'; |
| 2216 | - } |
|
| 2217 | - } |
|
| 2218 | - $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : ''; |
|
| 2219 | - $entries_per_page_dropdown .= ' |
|
| 2216 | + } |
|
| 2217 | + } |
|
| 2218 | + $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : ''; |
|
| 2219 | + $entries_per_page_dropdown .= ' |
|
| 2220 | 2220 | <option value="' . $max_entries . '"' . $selected . '>All </option>'; |
| 2221 | - $entries_per_page_dropdown .= ' |
|
| 2221 | + $entries_per_page_dropdown .= ' |
|
| 2222 | 2222 | </select> |
| 2223 | 2223 | entries |
| 2224 | 2224 | </label> |
| 2225 | 2225 | <input id="entries-per-page-btn" class="button-secondary" type="submit" value="Go" > |
| 2226 | 2226 | </div> |
| 2227 | 2227 | '; |
| 2228 | - return $entries_per_page_dropdown; |
|
| 2229 | - } |
|
| 2230 | - |
|
| 2231 | - |
|
| 2232 | - /** |
|
| 2233 | - * _set_search_attributes |
|
| 2234 | - * |
|
| 2235 | - * @return void |
|
| 2236 | - */ |
|
| 2237 | - public function _set_search_attributes() |
|
| 2238 | - { |
|
| 2239 | - $this->_template_args['search']['btn_label'] = sprintf( |
|
| 2240 | - esc_html__('Search %s', 'event_espresso'), |
|
| 2241 | - empty($this->_search_btn_label) ? $this->page_label |
|
| 2242 | - : $this->_search_btn_label |
|
| 2243 | - ); |
|
| 2244 | - $this->_template_args['search']['callback'] = 'search_' . $this->page_slug; |
|
| 2245 | - } |
|
| 2246 | - |
|
| 2247 | - |
|
| 2248 | - |
|
| 2249 | - /*** END LIST TABLE METHODS **/ |
|
| 2250 | - |
|
| 2251 | - |
|
| 2252 | - /** |
|
| 2253 | - * _add_registered_metaboxes |
|
| 2254 | - * this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array. |
|
| 2255 | - * |
|
| 2256 | - * @link http://codex.wordpress.org/Function_Reference/add_meta_box |
|
| 2257 | - * @return void |
|
| 2258 | - * @throws EE_Error |
|
| 2259 | - */ |
|
| 2260 | - private function _add_registered_meta_boxes() |
|
| 2261 | - { |
|
| 2262 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2263 | - // we only add meta boxes if the page_route calls for it |
|
| 2264 | - if (is_array($this->_route_config) && isset($this->_route_config['metaboxes']) |
|
| 2265 | - && is_array( |
|
| 2266 | - $this->_route_config['metaboxes'] |
|
| 2267 | - ) |
|
| 2268 | - ) { |
|
| 2269 | - // this simply loops through the callbacks provided |
|
| 2270 | - // and checks if there is a corresponding callback registered by the child |
|
| 2271 | - // if there is then we go ahead and process the metabox loader. |
|
| 2272 | - foreach ($this->_route_config['metaboxes'] as $metabox_callback) { |
|
| 2273 | - // first check for Closures |
|
| 2274 | - if ($metabox_callback instanceof Closure) { |
|
| 2275 | - $result = $metabox_callback(); |
|
| 2276 | - } elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) { |
|
| 2277 | - $result = call_user_func(array($metabox_callback[0], $metabox_callback[1])); |
|
| 2278 | - } else { |
|
| 2279 | - $result = call_user_func(array($this, &$metabox_callback)); |
|
| 2280 | - } |
|
| 2281 | - if ($result === false) { |
|
| 2282 | - // user error msg |
|
| 2283 | - $error_msg = esc_html__( |
|
| 2284 | - 'An error occurred. The requested metabox could not be found.', |
|
| 2285 | - 'event_espresso' |
|
| 2286 | - ); |
|
| 2287 | - // developer error msg |
|
| 2288 | - $error_msg .= '||' |
|
| 2289 | - . sprintf( |
|
| 2290 | - esc_html__( |
|
| 2291 | - 'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.', |
|
| 2292 | - 'event_espresso' |
|
| 2293 | - ), |
|
| 2294 | - $metabox_callback |
|
| 2295 | - ); |
|
| 2296 | - throw new EE_Error($error_msg); |
|
| 2297 | - } |
|
| 2298 | - } |
|
| 2299 | - } |
|
| 2300 | - } |
|
| 2301 | - |
|
| 2302 | - |
|
| 2303 | - /** |
|
| 2304 | - * _add_screen_columns |
|
| 2305 | - * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as |
|
| 2306 | - * the dynamic column template and we'll setup the column options for the page. |
|
| 2307 | - * |
|
| 2308 | - * @return void |
|
| 2309 | - */ |
|
| 2310 | - private function _add_screen_columns() |
|
| 2311 | - { |
|
| 2312 | - if (is_array($this->_route_config) |
|
| 2313 | - && isset($this->_route_config['columns']) |
|
| 2314 | - && is_array($this->_route_config['columns']) |
|
| 2315 | - && count($this->_route_config['columns']) === 2 |
|
| 2316 | - ) { |
|
| 2317 | - add_screen_option( |
|
| 2318 | - 'layout_columns', |
|
| 2319 | - array( |
|
| 2320 | - 'max' => (int) $this->_route_config['columns'][0], |
|
| 2321 | - 'default' => (int) $this->_route_config['columns'][1], |
|
| 2322 | - ) |
|
| 2323 | - ); |
|
| 2324 | - $this->_template_args['num_columns'] = $this->_route_config['columns'][0]; |
|
| 2325 | - $screen_id = $this->_current_screen->id; |
|
| 2326 | - $screen_columns = (int) get_user_option("screen_layout_{$screen_id}"); |
|
| 2327 | - $total_columns = ! empty($screen_columns) |
|
| 2328 | - ? $screen_columns |
|
| 2329 | - : $this->_route_config['columns'][1]; |
|
| 2330 | - $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns; |
|
| 2331 | - $this->_template_args['current_page'] = $this->_wp_page_slug; |
|
| 2332 | - $this->_template_args['screen'] = $this->_current_screen; |
|
| 2333 | - $this->_column_template_path = EE_ADMIN_TEMPLATE |
|
| 2334 | - . 'admin_details_metabox_column_wrapper.template.php'; |
|
| 2335 | - // finally if we don't have has_metaboxes set in the route config |
|
| 2336 | - // let's make sure it IS set other wise the necessary hidden fields for this won't be loaded. |
|
| 2337 | - $this->_route_config['has_metaboxes'] = true; |
|
| 2338 | - } |
|
| 2339 | - } |
|
| 2340 | - |
|
| 2341 | - |
|
| 2342 | - |
|
| 2343 | - /** GLOBALLY AVAILABLE METABOXES **/ |
|
| 2344 | - |
|
| 2345 | - |
|
| 2346 | - /** |
|
| 2347 | - * In this section we put any globally available EE metaboxes for all EE Admin pages. They are called by simply |
|
| 2348 | - * referencing the callback in the _page_config array property. This way you can be very specific about what pages |
|
| 2349 | - * these get loaded on. |
|
| 2350 | - */ |
|
| 2351 | - private function _espresso_news_post_box() |
|
| 2352 | - { |
|
| 2353 | - $news_box_title = apply_filters( |
|
| 2354 | - 'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title', |
|
| 2355 | - esc_html__('New @ Event Espresso', 'event_espresso') |
|
| 2356 | - ); |
|
| 2357 | - add_meta_box( |
|
| 2358 | - 'espresso_news_post_box', |
|
| 2359 | - $news_box_title, |
|
| 2360 | - array( |
|
| 2361 | - $this, |
|
| 2362 | - 'espresso_news_post_box', |
|
| 2363 | - ), |
|
| 2364 | - $this->_wp_page_slug, |
|
| 2365 | - 'side' |
|
| 2366 | - ); |
|
| 2367 | - } |
|
| 2368 | - |
|
| 2369 | - |
|
| 2370 | - /** |
|
| 2371 | - * Code for setting up espresso ratings request metabox. |
|
| 2372 | - */ |
|
| 2373 | - protected function _espresso_ratings_request() |
|
| 2374 | - { |
|
| 2375 | - if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) { |
|
| 2376 | - return; |
|
| 2377 | - } |
|
| 2378 | - $ratings_box_title = apply_filters( |
|
| 2379 | - 'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title', |
|
| 2380 | - esc_html__('Keep Event Espresso Decaf Free', 'event_espresso') |
|
| 2381 | - ); |
|
| 2382 | - add_meta_box( |
|
| 2383 | - 'espresso_ratings_request', |
|
| 2384 | - $ratings_box_title, |
|
| 2385 | - array( |
|
| 2386 | - $this, |
|
| 2387 | - 'espresso_ratings_request', |
|
| 2388 | - ), |
|
| 2389 | - $this->_wp_page_slug, |
|
| 2390 | - 'side' |
|
| 2391 | - ); |
|
| 2392 | - } |
|
| 2393 | - |
|
| 2394 | - |
|
| 2395 | - /** |
|
| 2396 | - * Code for setting up espresso ratings request metabox content. |
|
| 2397 | - * |
|
| 2398 | - * @throws DomainException |
|
| 2399 | - */ |
|
| 2400 | - public function espresso_ratings_request() |
|
| 2401 | - { |
|
| 2402 | - EEH_Template::display_template( |
|
| 2403 | - EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php', |
|
| 2404 | - array() |
|
| 2405 | - ); |
|
| 2406 | - } |
|
| 2407 | - |
|
| 2408 | - |
|
| 2409 | - public static function cached_rss_display($rss_id, $url) |
|
| 2410 | - { |
|
| 2411 | - $loading = '<p class="widget-loading hide-if-no-js">' |
|
| 2412 | - . __('Loading…', 'event_espresso') |
|
| 2413 | - . '</p><p class="hide-if-js">' |
|
| 2414 | - . esc_html__('This widget requires JavaScript.', 'event_espresso') |
|
| 2415 | - . '</p>'; |
|
| 2416 | - $pre = '<div class="espresso-rss-display">' . "\n\t"; |
|
| 2417 | - $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>'; |
|
| 2418 | - $post = '</div>' . "\n"; |
|
| 2419 | - $cache_key = 'ee_rss_' . md5($rss_id); |
|
| 2420 | - $output = get_transient($cache_key); |
|
| 2421 | - if ($output !== false) { |
|
| 2422 | - echo $pre . $output . $post; |
|
| 2423 | - return true; |
|
| 2424 | - } |
|
| 2425 | - if (! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
| 2426 | - echo $pre . $loading . $post; |
|
| 2427 | - return false; |
|
| 2428 | - } |
|
| 2429 | - ob_start(); |
|
| 2430 | - wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5)); |
|
| 2431 | - set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS); |
|
| 2432 | - return true; |
|
| 2433 | - } |
|
| 2434 | - |
|
| 2435 | - |
|
| 2436 | - public function espresso_news_post_box() |
|
| 2437 | - { |
|
| 2438 | - ?> |
|
| 2228 | + return $entries_per_page_dropdown; |
|
| 2229 | + } |
|
| 2230 | + |
|
| 2231 | + |
|
| 2232 | + /** |
|
| 2233 | + * _set_search_attributes |
|
| 2234 | + * |
|
| 2235 | + * @return void |
|
| 2236 | + */ |
|
| 2237 | + public function _set_search_attributes() |
|
| 2238 | + { |
|
| 2239 | + $this->_template_args['search']['btn_label'] = sprintf( |
|
| 2240 | + esc_html__('Search %s', 'event_espresso'), |
|
| 2241 | + empty($this->_search_btn_label) ? $this->page_label |
|
| 2242 | + : $this->_search_btn_label |
|
| 2243 | + ); |
|
| 2244 | + $this->_template_args['search']['callback'] = 'search_' . $this->page_slug; |
|
| 2245 | + } |
|
| 2246 | + |
|
| 2247 | + |
|
| 2248 | + |
|
| 2249 | + /*** END LIST TABLE METHODS **/ |
|
| 2250 | + |
|
| 2251 | + |
|
| 2252 | + /** |
|
| 2253 | + * _add_registered_metaboxes |
|
| 2254 | + * this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array. |
|
| 2255 | + * |
|
| 2256 | + * @link http://codex.wordpress.org/Function_Reference/add_meta_box |
|
| 2257 | + * @return void |
|
| 2258 | + * @throws EE_Error |
|
| 2259 | + */ |
|
| 2260 | + private function _add_registered_meta_boxes() |
|
| 2261 | + { |
|
| 2262 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2263 | + // we only add meta boxes if the page_route calls for it |
|
| 2264 | + if (is_array($this->_route_config) && isset($this->_route_config['metaboxes']) |
|
| 2265 | + && is_array( |
|
| 2266 | + $this->_route_config['metaboxes'] |
|
| 2267 | + ) |
|
| 2268 | + ) { |
|
| 2269 | + // this simply loops through the callbacks provided |
|
| 2270 | + // and checks if there is a corresponding callback registered by the child |
|
| 2271 | + // if there is then we go ahead and process the metabox loader. |
|
| 2272 | + foreach ($this->_route_config['metaboxes'] as $metabox_callback) { |
|
| 2273 | + // first check for Closures |
|
| 2274 | + if ($metabox_callback instanceof Closure) { |
|
| 2275 | + $result = $metabox_callback(); |
|
| 2276 | + } elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) { |
|
| 2277 | + $result = call_user_func(array($metabox_callback[0], $metabox_callback[1])); |
|
| 2278 | + } else { |
|
| 2279 | + $result = call_user_func(array($this, &$metabox_callback)); |
|
| 2280 | + } |
|
| 2281 | + if ($result === false) { |
|
| 2282 | + // user error msg |
|
| 2283 | + $error_msg = esc_html__( |
|
| 2284 | + 'An error occurred. The requested metabox could not be found.', |
|
| 2285 | + 'event_espresso' |
|
| 2286 | + ); |
|
| 2287 | + // developer error msg |
|
| 2288 | + $error_msg .= '||' |
|
| 2289 | + . sprintf( |
|
| 2290 | + esc_html__( |
|
| 2291 | + 'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.', |
|
| 2292 | + 'event_espresso' |
|
| 2293 | + ), |
|
| 2294 | + $metabox_callback |
|
| 2295 | + ); |
|
| 2296 | + throw new EE_Error($error_msg); |
|
| 2297 | + } |
|
| 2298 | + } |
|
| 2299 | + } |
|
| 2300 | + } |
|
| 2301 | + |
|
| 2302 | + |
|
| 2303 | + /** |
|
| 2304 | + * _add_screen_columns |
|
| 2305 | + * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as |
|
| 2306 | + * the dynamic column template and we'll setup the column options for the page. |
|
| 2307 | + * |
|
| 2308 | + * @return void |
|
| 2309 | + */ |
|
| 2310 | + private function _add_screen_columns() |
|
| 2311 | + { |
|
| 2312 | + if (is_array($this->_route_config) |
|
| 2313 | + && isset($this->_route_config['columns']) |
|
| 2314 | + && is_array($this->_route_config['columns']) |
|
| 2315 | + && count($this->_route_config['columns']) === 2 |
|
| 2316 | + ) { |
|
| 2317 | + add_screen_option( |
|
| 2318 | + 'layout_columns', |
|
| 2319 | + array( |
|
| 2320 | + 'max' => (int) $this->_route_config['columns'][0], |
|
| 2321 | + 'default' => (int) $this->_route_config['columns'][1], |
|
| 2322 | + ) |
|
| 2323 | + ); |
|
| 2324 | + $this->_template_args['num_columns'] = $this->_route_config['columns'][0]; |
|
| 2325 | + $screen_id = $this->_current_screen->id; |
|
| 2326 | + $screen_columns = (int) get_user_option("screen_layout_{$screen_id}"); |
|
| 2327 | + $total_columns = ! empty($screen_columns) |
|
| 2328 | + ? $screen_columns |
|
| 2329 | + : $this->_route_config['columns'][1]; |
|
| 2330 | + $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns; |
|
| 2331 | + $this->_template_args['current_page'] = $this->_wp_page_slug; |
|
| 2332 | + $this->_template_args['screen'] = $this->_current_screen; |
|
| 2333 | + $this->_column_template_path = EE_ADMIN_TEMPLATE |
|
| 2334 | + . 'admin_details_metabox_column_wrapper.template.php'; |
|
| 2335 | + // finally if we don't have has_metaboxes set in the route config |
|
| 2336 | + // let's make sure it IS set other wise the necessary hidden fields for this won't be loaded. |
|
| 2337 | + $this->_route_config['has_metaboxes'] = true; |
|
| 2338 | + } |
|
| 2339 | + } |
|
| 2340 | + |
|
| 2341 | + |
|
| 2342 | + |
|
| 2343 | + /** GLOBALLY AVAILABLE METABOXES **/ |
|
| 2344 | + |
|
| 2345 | + |
|
| 2346 | + /** |
|
| 2347 | + * In this section we put any globally available EE metaboxes for all EE Admin pages. They are called by simply |
|
| 2348 | + * referencing the callback in the _page_config array property. This way you can be very specific about what pages |
|
| 2349 | + * these get loaded on. |
|
| 2350 | + */ |
|
| 2351 | + private function _espresso_news_post_box() |
|
| 2352 | + { |
|
| 2353 | + $news_box_title = apply_filters( |
|
| 2354 | + 'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title', |
|
| 2355 | + esc_html__('New @ Event Espresso', 'event_espresso') |
|
| 2356 | + ); |
|
| 2357 | + add_meta_box( |
|
| 2358 | + 'espresso_news_post_box', |
|
| 2359 | + $news_box_title, |
|
| 2360 | + array( |
|
| 2361 | + $this, |
|
| 2362 | + 'espresso_news_post_box', |
|
| 2363 | + ), |
|
| 2364 | + $this->_wp_page_slug, |
|
| 2365 | + 'side' |
|
| 2366 | + ); |
|
| 2367 | + } |
|
| 2368 | + |
|
| 2369 | + |
|
| 2370 | + /** |
|
| 2371 | + * Code for setting up espresso ratings request metabox. |
|
| 2372 | + */ |
|
| 2373 | + protected function _espresso_ratings_request() |
|
| 2374 | + { |
|
| 2375 | + if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) { |
|
| 2376 | + return; |
|
| 2377 | + } |
|
| 2378 | + $ratings_box_title = apply_filters( |
|
| 2379 | + 'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title', |
|
| 2380 | + esc_html__('Keep Event Espresso Decaf Free', 'event_espresso') |
|
| 2381 | + ); |
|
| 2382 | + add_meta_box( |
|
| 2383 | + 'espresso_ratings_request', |
|
| 2384 | + $ratings_box_title, |
|
| 2385 | + array( |
|
| 2386 | + $this, |
|
| 2387 | + 'espresso_ratings_request', |
|
| 2388 | + ), |
|
| 2389 | + $this->_wp_page_slug, |
|
| 2390 | + 'side' |
|
| 2391 | + ); |
|
| 2392 | + } |
|
| 2393 | + |
|
| 2394 | + |
|
| 2395 | + /** |
|
| 2396 | + * Code for setting up espresso ratings request metabox content. |
|
| 2397 | + * |
|
| 2398 | + * @throws DomainException |
|
| 2399 | + */ |
|
| 2400 | + public function espresso_ratings_request() |
|
| 2401 | + { |
|
| 2402 | + EEH_Template::display_template( |
|
| 2403 | + EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php', |
|
| 2404 | + array() |
|
| 2405 | + ); |
|
| 2406 | + } |
|
| 2407 | + |
|
| 2408 | + |
|
| 2409 | + public static function cached_rss_display($rss_id, $url) |
|
| 2410 | + { |
|
| 2411 | + $loading = '<p class="widget-loading hide-if-no-js">' |
|
| 2412 | + . __('Loading…', 'event_espresso') |
|
| 2413 | + . '</p><p class="hide-if-js">' |
|
| 2414 | + . esc_html__('This widget requires JavaScript.', 'event_espresso') |
|
| 2415 | + . '</p>'; |
|
| 2416 | + $pre = '<div class="espresso-rss-display">' . "\n\t"; |
|
| 2417 | + $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>'; |
|
| 2418 | + $post = '</div>' . "\n"; |
|
| 2419 | + $cache_key = 'ee_rss_' . md5($rss_id); |
|
| 2420 | + $output = get_transient($cache_key); |
|
| 2421 | + if ($output !== false) { |
|
| 2422 | + echo $pre . $output . $post; |
|
| 2423 | + return true; |
|
| 2424 | + } |
|
| 2425 | + if (! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
| 2426 | + echo $pre . $loading . $post; |
|
| 2427 | + return false; |
|
| 2428 | + } |
|
| 2429 | + ob_start(); |
|
| 2430 | + wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5)); |
|
| 2431 | + set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS); |
|
| 2432 | + return true; |
|
| 2433 | + } |
|
| 2434 | + |
|
| 2435 | + |
|
| 2436 | + public function espresso_news_post_box() |
|
| 2437 | + { |
|
| 2438 | + ?> |
|
| 2439 | 2439 | <div class="padding"> |
| 2440 | 2440 | <div id="espresso_news_post_box_content" class="infolinks"> |
| 2441 | 2441 | <?php |
| 2442 | - // Get RSS Feed(s) |
|
| 2443 | - self::cached_rss_display( |
|
| 2444 | - 'espresso_news_post_box_content', |
|
| 2445 | - urlencode( |
|
| 2446 | - apply_filters( |
|
| 2447 | - 'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url', |
|
| 2448 | - 'http://eventespresso.com/feed/' |
|
| 2449 | - ) |
|
| 2450 | - ) |
|
| 2451 | - ); |
|
| 2452 | - ?> |
|
| 2442 | + // Get RSS Feed(s) |
|
| 2443 | + self::cached_rss_display( |
|
| 2444 | + 'espresso_news_post_box_content', |
|
| 2445 | + urlencode( |
|
| 2446 | + apply_filters( |
|
| 2447 | + 'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url', |
|
| 2448 | + 'http://eventespresso.com/feed/' |
|
| 2449 | + ) |
|
| 2450 | + ) |
|
| 2451 | + ); |
|
| 2452 | + ?> |
|
| 2453 | 2453 | </div> |
| 2454 | 2454 | <?php do_action('AHEE__EE_Admin_Page__espresso_news_post_box__after_content'); ?> |
| 2455 | 2455 | </div> |
| 2456 | 2456 | <?php |
| 2457 | - } |
|
| 2458 | - |
|
| 2459 | - |
|
| 2460 | - private function _espresso_links_post_box() |
|
| 2461 | - { |
|
| 2462 | - // Hiding until we actually have content to put in here... |
|
| 2463 | - // add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side'); |
|
| 2464 | - } |
|
| 2465 | - |
|
| 2466 | - |
|
| 2467 | - public function espresso_links_post_box() |
|
| 2468 | - { |
|
| 2469 | - // Hiding until we actually have content to put in here... |
|
| 2470 | - // EEH_Template::display_template( |
|
| 2471 | - // EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php' |
|
| 2472 | - // ); |
|
| 2473 | - } |
|
| 2474 | - |
|
| 2475 | - |
|
| 2476 | - protected function _espresso_sponsors_post_box() |
|
| 2477 | - { |
|
| 2478 | - if (apply_filters('FHEE_show_sponsors_meta_box', true)) { |
|
| 2479 | - add_meta_box( |
|
| 2480 | - 'espresso_sponsors_post_box', |
|
| 2481 | - esc_html__('Event Espresso Highlights', 'event_espresso'), |
|
| 2482 | - array($this, 'espresso_sponsors_post_box'), |
|
| 2483 | - $this->_wp_page_slug, |
|
| 2484 | - 'side' |
|
| 2485 | - ); |
|
| 2486 | - } |
|
| 2487 | - } |
|
| 2488 | - |
|
| 2489 | - |
|
| 2490 | - public function espresso_sponsors_post_box() |
|
| 2491 | - { |
|
| 2492 | - EEH_Template::display_template( |
|
| 2493 | - EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php' |
|
| 2494 | - ); |
|
| 2495 | - } |
|
| 2496 | - |
|
| 2497 | - |
|
| 2498 | - private function _publish_post_box() |
|
| 2499 | - { |
|
| 2500 | - $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview'; |
|
| 2501 | - // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array |
|
| 2502 | - // then we'll use that for the metabox label. |
|
| 2503 | - // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes) |
|
| 2504 | - if (! empty($this->_labels['publishbox'])) { |
|
| 2505 | - $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ] |
|
| 2506 | - : $this->_labels['publishbox']; |
|
| 2507 | - } else { |
|
| 2508 | - $box_label = esc_html__('Publish', 'event_espresso'); |
|
| 2509 | - } |
|
| 2510 | - $box_label = apply_filters( |
|
| 2511 | - 'FHEE__EE_Admin_Page___publish_post_box__box_label', |
|
| 2512 | - $box_label, |
|
| 2513 | - $this->_req_action, |
|
| 2514 | - $this |
|
| 2515 | - ); |
|
| 2516 | - add_meta_box( |
|
| 2517 | - $meta_box_ref, |
|
| 2518 | - $box_label, |
|
| 2519 | - array($this, 'editor_overview'), |
|
| 2520 | - $this->_current_screen->id, |
|
| 2521 | - 'side', |
|
| 2522 | - 'high' |
|
| 2523 | - ); |
|
| 2524 | - } |
|
| 2525 | - |
|
| 2526 | - |
|
| 2527 | - public function editor_overview() |
|
| 2528 | - { |
|
| 2529 | - // if we have extra content set let's add it in if not make sure its empty |
|
| 2530 | - $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content']) |
|
| 2531 | - ? $this->_template_args['publish_box_extra_content'] |
|
| 2532 | - : ''; |
|
| 2533 | - echo EEH_Template::display_template( |
|
| 2534 | - EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php', |
|
| 2535 | - $this->_template_args, |
|
| 2536 | - true |
|
| 2537 | - ); |
|
| 2538 | - } |
|
| 2539 | - |
|
| 2540 | - |
|
| 2541 | - /** end of globally available metaboxes section **/ |
|
| 2542 | - |
|
| 2543 | - |
|
| 2544 | - /** |
|
| 2545 | - * Public wrapper for the protected method. Allows plugins/addons to externally call the |
|
| 2546 | - * protected method. |
|
| 2547 | - * |
|
| 2548 | - * @see $this->_set_publish_post_box_vars for param details |
|
| 2549 | - * @since 4.6.0 |
|
| 2550 | - * @param string $name |
|
| 2551 | - * @param int $id |
|
| 2552 | - * @param bool $delete |
|
| 2553 | - * @param string $save_close_redirect_URL |
|
| 2554 | - * @param bool $both_btns |
|
| 2555 | - * @throws EE_Error |
|
| 2556 | - * @throws InvalidArgumentException |
|
| 2557 | - * @throws InvalidDataTypeException |
|
| 2558 | - * @throws InvalidInterfaceException |
|
| 2559 | - */ |
|
| 2560 | - public function set_publish_post_box_vars( |
|
| 2561 | - $name = '', |
|
| 2562 | - $id = 0, |
|
| 2563 | - $delete = false, |
|
| 2564 | - $save_close_redirect_URL = '', |
|
| 2565 | - $both_btns = true |
|
| 2566 | - ) { |
|
| 2567 | - $this->_set_publish_post_box_vars( |
|
| 2568 | - $name, |
|
| 2569 | - $id, |
|
| 2570 | - $delete, |
|
| 2571 | - $save_close_redirect_URL, |
|
| 2572 | - $both_btns |
|
| 2573 | - ); |
|
| 2574 | - } |
|
| 2575 | - |
|
| 2576 | - |
|
| 2577 | - /** |
|
| 2578 | - * Sets the _template_args arguments used by the _publish_post_box shortcut |
|
| 2579 | - * Note: currently there is no validation for this. However if you want the delete button, the |
|
| 2580 | - * save, and save and close buttons to work properly, then you will want to include a |
|
| 2581 | - * values for the name and id arguments. |
|
| 2582 | - * |
|
| 2583 | - * @todo Add in validation for name/id arguments. |
|
| 2584 | - * @param string $name key used for the action ID (i.e. event_id) |
|
| 2585 | - * @param int $id id attached to the item published |
|
| 2586 | - * @param string $delete page route callback for the delete action |
|
| 2587 | - * @param string $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed |
|
| 2588 | - * @param boolean $both_btns whether to display BOTH the "Save & Close" and "Save" buttons or just |
|
| 2589 | - * the Save button |
|
| 2590 | - * @throws EE_Error |
|
| 2591 | - * @throws InvalidArgumentException |
|
| 2592 | - * @throws InvalidDataTypeException |
|
| 2593 | - * @throws InvalidInterfaceException |
|
| 2594 | - */ |
|
| 2595 | - protected function _set_publish_post_box_vars( |
|
| 2596 | - $name = '', |
|
| 2597 | - $id = 0, |
|
| 2598 | - $delete = '', |
|
| 2599 | - $save_close_redirect_URL = '', |
|
| 2600 | - $both_btns = true |
|
| 2601 | - ) { |
|
| 2602 | - // if Save & Close, use a custom redirect URL or default to the main page? |
|
| 2603 | - $save_close_redirect_URL = ! empty($save_close_redirect_URL) |
|
| 2604 | - ? $save_close_redirect_URL |
|
| 2605 | - : $this->_admin_base_url; |
|
| 2606 | - // create the Save & Close and Save buttons |
|
| 2607 | - $this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL); |
|
| 2608 | - // if we have extra content set let's add it in if not make sure its empty |
|
| 2609 | - $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content']) |
|
| 2610 | - ? $this->_template_args['publish_box_extra_content'] |
|
| 2611 | - : ''; |
|
| 2612 | - if ($delete && ! empty($id)) { |
|
| 2613 | - // make sure we have a default if just true is sent. |
|
| 2614 | - $delete = ! empty($delete) ? $delete : 'delete'; |
|
| 2615 | - $delete_link_args = array($name => $id); |
|
| 2616 | - $delete = $this->get_action_link_or_button( |
|
| 2617 | - $delete, |
|
| 2618 | - $delete, |
|
| 2619 | - $delete_link_args, |
|
| 2620 | - 'submitdelete deletion', |
|
| 2621 | - '', |
|
| 2622 | - false |
|
| 2623 | - ); |
|
| 2624 | - } |
|
| 2625 | - $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : ''; |
|
| 2626 | - if (! empty($name) && ! empty($id)) { |
|
| 2627 | - $hidden_field_arr[ $name ] = array( |
|
| 2628 | - 'type' => 'hidden', |
|
| 2629 | - 'value' => $id, |
|
| 2630 | - ); |
|
| 2631 | - $hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array'); |
|
| 2632 | - } else { |
|
| 2633 | - $hf = ''; |
|
| 2634 | - } |
|
| 2635 | - // add hidden field |
|
| 2636 | - $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name) |
|
| 2637 | - ? $hf[ $name ]['field'] |
|
| 2638 | - : $hf; |
|
| 2639 | - } |
|
| 2640 | - |
|
| 2641 | - |
|
| 2642 | - /** |
|
| 2643 | - * displays an error message to ppl who have javascript disabled |
|
| 2644 | - * |
|
| 2645 | - * @return void |
|
| 2646 | - */ |
|
| 2647 | - private function _display_no_javascript_warning() |
|
| 2648 | - { |
|
| 2649 | - ?> |
|
| 2457 | + } |
|
| 2458 | + |
|
| 2459 | + |
|
| 2460 | + private function _espresso_links_post_box() |
|
| 2461 | + { |
|
| 2462 | + // Hiding until we actually have content to put in here... |
|
| 2463 | + // add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side'); |
|
| 2464 | + } |
|
| 2465 | + |
|
| 2466 | + |
|
| 2467 | + public function espresso_links_post_box() |
|
| 2468 | + { |
|
| 2469 | + // Hiding until we actually have content to put in here... |
|
| 2470 | + // EEH_Template::display_template( |
|
| 2471 | + // EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php' |
|
| 2472 | + // ); |
|
| 2473 | + } |
|
| 2474 | + |
|
| 2475 | + |
|
| 2476 | + protected function _espresso_sponsors_post_box() |
|
| 2477 | + { |
|
| 2478 | + if (apply_filters('FHEE_show_sponsors_meta_box', true)) { |
|
| 2479 | + add_meta_box( |
|
| 2480 | + 'espresso_sponsors_post_box', |
|
| 2481 | + esc_html__('Event Espresso Highlights', 'event_espresso'), |
|
| 2482 | + array($this, 'espresso_sponsors_post_box'), |
|
| 2483 | + $this->_wp_page_slug, |
|
| 2484 | + 'side' |
|
| 2485 | + ); |
|
| 2486 | + } |
|
| 2487 | + } |
|
| 2488 | + |
|
| 2489 | + |
|
| 2490 | + public function espresso_sponsors_post_box() |
|
| 2491 | + { |
|
| 2492 | + EEH_Template::display_template( |
|
| 2493 | + EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php' |
|
| 2494 | + ); |
|
| 2495 | + } |
|
| 2496 | + |
|
| 2497 | + |
|
| 2498 | + private function _publish_post_box() |
|
| 2499 | + { |
|
| 2500 | + $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview'; |
|
| 2501 | + // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array |
|
| 2502 | + // then we'll use that for the metabox label. |
|
| 2503 | + // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes) |
|
| 2504 | + if (! empty($this->_labels['publishbox'])) { |
|
| 2505 | + $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ] |
|
| 2506 | + : $this->_labels['publishbox']; |
|
| 2507 | + } else { |
|
| 2508 | + $box_label = esc_html__('Publish', 'event_espresso'); |
|
| 2509 | + } |
|
| 2510 | + $box_label = apply_filters( |
|
| 2511 | + 'FHEE__EE_Admin_Page___publish_post_box__box_label', |
|
| 2512 | + $box_label, |
|
| 2513 | + $this->_req_action, |
|
| 2514 | + $this |
|
| 2515 | + ); |
|
| 2516 | + add_meta_box( |
|
| 2517 | + $meta_box_ref, |
|
| 2518 | + $box_label, |
|
| 2519 | + array($this, 'editor_overview'), |
|
| 2520 | + $this->_current_screen->id, |
|
| 2521 | + 'side', |
|
| 2522 | + 'high' |
|
| 2523 | + ); |
|
| 2524 | + } |
|
| 2525 | + |
|
| 2526 | + |
|
| 2527 | + public function editor_overview() |
|
| 2528 | + { |
|
| 2529 | + // if we have extra content set let's add it in if not make sure its empty |
|
| 2530 | + $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content']) |
|
| 2531 | + ? $this->_template_args['publish_box_extra_content'] |
|
| 2532 | + : ''; |
|
| 2533 | + echo EEH_Template::display_template( |
|
| 2534 | + EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php', |
|
| 2535 | + $this->_template_args, |
|
| 2536 | + true |
|
| 2537 | + ); |
|
| 2538 | + } |
|
| 2539 | + |
|
| 2540 | + |
|
| 2541 | + /** end of globally available metaboxes section **/ |
|
| 2542 | + |
|
| 2543 | + |
|
| 2544 | + /** |
|
| 2545 | + * Public wrapper for the protected method. Allows plugins/addons to externally call the |
|
| 2546 | + * protected method. |
|
| 2547 | + * |
|
| 2548 | + * @see $this->_set_publish_post_box_vars for param details |
|
| 2549 | + * @since 4.6.0 |
|
| 2550 | + * @param string $name |
|
| 2551 | + * @param int $id |
|
| 2552 | + * @param bool $delete |
|
| 2553 | + * @param string $save_close_redirect_URL |
|
| 2554 | + * @param bool $both_btns |
|
| 2555 | + * @throws EE_Error |
|
| 2556 | + * @throws InvalidArgumentException |
|
| 2557 | + * @throws InvalidDataTypeException |
|
| 2558 | + * @throws InvalidInterfaceException |
|
| 2559 | + */ |
|
| 2560 | + public function set_publish_post_box_vars( |
|
| 2561 | + $name = '', |
|
| 2562 | + $id = 0, |
|
| 2563 | + $delete = false, |
|
| 2564 | + $save_close_redirect_URL = '', |
|
| 2565 | + $both_btns = true |
|
| 2566 | + ) { |
|
| 2567 | + $this->_set_publish_post_box_vars( |
|
| 2568 | + $name, |
|
| 2569 | + $id, |
|
| 2570 | + $delete, |
|
| 2571 | + $save_close_redirect_URL, |
|
| 2572 | + $both_btns |
|
| 2573 | + ); |
|
| 2574 | + } |
|
| 2575 | + |
|
| 2576 | + |
|
| 2577 | + /** |
|
| 2578 | + * Sets the _template_args arguments used by the _publish_post_box shortcut |
|
| 2579 | + * Note: currently there is no validation for this. However if you want the delete button, the |
|
| 2580 | + * save, and save and close buttons to work properly, then you will want to include a |
|
| 2581 | + * values for the name and id arguments. |
|
| 2582 | + * |
|
| 2583 | + * @todo Add in validation for name/id arguments. |
|
| 2584 | + * @param string $name key used for the action ID (i.e. event_id) |
|
| 2585 | + * @param int $id id attached to the item published |
|
| 2586 | + * @param string $delete page route callback for the delete action |
|
| 2587 | + * @param string $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed |
|
| 2588 | + * @param boolean $both_btns whether to display BOTH the "Save & Close" and "Save" buttons or just |
|
| 2589 | + * the Save button |
|
| 2590 | + * @throws EE_Error |
|
| 2591 | + * @throws InvalidArgumentException |
|
| 2592 | + * @throws InvalidDataTypeException |
|
| 2593 | + * @throws InvalidInterfaceException |
|
| 2594 | + */ |
|
| 2595 | + protected function _set_publish_post_box_vars( |
|
| 2596 | + $name = '', |
|
| 2597 | + $id = 0, |
|
| 2598 | + $delete = '', |
|
| 2599 | + $save_close_redirect_URL = '', |
|
| 2600 | + $both_btns = true |
|
| 2601 | + ) { |
|
| 2602 | + // if Save & Close, use a custom redirect URL or default to the main page? |
|
| 2603 | + $save_close_redirect_URL = ! empty($save_close_redirect_URL) |
|
| 2604 | + ? $save_close_redirect_URL |
|
| 2605 | + : $this->_admin_base_url; |
|
| 2606 | + // create the Save & Close and Save buttons |
|
| 2607 | + $this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL); |
|
| 2608 | + // if we have extra content set let's add it in if not make sure its empty |
|
| 2609 | + $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content']) |
|
| 2610 | + ? $this->_template_args['publish_box_extra_content'] |
|
| 2611 | + : ''; |
|
| 2612 | + if ($delete && ! empty($id)) { |
|
| 2613 | + // make sure we have a default if just true is sent. |
|
| 2614 | + $delete = ! empty($delete) ? $delete : 'delete'; |
|
| 2615 | + $delete_link_args = array($name => $id); |
|
| 2616 | + $delete = $this->get_action_link_or_button( |
|
| 2617 | + $delete, |
|
| 2618 | + $delete, |
|
| 2619 | + $delete_link_args, |
|
| 2620 | + 'submitdelete deletion', |
|
| 2621 | + '', |
|
| 2622 | + false |
|
| 2623 | + ); |
|
| 2624 | + } |
|
| 2625 | + $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : ''; |
|
| 2626 | + if (! empty($name) && ! empty($id)) { |
|
| 2627 | + $hidden_field_arr[ $name ] = array( |
|
| 2628 | + 'type' => 'hidden', |
|
| 2629 | + 'value' => $id, |
|
| 2630 | + ); |
|
| 2631 | + $hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array'); |
|
| 2632 | + } else { |
|
| 2633 | + $hf = ''; |
|
| 2634 | + } |
|
| 2635 | + // add hidden field |
|
| 2636 | + $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name) |
|
| 2637 | + ? $hf[ $name ]['field'] |
|
| 2638 | + : $hf; |
|
| 2639 | + } |
|
| 2640 | + |
|
| 2641 | + |
|
| 2642 | + /** |
|
| 2643 | + * displays an error message to ppl who have javascript disabled |
|
| 2644 | + * |
|
| 2645 | + * @return void |
|
| 2646 | + */ |
|
| 2647 | + private function _display_no_javascript_warning() |
|
| 2648 | + { |
|
| 2649 | + ?> |
|
| 2650 | 2650 | <noscript> |
| 2651 | 2651 | <div id="no-js-message" class="error"> |
| 2652 | 2652 | <p style="font-size:1.3em;"> |
| 2653 | 2653 | <span style="color:red;"><?php esc_html_e('Warning!', 'event_espresso'); ?></span> |
| 2654 | 2654 | <?php esc_html_e( |
| 2655 | - 'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.', |
|
| 2656 | - 'event_espresso' |
|
| 2657 | - ); ?> |
|
| 2655 | + 'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.', |
|
| 2656 | + 'event_espresso' |
|
| 2657 | + ); ?> |
|
| 2658 | 2658 | </p> |
| 2659 | 2659 | </div> |
| 2660 | 2660 | </noscript> |
| 2661 | 2661 | <?php |
| 2662 | - } |
|
| 2663 | - |
|
| 2664 | - |
|
| 2665 | - /** |
|
| 2666 | - * displays espresso success and/or error notices |
|
| 2667 | - * |
|
| 2668 | - * @return void |
|
| 2669 | - */ |
|
| 2670 | - private function _display_espresso_notices() |
|
| 2671 | - { |
|
| 2672 | - $notices = $this->_get_transient(true); |
|
| 2673 | - echo stripslashes($notices); |
|
| 2674 | - } |
|
| 2675 | - |
|
| 2676 | - |
|
| 2677 | - /** |
|
| 2678 | - * spinny things pacify the masses |
|
| 2679 | - * |
|
| 2680 | - * @return void |
|
| 2681 | - */ |
|
| 2682 | - protected function _add_admin_page_ajax_loading_img() |
|
| 2683 | - { |
|
| 2684 | - ?> |
|
| 2662 | + } |
|
| 2663 | + |
|
| 2664 | + |
|
| 2665 | + /** |
|
| 2666 | + * displays espresso success and/or error notices |
|
| 2667 | + * |
|
| 2668 | + * @return void |
|
| 2669 | + */ |
|
| 2670 | + private function _display_espresso_notices() |
|
| 2671 | + { |
|
| 2672 | + $notices = $this->_get_transient(true); |
|
| 2673 | + echo stripslashes($notices); |
|
| 2674 | + } |
|
| 2675 | + |
|
| 2676 | + |
|
| 2677 | + /** |
|
| 2678 | + * spinny things pacify the masses |
|
| 2679 | + * |
|
| 2680 | + * @return void |
|
| 2681 | + */ |
|
| 2682 | + protected function _add_admin_page_ajax_loading_img() |
|
| 2683 | + { |
|
| 2684 | + ?> |
|
| 2685 | 2685 | <div id="espresso-ajax-loading" class="ajax-loading-grey"> |
| 2686 | 2686 | <span class="ee-spinner ee-spin"></span><span class="hidden"><?php |
| 2687 | - esc_html_e('loading...', 'event_espresso'); ?></span> |
|
| 2687 | + esc_html_e('loading...', 'event_espresso'); ?></span> |
|
| 2688 | 2688 | </div> |
| 2689 | 2689 | <?php |
| 2690 | - } |
|
| 2690 | + } |
|
| 2691 | 2691 | |
| 2692 | 2692 | |
| 2693 | - /** |
|
| 2694 | - * add admin page overlay for modal boxes |
|
| 2695 | - * |
|
| 2696 | - * @return void |
|
| 2697 | - */ |
|
| 2698 | - protected function _add_admin_page_overlay() |
|
| 2699 | - { |
|
| 2700 | - ?> |
|
| 2693 | + /** |
|
| 2694 | + * add admin page overlay for modal boxes |
|
| 2695 | + * |
|
| 2696 | + * @return void |
|
| 2697 | + */ |
|
| 2698 | + protected function _add_admin_page_overlay() |
|
| 2699 | + { |
|
| 2700 | + ?> |
|
| 2701 | 2701 | <div id="espresso-admin-page-overlay-dv" class=""></div> |
| 2702 | 2702 | <?php |
| 2703 | - } |
|
| 2704 | - |
|
| 2705 | - |
|
| 2706 | - /** |
|
| 2707 | - * facade for add_meta_box |
|
| 2708 | - * |
|
| 2709 | - * @param string $action where the metabox get's displayed |
|
| 2710 | - * @param string $title Title of Metabox (output in metabox header) |
|
| 2711 | - * @param string $callback If not empty and $create_fun is set to false then we'll use a custom callback |
|
| 2712 | - * instead of the one created in here. |
|
| 2713 | - * @param array $callback_args an array of args supplied for the metabox |
|
| 2714 | - * @param string $column what metabox column |
|
| 2715 | - * @param string $priority give this metabox a priority (using accepted priorities for wp meta boxes) |
|
| 2716 | - * @param boolean $create_func default is true. Basically we can say we don't WANT to have the runtime function |
|
| 2717 | - * created but just set our own callback for wp's add_meta_box. |
|
| 2718 | - * @throws \DomainException |
|
| 2719 | - */ |
|
| 2720 | - public function _add_admin_page_meta_box( |
|
| 2721 | - $action, |
|
| 2722 | - $title, |
|
| 2723 | - $callback, |
|
| 2724 | - $callback_args, |
|
| 2725 | - $column = 'normal', |
|
| 2726 | - $priority = 'high', |
|
| 2727 | - $create_func = true |
|
| 2728 | - ) { |
|
| 2729 | - do_action('AHEE_log', __FILE__, __FUNCTION__, $callback); |
|
| 2730 | - // if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated. |
|
| 2731 | - if (empty($callback_args) && $create_func) { |
|
| 2732 | - $callback_args = array( |
|
| 2733 | - 'template_path' => $this->_template_path, |
|
| 2734 | - 'template_args' => $this->_template_args, |
|
| 2735 | - ); |
|
| 2736 | - } |
|
| 2737 | - // if $create_func is true (default) then we automatically create the function for displaying the actual meta box. If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish) |
|
| 2738 | - $call_back_func = $create_func |
|
| 2739 | - ? function ($post, $metabox) { |
|
| 2740 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2741 | - echo EEH_Template::display_template( |
|
| 2742 | - $metabox['args']['template_path'], |
|
| 2743 | - $metabox['args']['template_args'], |
|
| 2744 | - true |
|
| 2745 | - ); |
|
| 2746 | - } |
|
| 2747 | - : $callback; |
|
| 2748 | - add_meta_box( |
|
| 2749 | - str_replace('_', '-', $action) . '-mbox', |
|
| 2750 | - $title, |
|
| 2751 | - $call_back_func, |
|
| 2752 | - $this->_wp_page_slug, |
|
| 2753 | - $column, |
|
| 2754 | - $priority, |
|
| 2755 | - $callback_args |
|
| 2756 | - ); |
|
| 2757 | - } |
|
| 2758 | - |
|
| 2759 | - |
|
| 2760 | - /** |
|
| 2761 | - * generates HTML wrapper for and admin details page that contains metaboxes in columns |
|
| 2762 | - * |
|
| 2763 | - * @throws DomainException |
|
| 2764 | - * @throws EE_Error |
|
| 2765 | - */ |
|
| 2766 | - public function display_admin_page_with_metabox_columns() |
|
| 2767 | - { |
|
| 2768 | - $this->_template_args['post_body_content'] = $this->_template_args['admin_page_content']; |
|
| 2769 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 2770 | - $this->_column_template_path, |
|
| 2771 | - $this->_template_args, |
|
| 2772 | - true |
|
| 2773 | - ); |
|
| 2774 | - // the final wrapper |
|
| 2775 | - $this->admin_page_wrapper(); |
|
| 2776 | - } |
|
| 2777 | - |
|
| 2778 | - |
|
| 2779 | - /** |
|
| 2780 | - * generates HTML wrapper for an admin details page |
|
| 2781 | - * |
|
| 2782 | - * @return void |
|
| 2783 | - * @throws EE_Error |
|
| 2784 | - * @throws DomainException |
|
| 2785 | - */ |
|
| 2786 | - public function display_admin_page_with_sidebar() |
|
| 2787 | - { |
|
| 2788 | - $this->_display_admin_page(true); |
|
| 2789 | - } |
|
| 2790 | - |
|
| 2791 | - |
|
| 2792 | - /** |
|
| 2793 | - * generates HTML wrapper for an admin details page (except no sidebar) |
|
| 2794 | - * |
|
| 2795 | - * @return void |
|
| 2796 | - * @throws EE_Error |
|
| 2797 | - * @throws DomainException |
|
| 2798 | - */ |
|
| 2799 | - public function display_admin_page_with_no_sidebar() |
|
| 2800 | - { |
|
| 2801 | - $this->_display_admin_page(); |
|
| 2802 | - } |
|
| 2803 | - |
|
| 2804 | - |
|
| 2805 | - /** |
|
| 2806 | - * generates HTML wrapper for an EE about admin page (no sidebar) |
|
| 2807 | - * |
|
| 2808 | - * @return void |
|
| 2809 | - * @throws EE_Error |
|
| 2810 | - * @throws DomainException |
|
| 2811 | - */ |
|
| 2812 | - public function display_about_admin_page() |
|
| 2813 | - { |
|
| 2814 | - $this->_display_admin_page(false, true); |
|
| 2815 | - } |
|
| 2816 | - |
|
| 2817 | - |
|
| 2818 | - /** |
|
| 2819 | - * display_admin_page |
|
| 2820 | - * contains the code for actually displaying an admin page |
|
| 2821 | - * |
|
| 2822 | - * @param boolean $sidebar true with sidebar, false without |
|
| 2823 | - * @param boolean $about use the about admin wrapper instead of the default. |
|
| 2824 | - * @return void |
|
| 2825 | - * @throws DomainException |
|
| 2826 | - * @throws EE_Error |
|
| 2827 | - */ |
|
| 2828 | - private function _display_admin_page($sidebar = false, $about = false) |
|
| 2829 | - { |
|
| 2830 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2831 | - // custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages. |
|
| 2832 | - do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes'); |
|
| 2833 | - // set current wp page slug - looks like: event-espresso_page_event_categories |
|
| 2834 | - // keep in mind "event-espresso" COULD be something else if the top level menu label has been translated. |
|
| 2835 | - $this->_template_args['current_page'] = $this->_wp_page_slug; |
|
| 2836 | - $this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route |
|
| 2837 | - ? 'poststuff' |
|
| 2838 | - : 'espresso-default-admin'; |
|
| 2839 | - $template_path = $sidebar |
|
| 2840 | - ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php' |
|
| 2841 | - : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php'; |
|
| 2842 | - if (defined('DOING_AJAX') && DOING_AJAX) { |
|
| 2843 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php'; |
|
| 2844 | - } |
|
| 2845 | - $template_path = ! empty($this->_column_template_path) |
|
| 2846 | - ? $this->_column_template_path : $template_path; |
|
| 2847 | - $this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content']) |
|
| 2848 | - ? $this->_template_args['admin_page_content'] |
|
| 2849 | - : ''; |
|
| 2850 | - $this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content']) |
|
| 2851 | - ? $this->_template_args['before_admin_page_content'] |
|
| 2852 | - : ''; |
|
| 2853 | - $this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content']) |
|
| 2854 | - ? $this->_template_args['after_admin_page_content'] |
|
| 2855 | - : ''; |
|
| 2856 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 2857 | - $template_path, |
|
| 2858 | - $this->_template_args, |
|
| 2859 | - true |
|
| 2860 | - ); |
|
| 2861 | - // the final template wrapper |
|
| 2862 | - $this->admin_page_wrapper($about); |
|
| 2863 | - } |
|
| 2864 | - |
|
| 2865 | - |
|
| 2866 | - /** |
|
| 2867 | - * This is used to display caf preview pages. |
|
| 2868 | - * |
|
| 2869 | - * @since 4.3.2 |
|
| 2870 | - * @param string $utm_campaign_source what is the key used for google analytics link |
|
| 2871 | - * @param bool $display_sidebar whether to use the sidebar template or the full template for the page. TRUE |
|
| 2872 | - * = SHOW sidebar, FALSE = no sidebar. Default no sidebar. |
|
| 2873 | - * @return void |
|
| 2874 | - * @throws DomainException |
|
| 2875 | - * @throws EE_Error |
|
| 2876 | - * @throws InvalidArgumentException |
|
| 2877 | - * @throws InvalidDataTypeException |
|
| 2878 | - * @throws InvalidInterfaceException |
|
| 2879 | - */ |
|
| 2880 | - public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true) |
|
| 2881 | - { |
|
| 2882 | - // let's generate a default preview action button if there isn't one already present. |
|
| 2883 | - $this->_labels['buttons']['buy_now'] = esc_html__( |
|
| 2884 | - 'Upgrade to Event Espresso 4 Right Now', |
|
| 2885 | - 'event_espresso' |
|
| 2886 | - ); |
|
| 2887 | - $buy_now_url = add_query_arg( |
|
| 2888 | - array( |
|
| 2889 | - 'ee_ver' => 'ee4', |
|
| 2890 | - 'utm_source' => 'ee4_plugin_admin', |
|
| 2891 | - 'utm_medium' => 'link', |
|
| 2892 | - 'utm_campaign' => $utm_campaign_source, |
|
| 2893 | - 'utm_content' => 'buy_now_button', |
|
| 2894 | - ), |
|
| 2895 | - 'http://eventespresso.com/pricing/' |
|
| 2896 | - ); |
|
| 2897 | - $this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button']) |
|
| 2898 | - ? $this->get_action_link_or_button( |
|
| 2899 | - '', |
|
| 2900 | - 'buy_now', |
|
| 2901 | - array(), |
|
| 2902 | - 'button-primary button-large', |
|
| 2903 | - $buy_now_url, |
|
| 2904 | - true |
|
| 2905 | - ) |
|
| 2906 | - : $this->_template_args['preview_action_button']; |
|
| 2907 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 2908 | - EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php', |
|
| 2909 | - $this->_template_args, |
|
| 2910 | - true |
|
| 2911 | - ); |
|
| 2912 | - $this->_display_admin_page($display_sidebar); |
|
| 2913 | - } |
|
| 2914 | - |
|
| 2915 | - |
|
| 2916 | - /** |
|
| 2917 | - * display_admin_list_table_page_with_sidebar |
|
| 2918 | - * generates HTML wrapper for an admin_page with list_table |
|
| 2919 | - * |
|
| 2920 | - * @return void |
|
| 2921 | - * @throws EE_Error |
|
| 2922 | - * @throws DomainException |
|
| 2923 | - */ |
|
| 2924 | - public function display_admin_list_table_page_with_sidebar() |
|
| 2925 | - { |
|
| 2926 | - $this->_display_admin_list_table_page(true); |
|
| 2927 | - } |
|
| 2928 | - |
|
| 2929 | - |
|
| 2930 | - /** |
|
| 2931 | - * display_admin_list_table_page_with_no_sidebar |
|
| 2932 | - * generates HTML wrapper for an admin_page with list_table (but with no sidebar) |
|
| 2933 | - * |
|
| 2934 | - * @return void |
|
| 2935 | - * @throws EE_Error |
|
| 2936 | - * @throws DomainException |
|
| 2937 | - */ |
|
| 2938 | - public function display_admin_list_table_page_with_no_sidebar() |
|
| 2939 | - { |
|
| 2940 | - $this->_display_admin_list_table_page(); |
|
| 2941 | - } |
|
| 2942 | - |
|
| 2943 | - |
|
| 2944 | - /** |
|
| 2945 | - * generates html wrapper for an admin_list_table page |
|
| 2946 | - * |
|
| 2947 | - * @param boolean $sidebar whether to display with sidebar or not. |
|
| 2948 | - * @return void |
|
| 2949 | - * @throws DomainException |
|
| 2950 | - * @throws EE_Error |
|
| 2951 | - */ |
|
| 2952 | - private function _display_admin_list_table_page($sidebar = false) |
|
| 2953 | - { |
|
| 2954 | - // setup search attributes |
|
| 2955 | - $this->_set_search_attributes(); |
|
| 2956 | - $this->_template_args['current_page'] = $this->_wp_page_slug; |
|
| 2957 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php'; |
|
| 2958 | - $this->_template_args['table_url'] = defined('DOING_AJAX') |
|
| 2959 | - ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url) |
|
| 2960 | - : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url); |
|
| 2961 | - $this->_template_args['list_table'] = $this->_list_table_object; |
|
| 2962 | - $this->_template_args['current_route'] = $this->_req_action; |
|
| 2963 | - $this->_template_args['list_table_class'] = get_class($this->_list_table_object); |
|
| 2964 | - $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback(); |
|
| 2965 | - if (! empty($ajax_sorting_callback)) { |
|
| 2966 | - $sortable_list_table_form_fields = wp_nonce_field( |
|
| 2967 | - $ajax_sorting_callback . '_nonce', |
|
| 2968 | - $ajax_sorting_callback . '_nonce', |
|
| 2969 | - false, |
|
| 2970 | - false |
|
| 2971 | - ); |
|
| 2972 | - $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="' |
|
| 2973 | - . $this->page_slug |
|
| 2974 | - . '" />'; |
|
| 2975 | - $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="' |
|
| 2976 | - . $ajax_sorting_callback |
|
| 2977 | - . '" />'; |
|
| 2978 | - } else { |
|
| 2979 | - $sortable_list_table_form_fields = ''; |
|
| 2980 | - } |
|
| 2981 | - $this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields; |
|
| 2982 | - $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields']) |
|
| 2983 | - ? $this->_template_args['list_table_hidden_fields'] |
|
| 2984 | - : ''; |
|
| 2985 | - $nonce_ref = $this->_req_action . '_nonce'; |
|
| 2986 | - $hidden_form_fields .= '<input type="hidden" name="' |
|
| 2987 | - . $nonce_ref |
|
| 2988 | - . '" value="' |
|
| 2989 | - . wp_create_nonce($nonce_ref) |
|
| 2990 | - . '">'; |
|
| 2991 | - $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields; |
|
| 2992 | - // display message about search results? |
|
| 2993 | - $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s']) |
|
| 2994 | - ? '<p class="ee-search-results">' . sprintf( |
|
| 2995 | - esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'), |
|
| 2996 | - trim($this->_req_data['s'], '%') |
|
| 2997 | - ) . '</p>' |
|
| 2998 | - : ''; |
|
| 2999 | - // filter before_list_table template arg |
|
| 3000 | - $this->_template_args['before_list_table'] = apply_filters( |
|
| 3001 | - 'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg', |
|
| 3002 | - $this->_template_args['before_list_table'], |
|
| 3003 | - $this->page_slug, |
|
| 3004 | - $this->_req_data, |
|
| 3005 | - $this->_req_action |
|
| 3006 | - ); |
|
| 3007 | - // convert to array and filter again |
|
| 3008 | - // arrays are easier to inject new items in a specific location, |
|
| 3009 | - // but would not be backwards compatible, so we have to add a new filter |
|
| 3010 | - $this->_template_args['before_list_table'] = implode( |
|
| 3011 | - " \n", |
|
| 3012 | - (array) apply_filters( |
|
| 3013 | - 'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array', |
|
| 3014 | - (array) $this->_template_args['before_list_table'], |
|
| 3015 | - $this->page_slug, |
|
| 3016 | - $this->_req_data, |
|
| 3017 | - $this->_req_action |
|
| 3018 | - ) |
|
| 3019 | - ); |
|
| 3020 | - // filter after_list_table template arg |
|
| 3021 | - $this->_template_args['after_list_table'] = apply_filters( |
|
| 3022 | - 'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg', |
|
| 3023 | - $this->_template_args['after_list_table'], |
|
| 3024 | - $this->page_slug, |
|
| 3025 | - $this->_req_data, |
|
| 3026 | - $this->_req_action |
|
| 3027 | - ); |
|
| 3028 | - // convert to array and filter again |
|
| 3029 | - // arrays are easier to inject new items in a specific location, |
|
| 3030 | - // but would not be backwards compatible, so we have to add a new filter |
|
| 3031 | - $this->_template_args['after_list_table'] = implode( |
|
| 3032 | - " \n", |
|
| 3033 | - (array) apply_filters( |
|
| 3034 | - 'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array', |
|
| 3035 | - (array) $this->_template_args['after_list_table'], |
|
| 3036 | - $this->page_slug, |
|
| 3037 | - $this->_req_data, |
|
| 3038 | - $this->_req_action |
|
| 3039 | - ) |
|
| 3040 | - ); |
|
| 3041 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 3042 | - $template_path, |
|
| 3043 | - $this->_template_args, |
|
| 3044 | - true |
|
| 3045 | - ); |
|
| 3046 | - // the final template wrapper |
|
| 3047 | - if ($sidebar) { |
|
| 3048 | - $this->display_admin_page_with_sidebar(); |
|
| 3049 | - } else { |
|
| 3050 | - $this->display_admin_page_with_no_sidebar(); |
|
| 3051 | - } |
|
| 3052 | - } |
|
| 3053 | - |
|
| 3054 | - |
|
| 3055 | - /** |
|
| 3056 | - * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the |
|
| 3057 | - * html string for the legend. |
|
| 3058 | - * $items are expected in an array in the following format: |
|
| 3059 | - * $legend_items = array( |
|
| 3060 | - * 'item_id' => array( |
|
| 3061 | - * 'icon' => 'http://url_to_icon_being_described.png', |
|
| 3062 | - * 'desc' => esc_html__('localized description of item'); |
|
| 3063 | - * ) |
|
| 3064 | - * ); |
|
| 3065 | - * |
|
| 3066 | - * @param array $items see above for format of array |
|
| 3067 | - * @return string html string of legend |
|
| 3068 | - * @throws DomainException |
|
| 3069 | - */ |
|
| 3070 | - protected function _display_legend($items) |
|
| 3071 | - { |
|
| 3072 | - $this->_template_args['items'] = apply_filters( |
|
| 3073 | - 'FHEE__EE_Admin_Page___display_legend__items', |
|
| 3074 | - (array) $items, |
|
| 3075 | - $this |
|
| 3076 | - ); |
|
| 3077 | - return EEH_Template::display_template( |
|
| 3078 | - EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php', |
|
| 3079 | - $this->_template_args, |
|
| 3080 | - true |
|
| 3081 | - ); |
|
| 3082 | - } |
|
| 3083 | - |
|
| 3084 | - |
|
| 3085 | - /** |
|
| 3086 | - * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect |
|
| 3087 | - * The returned json object is created from an array in the following format: |
|
| 3088 | - * array( |
|
| 3089 | - * 'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early), |
|
| 3090 | - * 'success' => FALSE, //(default FALSE) - contains any special success message. |
|
| 3091 | - * 'notices' => '', // - contains any EE_Error formatted notices |
|
| 3092 | - * 'content' => 'string can be html', //this is a string of formatted content (can be html) |
|
| 3093 | - * 'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js. |
|
| 3094 | - * We're also going to include the template args with every package (so js can pick out any specific template args |
|
| 3095 | - * that might be included in here) |
|
| 3096 | - * ) |
|
| 3097 | - * The json object is populated by whatever is set in the $_template_args property. |
|
| 3098 | - * |
|
| 3099 | - * @param bool $sticky_notices Used to indicate whether you want to ensure notices are added to a transient |
|
| 3100 | - * instead of displayed. |
|
| 3101 | - * @param array $notices_arguments Use this to pass any additional args on to the _process_notices. |
|
| 3102 | - * @return void |
|
| 3103 | - * @throws EE_Error |
|
| 3104 | - */ |
|
| 3105 | - protected function _return_json($sticky_notices = false, $notices_arguments = array()) |
|
| 3106 | - { |
|
| 3107 | - // make sure any EE_Error notices have been handled. |
|
| 3108 | - $this->_process_notices($notices_arguments, true, $sticky_notices); |
|
| 3109 | - $data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array(); |
|
| 3110 | - unset($this->_template_args['data']); |
|
| 3111 | - $json = array( |
|
| 3112 | - 'error' => isset($this->_template_args['error']) ? $this->_template_args['error'] : false, |
|
| 3113 | - 'success' => isset($this->_template_args['success']) ? $this->_template_args['success'] : false, |
|
| 3114 | - 'errors' => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false, |
|
| 3115 | - 'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false, |
|
| 3116 | - 'notices' => EE_Error::get_notices(), |
|
| 3117 | - 'content' => isset($this->_template_args['admin_page_content']) |
|
| 3118 | - ? $this->_template_args['admin_page_content'] : '', |
|
| 3119 | - 'data' => array_merge($data, array('template_args' => $this->_template_args)), |
|
| 3120 | - 'isEEajax' => true |
|
| 3121 | - // special flag so any ajax.Success methods in js can identify this return package as a EEajax package. |
|
| 3122 | - ); |
|
| 3123 | - // make sure there are no php errors or headers_sent. Then we can set correct json header. |
|
| 3124 | - if (null === error_get_last() || ! headers_sent()) { |
|
| 3125 | - header('Content-Type: application/json; charset=UTF-8'); |
|
| 3126 | - } |
|
| 3127 | - echo wp_json_encode($json); |
|
| 3128 | - exit(); |
|
| 3129 | - } |
|
| 3130 | - |
|
| 3131 | - |
|
| 3132 | - /** |
|
| 3133 | - * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax) |
|
| 3134 | - * |
|
| 3135 | - * @return void |
|
| 3136 | - * @throws EE_Error |
|
| 3137 | - */ |
|
| 3138 | - public function return_json() |
|
| 3139 | - { |
|
| 3140 | - if (defined('DOING_AJAX') && DOING_AJAX) { |
|
| 3141 | - $this->_return_json(); |
|
| 3142 | - } else { |
|
| 3143 | - throw new EE_Error( |
|
| 3144 | - sprintf( |
|
| 3145 | - esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'), |
|
| 3146 | - __FUNCTION__ |
|
| 3147 | - ) |
|
| 3148 | - ); |
|
| 3149 | - } |
|
| 3150 | - } |
|
| 3151 | - |
|
| 3152 | - |
|
| 3153 | - /** |
|
| 3154 | - * This provides a way for child hook classes to send along themselves by reference so methods/properties within |
|
| 3155 | - * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property. |
|
| 3156 | - * |
|
| 3157 | - * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child |
|
| 3158 | - */ |
|
| 3159 | - public function set_hook_object(EE_Admin_Hooks $hook_obj) |
|
| 3160 | - { |
|
| 3161 | - $this->_hook_obj = $hook_obj; |
|
| 3162 | - } |
|
| 3163 | - |
|
| 3164 | - |
|
| 3165 | - /** |
|
| 3166 | - * generates HTML wrapper with Tabbed nav for an admin page |
|
| 3167 | - * |
|
| 3168 | - * @param boolean $about whether to use the special about page wrapper or default. |
|
| 3169 | - * @return void |
|
| 3170 | - * @throws DomainException |
|
| 3171 | - * @throws EE_Error |
|
| 3172 | - */ |
|
| 3173 | - public function admin_page_wrapper($about = false) |
|
| 3174 | - { |
|
| 3175 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 3176 | - $this->_nav_tabs = $this->_get_main_nav_tabs(); |
|
| 3177 | - $this->_template_args['nav_tabs'] = $this->_nav_tabs; |
|
| 3178 | - $this->_template_args['admin_page_title'] = $this->_admin_page_title; |
|
| 3179 | - $this->_template_args['before_admin_page_content'] = apply_filters( |
|
| 3180 | - "FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}", |
|
| 3181 | - isset($this->_template_args['before_admin_page_content']) |
|
| 3182 | - ? $this->_template_args['before_admin_page_content'] |
|
| 3183 | - : '' |
|
| 3184 | - ); |
|
| 3185 | - $this->_template_args['after_admin_page_content'] = apply_filters( |
|
| 3186 | - "FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}", |
|
| 3187 | - isset($this->_template_args['after_admin_page_content']) |
|
| 3188 | - ? $this->_template_args['after_admin_page_content'] |
|
| 3189 | - : '' |
|
| 3190 | - ); |
|
| 3191 | - $this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content(); |
|
| 3192 | - // load settings page wrapper template |
|
| 3193 | - $template_path = ! defined('DOING_AJAX') |
|
| 3194 | - ? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php' |
|
| 3195 | - : EE_ADMIN_TEMPLATE |
|
| 3196 | - . 'admin_wrapper_ajax.template.php'; |
|
| 3197 | - // about page? |
|
| 3198 | - $template_path = $about |
|
| 3199 | - ? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php' |
|
| 3200 | - : $template_path; |
|
| 3201 | - if (defined('DOING_AJAX')) { |
|
| 3202 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 3203 | - $template_path, |
|
| 3204 | - $this->_template_args, |
|
| 3205 | - true |
|
| 3206 | - ); |
|
| 3207 | - $this->_return_json(); |
|
| 3208 | - } else { |
|
| 3209 | - EEH_Template::display_template($template_path, $this->_template_args); |
|
| 3210 | - } |
|
| 3211 | - } |
|
| 3212 | - |
|
| 3213 | - |
|
| 3214 | - /** |
|
| 3215 | - * This returns the admin_nav tabs html using the configuration in the _nav_tabs property |
|
| 3216 | - * |
|
| 3217 | - * @return string html |
|
| 3218 | - * @throws EE_Error |
|
| 3219 | - */ |
|
| 3220 | - protected function _get_main_nav_tabs() |
|
| 3221 | - { |
|
| 3222 | - // let's generate the html using the EEH_Tabbed_Content helper. |
|
| 3223 | - // We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute |
|
| 3224 | - // (rather than setting in the page_routes array) |
|
| 3225 | - return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs); |
|
| 3226 | - } |
|
| 3227 | - |
|
| 3228 | - |
|
| 3229 | - /** |
|
| 3230 | - * sort nav tabs |
|
| 3231 | - * |
|
| 3232 | - * @param $a |
|
| 3233 | - * @param $b |
|
| 3234 | - * @return int |
|
| 3235 | - */ |
|
| 3236 | - private function _sort_nav_tabs($a, $b) |
|
| 3237 | - { |
|
| 3238 | - if ($a['order'] === $b['order']) { |
|
| 3239 | - return 0; |
|
| 3240 | - } |
|
| 3241 | - return ($a['order'] < $b['order']) ? -1 : 1; |
|
| 3242 | - } |
|
| 3243 | - |
|
| 3244 | - |
|
| 3245 | - /** |
|
| 3246 | - * generates HTML for the forms used on admin pages |
|
| 3247 | - * |
|
| 3248 | - * @param array $input_vars - array of input field details |
|
| 3249 | - * @param string $generator (options are 'string' or 'array', basically use this to indicate which generator to |
|
| 3250 | - * use) |
|
| 3251 | - * @param bool $id |
|
| 3252 | - * @return string |
|
| 3253 | - * @uses EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php) |
|
| 3254 | - * @uses EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php) |
|
| 3255 | - */ |
|
| 3256 | - protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false) |
|
| 3257 | - { |
|
| 3258 | - $content = $generator === 'string' |
|
| 3259 | - ? EEH_Form_Fields::get_form_fields($input_vars, $id) |
|
| 3260 | - : EEH_Form_Fields::get_form_fields_array($input_vars); |
|
| 3261 | - return $content; |
|
| 3262 | - } |
|
| 3263 | - |
|
| 3264 | - |
|
| 3265 | - /** |
|
| 3266 | - * generates the "Save" and "Save & Close" buttons for edit forms |
|
| 3267 | - * |
|
| 3268 | - * @param bool $both if true then both buttons will be generated. If false then just the "Save & |
|
| 3269 | - * Close" button. |
|
| 3270 | - * @param array $text if included, generator will use the given text for the buttons ( array([0] => |
|
| 3271 | - * 'Save', [1] => 'save & close') |
|
| 3272 | - * @param array $actions if included allows us to set the actions that each button will carry out (i.e. |
|
| 3273 | - * via the "name" value in the button). We can also use this to just dump |
|
| 3274 | - * default actions by submitting some other value. |
|
| 3275 | - * @param bool|string|null $referrer if false then we just do the default action on save and close. Other wise it |
|
| 3276 | - * will use the $referrer string. IF null, then we don't do ANYTHING on save and |
|
| 3277 | - * close (normal form handling). |
|
| 3278 | - */ |
|
| 3279 | - protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null) |
|
| 3280 | - { |
|
| 3281 | - // make sure $text and $actions are in an array |
|
| 3282 | - $text = (array) $text; |
|
| 3283 | - $actions = (array) $actions; |
|
| 3284 | - $referrer_url = empty($referrer) |
|
| 3285 | - ? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="' |
|
| 3286 | - . $_SERVER['REQUEST_URI'] |
|
| 3287 | - . '" />' |
|
| 3288 | - : '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="' |
|
| 3289 | - . $referrer |
|
| 3290 | - . '" />'; |
|
| 3291 | - $button_text = ! empty($text) |
|
| 3292 | - ? $text |
|
| 3293 | - : array( |
|
| 3294 | - esc_html__('Save', 'event_espresso'), |
|
| 3295 | - esc_html__('Save and Close', 'event_espresso'), |
|
| 3296 | - ); |
|
| 3297 | - $default_names = array('save', 'save_and_close'); |
|
| 3298 | - // add in a hidden index for the current page (so save and close redirects properly) |
|
| 3299 | - $this->_template_args['save_buttons'] = $referrer_url; |
|
| 3300 | - foreach ($button_text as $key => $button) { |
|
| 3301 | - $ref = $default_names[ $key ]; |
|
| 3302 | - $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary ' |
|
| 3303 | - . $ref |
|
| 3304 | - . '" value="' |
|
| 3305 | - . $button |
|
| 3306 | - . '" name="' |
|
| 3307 | - . (! empty($actions) ? $actions[ $key ] : $ref) |
|
| 3308 | - . '" id="' |
|
| 3309 | - . $this->_current_view . '_' . $ref |
|
| 3310 | - . '" />'; |
|
| 3311 | - if (! $both) { |
|
| 3312 | - break; |
|
| 3313 | - } |
|
| 3314 | - } |
|
| 3315 | - } |
|
| 3316 | - |
|
| 3317 | - |
|
| 3318 | - /** |
|
| 3319 | - * Wrapper for the protected function. Allows plugins/addons to call this to set the form tags. |
|
| 3320 | - * |
|
| 3321 | - * @see $this->_set_add_edit_form_tags() for details on params |
|
| 3322 | - * @since 4.6.0 |
|
| 3323 | - * @param string $route |
|
| 3324 | - * @param array $additional_hidden_fields |
|
| 3325 | - */ |
|
| 3326 | - public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array()) |
|
| 3327 | - { |
|
| 3328 | - $this->_set_add_edit_form_tags($route, $additional_hidden_fields); |
|
| 3329 | - } |
|
| 3330 | - |
|
| 3331 | - |
|
| 3332 | - /** |
|
| 3333 | - * set form open and close tags on add/edit pages. |
|
| 3334 | - * |
|
| 3335 | - * @param string $route the route you want the form to direct to |
|
| 3336 | - * @param array $additional_hidden_fields any additional hidden fields required in the form header |
|
| 3337 | - * @return void |
|
| 3338 | - */ |
|
| 3339 | - protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array()) |
|
| 3340 | - { |
|
| 3341 | - if (empty($route)) { |
|
| 3342 | - $user_msg = esc_html__( |
|
| 3343 | - 'An error occurred. No action was set for this page\'s form.', |
|
| 3344 | - 'event_espresso' |
|
| 3345 | - ); |
|
| 3346 | - $dev_msg = $user_msg . "\n" |
|
| 3347 | - . sprintf( |
|
| 3348 | - esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'), |
|
| 3349 | - __FUNCTION__, |
|
| 3350 | - __CLASS__ |
|
| 3351 | - ); |
|
| 3352 | - EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 3353 | - } |
|
| 3354 | - // open form |
|
| 3355 | - $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="' |
|
| 3356 | - . $this->_admin_base_url |
|
| 3357 | - . '" id="' |
|
| 3358 | - . $route |
|
| 3359 | - . '_event_form" >'; |
|
| 3360 | - // add nonce |
|
| 3361 | - $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false); |
|
| 3362 | - $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce; |
|
| 3363 | - // add REQUIRED form action |
|
| 3364 | - $hidden_fields = array( |
|
| 3365 | - 'action' => array('type' => 'hidden', 'value' => $route), |
|
| 3366 | - ); |
|
| 3367 | - // merge arrays |
|
| 3368 | - $hidden_fields = is_array($additional_hidden_fields) |
|
| 3369 | - ? array_merge($hidden_fields, $additional_hidden_fields) |
|
| 3370 | - : $hidden_fields; |
|
| 3371 | - // generate form fields |
|
| 3372 | - $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array'); |
|
| 3373 | - // add fields to form |
|
| 3374 | - foreach ((array) $form_fields as $field_name => $form_field) { |
|
| 3375 | - $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field']; |
|
| 3376 | - } |
|
| 3377 | - // close form |
|
| 3378 | - $this->_template_args['after_admin_page_content'] = '</form>'; |
|
| 3379 | - } |
|
| 3380 | - |
|
| 3381 | - |
|
| 3382 | - /** |
|
| 3383 | - * Public Wrapper for _redirect_after_action() method since its |
|
| 3384 | - * discovered it would be useful for external code to have access. |
|
| 3385 | - * |
|
| 3386 | - * @see EE_Admin_Page::_redirect_after_action() for params. |
|
| 3387 | - * @since 4.5.0 |
|
| 3388 | - * @param bool $success |
|
| 3389 | - * @param string $what |
|
| 3390 | - * @param string $action_desc |
|
| 3391 | - * @param array $query_args |
|
| 3392 | - * @param bool $override_overwrite |
|
| 3393 | - * @throws EE_Error |
|
| 3394 | - */ |
|
| 3395 | - public function redirect_after_action( |
|
| 3396 | - $success = false, |
|
| 3397 | - $what = 'item', |
|
| 3398 | - $action_desc = 'processed', |
|
| 3399 | - $query_args = array(), |
|
| 3400 | - $override_overwrite = false |
|
| 3401 | - ) { |
|
| 3402 | - $this->_redirect_after_action( |
|
| 3403 | - $success, |
|
| 3404 | - $what, |
|
| 3405 | - $action_desc, |
|
| 3406 | - $query_args, |
|
| 3407 | - $override_overwrite |
|
| 3408 | - ); |
|
| 3409 | - } |
|
| 3410 | - |
|
| 3411 | - |
|
| 3412 | - /** |
|
| 3413 | - * Helper method for merging existing request data with the returned redirect url. |
|
| 3414 | - * |
|
| 3415 | - * This is typically used for redirects after an action so that if the original view was a filtered view those |
|
| 3416 | - * filters are still applied. |
|
| 3417 | - * |
|
| 3418 | - * @param array $new_route_data |
|
| 3419 | - * @return array |
|
| 3420 | - */ |
|
| 3421 | - protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data) |
|
| 3422 | - { |
|
| 3423 | - foreach ($this->_req_data as $ref => $value) { |
|
| 3424 | - // unset nonces |
|
| 3425 | - if (strpos($ref, 'nonce') !== false) { |
|
| 3426 | - unset($this->_req_data[ $ref ]); |
|
| 3427 | - continue; |
|
| 3428 | - } |
|
| 3429 | - // urlencode values. |
|
| 3430 | - $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value); |
|
| 3431 | - $this->_req_data[ $ref ] = $value; |
|
| 3432 | - } |
|
| 3433 | - return array_merge($this->_req_data, $new_route_data); |
|
| 3434 | - } |
|
| 3435 | - |
|
| 3436 | - |
|
| 3437 | - /** |
|
| 3438 | - * _redirect_after_action |
|
| 3439 | - * |
|
| 3440 | - * @param int $success - whether success was for two or more records, or just one, or none |
|
| 3441 | - * @param string $what - what the action was performed on |
|
| 3442 | - * @param string $action_desc - what was done ie: updated, deleted, etc |
|
| 3443 | - * @param array $query_args - an array of query_args to be added to the URL to redirect to after the admin |
|
| 3444 | - * action is completed |
|
| 3445 | - * @param BOOL $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to |
|
| 3446 | - * override this so that they show. |
|
| 3447 | - * @return void |
|
| 3448 | - * @throws EE_Error |
|
| 3449 | - */ |
|
| 3450 | - protected function _redirect_after_action( |
|
| 3451 | - $success = 0, |
|
| 3452 | - $what = 'item', |
|
| 3453 | - $action_desc = 'processed', |
|
| 3454 | - $query_args = array(), |
|
| 3455 | - $override_overwrite = false |
|
| 3456 | - ) { |
|
| 3457 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 3458 | - // class name for actions/filters. |
|
| 3459 | - $classname = get_class($this); |
|
| 3460 | - // set redirect url. |
|
| 3461 | - // Note if there is a "page" index in the $query_args then we go with vanilla admin.php route, |
|
| 3462 | - // otherwise we go with whatever is set as the _admin_base_url |
|
| 3463 | - $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url; |
|
| 3464 | - $notices = EE_Error::get_notices(false); |
|
| 3465 | - // overwrite default success messages //BUT ONLY if overwrite not overridden |
|
| 3466 | - if (! $override_overwrite || ! empty($notices['errors'])) { |
|
| 3467 | - EE_Error::overwrite_success(); |
|
| 3468 | - } |
|
| 3469 | - if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) { |
|
| 3470 | - // how many records affected ? more than one record ? or just one ? |
|
| 3471 | - if ($success > 1) { |
|
| 3472 | - // set plural msg |
|
| 3473 | - EE_Error::add_success( |
|
| 3474 | - sprintf( |
|
| 3475 | - esc_html__('The "%s" have been successfully %s.', 'event_espresso'), |
|
| 3476 | - $what, |
|
| 3477 | - $action_desc |
|
| 3478 | - ), |
|
| 3479 | - __FILE__, |
|
| 3480 | - __FUNCTION__, |
|
| 3481 | - __LINE__ |
|
| 3482 | - ); |
|
| 3483 | - } elseif ($success === 1) { |
|
| 3484 | - // set singular msg |
|
| 3485 | - EE_Error::add_success( |
|
| 3486 | - sprintf( |
|
| 3487 | - esc_html__('The "%s" has been successfully %s.', 'event_espresso'), |
|
| 3488 | - $what, |
|
| 3489 | - $action_desc |
|
| 3490 | - ), |
|
| 3491 | - __FILE__, |
|
| 3492 | - __FUNCTION__, |
|
| 3493 | - __LINE__ |
|
| 3494 | - ); |
|
| 3495 | - } |
|
| 3496 | - } |
|
| 3497 | - // check that $query_args isn't something crazy |
|
| 3498 | - if (! is_array($query_args)) { |
|
| 3499 | - $query_args = array(); |
|
| 3500 | - } |
|
| 3501 | - /** |
|
| 3502 | - * Allow injecting actions before the query_args are modified for possible different |
|
| 3503 | - * redirections on save and close actions |
|
| 3504 | - * |
|
| 3505 | - * @since 4.2.0 |
|
| 3506 | - * @param array $query_args The original query_args array coming into the |
|
| 3507 | - * method. |
|
| 3508 | - */ |
|
| 3509 | - do_action( |
|
| 3510 | - "AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}", |
|
| 3511 | - $query_args |
|
| 3512 | - ); |
|
| 3513 | - // calculate where we're going (if we have a "save and close" button pushed) |
|
| 3514 | - if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) { |
|
| 3515 | - // even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce |
|
| 3516 | - $parsed_url = parse_url($this->_req_data['save_and_close_referrer']); |
|
| 3517 | - // regenerate query args array from referrer URL |
|
| 3518 | - parse_str($parsed_url['query'], $query_args); |
|
| 3519 | - // correct page and action will be in the query args now |
|
| 3520 | - $redirect_url = admin_url('admin.php'); |
|
| 3521 | - } |
|
| 3522 | - // merge any default query_args set in _default_route_query_args property |
|
| 3523 | - if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) { |
|
| 3524 | - $args_to_merge = array(); |
|
| 3525 | - foreach ($this->_default_route_query_args as $query_param => $query_value) { |
|
| 3526 | - // is there a wp_referer array in our _default_route_query_args property? |
|
| 3527 | - if ($query_param === 'wp_referer') { |
|
| 3528 | - $query_value = (array) $query_value; |
|
| 3529 | - foreach ($query_value as $reference => $value) { |
|
| 3530 | - if (strpos($reference, 'nonce') !== false) { |
|
| 3531 | - continue; |
|
| 3532 | - } |
|
| 3533 | - // finally we will override any arguments in the referer with |
|
| 3534 | - // what might be set on the _default_route_query_args array. |
|
| 3535 | - if (isset($this->_default_route_query_args[ $reference ])) { |
|
| 3536 | - $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]); |
|
| 3537 | - } else { |
|
| 3538 | - $args_to_merge[ $reference ] = urlencode($value); |
|
| 3539 | - } |
|
| 3540 | - } |
|
| 3541 | - continue; |
|
| 3542 | - } |
|
| 3543 | - $args_to_merge[ $query_param ] = $query_value; |
|
| 3544 | - } |
|
| 3545 | - // now let's merge these arguments but override with what was specifically sent in to the |
|
| 3546 | - // redirect. |
|
| 3547 | - $query_args = array_merge($args_to_merge, $query_args); |
|
| 3548 | - } |
|
| 3549 | - $this->_process_notices($query_args); |
|
| 3550 | - // generate redirect url |
|
| 3551 | - // if redirecting to anything other than the main page, add a nonce |
|
| 3552 | - if (isset($query_args['action'])) { |
|
| 3553 | - // manually generate wp_nonce and merge that with the query vars |
|
| 3554 | - // becuz the wp_nonce_url function wrecks havoc on some vars |
|
| 3555 | - $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce'); |
|
| 3556 | - } |
|
| 3557 | - // we're adding some hooks and filters in here for processing any things just before redirects |
|
| 3558 | - // (example: an admin page has done an insert or update and we want to run something after that). |
|
| 3559 | - do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args); |
|
| 3560 | - $redirect_url = apply_filters( |
|
| 3561 | - 'FHEE_redirect_' . $classname . $this->_req_action, |
|
| 3562 | - self::add_query_args_and_nonce($query_args, $redirect_url), |
|
| 3563 | - $query_args |
|
| 3564 | - ); |
|
| 3565 | - // check if we're doing ajax. If we are then lets just return the results and js can handle how it wants. |
|
| 3566 | - if (defined('DOING_AJAX')) { |
|
| 3567 | - $default_data = array( |
|
| 3568 | - 'close' => true, |
|
| 3569 | - 'redirect_url' => $redirect_url, |
|
| 3570 | - 'where' => 'main', |
|
| 3571 | - 'what' => 'append', |
|
| 3572 | - ); |
|
| 3573 | - $this->_template_args['success'] = $success; |
|
| 3574 | - $this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge( |
|
| 3575 | - $default_data, |
|
| 3576 | - $this->_template_args['data'] |
|
| 3577 | - ) : $default_data; |
|
| 3578 | - $this->_return_json(); |
|
| 3579 | - } |
|
| 3580 | - wp_safe_redirect($redirect_url); |
|
| 3581 | - exit(); |
|
| 3582 | - } |
|
| 3583 | - |
|
| 3584 | - |
|
| 3585 | - /** |
|
| 3586 | - * process any notices before redirecting (or returning ajax request) |
|
| 3587 | - * This method sets the $this->_template_args['notices'] attribute; |
|
| 3588 | - * |
|
| 3589 | - * @param array $query_args any query args that need to be used for notice transient ('action') |
|
| 3590 | - * @param bool $skip_route_verify This is typically used when we are processing notices REALLY early and |
|
| 3591 | - * page_routes haven't been defined yet. |
|
| 3592 | - * @param bool $sticky_notices This is used to flag that regardless of whether this is doing_ajax or not, we |
|
| 3593 | - * still save a transient for the notice. |
|
| 3594 | - * @return void |
|
| 3595 | - * @throws EE_Error |
|
| 3596 | - */ |
|
| 3597 | - protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true) |
|
| 3598 | - { |
|
| 3599 | - // first let's set individual error properties if doing_ajax and the properties aren't already set. |
|
| 3600 | - if (defined('DOING_AJAX') && DOING_AJAX) { |
|
| 3601 | - $notices = EE_Error::get_notices(false); |
|
| 3602 | - if (empty($this->_template_args['success'])) { |
|
| 3603 | - $this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false; |
|
| 3604 | - } |
|
| 3605 | - if (empty($this->_template_args['errors'])) { |
|
| 3606 | - $this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false; |
|
| 3607 | - } |
|
| 3608 | - if (empty($this->_template_args['attention'])) { |
|
| 3609 | - $this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false; |
|
| 3610 | - } |
|
| 3611 | - } |
|
| 3612 | - $this->_template_args['notices'] = EE_Error::get_notices(); |
|
| 3613 | - // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true) |
|
| 3614 | - if (! defined('DOING_AJAX') || $sticky_notices) { |
|
| 3615 | - $route = isset($query_args['action']) ? $query_args['action'] : 'default'; |
|
| 3616 | - $this->_add_transient( |
|
| 3617 | - $route, |
|
| 3618 | - $this->_template_args['notices'], |
|
| 3619 | - true, |
|
| 3620 | - $skip_route_verify |
|
| 3621 | - ); |
|
| 3622 | - } |
|
| 3623 | - } |
|
| 3624 | - |
|
| 3625 | - |
|
| 3626 | - /** |
|
| 3627 | - * get_action_link_or_button |
|
| 3628 | - * returns the button html for adding, editing, or deleting an item (depending on given type) |
|
| 3629 | - * |
|
| 3630 | - * @param string $action use this to indicate which action the url is generated with. |
|
| 3631 | - * @param string $type accepted strings must be defined in the $_labels['button'] array(as the key) |
|
| 3632 | - * property. |
|
| 3633 | - * @param array $extra_request if the button requires extra params you can include them in $key=>$value pairs. |
|
| 3634 | - * @param string $class Use this to give the class for the button. Defaults to 'button-primary' |
|
| 3635 | - * @param string $base_url If this is not provided |
|
| 3636 | - * the _admin_base_url will be used as the default for the button base_url. |
|
| 3637 | - * Otherwise this value will be used. |
|
| 3638 | - * @param bool $exclude_nonce If true then no nonce will be in the generated button link. |
|
| 3639 | - * @return string |
|
| 3640 | - * @throws InvalidArgumentException |
|
| 3641 | - * @throws InvalidInterfaceException |
|
| 3642 | - * @throws InvalidDataTypeException |
|
| 3643 | - * @throws EE_Error |
|
| 3644 | - */ |
|
| 3645 | - public function get_action_link_or_button( |
|
| 3646 | - $action, |
|
| 3647 | - $type = 'add', |
|
| 3648 | - $extra_request = array(), |
|
| 3649 | - $class = 'button-primary', |
|
| 3650 | - $base_url = '', |
|
| 3651 | - $exclude_nonce = false |
|
| 3652 | - ) { |
|
| 3653 | - // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along) |
|
| 3654 | - if (empty($base_url) && ! isset($this->_page_routes[ $action ])) { |
|
| 3655 | - throw new EE_Error( |
|
| 3656 | - sprintf( |
|
| 3657 | - esc_html__( |
|
| 3658 | - 'There is no page route for given action for the button. This action was given: %s', |
|
| 3659 | - 'event_espresso' |
|
| 3660 | - ), |
|
| 3661 | - $action |
|
| 3662 | - ) |
|
| 3663 | - ); |
|
| 3664 | - } |
|
| 3665 | - if (! isset($this->_labels['buttons'][ $type ])) { |
|
| 3666 | - throw new EE_Error( |
|
| 3667 | - sprintf( |
|
| 3668 | - __( |
|
| 3669 | - 'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.', |
|
| 3670 | - 'event_espresso' |
|
| 3671 | - ), |
|
| 3672 | - $type |
|
| 3673 | - ) |
|
| 3674 | - ); |
|
| 3675 | - } |
|
| 3676 | - // finally check user access for this button. |
|
| 3677 | - $has_access = $this->check_user_access($action, true); |
|
| 3678 | - if (! $has_access) { |
|
| 3679 | - return ''; |
|
| 3680 | - } |
|
| 3681 | - $_base_url = ! $base_url ? $this->_admin_base_url : $base_url; |
|
| 3682 | - $query_args = array( |
|
| 3683 | - 'action' => $action, |
|
| 3684 | - ); |
|
| 3685 | - // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten. |
|
| 3686 | - if (! empty($extra_request)) { |
|
| 3687 | - $query_args = array_merge($extra_request, $query_args); |
|
| 3688 | - } |
|
| 3689 | - $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce); |
|
| 3690 | - return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class); |
|
| 3691 | - } |
|
| 3692 | - |
|
| 3693 | - |
|
| 3694 | - /** |
|
| 3695 | - * _per_page_screen_option |
|
| 3696 | - * Utility function for adding in a per_page_option in the screen_options_dropdown. |
|
| 3697 | - * |
|
| 3698 | - * @return void |
|
| 3699 | - * @throws InvalidArgumentException |
|
| 3700 | - * @throws InvalidInterfaceException |
|
| 3701 | - * @throws InvalidDataTypeException |
|
| 3702 | - */ |
|
| 3703 | - protected function _per_page_screen_option() |
|
| 3704 | - { |
|
| 3705 | - $option = 'per_page'; |
|
| 3706 | - $args = array( |
|
| 3707 | - 'label' => apply_filters( |
|
| 3708 | - 'FHEE__EE_Admin_Page___per_page_screen_options___label', |
|
| 3709 | - $this->_admin_page_title, |
|
| 3710 | - $this |
|
| 3711 | - ), |
|
| 3712 | - 'default' => (int) apply_filters( |
|
| 3713 | - 'FHEE__EE_Admin_Page___per_page_screen_options__default', |
|
| 3714 | - 20 |
|
| 3715 | - ), |
|
| 3716 | - 'option' => $this->_current_page . '_' . $this->_current_view . '_per_page', |
|
| 3717 | - ); |
|
| 3718 | - // ONLY add the screen option if the user has access to it. |
|
| 3719 | - if ($this->check_user_access($this->_current_view, true)) { |
|
| 3720 | - add_screen_option($option, $args); |
|
| 3721 | - } |
|
| 3722 | - } |
|
| 3723 | - |
|
| 3724 | - |
|
| 3725 | - /** |
|
| 3726 | - * set_per_page_screen_option |
|
| 3727 | - * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page. |
|
| 3728 | - * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than |
|
| 3729 | - * admin_menu. |
|
| 3730 | - * |
|
| 3731 | - * @return void |
|
| 3732 | - */ |
|
| 3733 | - private function _set_per_page_screen_options() |
|
| 3734 | - { |
|
| 3735 | - if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) { |
|
| 3736 | - check_admin_referer('screen-options-nonce', 'screenoptionnonce'); |
|
| 3737 | - if (! $user = wp_get_current_user()) { |
|
| 3738 | - return; |
|
| 3739 | - } |
|
| 3740 | - $option = $_POST['wp_screen_options']['option']; |
|
| 3741 | - $value = $_POST['wp_screen_options']['value']; |
|
| 3742 | - if ($option != sanitize_key($option)) { |
|
| 3743 | - return; |
|
| 3744 | - } |
|
| 3745 | - $map_option = $option; |
|
| 3746 | - $option = str_replace('-', '_', $option); |
|
| 3747 | - switch ($map_option) { |
|
| 3748 | - case $this->_current_page . '_' . $this->_current_view . '_per_page': |
|
| 3749 | - $value = (int) $value; |
|
| 3750 | - $max_value = apply_filters( |
|
| 3751 | - 'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value', |
|
| 3752 | - 999, |
|
| 3753 | - $this->_current_page, |
|
| 3754 | - $this->_current_view |
|
| 3755 | - ); |
|
| 3756 | - if ($value < 1) { |
|
| 3757 | - return; |
|
| 3758 | - } |
|
| 3759 | - $value = min($value, $max_value); |
|
| 3760 | - break; |
|
| 3761 | - default: |
|
| 3762 | - $value = apply_filters( |
|
| 3763 | - 'FHEE__EE_Admin_Page___set_per_page_screen_options__value', |
|
| 3764 | - false, |
|
| 3765 | - $option, |
|
| 3766 | - $value |
|
| 3767 | - ); |
|
| 3768 | - if (false === $value) { |
|
| 3769 | - return; |
|
| 3770 | - } |
|
| 3771 | - break; |
|
| 3772 | - } |
|
| 3773 | - update_user_meta($user->ID, $option, $value); |
|
| 3774 | - wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer())); |
|
| 3775 | - exit; |
|
| 3776 | - } |
|
| 3777 | - } |
|
| 3778 | - |
|
| 3779 | - |
|
| 3780 | - /** |
|
| 3781 | - * This just allows for setting the $_template_args property if it needs to be set outside the object |
|
| 3782 | - * |
|
| 3783 | - * @param array $data array that will be assigned to template args. |
|
| 3784 | - */ |
|
| 3785 | - public function set_template_args($data) |
|
| 3786 | - { |
|
| 3787 | - $this->_template_args = array_merge($this->_template_args, (array) $data); |
|
| 3788 | - } |
|
| 3789 | - |
|
| 3790 | - |
|
| 3791 | - /** |
|
| 3792 | - * This makes available the WP transient system for temporarily moving data between routes |
|
| 3793 | - * |
|
| 3794 | - * @param string $route the route that should receive the transient |
|
| 3795 | - * @param array $data the data that gets sent |
|
| 3796 | - * @param bool $notices If this is for notices then we use this to indicate so, otherwise its just a |
|
| 3797 | - * normal route transient. |
|
| 3798 | - * @param bool $skip_route_verify Used to indicate we want to skip route verification. This is usually ONLY used |
|
| 3799 | - * when we are adding a transient before page_routes have been defined. |
|
| 3800 | - * @return void |
|
| 3801 | - * @throws EE_Error |
|
| 3802 | - */ |
|
| 3803 | - protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false) |
|
| 3804 | - { |
|
| 3805 | - $user_id = get_current_user_id(); |
|
| 3806 | - if (! $skip_route_verify) { |
|
| 3807 | - $this->_verify_route($route); |
|
| 3808 | - } |
|
| 3809 | - // now let's set the string for what kind of transient we're setting |
|
| 3810 | - $transient = $notices |
|
| 3811 | - ? 'ee_rte_n_tx_' . $route . '_' . $user_id |
|
| 3812 | - : 'rte_tx_' . $route . '_' . $user_id; |
|
| 3813 | - $data = $notices ? array('notices' => $data) : $data; |
|
| 3814 | - // is there already a transient for this route? If there is then let's ADD to that transient |
|
| 3815 | - $existing = is_multisite() && is_network_admin() |
|
| 3816 | - ? get_site_transient($transient) |
|
| 3817 | - : get_transient($transient); |
|
| 3818 | - if ($existing) { |
|
| 3819 | - $data = array_merge((array) $data, (array) $existing); |
|
| 3820 | - } |
|
| 3821 | - if (is_multisite() && is_network_admin()) { |
|
| 3822 | - set_site_transient($transient, $data, 8); |
|
| 3823 | - } else { |
|
| 3824 | - set_transient($transient, $data, 8); |
|
| 3825 | - } |
|
| 3826 | - } |
|
| 3827 | - |
|
| 3828 | - |
|
| 3829 | - /** |
|
| 3830 | - * this retrieves the temporary transient that has been set for moving data between routes. |
|
| 3831 | - * |
|
| 3832 | - * @param bool $notices true we get notices transient. False we just return normal route transient |
|
| 3833 | - * @param string $route |
|
| 3834 | - * @return mixed data |
|
| 3835 | - */ |
|
| 3836 | - protected function _get_transient($notices = false, $route = '') |
|
| 3837 | - { |
|
| 3838 | - $user_id = get_current_user_id(); |
|
| 3839 | - $route = ! $route ? $this->_req_action : $route; |
|
| 3840 | - $transient = $notices |
|
| 3841 | - ? 'ee_rte_n_tx_' . $route . '_' . $user_id |
|
| 3842 | - : 'rte_tx_' . $route . '_' . $user_id; |
|
| 3843 | - $data = is_multisite() && is_network_admin() |
|
| 3844 | - ? get_site_transient($transient) |
|
| 3845 | - : get_transient($transient); |
|
| 3846 | - // delete transient after retrieval (just in case it hasn't expired); |
|
| 3847 | - if (is_multisite() && is_network_admin()) { |
|
| 3848 | - delete_site_transient($transient); |
|
| 3849 | - } else { |
|
| 3850 | - delete_transient($transient); |
|
| 3851 | - } |
|
| 3852 | - return $notices && isset($data['notices']) ? $data['notices'] : $data; |
|
| 3853 | - } |
|
| 3854 | - |
|
| 3855 | - |
|
| 3856 | - /** |
|
| 3857 | - * The purpose of this method is just to run garbage collection on any EE transients that might have expired but |
|
| 3858 | - * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the |
|
| 3859 | - * default route callback on the EE_Admin page you want it run.) |
|
| 3860 | - * |
|
| 3861 | - * @return void |
|
| 3862 | - */ |
|
| 3863 | - protected function _transient_garbage_collection() |
|
| 3864 | - { |
|
| 3865 | - global $wpdb; |
|
| 3866 | - // retrieve all existing transients |
|
| 3867 | - $query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'"; |
|
| 3868 | - if ($results = $wpdb->get_results($query)) { |
|
| 3869 | - foreach ($results as $result) { |
|
| 3870 | - $transient = str_replace('_transient_', '', $result->option_name); |
|
| 3871 | - get_transient($transient); |
|
| 3872 | - if (is_multisite() && is_network_admin()) { |
|
| 3873 | - get_site_transient($transient); |
|
| 3874 | - } |
|
| 3875 | - } |
|
| 3876 | - } |
|
| 3877 | - } |
|
| 3878 | - |
|
| 3879 | - |
|
| 3880 | - /** |
|
| 3881 | - * get_view |
|
| 3882 | - * |
|
| 3883 | - * @return string content of _view property |
|
| 3884 | - */ |
|
| 3885 | - public function get_view() |
|
| 3886 | - { |
|
| 3887 | - return $this->_view; |
|
| 3888 | - } |
|
| 3889 | - |
|
| 3890 | - |
|
| 3891 | - /** |
|
| 3892 | - * getter for the protected $_views property |
|
| 3893 | - * |
|
| 3894 | - * @return array |
|
| 3895 | - */ |
|
| 3896 | - public function get_views() |
|
| 3897 | - { |
|
| 3898 | - return $this->_views; |
|
| 3899 | - } |
|
| 3900 | - |
|
| 3901 | - |
|
| 3902 | - /** |
|
| 3903 | - * get_current_page |
|
| 3904 | - * |
|
| 3905 | - * @return string _current_page property value |
|
| 3906 | - */ |
|
| 3907 | - public function get_current_page() |
|
| 3908 | - { |
|
| 3909 | - return $this->_current_page; |
|
| 3910 | - } |
|
| 3911 | - |
|
| 3912 | - |
|
| 3913 | - /** |
|
| 3914 | - * get_current_view |
|
| 3915 | - * |
|
| 3916 | - * @return string _current_view property value |
|
| 3917 | - */ |
|
| 3918 | - public function get_current_view() |
|
| 3919 | - { |
|
| 3920 | - return $this->_current_view; |
|
| 3921 | - } |
|
| 3922 | - |
|
| 3923 | - |
|
| 3924 | - /** |
|
| 3925 | - * get_current_screen |
|
| 3926 | - * |
|
| 3927 | - * @return object The current WP_Screen object |
|
| 3928 | - */ |
|
| 3929 | - public function get_current_screen() |
|
| 3930 | - { |
|
| 3931 | - return $this->_current_screen; |
|
| 3932 | - } |
|
| 3933 | - |
|
| 3934 | - |
|
| 3935 | - /** |
|
| 3936 | - * get_current_page_view_url |
|
| 3937 | - * |
|
| 3938 | - * @return string This returns the url for the current_page_view. |
|
| 3939 | - */ |
|
| 3940 | - public function get_current_page_view_url() |
|
| 3941 | - { |
|
| 3942 | - return $this->_current_page_view_url; |
|
| 3943 | - } |
|
| 3944 | - |
|
| 3945 | - |
|
| 3946 | - /** |
|
| 3947 | - * just returns the _req_data property |
|
| 3948 | - * |
|
| 3949 | - * @return array |
|
| 3950 | - */ |
|
| 3951 | - public function get_request_data() |
|
| 3952 | - { |
|
| 3953 | - return $this->_req_data; |
|
| 3954 | - } |
|
| 3955 | - |
|
| 3956 | - |
|
| 3957 | - /** |
|
| 3958 | - * returns the _req_data protected property |
|
| 3959 | - * |
|
| 3960 | - * @return string |
|
| 3961 | - */ |
|
| 3962 | - public function get_req_action() |
|
| 3963 | - { |
|
| 3964 | - return $this->_req_action; |
|
| 3965 | - } |
|
| 3966 | - |
|
| 3967 | - |
|
| 3968 | - /** |
|
| 3969 | - * @return bool value of $_is_caf property |
|
| 3970 | - */ |
|
| 3971 | - public function is_caf() |
|
| 3972 | - { |
|
| 3973 | - return $this->_is_caf; |
|
| 3974 | - } |
|
| 3975 | - |
|
| 3976 | - |
|
| 3977 | - /** |
|
| 3978 | - * @return mixed |
|
| 3979 | - */ |
|
| 3980 | - public function default_espresso_metaboxes() |
|
| 3981 | - { |
|
| 3982 | - return $this->_default_espresso_metaboxes; |
|
| 3983 | - } |
|
| 3984 | - |
|
| 3985 | - |
|
| 3986 | - /** |
|
| 3987 | - * @return mixed |
|
| 3988 | - */ |
|
| 3989 | - public function admin_base_url() |
|
| 3990 | - { |
|
| 3991 | - return $this->_admin_base_url; |
|
| 3992 | - } |
|
| 3993 | - |
|
| 3994 | - |
|
| 3995 | - /** |
|
| 3996 | - * @return mixed |
|
| 3997 | - */ |
|
| 3998 | - public function wp_page_slug() |
|
| 3999 | - { |
|
| 4000 | - return $this->_wp_page_slug; |
|
| 4001 | - } |
|
| 4002 | - |
|
| 4003 | - |
|
| 4004 | - /** |
|
| 4005 | - * updates espresso configuration settings |
|
| 4006 | - * |
|
| 4007 | - * @param string $tab |
|
| 4008 | - * @param EE_Config_Base|EE_Config $config |
|
| 4009 | - * @param string $file file where error occurred |
|
| 4010 | - * @param string $func function where error occurred |
|
| 4011 | - * @param string $line line no where error occurred |
|
| 4012 | - * @return boolean |
|
| 4013 | - */ |
|
| 4014 | - protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '') |
|
| 4015 | - { |
|
| 4016 | - // remove any options that are NOT going to be saved with the config settings. |
|
| 4017 | - if (isset($config->core->ee_ueip_optin)) { |
|
| 4018 | - // TODO: remove the following two lines and make sure values are migrated from 3.1 |
|
| 4019 | - update_option('ee_ueip_optin', $config->core->ee_ueip_optin); |
|
| 4020 | - update_option('ee_ueip_has_notified', true); |
|
| 4021 | - } |
|
| 4022 | - // and save it (note we're also doing the network save here) |
|
| 4023 | - $net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true; |
|
| 4024 | - $config_saved = EE_Config::instance()->update_espresso_config(false, false); |
|
| 4025 | - if ($config_saved && $net_saved) { |
|
| 4026 | - EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab)); |
|
| 4027 | - return true; |
|
| 4028 | - } |
|
| 4029 | - EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line); |
|
| 4030 | - return false; |
|
| 4031 | - } |
|
| 4032 | - |
|
| 4033 | - |
|
| 4034 | - /** |
|
| 4035 | - * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument. |
|
| 4036 | - * |
|
| 4037 | - * @return array |
|
| 4038 | - */ |
|
| 4039 | - public function get_yes_no_values() |
|
| 4040 | - { |
|
| 4041 | - return $this->_yes_no_values; |
|
| 4042 | - } |
|
| 4043 | - |
|
| 4044 | - |
|
| 4045 | - protected function _get_dir() |
|
| 4046 | - { |
|
| 4047 | - $reflector = new ReflectionClass(get_class($this)); |
|
| 4048 | - return dirname($reflector->getFileName()); |
|
| 4049 | - } |
|
| 4050 | - |
|
| 4051 | - |
|
| 4052 | - /** |
|
| 4053 | - * A helper for getting a "next link". |
|
| 4054 | - * |
|
| 4055 | - * @param string $url The url to link to |
|
| 4056 | - * @param string $class The class to use. |
|
| 4057 | - * @return string |
|
| 4058 | - */ |
|
| 4059 | - protected function _next_link($url, $class = 'dashicons dashicons-arrow-right') |
|
| 4060 | - { |
|
| 4061 | - return '<a class="' . $class . '" href="' . $url . '"></a>'; |
|
| 4062 | - } |
|
| 4063 | - |
|
| 4064 | - |
|
| 4065 | - /** |
|
| 4066 | - * A helper for getting a "previous link". |
|
| 4067 | - * |
|
| 4068 | - * @param string $url The url to link to |
|
| 4069 | - * @param string $class The class to use. |
|
| 4070 | - * @return string |
|
| 4071 | - */ |
|
| 4072 | - protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left') |
|
| 4073 | - { |
|
| 4074 | - return '<a class="' . $class . '" href="' . $url . '"></a>'; |
|
| 4075 | - } |
|
| 4076 | - |
|
| 4077 | - |
|
| 4078 | - |
|
| 4079 | - |
|
| 4080 | - |
|
| 4081 | - |
|
| 4082 | - |
|
| 4083 | - // below are some messages related methods that should be available across the EE_Admin system. Note, these methods are NOT page specific |
|
| 4084 | - |
|
| 4085 | - |
|
| 4086 | - /** |
|
| 4087 | - * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller |
|
| 4088 | - * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the |
|
| 4089 | - * _req_data array. |
|
| 4090 | - * |
|
| 4091 | - * @return bool success/fail |
|
| 4092 | - * @throws EE_Error |
|
| 4093 | - * @throws InvalidArgumentException |
|
| 4094 | - * @throws ReflectionException |
|
| 4095 | - * @throws InvalidDataTypeException |
|
| 4096 | - * @throws InvalidInterfaceException |
|
| 4097 | - */ |
|
| 4098 | - protected function _process_resend_registration() |
|
| 4099 | - { |
|
| 4100 | - $this->_template_args['success'] = EED_Messages::process_resend($this->_req_data); |
|
| 4101 | - do_action( |
|
| 4102 | - 'AHEE__EE_Admin_Page___process_resend_registration', |
|
| 4103 | - $this->_template_args['success'], |
|
| 4104 | - $this->_req_data |
|
| 4105 | - ); |
|
| 4106 | - return $this->_template_args['success']; |
|
| 4107 | - } |
|
| 4108 | - |
|
| 4109 | - |
|
| 4110 | - /** |
|
| 4111 | - * This automatically processes any payment message notifications when manual payment has been applied. |
|
| 4112 | - * |
|
| 4113 | - * @param \EE_Payment $payment |
|
| 4114 | - * @return bool success/fail |
|
| 4115 | - */ |
|
| 4116 | - protected function _process_payment_notification(EE_Payment $payment) |
|
| 4117 | - { |
|
| 4118 | - add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true'); |
|
| 4119 | - do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment); |
|
| 4120 | - $this->_template_args['success'] = apply_filters( |
|
| 4121 | - 'FHEE__EE_Admin_Page___process_admin_payment_notification__success', |
|
| 4122 | - false, |
|
| 4123 | - $payment |
|
| 4124 | - ); |
|
| 4125 | - return $this->_template_args['success']; |
|
| 4126 | - } |
|
| 2703 | + } |
|
| 2704 | + |
|
| 2705 | + |
|
| 2706 | + /** |
|
| 2707 | + * facade for add_meta_box |
|
| 2708 | + * |
|
| 2709 | + * @param string $action where the metabox get's displayed |
|
| 2710 | + * @param string $title Title of Metabox (output in metabox header) |
|
| 2711 | + * @param string $callback If not empty and $create_fun is set to false then we'll use a custom callback |
|
| 2712 | + * instead of the one created in here. |
|
| 2713 | + * @param array $callback_args an array of args supplied for the metabox |
|
| 2714 | + * @param string $column what metabox column |
|
| 2715 | + * @param string $priority give this metabox a priority (using accepted priorities for wp meta boxes) |
|
| 2716 | + * @param boolean $create_func default is true. Basically we can say we don't WANT to have the runtime function |
|
| 2717 | + * created but just set our own callback for wp's add_meta_box. |
|
| 2718 | + * @throws \DomainException |
|
| 2719 | + */ |
|
| 2720 | + public function _add_admin_page_meta_box( |
|
| 2721 | + $action, |
|
| 2722 | + $title, |
|
| 2723 | + $callback, |
|
| 2724 | + $callback_args, |
|
| 2725 | + $column = 'normal', |
|
| 2726 | + $priority = 'high', |
|
| 2727 | + $create_func = true |
|
| 2728 | + ) { |
|
| 2729 | + do_action('AHEE_log', __FILE__, __FUNCTION__, $callback); |
|
| 2730 | + // if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated. |
|
| 2731 | + if (empty($callback_args) && $create_func) { |
|
| 2732 | + $callback_args = array( |
|
| 2733 | + 'template_path' => $this->_template_path, |
|
| 2734 | + 'template_args' => $this->_template_args, |
|
| 2735 | + ); |
|
| 2736 | + } |
|
| 2737 | + // if $create_func is true (default) then we automatically create the function for displaying the actual meta box. If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish) |
|
| 2738 | + $call_back_func = $create_func |
|
| 2739 | + ? function ($post, $metabox) { |
|
| 2740 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2741 | + echo EEH_Template::display_template( |
|
| 2742 | + $metabox['args']['template_path'], |
|
| 2743 | + $metabox['args']['template_args'], |
|
| 2744 | + true |
|
| 2745 | + ); |
|
| 2746 | + } |
|
| 2747 | + : $callback; |
|
| 2748 | + add_meta_box( |
|
| 2749 | + str_replace('_', '-', $action) . '-mbox', |
|
| 2750 | + $title, |
|
| 2751 | + $call_back_func, |
|
| 2752 | + $this->_wp_page_slug, |
|
| 2753 | + $column, |
|
| 2754 | + $priority, |
|
| 2755 | + $callback_args |
|
| 2756 | + ); |
|
| 2757 | + } |
|
| 2758 | + |
|
| 2759 | + |
|
| 2760 | + /** |
|
| 2761 | + * generates HTML wrapper for and admin details page that contains metaboxes in columns |
|
| 2762 | + * |
|
| 2763 | + * @throws DomainException |
|
| 2764 | + * @throws EE_Error |
|
| 2765 | + */ |
|
| 2766 | + public function display_admin_page_with_metabox_columns() |
|
| 2767 | + { |
|
| 2768 | + $this->_template_args['post_body_content'] = $this->_template_args['admin_page_content']; |
|
| 2769 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 2770 | + $this->_column_template_path, |
|
| 2771 | + $this->_template_args, |
|
| 2772 | + true |
|
| 2773 | + ); |
|
| 2774 | + // the final wrapper |
|
| 2775 | + $this->admin_page_wrapper(); |
|
| 2776 | + } |
|
| 2777 | + |
|
| 2778 | + |
|
| 2779 | + /** |
|
| 2780 | + * generates HTML wrapper for an admin details page |
|
| 2781 | + * |
|
| 2782 | + * @return void |
|
| 2783 | + * @throws EE_Error |
|
| 2784 | + * @throws DomainException |
|
| 2785 | + */ |
|
| 2786 | + public function display_admin_page_with_sidebar() |
|
| 2787 | + { |
|
| 2788 | + $this->_display_admin_page(true); |
|
| 2789 | + } |
|
| 2790 | + |
|
| 2791 | + |
|
| 2792 | + /** |
|
| 2793 | + * generates HTML wrapper for an admin details page (except no sidebar) |
|
| 2794 | + * |
|
| 2795 | + * @return void |
|
| 2796 | + * @throws EE_Error |
|
| 2797 | + * @throws DomainException |
|
| 2798 | + */ |
|
| 2799 | + public function display_admin_page_with_no_sidebar() |
|
| 2800 | + { |
|
| 2801 | + $this->_display_admin_page(); |
|
| 2802 | + } |
|
| 2803 | + |
|
| 2804 | + |
|
| 2805 | + /** |
|
| 2806 | + * generates HTML wrapper for an EE about admin page (no sidebar) |
|
| 2807 | + * |
|
| 2808 | + * @return void |
|
| 2809 | + * @throws EE_Error |
|
| 2810 | + * @throws DomainException |
|
| 2811 | + */ |
|
| 2812 | + public function display_about_admin_page() |
|
| 2813 | + { |
|
| 2814 | + $this->_display_admin_page(false, true); |
|
| 2815 | + } |
|
| 2816 | + |
|
| 2817 | + |
|
| 2818 | + /** |
|
| 2819 | + * display_admin_page |
|
| 2820 | + * contains the code for actually displaying an admin page |
|
| 2821 | + * |
|
| 2822 | + * @param boolean $sidebar true with sidebar, false without |
|
| 2823 | + * @param boolean $about use the about admin wrapper instead of the default. |
|
| 2824 | + * @return void |
|
| 2825 | + * @throws DomainException |
|
| 2826 | + * @throws EE_Error |
|
| 2827 | + */ |
|
| 2828 | + private function _display_admin_page($sidebar = false, $about = false) |
|
| 2829 | + { |
|
| 2830 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2831 | + // custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages. |
|
| 2832 | + do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes'); |
|
| 2833 | + // set current wp page slug - looks like: event-espresso_page_event_categories |
|
| 2834 | + // keep in mind "event-espresso" COULD be something else if the top level menu label has been translated. |
|
| 2835 | + $this->_template_args['current_page'] = $this->_wp_page_slug; |
|
| 2836 | + $this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route |
|
| 2837 | + ? 'poststuff' |
|
| 2838 | + : 'espresso-default-admin'; |
|
| 2839 | + $template_path = $sidebar |
|
| 2840 | + ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php' |
|
| 2841 | + : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php'; |
|
| 2842 | + if (defined('DOING_AJAX') && DOING_AJAX) { |
|
| 2843 | + $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php'; |
|
| 2844 | + } |
|
| 2845 | + $template_path = ! empty($this->_column_template_path) |
|
| 2846 | + ? $this->_column_template_path : $template_path; |
|
| 2847 | + $this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content']) |
|
| 2848 | + ? $this->_template_args['admin_page_content'] |
|
| 2849 | + : ''; |
|
| 2850 | + $this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content']) |
|
| 2851 | + ? $this->_template_args['before_admin_page_content'] |
|
| 2852 | + : ''; |
|
| 2853 | + $this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content']) |
|
| 2854 | + ? $this->_template_args['after_admin_page_content'] |
|
| 2855 | + : ''; |
|
| 2856 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 2857 | + $template_path, |
|
| 2858 | + $this->_template_args, |
|
| 2859 | + true |
|
| 2860 | + ); |
|
| 2861 | + // the final template wrapper |
|
| 2862 | + $this->admin_page_wrapper($about); |
|
| 2863 | + } |
|
| 2864 | + |
|
| 2865 | + |
|
| 2866 | + /** |
|
| 2867 | + * This is used to display caf preview pages. |
|
| 2868 | + * |
|
| 2869 | + * @since 4.3.2 |
|
| 2870 | + * @param string $utm_campaign_source what is the key used for google analytics link |
|
| 2871 | + * @param bool $display_sidebar whether to use the sidebar template or the full template for the page. TRUE |
|
| 2872 | + * = SHOW sidebar, FALSE = no sidebar. Default no sidebar. |
|
| 2873 | + * @return void |
|
| 2874 | + * @throws DomainException |
|
| 2875 | + * @throws EE_Error |
|
| 2876 | + * @throws InvalidArgumentException |
|
| 2877 | + * @throws InvalidDataTypeException |
|
| 2878 | + * @throws InvalidInterfaceException |
|
| 2879 | + */ |
|
| 2880 | + public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true) |
|
| 2881 | + { |
|
| 2882 | + // let's generate a default preview action button if there isn't one already present. |
|
| 2883 | + $this->_labels['buttons']['buy_now'] = esc_html__( |
|
| 2884 | + 'Upgrade to Event Espresso 4 Right Now', |
|
| 2885 | + 'event_espresso' |
|
| 2886 | + ); |
|
| 2887 | + $buy_now_url = add_query_arg( |
|
| 2888 | + array( |
|
| 2889 | + 'ee_ver' => 'ee4', |
|
| 2890 | + 'utm_source' => 'ee4_plugin_admin', |
|
| 2891 | + 'utm_medium' => 'link', |
|
| 2892 | + 'utm_campaign' => $utm_campaign_source, |
|
| 2893 | + 'utm_content' => 'buy_now_button', |
|
| 2894 | + ), |
|
| 2895 | + 'http://eventespresso.com/pricing/' |
|
| 2896 | + ); |
|
| 2897 | + $this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button']) |
|
| 2898 | + ? $this->get_action_link_or_button( |
|
| 2899 | + '', |
|
| 2900 | + 'buy_now', |
|
| 2901 | + array(), |
|
| 2902 | + 'button-primary button-large', |
|
| 2903 | + $buy_now_url, |
|
| 2904 | + true |
|
| 2905 | + ) |
|
| 2906 | + : $this->_template_args['preview_action_button']; |
|
| 2907 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 2908 | + EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php', |
|
| 2909 | + $this->_template_args, |
|
| 2910 | + true |
|
| 2911 | + ); |
|
| 2912 | + $this->_display_admin_page($display_sidebar); |
|
| 2913 | + } |
|
| 2914 | + |
|
| 2915 | + |
|
| 2916 | + /** |
|
| 2917 | + * display_admin_list_table_page_with_sidebar |
|
| 2918 | + * generates HTML wrapper for an admin_page with list_table |
|
| 2919 | + * |
|
| 2920 | + * @return void |
|
| 2921 | + * @throws EE_Error |
|
| 2922 | + * @throws DomainException |
|
| 2923 | + */ |
|
| 2924 | + public function display_admin_list_table_page_with_sidebar() |
|
| 2925 | + { |
|
| 2926 | + $this->_display_admin_list_table_page(true); |
|
| 2927 | + } |
|
| 2928 | + |
|
| 2929 | + |
|
| 2930 | + /** |
|
| 2931 | + * display_admin_list_table_page_with_no_sidebar |
|
| 2932 | + * generates HTML wrapper for an admin_page with list_table (but with no sidebar) |
|
| 2933 | + * |
|
| 2934 | + * @return void |
|
| 2935 | + * @throws EE_Error |
|
| 2936 | + * @throws DomainException |
|
| 2937 | + */ |
|
| 2938 | + public function display_admin_list_table_page_with_no_sidebar() |
|
| 2939 | + { |
|
| 2940 | + $this->_display_admin_list_table_page(); |
|
| 2941 | + } |
|
| 2942 | + |
|
| 2943 | + |
|
| 2944 | + /** |
|
| 2945 | + * generates html wrapper for an admin_list_table page |
|
| 2946 | + * |
|
| 2947 | + * @param boolean $sidebar whether to display with sidebar or not. |
|
| 2948 | + * @return void |
|
| 2949 | + * @throws DomainException |
|
| 2950 | + * @throws EE_Error |
|
| 2951 | + */ |
|
| 2952 | + private function _display_admin_list_table_page($sidebar = false) |
|
| 2953 | + { |
|
| 2954 | + // setup search attributes |
|
| 2955 | + $this->_set_search_attributes(); |
|
| 2956 | + $this->_template_args['current_page'] = $this->_wp_page_slug; |
|
| 2957 | + $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php'; |
|
| 2958 | + $this->_template_args['table_url'] = defined('DOING_AJAX') |
|
| 2959 | + ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url) |
|
| 2960 | + : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url); |
|
| 2961 | + $this->_template_args['list_table'] = $this->_list_table_object; |
|
| 2962 | + $this->_template_args['current_route'] = $this->_req_action; |
|
| 2963 | + $this->_template_args['list_table_class'] = get_class($this->_list_table_object); |
|
| 2964 | + $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback(); |
|
| 2965 | + if (! empty($ajax_sorting_callback)) { |
|
| 2966 | + $sortable_list_table_form_fields = wp_nonce_field( |
|
| 2967 | + $ajax_sorting_callback . '_nonce', |
|
| 2968 | + $ajax_sorting_callback . '_nonce', |
|
| 2969 | + false, |
|
| 2970 | + false |
|
| 2971 | + ); |
|
| 2972 | + $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="' |
|
| 2973 | + . $this->page_slug |
|
| 2974 | + . '" />'; |
|
| 2975 | + $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="' |
|
| 2976 | + . $ajax_sorting_callback |
|
| 2977 | + . '" />'; |
|
| 2978 | + } else { |
|
| 2979 | + $sortable_list_table_form_fields = ''; |
|
| 2980 | + } |
|
| 2981 | + $this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields; |
|
| 2982 | + $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields']) |
|
| 2983 | + ? $this->_template_args['list_table_hidden_fields'] |
|
| 2984 | + : ''; |
|
| 2985 | + $nonce_ref = $this->_req_action . '_nonce'; |
|
| 2986 | + $hidden_form_fields .= '<input type="hidden" name="' |
|
| 2987 | + . $nonce_ref |
|
| 2988 | + . '" value="' |
|
| 2989 | + . wp_create_nonce($nonce_ref) |
|
| 2990 | + . '">'; |
|
| 2991 | + $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields; |
|
| 2992 | + // display message about search results? |
|
| 2993 | + $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s']) |
|
| 2994 | + ? '<p class="ee-search-results">' . sprintf( |
|
| 2995 | + esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'), |
|
| 2996 | + trim($this->_req_data['s'], '%') |
|
| 2997 | + ) . '</p>' |
|
| 2998 | + : ''; |
|
| 2999 | + // filter before_list_table template arg |
|
| 3000 | + $this->_template_args['before_list_table'] = apply_filters( |
|
| 3001 | + 'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg', |
|
| 3002 | + $this->_template_args['before_list_table'], |
|
| 3003 | + $this->page_slug, |
|
| 3004 | + $this->_req_data, |
|
| 3005 | + $this->_req_action |
|
| 3006 | + ); |
|
| 3007 | + // convert to array and filter again |
|
| 3008 | + // arrays are easier to inject new items in a specific location, |
|
| 3009 | + // but would not be backwards compatible, so we have to add a new filter |
|
| 3010 | + $this->_template_args['before_list_table'] = implode( |
|
| 3011 | + " \n", |
|
| 3012 | + (array) apply_filters( |
|
| 3013 | + 'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array', |
|
| 3014 | + (array) $this->_template_args['before_list_table'], |
|
| 3015 | + $this->page_slug, |
|
| 3016 | + $this->_req_data, |
|
| 3017 | + $this->_req_action |
|
| 3018 | + ) |
|
| 3019 | + ); |
|
| 3020 | + // filter after_list_table template arg |
|
| 3021 | + $this->_template_args['after_list_table'] = apply_filters( |
|
| 3022 | + 'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg', |
|
| 3023 | + $this->_template_args['after_list_table'], |
|
| 3024 | + $this->page_slug, |
|
| 3025 | + $this->_req_data, |
|
| 3026 | + $this->_req_action |
|
| 3027 | + ); |
|
| 3028 | + // convert to array and filter again |
|
| 3029 | + // arrays are easier to inject new items in a specific location, |
|
| 3030 | + // but would not be backwards compatible, so we have to add a new filter |
|
| 3031 | + $this->_template_args['after_list_table'] = implode( |
|
| 3032 | + " \n", |
|
| 3033 | + (array) apply_filters( |
|
| 3034 | + 'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array', |
|
| 3035 | + (array) $this->_template_args['after_list_table'], |
|
| 3036 | + $this->page_slug, |
|
| 3037 | + $this->_req_data, |
|
| 3038 | + $this->_req_action |
|
| 3039 | + ) |
|
| 3040 | + ); |
|
| 3041 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 3042 | + $template_path, |
|
| 3043 | + $this->_template_args, |
|
| 3044 | + true |
|
| 3045 | + ); |
|
| 3046 | + // the final template wrapper |
|
| 3047 | + if ($sidebar) { |
|
| 3048 | + $this->display_admin_page_with_sidebar(); |
|
| 3049 | + } else { |
|
| 3050 | + $this->display_admin_page_with_no_sidebar(); |
|
| 3051 | + } |
|
| 3052 | + } |
|
| 3053 | + |
|
| 3054 | + |
|
| 3055 | + /** |
|
| 3056 | + * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the |
|
| 3057 | + * html string for the legend. |
|
| 3058 | + * $items are expected in an array in the following format: |
|
| 3059 | + * $legend_items = array( |
|
| 3060 | + * 'item_id' => array( |
|
| 3061 | + * 'icon' => 'http://url_to_icon_being_described.png', |
|
| 3062 | + * 'desc' => esc_html__('localized description of item'); |
|
| 3063 | + * ) |
|
| 3064 | + * ); |
|
| 3065 | + * |
|
| 3066 | + * @param array $items see above for format of array |
|
| 3067 | + * @return string html string of legend |
|
| 3068 | + * @throws DomainException |
|
| 3069 | + */ |
|
| 3070 | + protected function _display_legend($items) |
|
| 3071 | + { |
|
| 3072 | + $this->_template_args['items'] = apply_filters( |
|
| 3073 | + 'FHEE__EE_Admin_Page___display_legend__items', |
|
| 3074 | + (array) $items, |
|
| 3075 | + $this |
|
| 3076 | + ); |
|
| 3077 | + return EEH_Template::display_template( |
|
| 3078 | + EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php', |
|
| 3079 | + $this->_template_args, |
|
| 3080 | + true |
|
| 3081 | + ); |
|
| 3082 | + } |
|
| 3083 | + |
|
| 3084 | + |
|
| 3085 | + /** |
|
| 3086 | + * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect |
|
| 3087 | + * The returned json object is created from an array in the following format: |
|
| 3088 | + * array( |
|
| 3089 | + * 'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early), |
|
| 3090 | + * 'success' => FALSE, //(default FALSE) - contains any special success message. |
|
| 3091 | + * 'notices' => '', // - contains any EE_Error formatted notices |
|
| 3092 | + * 'content' => 'string can be html', //this is a string of formatted content (can be html) |
|
| 3093 | + * 'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js. |
|
| 3094 | + * We're also going to include the template args with every package (so js can pick out any specific template args |
|
| 3095 | + * that might be included in here) |
|
| 3096 | + * ) |
|
| 3097 | + * The json object is populated by whatever is set in the $_template_args property. |
|
| 3098 | + * |
|
| 3099 | + * @param bool $sticky_notices Used to indicate whether you want to ensure notices are added to a transient |
|
| 3100 | + * instead of displayed. |
|
| 3101 | + * @param array $notices_arguments Use this to pass any additional args on to the _process_notices. |
|
| 3102 | + * @return void |
|
| 3103 | + * @throws EE_Error |
|
| 3104 | + */ |
|
| 3105 | + protected function _return_json($sticky_notices = false, $notices_arguments = array()) |
|
| 3106 | + { |
|
| 3107 | + // make sure any EE_Error notices have been handled. |
|
| 3108 | + $this->_process_notices($notices_arguments, true, $sticky_notices); |
|
| 3109 | + $data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array(); |
|
| 3110 | + unset($this->_template_args['data']); |
|
| 3111 | + $json = array( |
|
| 3112 | + 'error' => isset($this->_template_args['error']) ? $this->_template_args['error'] : false, |
|
| 3113 | + 'success' => isset($this->_template_args['success']) ? $this->_template_args['success'] : false, |
|
| 3114 | + 'errors' => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false, |
|
| 3115 | + 'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false, |
|
| 3116 | + 'notices' => EE_Error::get_notices(), |
|
| 3117 | + 'content' => isset($this->_template_args['admin_page_content']) |
|
| 3118 | + ? $this->_template_args['admin_page_content'] : '', |
|
| 3119 | + 'data' => array_merge($data, array('template_args' => $this->_template_args)), |
|
| 3120 | + 'isEEajax' => true |
|
| 3121 | + // special flag so any ajax.Success methods in js can identify this return package as a EEajax package. |
|
| 3122 | + ); |
|
| 3123 | + // make sure there are no php errors or headers_sent. Then we can set correct json header. |
|
| 3124 | + if (null === error_get_last() || ! headers_sent()) { |
|
| 3125 | + header('Content-Type: application/json; charset=UTF-8'); |
|
| 3126 | + } |
|
| 3127 | + echo wp_json_encode($json); |
|
| 3128 | + exit(); |
|
| 3129 | + } |
|
| 3130 | + |
|
| 3131 | + |
|
| 3132 | + /** |
|
| 3133 | + * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax) |
|
| 3134 | + * |
|
| 3135 | + * @return void |
|
| 3136 | + * @throws EE_Error |
|
| 3137 | + */ |
|
| 3138 | + public function return_json() |
|
| 3139 | + { |
|
| 3140 | + if (defined('DOING_AJAX') && DOING_AJAX) { |
|
| 3141 | + $this->_return_json(); |
|
| 3142 | + } else { |
|
| 3143 | + throw new EE_Error( |
|
| 3144 | + sprintf( |
|
| 3145 | + esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'), |
|
| 3146 | + __FUNCTION__ |
|
| 3147 | + ) |
|
| 3148 | + ); |
|
| 3149 | + } |
|
| 3150 | + } |
|
| 3151 | + |
|
| 3152 | + |
|
| 3153 | + /** |
|
| 3154 | + * This provides a way for child hook classes to send along themselves by reference so methods/properties within |
|
| 3155 | + * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property. |
|
| 3156 | + * |
|
| 3157 | + * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child |
|
| 3158 | + */ |
|
| 3159 | + public function set_hook_object(EE_Admin_Hooks $hook_obj) |
|
| 3160 | + { |
|
| 3161 | + $this->_hook_obj = $hook_obj; |
|
| 3162 | + } |
|
| 3163 | + |
|
| 3164 | + |
|
| 3165 | + /** |
|
| 3166 | + * generates HTML wrapper with Tabbed nav for an admin page |
|
| 3167 | + * |
|
| 3168 | + * @param boolean $about whether to use the special about page wrapper or default. |
|
| 3169 | + * @return void |
|
| 3170 | + * @throws DomainException |
|
| 3171 | + * @throws EE_Error |
|
| 3172 | + */ |
|
| 3173 | + public function admin_page_wrapper($about = false) |
|
| 3174 | + { |
|
| 3175 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 3176 | + $this->_nav_tabs = $this->_get_main_nav_tabs(); |
|
| 3177 | + $this->_template_args['nav_tabs'] = $this->_nav_tabs; |
|
| 3178 | + $this->_template_args['admin_page_title'] = $this->_admin_page_title; |
|
| 3179 | + $this->_template_args['before_admin_page_content'] = apply_filters( |
|
| 3180 | + "FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}", |
|
| 3181 | + isset($this->_template_args['before_admin_page_content']) |
|
| 3182 | + ? $this->_template_args['before_admin_page_content'] |
|
| 3183 | + : '' |
|
| 3184 | + ); |
|
| 3185 | + $this->_template_args['after_admin_page_content'] = apply_filters( |
|
| 3186 | + "FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}", |
|
| 3187 | + isset($this->_template_args['after_admin_page_content']) |
|
| 3188 | + ? $this->_template_args['after_admin_page_content'] |
|
| 3189 | + : '' |
|
| 3190 | + ); |
|
| 3191 | + $this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content(); |
|
| 3192 | + // load settings page wrapper template |
|
| 3193 | + $template_path = ! defined('DOING_AJAX') |
|
| 3194 | + ? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php' |
|
| 3195 | + : EE_ADMIN_TEMPLATE |
|
| 3196 | + . 'admin_wrapper_ajax.template.php'; |
|
| 3197 | + // about page? |
|
| 3198 | + $template_path = $about |
|
| 3199 | + ? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php' |
|
| 3200 | + : $template_path; |
|
| 3201 | + if (defined('DOING_AJAX')) { |
|
| 3202 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 3203 | + $template_path, |
|
| 3204 | + $this->_template_args, |
|
| 3205 | + true |
|
| 3206 | + ); |
|
| 3207 | + $this->_return_json(); |
|
| 3208 | + } else { |
|
| 3209 | + EEH_Template::display_template($template_path, $this->_template_args); |
|
| 3210 | + } |
|
| 3211 | + } |
|
| 3212 | + |
|
| 3213 | + |
|
| 3214 | + /** |
|
| 3215 | + * This returns the admin_nav tabs html using the configuration in the _nav_tabs property |
|
| 3216 | + * |
|
| 3217 | + * @return string html |
|
| 3218 | + * @throws EE_Error |
|
| 3219 | + */ |
|
| 3220 | + protected function _get_main_nav_tabs() |
|
| 3221 | + { |
|
| 3222 | + // let's generate the html using the EEH_Tabbed_Content helper. |
|
| 3223 | + // We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute |
|
| 3224 | + // (rather than setting in the page_routes array) |
|
| 3225 | + return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs); |
|
| 3226 | + } |
|
| 3227 | + |
|
| 3228 | + |
|
| 3229 | + /** |
|
| 3230 | + * sort nav tabs |
|
| 3231 | + * |
|
| 3232 | + * @param $a |
|
| 3233 | + * @param $b |
|
| 3234 | + * @return int |
|
| 3235 | + */ |
|
| 3236 | + private function _sort_nav_tabs($a, $b) |
|
| 3237 | + { |
|
| 3238 | + if ($a['order'] === $b['order']) { |
|
| 3239 | + return 0; |
|
| 3240 | + } |
|
| 3241 | + return ($a['order'] < $b['order']) ? -1 : 1; |
|
| 3242 | + } |
|
| 3243 | + |
|
| 3244 | + |
|
| 3245 | + /** |
|
| 3246 | + * generates HTML for the forms used on admin pages |
|
| 3247 | + * |
|
| 3248 | + * @param array $input_vars - array of input field details |
|
| 3249 | + * @param string $generator (options are 'string' or 'array', basically use this to indicate which generator to |
|
| 3250 | + * use) |
|
| 3251 | + * @param bool $id |
|
| 3252 | + * @return string |
|
| 3253 | + * @uses EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php) |
|
| 3254 | + * @uses EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php) |
|
| 3255 | + */ |
|
| 3256 | + protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false) |
|
| 3257 | + { |
|
| 3258 | + $content = $generator === 'string' |
|
| 3259 | + ? EEH_Form_Fields::get_form_fields($input_vars, $id) |
|
| 3260 | + : EEH_Form_Fields::get_form_fields_array($input_vars); |
|
| 3261 | + return $content; |
|
| 3262 | + } |
|
| 3263 | + |
|
| 3264 | + |
|
| 3265 | + /** |
|
| 3266 | + * generates the "Save" and "Save & Close" buttons for edit forms |
|
| 3267 | + * |
|
| 3268 | + * @param bool $both if true then both buttons will be generated. If false then just the "Save & |
|
| 3269 | + * Close" button. |
|
| 3270 | + * @param array $text if included, generator will use the given text for the buttons ( array([0] => |
|
| 3271 | + * 'Save', [1] => 'save & close') |
|
| 3272 | + * @param array $actions if included allows us to set the actions that each button will carry out (i.e. |
|
| 3273 | + * via the "name" value in the button). We can also use this to just dump |
|
| 3274 | + * default actions by submitting some other value. |
|
| 3275 | + * @param bool|string|null $referrer if false then we just do the default action on save and close. Other wise it |
|
| 3276 | + * will use the $referrer string. IF null, then we don't do ANYTHING on save and |
|
| 3277 | + * close (normal form handling). |
|
| 3278 | + */ |
|
| 3279 | + protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null) |
|
| 3280 | + { |
|
| 3281 | + // make sure $text and $actions are in an array |
|
| 3282 | + $text = (array) $text; |
|
| 3283 | + $actions = (array) $actions; |
|
| 3284 | + $referrer_url = empty($referrer) |
|
| 3285 | + ? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="' |
|
| 3286 | + . $_SERVER['REQUEST_URI'] |
|
| 3287 | + . '" />' |
|
| 3288 | + : '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="' |
|
| 3289 | + . $referrer |
|
| 3290 | + . '" />'; |
|
| 3291 | + $button_text = ! empty($text) |
|
| 3292 | + ? $text |
|
| 3293 | + : array( |
|
| 3294 | + esc_html__('Save', 'event_espresso'), |
|
| 3295 | + esc_html__('Save and Close', 'event_espresso'), |
|
| 3296 | + ); |
|
| 3297 | + $default_names = array('save', 'save_and_close'); |
|
| 3298 | + // add in a hidden index for the current page (so save and close redirects properly) |
|
| 3299 | + $this->_template_args['save_buttons'] = $referrer_url; |
|
| 3300 | + foreach ($button_text as $key => $button) { |
|
| 3301 | + $ref = $default_names[ $key ]; |
|
| 3302 | + $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary ' |
|
| 3303 | + . $ref |
|
| 3304 | + . '" value="' |
|
| 3305 | + . $button |
|
| 3306 | + . '" name="' |
|
| 3307 | + . (! empty($actions) ? $actions[ $key ] : $ref) |
|
| 3308 | + . '" id="' |
|
| 3309 | + . $this->_current_view . '_' . $ref |
|
| 3310 | + . '" />'; |
|
| 3311 | + if (! $both) { |
|
| 3312 | + break; |
|
| 3313 | + } |
|
| 3314 | + } |
|
| 3315 | + } |
|
| 3316 | + |
|
| 3317 | + |
|
| 3318 | + /** |
|
| 3319 | + * Wrapper for the protected function. Allows plugins/addons to call this to set the form tags. |
|
| 3320 | + * |
|
| 3321 | + * @see $this->_set_add_edit_form_tags() for details on params |
|
| 3322 | + * @since 4.6.0 |
|
| 3323 | + * @param string $route |
|
| 3324 | + * @param array $additional_hidden_fields |
|
| 3325 | + */ |
|
| 3326 | + public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array()) |
|
| 3327 | + { |
|
| 3328 | + $this->_set_add_edit_form_tags($route, $additional_hidden_fields); |
|
| 3329 | + } |
|
| 3330 | + |
|
| 3331 | + |
|
| 3332 | + /** |
|
| 3333 | + * set form open and close tags on add/edit pages. |
|
| 3334 | + * |
|
| 3335 | + * @param string $route the route you want the form to direct to |
|
| 3336 | + * @param array $additional_hidden_fields any additional hidden fields required in the form header |
|
| 3337 | + * @return void |
|
| 3338 | + */ |
|
| 3339 | + protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array()) |
|
| 3340 | + { |
|
| 3341 | + if (empty($route)) { |
|
| 3342 | + $user_msg = esc_html__( |
|
| 3343 | + 'An error occurred. No action was set for this page\'s form.', |
|
| 3344 | + 'event_espresso' |
|
| 3345 | + ); |
|
| 3346 | + $dev_msg = $user_msg . "\n" |
|
| 3347 | + . sprintf( |
|
| 3348 | + esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'), |
|
| 3349 | + __FUNCTION__, |
|
| 3350 | + __CLASS__ |
|
| 3351 | + ); |
|
| 3352 | + EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 3353 | + } |
|
| 3354 | + // open form |
|
| 3355 | + $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="' |
|
| 3356 | + . $this->_admin_base_url |
|
| 3357 | + . '" id="' |
|
| 3358 | + . $route |
|
| 3359 | + . '_event_form" >'; |
|
| 3360 | + // add nonce |
|
| 3361 | + $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false); |
|
| 3362 | + $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce; |
|
| 3363 | + // add REQUIRED form action |
|
| 3364 | + $hidden_fields = array( |
|
| 3365 | + 'action' => array('type' => 'hidden', 'value' => $route), |
|
| 3366 | + ); |
|
| 3367 | + // merge arrays |
|
| 3368 | + $hidden_fields = is_array($additional_hidden_fields) |
|
| 3369 | + ? array_merge($hidden_fields, $additional_hidden_fields) |
|
| 3370 | + : $hidden_fields; |
|
| 3371 | + // generate form fields |
|
| 3372 | + $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array'); |
|
| 3373 | + // add fields to form |
|
| 3374 | + foreach ((array) $form_fields as $field_name => $form_field) { |
|
| 3375 | + $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field']; |
|
| 3376 | + } |
|
| 3377 | + // close form |
|
| 3378 | + $this->_template_args['after_admin_page_content'] = '</form>'; |
|
| 3379 | + } |
|
| 3380 | + |
|
| 3381 | + |
|
| 3382 | + /** |
|
| 3383 | + * Public Wrapper for _redirect_after_action() method since its |
|
| 3384 | + * discovered it would be useful for external code to have access. |
|
| 3385 | + * |
|
| 3386 | + * @see EE_Admin_Page::_redirect_after_action() for params. |
|
| 3387 | + * @since 4.5.0 |
|
| 3388 | + * @param bool $success |
|
| 3389 | + * @param string $what |
|
| 3390 | + * @param string $action_desc |
|
| 3391 | + * @param array $query_args |
|
| 3392 | + * @param bool $override_overwrite |
|
| 3393 | + * @throws EE_Error |
|
| 3394 | + */ |
|
| 3395 | + public function redirect_after_action( |
|
| 3396 | + $success = false, |
|
| 3397 | + $what = 'item', |
|
| 3398 | + $action_desc = 'processed', |
|
| 3399 | + $query_args = array(), |
|
| 3400 | + $override_overwrite = false |
|
| 3401 | + ) { |
|
| 3402 | + $this->_redirect_after_action( |
|
| 3403 | + $success, |
|
| 3404 | + $what, |
|
| 3405 | + $action_desc, |
|
| 3406 | + $query_args, |
|
| 3407 | + $override_overwrite |
|
| 3408 | + ); |
|
| 3409 | + } |
|
| 3410 | + |
|
| 3411 | + |
|
| 3412 | + /** |
|
| 3413 | + * Helper method for merging existing request data with the returned redirect url. |
|
| 3414 | + * |
|
| 3415 | + * This is typically used for redirects after an action so that if the original view was a filtered view those |
|
| 3416 | + * filters are still applied. |
|
| 3417 | + * |
|
| 3418 | + * @param array $new_route_data |
|
| 3419 | + * @return array |
|
| 3420 | + */ |
|
| 3421 | + protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data) |
|
| 3422 | + { |
|
| 3423 | + foreach ($this->_req_data as $ref => $value) { |
|
| 3424 | + // unset nonces |
|
| 3425 | + if (strpos($ref, 'nonce') !== false) { |
|
| 3426 | + unset($this->_req_data[ $ref ]); |
|
| 3427 | + continue; |
|
| 3428 | + } |
|
| 3429 | + // urlencode values. |
|
| 3430 | + $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value); |
|
| 3431 | + $this->_req_data[ $ref ] = $value; |
|
| 3432 | + } |
|
| 3433 | + return array_merge($this->_req_data, $new_route_data); |
|
| 3434 | + } |
|
| 3435 | + |
|
| 3436 | + |
|
| 3437 | + /** |
|
| 3438 | + * _redirect_after_action |
|
| 3439 | + * |
|
| 3440 | + * @param int $success - whether success was for two or more records, or just one, or none |
|
| 3441 | + * @param string $what - what the action was performed on |
|
| 3442 | + * @param string $action_desc - what was done ie: updated, deleted, etc |
|
| 3443 | + * @param array $query_args - an array of query_args to be added to the URL to redirect to after the admin |
|
| 3444 | + * action is completed |
|
| 3445 | + * @param BOOL $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to |
|
| 3446 | + * override this so that they show. |
|
| 3447 | + * @return void |
|
| 3448 | + * @throws EE_Error |
|
| 3449 | + */ |
|
| 3450 | + protected function _redirect_after_action( |
|
| 3451 | + $success = 0, |
|
| 3452 | + $what = 'item', |
|
| 3453 | + $action_desc = 'processed', |
|
| 3454 | + $query_args = array(), |
|
| 3455 | + $override_overwrite = false |
|
| 3456 | + ) { |
|
| 3457 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 3458 | + // class name for actions/filters. |
|
| 3459 | + $classname = get_class($this); |
|
| 3460 | + // set redirect url. |
|
| 3461 | + // Note if there is a "page" index in the $query_args then we go with vanilla admin.php route, |
|
| 3462 | + // otherwise we go with whatever is set as the _admin_base_url |
|
| 3463 | + $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url; |
|
| 3464 | + $notices = EE_Error::get_notices(false); |
|
| 3465 | + // overwrite default success messages //BUT ONLY if overwrite not overridden |
|
| 3466 | + if (! $override_overwrite || ! empty($notices['errors'])) { |
|
| 3467 | + EE_Error::overwrite_success(); |
|
| 3468 | + } |
|
| 3469 | + if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) { |
|
| 3470 | + // how many records affected ? more than one record ? or just one ? |
|
| 3471 | + if ($success > 1) { |
|
| 3472 | + // set plural msg |
|
| 3473 | + EE_Error::add_success( |
|
| 3474 | + sprintf( |
|
| 3475 | + esc_html__('The "%s" have been successfully %s.', 'event_espresso'), |
|
| 3476 | + $what, |
|
| 3477 | + $action_desc |
|
| 3478 | + ), |
|
| 3479 | + __FILE__, |
|
| 3480 | + __FUNCTION__, |
|
| 3481 | + __LINE__ |
|
| 3482 | + ); |
|
| 3483 | + } elseif ($success === 1) { |
|
| 3484 | + // set singular msg |
|
| 3485 | + EE_Error::add_success( |
|
| 3486 | + sprintf( |
|
| 3487 | + esc_html__('The "%s" has been successfully %s.', 'event_espresso'), |
|
| 3488 | + $what, |
|
| 3489 | + $action_desc |
|
| 3490 | + ), |
|
| 3491 | + __FILE__, |
|
| 3492 | + __FUNCTION__, |
|
| 3493 | + __LINE__ |
|
| 3494 | + ); |
|
| 3495 | + } |
|
| 3496 | + } |
|
| 3497 | + // check that $query_args isn't something crazy |
|
| 3498 | + if (! is_array($query_args)) { |
|
| 3499 | + $query_args = array(); |
|
| 3500 | + } |
|
| 3501 | + /** |
|
| 3502 | + * Allow injecting actions before the query_args are modified for possible different |
|
| 3503 | + * redirections on save and close actions |
|
| 3504 | + * |
|
| 3505 | + * @since 4.2.0 |
|
| 3506 | + * @param array $query_args The original query_args array coming into the |
|
| 3507 | + * method. |
|
| 3508 | + */ |
|
| 3509 | + do_action( |
|
| 3510 | + "AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}", |
|
| 3511 | + $query_args |
|
| 3512 | + ); |
|
| 3513 | + // calculate where we're going (if we have a "save and close" button pushed) |
|
| 3514 | + if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) { |
|
| 3515 | + // even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce |
|
| 3516 | + $parsed_url = parse_url($this->_req_data['save_and_close_referrer']); |
|
| 3517 | + // regenerate query args array from referrer URL |
|
| 3518 | + parse_str($parsed_url['query'], $query_args); |
|
| 3519 | + // correct page and action will be in the query args now |
|
| 3520 | + $redirect_url = admin_url('admin.php'); |
|
| 3521 | + } |
|
| 3522 | + // merge any default query_args set in _default_route_query_args property |
|
| 3523 | + if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) { |
|
| 3524 | + $args_to_merge = array(); |
|
| 3525 | + foreach ($this->_default_route_query_args as $query_param => $query_value) { |
|
| 3526 | + // is there a wp_referer array in our _default_route_query_args property? |
|
| 3527 | + if ($query_param === 'wp_referer') { |
|
| 3528 | + $query_value = (array) $query_value; |
|
| 3529 | + foreach ($query_value as $reference => $value) { |
|
| 3530 | + if (strpos($reference, 'nonce') !== false) { |
|
| 3531 | + continue; |
|
| 3532 | + } |
|
| 3533 | + // finally we will override any arguments in the referer with |
|
| 3534 | + // what might be set on the _default_route_query_args array. |
|
| 3535 | + if (isset($this->_default_route_query_args[ $reference ])) { |
|
| 3536 | + $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]); |
|
| 3537 | + } else { |
|
| 3538 | + $args_to_merge[ $reference ] = urlencode($value); |
|
| 3539 | + } |
|
| 3540 | + } |
|
| 3541 | + continue; |
|
| 3542 | + } |
|
| 3543 | + $args_to_merge[ $query_param ] = $query_value; |
|
| 3544 | + } |
|
| 3545 | + // now let's merge these arguments but override with what was specifically sent in to the |
|
| 3546 | + // redirect. |
|
| 3547 | + $query_args = array_merge($args_to_merge, $query_args); |
|
| 3548 | + } |
|
| 3549 | + $this->_process_notices($query_args); |
|
| 3550 | + // generate redirect url |
|
| 3551 | + // if redirecting to anything other than the main page, add a nonce |
|
| 3552 | + if (isset($query_args['action'])) { |
|
| 3553 | + // manually generate wp_nonce and merge that with the query vars |
|
| 3554 | + // becuz the wp_nonce_url function wrecks havoc on some vars |
|
| 3555 | + $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce'); |
|
| 3556 | + } |
|
| 3557 | + // we're adding some hooks and filters in here for processing any things just before redirects |
|
| 3558 | + // (example: an admin page has done an insert or update and we want to run something after that). |
|
| 3559 | + do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args); |
|
| 3560 | + $redirect_url = apply_filters( |
|
| 3561 | + 'FHEE_redirect_' . $classname . $this->_req_action, |
|
| 3562 | + self::add_query_args_and_nonce($query_args, $redirect_url), |
|
| 3563 | + $query_args |
|
| 3564 | + ); |
|
| 3565 | + // check if we're doing ajax. If we are then lets just return the results and js can handle how it wants. |
|
| 3566 | + if (defined('DOING_AJAX')) { |
|
| 3567 | + $default_data = array( |
|
| 3568 | + 'close' => true, |
|
| 3569 | + 'redirect_url' => $redirect_url, |
|
| 3570 | + 'where' => 'main', |
|
| 3571 | + 'what' => 'append', |
|
| 3572 | + ); |
|
| 3573 | + $this->_template_args['success'] = $success; |
|
| 3574 | + $this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge( |
|
| 3575 | + $default_data, |
|
| 3576 | + $this->_template_args['data'] |
|
| 3577 | + ) : $default_data; |
|
| 3578 | + $this->_return_json(); |
|
| 3579 | + } |
|
| 3580 | + wp_safe_redirect($redirect_url); |
|
| 3581 | + exit(); |
|
| 3582 | + } |
|
| 3583 | + |
|
| 3584 | + |
|
| 3585 | + /** |
|
| 3586 | + * process any notices before redirecting (or returning ajax request) |
|
| 3587 | + * This method sets the $this->_template_args['notices'] attribute; |
|
| 3588 | + * |
|
| 3589 | + * @param array $query_args any query args that need to be used for notice transient ('action') |
|
| 3590 | + * @param bool $skip_route_verify This is typically used when we are processing notices REALLY early and |
|
| 3591 | + * page_routes haven't been defined yet. |
|
| 3592 | + * @param bool $sticky_notices This is used to flag that regardless of whether this is doing_ajax or not, we |
|
| 3593 | + * still save a transient for the notice. |
|
| 3594 | + * @return void |
|
| 3595 | + * @throws EE_Error |
|
| 3596 | + */ |
|
| 3597 | + protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true) |
|
| 3598 | + { |
|
| 3599 | + // first let's set individual error properties if doing_ajax and the properties aren't already set. |
|
| 3600 | + if (defined('DOING_AJAX') && DOING_AJAX) { |
|
| 3601 | + $notices = EE_Error::get_notices(false); |
|
| 3602 | + if (empty($this->_template_args['success'])) { |
|
| 3603 | + $this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false; |
|
| 3604 | + } |
|
| 3605 | + if (empty($this->_template_args['errors'])) { |
|
| 3606 | + $this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false; |
|
| 3607 | + } |
|
| 3608 | + if (empty($this->_template_args['attention'])) { |
|
| 3609 | + $this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false; |
|
| 3610 | + } |
|
| 3611 | + } |
|
| 3612 | + $this->_template_args['notices'] = EE_Error::get_notices(); |
|
| 3613 | + // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true) |
|
| 3614 | + if (! defined('DOING_AJAX') || $sticky_notices) { |
|
| 3615 | + $route = isset($query_args['action']) ? $query_args['action'] : 'default'; |
|
| 3616 | + $this->_add_transient( |
|
| 3617 | + $route, |
|
| 3618 | + $this->_template_args['notices'], |
|
| 3619 | + true, |
|
| 3620 | + $skip_route_verify |
|
| 3621 | + ); |
|
| 3622 | + } |
|
| 3623 | + } |
|
| 3624 | + |
|
| 3625 | + |
|
| 3626 | + /** |
|
| 3627 | + * get_action_link_or_button |
|
| 3628 | + * returns the button html for adding, editing, or deleting an item (depending on given type) |
|
| 3629 | + * |
|
| 3630 | + * @param string $action use this to indicate which action the url is generated with. |
|
| 3631 | + * @param string $type accepted strings must be defined in the $_labels['button'] array(as the key) |
|
| 3632 | + * property. |
|
| 3633 | + * @param array $extra_request if the button requires extra params you can include them in $key=>$value pairs. |
|
| 3634 | + * @param string $class Use this to give the class for the button. Defaults to 'button-primary' |
|
| 3635 | + * @param string $base_url If this is not provided |
|
| 3636 | + * the _admin_base_url will be used as the default for the button base_url. |
|
| 3637 | + * Otherwise this value will be used. |
|
| 3638 | + * @param bool $exclude_nonce If true then no nonce will be in the generated button link. |
|
| 3639 | + * @return string |
|
| 3640 | + * @throws InvalidArgumentException |
|
| 3641 | + * @throws InvalidInterfaceException |
|
| 3642 | + * @throws InvalidDataTypeException |
|
| 3643 | + * @throws EE_Error |
|
| 3644 | + */ |
|
| 3645 | + public function get_action_link_or_button( |
|
| 3646 | + $action, |
|
| 3647 | + $type = 'add', |
|
| 3648 | + $extra_request = array(), |
|
| 3649 | + $class = 'button-primary', |
|
| 3650 | + $base_url = '', |
|
| 3651 | + $exclude_nonce = false |
|
| 3652 | + ) { |
|
| 3653 | + // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along) |
|
| 3654 | + if (empty($base_url) && ! isset($this->_page_routes[ $action ])) { |
|
| 3655 | + throw new EE_Error( |
|
| 3656 | + sprintf( |
|
| 3657 | + esc_html__( |
|
| 3658 | + 'There is no page route for given action for the button. This action was given: %s', |
|
| 3659 | + 'event_espresso' |
|
| 3660 | + ), |
|
| 3661 | + $action |
|
| 3662 | + ) |
|
| 3663 | + ); |
|
| 3664 | + } |
|
| 3665 | + if (! isset($this->_labels['buttons'][ $type ])) { |
|
| 3666 | + throw new EE_Error( |
|
| 3667 | + sprintf( |
|
| 3668 | + __( |
|
| 3669 | + 'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.', |
|
| 3670 | + 'event_espresso' |
|
| 3671 | + ), |
|
| 3672 | + $type |
|
| 3673 | + ) |
|
| 3674 | + ); |
|
| 3675 | + } |
|
| 3676 | + // finally check user access for this button. |
|
| 3677 | + $has_access = $this->check_user_access($action, true); |
|
| 3678 | + if (! $has_access) { |
|
| 3679 | + return ''; |
|
| 3680 | + } |
|
| 3681 | + $_base_url = ! $base_url ? $this->_admin_base_url : $base_url; |
|
| 3682 | + $query_args = array( |
|
| 3683 | + 'action' => $action, |
|
| 3684 | + ); |
|
| 3685 | + // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten. |
|
| 3686 | + if (! empty($extra_request)) { |
|
| 3687 | + $query_args = array_merge($extra_request, $query_args); |
|
| 3688 | + } |
|
| 3689 | + $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce); |
|
| 3690 | + return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class); |
|
| 3691 | + } |
|
| 3692 | + |
|
| 3693 | + |
|
| 3694 | + /** |
|
| 3695 | + * _per_page_screen_option |
|
| 3696 | + * Utility function for adding in a per_page_option in the screen_options_dropdown. |
|
| 3697 | + * |
|
| 3698 | + * @return void |
|
| 3699 | + * @throws InvalidArgumentException |
|
| 3700 | + * @throws InvalidInterfaceException |
|
| 3701 | + * @throws InvalidDataTypeException |
|
| 3702 | + */ |
|
| 3703 | + protected function _per_page_screen_option() |
|
| 3704 | + { |
|
| 3705 | + $option = 'per_page'; |
|
| 3706 | + $args = array( |
|
| 3707 | + 'label' => apply_filters( |
|
| 3708 | + 'FHEE__EE_Admin_Page___per_page_screen_options___label', |
|
| 3709 | + $this->_admin_page_title, |
|
| 3710 | + $this |
|
| 3711 | + ), |
|
| 3712 | + 'default' => (int) apply_filters( |
|
| 3713 | + 'FHEE__EE_Admin_Page___per_page_screen_options__default', |
|
| 3714 | + 20 |
|
| 3715 | + ), |
|
| 3716 | + 'option' => $this->_current_page . '_' . $this->_current_view . '_per_page', |
|
| 3717 | + ); |
|
| 3718 | + // ONLY add the screen option if the user has access to it. |
|
| 3719 | + if ($this->check_user_access($this->_current_view, true)) { |
|
| 3720 | + add_screen_option($option, $args); |
|
| 3721 | + } |
|
| 3722 | + } |
|
| 3723 | + |
|
| 3724 | + |
|
| 3725 | + /** |
|
| 3726 | + * set_per_page_screen_option |
|
| 3727 | + * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page. |
|
| 3728 | + * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than |
|
| 3729 | + * admin_menu. |
|
| 3730 | + * |
|
| 3731 | + * @return void |
|
| 3732 | + */ |
|
| 3733 | + private function _set_per_page_screen_options() |
|
| 3734 | + { |
|
| 3735 | + if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) { |
|
| 3736 | + check_admin_referer('screen-options-nonce', 'screenoptionnonce'); |
|
| 3737 | + if (! $user = wp_get_current_user()) { |
|
| 3738 | + return; |
|
| 3739 | + } |
|
| 3740 | + $option = $_POST['wp_screen_options']['option']; |
|
| 3741 | + $value = $_POST['wp_screen_options']['value']; |
|
| 3742 | + if ($option != sanitize_key($option)) { |
|
| 3743 | + return; |
|
| 3744 | + } |
|
| 3745 | + $map_option = $option; |
|
| 3746 | + $option = str_replace('-', '_', $option); |
|
| 3747 | + switch ($map_option) { |
|
| 3748 | + case $this->_current_page . '_' . $this->_current_view . '_per_page': |
|
| 3749 | + $value = (int) $value; |
|
| 3750 | + $max_value = apply_filters( |
|
| 3751 | + 'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value', |
|
| 3752 | + 999, |
|
| 3753 | + $this->_current_page, |
|
| 3754 | + $this->_current_view |
|
| 3755 | + ); |
|
| 3756 | + if ($value < 1) { |
|
| 3757 | + return; |
|
| 3758 | + } |
|
| 3759 | + $value = min($value, $max_value); |
|
| 3760 | + break; |
|
| 3761 | + default: |
|
| 3762 | + $value = apply_filters( |
|
| 3763 | + 'FHEE__EE_Admin_Page___set_per_page_screen_options__value', |
|
| 3764 | + false, |
|
| 3765 | + $option, |
|
| 3766 | + $value |
|
| 3767 | + ); |
|
| 3768 | + if (false === $value) { |
|
| 3769 | + return; |
|
| 3770 | + } |
|
| 3771 | + break; |
|
| 3772 | + } |
|
| 3773 | + update_user_meta($user->ID, $option, $value); |
|
| 3774 | + wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer())); |
|
| 3775 | + exit; |
|
| 3776 | + } |
|
| 3777 | + } |
|
| 3778 | + |
|
| 3779 | + |
|
| 3780 | + /** |
|
| 3781 | + * This just allows for setting the $_template_args property if it needs to be set outside the object |
|
| 3782 | + * |
|
| 3783 | + * @param array $data array that will be assigned to template args. |
|
| 3784 | + */ |
|
| 3785 | + public function set_template_args($data) |
|
| 3786 | + { |
|
| 3787 | + $this->_template_args = array_merge($this->_template_args, (array) $data); |
|
| 3788 | + } |
|
| 3789 | + |
|
| 3790 | + |
|
| 3791 | + /** |
|
| 3792 | + * This makes available the WP transient system for temporarily moving data between routes |
|
| 3793 | + * |
|
| 3794 | + * @param string $route the route that should receive the transient |
|
| 3795 | + * @param array $data the data that gets sent |
|
| 3796 | + * @param bool $notices If this is for notices then we use this to indicate so, otherwise its just a |
|
| 3797 | + * normal route transient. |
|
| 3798 | + * @param bool $skip_route_verify Used to indicate we want to skip route verification. This is usually ONLY used |
|
| 3799 | + * when we are adding a transient before page_routes have been defined. |
|
| 3800 | + * @return void |
|
| 3801 | + * @throws EE_Error |
|
| 3802 | + */ |
|
| 3803 | + protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false) |
|
| 3804 | + { |
|
| 3805 | + $user_id = get_current_user_id(); |
|
| 3806 | + if (! $skip_route_verify) { |
|
| 3807 | + $this->_verify_route($route); |
|
| 3808 | + } |
|
| 3809 | + // now let's set the string for what kind of transient we're setting |
|
| 3810 | + $transient = $notices |
|
| 3811 | + ? 'ee_rte_n_tx_' . $route . '_' . $user_id |
|
| 3812 | + : 'rte_tx_' . $route . '_' . $user_id; |
|
| 3813 | + $data = $notices ? array('notices' => $data) : $data; |
|
| 3814 | + // is there already a transient for this route? If there is then let's ADD to that transient |
|
| 3815 | + $existing = is_multisite() && is_network_admin() |
|
| 3816 | + ? get_site_transient($transient) |
|
| 3817 | + : get_transient($transient); |
|
| 3818 | + if ($existing) { |
|
| 3819 | + $data = array_merge((array) $data, (array) $existing); |
|
| 3820 | + } |
|
| 3821 | + if (is_multisite() && is_network_admin()) { |
|
| 3822 | + set_site_transient($transient, $data, 8); |
|
| 3823 | + } else { |
|
| 3824 | + set_transient($transient, $data, 8); |
|
| 3825 | + } |
|
| 3826 | + } |
|
| 3827 | + |
|
| 3828 | + |
|
| 3829 | + /** |
|
| 3830 | + * this retrieves the temporary transient that has been set for moving data between routes. |
|
| 3831 | + * |
|
| 3832 | + * @param bool $notices true we get notices transient. False we just return normal route transient |
|
| 3833 | + * @param string $route |
|
| 3834 | + * @return mixed data |
|
| 3835 | + */ |
|
| 3836 | + protected function _get_transient($notices = false, $route = '') |
|
| 3837 | + { |
|
| 3838 | + $user_id = get_current_user_id(); |
|
| 3839 | + $route = ! $route ? $this->_req_action : $route; |
|
| 3840 | + $transient = $notices |
|
| 3841 | + ? 'ee_rte_n_tx_' . $route . '_' . $user_id |
|
| 3842 | + : 'rte_tx_' . $route . '_' . $user_id; |
|
| 3843 | + $data = is_multisite() && is_network_admin() |
|
| 3844 | + ? get_site_transient($transient) |
|
| 3845 | + : get_transient($transient); |
|
| 3846 | + // delete transient after retrieval (just in case it hasn't expired); |
|
| 3847 | + if (is_multisite() && is_network_admin()) { |
|
| 3848 | + delete_site_transient($transient); |
|
| 3849 | + } else { |
|
| 3850 | + delete_transient($transient); |
|
| 3851 | + } |
|
| 3852 | + return $notices && isset($data['notices']) ? $data['notices'] : $data; |
|
| 3853 | + } |
|
| 3854 | + |
|
| 3855 | + |
|
| 3856 | + /** |
|
| 3857 | + * The purpose of this method is just to run garbage collection on any EE transients that might have expired but |
|
| 3858 | + * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the |
|
| 3859 | + * default route callback on the EE_Admin page you want it run.) |
|
| 3860 | + * |
|
| 3861 | + * @return void |
|
| 3862 | + */ |
|
| 3863 | + protected function _transient_garbage_collection() |
|
| 3864 | + { |
|
| 3865 | + global $wpdb; |
|
| 3866 | + // retrieve all existing transients |
|
| 3867 | + $query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'"; |
|
| 3868 | + if ($results = $wpdb->get_results($query)) { |
|
| 3869 | + foreach ($results as $result) { |
|
| 3870 | + $transient = str_replace('_transient_', '', $result->option_name); |
|
| 3871 | + get_transient($transient); |
|
| 3872 | + if (is_multisite() && is_network_admin()) { |
|
| 3873 | + get_site_transient($transient); |
|
| 3874 | + } |
|
| 3875 | + } |
|
| 3876 | + } |
|
| 3877 | + } |
|
| 3878 | + |
|
| 3879 | + |
|
| 3880 | + /** |
|
| 3881 | + * get_view |
|
| 3882 | + * |
|
| 3883 | + * @return string content of _view property |
|
| 3884 | + */ |
|
| 3885 | + public function get_view() |
|
| 3886 | + { |
|
| 3887 | + return $this->_view; |
|
| 3888 | + } |
|
| 3889 | + |
|
| 3890 | + |
|
| 3891 | + /** |
|
| 3892 | + * getter for the protected $_views property |
|
| 3893 | + * |
|
| 3894 | + * @return array |
|
| 3895 | + */ |
|
| 3896 | + public function get_views() |
|
| 3897 | + { |
|
| 3898 | + return $this->_views; |
|
| 3899 | + } |
|
| 3900 | + |
|
| 3901 | + |
|
| 3902 | + /** |
|
| 3903 | + * get_current_page |
|
| 3904 | + * |
|
| 3905 | + * @return string _current_page property value |
|
| 3906 | + */ |
|
| 3907 | + public function get_current_page() |
|
| 3908 | + { |
|
| 3909 | + return $this->_current_page; |
|
| 3910 | + } |
|
| 3911 | + |
|
| 3912 | + |
|
| 3913 | + /** |
|
| 3914 | + * get_current_view |
|
| 3915 | + * |
|
| 3916 | + * @return string _current_view property value |
|
| 3917 | + */ |
|
| 3918 | + public function get_current_view() |
|
| 3919 | + { |
|
| 3920 | + return $this->_current_view; |
|
| 3921 | + } |
|
| 3922 | + |
|
| 3923 | + |
|
| 3924 | + /** |
|
| 3925 | + * get_current_screen |
|
| 3926 | + * |
|
| 3927 | + * @return object The current WP_Screen object |
|
| 3928 | + */ |
|
| 3929 | + public function get_current_screen() |
|
| 3930 | + { |
|
| 3931 | + return $this->_current_screen; |
|
| 3932 | + } |
|
| 3933 | + |
|
| 3934 | + |
|
| 3935 | + /** |
|
| 3936 | + * get_current_page_view_url |
|
| 3937 | + * |
|
| 3938 | + * @return string This returns the url for the current_page_view. |
|
| 3939 | + */ |
|
| 3940 | + public function get_current_page_view_url() |
|
| 3941 | + { |
|
| 3942 | + return $this->_current_page_view_url; |
|
| 3943 | + } |
|
| 3944 | + |
|
| 3945 | + |
|
| 3946 | + /** |
|
| 3947 | + * just returns the _req_data property |
|
| 3948 | + * |
|
| 3949 | + * @return array |
|
| 3950 | + */ |
|
| 3951 | + public function get_request_data() |
|
| 3952 | + { |
|
| 3953 | + return $this->_req_data; |
|
| 3954 | + } |
|
| 3955 | + |
|
| 3956 | + |
|
| 3957 | + /** |
|
| 3958 | + * returns the _req_data protected property |
|
| 3959 | + * |
|
| 3960 | + * @return string |
|
| 3961 | + */ |
|
| 3962 | + public function get_req_action() |
|
| 3963 | + { |
|
| 3964 | + return $this->_req_action; |
|
| 3965 | + } |
|
| 3966 | + |
|
| 3967 | + |
|
| 3968 | + /** |
|
| 3969 | + * @return bool value of $_is_caf property |
|
| 3970 | + */ |
|
| 3971 | + public function is_caf() |
|
| 3972 | + { |
|
| 3973 | + return $this->_is_caf; |
|
| 3974 | + } |
|
| 3975 | + |
|
| 3976 | + |
|
| 3977 | + /** |
|
| 3978 | + * @return mixed |
|
| 3979 | + */ |
|
| 3980 | + public function default_espresso_metaboxes() |
|
| 3981 | + { |
|
| 3982 | + return $this->_default_espresso_metaboxes; |
|
| 3983 | + } |
|
| 3984 | + |
|
| 3985 | + |
|
| 3986 | + /** |
|
| 3987 | + * @return mixed |
|
| 3988 | + */ |
|
| 3989 | + public function admin_base_url() |
|
| 3990 | + { |
|
| 3991 | + return $this->_admin_base_url; |
|
| 3992 | + } |
|
| 3993 | + |
|
| 3994 | + |
|
| 3995 | + /** |
|
| 3996 | + * @return mixed |
|
| 3997 | + */ |
|
| 3998 | + public function wp_page_slug() |
|
| 3999 | + { |
|
| 4000 | + return $this->_wp_page_slug; |
|
| 4001 | + } |
|
| 4002 | + |
|
| 4003 | + |
|
| 4004 | + /** |
|
| 4005 | + * updates espresso configuration settings |
|
| 4006 | + * |
|
| 4007 | + * @param string $tab |
|
| 4008 | + * @param EE_Config_Base|EE_Config $config |
|
| 4009 | + * @param string $file file where error occurred |
|
| 4010 | + * @param string $func function where error occurred |
|
| 4011 | + * @param string $line line no where error occurred |
|
| 4012 | + * @return boolean |
|
| 4013 | + */ |
|
| 4014 | + protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '') |
|
| 4015 | + { |
|
| 4016 | + // remove any options that are NOT going to be saved with the config settings. |
|
| 4017 | + if (isset($config->core->ee_ueip_optin)) { |
|
| 4018 | + // TODO: remove the following two lines and make sure values are migrated from 3.1 |
|
| 4019 | + update_option('ee_ueip_optin', $config->core->ee_ueip_optin); |
|
| 4020 | + update_option('ee_ueip_has_notified', true); |
|
| 4021 | + } |
|
| 4022 | + // and save it (note we're also doing the network save here) |
|
| 4023 | + $net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true; |
|
| 4024 | + $config_saved = EE_Config::instance()->update_espresso_config(false, false); |
|
| 4025 | + if ($config_saved && $net_saved) { |
|
| 4026 | + EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab)); |
|
| 4027 | + return true; |
|
| 4028 | + } |
|
| 4029 | + EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line); |
|
| 4030 | + return false; |
|
| 4031 | + } |
|
| 4032 | + |
|
| 4033 | + |
|
| 4034 | + /** |
|
| 4035 | + * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument. |
|
| 4036 | + * |
|
| 4037 | + * @return array |
|
| 4038 | + */ |
|
| 4039 | + public function get_yes_no_values() |
|
| 4040 | + { |
|
| 4041 | + return $this->_yes_no_values; |
|
| 4042 | + } |
|
| 4043 | + |
|
| 4044 | + |
|
| 4045 | + protected function _get_dir() |
|
| 4046 | + { |
|
| 4047 | + $reflector = new ReflectionClass(get_class($this)); |
|
| 4048 | + return dirname($reflector->getFileName()); |
|
| 4049 | + } |
|
| 4050 | + |
|
| 4051 | + |
|
| 4052 | + /** |
|
| 4053 | + * A helper for getting a "next link". |
|
| 4054 | + * |
|
| 4055 | + * @param string $url The url to link to |
|
| 4056 | + * @param string $class The class to use. |
|
| 4057 | + * @return string |
|
| 4058 | + */ |
|
| 4059 | + protected function _next_link($url, $class = 'dashicons dashicons-arrow-right') |
|
| 4060 | + { |
|
| 4061 | + return '<a class="' . $class . '" href="' . $url . '"></a>'; |
|
| 4062 | + } |
|
| 4063 | + |
|
| 4064 | + |
|
| 4065 | + /** |
|
| 4066 | + * A helper for getting a "previous link". |
|
| 4067 | + * |
|
| 4068 | + * @param string $url The url to link to |
|
| 4069 | + * @param string $class The class to use. |
|
| 4070 | + * @return string |
|
| 4071 | + */ |
|
| 4072 | + protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left') |
|
| 4073 | + { |
|
| 4074 | + return '<a class="' . $class . '" href="' . $url . '"></a>'; |
|
| 4075 | + } |
|
| 4076 | + |
|
| 4077 | + |
|
| 4078 | + |
|
| 4079 | + |
|
| 4080 | + |
|
| 4081 | + |
|
| 4082 | + |
|
| 4083 | + // below are some messages related methods that should be available across the EE_Admin system. Note, these methods are NOT page specific |
|
| 4084 | + |
|
| 4085 | + |
|
| 4086 | + /** |
|
| 4087 | + * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller |
|
| 4088 | + * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the |
|
| 4089 | + * _req_data array. |
|
| 4090 | + * |
|
| 4091 | + * @return bool success/fail |
|
| 4092 | + * @throws EE_Error |
|
| 4093 | + * @throws InvalidArgumentException |
|
| 4094 | + * @throws ReflectionException |
|
| 4095 | + * @throws InvalidDataTypeException |
|
| 4096 | + * @throws InvalidInterfaceException |
|
| 4097 | + */ |
|
| 4098 | + protected function _process_resend_registration() |
|
| 4099 | + { |
|
| 4100 | + $this->_template_args['success'] = EED_Messages::process_resend($this->_req_data); |
|
| 4101 | + do_action( |
|
| 4102 | + 'AHEE__EE_Admin_Page___process_resend_registration', |
|
| 4103 | + $this->_template_args['success'], |
|
| 4104 | + $this->_req_data |
|
| 4105 | + ); |
|
| 4106 | + return $this->_template_args['success']; |
|
| 4107 | + } |
|
| 4108 | + |
|
| 4109 | + |
|
| 4110 | + /** |
|
| 4111 | + * This automatically processes any payment message notifications when manual payment has been applied. |
|
| 4112 | + * |
|
| 4113 | + * @param \EE_Payment $payment |
|
| 4114 | + * @return bool success/fail |
|
| 4115 | + */ |
|
| 4116 | + protected function _process_payment_notification(EE_Payment $payment) |
|
| 4117 | + { |
|
| 4118 | + add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true'); |
|
| 4119 | + do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment); |
|
| 4120 | + $this->_template_args['success'] = apply_filters( |
|
| 4121 | + 'FHEE__EE_Admin_Page___process_admin_payment_notification__success', |
|
| 4122 | + false, |
|
| 4123 | + $payment |
|
| 4124 | + ); |
|
| 4125 | + return $this->_template_args['success']; |
|
| 4126 | + } |
|
| 4127 | 4127 | } |
@@ -500,7 +500,7 @@ discard block |
||
| 500 | 500 | ); |
| 501 | 501 | global $ee_menu_slugs; |
| 502 | 502 | $ee_menu_slugs = (array) $ee_menu_slugs; |
| 503 | - if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) { |
|
| 503 | + if ( ! defined('DOING_AJAX') && ( ! $this->_current_page || ! isset($ee_menu_slugs[$this->_current_page]))) { |
|
| 504 | 504 | return; |
| 505 | 505 | } |
| 506 | 506 | // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first |
@@ -524,7 +524,7 @@ discard block |
||
| 524 | 524 | ? $this->_req_data['route'] |
| 525 | 525 | : $this->_req_action; |
| 526 | 526 | $this->_current_view = $this->_req_action; |
| 527 | - $this->_req_nonce = $this->_req_action . '_nonce'; |
|
| 527 | + $this->_req_nonce = $this->_req_action.'_nonce'; |
|
| 528 | 528 | $this->_define_page_props(); |
| 529 | 529 | $this->_current_page_view_url = add_query_arg( |
| 530 | 530 | array('page' => $this->_current_page, 'action' => $this->_current_view), |
@@ -558,21 +558,21 @@ discard block |
||
| 558 | 558 | } |
| 559 | 559 | // filter routes and page_config so addons can add their stuff. Filtering done per class |
| 560 | 560 | $this->_page_routes = apply_filters( |
| 561 | - 'FHEE__' . get_class($this) . '__page_setup__page_routes', |
|
| 561 | + 'FHEE__'.get_class($this).'__page_setup__page_routes', |
|
| 562 | 562 | $this->_page_routes, |
| 563 | 563 | $this |
| 564 | 564 | ); |
| 565 | 565 | $this->_page_config = apply_filters( |
| 566 | - 'FHEE__' . get_class($this) . '__page_setup__page_config', |
|
| 566 | + 'FHEE__'.get_class($this).'__page_setup__page_config', |
|
| 567 | 567 | $this->_page_config, |
| 568 | 568 | $this |
| 569 | 569 | ); |
| 570 | 570 | // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present |
| 571 | 571 | // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action |
| 572 | - if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) { |
|
| 572 | + if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view)) { |
|
| 573 | 573 | add_action( |
| 574 | 574 | 'AHEE__EE_Admin_Page__route_admin_request', |
| 575 | - array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view), |
|
| 575 | + array($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view), |
|
| 576 | 576 | 10, |
| 577 | 577 | 2 |
| 578 | 578 | ); |
@@ -585,8 +585,8 @@ discard block |
||
| 585 | 585 | if ($this->_is_UI_request) { |
| 586 | 586 | // admin_init stuff - global, all views for this page class, specific view |
| 587 | 587 | add_action('admin_init', array($this, 'admin_init'), 10); |
| 588 | - if (method_exists($this, 'admin_init_' . $this->_current_view)) { |
|
| 589 | - add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15); |
|
| 588 | + if (method_exists($this, 'admin_init_'.$this->_current_view)) { |
|
| 589 | + add_action('admin_init', array($this, 'admin_init_'.$this->_current_view), 15); |
|
| 590 | 590 | } |
| 591 | 591 | } else { |
| 592 | 592 | // hijack regular WP loading and route admin request immediately |
@@ -606,12 +606,12 @@ discard block |
||
| 606 | 606 | */ |
| 607 | 607 | private function _do_other_page_hooks() |
| 608 | 608 | { |
| 609 | - $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array()); |
|
| 609 | + $registered_pages = apply_filters('FHEE_do_other_page_hooks_'.$this->page_slug, array()); |
|
| 610 | 610 | foreach ($registered_pages as $page) { |
| 611 | 611 | // now let's setup the file name and class that should be present |
| 612 | 612 | $classname = str_replace('.class.php', '', $page); |
| 613 | 613 | // autoloaders should take care of loading file |
| 614 | - if (! class_exists($classname)) { |
|
| 614 | + if ( ! class_exists($classname)) { |
|
| 615 | 615 | $error_msg[] = sprintf( |
| 616 | 616 | esc_html__( |
| 617 | 617 | 'Something went wrong with loading the %s admin hooks page.', |
@@ -628,7 +628,7 @@ discard block |
||
| 628 | 628 | ), |
| 629 | 629 | $page, |
| 630 | 630 | '<br />', |
| 631 | - '<strong>' . $classname . '</strong>' |
|
| 631 | + '<strong>'.$classname.'</strong>' |
|
| 632 | 632 | ); |
| 633 | 633 | throw new EE_Error(implode('||', $error_msg)); |
| 634 | 634 | } |
@@ -668,13 +668,13 @@ discard block |
||
| 668 | 668 | // load admin_notices - global, page class, and view specific |
| 669 | 669 | add_action('admin_notices', array($this, 'admin_notices_global'), 5); |
| 670 | 670 | add_action('admin_notices', array($this, 'admin_notices'), 10); |
| 671 | - if (method_exists($this, 'admin_notices_' . $this->_current_view)) { |
|
| 672 | - add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15); |
|
| 671 | + if (method_exists($this, 'admin_notices_'.$this->_current_view)) { |
|
| 672 | + add_action('admin_notices', array($this, 'admin_notices_'.$this->_current_view), 15); |
|
| 673 | 673 | } |
| 674 | 674 | // load network admin_notices - global, page class, and view specific |
| 675 | 675 | add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5); |
| 676 | - if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) { |
|
| 677 | - add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view)); |
|
| 676 | + if (method_exists($this, 'network_admin_notices_'.$this->_current_view)) { |
|
| 677 | + add_action('network_admin_notices', array($this, 'network_admin_notices_'.$this->_current_view)); |
|
| 678 | 678 | } |
| 679 | 679 | // this will save any per_page screen options if they are present |
| 680 | 680 | $this->_set_per_page_screen_options(); |
@@ -796,7 +796,7 @@ discard block |
||
| 796 | 796 | protected function _verify_routes() |
| 797 | 797 | { |
| 798 | 798 | do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
| 799 | - if (! $this->_current_page && ! defined('DOING_AJAX')) { |
|
| 799 | + if ( ! $this->_current_page && ! defined('DOING_AJAX')) { |
|
| 800 | 800 | return false; |
| 801 | 801 | } |
| 802 | 802 | $this->_route = false; |
@@ -808,7 +808,7 @@ discard block |
||
| 808 | 808 | $this->_admin_page_title |
| 809 | 809 | ); |
| 810 | 810 | // developer error msg |
| 811 | - $error_msg .= '||' . $error_msg |
|
| 811 | + $error_msg .= '||'.$error_msg |
|
| 812 | 812 | . esc_html__( |
| 813 | 813 | ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.', |
| 814 | 814 | 'event_espresso' |
@@ -817,9 +817,9 @@ discard block |
||
| 817 | 817 | } |
| 818 | 818 | // and that the requested page route exists |
| 819 | 819 | if (array_key_exists($this->_req_action, $this->_page_routes)) { |
| 820 | - $this->_route = $this->_page_routes[ $this->_req_action ]; |
|
| 821 | - $this->_route_config = isset($this->_page_config[ $this->_req_action ]) |
|
| 822 | - ? $this->_page_config[ $this->_req_action ] : array(); |
|
| 820 | + $this->_route = $this->_page_routes[$this->_req_action]; |
|
| 821 | + $this->_route_config = isset($this->_page_config[$this->_req_action]) |
|
| 822 | + ? $this->_page_config[$this->_req_action] : array(); |
|
| 823 | 823 | } else { |
| 824 | 824 | // user error msg |
| 825 | 825 | $error_msg = sprintf( |
@@ -830,7 +830,7 @@ discard block |
||
| 830 | 830 | $this->_admin_page_title |
| 831 | 831 | ); |
| 832 | 832 | // developer error msg |
| 833 | - $error_msg .= '||' . $error_msg |
|
| 833 | + $error_msg .= '||'.$error_msg |
|
| 834 | 834 | . sprintf( |
| 835 | 835 | esc_html__( |
| 836 | 836 | ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.', |
@@ -841,7 +841,7 @@ discard block |
||
| 841 | 841 | throw new EE_Error($error_msg); |
| 842 | 842 | } |
| 843 | 843 | // and that a default route exists |
| 844 | - if (! array_key_exists('default', $this->_page_routes)) { |
|
| 844 | + if ( ! array_key_exists('default', $this->_page_routes)) { |
|
| 845 | 845 | // user error msg |
| 846 | 846 | $error_msg = sprintf( |
| 847 | 847 | esc_html__( |
@@ -851,7 +851,7 @@ discard block |
||
| 851 | 851 | $this->_admin_page_title |
| 852 | 852 | ); |
| 853 | 853 | // developer error msg |
| 854 | - $error_msg .= '||' . $error_msg |
|
| 854 | + $error_msg .= '||'.$error_msg |
|
| 855 | 855 | . esc_html__( |
| 856 | 856 | ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.', |
| 857 | 857 | 'event_espresso' |
@@ -890,7 +890,7 @@ discard block |
||
| 890 | 890 | $this->_admin_page_title |
| 891 | 891 | ); |
| 892 | 892 | // developer error msg |
| 893 | - $error_msg .= '||' . $error_msg |
|
| 893 | + $error_msg .= '||'.$error_msg |
|
| 894 | 894 | . sprintf( |
| 895 | 895 | esc_html__( |
| 896 | 896 | ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property', |
@@ -915,7 +915,7 @@ discard block |
||
| 915 | 915 | protected function _verify_nonce($nonce, $nonce_ref) |
| 916 | 916 | { |
| 917 | 917 | // verify nonce against expected value |
| 918 | - if (! wp_verify_nonce($nonce, $nonce_ref)) { |
|
| 918 | + if ( ! wp_verify_nonce($nonce, $nonce_ref)) { |
|
| 919 | 919 | // these are not the droids you are looking for !!! |
| 920 | 920 | $msg = sprintf( |
| 921 | 921 | esc_html__('%sNonce Fail.%s', 'event_espresso'), |
@@ -932,7 +932,7 @@ discard block |
||
| 932 | 932 | __CLASS__ |
| 933 | 933 | ); |
| 934 | 934 | } |
| 935 | - if (! defined('DOING_AJAX')) { |
|
| 935 | + if ( ! defined('DOING_AJAX')) { |
|
| 936 | 936 | wp_die($msg); |
| 937 | 937 | } else { |
| 938 | 938 | EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
@@ -957,7 +957,7 @@ discard block |
||
| 957 | 957 | */ |
| 958 | 958 | protected function _route_admin_request() |
| 959 | 959 | { |
| 960 | - if (! $this->_is_UI_request) { |
|
| 960 | + if ( ! $this->_is_UI_request) { |
|
| 961 | 961 | $this->_verify_routes(); |
| 962 | 962 | } |
| 963 | 963 | $nonce_check = isset($this->_route_config['require_nonce']) |
@@ -965,8 +965,8 @@ discard block |
||
| 965 | 965 | : true; |
| 966 | 966 | if ($this->_req_action !== 'default' && $nonce_check) { |
| 967 | 967 | // set nonce from post data |
| 968 | - $nonce = isset($this->_req_data[ $this->_req_nonce ]) |
|
| 969 | - ? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) |
|
| 968 | + $nonce = isset($this->_req_data[$this->_req_nonce]) |
|
| 969 | + ? sanitize_text_field($this->_req_data[$this->_req_nonce]) |
|
| 970 | 970 | : ''; |
| 971 | 971 | $this->_verify_nonce($nonce, $this->_req_nonce); |
| 972 | 972 | } |
@@ -981,7 +981,7 @@ discard block |
||
| 981 | 981 | $error_msg = ''; |
| 982 | 982 | // action right before calling route |
| 983 | 983 | // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request') |
| 984 | - if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) { |
|
| 984 | + if ( ! did_action('AHEE__EE_Admin_Page__route_admin_request')) { |
|
| 985 | 985 | do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this); |
| 986 | 986 | } |
| 987 | 987 | // right before calling the route, let's remove _wp_http_referer from the |
@@ -990,7 +990,7 @@ discard block |
||
| 990 | 990 | '_wp_http_referer', |
| 991 | 991 | wp_unslash($_SERVER['REQUEST_URI']) |
| 992 | 992 | ); |
| 993 | - if (! empty($func)) { |
|
| 993 | + if ( ! empty($func)) { |
|
| 994 | 994 | if (is_array($func)) { |
| 995 | 995 | list($class, $method) = $func; |
| 996 | 996 | } elseif (strpos($func, '::') !== false) { |
@@ -999,7 +999,7 @@ discard block |
||
| 999 | 999 | $class = $this; |
| 1000 | 1000 | $method = $func; |
| 1001 | 1001 | } |
| 1002 | - if (! (is_object($class) && $class === $this)) { |
|
| 1002 | + if ( ! (is_object($class) && $class === $this)) { |
|
| 1003 | 1003 | // send along this admin page object for access by addons. |
| 1004 | 1004 | $args['admin_page_object'] = $this; |
| 1005 | 1005 | } |
@@ -1039,7 +1039,7 @@ discard block |
||
| 1039 | 1039 | $method |
| 1040 | 1040 | ); |
| 1041 | 1041 | } |
| 1042 | - if (! empty($error_msg)) { |
|
| 1042 | + if ( ! empty($error_msg)) { |
|
| 1043 | 1043 | throw new EE_Error($error_msg); |
| 1044 | 1044 | } |
| 1045 | 1045 | } |
@@ -1123,7 +1123,7 @@ discard block |
||
| 1123 | 1123 | if (strpos($key, 'nonce') !== false) { |
| 1124 | 1124 | continue; |
| 1125 | 1125 | } |
| 1126 | - $args[ 'wp_referer[' . $key . ']' ] = $value; |
|
| 1126 | + $args['wp_referer['.$key.']'] = $value; |
|
| 1127 | 1127 | } |
| 1128 | 1128 | } |
| 1129 | 1129 | return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce); |
@@ -1163,10 +1163,10 @@ discard block |
||
| 1163 | 1163 | protected function _add_help_tabs() |
| 1164 | 1164 | { |
| 1165 | 1165 | $tour_buttons = ''; |
| 1166 | - if (isset($this->_page_config[ $this->_req_action ])) { |
|
| 1167 | - $config = $this->_page_config[ $this->_req_action ]; |
|
| 1166 | + if (isset($this->_page_config[$this->_req_action])) { |
|
| 1167 | + $config = $this->_page_config[$this->_req_action]; |
|
| 1168 | 1168 | // is there a help tour for the current route? if there is let's setup the tour buttons |
| 1169 | - if (isset($this->_help_tour[ $this->_req_action ])) { |
|
| 1169 | + if (isset($this->_help_tour[$this->_req_action])) { |
|
| 1170 | 1170 | $tb = array(); |
| 1171 | 1171 | $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">'; |
| 1172 | 1172 | foreach ($this->_help_tour['tours'] as $tour) { |
@@ -1186,7 +1186,7 @@ discard block |
||
| 1186 | 1186 | // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well. |
| 1187 | 1187 | if (is_array($config) && isset($config['help_sidebar'])) { |
| 1188 | 1188 | // check that the callback given is valid |
| 1189 | - if (! method_exists($this, $config['help_sidebar'])) { |
|
| 1189 | + if ( ! method_exists($this, $config['help_sidebar'])) { |
|
| 1190 | 1190 | throw new EE_Error( |
| 1191 | 1191 | sprintf( |
| 1192 | 1192 | esc_html__( |
@@ -1199,7 +1199,7 @@ discard block |
||
| 1199 | 1199 | ); |
| 1200 | 1200 | } |
| 1201 | 1201 | $content = apply_filters( |
| 1202 | - 'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar', |
|
| 1202 | + 'FHEE__'.get_class($this).'__add_help_tabs__help_sidebar', |
|
| 1203 | 1203 | $this->{$config['help_sidebar']}() |
| 1204 | 1204 | ); |
| 1205 | 1205 | $content .= $tour_buttons; // add help tour buttons. |
@@ -1207,27 +1207,27 @@ discard block |
||
| 1207 | 1207 | $this->_current_screen->set_help_sidebar($content); |
| 1208 | 1208 | } |
| 1209 | 1209 | // if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar. |
| 1210 | - if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) { |
|
| 1210 | + if ( ! isset($config['help_sidebar']) && ! empty($tour_buttons)) { |
|
| 1211 | 1211 | $this->_current_screen->set_help_sidebar($tour_buttons); |
| 1212 | 1212 | } |
| 1213 | 1213 | // handle if no help_tabs are set so the sidebar will still show for the help tour buttons |
| 1214 | - if (! isset($config['help_tabs']) && ! empty($tour_buttons)) { |
|
| 1214 | + if ( ! isset($config['help_tabs']) && ! empty($tour_buttons)) { |
|
| 1215 | 1215 | $_ht['id'] = $this->page_slug; |
| 1216 | 1216 | $_ht['title'] = esc_html__('Help Tours', 'event_espresso'); |
| 1217 | 1217 | $_ht['content'] = '<p>' |
| 1218 | 1218 | . esc_html__( |
| 1219 | 1219 | 'The buttons to the right allow you to start/restart any help tours available for this page', |
| 1220 | 1220 | 'event_espresso' |
| 1221 | - ) . '</p>'; |
|
| 1221 | + ).'</p>'; |
|
| 1222 | 1222 | $this->_current_screen->add_help_tab($_ht); |
| 1223 | 1223 | } |
| 1224 | - if (! isset($config['help_tabs'])) { |
|
| 1224 | + if ( ! isset($config['help_tabs'])) { |
|
| 1225 | 1225 | return; |
| 1226 | 1226 | } //no help tabs for this route |
| 1227 | 1227 | foreach ((array) $config['help_tabs'] as $tab_id => $cfg) { |
| 1228 | 1228 | // we're here so there ARE help tabs! |
| 1229 | 1229 | // make sure we've got what we need |
| 1230 | - if (! isset($cfg['title'])) { |
|
| 1230 | + if ( ! isset($cfg['title'])) { |
|
| 1231 | 1231 | throw new EE_Error( |
| 1232 | 1232 | esc_html__( |
| 1233 | 1233 | 'The _page_config array is not set up properly for help tabs. It is missing a title', |
@@ -1235,7 +1235,7 @@ discard block |
||
| 1235 | 1235 | ) |
| 1236 | 1236 | ); |
| 1237 | 1237 | } |
| 1238 | - if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) { |
|
| 1238 | + if ( ! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) { |
|
| 1239 | 1239 | throw new EE_Error( |
| 1240 | 1240 | esc_html__( |
| 1241 | 1241 | 'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab', |
@@ -1244,11 +1244,11 @@ discard block |
||
| 1244 | 1244 | ); |
| 1245 | 1245 | } |
| 1246 | 1246 | // first priority goes to content. |
| 1247 | - if (! empty($cfg['content'])) { |
|
| 1247 | + if ( ! empty($cfg['content'])) { |
|
| 1248 | 1248 | $content = ! empty($cfg['content']) ? $cfg['content'] : null; |
| 1249 | 1249 | // second priority goes to filename |
| 1250 | - } elseif (! empty($cfg['filename'])) { |
|
| 1251 | - $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php'; |
|
| 1250 | + } elseif ( ! empty($cfg['filename'])) { |
|
| 1251 | + $file_path = $this->_get_dir().'/help_tabs/'.$cfg['filename'].'.help_tab.php'; |
|
| 1252 | 1252 | // it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too) |
| 1253 | 1253 | $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES |
| 1254 | 1254 | . basename($this->_get_dir()) |
@@ -1256,7 +1256,7 @@ discard block |
||
| 1256 | 1256 | . $cfg['filename'] |
| 1257 | 1257 | . '.help_tab.php' : $file_path; |
| 1258 | 1258 | // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error. |
| 1259 | - if (! isset($cfg['callback']) && ! is_readable($file_path)) { |
|
| 1259 | + if ( ! isset($cfg['callback']) && ! is_readable($file_path)) { |
|
| 1260 | 1260 | EE_Error::add_error( |
| 1261 | 1261 | sprintf( |
| 1262 | 1262 | esc_html__( |
@@ -1302,7 +1302,7 @@ discard block |
||
| 1302 | 1302 | return; |
| 1303 | 1303 | } |
| 1304 | 1304 | // setup config array for help tab method |
| 1305 | - $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id; |
|
| 1305 | + $id = $this->page_slug.'-'.$this->_req_action.'-'.$tab_id; |
|
| 1306 | 1306 | $_ht = array( |
| 1307 | 1307 | 'id' => $id, |
| 1308 | 1308 | 'title' => $cfg['title'], |
@@ -1346,7 +1346,7 @@ discard block |
||
| 1346 | 1346 | } |
| 1347 | 1347 | if (isset($config['help_tour'])) { |
| 1348 | 1348 | foreach ($config['help_tour'] as $tour) { |
| 1349 | - $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php'; |
|
| 1349 | + $file_path = $this->_get_dir().'/help_tours/'.$tour.'.class.php'; |
|
| 1350 | 1350 | // let's see if we can get that file... |
| 1351 | 1351 | // if not its possible this is a decaf route not set in caffeinated |
| 1352 | 1352 | // so lets try and get the caffeinated equivalent |
@@ -1356,7 +1356,7 @@ discard block |
||
| 1356 | 1356 | . $tour |
| 1357 | 1357 | . '.class.php' : $file_path; |
| 1358 | 1358 | // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error. |
| 1359 | - if (! is_readable($file_path)) { |
|
| 1359 | + if ( ! is_readable($file_path)) { |
|
| 1360 | 1360 | EE_Error::add_error( |
| 1361 | 1361 | sprintf( |
| 1362 | 1362 | esc_html__( |
@@ -1373,12 +1373,12 @@ discard block |
||
| 1373 | 1373 | return; |
| 1374 | 1374 | } |
| 1375 | 1375 | require_once $file_path; |
| 1376 | - if (! class_exists($tour)) { |
|
| 1376 | + if ( ! class_exists($tour)) { |
|
| 1377 | 1377 | $error_msg[] = sprintf( |
| 1378 | 1378 | esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'), |
| 1379 | 1379 | $tour |
| 1380 | 1380 | ); |
| 1381 | - $error_msg[] = $error_msg[0] . "\r\n" |
|
| 1381 | + $error_msg[] = $error_msg[0]."\r\n" |
|
| 1382 | 1382 | . sprintf( |
| 1383 | 1383 | esc_html__( |
| 1384 | 1384 | 'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.', |
@@ -1394,15 +1394,15 @@ discard block |
||
| 1394 | 1394 | } |
| 1395 | 1395 | $tour_obj = new $tour($this->_is_caf); |
| 1396 | 1396 | $tours[] = $tour_obj; |
| 1397 | - $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj); |
|
| 1397 | + $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($tour_obj); |
|
| 1398 | 1398 | } |
| 1399 | 1399 | // let's inject the end tour stop element common to all pages... this will only get seen once per machine. |
| 1400 | 1400 | $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf); |
| 1401 | 1401 | $tours[] = $end_stop_tour; |
| 1402 | - $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour); |
|
| 1402 | + $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($end_stop_tour); |
|
| 1403 | 1403 | } |
| 1404 | 1404 | } |
| 1405 | - if (! empty($tours)) { |
|
| 1405 | + if ( ! empty($tours)) { |
|
| 1406 | 1406 | $this->_help_tour['tours'] = $tours; |
| 1407 | 1407 | } |
| 1408 | 1408 | // that's it! Now that the $_help_tours property is set (or not) |
@@ -1421,8 +1421,8 @@ discard block |
||
| 1421 | 1421 | $qtips = (array) $this->_route_config['qtips']; |
| 1422 | 1422 | // load qtip loader |
| 1423 | 1423 | $path = array( |
| 1424 | - $this->_get_dir() . '/qtips/', |
|
| 1425 | - EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/', |
|
| 1424 | + $this->_get_dir().'/qtips/', |
|
| 1425 | + EE_ADMIN_PAGES.basename($this->_get_dir()).'/qtips/', |
|
| 1426 | 1426 | ); |
| 1427 | 1427 | EEH_Qtip_Loader::instance()->register($qtips, $path); |
| 1428 | 1428 | } |
@@ -1444,7 +1444,7 @@ discard block |
||
| 1444 | 1444 | do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
| 1445 | 1445 | $i = 0; |
| 1446 | 1446 | foreach ($this->_page_config as $slug => $config) { |
| 1447 | - if (! is_array($config) |
|
| 1447 | + if ( ! is_array($config) |
|
| 1448 | 1448 | || ( |
| 1449 | 1449 | is_array($config) |
| 1450 | 1450 | && ( |
@@ -1461,12 +1461,12 @@ discard block |
||
| 1461 | 1461 | // nav tab is only to appear when route requested. |
| 1462 | 1462 | continue; |
| 1463 | 1463 | } |
| 1464 | - if (! $this->check_user_access($slug, true)) { |
|
| 1464 | + if ( ! $this->check_user_access($slug, true)) { |
|
| 1465 | 1465 | // no nav tab because current user does not have access. |
| 1466 | 1466 | continue; |
| 1467 | 1467 | } |
| 1468 | - $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : ''; |
|
| 1469 | - $this->_nav_tabs[ $slug ] = array( |
|
| 1468 | + $css_class = isset($config['css_class']) ? $config['css_class'].' ' : ''; |
|
| 1469 | + $this->_nav_tabs[$slug] = array( |
|
| 1470 | 1470 | 'url' => isset($config['nav']['url']) |
| 1471 | 1471 | ? $config['nav']['url'] |
| 1472 | 1472 | : self::add_query_args_and_nonce( |
@@ -1478,14 +1478,14 @@ discard block |
||
| 1478 | 1478 | : ucwords( |
| 1479 | 1479 | str_replace('_', ' ', $slug) |
| 1480 | 1480 | ), |
| 1481 | - 'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class, |
|
| 1481 | + 'css_class' => $this->_req_action === $slug ? $css_class.'nav-tab-active' : $css_class, |
|
| 1482 | 1482 | 'order' => isset($config['nav']['order']) ? $config['nav']['order'] : $i, |
| 1483 | 1483 | ); |
| 1484 | 1484 | $i++; |
| 1485 | 1485 | } |
| 1486 | 1486 | // if $this->_nav_tabs is empty then lets set the default |
| 1487 | 1487 | if (empty($this->_nav_tabs)) { |
| 1488 | - $this->_nav_tabs[ $this->_default_nav_tab_name ] = array( |
|
| 1488 | + $this->_nav_tabs[$this->_default_nav_tab_name] = array( |
|
| 1489 | 1489 | 'url' => $this->_admin_base_url, |
| 1490 | 1490 | 'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)), |
| 1491 | 1491 | 'css_class' => 'nav-tab-active', |
@@ -1510,10 +1510,10 @@ discard block |
||
| 1510 | 1510 | foreach ($this->_route_config['labels'] as $label => $text) { |
| 1511 | 1511 | if (is_array($text)) { |
| 1512 | 1512 | foreach ($text as $sublabel => $subtext) { |
| 1513 | - $this->_labels[ $label ][ $sublabel ] = $subtext; |
|
| 1513 | + $this->_labels[$label][$sublabel] = $subtext; |
|
| 1514 | 1514 | } |
| 1515 | 1515 | } else { |
| 1516 | - $this->_labels[ $label ] = $text; |
|
| 1516 | + $this->_labels[$label] = $text; |
|
| 1517 | 1517 | } |
| 1518 | 1518 | } |
| 1519 | 1519 | } |
@@ -1535,12 +1535,12 @@ discard block |
||
| 1535 | 1535 | { |
| 1536 | 1536 | do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
| 1537 | 1537 | $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check; |
| 1538 | - $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ]) |
|
| 1538 | + $capability = ! empty($route_to_check) && isset($this->_page_routes[$route_to_check]) |
|
| 1539 | 1539 | && is_array( |
| 1540 | - $this->_page_routes[ $route_to_check ] |
|
| 1540 | + $this->_page_routes[$route_to_check] |
|
| 1541 | 1541 | ) |
| 1542 | - && ! empty($this->_page_routes[ $route_to_check ]['capability']) |
|
| 1543 | - ? $this->_page_routes[ $route_to_check ]['capability'] : null; |
|
| 1542 | + && ! empty($this->_page_routes[$route_to_check]['capability']) |
|
| 1543 | + ? $this->_page_routes[$route_to_check]['capability'] : null; |
|
| 1544 | 1544 | if (empty($capability) && empty($route_to_check)) { |
| 1545 | 1545 | $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options' |
| 1546 | 1546 | : $this->_route['capability']; |
@@ -1548,7 +1548,7 @@ discard block |
||
| 1548 | 1548 | $capability = empty($capability) ? 'manage_options' : $capability; |
| 1549 | 1549 | } |
| 1550 | 1550 | $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0; |
| 1551 | - if (! defined('DOING_AJAX') |
|
| 1551 | + if ( ! defined('DOING_AJAX') |
|
| 1552 | 1552 | && ( |
| 1553 | 1553 | ! function_exists('is_admin') |
| 1554 | 1554 | || ! EE_Registry::instance()->CAP->current_user_can( |
@@ -1651,17 +1651,17 @@ discard block |
||
| 1651 | 1651 | public function admin_footer_global() |
| 1652 | 1652 | { |
| 1653 | 1653 | // dialog container for dialog helper |
| 1654 | - $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n"; |
|
| 1654 | + $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">'."\n"; |
|
| 1655 | 1655 | $d_cont .= '<div class="ee-notices"></div>'; |
| 1656 | 1656 | $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>'; |
| 1657 | 1657 | $d_cont .= '</div>'; |
| 1658 | 1658 | echo $d_cont; |
| 1659 | 1659 | // help tour stuff? |
| 1660 | - if (isset($this->_help_tour[ $this->_req_action ])) { |
|
| 1661 | - echo implode('<br />', $this->_help_tour[ $this->_req_action ]); |
|
| 1660 | + if (isset($this->_help_tour[$this->_req_action])) { |
|
| 1661 | + echo implode('<br />', $this->_help_tour[$this->_req_action]); |
|
| 1662 | 1662 | } |
| 1663 | 1663 | // current set timezone for timezone js |
| 1664 | - echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>'; |
|
| 1664 | + echo '<span id="current_timezone" class="hidden">'.EEH_DTT_Helper::get_timezone().'</span>'; |
|
| 1665 | 1665 | } |
| 1666 | 1666 | |
| 1667 | 1667 | |
@@ -1695,7 +1695,7 @@ discard block |
||
| 1695 | 1695 | // loop through the array and setup content |
| 1696 | 1696 | foreach ($help_array as $trigger => $help) { |
| 1697 | 1697 | // make sure the array is setup properly |
| 1698 | - if (! isset($help['title']) || ! isset($help['content'])) { |
|
| 1698 | + if ( ! isset($help['title']) || ! isset($help['content'])) { |
|
| 1699 | 1699 | throw new EE_Error( |
| 1700 | 1700 | esc_html__( |
| 1701 | 1701 | 'Does not look like the popup content array has been setup correctly. Might want to double check that. Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class', |
@@ -1710,7 +1710,7 @@ discard block |
||
| 1710 | 1710 | 'help_popup_content' => $help['content'], |
| 1711 | 1711 | ); |
| 1712 | 1712 | $content .= EEH_Template::display_template( |
| 1713 | - EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php', |
|
| 1713 | + EE_ADMIN_TEMPLATE.'admin_help_popup.template.php', |
|
| 1714 | 1714 | $template_args, |
| 1715 | 1715 | true |
| 1716 | 1716 | ); |
@@ -1732,15 +1732,15 @@ discard block |
||
| 1732 | 1732 | private function _get_help_content() |
| 1733 | 1733 | { |
| 1734 | 1734 | // what is the method we're looking for? |
| 1735 | - $method_name = '_help_popup_content_' . $this->_req_action; |
|
| 1735 | + $method_name = '_help_popup_content_'.$this->_req_action; |
|
| 1736 | 1736 | // if method doesn't exist let's get out. |
| 1737 | - if (! method_exists($this, $method_name)) { |
|
| 1737 | + if ( ! method_exists($this, $method_name)) { |
|
| 1738 | 1738 | return array(); |
| 1739 | 1739 | } |
| 1740 | 1740 | // k we're good to go let's retrieve the help array |
| 1741 | 1741 | $help_array = call_user_func(array($this, $method_name)); |
| 1742 | 1742 | // make sure we've got an array! |
| 1743 | - if (! is_array($help_array)) { |
|
| 1743 | + if ( ! is_array($help_array)) { |
|
| 1744 | 1744 | throw new EE_Error( |
| 1745 | 1745 | esc_html__( |
| 1746 | 1746 | 'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.', |
@@ -1772,8 +1772,8 @@ discard block |
||
| 1772 | 1772 | // let's check and see if there is any content set for this popup. If there isn't then we'll include a default title and content so that developers know something needs to be corrected |
| 1773 | 1773 | $help_array = $this->_get_help_content(); |
| 1774 | 1774 | $help_content = ''; |
| 1775 | - if (empty($help_array) || ! isset($help_array[ $trigger_id ])) { |
|
| 1776 | - $help_array[ $trigger_id ] = array( |
|
| 1775 | + if (empty($help_array) || ! isset($help_array[$trigger_id])) { |
|
| 1776 | + $help_array[$trigger_id] = array( |
|
| 1777 | 1777 | 'title' => esc_html__('Missing Content', 'event_espresso'), |
| 1778 | 1778 | 'content' => esc_html__( |
| 1779 | 1779 | 'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)', |
@@ -1849,15 +1849,15 @@ discard block |
||
| 1849 | 1849 | // register all styles |
| 1850 | 1850 | wp_register_style( |
| 1851 | 1851 | 'espresso-ui-theme', |
| 1852 | - EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', |
|
| 1852 | + EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', |
|
| 1853 | 1853 | array(), |
| 1854 | 1854 | EVENT_ESPRESSO_VERSION |
| 1855 | 1855 | ); |
| 1856 | - wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 1856 | + wp_register_style('ee-admin-css', EE_ADMIN_URL.'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 1857 | 1857 | // helpers styles |
| 1858 | 1858 | wp_register_style( |
| 1859 | 1859 | 'ee-text-links', |
| 1860 | - EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css', |
|
| 1860 | + EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.css', |
|
| 1861 | 1861 | array(), |
| 1862 | 1862 | EVENT_ESPRESSO_VERSION |
| 1863 | 1863 | ); |
@@ -1865,21 +1865,21 @@ discard block |
||
| 1865 | 1865 | // register all scripts |
| 1866 | 1866 | wp_register_script( |
| 1867 | 1867 | 'ee-dialog', |
| 1868 | - EE_ADMIN_URL . 'assets/ee-dialog-helper.js', |
|
| 1868 | + EE_ADMIN_URL.'assets/ee-dialog-helper.js', |
|
| 1869 | 1869 | array('jquery', 'jquery-ui-draggable'), |
| 1870 | 1870 | EVENT_ESPRESSO_VERSION, |
| 1871 | 1871 | true |
| 1872 | 1872 | ); |
| 1873 | 1873 | wp_register_script( |
| 1874 | 1874 | 'ee_admin_js', |
| 1875 | - EE_ADMIN_URL . 'assets/ee-admin-page.js', |
|
| 1875 | + EE_ADMIN_URL.'assets/ee-admin-page.js', |
|
| 1876 | 1876 | array('espresso_core', 'ee-parse-uri', 'ee-dialog'), |
| 1877 | 1877 | EVENT_ESPRESSO_VERSION, |
| 1878 | 1878 | true |
| 1879 | 1879 | ); |
| 1880 | 1880 | wp_register_script( |
| 1881 | 1881 | 'jquery-ui-timepicker-addon', |
| 1882 | - EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js', |
|
| 1882 | + EE_GLOBAL_ASSETS_URL.'scripts/jquery-ui-timepicker-addon.js', |
|
| 1883 | 1883 | array('jquery-ui-datepicker', 'jquery-ui-slider'), |
| 1884 | 1884 | EVENT_ESPRESSO_VERSION, |
| 1885 | 1885 | true |
@@ -1888,7 +1888,7 @@ discard block |
||
| 1888 | 1888 | // script for sorting tables |
| 1889 | 1889 | wp_register_script( |
| 1890 | 1890 | 'espresso_ajax_table_sorting', |
| 1891 | - EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js', |
|
| 1891 | + EE_ADMIN_URL.'assets/espresso_ajax_table_sorting.js', |
|
| 1892 | 1892 | array('ee_admin_js', 'jquery-ui-sortable'), |
| 1893 | 1893 | EVENT_ESPRESSO_VERSION, |
| 1894 | 1894 | true |
@@ -1896,7 +1896,7 @@ discard block |
||
| 1896 | 1896 | // script for parsing uri's |
| 1897 | 1897 | wp_register_script( |
| 1898 | 1898 | 'ee-parse-uri', |
| 1899 | - EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js', |
|
| 1899 | + EE_GLOBAL_ASSETS_URL.'scripts/parseuri.js', |
|
| 1900 | 1900 | array(), |
| 1901 | 1901 | EVENT_ESPRESSO_VERSION, |
| 1902 | 1902 | true |
@@ -1904,7 +1904,7 @@ discard block |
||
| 1904 | 1904 | // and parsing associative serialized form elements |
| 1905 | 1905 | wp_register_script( |
| 1906 | 1906 | 'ee-serialize-full-array', |
| 1907 | - EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js', |
|
| 1907 | + EE_GLOBAL_ASSETS_URL.'scripts/jquery.serializefullarray.js', |
|
| 1908 | 1908 | array('jquery'), |
| 1909 | 1909 | EVENT_ESPRESSO_VERSION, |
| 1910 | 1910 | true |
@@ -1912,28 +1912,28 @@ discard block |
||
| 1912 | 1912 | // helpers scripts |
| 1913 | 1913 | wp_register_script( |
| 1914 | 1914 | 'ee-text-links', |
| 1915 | - EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js', |
|
| 1915 | + EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.js', |
|
| 1916 | 1916 | array('jquery'), |
| 1917 | 1917 | EVENT_ESPRESSO_VERSION, |
| 1918 | 1918 | true |
| 1919 | 1919 | ); |
| 1920 | 1920 | wp_register_script( |
| 1921 | 1921 | 'ee-moment-core', |
| 1922 | - EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js', |
|
| 1922 | + EE_THIRD_PARTY_URL.'moment/moment-with-locales.min.js', |
|
| 1923 | 1923 | array(), |
| 1924 | 1924 | EVENT_ESPRESSO_VERSION, |
| 1925 | 1925 | true |
| 1926 | 1926 | ); |
| 1927 | 1927 | wp_register_script( |
| 1928 | 1928 | 'ee-moment', |
| 1929 | - EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js', |
|
| 1929 | + EE_THIRD_PARTY_URL.'moment/moment-timezone-with-data.min.js', |
|
| 1930 | 1930 | array('ee-moment-core'), |
| 1931 | 1931 | EVENT_ESPRESSO_VERSION, |
| 1932 | 1932 | true |
| 1933 | 1933 | ); |
| 1934 | 1934 | wp_register_script( |
| 1935 | 1935 | 'ee-datepicker', |
| 1936 | - EE_ADMIN_URL . 'assets/ee-datepicker.js', |
|
| 1936 | + EE_ADMIN_URL.'assets/ee-datepicker.js', |
|
| 1937 | 1937 | array('jquery-ui-timepicker-addon', 'ee-moment'), |
| 1938 | 1938 | EVENT_ESPRESSO_VERSION, |
| 1939 | 1939 | true |
@@ -1967,11 +1967,11 @@ discard block |
||
| 1967 | 1967 | /** |
| 1968 | 1968 | * help tour stuff |
| 1969 | 1969 | */ |
| 1970 | - if (! empty($this->_help_tour)) { |
|
| 1970 | + if ( ! empty($this->_help_tour)) { |
|
| 1971 | 1971 | // register the js for kicking things off |
| 1972 | 1972 | wp_enqueue_script( |
| 1973 | 1973 | 'ee-help-tour', |
| 1974 | - EE_ADMIN_URL . 'assets/ee-help-tour.js', |
|
| 1974 | + EE_ADMIN_URL.'assets/ee-help-tour.js', |
|
| 1975 | 1975 | array('jquery-joyride'), |
| 1976 | 1976 | EVENT_ESPRESSO_VERSION, |
| 1977 | 1977 | true |
@@ -2068,12 +2068,12 @@ discard block |
||
| 2068 | 2068 | protected function _set_list_table() |
| 2069 | 2069 | { |
| 2070 | 2070 | // first is this a list_table view? |
| 2071 | - if (! isset($this->_route_config['list_table'])) { |
|
| 2071 | + if ( ! isset($this->_route_config['list_table'])) { |
|
| 2072 | 2072 | return; |
| 2073 | 2073 | } //not a list_table view so get out. |
| 2074 | 2074 | // list table functions are per view specific (because some admin pages might have more than one list table!) |
| 2075 | - $list_table_view = '_set_list_table_views_' . $this->_req_action; |
|
| 2076 | - if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) { |
|
| 2075 | + $list_table_view = '_set_list_table_views_'.$this->_req_action; |
|
| 2076 | + if ( ! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) { |
|
| 2077 | 2077 | // user error msg |
| 2078 | 2078 | $error_msg = esc_html__( |
| 2079 | 2079 | 'An error occurred. The requested list table views could not be found.', |
@@ -2093,10 +2093,10 @@ discard block |
||
| 2093 | 2093 | } |
| 2094 | 2094 | // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally |
| 2095 | 2095 | $this->_views = apply_filters( |
| 2096 | - 'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action, |
|
| 2096 | + 'FHEE_list_table_views_'.$this->page_slug.'_'.$this->_req_action, |
|
| 2097 | 2097 | $this->_views |
| 2098 | 2098 | ); |
| 2099 | - $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views); |
|
| 2099 | + $this->_views = apply_filters('FHEE_list_table_views_'.$this->page_slug, $this->_views); |
|
| 2100 | 2100 | $this->_views = apply_filters('FHEE_list_table_views', $this->_views); |
| 2101 | 2101 | $this->_set_list_table_view(); |
| 2102 | 2102 | $this->_set_list_table_object(); |
@@ -2112,7 +2112,7 @@ discard block |
||
| 2112 | 2112 | { |
| 2113 | 2113 | do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
| 2114 | 2114 | // looking at active items or dumpster diving ? |
| 2115 | - if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) { |
|
| 2115 | + if ( ! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) { |
|
| 2116 | 2116 | $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all'; |
| 2117 | 2117 | } else { |
| 2118 | 2118 | $this->_view = sanitize_key($this->_req_data['status']); |
@@ -2133,7 +2133,7 @@ discard block |
||
| 2133 | 2133 | protected function _set_list_table_object() |
| 2134 | 2134 | { |
| 2135 | 2135 | if (isset($this->_route_config['list_table'])) { |
| 2136 | - if (! class_exists($this->_route_config['list_table'])) { |
|
| 2136 | + if ( ! class_exists($this->_route_config['list_table'])) { |
|
| 2137 | 2137 | throw new EE_Error( |
| 2138 | 2138 | sprintf( |
| 2139 | 2139 | esc_html__( |
@@ -2171,15 +2171,15 @@ discard block |
||
| 2171 | 2171 | foreach ($this->_views as $key => $view) { |
| 2172 | 2172 | $query_args = array(); |
| 2173 | 2173 | // check for current view |
| 2174 | - $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : ''; |
|
| 2174 | + $this->_views[$key]['class'] = $this->_view === $view['slug'] ? 'current' : ''; |
|
| 2175 | 2175 | $query_args['action'] = $this->_req_action; |
| 2176 | - $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce'); |
|
| 2176 | + $query_args[$this->_req_action.'_nonce'] = wp_create_nonce($query_args['action'].'_nonce'); |
|
| 2177 | 2177 | $query_args['status'] = $view['slug']; |
| 2178 | 2178 | // merge any other arguments sent in. |
| 2179 | - if (isset($extra_query_args[ $view['slug'] ])) { |
|
| 2180 | - $query_args = array_merge($query_args, $extra_query_args[ $view['slug'] ]); |
|
| 2179 | + if (isset($extra_query_args[$view['slug']])) { |
|
| 2180 | + $query_args = array_merge($query_args, $extra_query_args[$view['slug']]); |
|
| 2181 | 2181 | } |
| 2182 | - $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url); |
|
| 2182 | + $this->_views[$key]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url); |
|
| 2183 | 2183 | } |
| 2184 | 2184 | return $this->_views; |
| 2185 | 2185 | } |
@@ -2198,7 +2198,7 @@ discard block |
||
| 2198 | 2198 | { |
| 2199 | 2199 | do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
| 2200 | 2200 | $values = array(10, 25, 50, 100); |
| 2201 | - $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10; |
|
| 2201 | + $per_page = ( ! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10; |
|
| 2202 | 2202 | if ($max_entries) { |
| 2203 | 2203 | $values[] = $max_entries; |
| 2204 | 2204 | sort($values); |
@@ -2210,14 +2210,14 @@ discard block |
||
| 2210 | 2210 | <select id="entries-per-page-slct" name="entries-per-page-slct">'; |
| 2211 | 2211 | foreach ($values as $value) { |
| 2212 | 2212 | if ($value < $max_entries) { |
| 2213 | - $selected = $value === $per_page ? ' selected="' . $per_page . '"' : ''; |
|
| 2213 | + $selected = $value === $per_page ? ' selected="'.$per_page.'"' : ''; |
|
| 2214 | 2214 | $entries_per_page_dropdown .= ' |
| 2215 | - <option value="' . $value . '"' . $selected . '>' . $value . ' </option>'; |
|
| 2215 | + <option value="' . $value.'"'.$selected.'>'.$value.' </option>'; |
|
| 2216 | 2216 | } |
| 2217 | 2217 | } |
| 2218 | - $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : ''; |
|
| 2218 | + $selected = $max_entries === $per_page ? ' selected="'.$per_page.'"' : ''; |
|
| 2219 | 2219 | $entries_per_page_dropdown .= ' |
| 2220 | - <option value="' . $max_entries . '"' . $selected . '>All </option>'; |
|
| 2220 | + <option value="' . $max_entries.'"'.$selected.'>All </option>'; |
|
| 2221 | 2221 | $entries_per_page_dropdown .= ' |
| 2222 | 2222 | </select> |
| 2223 | 2223 | entries |
@@ -2241,7 +2241,7 @@ discard block |
||
| 2241 | 2241 | empty($this->_search_btn_label) ? $this->page_label |
| 2242 | 2242 | : $this->_search_btn_label |
| 2243 | 2243 | ); |
| 2244 | - $this->_template_args['search']['callback'] = 'search_' . $this->page_slug; |
|
| 2244 | + $this->_template_args['search']['callback'] = 'search_'.$this->page_slug; |
|
| 2245 | 2245 | } |
| 2246 | 2246 | |
| 2247 | 2247 | |
@@ -2327,7 +2327,7 @@ discard block |
||
| 2327 | 2327 | $total_columns = ! empty($screen_columns) |
| 2328 | 2328 | ? $screen_columns |
| 2329 | 2329 | : $this->_route_config['columns'][1]; |
| 2330 | - $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns; |
|
| 2330 | + $this->_template_args['current_screen_widget_class'] = 'columns-'.$total_columns; |
|
| 2331 | 2331 | $this->_template_args['current_page'] = $this->_wp_page_slug; |
| 2332 | 2332 | $this->_template_args['screen'] = $this->_current_screen; |
| 2333 | 2333 | $this->_column_template_path = EE_ADMIN_TEMPLATE |
@@ -2372,7 +2372,7 @@ discard block |
||
| 2372 | 2372 | */ |
| 2373 | 2373 | protected function _espresso_ratings_request() |
| 2374 | 2374 | { |
| 2375 | - if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) { |
|
| 2375 | + if ( ! apply_filters('FHEE_show_ratings_request_meta_box', true)) { |
|
| 2376 | 2376 | return; |
| 2377 | 2377 | } |
| 2378 | 2378 | $ratings_box_title = apply_filters( |
@@ -2400,7 +2400,7 @@ discard block |
||
| 2400 | 2400 | public function espresso_ratings_request() |
| 2401 | 2401 | { |
| 2402 | 2402 | EEH_Template::display_template( |
| 2403 | - EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php', |
|
| 2403 | + EE_ADMIN_TEMPLATE.'espresso_ratings_request_content.template.php', |
|
| 2404 | 2404 | array() |
| 2405 | 2405 | ); |
| 2406 | 2406 | } |
@@ -2413,17 +2413,17 @@ discard block |
||
| 2413 | 2413 | . '</p><p class="hide-if-js">' |
| 2414 | 2414 | . esc_html__('This widget requires JavaScript.', 'event_espresso') |
| 2415 | 2415 | . '</p>'; |
| 2416 | - $pre = '<div class="espresso-rss-display">' . "\n\t"; |
|
| 2417 | - $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>'; |
|
| 2418 | - $post = '</div>' . "\n"; |
|
| 2419 | - $cache_key = 'ee_rss_' . md5($rss_id); |
|
| 2416 | + $pre = '<div class="espresso-rss-display">'."\n\t"; |
|
| 2417 | + $pre .= '<span id="'.$rss_id.'_url" class="hidden">'.$url.'</span>'; |
|
| 2418 | + $post = '</div>'."\n"; |
|
| 2419 | + $cache_key = 'ee_rss_'.md5($rss_id); |
|
| 2420 | 2420 | $output = get_transient($cache_key); |
| 2421 | 2421 | if ($output !== false) { |
| 2422 | - echo $pre . $output . $post; |
|
| 2422 | + echo $pre.$output.$post; |
|
| 2423 | 2423 | return true; |
| 2424 | 2424 | } |
| 2425 | - if (! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
| 2426 | - echo $pre . $loading . $post; |
|
| 2425 | + if ( ! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
| 2426 | + echo $pre.$loading.$post; |
|
| 2427 | 2427 | return false; |
| 2428 | 2428 | } |
| 2429 | 2429 | ob_start(); |
@@ -2490,19 +2490,19 @@ discard block |
||
| 2490 | 2490 | public function espresso_sponsors_post_box() |
| 2491 | 2491 | { |
| 2492 | 2492 | EEH_Template::display_template( |
| 2493 | - EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php' |
|
| 2493 | + EE_ADMIN_TEMPLATE.'admin_general_metabox_contents_espresso_sponsors.template.php' |
|
| 2494 | 2494 | ); |
| 2495 | 2495 | } |
| 2496 | 2496 | |
| 2497 | 2497 | |
| 2498 | 2498 | private function _publish_post_box() |
| 2499 | 2499 | { |
| 2500 | - $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview'; |
|
| 2500 | + $meta_box_ref = 'espresso_'.$this->page_slug.'_editor_overview'; |
|
| 2501 | 2501 | // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array |
| 2502 | 2502 | // then we'll use that for the metabox label. |
| 2503 | 2503 | // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes) |
| 2504 | - if (! empty($this->_labels['publishbox'])) { |
|
| 2505 | - $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ] |
|
| 2504 | + if ( ! empty($this->_labels['publishbox'])) { |
|
| 2505 | + $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][$this->_req_action] |
|
| 2506 | 2506 | : $this->_labels['publishbox']; |
| 2507 | 2507 | } else { |
| 2508 | 2508 | $box_label = esc_html__('Publish', 'event_espresso'); |
@@ -2531,7 +2531,7 @@ discard block |
||
| 2531 | 2531 | ? $this->_template_args['publish_box_extra_content'] |
| 2532 | 2532 | : ''; |
| 2533 | 2533 | echo EEH_Template::display_template( |
| 2534 | - EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php', |
|
| 2534 | + EE_ADMIN_TEMPLATE.'admin_details_publish_metabox.template.php', |
|
| 2535 | 2535 | $this->_template_args, |
| 2536 | 2536 | true |
| 2537 | 2537 | ); |
@@ -2623,8 +2623,8 @@ discard block |
||
| 2623 | 2623 | ); |
| 2624 | 2624 | } |
| 2625 | 2625 | $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : ''; |
| 2626 | - if (! empty($name) && ! empty($id)) { |
|
| 2627 | - $hidden_field_arr[ $name ] = array( |
|
| 2626 | + if ( ! empty($name) && ! empty($id)) { |
|
| 2627 | + $hidden_field_arr[$name] = array( |
|
| 2628 | 2628 | 'type' => 'hidden', |
| 2629 | 2629 | 'value' => $id, |
| 2630 | 2630 | ); |
@@ -2634,7 +2634,7 @@ discard block |
||
| 2634 | 2634 | } |
| 2635 | 2635 | // add hidden field |
| 2636 | 2636 | $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name) |
| 2637 | - ? $hf[ $name ]['field'] |
|
| 2637 | + ? $hf[$name]['field'] |
|
| 2638 | 2638 | : $hf; |
| 2639 | 2639 | } |
| 2640 | 2640 | |
@@ -2736,7 +2736,7 @@ discard block |
||
| 2736 | 2736 | } |
| 2737 | 2737 | // if $create_func is true (default) then we automatically create the function for displaying the actual meta box. If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish) |
| 2738 | 2738 | $call_back_func = $create_func |
| 2739 | - ? function ($post, $metabox) { |
|
| 2739 | + ? function($post, $metabox) { |
|
| 2740 | 2740 | do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
| 2741 | 2741 | echo EEH_Template::display_template( |
| 2742 | 2742 | $metabox['args']['template_path'], |
@@ -2746,7 +2746,7 @@ discard block |
||
| 2746 | 2746 | } |
| 2747 | 2747 | : $callback; |
| 2748 | 2748 | add_meta_box( |
| 2749 | - str_replace('_', '-', $action) . '-mbox', |
|
| 2749 | + str_replace('_', '-', $action).'-mbox', |
|
| 2750 | 2750 | $title, |
| 2751 | 2751 | $call_back_func, |
| 2752 | 2752 | $this->_wp_page_slug, |
@@ -2838,9 +2838,9 @@ discard block |
||
| 2838 | 2838 | : 'espresso-default-admin'; |
| 2839 | 2839 | $template_path = $sidebar |
| 2840 | 2840 | ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php' |
| 2841 | - : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php'; |
|
| 2841 | + : EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar.template.php'; |
|
| 2842 | 2842 | if (defined('DOING_AJAX') && DOING_AJAX) { |
| 2843 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php'; |
|
| 2843 | + $template_path = EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar_ajax.template.php'; |
|
| 2844 | 2844 | } |
| 2845 | 2845 | $template_path = ! empty($this->_column_template_path) |
| 2846 | 2846 | ? $this->_column_template_path : $template_path; |
@@ -2905,7 +2905,7 @@ discard block |
||
| 2905 | 2905 | ) |
| 2906 | 2906 | : $this->_template_args['preview_action_button']; |
| 2907 | 2907 | $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
| 2908 | - EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php', |
|
| 2908 | + EE_ADMIN_TEMPLATE.'admin_caf_full_page_preview.template.php', |
|
| 2909 | 2909 | $this->_template_args, |
| 2910 | 2910 | true |
| 2911 | 2911 | ); |
@@ -2954,7 +2954,7 @@ discard block |
||
| 2954 | 2954 | // setup search attributes |
| 2955 | 2955 | $this->_set_search_attributes(); |
| 2956 | 2956 | $this->_template_args['current_page'] = $this->_wp_page_slug; |
| 2957 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php'; |
|
| 2957 | + $template_path = EE_ADMIN_TEMPLATE.'admin_list_wrapper.template.php'; |
|
| 2958 | 2958 | $this->_template_args['table_url'] = defined('DOING_AJAX') |
| 2959 | 2959 | ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url) |
| 2960 | 2960 | : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url); |
@@ -2962,10 +2962,10 @@ discard block |
||
| 2962 | 2962 | $this->_template_args['current_route'] = $this->_req_action; |
| 2963 | 2963 | $this->_template_args['list_table_class'] = get_class($this->_list_table_object); |
| 2964 | 2964 | $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback(); |
| 2965 | - if (! empty($ajax_sorting_callback)) { |
|
| 2965 | + if ( ! empty($ajax_sorting_callback)) { |
|
| 2966 | 2966 | $sortable_list_table_form_fields = wp_nonce_field( |
| 2967 | - $ajax_sorting_callback . '_nonce', |
|
| 2968 | - $ajax_sorting_callback . '_nonce', |
|
| 2967 | + $ajax_sorting_callback.'_nonce', |
|
| 2968 | + $ajax_sorting_callback.'_nonce', |
|
| 2969 | 2969 | false, |
| 2970 | 2970 | false |
| 2971 | 2971 | ); |
@@ -2982,7 +2982,7 @@ discard block |
||
| 2982 | 2982 | $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields']) |
| 2983 | 2983 | ? $this->_template_args['list_table_hidden_fields'] |
| 2984 | 2984 | : ''; |
| 2985 | - $nonce_ref = $this->_req_action . '_nonce'; |
|
| 2985 | + $nonce_ref = $this->_req_action.'_nonce'; |
|
| 2986 | 2986 | $hidden_form_fields .= '<input type="hidden" name="' |
| 2987 | 2987 | . $nonce_ref |
| 2988 | 2988 | . '" value="' |
@@ -2991,10 +2991,10 @@ discard block |
||
| 2991 | 2991 | $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields; |
| 2992 | 2992 | // display message about search results? |
| 2993 | 2993 | $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s']) |
| 2994 | - ? '<p class="ee-search-results">' . sprintf( |
|
| 2994 | + ? '<p class="ee-search-results">'.sprintf( |
|
| 2995 | 2995 | esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'), |
| 2996 | 2996 | trim($this->_req_data['s'], '%') |
| 2997 | - ) . '</p>' |
|
| 2997 | + ).'</p>' |
|
| 2998 | 2998 | : ''; |
| 2999 | 2999 | // filter before_list_table template arg |
| 3000 | 3000 | $this->_template_args['before_list_table'] = apply_filters( |
@@ -3075,7 +3075,7 @@ discard block |
||
| 3075 | 3075 | $this |
| 3076 | 3076 | ); |
| 3077 | 3077 | return EEH_Template::display_template( |
| 3078 | - EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php', |
|
| 3078 | + EE_ADMIN_TEMPLATE.'admin_details_legend.template.php', |
|
| 3079 | 3079 | $this->_template_args, |
| 3080 | 3080 | true |
| 3081 | 3081 | ); |
@@ -3298,17 +3298,17 @@ discard block |
||
| 3298 | 3298 | // add in a hidden index for the current page (so save and close redirects properly) |
| 3299 | 3299 | $this->_template_args['save_buttons'] = $referrer_url; |
| 3300 | 3300 | foreach ($button_text as $key => $button) { |
| 3301 | - $ref = $default_names[ $key ]; |
|
| 3301 | + $ref = $default_names[$key]; |
|
| 3302 | 3302 | $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary ' |
| 3303 | 3303 | . $ref |
| 3304 | 3304 | . '" value="' |
| 3305 | 3305 | . $button |
| 3306 | 3306 | . '" name="' |
| 3307 | - . (! empty($actions) ? $actions[ $key ] : $ref) |
|
| 3307 | + . ( ! empty($actions) ? $actions[$key] : $ref) |
|
| 3308 | 3308 | . '" id="' |
| 3309 | - . $this->_current_view . '_' . $ref |
|
| 3309 | + . $this->_current_view.'_'.$ref |
|
| 3310 | 3310 | . '" />'; |
| 3311 | - if (! $both) { |
|
| 3311 | + if ( ! $both) { |
|
| 3312 | 3312 | break; |
| 3313 | 3313 | } |
| 3314 | 3314 | } |
@@ -3343,13 +3343,13 @@ discard block |
||
| 3343 | 3343 | 'An error occurred. No action was set for this page\'s form.', |
| 3344 | 3344 | 'event_espresso' |
| 3345 | 3345 | ); |
| 3346 | - $dev_msg = $user_msg . "\n" |
|
| 3346 | + $dev_msg = $user_msg."\n" |
|
| 3347 | 3347 | . sprintf( |
| 3348 | 3348 | esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'), |
| 3349 | 3349 | __FUNCTION__, |
| 3350 | 3350 | __CLASS__ |
| 3351 | 3351 | ); |
| 3352 | - EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 3352 | + EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 3353 | 3353 | } |
| 3354 | 3354 | // open form |
| 3355 | 3355 | $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="' |
@@ -3358,8 +3358,8 @@ discard block |
||
| 3358 | 3358 | . $route |
| 3359 | 3359 | . '_event_form" >'; |
| 3360 | 3360 | // add nonce |
| 3361 | - $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false); |
|
| 3362 | - $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce; |
|
| 3361 | + $nonce = wp_nonce_field($route.'_nonce', $route.'_nonce', false, false); |
|
| 3362 | + $this->_template_args['before_admin_page_content'] .= "\n\t".$nonce; |
|
| 3363 | 3363 | // add REQUIRED form action |
| 3364 | 3364 | $hidden_fields = array( |
| 3365 | 3365 | 'action' => array('type' => 'hidden', 'value' => $route), |
@@ -3372,7 +3372,7 @@ discard block |
||
| 3372 | 3372 | $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array'); |
| 3373 | 3373 | // add fields to form |
| 3374 | 3374 | foreach ((array) $form_fields as $field_name => $form_field) { |
| 3375 | - $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field']; |
|
| 3375 | + $this->_template_args['before_admin_page_content'] .= "\n\t".$form_field['field']; |
|
| 3376 | 3376 | } |
| 3377 | 3377 | // close form |
| 3378 | 3378 | $this->_template_args['after_admin_page_content'] = '</form>'; |
@@ -3423,12 +3423,12 @@ discard block |
||
| 3423 | 3423 | foreach ($this->_req_data as $ref => $value) { |
| 3424 | 3424 | // unset nonces |
| 3425 | 3425 | if (strpos($ref, 'nonce') !== false) { |
| 3426 | - unset($this->_req_data[ $ref ]); |
|
| 3426 | + unset($this->_req_data[$ref]); |
|
| 3427 | 3427 | continue; |
| 3428 | 3428 | } |
| 3429 | 3429 | // urlencode values. |
| 3430 | 3430 | $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value); |
| 3431 | - $this->_req_data[ $ref ] = $value; |
|
| 3431 | + $this->_req_data[$ref] = $value; |
|
| 3432 | 3432 | } |
| 3433 | 3433 | return array_merge($this->_req_data, $new_route_data); |
| 3434 | 3434 | } |
@@ -3463,10 +3463,10 @@ discard block |
||
| 3463 | 3463 | $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url; |
| 3464 | 3464 | $notices = EE_Error::get_notices(false); |
| 3465 | 3465 | // overwrite default success messages //BUT ONLY if overwrite not overridden |
| 3466 | - if (! $override_overwrite || ! empty($notices['errors'])) { |
|
| 3466 | + if ( ! $override_overwrite || ! empty($notices['errors'])) { |
|
| 3467 | 3467 | EE_Error::overwrite_success(); |
| 3468 | 3468 | } |
| 3469 | - if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) { |
|
| 3469 | + if ( ! empty($what) && ! empty($action_desc) && empty($notices['errors'])) { |
|
| 3470 | 3470 | // how many records affected ? more than one record ? or just one ? |
| 3471 | 3471 | if ($success > 1) { |
| 3472 | 3472 | // set plural msg |
@@ -3495,7 +3495,7 @@ discard block |
||
| 3495 | 3495 | } |
| 3496 | 3496 | } |
| 3497 | 3497 | // check that $query_args isn't something crazy |
| 3498 | - if (! is_array($query_args)) { |
|
| 3498 | + if ( ! is_array($query_args)) { |
|
| 3499 | 3499 | $query_args = array(); |
| 3500 | 3500 | } |
| 3501 | 3501 | /** |
@@ -3520,7 +3520,7 @@ discard block |
||
| 3520 | 3520 | $redirect_url = admin_url('admin.php'); |
| 3521 | 3521 | } |
| 3522 | 3522 | // merge any default query_args set in _default_route_query_args property |
| 3523 | - if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) { |
|
| 3523 | + if ( ! empty($this->_default_route_query_args) && ! $this->_is_UI_request) { |
|
| 3524 | 3524 | $args_to_merge = array(); |
| 3525 | 3525 | foreach ($this->_default_route_query_args as $query_param => $query_value) { |
| 3526 | 3526 | // is there a wp_referer array in our _default_route_query_args property? |
@@ -3532,15 +3532,15 @@ discard block |
||
| 3532 | 3532 | } |
| 3533 | 3533 | // finally we will override any arguments in the referer with |
| 3534 | 3534 | // what might be set on the _default_route_query_args array. |
| 3535 | - if (isset($this->_default_route_query_args[ $reference ])) { |
|
| 3536 | - $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]); |
|
| 3535 | + if (isset($this->_default_route_query_args[$reference])) { |
|
| 3536 | + $args_to_merge[$reference] = urlencode($this->_default_route_query_args[$reference]); |
|
| 3537 | 3537 | } else { |
| 3538 | - $args_to_merge[ $reference ] = urlencode($value); |
|
| 3538 | + $args_to_merge[$reference] = urlencode($value); |
|
| 3539 | 3539 | } |
| 3540 | 3540 | } |
| 3541 | 3541 | continue; |
| 3542 | 3542 | } |
| 3543 | - $args_to_merge[ $query_param ] = $query_value; |
|
| 3543 | + $args_to_merge[$query_param] = $query_value; |
|
| 3544 | 3544 | } |
| 3545 | 3545 | // now let's merge these arguments but override with what was specifically sent in to the |
| 3546 | 3546 | // redirect. |
@@ -3552,13 +3552,13 @@ discard block |
||
| 3552 | 3552 | if (isset($query_args['action'])) { |
| 3553 | 3553 | // manually generate wp_nonce and merge that with the query vars |
| 3554 | 3554 | // becuz the wp_nonce_url function wrecks havoc on some vars |
| 3555 | - $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce'); |
|
| 3555 | + $query_args['_wpnonce'] = wp_create_nonce($query_args['action'].'_nonce'); |
|
| 3556 | 3556 | } |
| 3557 | 3557 | // we're adding some hooks and filters in here for processing any things just before redirects |
| 3558 | 3558 | // (example: an admin page has done an insert or update and we want to run something after that). |
| 3559 | - do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args); |
|
| 3559 | + do_action('AHEE_redirect_'.$classname.$this->_req_action, $query_args); |
|
| 3560 | 3560 | $redirect_url = apply_filters( |
| 3561 | - 'FHEE_redirect_' . $classname . $this->_req_action, |
|
| 3561 | + 'FHEE_redirect_'.$classname.$this->_req_action, |
|
| 3562 | 3562 | self::add_query_args_and_nonce($query_args, $redirect_url), |
| 3563 | 3563 | $query_args |
| 3564 | 3564 | ); |
@@ -3611,7 +3611,7 @@ discard block |
||
| 3611 | 3611 | } |
| 3612 | 3612 | $this->_template_args['notices'] = EE_Error::get_notices(); |
| 3613 | 3613 | // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true) |
| 3614 | - if (! defined('DOING_AJAX') || $sticky_notices) { |
|
| 3614 | + if ( ! defined('DOING_AJAX') || $sticky_notices) { |
|
| 3615 | 3615 | $route = isset($query_args['action']) ? $query_args['action'] : 'default'; |
| 3616 | 3616 | $this->_add_transient( |
| 3617 | 3617 | $route, |
@@ -3651,7 +3651,7 @@ discard block |
||
| 3651 | 3651 | $exclude_nonce = false |
| 3652 | 3652 | ) { |
| 3653 | 3653 | // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along) |
| 3654 | - if (empty($base_url) && ! isset($this->_page_routes[ $action ])) { |
|
| 3654 | + if (empty($base_url) && ! isset($this->_page_routes[$action])) { |
|
| 3655 | 3655 | throw new EE_Error( |
| 3656 | 3656 | sprintf( |
| 3657 | 3657 | esc_html__( |
@@ -3662,7 +3662,7 @@ discard block |
||
| 3662 | 3662 | ) |
| 3663 | 3663 | ); |
| 3664 | 3664 | } |
| 3665 | - if (! isset($this->_labels['buttons'][ $type ])) { |
|
| 3665 | + if ( ! isset($this->_labels['buttons'][$type])) { |
|
| 3666 | 3666 | throw new EE_Error( |
| 3667 | 3667 | sprintf( |
| 3668 | 3668 | __( |
@@ -3675,7 +3675,7 @@ discard block |
||
| 3675 | 3675 | } |
| 3676 | 3676 | // finally check user access for this button. |
| 3677 | 3677 | $has_access = $this->check_user_access($action, true); |
| 3678 | - if (! $has_access) { |
|
| 3678 | + if ( ! $has_access) { |
|
| 3679 | 3679 | return ''; |
| 3680 | 3680 | } |
| 3681 | 3681 | $_base_url = ! $base_url ? $this->_admin_base_url : $base_url; |
@@ -3683,11 +3683,11 @@ discard block |
||
| 3683 | 3683 | 'action' => $action, |
| 3684 | 3684 | ); |
| 3685 | 3685 | // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten. |
| 3686 | - if (! empty($extra_request)) { |
|
| 3686 | + if ( ! empty($extra_request)) { |
|
| 3687 | 3687 | $query_args = array_merge($extra_request, $query_args); |
| 3688 | 3688 | } |
| 3689 | 3689 | $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce); |
| 3690 | - return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class); |
|
| 3690 | + return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][$type], $class); |
|
| 3691 | 3691 | } |
| 3692 | 3692 | |
| 3693 | 3693 | |
@@ -3713,7 +3713,7 @@ discard block |
||
| 3713 | 3713 | 'FHEE__EE_Admin_Page___per_page_screen_options__default', |
| 3714 | 3714 | 20 |
| 3715 | 3715 | ), |
| 3716 | - 'option' => $this->_current_page . '_' . $this->_current_view . '_per_page', |
|
| 3716 | + 'option' => $this->_current_page.'_'.$this->_current_view.'_per_page', |
|
| 3717 | 3717 | ); |
| 3718 | 3718 | // ONLY add the screen option if the user has access to it. |
| 3719 | 3719 | if ($this->check_user_access($this->_current_view, true)) { |
@@ -3734,7 +3734,7 @@ discard block |
||
| 3734 | 3734 | { |
| 3735 | 3735 | if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) { |
| 3736 | 3736 | check_admin_referer('screen-options-nonce', 'screenoptionnonce'); |
| 3737 | - if (! $user = wp_get_current_user()) { |
|
| 3737 | + if ( ! $user = wp_get_current_user()) { |
|
| 3738 | 3738 | return; |
| 3739 | 3739 | } |
| 3740 | 3740 | $option = $_POST['wp_screen_options']['option']; |
@@ -3745,7 +3745,7 @@ discard block |
||
| 3745 | 3745 | $map_option = $option; |
| 3746 | 3746 | $option = str_replace('-', '_', $option); |
| 3747 | 3747 | switch ($map_option) { |
| 3748 | - case $this->_current_page . '_' . $this->_current_view . '_per_page': |
|
| 3748 | + case $this->_current_page.'_'.$this->_current_view.'_per_page': |
|
| 3749 | 3749 | $value = (int) $value; |
| 3750 | 3750 | $max_value = apply_filters( |
| 3751 | 3751 | 'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value', |
@@ -3803,13 +3803,13 @@ discard block |
||
| 3803 | 3803 | protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false) |
| 3804 | 3804 | { |
| 3805 | 3805 | $user_id = get_current_user_id(); |
| 3806 | - if (! $skip_route_verify) { |
|
| 3806 | + if ( ! $skip_route_verify) { |
|
| 3807 | 3807 | $this->_verify_route($route); |
| 3808 | 3808 | } |
| 3809 | 3809 | // now let's set the string for what kind of transient we're setting |
| 3810 | 3810 | $transient = $notices |
| 3811 | - ? 'ee_rte_n_tx_' . $route . '_' . $user_id |
|
| 3812 | - : 'rte_tx_' . $route . '_' . $user_id; |
|
| 3811 | + ? 'ee_rte_n_tx_'.$route.'_'.$user_id |
|
| 3812 | + : 'rte_tx_'.$route.'_'.$user_id; |
|
| 3813 | 3813 | $data = $notices ? array('notices' => $data) : $data; |
| 3814 | 3814 | // is there already a transient for this route? If there is then let's ADD to that transient |
| 3815 | 3815 | $existing = is_multisite() && is_network_admin() |
@@ -3838,8 +3838,8 @@ discard block |
||
| 3838 | 3838 | $user_id = get_current_user_id(); |
| 3839 | 3839 | $route = ! $route ? $this->_req_action : $route; |
| 3840 | 3840 | $transient = $notices |
| 3841 | - ? 'ee_rte_n_tx_' . $route . '_' . $user_id |
|
| 3842 | - : 'rte_tx_' . $route . '_' . $user_id; |
|
| 3841 | + ? 'ee_rte_n_tx_'.$route.'_'.$user_id |
|
| 3842 | + : 'rte_tx_'.$route.'_'.$user_id; |
|
| 3843 | 3843 | $data = is_multisite() && is_network_admin() |
| 3844 | 3844 | ? get_site_transient($transient) |
| 3845 | 3845 | : get_transient($transient); |
@@ -4058,7 +4058,7 @@ discard block |
||
| 4058 | 4058 | */ |
| 4059 | 4059 | protected function _next_link($url, $class = 'dashicons dashicons-arrow-right') |
| 4060 | 4060 | { |
| 4061 | - return '<a class="' . $class . '" href="' . $url . '"></a>'; |
|
| 4061 | + return '<a class="'.$class.'" href="'.$url.'"></a>'; |
|
| 4062 | 4062 | } |
| 4063 | 4063 | |
| 4064 | 4064 | |
@@ -4071,7 +4071,7 @@ discard block |
||
| 4071 | 4071 | */ |
| 4072 | 4072 | protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left') |
| 4073 | 4073 | { |
| 4074 | - return '<a class="' . $class . '" href="' . $url . '"></a>'; |
|
| 4074 | + return '<a class="'.$class.'" href="'.$url.'"></a>'; |
|
| 4075 | 4075 | } |
| 4076 | 4076 | |
| 4077 | 4077 | |
@@ -44,7 +44,7 @@ discard block |
||
| 44 | 44 | { |
| 45 | 45 | $this->singlular_item = __('Payment Method', 'event_espresso'); |
| 46 | 46 | $this->plural_item = __('Payment Methods', 'event_espresso'); |
| 47 | - $this->_tables = array( 'Payment_Method' => new EE_Primary_Table('esp_payment_method', 'PMD_ID') ); |
|
| 47 | + $this->_tables = array('Payment_Method' => new EE_Primary_Table('esp_payment_method', 'PMD_ID')); |
|
| 48 | 48 | $this->_fields = array( |
| 49 | 49 | 'Payment_Method' => array( |
| 50 | 50 | 'PMD_ID' => new EE_Primary_Key_Int_Field('PMD_ID', __("ID", 'event_espresso')), |
@@ -78,7 +78,7 @@ discard block |
||
| 78 | 78 | */ |
| 79 | 79 | public function get_one_by_slug($slug) |
| 80 | 80 | { |
| 81 | - return $this->get_one(array( array( 'PMD_slug' => $slug ) )); |
|
| 81 | + return $this->get_one(array(array('PMD_slug' => $slug))); |
|
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | |
@@ -109,7 +109,7 @@ discard block |
||
| 109 | 109 | public function is_valid_scope($scope) |
| 110 | 110 | { |
| 111 | 111 | $scopes = $this->scopes(); |
| 112 | - if (isset($scopes[ $scope ])) { |
|
| 112 | + if (isset($scopes[$scope])) { |
|
| 113 | 113 | return true; |
| 114 | 114 | } else { |
| 115 | 115 | return false; |
@@ -127,8 +127,8 @@ discard block |
||
| 127 | 127 | */ |
| 128 | 128 | public function get_all_active($scope = null, $query_params = array()) |
| 129 | 129 | { |
| 130 | - if (! isset($query_params['order_by']) && ! isset($query_params['order'])) { |
|
| 131 | - $query_params['order_by'] = array( 'PMD_order' => 'ASC', 'PMD_ID' => 'ASC' ); |
|
| 130 | + if ( ! isset($query_params['order_by']) && ! isset($query_params['order'])) { |
|
| 131 | + $query_params['order_by'] = array('PMD_order' => 'ASC', 'PMD_ID' => 'ASC'); |
|
| 132 | 132 | } |
| 133 | 133 | return $this->get_all($this->_get_query_params_for_all_active($scope, $query_params)); |
| 134 | 134 | } |
@@ -156,7 +156,7 @@ discard block |
||
| 156 | 156 | { |
| 157 | 157 | if ($scope) { |
| 158 | 158 | if ($this->is_valid_scope($scope)) { |
| 159 | - return array_replace_recursive(array( array( 'PMD_scope' => array( 'LIKE', "%$scope%" ) ) ), $query_params); |
|
| 159 | + return array_replace_recursive(array(array('PMD_scope' => array('LIKE', "%$scope%"))), $query_params); |
|
| 160 | 160 | } else { |
| 161 | 161 | throw new EE_Error(sprintf(__("'%s' is not a valid scope for a payment method", "event_espresso"), $scope)); |
| 162 | 162 | } |
@@ -165,9 +165,9 @@ discard block |
||
| 165 | 165 | $count = 0; |
| 166 | 166 | foreach ($this->scopes() as $scope_name => $desc) { |
| 167 | 167 | $count++; |
| 168 | - $acceptable_scopes[ 'PMD_scope*' . $count ] = array( 'LIKE', '%' . $scope_name . '%' ); |
|
| 168 | + $acceptable_scopes['PMD_scope*'.$count] = array('LIKE', '%'.$scope_name.'%'); |
|
| 169 | 169 | } |
| 170 | - return array_replace_recursive(array( array( 'OR*active_scope' => $acceptable_scopes ) ), $query_params); |
|
| 170 | + return array_replace_recursive(array(array('OR*active_scope' => $acceptable_scopes)), $query_params); |
|
| 171 | 171 | } |
| 172 | 172 | } |
| 173 | 173 | |
@@ -205,7 +205,7 @@ discard block |
||
| 205 | 205 | */ |
| 206 | 206 | public function get_one_of_type($type) |
| 207 | 207 | { |
| 208 | - return $this->get_one(array( array( 'PMD_type' => $type ) )); |
|
| 208 | + return $this->get_one(array(array('PMD_type' => $type))); |
|
| 209 | 209 | } |
| 210 | 210 | |
| 211 | 211 | |
@@ -298,7 +298,7 @@ discard block |
||
| 298 | 298 | $usable_payment_methods = array(); |
| 299 | 299 | foreach ($payment_methods as $key => $payment_method) { |
| 300 | 300 | if (EE_Payment_Method_Manager::instance()->payment_method_type_exists($payment_method->type())) { |
| 301 | - $usable_payment_methods[ $key ] = $payment_method; |
|
| 301 | + $usable_payment_methods[$key] = $payment_method; |
|
| 302 | 302 | // some payment methods enqueue their scripts in EE_PMT_*::__construct |
| 303 | 303 | // which is kinda a no-no (just because it's being constructed doesn't mean we need to enqueue |
| 304 | 304 | // its scripts). but for backwards-compat we should continue to do that |
@@ -312,7 +312,7 @@ discard block |
||
| 312 | 312 | $payment_method |
| 313 | 313 | ); |
| 314 | 314 | new PersistentAdminNotice( |
| 315 | - 'auto-deactivated-' . $payment_method->type(), |
|
| 315 | + 'auto-deactivated-'.$payment_method->type(), |
|
| 316 | 316 | sprintf( |
| 317 | 317 | __( |
| 318 | 318 | 'The payment method %1$s was automatically deactivated because it appears its associated Event Espresso Addon was recently deactivated.%2$sIt can be reactivated on the %3$sPlugins admin page%4$s, then you can reactivate the payment method.', |
@@ -320,7 +320,7 @@ discard block |
||
| 320 | 320 | ), |
| 321 | 321 | $payment_method->admin_name(), |
| 322 | 322 | '<br />', |
| 323 | - '<a href="' . admin_url('plugins.php') . '">', |
|
| 323 | + '<a href="'.admin_url('plugins.php').'">', |
|
| 324 | 324 | '</a>' |
| 325 | 325 | ), |
| 326 | 326 | true |
@@ -345,7 +345,7 @@ discard block |
||
| 345 | 345 | // give addons a chance to override what payment methods are chosen based on the transaction |
| 346 | 346 | return apply_filters( |
| 347 | 347 | 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
| 348 | - $this->get_all_active($scope, array( 'group_by' => 'PMD_type' )), |
|
| 348 | + $this->get_all_active($scope, array('group_by' => 'PMD_type')), |
|
| 349 | 349 | $transaction, |
| 350 | 350 | $scope |
| 351 | 351 | ); |
@@ -369,7 +369,7 @@ discard block |
||
| 369 | 369 | 0 => array( |
| 370 | 370 | 'Payment.Registration.REG_ID' => $registration_id, |
| 371 | 371 | ), |
| 372 | - 'order_by' => array( 'Payment.PAY_ID' => 'DESC' ) |
|
| 372 | + 'order_by' => array('Payment.PAY_ID' => 'DESC') |
|
| 373 | 373 | ); |
| 374 | 374 | return $this->get_one($query_params); |
| 375 | 375 | } |
@@ -20,363 +20,363 @@ |
||
| 20 | 20 | class EEM_Payment_Method extends EEM_Base |
| 21 | 21 | { |
| 22 | 22 | |
| 23 | - const scope_cart = 'CART'; |
|
| 24 | - |
|
| 25 | - const scope_admin = 'ADMIN'; |
|
| 26 | - |
|
| 27 | - const scope_api = 'API'; |
|
| 28 | - |
|
| 29 | - /** |
|
| 30 | - * |
|
| 31 | - * @type EEM_Payment_Method |
|
| 32 | - */ |
|
| 33 | - protected static $_instance = null; |
|
| 34 | - |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * private constructor to prevent direct creation |
|
| 39 | - * @Constructor |
|
| 40 | - * @access protected |
|
| 41 | - * @return EEM_Payment_Method |
|
| 42 | - */ |
|
| 43 | - protected function __construct($timezone = null) |
|
| 44 | - { |
|
| 45 | - $this->singlular_item = __('Payment Method', 'event_espresso'); |
|
| 46 | - $this->plural_item = __('Payment Methods', 'event_espresso'); |
|
| 47 | - $this->_tables = array( 'Payment_Method' => new EE_Primary_Table('esp_payment_method', 'PMD_ID') ); |
|
| 48 | - $this->_fields = array( |
|
| 49 | - 'Payment_Method' => array( |
|
| 50 | - 'PMD_ID' => new EE_Primary_Key_Int_Field('PMD_ID', __("ID", 'event_espresso')), |
|
| 51 | - 'PMD_type' => new EE_Plain_Text_Field('PMD_type', __("Payment Method Type", 'event_espresso'), false, 'Admin_Only'), |
|
| 52 | - 'PMD_name' => new EE_Plain_Text_Field('PMD_name', __("Name", 'event_espresso'), false), |
|
| 53 | - 'PMD_desc' => new EE_Post_Content_Field('PMD_desc', __("Description", 'event_espresso'), false, ''), |
|
| 54 | - 'PMD_admin_name' => new EE_Plain_Text_Field('PMD_admin_name', __("Admin-Only Name", 'event_espresso'), true), |
|
| 55 | - 'PMD_admin_desc' => new EE_Post_Content_Field('PMD_admin_desc', __("Admin-Only Description", 'event_espresso'), true), |
|
| 56 | - 'PMD_slug' => new EE_Slug_Field('PMD_slug', __("Slug", 'event_espresso'), false), |
|
| 57 | - 'PMD_order' => new EE_Integer_Field('PMD_order', __("Order", 'event_espresso'), false, 0), |
|
| 58 | - 'PMD_debug_mode' => new EE_Boolean_Field('PMD_debug_mode', __("Debug Mode On?", 'event_espresso'), false, false), |
|
| 59 | - 'PMD_wp_user' => new EE_WP_User_Field('PMD_wp_user', __("Payment Method Creator ID", 'event_espresso'), false), |
|
| 60 | - 'PMD_open_by_default' => new EE_Boolean_Field('PMD_open_by_default', __("Open by Default?", 'event_espresso'), false, false), 'PMD_button_url' => new EE_Plain_Text_Field('PMD_button_url', __("Button URL", 'event_espresso'), true, ''), |
|
| 61 | - 'PMD_scope' => new EE_Serialized_Text_Field('PMD_scope', __("Usable From?", 'event_espresso'), false, array()), // possible values currently are 'CART','ADMIN','API' |
|
| 62 | - ) ); |
|
| 63 | - $this->_model_relations = array( |
|
| 64 | - 'Payment' => new EE_Has_Many_Relation(), |
|
| 65 | - 'Currency' => new EE_HABTM_Relation('Currency_Payment_Method'), |
|
| 66 | - 'Transaction' => new EE_Has_Many_Relation(), |
|
| 67 | - 'WP_User' => new EE_Belongs_To_Relation(), |
|
| 68 | - ); |
|
| 69 | - parent::__construct($timezone); |
|
| 70 | - } |
|
| 71 | - |
|
| 72 | - |
|
| 73 | - |
|
| 74 | - /** |
|
| 75 | - * Gets one by the slug provided |
|
| 76 | - * @param string $slug |
|
| 77 | - * @return EE_Payment_Method |
|
| 78 | - */ |
|
| 79 | - public function get_one_by_slug($slug) |
|
| 80 | - { |
|
| 81 | - return $this->get_one(array( array( 'PMD_slug' => $slug ) )); |
|
| 82 | - } |
|
| 83 | - |
|
| 84 | - |
|
| 85 | - |
|
| 86 | - /** |
|
| 87 | - * Gets all the acceptable scopes for payment methods. |
|
| 88 | - * Keys are their names as store din the DB, and values are nice names for displaying them |
|
| 89 | - * @return array |
|
| 90 | - */ |
|
| 91 | - public function scopes() |
|
| 92 | - { |
|
| 93 | - return apply_filters( |
|
| 94 | - 'FHEE__EEM_Payment_Method__scopes', |
|
| 95 | - array( |
|
| 96 | - self::scope_cart => __("Front-end Registration Page", 'event_espresso'), |
|
| 97 | - self::scope_admin => __("Admin Registration Page (no online processing)", 'event_espresso') |
|
| 98 | - ) |
|
| 99 | - ); |
|
| 100 | - } |
|
| 101 | - |
|
| 102 | - |
|
| 103 | - |
|
| 104 | - /** |
|
| 105 | - * Determines if this is an valid scope |
|
| 106 | - * @param string $scope like one of EEM_Payment_Method::instance()->scopes() |
|
| 107 | - * @return boolean |
|
| 108 | - */ |
|
| 109 | - public function is_valid_scope($scope) |
|
| 110 | - { |
|
| 111 | - $scopes = $this->scopes(); |
|
| 112 | - if (isset($scopes[ $scope ])) { |
|
| 113 | - return true; |
|
| 114 | - } else { |
|
| 115 | - return false; |
|
| 116 | - } |
|
| 117 | - } |
|
| 118 | - |
|
| 119 | - |
|
| 120 | - |
|
| 121 | - /** |
|
| 122 | - * Gets all active payment methods |
|
| 123 | - * @param string $scope one of |
|
| 124 | - * @param array $query_params |
|
| 125 | - * @throws EE_Error |
|
| 126 | - * @return EE_Payment_Method[] |
|
| 127 | - */ |
|
| 128 | - public function get_all_active($scope = null, $query_params = array()) |
|
| 129 | - { |
|
| 130 | - if (! isset($query_params['order_by']) && ! isset($query_params['order'])) { |
|
| 131 | - $query_params['order_by'] = array( 'PMD_order' => 'ASC', 'PMD_ID' => 'ASC' ); |
|
| 132 | - } |
|
| 133 | - return $this->get_all($this->_get_query_params_for_all_active($scope, $query_params)); |
|
| 134 | - } |
|
| 135 | - |
|
| 136 | - /** |
|
| 137 | - * Counts all active gateways in the specified scope |
|
| 138 | - * @param string $scope one of EEM_Payment_Method::scope_* |
|
| 139 | - * @param array $query_params |
|
| 140 | - * @return int |
|
| 141 | - */ |
|
| 142 | - public function count_active($scope = null, $query_params = array()) |
|
| 143 | - { |
|
| 144 | - return $this->count($this->_get_query_params_for_all_active($scope, $query_params)); |
|
| 145 | - } |
|
| 146 | - |
|
| 147 | - /** |
|
| 148 | - * Creates the $query_params that can be passed into any EEM_Payment_Method as their $query_params |
|
| 149 | - * argument to get all active for a given scope |
|
| 150 | - * @param string $scope one of the constants EEM_Payment_Method::scope_* |
|
| 151 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 152 | - * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 153 | - * @throws EE_Error |
|
| 154 | - */ |
|
| 155 | - protected function _get_query_params_for_all_active($scope = null, $query_params = array()) |
|
| 156 | - { |
|
| 157 | - if ($scope) { |
|
| 158 | - if ($this->is_valid_scope($scope)) { |
|
| 159 | - return array_replace_recursive(array( array( 'PMD_scope' => array( 'LIKE', "%$scope%" ) ) ), $query_params); |
|
| 160 | - } else { |
|
| 161 | - throw new EE_Error(sprintf(__("'%s' is not a valid scope for a payment method", "event_espresso"), $scope)); |
|
| 162 | - } |
|
| 163 | - } else { |
|
| 164 | - $acceptable_scopes = array(); |
|
| 165 | - $count = 0; |
|
| 166 | - foreach ($this->scopes() as $scope_name => $desc) { |
|
| 167 | - $count++; |
|
| 168 | - $acceptable_scopes[ 'PMD_scope*' . $count ] = array( 'LIKE', '%' . $scope_name . '%' ); |
|
| 169 | - } |
|
| 170 | - return array_replace_recursive(array( array( 'OR*active_scope' => $acceptable_scopes ) ), $query_params); |
|
| 171 | - } |
|
| 172 | - } |
|
| 173 | - |
|
| 174 | - /** |
|
| 175 | - * Creates the $query_params that can be passed into any EEM_Payment_Method as their $query_params |
|
| 176 | - * argument to get all active for a given scope |
|
| 177 | - * @param string $scope one of the constants EEM_Payment_Method::scope_* |
|
| 178 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 179 | - * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 180 | - * @throws EE_Error |
|
| 181 | - */ |
|
| 182 | - public function get_query_params_for_all_active($scope = null, $query_params = array()) |
|
| 183 | - { |
|
| 184 | - return $this->_get_query_params_for_all_active($scope, $query_params); |
|
| 185 | - } |
|
| 186 | - |
|
| 187 | - |
|
| 188 | - /** |
|
| 189 | - * Gets one active payment method. see @get_all_active for documentation |
|
| 190 | - * @param string $scope |
|
| 191 | - * @param array $query_params |
|
| 192 | - * @return EE_Payment_Method |
|
| 193 | - */ |
|
| 194 | - public function get_one_active($scope = null, $query_params = array()) |
|
| 195 | - { |
|
| 196 | - return $this->get_one($this->_get_query_params_for_all_active($scope, $query_params)); |
|
| 197 | - } |
|
| 198 | - |
|
| 199 | - |
|
| 200 | - |
|
| 201 | - /** |
|
| 202 | - * Gets one payment method of that type, regardless of whether its active or not |
|
| 203 | - * @param string $type |
|
| 204 | - * @return EE_Payment_Method |
|
| 205 | - */ |
|
| 206 | - public function get_one_of_type($type) |
|
| 207 | - { |
|
| 208 | - return $this->get_one(array( array( 'PMD_type' => $type ) )); |
|
| 209 | - } |
|
| 210 | - |
|
| 211 | - |
|
| 212 | - |
|
| 213 | - /** |
|
| 214 | - * Overrides parent ot also check by the slug |
|
| 215 | - * @see EEM_Base::ensure_is_obj() |
|
| 216 | - * @param string|int|EE_Payment_Method $base_class_obj_or_id |
|
| 217 | - * @param boolean $ensure_is_in_db |
|
| 218 | - * @return EE_Payment_Method |
|
| 219 | - * @throws EE_Error |
|
| 220 | - */ |
|
| 221 | - public function ensure_is_obj($base_class_obj_or_id, $ensure_is_in_db = false) |
|
| 222 | - { |
|
| 223 | - // first: check if it's a slug |
|
| 224 | - if (is_string($base_class_obj_or_id)) { |
|
| 225 | - $obj = $this->get_one_by_slug($base_class_obj_or_id); |
|
| 226 | - if ($obj) { |
|
| 227 | - return $obj; |
|
| 228 | - } |
|
| 229 | - } |
|
| 230 | - // ok so it wasn't a slug we were passed. try the usual then (ie, it's an object or an ID) |
|
| 231 | - try { |
|
| 232 | - return parent::ensure_is_obj($base_class_obj_or_id, $ensure_is_in_db); |
|
| 233 | - } catch (EE_Error $e) { |
|
| 234 | - // handle it outside the catch |
|
| 235 | - } |
|
| 236 | - throw new EE_Error(sprintf(__("'%s' is neither a Payment Method ID, slug, nor object.", "event_espresso"), $base_class_obj_or_id)); |
|
| 237 | - } |
|
| 238 | - |
|
| 239 | - |
|
| 240 | - |
|
| 241 | - /** |
|
| 242 | - * Gets the ID of this object, or if its a string finds the object's id |
|
| 243 | - * associated with that slug |
|
| 244 | - * @param mixed $base_obj_or_id_or_slug |
|
| 245 | - * @return int |
|
| 246 | - */ |
|
| 247 | - public function ensure_is_ID($base_obj_or_id_or_slug) |
|
| 248 | - { |
|
| 249 | - if (is_string($base_obj_or_id_or_slug)) { |
|
| 250 | - // assume it's a slug |
|
| 251 | - $base_obj_or_id_or_slug = $this->get_one_by_slug($base_obj_or_id_or_slug); |
|
| 252 | - } |
|
| 253 | - return parent::ensure_is_ID($base_obj_or_id_or_slug); |
|
| 254 | - } |
|
| 255 | - |
|
| 256 | - |
|
| 257 | - |
|
| 258 | - /** |
|
| 259 | - * Verifies the button urls on all the passed payment methods have a valid button url. If not, resets them to their default. |
|
| 260 | - * @param EE_Payment_Method[] $payment_methods. If NULL is provided defaults to all payment methods active in the cart |
|
| 261 | - */ |
|
| 262 | - public function verify_button_urls($payment_methods = null) |
|
| 263 | - { |
|
| 264 | - $payment_methods = is_array($payment_methods) ? $payment_methods : $this->get_all_active(EEM_Payment_Method::scope_cart); |
|
| 265 | - foreach ($payment_methods as $payment_method) { |
|
| 266 | - try { |
|
| 267 | - // If there is really no button URL at all, or if the button URLs still point to decaf folder even |
|
| 268 | - // though this is a caffeinated install, reset it to the default. |
|
| 269 | - $current_button_url = $payment_method->button_url(); |
|
| 270 | - if (empty($current_button_url) |
|
| 271 | - || ( |
|
| 272 | - strpos($current_button_url, 'decaf') !== false |
|
| 273 | - && strpos($payment_method->type_obj()->default_button_url(), 'decaf') === false |
|
| 274 | - ) |
|
| 275 | - ) { |
|
| 276 | - $payment_method->save( |
|
| 277 | - [ |
|
| 278 | - 'PMD_button_url' => $payment_method->type_obj()->default_button_url() |
|
| 279 | - ] |
|
| 280 | - ); |
|
| 281 | - } |
|
| 282 | - } catch (EE_Error $e) { |
|
| 283 | - $payment_method->set_active(false); |
|
| 284 | - } |
|
| 285 | - } |
|
| 286 | - } |
|
| 287 | - |
|
| 288 | - |
|
| 289 | - |
|
| 290 | - /** |
|
| 291 | - * Overrides parent to not only turn wpdb results into EE_Payment_Method objects, |
|
| 292 | - * but also verifies the payment method type of each is a usable object. If not, |
|
| 293 | - * deactivate it, sets a notification, and deactivates it |
|
| 294 | - * |
|
| 295 | - * @param array $rows |
|
| 296 | - * @return EE_Payment_Method[] |
|
| 297 | - * @throws InvalidDataTypeException |
|
| 298 | - */ |
|
| 299 | - protected function _create_objects($rows = array()) |
|
| 300 | - { |
|
| 301 | - EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
| 302 | - $payment_methods = parent::_create_objects($rows); |
|
| 303 | - /* @var $payment_methods EE_Payment_Method[] */ |
|
| 304 | - $usable_payment_methods = array(); |
|
| 305 | - foreach ($payment_methods as $key => $payment_method) { |
|
| 306 | - if (EE_Payment_Method_Manager::instance()->payment_method_type_exists($payment_method->type())) { |
|
| 307 | - $usable_payment_methods[ $key ] = $payment_method; |
|
| 308 | - // some payment methods enqueue their scripts in EE_PMT_*::__construct |
|
| 309 | - // which is kinda a no-no (just because it's being constructed doesn't mean we need to enqueue |
|
| 310 | - // its scripts). but for backwards-compat we should continue to do that |
|
| 311 | - $payment_method->type_obj(); |
|
| 312 | - } elseif ($payment_method->active()) { |
|
| 313 | - // only deactivate and notify the admin if the payment is active somewhere |
|
| 314 | - $payment_method->deactivate(); |
|
| 315 | - $payment_method->save(); |
|
| 316 | - do_action( |
|
| 317 | - 'AHEE__EEM_Payment_Method___create_objects_auto_deactivated_payment_method', |
|
| 318 | - $payment_method |
|
| 319 | - ); |
|
| 320 | - new PersistentAdminNotice( |
|
| 321 | - 'auto-deactivated-' . $payment_method->type(), |
|
| 322 | - sprintf( |
|
| 323 | - __( |
|
| 324 | - 'The payment method %1$s was automatically deactivated because it appears its associated Event Espresso Addon was recently deactivated.%2$sIt can be reactivated on the %3$sPlugins admin page%4$s, then you can reactivate the payment method.', |
|
| 325 | - 'event_espresso' |
|
| 326 | - ), |
|
| 327 | - $payment_method->admin_name(), |
|
| 328 | - '<br />', |
|
| 329 | - '<a href="' . admin_url('plugins.php') . '">', |
|
| 330 | - '</a>' |
|
| 331 | - ), |
|
| 332 | - true |
|
| 333 | - ); |
|
| 334 | - } |
|
| 335 | - } |
|
| 336 | - return $usable_payment_methods; |
|
| 337 | - } |
|
| 338 | - |
|
| 339 | - |
|
| 340 | - |
|
| 341 | - /** |
|
| 342 | - * Gets all the payment methods which can be used for transaction |
|
| 343 | - * (according to the relations between payment methods and events, and |
|
| 344 | - * the currencies used for the transaction and their relation to payment methods) |
|
| 345 | - * @param EE_Transaction $transaction |
|
| 346 | - * @param string $scope @see EEM_Payment_Method::get_all_for_events |
|
| 347 | - * @return EE_Payment_Method[] |
|
| 348 | - */ |
|
| 349 | - public function get_all_for_transaction($transaction, $scope) |
|
| 350 | - { |
|
| 351 | - // give addons a chance to override what payment methods are chosen based on the transaction |
|
| 352 | - return apply_filters( |
|
| 353 | - 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
| 354 | - $this->get_all_active($scope, array( 'group_by' => 'PMD_type' )), |
|
| 355 | - $transaction, |
|
| 356 | - $scope |
|
| 357 | - ); |
|
| 358 | - } |
|
| 359 | - |
|
| 360 | - |
|
| 361 | - /** |
|
| 362 | - * Returns the payment method used for the last payment made for a registration. |
|
| 363 | - * |
|
| 364 | - * Note: if an offline payment method was selected on the related transaction then this will have no payment methods returned. |
|
| 365 | - * It will ONLY return a payment method for a PAYMENT recorded against the registration. |
|
| 366 | - * |
|
| 367 | - * @param EE_Registration|int $registration_or_reg_id Either the EE_Registration object or the id for the registration. |
|
| 368 | - * @return EE_Payment|null |
|
| 369 | - */ |
|
| 370 | - public function get_last_used_for_registration($registration_or_reg_id) |
|
| 371 | - { |
|
| 372 | - $registration_id = EEM_Registration::instance()->ensure_is_ID($registration_or_reg_id); |
|
| 373 | - |
|
| 374 | - $query_params = array( |
|
| 375 | - 0 => array( |
|
| 376 | - 'Payment.Registration.REG_ID' => $registration_id, |
|
| 377 | - ), |
|
| 378 | - 'order_by' => array( 'Payment.PAY_ID' => 'DESC' ) |
|
| 379 | - ); |
|
| 380 | - return $this->get_one($query_params); |
|
| 381 | - } |
|
| 23 | + const scope_cart = 'CART'; |
|
| 24 | + |
|
| 25 | + const scope_admin = 'ADMIN'; |
|
| 26 | + |
|
| 27 | + const scope_api = 'API'; |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * |
|
| 31 | + * @type EEM_Payment_Method |
|
| 32 | + */ |
|
| 33 | + protected static $_instance = null; |
|
| 34 | + |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * private constructor to prevent direct creation |
|
| 39 | + * @Constructor |
|
| 40 | + * @access protected |
|
| 41 | + * @return EEM_Payment_Method |
|
| 42 | + */ |
|
| 43 | + protected function __construct($timezone = null) |
|
| 44 | + { |
|
| 45 | + $this->singlular_item = __('Payment Method', 'event_espresso'); |
|
| 46 | + $this->plural_item = __('Payment Methods', 'event_espresso'); |
|
| 47 | + $this->_tables = array( 'Payment_Method' => new EE_Primary_Table('esp_payment_method', 'PMD_ID') ); |
|
| 48 | + $this->_fields = array( |
|
| 49 | + 'Payment_Method' => array( |
|
| 50 | + 'PMD_ID' => new EE_Primary_Key_Int_Field('PMD_ID', __("ID", 'event_espresso')), |
|
| 51 | + 'PMD_type' => new EE_Plain_Text_Field('PMD_type', __("Payment Method Type", 'event_espresso'), false, 'Admin_Only'), |
|
| 52 | + 'PMD_name' => new EE_Plain_Text_Field('PMD_name', __("Name", 'event_espresso'), false), |
|
| 53 | + 'PMD_desc' => new EE_Post_Content_Field('PMD_desc', __("Description", 'event_espresso'), false, ''), |
|
| 54 | + 'PMD_admin_name' => new EE_Plain_Text_Field('PMD_admin_name', __("Admin-Only Name", 'event_espresso'), true), |
|
| 55 | + 'PMD_admin_desc' => new EE_Post_Content_Field('PMD_admin_desc', __("Admin-Only Description", 'event_espresso'), true), |
|
| 56 | + 'PMD_slug' => new EE_Slug_Field('PMD_slug', __("Slug", 'event_espresso'), false), |
|
| 57 | + 'PMD_order' => new EE_Integer_Field('PMD_order', __("Order", 'event_espresso'), false, 0), |
|
| 58 | + 'PMD_debug_mode' => new EE_Boolean_Field('PMD_debug_mode', __("Debug Mode On?", 'event_espresso'), false, false), |
|
| 59 | + 'PMD_wp_user' => new EE_WP_User_Field('PMD_wp_user', __("Payment Method Creator ID", 'event_espresso'), false), |
|
| 60 | + 'PMD_open_by_default' => new EE_Boolean_Field('PMD_open_by_default', __("Open by Default?", 'event_espresso'), false, false), 'PMD_button_url' => new EE_Plain_Text_Field('PMD_button_url', __("Button URL", 'event_espresso'), true, ''), |
|
| 61 | + 'PMD_scope' => new EE_Serialized_Text_Field('PMD_scope', __("Usable From?", 'event_espresso'), false, array()), // possible values currently are 'CART','ADMIN','API' |
|
| 62 | + ) ); |
|
| 63 | + $this->_model_relations = array( |
|
| 64 | + 'Payment' => new EE_Has_Many_Relation(), |
|
| 65 | + 'Currency' => new EE_HABTM_Relation('Currency_Payment_Method'), |
|
| 66 | + 'Transaction' => new EE_Has_Many_Relation(), |
|
| 67 | + 'WP_User' => new EE_Belongs_To_Relation(), |
|
| 68 | + ); |
|
| 69 | + parent::__construct($timezone); |
|
| 70 | + } |
|
| 71 | + |
|
| 72 | + |
|
| 73 | + |
|
| 74 | + /** |
|
| 75 | + * Gets one by the slug provided |
|
| 76 | + * @param string $slug |
|
| 77 | + * @return EE_Payment_Method |
|
| 78 | + */ |
|
| 79 | + public function get_one_by_slug($slug) |
|
| 80 | + { |
|
| 81 | + return $this->get_one(array( array( 'PMD_slug' => $slug ) )); |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + |
|
| 85 | + |
|
| 86 | + /** |
|
| 87 | + * Gets all the acceptable scopes for payment methods. |
|
| 88 | + * Keys are their names as store din the DB, and values are nice names for displaying them |
|
| 89 | + * @return array |
|
| 90 | + */ |
|
| 91 | + public function scopes() |
|
| 92 | + { |
|
| 93 | + return apply_filters( |
|
| 94 | + 'FHEE__EEM_Payment_Method__scopes', |
|
| 95 | + array( |
|
| 96 | + self::scope_cart => __("Front-end Registration Page", 'event_espresso'), |
|
| 97 | + self::scope_admin => __("Admin Registration Page (no online processing)", 'event_espresso') |
|
| 98 | + ) |
|
| 99 | + ); |
|
| 100 | + } |
|
| 101 | + |
|
| 102 | + |
|
| 103 | + |
|
| 104 | + /** |
|
| 105 | + * Determines if this is an valid scope |
|
| 106 | + * @param string $scope like one of EEM_Payment_Method::instance()->scopes() |
|
| 107 | + * @return boolean |
|
| 108 | + */ |
|
| 109 | + public function is_valid_scope($scope) |
|
| 110 | + { |
|
| 111 | + $scopes = $this->scopes(); |
|
| 112 | + if (isset($scopes[ $scope ])) { |
|
| 113 | + return true; |
|
| 114 | + } else { |
|
| 115 | + return false; |
|
| 116 | + } |
|
| 117 | + } |
|
| 118 | + |
|
| 119 | + |
|
| 120 | + |
|
| 121 | + /** |
|
| 122 | + * Gets all active payment methods |
|
| 123 | + * @param string $scope one of |
|
| 124 | + * @param array $query_params |
|
| 125 | + * @throws EE_Error |
|
| 126 | + * @return EE_Payment_Method[] |
|
| 127 | + */ |
|
| 128 | + public function get_all_active($scope = null, $query_params = array()) |
|
| 129 | + { |
|
| 130 | + if (! isset($query_params['order_by']) && ! isset($query_params['order'])) { |
|
| 131 | + $query_params['order_by'] = array( 'PMD_order' => 'ASC', 'PMD_ID' => 'ASC' ); |
|
| 132 | + } |
|
| 133 | + return $this->get_all($this->_get_query_params_for_all_active($scope, $query_params)); |
|
| 134 | + } |
|
| 135 | + |
|
| 136 | + /** |
|
| 137 | + * Counts all active gateways in the specified scope |
|
| 138 | + * @param string $scope one of EEM_Payment_Method::scope_* |
|
| 139 | + * @param array $query_params |
|
| 140 | + * @return int |
|
| 141 | + */ |
|
| 142 | + public function count_active($scope = null, $query_params = array()) |
|
| 143 | + { |
|
| 144 | + return $this->count($this->_get_query_params_for_all_active($scope, $query_params)); |
|
| 145 | + } |
|
| 146 | + |
|
| 147 | + /** |
|
| 148 | + * Creates the $query_params that can be passed into any EEM_Payment_Method as their $query_params |
|
| 149 | + * argument to get all active for a given scope |
|
| 150 | + * @param string $scope one of the constants EEM_Payment_Method::scope_* |
|
| 151 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 152 | + * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 153 | + * @throws EE_Error |
|
| 154 | + */ |
|
| 155 | + protected function _get_query_params_for_all_active($scope = null, $query_params = array()) |
|
| 156 | + { |
|
| 157 | + if ($scope) { |
|
| 158 | + if ($this->is_valid_scope($scope)) { |
|
| 159 | + return array_replace_recursive(array( array( 'PMD_scope' => array( 'LIKE', "%$scope%" ) ) ), $query_params); |
|
| 160 | + } else { |
|
| 161 | + throw new EE_Error(sprintf(__("'%s' is not a valid scope for a payment method", "event_espresso"), $scope)); |
|
| 162 | + } |
|
| 163 | + } else { |
|
| 164 | + $acceptable_scopes = array(); |
|
| 165 | + $count = 0; |
|
| 166 | + foreach ($this->scopes() as $scope_name => $desc) { |
|
| 167 | + $count++; |
|
| 168 | + $acceptable_scopes[ 'PMD_scope*' . $count ] = array( 'LIKE', '%' . $scope_name . '%' ); |
|
| 169 | + } |
|
| 170 | + return array_replace_recursive(array( array( 'OR*active_scope' => $acceptable_scopes ) ), $query_params); |
|
| 171 | + } |
|
| 172 | + } |
|
| 173 | + |
|
| 174 | + /** |
|
| 175 | + * Creates the $query_params that can be passed into any EEM_Payment_Method as their $query_params |
|
| 176 | + * argument to get all active for a given scope |
|
| 177 | + * @param string $scope one of the constants EEM_Payment_Method::scope_* |
|
| 178 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 179 | + * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 180 | + * @throws EE_Error |
|
| 181 | + */ |
|
| 182 | + public function get_query_params_for_all_active($scope = null, $query_params = array()) |
|
| 183 | + { |
|
| 184 | + return $this->_get_query_params_for_all_active($scope, $query_params); |
|
| 185 | + } |
|
| 186 | + |
|
| 187 | + |
|
| 188 | + /** |
|
| 189 | + * Gets one active payment method. see @get_all_active for documentation |
|
| 190 | + * @param string $scope |
|
| 191 | + * @param array $query_params |
|
| 192 | + * @return EE_Payment_Method |
|
| 193 | + */ |
|
| 194 | + public function get_one_active($scope = null, $query_params = array()) |
|
| 195 | + { |
|
| 196 | + return $this->get_one($this->_get_query_params_for_all_active($scope, $query_params)); |
|
| 197 | + } |
|
| 198 | + |
|
| 199 | + |
|
| 200 | + |
|
| 201 | + /** |
|
| 202 | + * Gets one payment method of that type, regardless of whether its active or not |
|
| 203 | + * @param string $type |
|
| 204 | + * @return EE_Payment_Method |
|
| 205 | + */ |
|
| 206 | + public function get_one_of_type($type) |
|
| 207 | + { |
|
| 208 | + return $this->get_one(array( array( 'PMD_type' => $type ) )); |
|
| 209 | + } |
|
| 210 | + |
|
| 211 | + |
|
| 212 | + |
|
| 213 | + /** |
|
| 214 | + * Overrides parent ot also check by the slug |
|
| 215 | + * @see EEM_Base::ensure_is_obj() |
|
| 216 | + * @param string|int|EE_Payment_Method $base_class_obj_or_id |
|
| 217 | + * @param boolean $ensure_is_in_db |
|
| 218 | + * @return EE_Payment_Method |
|
| 219 | + * @throws EE_Error |
|
| 220 | + */ |
|
| 221 | + public function ensure_is_obj($base_class_obj_or_id, $ensure_is_in_db = false) |
|
| 222 | + { |
|
| 223 | + // first: check if it's a slug |
|
| 224 | + if (is_string($base_class_obj_or_id)) { |
|
| 225 | + $obj = $this->get_one_by_slug($base_class_obj_or_id); |
|
| 226 | + if ($obj) { |
|
| 227 | + return $obj; |
|
| 228 | + } |
|
| 229 | + } |
|
| 230 | + // ok so it wasn't a slug we were passed. try the usual then (ie, it's an object or an ID) |
|
| 231 | + try { |
|
| 232 | + return parent::ensure_is_obj($base_class_obj_or_id, $ensure_is_in_db); |
|
| 233 | + } catch (EE_Error $e) { |
|
| 234 | + // handle it outside the catch |
|
| 235 | + } |
|
| 236 | + throw new EE_Error(sprintf(__("'%s' is neither a Payment Method ID, slug, nor object.", "event_espresso"), $base_class_obj_or_id)); |
|
| 237 | + } |
|
| 238 | + |
|
| 239 | + |
|
| 240 | + |
|
| 241 | + /** |
|
| 242 | + * Gets the ID of this object, or if its a string finds the object's id |
|
| 243 | + * associated with that slug |
|
| 244 | + * @param mixed $base_obj_or_id_or_slug |
|
| 245 | + * @return int |
|
| 246 | + */ |
|
| 247 | + public function ensure_is_ID($base_obj_or_id_or_slug) |
|
| 248 | + { |
|
| 249 | + if (is_string($base_obj_or_id_or_slug)) { |
|
| 250 | + // assume it's a slug |
|
| 251 | + $base_obj_or_id_or_slug = $this->get_one_by_slug($base_obj_or_id_or_slug); |
|
| 252 | + } |
|
| 253 | + return parent::ensure_is_ID($base_obj_or_id_or_slug); |
|
| 254 | + } |
|
| 255 | + |
|
| 256 | + |
|
| 257 | + |
|
| 258 | + /** |
|
| 259 | + * Verifies the button urls on all the passed payment methods have a valid button url. If not, resets them to their default. |
|
| 260 | + * @param EE_Payment_Method[] $payment_methods. If NULL is provided defaults to all payment methods active in the cart |
|
| 261 | + */ |
|
| 262 | + public function verify_button_urls($payment_methods = null) |
|
| 263 | + { |
|
| 264 | + $payment_methods = is_array($payment_methods) ? $payment_methods : $this->get_all_active(EEM_Payment_Method::scope_cart); |
|
| 265 | + foreach ($payment_methods as $payment_method) { |
|
| 266 | + try { |
|
| 267 | + // If there is really no button URL at all, or if the button URLs still point to decaf folder even |
|
| 268 | + // though this is a caffeinated install, reset it to the default. |
|
| 269 | + $current_button_url = $payment_method->button_url(); |
|
| 270 | + if (empty($current_button_url) |
|
| 271 | + || ( |
|
| 272 | + strpos($current_button_url, 'decaf') !== false |
|
| 273 | + && strpos($payment_method->type_obj()->default_button_url(), 'decaf') === false |
|
| 274 | + ) |
|
| 275 | + ) { |
|
| 276 | + $payment_method->save( |
|
| 277 | + [ |
|
| 278 | + 'PMD_button_url' => $payment_method->type_obj()->default_button_url() |
|
| 279 | + ] |
|
| 280 | + ); |
|
| 281 | + } |
|
| 282 | + } catch (EE_Error $e) { |
|
| 283 | + $payment_method->set_active(false); |
|
| 284 | + } |
|
| 285 | + } |
|
| 286 | + } |
|
| 287 | + |
|
| 288 | + |
|
| 289 | + |
|
| 290 | + /** |
|
| 291 | + * Overrides parent to not only turn wpdb results into EE_Payment_Method objects, |
|
| 292 | + * but also verifies the payment method type of each is a usable object. If not, |
|
| 293 | + * deactivate it, sets a notification, and deactivates it |
|
| 294 | + * |
|
| 295 | + * @param array $rows |
|
| 296 | + * @return EE_Payment_Method[] |
|
| 297 | + * @throws InvalidDataTypeException |
|
| 298 | + */ |
|
| 299 | + protected function _create_objects($rows = array()) |
|
| 300 | + { |
|
| 301 | + EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
| 302 | + $payment_methods = parent::_create_objects($rows); |
|
| 303 | + /* @var $payment_methods EE_Payment_Method[] */ |
|
| 304 | + $usable_payment_methods = array(); |
|
| 305 | + foreach ($payment_methods as $key => $payment_method) { |
|
| 306 | + if (EE_Payment_Method_Manager::instance()->payment_method_type_exists($payment_method->type())) { |
|
| 307 | + $usable_payment_methods[ $key ] = $payment_method; |
|
| 308 | + // some payment methods enqueue their scripts in EE_PMT_*::__construct |
|
| 309 | + // which is kinda a no-no (just because it's being constructed doesn't mean we need to enqueue |
|
| 310 | + // its scripts). but for backwards-compat we should continue to do that |
|
| 311 | + $payment_method->type_obj(); |
|
| 312 | + } elseif ($payment_method->active()) { |
|
| 313 | + // only deactivate and notify the admin if the payment is active somewhere |
|
| 314 | + $payment_method->deactivate(); |
|
| 315 | + $payment_method->save(); |
|
| 316 | + do_action( |
|
| 317 | + 'AHEE__EEM_Payment_Method___create_objects_auto_deactivated_payment_method', |
|
| 318 | + $payment_method |
|
| 319 | + ); |
|
| 320 | + new PersistentAdminNotice( |
|
| 321 | + 'auto-deactivated-' . $payment_method->type(), |
|
| 322 | + sprintf( |
|
| 323 | + __( |
|
| 324 | + 'The payment method %1$s was automatically deactivated because it appears its associated Event Espresso Addon was recently deactivated.%2$sIt can be reactivated on the %3$sPlugins admin page%4$s, then you can reactivate the payment method.', |
|
| 325 | + 'event_espresso' |
|
| 326 | + ), |
|
| 327 | + $payment_method->admin_name(), |
|
| 328 | + '<br />', |
|
| 329 | + '<a href="' . admin_url('plugins.php') . '">', |
|
| 330 | + '</a>' |
|
| 331 | + ), |
|
| 332 | + true |
|
| 333 | + ); |
|
| 334 | + } |
|
| 335 | + } |
|
| 336 | + return $usable_payment_methods; |
|
| 337 | + } |
|
| 338 | + |
|
| 339 | + |
|
| 340 | + |
|
| 341 | + /** |
|
| 342 | + * Gets all the payment methods which can be used for transaction |
|
| 343 | + * (according to the relations between payment methods and events, and |
|
| 344 | + * the currencies used for the transaction and their relation to payment methods) |
|
| 345 | + * @param EE_Transaction $transaction |
|
| 346 | + * @param string $scope @see EEM_Payment_Method::get_all_for_events |
|
| 347 | + * @return EE_Payment_Method[] |
|
| 348 | + */ |
|
| 349 | + public function get_all_for_transaction($transaction, $scope) |
|
| 350 | + { |
|
| 351 | + // give addons a chance to override what payment methods are chosen based on the transaction |
|
| 352 | + return apply_filters( |
|
| 353 | + 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
| 354 | + $this->get_all_active($scope, array( 'group_by' => 'PMD_type' )), |
|
| 355 | + $transaction, |
|
| 356 | + $scope |
|
| 357 | + ); |
|
| 358 | + } |
|
| 359 | + |
|
| 360 | + |
|
| 361 | + /** |
|
| 362 | + * Returns the payment method used for the last payment made for a registration. |
|
| 363 | + * |
|
| 364 | + * Note: if an offline payment method was selected on the related transaction then this will have no payment methods returned. |
|
| 365 | + * It will ONLY return a payment method for a PAYMENT recorded against the registration. |
|
| 366 | + * |
|
| 367 | + * @param EE_Registration|int $registration_or_reg_id Either the EE_Registration object or the id for the registration. |
|
| 368 | + * @return EE_Payment|null |
|
| 369 | + */ |
|
| 370 | + public function get_last_used_for_registration($registration_or_reg_id) |
|
| 371 | + { |
|
| 372 | + $registration_id = EEM_Registration::instance()->ensure_is_ID($registration_or_reg_id); |
|
| 373 | + |
|
| 374 | + $query_params = array( |
|
| 375 | + 0 => array( |
|
| 376 | + 'Payment.Registration.REG_ID' => $registration_id, |
|
| 377 | + ), |
|
| 378 | + 'order_by' => array( 'Payment.PAY_ID' => 'DESC' ) |
|
| 379 | + ); |
|
| 380 | + return $this->get_one($query_params); |
|
| 381 | + } |
|
| 382 | 382 | } |
@@ -23,594 +23,594 @@ |
||
| 23 | 23 | class Registry |
| 24 | 24 | { |
| 25 | 25 | |
| 26 | - const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json'; |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * @var AssetCollection $assets |
|
| 30 | - */ |
|
| 31 | - protected $assets; |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * @var I18nRegistry |
|
| 35 | - */ |
|
| 36 | - private $i18n_registry; |
|
| 37 | - |
|
| 38 | - /** |
|
| 39 | - * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script. |
|
| 40 | - * |
|
| 41 | - * @var array |
|
| 42 | - */ |
|
| 43 | - protected $jsdata = array(); |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * This keeps track of all scripts with registered data. It is used to prevent duplicate data objects setup in the |
|
| 47 | - * page source. |
|
| 48 | - * |
|
| 49 | - * @var array |
|
| 50 | - */ |
|
| 51 | - private $script_handles_with_data = array(); |
|
| 52 | - |
|
| 53 | - |
|
| 54 | - /** |
|
| 55 | - * Holds the manifest data obtained from registered manifest files. |
|
| 56 | - * Manifests are maps of asset chunk name to actual built asset file names. |
|
| 57 | - * Shape of this array is: |
|
| 58 | - * array( |
|
| 59 | - * 'some_namespace_slug' => array( |
|
| 60 | - * 'some_chunk_name' => array( |
|
| 61 | - * 'js' => 'filename.js' |
|
| 62 | - * 'css' => 'filename.js' |
|
| 63 | - * ), |
|
| 64 | - * 'url_base' => 'https://baseurl.com/to/assets |
|
| 65 | - * ) |
|
| 66 | - * ) |
|
| 67 | - * |
|
| 68 | - * @var array |
|
| 69 | - */ |
|
| 70 | - private $manifest_data = array(); |
|
| 71 | - |
|
| 72 | - |
|
| 73 | - /** |
|
| 74 | - * Registry constructor. |
|
| 75 | - * Hooking into WP actions for script registry. |
|
| 76 | - * |
|
| 77 | - * @param AssetCollection $assets |
|
| 78 | - * @param I18nRegistry $i18n_registry |
|
| 79 | - */ |
|
| 80 | - public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry) |
|
| 81 | - { |
|
| 82 | - $this->assets = $assets; |
|
| 83 | - $this->i18n_registry = $i18n_registry; |
|
| 84 | - add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
| 85 | - add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
| 86 | - add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
| 87 | - add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
| 88 | - add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
| 89 | - add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
| 90 | - add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
| 91 | - add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
| 92 | - } |
|
| 93 | - |
|
| 94 | - |
|
| 95 | - /** |
|
| 96 | - * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n |
|
| 97 | - * translation handling. |
|
| 98 | - * |
|
| 99 | - * @return I18nRegistry |
|
| 100 | - */ |
|
| 101 | - public function getI18nRegistry() |
|
| 102 | - { |
|
| 103 | - return $this->i18n_registry; |
|
| 104 | - } |
|
| 105 | - |
|
| 106 | - |
|
| 107 | - /** |
|
| 108 | - * Callback for the wp_enqueue_scripts actions used to register assets. |
|
| 109 | - * |
|
| 110 | - * @since 4.9.62.p |
|
| 111 | - * @throws Exception |
|
| 112 | - */ |
|
| 113 | - public function registerScriptsAndStyles() |
|
| 114 | - { |
|
| 115 | - try { |
|
| 116 | - $this->registerScripts($this->assets->getJavascriptAssets()); |
|
| 117 | - $this->registerStyles($this->assets->getStylesheetAssets()); |
|
| 118 | - } catch (Exception $exception) { |
|
| 119 | - new ExceptionStackTraceDisplay($exception); |
|
| 120 | - } |
|
| 121 | - } |
|
| 122 | - |
|
| 123 | - |
|
| 124 | - /** |
|
| 125 | - * Registers JS assets with WP core |
|
| 126 | - * |
|
| 127 | - * @since 4.9.62.p |
|
| 128 | - * @param JavascriptAsset[] $scripts |
|
| 129 | - * @throws AssetRegistrationException |
|
| 130 | - * @throws InvalidDataTypeException |
|
| 131 | - */ |
|
| 132 | - public function registerScripts(array $scripts) |
|
| 133 | - { |
|
| 134 | - foreach ($scripts as $script) { |
|
| 135 | - // skip to next script if this has already been done |
|
| 136 | - if ($script->isRegistered()) { |
|
| 137 | - continue; |
|
| 138 | - } |
|
| 139 | - do_action( |
|
| 140 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script', |
|
| 141 | - $script |
|
| 142 | - ); |
|
| 143 | - $registered = wp_register_script( |
|
| 144 | - $script->handle(), |
|
| 145 | - $script->source(), |
|
| 146 | - $script->dependencies(), |
|
| 147 | - $script->version(), |
|
| 148 | - $script->loadInFooter() |
|
| 149 | - ); |
|
| 150 | - if (! $registered && $this->debug()) { |
|
| 151 | - throw new AssetRegistrationException($script->handle()); |
|
| 152 | - } |
|
| 153 | - $script->setRegistered($registered); |
|
| 154 | - if ($script->requiresTranslation()) { |
|
| 155 | - $this->registerTranslation($script->handle()); |
|
| 156 | - } |
|
| 157 | - do_action( |
|
| 158 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script', |
|
| 159 | - $script |
|
| 160 | - ); |
|
| 161 | - } |
|
| 162 | - } |
|
| 163 | - |
|
| 164 | - |
|
| 165 | - /** |
|
| 166 | - * Registers CSS assets with WP core |
|
| 167 | - * |
|
| 168 | - * @since 4.9.62.p |
|
| 169 | - * @param StylesheetAsset[] $styles |
|
| 170 | - * @throws InvalidDataTypeException |
|
| 171 | - */ |
|
| 172 | - public function registerStyles(array $styles) |
|
| 173 | - { |
|
| 174 | - foreach ($styles as $style) { |
|
| 175 | - // skip to next style if this has already been done |
|
| 176 | - if ($style->isRegistered()) { |
|
| 177 | - continue; |
|
| 178 | - } |
|
| 179 | - do_action( |
|
| 180 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style', |
|
| 181 | - $style |
|
| 182 | - ); |
|
| 183 | - wp_register_style( |
|
| 184 | - $style->handle(), |
|
| 185 | - $style->source(), |
|
| 186 | - $style->dependencies(), |
|
| 187 | - $style->version(), |
|
| 188 | - $style->media() |
|
| 189 | - ); |
|
| 190 | - $style->setRegistered(); |
|
| 191 | - do_action( |
|
| 192 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style', |
|
| 193 | - $style |
|
| 194 | - ); |
|
| 195 | - } |
|
| 196 | - } |
|
| 197 | - |
|
| 198 | - |
|
| 199 | - /** |
|
| 200 | - * Call back for the script print in frontend and backend. |
|
| 201 | - * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point. |
|
| 202 | - * |
|
| 203 | - * @since 4.9.31.rc.015 |
|
| 204 | - */ |
|
| 205 | - public function enqueueData() |
|
| 206 | - { |
|
| 207 | - $this->removeAlreadyRegisteredDataForScriptHandles(); |
|
| 208 | - wp_add_inline_script( |
|
| 209 | - 'eejs-core', |
|
| 210 | - 'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)), |
|
| 211 | - 'before' |
|
| 212 | - ); |
|
| 213 | - $scripts = $this->assets->getJavascriptAssetsWithData(); |
|
| 214 | - foreach ($scripts as $script) { |
|
| 215 | - $this->addRegisteredScriptHandlesWithData($script->handle()); |
|
| 216 | - if ($script->hasInlineDataCallback()) { |
|
| 217 | - $localize = $script->inlineDataCallback(); |
|
| 218 | - $localize(); |
|
| 219 | - } |
|
| 220 | - } |
|
| 221 | - } |
|
| 222 | - |
|
| 223 | - |
|
| 224 | - /** |
|
| 225 | - * Used to add data to eejs.data object. |
|
| 226 | - * Note: Overriding existing data is not allowed. |
|
| 227 | - * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript. |
|
| 228 | - * If the data you add is something like this: |
|
| 229 | - * $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) ); |
|
| 230 | - * It will be exposed in the page source as: |
|
| 231 | - * eejs.data.my_plugin_data.foo == gar |
|
| 232 | - * |
|
| 233 | - * @param string $key Key used to access your data |
|
| 234 | - * @param string|array $value Value to attach to key |
|
| 235 | - * @throws InvalidArgumentException |
|
| 236 | - */ |
|
| 237 | - public function addData($key, $value) |
|
| 238 | - { |
|
| 239 | - if ($this->verifyDataNotExisting($key)) { |
|
| 240 | - $this->jsdata[ $key ] = $value; |
|
| 241 | - } |
|
| 242 | - } |
|
| 243 | - |
|
| 244 | - |
|
| 245 | - /** |
|
| 246 | - * Similar to addData except this allows for users to push values to an existing key where the values on key are |
|
| 247 | - * elements in an array. |
|
| 248 | - * |
|
| 249 | - * When you use this method, the value you include will be merged with the array on $key. |
|
| 250 | - * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript |
|
| 251 | - * object like this, eejs.data.test = [ my_data, |
|
| 252 | - * ] |
|
| 253 | - * If there has already been a scalar value attached to the data object given key (via addData for instance), then |
|
| 254 | - * this will throw an exception. |
|
| 255 | - * |
|
| 256 | - * Caution: Only add data using this method if you are okay with the potential for additional data added on the same |
|
| 257 | - * key potentially overriding the existing data on merge (specifically with associative arrays). |
|
| 258 | - * |
|
| 259 | - * @param string $key Key to attach data to. |
|
| 260 | - * @param string|array $value Value being registered. |
|
| 261 | - * @throws InvalidArgumentException |
|
| 262 | - */ |
|
| 263 | - public function pushData($key, $value) |
|
| 264 | - { |
|
| 265 | - if (isset($this->jsdata[ $key ]) |
|
| 266 | - && ! is_array($this->jsdata[ $key ]) |
|
| 267 | - ) { |
|
| 268 | - if (! $this->debug()) { |
|
| 269 | - return; |
|
| 270 | - } |
|
| 271 | - throw new InvalidArgumentException( |
|
| 272 | - sprintf( |
|
| 273 | - __( |
|
| 274 | - 'The value for %1$s is already set and it is not an array. The %2$s method can only be used to |
|
| 26 | + const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json'; |
|
| 27 | + |
|
| 28 | + /** |
|
| 29 | + * @var AssetCollection $assets |
|
| 30 | + */ |
|
| 31 | + protected $assets; |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * @var I18nRegistry |
|
| 35 | + */ |
|
| 36 | + private $i18n_registry; |
|
| 37 | + |
|
| 38 | + /** |
|
| 39 | + * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script. |
|
| 40 | + * |
|
| 41 | + * @var array |
|
| 42 | + */ |
|
| 43 | + protected $jsdata = array(); |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * This keeps track of all scripts with registered data. It is used to prevent duplicate data objects setup in the |
|
| 47 | + * page source. |
|
| 48 | + * |
|
| 49 | + * @var array |
|
| 50 | + */ |
|
| 51 | + private $script_handles_with_data = array(); |
|
| 52 | + |
|
| 53 | + |
|
| 54 | + /** |
|
| 55 | + * Holds the manifest data obtained from registered manifest files. |
|
| 56 | + * Manifests are maps of asset chunk name to actual built asset file names. |
|
| 57 | + * Shape of this array is: |
|
| 58 | + * array( |
|
| 59 | + * 'some_namespace_slug' => array( |
|
| 60 | + * 'some_chunk_name' => array( |
|
| 61 | + * 'js' => 'filename.js' |
|
| 62 | + * 'css' => 'filename.js' |
|
| 63 | + * ), |
|
| 64 | + * 'url_base' => 'https://baseurl.com/to/assets |
|
| 65 | + * ) |
|
| 66 | + * ) |
|
| 67 | + * |
|
| 68 | + * @var array |
|
| 69 | + */ |
|
| 70 | + private $manifest_data = array(); |
|
| 71 | + |
|
| 72 | + |
|
| 73 | + /** |
|
| 74 | + * Registry constructor. |
|
| 75 | + * Hooking into WP actions for script registry. |
|
| 76 | + * |
|
| 77 | + * @param AssetCollection $assets |
|
| 78 | + * @param I18nRegistry $i18n_registry |
|
| 79 | + */ |
|
| 80 | + public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry) |
|
| 81 | + { |
|
| 82 | + $this->assets = $assets; |
|
| 83 | + $this->i18n_registry = $i18n_registry; |
|
| 84 | + add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
| 85 | + add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
| 86 | + add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
| 87 | + add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
| 88 | + add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
| 89 | + add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
| 90 | + add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
| 91 | + add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
| 92 | + } |
|
| 93 | + |
|
| 94 | + |
|
| 95 | + /** |
|
| 96 | + * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n |
|
| 97 | + * translation handling. |
|
| 98 | + * |
|
| 99 | + * @return I18nRegistry |
|
| 100 | + */ |
|
| 101 | + public function getI18nRegistry() |
|
| 102 | + { |
|
| 103 | + return $this->i18n_registry; |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + |
|
| 107 | + /** |
|
| 108 | + * Callback for the wp_enqueue_scripts actions used to register assets. |
|
| 109 | + * |
|
| 110 | + * @since 4.9.62.p |
|
| 111 | + * @throws Exception |
|
| 112 | + */ |
|
| 113 | + public function registerScriptsAndStyles() |
|
| 114 | + { |
|
| 115 | + try { |
|
| 116 | + $this->registerScripts($this->assets->getJavascriptAssets()); |
|
| 117 | + $this->registerStyles($this->assets->getStylesheetAssets()); |
|
| 118 | + } catch (Exception $exception) { |
|
| 119 | + new ExceptionStackTraceDisplay($exception); |
|
| 120 | + } |
|
| 121 | + } |
|
| 122 | + |
|
| 123 | + |
|
| 124 | + /** |
|
| 125 | + * Registers JS assets with WP core |
|
| 126 | + * |
|
| 127 | + * @since 4.9.62.p |
|
| 128 | + * @param JavascriptAsset[] $scripts |
|
| 129 | + * @throws AssetRegistrationException |
|
| 130 | + * @throws InvalidDataTypeException |
|
| 131 | + */ |
|
| 132 | + public function registerScripts(array $scripts) |
|
| 133 | + { |
|
| 134 | + foreach ($scripts as $script) { |
|
| 135 | + // skip to next script if this has already been done |
|
| 136 | + if ($script->isRegistered()) { |
|
| 137 | + continue; |
|
| 138 | + } |
|
| 139 | + do_action( |
|
| 140 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script', |
|
| 141 | + $script |
|
| 142 | + ); |
|
| 143 | + $registered = wp_register_script( |
|
| 144 | + $script->handle(), |
|
| 145 | + $script->source(), |
|
| 146 | + $script->dependencies(), |
|
| 147 | + $script->version(), |
|
| 148 | + $script->loadInFooter() |
|
| 149 | + ); |
|
| 150 | + if (! $registered && $this->debug()) { |
|
| 151 | + throw new AssetRegistrationException($script->handle()); |
|
| 152 | + } |
|
| 153 | + $script->setRegistered($registered); |
|
| 154 | + if ($script->requiresTranslation()) { |
|
| 155 | + $this->registerTranslation($script->handle()); |
|
| 156 | + } |
|
| 157 | + do_action( |
|
| 158 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script', |
|
| 159 | + $script |
|
| 160 | + ); |
|
| 161 | + } |
|
| 162 | + } |
|
| 163 | + |
|
| 164 | + |
|
| 165 | + /** |
|
| 166 | + * Registers CSS assets with WP core |
|
| 167 | + * |
|
| 168 | + * @since 4.9.62.p |
|
| 169 | + * @param StylesheetAsset[] $styles |
|
| 170 | + * @throws InvalidDataTypeException |
|
| 171 | + */ |
|
| 172 | + public function registerStyles(array $styles) |
|
| 173 | + { |
|
| 174 | + foreach ($styles as $style) { |
|
| 175 | + // skip to next style if this has already been done |
|
| 176 | + if ($style->isRegistered()) { |
|
| 177 | + continue; |
|
| 178 | + } |
|
| 179 | + do_action( |
|
| 180 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style', |
|
| 181 | + $style |
|
| 182 | + ); |
|
| 183 | + wp_register_style( |
|
| 184 | + $style->handle(), |
|
| 185 | + $style->source(), |
|
| 186 | + $style->dependencies(), |
|
| 187 | + $style->version(), |
|
| 188 | + $style->media() |
|
| 189 | + ); |
|
| 190 | + $style->setRegistered(); |
|
| 191 | + do_action( |
|
| 192 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style', |
|
| 193 | + $style |
|
| 194 | + ); |
|
| 195 | + } |
|
| 196 | + } |
|
| 197 | + |
|
| 198 | + |
|
| 199 | + /** |
|
| 200 | + * Call back for the script print in frontend and backend. |
|
| 201 | + * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point. |
|
| 202 | + * |
|
| 203 | + * @since 4.9.31.rc.015 |
|
| 204 | + */ |
|
| 205 | + public function enqueueData() |
|
| 206 | + { |
|
| 207 | + $this->removeAlreadyRegisteredDataForScriptHandles(); |
|
| 208 | + wp_add_inline_script( |
|
| 209 | + 'eejs-core', |
|
| 210 | + 'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)), |
|
| 211 | + 'before' |
|
| 212 | + ); |
|
| 213 | + $scripts = $this->assets->getJavascriptAssetsWithData(); |
|
| 214 | + foreach ($scripts as $script) { |
|
| 215 | + $this->addRegisteredScriptHandlesWithData($script->handle()); |
|
| 216 | + if ($script->hasInlineDataCallback()) { |
|
| 217 | + $localize = $script->inlineDataCallback(); |
|
| 218 | + $localize(); |
|
| 219 | + } |
|
| 220 | + } |
|
| 221 | + } |
|
| 222 | + |
|
| 223 | + |
|
| 224 | + /** |
|
| 225 | + * Used to add data to eejs.data object. |
|
| 226 | + * Note: Overriding existing data is not allowed. |
|
| 227 | + * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript. |
|
| 228 | + * If the data you add is something like this: |
|
| 229 | + * $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) ); |
|
| 230 | + * It will be exposed in the page source as: |
|
| 231 | + * eejs.data.my_plugin_data.foo == gar |
|
| 232 | + * |
|
| 233 | + * @param string $key Key used to access your data |
|
| 234 | + * @param string|array $value Value to attach to key |
|
| 235 | + * @throws InvalidArgumentException |
|
| 236 | + */ |
|
| 237 | + public function addData($key, $value) |
|
| 238 | + { |
|
| 239 | + if ($this->verifyDataNotExisting($key)) { |
|
| 240 | + $this->jsdata[ $key ] = $value; |
|
| 241 | + } |
|
| 242 | + } |
|
| 243 | + |
|
| 244 | + |
|
| 245 | + /** |
|
| 246 | + * Similar to addData except this allows for users to push values to an existing key where the values on key are |
|
| 247 | + * elements in an array. |
|
| 248 | + * |
|
| 249 | + * When you use this method, the value you include will be merged with the array on $key. |
|
| 250 | + * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript |
|
| 251 | + * object like this, eejs.data.test = [ my_data, |
|
| 252 | + * ] |
|
| 253 | + * If there has already been a scalar value attached to the data object given key (via addData for instance), then |
|
| 254 | + * this will throw an exception. |
|
| 255 | + * |
|
| 256 | + * Caution: Only add data using this method if you are okay with the potential for additional data added on the same |
|
| 257 | + * key potentially overriding the existing data on merge (specifically with associative arrays). |
|
| 258 | + * |
|
| 259 | + * @param string $key Key to attach data to. |
|
| 260 | + * @param string|array $value Value being registered. |
|
| 261 | + * @throws InvalidArgumentException |
|
| 262 | + */ |
|
| 263 | + public function pushData($key, $value) |
|
| 264 | + { |
|
| 265 | + if (isset($this->jsdata[ $key ]) |
|
| 266 | + && ! is_array($this->jsdata[ $key ]) |
|
| 267 | + ) { |
|
| 268 | + if (! $this->debug()) { |
|
| 269 | + return; |
|
| 270 | + } |
|
| 271 | + throw new InvalidArgumentException( |
|
| 272 | + sprintf( |
|
| 273 | + __( |
|
| 274 | + 'The value for %1$s is already set and it is not an array. The %2$s method can only be used to |
|
| 275 | 275 | push values to this data element when it is an array.', |
| 276 | - 'event_espresso' |
|
| 277 | - ), |
|
| 278 | - $key, |
|
| 279 | - __METHOD__ |
|
| 280 | - ) |
|
| 281 | - ); |
|
| 282 | - } |
|
| 283 | - if ( ! isset( $this->jsdata[ $key ] ) ) { |
|
| 284 | - $this->jsdata[ $key ] = is_array($value) ? $value : [$value]; |
|
| 285 | - } else { |
|
| 286 | - $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value); |
|
| 287 | - } |
|
| 288 | - } |
|
| 289 | - |
|
| 290 | - |
|
| 291 | - /** |
|
| 292 | - * Used to set content used by javascript for a template. |
|
| 293 | - * Note: Overrides of existing registered templates are not allowed. |
|
| 294 | - * |
|
| 295 | - * @param string $template_reference |
|
| 296 | - * @param string $template_content |
|
| 297 | - * @throws InvalidArgumentException |
|
| 298 | - */ |
|
| 299 | - public function addTemplate($template_reference, $template_content) |
|
| 300 | - { |
|
| 301 | - if (! isset($this->jsdata['templates'])) { |
|
| 302 | - $this->jsdata['templates'] = array(); |
|
| 303 | - } |
|
| 304 | - //no overrides allowed. |
|
| 305 | - if (isset($this->jsdata['templates'][ $template_reference ])) { |
|
| 306 | - if (! $this->debug()) { |
|
| 307 | - return; |
|
| 308 | - } |
|
| 309 | - throw new InvalidArgumentException( |
|
| 310 | - sprintf( |
|
| 311 | - __( |
|
| 312 | - 'The %1$s key already exists for the templates array in the js data array. No overrides are allowed.', |
|
| 313 | - 'event_espresso' |
|
| 314 | - ), |
|
| 315 | - $template_reference |
|
| 316 | - ) |
|
| 317 | - ); |
|
| 318 | - } |
|
| 319 | - $this->jsdata['templates'][ $template_reference ] = $template_content; |
|
| 320 | - } |
|
| 321 | - |
|
| 322 | - |
|
| 323 | - /** |
|
| 324 | - * Retrieve the template content already registered for the given reference. |
|
| 325 | - * |
|
| 326 | - * @param string $template_reference |
|
| 327 | - * @return string |
|
| 328 | - */ |
|
| 329 | - public function getTemplate($template_reference) |
|
| 330 | - { |
|
| 331 | - return isset($this->jsdata['templates'][ $template_reference ]) |
|
| 332 | - ? $this->jsdata['templates'][ $template_reference ] |
|
| 333 | - : ''; |
|
| 334 | - } |
|
| 335 | - |
|
| 336 | - |
|
| 337 | - /** |
|
| 338 | - * Retrieve registered data. |
|
| 339 | - * |
|
| 340 | - * @param string $key Name of key to attach data to. |
|
| 341 | - * @return mixed If there is no for the given key, then false is returned. |
|
| 342 | - */ |
|
| 343 | - public function getData($key) |
|
| 344 | - { |
|
| 345 | - return isset($this->jsdata[ $key ]) |
|
| 346 | - ? $this->jsdata[ $key ] |
|
| 347 | - : false; |
|
| 348 | - } |
|
| 349 | - |
|
| 350 | - |
|
| 351 | - /** |
|
| 352 | - * Verifies whether the given data exists already on the jsdata array. |
|
| 353 | - * Overriding data is not allowed. |
|
| 354 | - * |
|
| 355 | - * @param string $key Index for data. |
|
| 356 | - * @return bool If valid then return true. |
|
| 357 | - * @throws InvalidArgumentException if data already exists. |
|
| 358 | - */ |
|
| 359 | - protected function verifyDataNotExisting($key) |
|
| 360 | - { |
|
| 361 | - if (isset($this->jsdata[ $key ])) { |
|
| 362 | - if (! $this->debug()) { |
|
| 363 | - return false; |
|
| 364 | - } |
|
| 365 | - if (is_array($this->jsdata[ $key ])) { |
|
| 366 | - throw new InvalidArgumentException( |
|
| 367 | - sprintf( |
|
| 368 | - __( |
|
| 369 | - 'The value for %1$s already exists in the Registry::eejs object. |
|
| 276 | + 'event_espresso' |
|
| 277 | + ), |
|
| 278 | + $key, |
|
| 279 | + __METHOD__ |
|
| 280 | + ) |
|
| 281 | + ); |
|
| 282 | + } |
|
| 283 | + if ( ! isset( $this->jsdata[ $key ] ) ) { |
|
| 284 | + $this->jsdata[ $key ] = is_array($value) ? $value : [$value]; |
|
| 285 | + } else { |
|
| 286 | + $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value); |
|
| 287 | + } |
|
| 288 | + } |
|
| 289 | + |
|
| 290 | + |
|
| 291 | + /** |
|
| 292 | + * Used to set content used by javascript for a template. |
|
| 293 | + * Note: Overrides of existing registered templates are not allowed. |
|
| 294 | + * |
|
| 295 | + * @param string $template_reference |
|
| 296 | + * @param string $template_content |
|
| 297 | + * @throws InvalidArgumentException |
|
| 298 | + */ |
|
| 299 | + public function addTemplate($template_reference, $template_content) |
|
| 300 | + { |
|
| 301 | + if (! isset($this->jsdata['templates'])) { |
|
| 302 | + $this->jsdata['templates'] = array(); |
|
| 303 | + } |
|
| 304 | + //no overrides allowed. |
|
| 305 | + if (isset($this->jsdata['templates'][ $template_reference ])) { |
|
| 306 | + if (! $this->debug()) { |
|
| 307 | + return; |
|
| 308 | + } |
|
| 309 | + throw new InvalidArgumentException( |
|
| 310 | + sprintf( |
|
| 311 | + __( |
|
| 312 | + 'The %1$s key already exists for the templates array in the js data array. No overrides are allowed.', |
|
| 313 | + 'event_espresso' |
|
| 314 | + ), |
|
| 315 | + $template_reference |
|
| 316 | + ) |
|
| 317 | + ); |
|
| 318 | + } |
|
| 319 | + $this->jsdata['templates'][ $template_reference ] = $template_content; |
|
| 320 | + } |
|
| 321 | + |
|
| 322 | + |
|
| 323 | + /** |
|
| 324 | + * Retrieve the template content already registered for the given reference. |
|
| 325 | + * |
|
| 326 | + * @param string $template_reference |
|
| 327 | + * @return string |
|
| 328 | + */ |
|
| 329 | + public function getTemplate($template_reference) |
|
| 330 | + { |
|
| 331 | + return isset($this->jsdata['templates'][ $template_reference ]) |
|
| 332 | + ? $this->jsdata['templates'][ $template_reference ] |
|
| 333 | + : ''; |
|
| 334 | + } |
|
| 335 | + |
|
| 336 | + |
|
| 337 | + /** |
|
| 338 | + * Retrieve registered data. |
|
| 339 | + * |
|
| 340 | + * @param string $key Name of key to attach data to. |
|
| 341 | + * @return mixed If there is no for the given key, then false is returned. |
|
| 342 | + */ |
|
| 343 | + public function getData($key) |
|
| 344 | + { |
|
| 345 | + return isset($this->jsdata[ $key ]) |
|
| 346 | + ? $this->jsdata[ $key ] |
|
| 347 | + : false; |
|
| 348 | + } |
|
| 349 | + |
|
| 350 | + |
|
| 351 | + /** |
|
| 352 | + * Verifies whether the given data exists already on the jsdata array. |
|
| 353 | + * Overriding data is not allowed. |
|
| 354 | + * |
|
| 355 | + * @param string $key Index for data. |
|
| 356 | + * @return bool If valid then return true. |
|
| 357 | + * @throws InvalidArgumentException if data already exists. |
|
| 358 | + */ |
|
| 359 | + protected function verifyDataNotExisting($key) |
|
| 360 | + { |
|
| 361 | + if (isset($this->jsdata[ $key ])) { |
|
| 362 | + if (! $this->debug()) { |
|
| 363 | + return false; |
|
| 364 | + } |
|
| 365 | + if (is_array($this->jsdata[ $key ])) { |
|
| 366 | + throw new InvalidArgumentException( |
|
| 367 | + sprintf( |
|
| 368 | + __( |
|
| 369 | + 'The value for %1$s already exists in the Registry::eejs object. |
|
| 370 | 370 | Overrides are not allowed. Since the value of this data is an array, you may want to use the |
| 371 | 371 | %2$s method to push your value to the array.', |
| 372 | - 'event_espresso' |
|
| 373 | - ), |
|
| 374 | - $key, |
|
| 375 | - 'pushData()' |
|
| 376 | - ) |
|
| 377 | - ); |
|
| 378 | - } |
|
| 379 | - throw new InvalidArgumentException( |
|
| 380 | - sprintf( |
|
| 381 | - __( |
|
| 382 | - 'The value for %1$s already exists in the Registry::eejs object. Overrides are not |
|
| 372 | + 'event_espresso' |
|
| 373 | + ), |
|
| 374 | + $key, |
|
| 375 | + 'pushData()' |
|
| 376 | + ) |
|
| 377 | + ); |
|
| 378 | + } |
|
| 379 | + throw new InvalidArgumentException( |
|
| 380 | + sprintf( |
|
| 381 | + __( |
|
| 382 | + 'The value for %1$s already exists in the Registry::eejs object. Overrides are not |
|
| 383 | 383 | allowed. Consider attaching your value to a different key', |
| 384 | - 'event_espresso' |
|
| 385 | - ), |
|
| 386 | - $key |
|
| 387 | - ) |
|
| 388 | - ); |
|
| 389 | - } |
|
| 390 | - return true; |
|
| 391 | - } |
|
| 392 | - |
|
| 393 | - |
|
| 394 | - /** |
|
| 395 | - * Get the actual asset path for asset manifests. |
|
| 396 | - * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned. |
|
| 397 | - * |
|
| 398 | - * @param string $namespace The namespace associated with the manifest file hosting the map of chunk_name to actual |
|
| 399 | - * asset file location. |
|
| 400 | - * @param string $chunk_name |
|
| 401 | - * @param string $asset_type |
|
| 402 | - * @return string |
|
| 403 | - * @since 4.9.59.p |
|
| 404 | - */ |
|
| 405 | - public function getAssetUrl($namespace, $chunk_name, $asset_type) |
|
| 406 | - { |
|
| 407 | - $url = isset( |
|
| 408 | - $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ], |
|
| 409 | - $this->manifest_data[ $namespace ]['url_base'] |
|
| 410 | - ) |
|
| 411 | - ? $this->manifest_data[ $namespace ]['url_base'] |
|
| 412 | - . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ] |
|
| 413 | - : $chunk_name; |
|
| 414 | - return apply_filters( |
|
| 415 | - 'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl', |
|
| 416 | - $url, |
|
| 417 | - $namespace, |
|
| 418 | - $chunk_name, |
|
| 419 | - $asset_type |
|
| 420 | - ); |
|
| 421 | - } |
|
| 422 | - |
|
| 423 | - |
|
| 424 | - |
|
| 425 | - /** |
|
| 426 | - * Return the url to a js file for the given namespace and chunk name. |
|
| 427 | - * |
|
| 428 | - * @param string $namespace |
|
| 429 | - * @param string $chunk_name |
|
| 430 | - * @return string |
|
| 431 | - */ |
|
| 432 | - public function getJsUrl($namespace, $chunk_name) |
|
| 433 | - { |
|
| 434 | - return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS); |
|
| 435 | - } |
|
| 436 | - |
|
| 437 | - |
|
| 438 | - /** |
|
| 439 | - * Return the url to a css file for the given namespace and chunk name. |
|
| 440 | - * |
|
| 441 | - * @param string $namespace |
|
| 442 | - * @param string $chunk_name |
|
| 443 | - * @return string |
|
| 444 | - */ |
|
| 445 | - public function getCssUrl($namespace, $chunk_name) |
|
| 446 | - { |
|
| 447 | - return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS); |
|
| 448 | - } |
|
| 449 | - |
|
| 450 | - |
|
| 451 | - /** |
|
| 452 | - * @since 4.9.62.p |
|
| 453 | - * @throws InvalidArgumentException |
|
| 454 | - * @throws InvalidFilePathException |
|
| 455 | - */ |
|
| 456 | - public function registerManifestFiles() |
|
| 457 | - { |
|
| 458 | - $manifest_files = $this->assets->getManifestFiles(); |
|
| 459 | - foreach ($manifest_files as $manifest_file) { |
|
| 460 | - $this->registerManifestFile( |
|
| 461 | - $manifest_file->assetNamespace(), |
|
| 462 | - $manifest_file->urlBase(), |
|
| 463 | - $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST |
|
| 464 | - ); |
|
| 465 | - } |
|
| 466 | - } |
|
| 467 | - |
|
| 468 | - |
|
| 469 | - /** |
|
| 470 | - * Used to register a js/css manifest file with the registered_manifest_files property. |
|
| 471 | - * |
|
| 472 | - * @param string $namespace Provided to associate the manifest file with a specific namespace. |
|
| 473 | - * @param string $url_base The url base for the manifest file location. |
|
| 474 | - * @param string $manifest_file The absolute path to the manifest file. |
|
| 475 | - * @throws InvalidArgumentException |
|
| 476 | - * @throws InvalidFilePathException |
|
| 477 | - * @since 4.9.59.p |
|
| 478 | - */ |
|
| 479 | - public function registerManifestFile($namespace, $url_base, $manifest_file) |
|
| 480 | - { |
|
| 481 | - if (isset($this->manifest_data[ $namespace ])) { |
|
| 482 | - if (! $this->debug()) { |
|
| 483 | - return; |
|
| 484 | - } |
|
| 485 | - throw new InvalidArgumentException( |
|
| 486 | - sprintf( |
|
| 487 | - esc_html__( |
|
| 488 | - 'The namespace for this manifest file has already been registered, choose a namespace other than %s', |
|
| 489 | - 'event_espresso' |
|
| 490 | - ), |
|
| 491 | - $namespace |
|
| 492 | - ) |
|
| 493 | - ); |
|
| 494 | - } |
|
| 495 | - if (filter_var($url_base, FILTER_VALIDATE_URL) === false) { |
|
| 496 | - if (is_admin()) { |
|
| 497 | - EE_Error::add_error( |
|
| 498 | - sprintf( |
|
| 499 | - esc_html__( |
|
| 500 | - 'The url given for %1$s assets is invalid. The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant', |
|
| 501 | - 'event_espresso' |
|
| 502 | - ), |
|
| 503 | - 'Event Espresso', |
|
| 504 | - $url_base, |
|
| 505 | - 'plugins_url', |
|
| 506 | - 'WP_PLUGIN_URL' |
|
| 507 | - ), |
|
| 508 | - __FILE__, |
|
| 509 | - __FUNCTION__, |
|
| 510 | - __LINE__ |
|
| 511 | - ); |
|
| 512 | - } |
|
| 513 | - return; |
|
| 514 | - } |
|
| 515 | - $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file); |
|
| 516 | - if (! isset($this->manifest_data[ $namespace ]['url_base'])) { |
|
| 517 | - $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base); |
|
| 518 | - } |
|
| 519 | - } |
|
| 520 | - |
|
| 521 | - |
|
| 522 | - /** |
|
| 523 | - * Decodes json from the provided manifest file. |
|
| 524 | - * |
|
| 525 | - * @since 4.9.59.p |
|
| 526 | - * @param string $manifest_file Path to manifest file. |
|
| 527 | - * @return array |
|
| 528 | - * @throws InvalidFilePathException |
|
| 529 | - */ |
|
| 530 | - private function decodeManifestFile($manifest_file) |
|
| 531 | - { |
|
| 532 | - if (! file_exists($manifest_file)) { |
|
| 533 | - throw new InvalidFilePathException($manifest_file); |
|
| 534 | - } |
|
| 535 | - return json_decode(file_get_contents($manifest_file), true); |
|
| 536 | - } |
|
| 537 | - |
|
| 538 | - |
|
| 539 | - /** |
|
| 540 | - * This is used to set registered script handles that have data. |
|
| 541 | - * |
|
| 542 | - * @param string $script_handle |
|
| 543 | - */ |
|
| 544 | - private function addRegisteredScriptHandlesWithData($script_handle) |
|
| 545 | - { |
|
| 546 | - $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
| 547 | - } |
|
| 548 | - |
|
| 549 | - |
|
| 550 | - /**i |
|
| 384 | + 'event_espresso' |
|
| 385 | + ), |
|
| 386 | + $key |
|
| 387 | + ) |
|
| 388 | + ); |
|
| 389 | + } |
|
| 390 | + return true; |
|
| 391 | + } |
|
| 392 | + |
|
| 393 | + |
|
| 394 | + /** |
|
| 395 | + * Get the actual asset path for asset manifests. |
|
| 396 | + * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned. |
|
| 397 | + * |
|
| 398 | + * @param string $namespace The namespace associated with the manifest file hosting the map of chunk_name to actual |
|
| 399 | + * asset file location. |
|
| 400 | + * @param string $chunk_name |
|
| 401 | + * @param string $asset_type |
|
| 402 | + * @return string |
|
| 403 | + * @since 4.9.59.p |
|
| 404 | + */ |
|
| 405 | + public function getAssetUrl($namespace, $chunk_name, $asset_type) |
|
| 406 | + { |
|
| 407 | + $url = isset( |
|
| 408 | + $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ], |
|
| 409 | + $this->manifest_data[ $namespace ]['url_base'] |
|
| 410 | + ) |
|
| 411 | + ? $this->manifest_data[ $namespace ]['url_base'] |
|
| 412 | + . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ] |
|
| 413 | + : $chunk_name; |
|
| 414 | + return apply_filters( |
|
| 415 | + 'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl', |
|
| 416 | + $url, |
|
| 417 | + $namespace, |
|
| 418 | + $chunk_name, |
|
| 419 | + $asset_type |
|
| 420 | + ); |
|
| 421 | + } |
|
| 422 | + |
|
| 423 | + |
|
| 424 | + |
|
| 425 | + /** |
|
| 426 | + * Return the url to a js file for the given namespace and chunk name. |
|
| 427 | + * |
|
| 428 | + * @param string $namespace |
|
| 429 | + * @param string $chunk_name |
|
| 430 | + * @return string |
|
| 431 | + */ |
|
| 432 | + public function getJsUrl($namespace, $chunk_name) |
|
| 433 | + { |
|
| 434 | + return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS); |
|
| 435 | + } |
|
| 436 | + |
|
| 437 | + |
|
| 438 | + /** |
|
| 439 | + * Return the url to a css file for the given namespace and chunk name. |
|
| 440 | + * |
|
| 441 | + * @param string $namespace |
|
| 442 | + * @param string $chunk_name |
|
| 443 | + * @return string |
|
| 444 | + */ |
|
| 445 | + public function getCssUrl($namespace, $chunk_name) |
|
| 446 | + { |
|
| 447 | + return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS); |
|
| 448 | + } |
|
| 449 | + |
|
| 450 | + |
|
| 451 | + /** |
|
| 452 | + * @since 4.9.62.p |
|
| 453 | + * @throws InvalidArgumentException |
|
| 454 | + * @throws InvalidFilePathException |
|
| 455 | + */ |
|
| 456 | + public function registerManifestFiles() |
|
| 457 | + { |
|
| 458 | + $manifest_files = $this->assets->getManifestFiles(); |
|
| 459 | + foreach ($manifest_files as $manifest_file) { |
|
| 460 | + $this->registerManifestFile( |
|
| 461 | + $manifest_file->assetNamespace(), |
|
| 462 | + $manifest_file->urlBase(), |
|
| 463 | + $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST |
|
| 464 | + ); |
|
| 465 | + } |
|
| 466 | + } |
|
| 467 | + |
|
| 468 | + |
|
| 469 | + /** |
|
| 470 | + * Used to register a js/css manifest file with the registered_manifest_files property. |
|
| 471 | + * |
|
| 472 | + * @param string $namespace Provided to associate the manifest file with a specific namespace. |
|
| 473 | + * @param string $url_base The url base for the manifest file location. |
|
| 474 | + * @param string $manifest_file The absolute path to the manifest file. |
|
| 475 | + * @throws InvalidArgumentException |
|
| 476 | + * @throws InvalidFilePathException |
|
| 477 | + * @since 4.9.59.p |
|
| 478 | + */ |
|
| 479 | + public function registerManifestFile($namespace, $url_base, $manifest_file) |
|
| 480 | + { |
|
| 481 | + if (isset($this->manifest_data[ $namespace ])) { |
|
| 482 | + if (! $this->debug()) { |
|
| 483 | + return; |
|
| 484 | + } |
|
| 485 | + throw new InvalidArgumentException( |
|
| 486 | + sprintf( |
|
| 487 | + esc_html__( |
|
| 488 | + 'The namespace for this manifest file has already been registered, choose a namespace other than %s', |
|
| 489 | + 'event_espresso' |
|
| 490 | + ), |
|
| 491 | + $namespace |
|
| 492 | + ) |
|
| 493 | + ); |
|
| 494 | + } |
|
| 495 | + if (filter_var($url_base, FILTER_VALIDATE_URL) === false) { |
|
| 496 | + if (is_admin()) { |
|
| 497 | + EE_Error::add_error( |
|
| 498 | + sprintf( |
|
| 499 | + esc_html__( |
|
| 500 | + 'The url given for %1$s assets is invalid. The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant', |
|
| 501 | + 'event_espresso' |
|
| 502 | + ), |
|
| 503 | + 'Event Espresso', |
|
| 504 | + $url_base, |
|
| 505 | + 'plugins_url', |
|
| 506 | + 'WP_PLUGIN_URL' |
|
| 507 | + ), |
|
| 508 | + __FILE__, |
|
| 509 | + __FUNCTION__, |
|
| 510 | + __LINE__ |
|
| 511 | + ); |
|
| 512 | + } |
|
| 513 | + return; |
|
| 514 | + } |
|
| 515 | + $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file); |
|
| 516 | + if (! isset($this->manifest_data[ $namespace ]['url_base'])) { |
|
| 517 | + $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base); |
|
| 518 | + } |
|
| 519 | + } |
|
| 520 | + |
|
| 521 | + |
|
| 522 | + /** |
|
| 523 | + * Decodes json from the provided manifest file. |
|
| 524 | + * |
|
| 525 | + * @since 4.9.59.p |
|
| 526 | + * @param string $manifest_file Path to manifest file. |
|
| 527 | + * @return array |
|
| 528 | + * @throws InvalidFilePathException |
|
| 529 | + */ |
|
| 530 | + private function decodeManifestFile($manifest_file) |
|
| 531 | + { |
|
| 532 | + if (! file_exists($manifest_file)) { |
|
| 533 | + throw new InvalidFilePathException($manifest_file); |
|
| 534 | + } |
|
| 535 | + return json_decode(file_get_contents($manifest_file), true); |
|
| 536 | + } |
|
| 537 | + |
|
| 538 | + |
|
| 539 | + /** |
|
| 540 | + * This is used to set registered script handles that have data. |
|
| 541 | + * |
|
| 542 | + * @param string $script_handle |
|
| 543 | + */ |
|
| 544 | + private function addRegisteredScriptHandlesWithData($script_handle) |
|
| 545 | + { |
|
| 546 | + $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
| 547 | + } |
|
| 548 | + |
|
| 549 | + |
|
| 550 | + /**i |
|
| 551 | 551 | * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the |
| 552 | 552 | * Dependency stored in WP_Scripts if its set. |
| 553 | 553 | */ |
| 554 | - private function removeAlreadyRegisteredDataForScriptHandles() |
|
| 555 | - { |
|
| 556 | - if (empty($this->script_handles_with_data)) { |
|
| 557 | - return; |
|
| 558 | - } |
|
| 559 | - foreach ($this->script_handles_with_data as $script_handle) { |
|
| 560 | - $this->removeAlreadyRegisteredDataForScriptHandle($script_handle); |
|
| 561 | - } |
|
| 562 | - } |
|
| 563 | - |
|
| 564 | - |
|
| 565 | - /** |
|
| 566 | - * Removes any data dependency registered in WP_Scripts if its set. |
|
| 567 | - * |
|
| 568 | - * @param string $script_handle |
|
| 569 | - */ |
|
| 570 | - private function removeAlreadyRegisteredDataForScriptHandle($script_handle) |
|
| 571 | - { |
|
| 572 | - if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
| 573 | - global $wp_scripts; |
|
| 574 | - $unset_handle = false; |
|
| 575 | - if ($wp_scripts->get_data($script_handle, 'data')) { |
|
| 576 | - unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
| 577 | - $unset_handle = true; |
|
| 578 | - } |
|
| 579 | - //deal with inline_scripts |
|
| 580 | - if ($wp_scripts->get_data($script_handle, 'before')) { |
|
| 581 | - unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
| 582 | - $unset_handle = true; |
|
| 583 | - } |
|
| 584 | - if ($wp_scripts->get_data($script_handle, 'after')) { |
|
| 585 | - unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
| 586 | - } |
|
| 587 | - if ($unset_handle) { |
|
| 588 | - unset($this->script_handles_with_data[ $script_handle ]); |
|
| 589 | - } |
|
| 590 | - } |
|
| 591 | - } |
|
| 592 | - |
|
| 593 | - |
|
| 594 | - /** |
|
| 595 | - * register translations for a registered script |
|
| 596 | - * |
|
| 597 | - * @param string $handle |
|
| 598 | - */ |
|
| 599 | - public function registerTranslation($handle) |
|
| 600 | - { |
|
| 601 | - $this->i18n_registry->registerScriptI18n($handle); |
|
| 602 | - } |
|
| 603 | - |
|
| 604 | - |
|
| 605 | - /** |
|
| 606 | - * @since 4.9.63.p |
|
| 607 | - * @return bool |
|
| 608 | - */ |
|
| 609 | - private function debug() |
|
| 610 | - { |
|
| 611 | - return apply_filters( |
|
| 612 | - 'FHEE__EventEspresso_core_services_assets_Registry__debug', |
|
| 613 | - defined('EE_DEBUG') && EE_DEBUG |
|
| 614 | - ); |
|
| 615 | - } |
|
| 554 | + private function removeAlreadyRegisteredDataForScriptHandles() |
|
| 555 | + { |
|
| 556 | + if (empty($this->script_handles_with_data)) { |
|
| 557 | + return; |
|
| 558 | + } |
|
| 559 | + foreach ($this->script_handles_with_data as $script_handle) { |
|
| 560 | + $this->removeAlreadyRegisteredDataForScriptHandle($script_handle); |
|
| 561 | + } |
|
| 562 | + } |
|
| 563 | + |
|
| 564 | + |
|
| 565 | + /** |
|
| 566 | + * Removes any data dependency registered in WP_Scripts if its set. |
|
| 567 | + * |
|
| 568 | + * @param string $script_handle |
|
| 569 | + */ |
|
| 570 | + private function removeAlreadyRegisteredDataForScriptHandle($script_handle) |
|
| 571 | + { |
|
| 572 | + if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
| 573 | + global $wp_scripts; |
|
| 574 | + $unset_handle = false; |
|
| 575 | + if ($wp_scripts->get_data($script_handle, 'data')) { |
|
| 576 | + unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
| 577 | + $unset_handle = true; |
|
| 578 | + } |
|
| 579 | + //deal with inline_scripts |
|
| 580 | + if ($wp_scripts->get_data($script_handle, 'before')) { |
|
| 581 | + unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
| 582 | + $unset_handle = true; |
|
| 583 | + } |
|
| 584 | + if ($wp_scripts->get_data($script_handle, 'after')) { |
|
| 585 | + unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
| 586 | + } |
|
| 587 | + if ($unset_handle) { |
|
| 588 | + unset($this->script_handles_with_data[ $script_handle ]); |
|
| 589 | + } |
|
| 590 | + } |
|
| 591 | + } |
|
| 592 | + |
|
| 593 | + |
|
| 594 | + /** |
|
| 595 | + * register translations for a registered script |
|
| 596 | + * |
|
| 597 | + * @param string $handle |
|
| 598 | + */ |
|
| 599 | + public function registerTranslation($handle) |
|
| 600 | + { |
|
| 601 | + $this->i18n_registry->registerScriptI18n($handle); |
|
| 602 | + } |
|
| 603 | + |
|
| 604 | + |
|
| 605 | + /** |
|
| 606 | + * @since 4.9.63.p |
|
| 607 | + * @return bool |
|
| 608 | + */ |
|
| 609 | + private function debug() |
|
| 610 | + { |
|
| 611 | + return apply_filters( |
|
| 612 | + 'FHEE__EventEspresso_core_services_assets_Registry__debug', |
|
| 613 | + defined('EE_DEBUG') && EE_DEBUG |
|
| 614 | + ); |
|
| 615 | + } |
|
| 616 | 616 | } |
@@ -147,7 +147,7 @@ discard block |
||
| 147 | 147 | $script->version(), |
| 148 | 148 | $script->loadInFooter() |
| 149 | 149 | ); |
| 150 | - if (! $registered && $this->debug()) { |
|
| 150 | + if ( ! $registered && $this->debug()) { |
|
| 151 | 151 | throw new AssetRegistrationException($script->handle()); |
| 152 | 152 | } |
| 153 | 153 | $script->setRegistered($registered); |
@@ -207,7 +207,7 @@ discard block |
||
| 207 | 207 | $this->removeAlreadyRegisteredDataForScriptHandles(); |
| 208 | 208 | wp_add_inline_script( |
| 209 | 209 | 'eejs-core', |
| 210 | - 'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)), |
|
| 210 | + 'var eejsdata='.wp_json_encode(array('data' => $this->jsdata)), |
|
| 211 | 211 | 'before' |
| 212 | 212 | ); |
| 213 | 213 | $scripts = $this->assets->getJavascriptAssetsWithData(); |
@@ -237,7 +237,7 @@ discard block |
||
| 237 | 237 | public function addData($key, $value) |
| 238 | 238 | { |
| 239 | 239 | if ($this->verifyDataNotExisting($key)) { |
| 240 | - $this->jsdata[ $key ] = $value; |
|
| 240 | + $this->jsdata[$key] = $value; |
|
| 241 | 241 | } |
| 242 | 242 | } |
| 243 | 243 | |
@@ -262,10 +262,10 @@ discard block |
||
| 262 | 262 | */ |
| 263 | 263 | public function pushData($key, $value) |
| 264 | 264 | { |
| 265 | - if (isset($this->jsdata[ $key ]) |
|
| 266 | - && ! is_array($this->jsdata[ $key ]) |
|
| 265 | + if (isset($this->jsdata[$key]) |
|
| 266 | + && ! is_array($this->jsdata[$key]) |
|
| 267 | 267 | ) { |
| 268 | - if (! $this->debug()) { |
|
| 268 | + if ( ! $this->debug()) { |
|
| 269 | 269 | return; |
| 270 | 270 | } |
| 271 | 271 | throw new InvalidArgumentException( |
@@ -280,10 +280,10 @@ discard block |
||
| 280 | 280 | ) |
| 281 | 281 | ); |
| 282 | 282 | } |
| 283 | - if ( ! isset( $this->jsdata[ $key ] ) ) { |
|
| 284 | - $this->jsdata[ $key ] = is_array($value) ? $value : [$value]; |
|
| 283 | + if ( ! isset($this->jsdata[$key])) { |
|
| 284 | + $this->jsdata[$key] = is_array($value) ? $value : [$value]; |
|
| 285 | 285 | } else { |
| 286 | - $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value); |
|
| 286 | + $this->jsdata[$key] = array_merge($this->jsdata[$key], (array) $value); |
|
| 287 | 287 | } |
| 288 | 288 | } |
| 289 | 289 | |
@@ -298,12 +298,12 @@ discard block |
||
| 298 | 298 | */ |
| 299 | 299 | public function addTemplate($template_reference, $template_content) |
| 300 | 300 | { |
| 301 | - if (! isset($this->jsdata['templates'])) { |
|
| 301 | + if ( ! isset($this->jsdata['templates'])) { |
|
| 302 | 302 | $this->jsdata['templates'] = array(); |
| 303 | 303 | } |
| 304 | 304 | //no overrides allowed. |
| 305 | - if (isset($this->jsdata['templates'][ $template_reference ])) { |
|
| 306 | - if (! $this->debug()) { |
|
| 305 | + if (isset($this->jsdata['templates'][$template_reference])) { |
|
| 306 | + if ( ! $this->debug()) { |
|
| 307 | 307 | return; |
| 308 | 308 | } |
| 309 | 309 | throw new InvalidArgumentException( |
@@ -316,7 +316,7 @@ discard block |
||
| 316 | 316 | ) |
| 317 | 317 | ); |
| 318 | 318 | } |
| 319 | - $this->jsdata['templates'][ $template_reference ] = $template_content; |
|
| 319 | + $this->jsdata['templates'][$template_reference] = $template_content; |
|
| 320 | 320 | } |
| 321 | 321 | |
| 322 | 322 | |
@@ -328,8 +328,8 @@ discard block |
||
| 328 | 328 | */ |
| 329 | 329 | public function getTemplate($template_reference) |
| 330 | 330 | { |
| 331 | - return isset($this->jsdata['templates'][ $template_reference ]) |
|
| 332 | - ? $this->jsdata['templates'][ $template_reference ] |
|
| 331 | + return isset($this->jsdata['templates'][$template_reference]) |
|
| 332 | + ? $this->jsdata['templates'][$template_reference] |
|
| 333 | 333 | : ''; |
| 334 | 334 | } |
| 335 | 335 | |
@@ -342,8 +342,8 @@ discard block |
||
| 342 | 342 | */ |
| 343 | 343 | public function getData($key) |
| 344 | 344 | { |
| 345 | - return isset($this->jsdata[ $key ]) |
|
| 346 | - ? $this->jsdata[ $key ] |
|
| 345 | + return isset($this->jsdata[$key]) |
|
| 346 | + ? $this->jsdata[$key] |
|
| 347 | 347 | : false; |
| 348 | 348 | } |
| 349 | 349 | |
@@ -358,11 +358,11 @@ discard block |
||
| 358 | 358 | */ |
| 359 | 359 | protected function verifyDataNotExisting($key) |
| 360 | 360 | { |
| 361 | - if (isset($this->jsdata[ $key ])) { |
|
| 362 | - if (! $this->debug()) { |
|
| 361 | + if (isset($this->jsdata[$key])) { |
|
| 362 | + if ( ! $this->debug()) { |
|
| 363 | 363 | return false; |
| 364 | 364 | } |
| 365 | - if (is_array($this->jsdata[ $key ])) { |
|
| 365 | + if (is_array($this->jsdata[$key])) { |
|
| 366 | 366 | throw new InvalidArgumentException( |
| 367 | 367 | sprintf( |
| 368 | 368 | __( |
@@ -405,11 +405,11 @@ discard block |
||
| 405 | 405 | public function getAssetUrl($namespace, $chunk_name, $asset_type) |
| 406 | 406 | { |
| 407 | 407 | $url = isset( |
| 408 | - $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ], |
|
| 409 | - $this->manifest_data[ $namespace ]['url_base'] |
|
| 408 | + $this->manifest_data[$namespace][$chunk_name.'.'.$asset_type], |
|
| 409 | + $this->manifest_data[$namespace]['url_base'] |
|
| 410 | 410 | ) |
| 411 | - ? $this->manifest_data[ $namespace ]['url_base'] |
|
| 412 | - . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ] |
|
| 411 | + ? $this->manifest_data[$namespace]['url_base'] |
|
| 412 | + . $this->manifest_data[$namespace][$chunk_name.'.'.$asset_type] |
|
| 413 | 413 | : $chunk_name; |
| 414 | 414 | return apply_filters( |
| 415 | 415 | 'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl', |
@@ -460,7 +460,7 @@ discard block |
||
| 460 | 460 | $this->registerManifestFile( |
| 461 | 461 | $manifest_file->assetNamespace(), |
| 462 | 462 | $manifest_file->urlBase(), |
| 463 | - $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST |
|
| 463 | + $manifest_file->filepath().Registry::FILE_NAME_BUILD_MANIFEST |
|
| 464 | 464 | ); |
| 465 | 465 | } |
| 466 | 466 | } |
@@ -478,8 +478,8 @@ discard block |
||
| 478 | 478 | */ |
| 479 | 479 | public function registerManifestFile($namespace, $url_base, $manifest_file) |
| 480 | 480 | { |
| 481 | - if (isset($this->manifest_data[ $namespace ])) { |
|
| 482 | - if (! $this->debug()) { |
|
| 481 | + if (isset($this->manifest_data[$namespace])) { |
|
| 482 | + if ( ! $this->debug()) { |
|
| 483 | 483 | return; |
| 484 | 484 | } |
| 485 | 485 | throw new InvalidArgumentException( |
@@ -512,9 +512,9 @@ discard block |
||
| 512 | 512 | } |
| 513 | 513 | return; |
| 514 | 514 | } |
| 515 | - $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file); |
|
| 516 | - if (! isset($this->manifest_data[ $namespace ]['url_base'])) { |
|
| 517 | - $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base); |
|
| 515 | + $this->manifest_data[$namespace] = $this->decodeManifestFile($manifest_file); |
|
| 516 | + if ( ! isset($this->manifest_data[$namespace]['url_base'])) { |
|
| 517 | + $this->manifest_data[$namespace]['url_base'] = trailingslashit($url_base); |
|
| 518 | 518 | } |
| 519 | 519 | } |
| 520 | 520 | |
@@ -529,7 +529,7 @@ discard block |
||
| 529 | 529 | */ |
| 530 | 530 | private function decodeManifestFile($manifest_file) |
| 531 | 531 | { |
| 532 | - if (! file_exists($manifest_file)) { |
|
| 532 | + if ( ! file_exists($manifest_file)) { |
|
| 533 | 533 | throw new InvalidFilePathException($manifest_file); |
| 534 | 534 | } |
| 535 | 535 | return json_decode(file_get_contents($manifest_file), true); |
@@ -543,7 +543,7 @@ discard block |
||
| 543 | 543 | */ |
| 544 | 544 | private function addRegisteredScriptHandlesWithData($script_handle) |
| 545 | 545 | { |
| 546 | - $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
| 546 | + $this->script_handles_with_data[$script_handle] = $script_handle; |
|
| 547 | 547 | } |
| 548 | 548 | |
| 549 | 549 | |
@@ -569,23 +569,23 @@ discard block |
||
| 569 | 569 | */ |
| 570 | 570 | private function removeAlreadyRegisteredDataForScriptHandle($script_handle) |
| 571 | 571 | { |
| 572 | - if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
| 572 | + if (isset($this->script_handles_with_data[$script_handle])) { |
|
| 573 | 573 | global $wp_scripts; |
| 574 | 574 | $unset_handle = false; |
| 575 | 575 | if ($wp_scripts->get_data($script_handle, 'data')) { |
| 576 | - unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
| 576 | + unset($wp_scripts->registered[$script_handle]->extra['data']); |
|
| 577 | 577 | $unset_handle = true; |
| 578 | 578 | } |
| 579 | 579 | //deal with inline_scripts |
| 580 | 580 | if ($wp_scripts->get_data($script_handle, 'before')) { |
| 581 | - unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
| 581 | + unset($wp_scripts->registered[$script_handle]->extra['before']); |
|
| 582 | 582 | $unset_handle = true; |
| 583 | 583 | } |
| 584 | 584 | if ($wp_scripts->get_data($script_handle, 'after')) { |
| 585 | - unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
| 585 | + unset($wp_scripts->registered[$script_handle]->extra['after']); |
|
| 586 | 586 | } |
| 587 | 587 | if ($unset_handle) { |
| 588 | - unset($this->script_handles_with_data[ $script_handle ]); |
|
| 588 | + unset($this->script_handles_with_data[$script_handle]); |
|
| 589 | 589 | } |
| 590 | 590 | } |
| 591 | 591 | } |
@@ -468,7 +468,7 @@ discard block |
||
| 468 | 468 | * there's a single shared message template group among all the events. Otherwise it returns null. |
| 469 | 469 | * |
| 470 | 470 | * @param array $event_ids |
| 471 | - * @return EE_Message_Template_Group|null |
|
| 471 | + * @return null|EE_Base_Class |
|
| 472 | 472 | * @throws EE_Error |
| 473 | 473 | * @throws InvalidArgumentException |
| 474 | 474 | * @throws InvalidDataTypeException |
@@ -504,7 +504,7 @@ discard block |
||
| 504 | 504 | /** |
| 505 | 505 | * Retrieves the global message template group for the current messenger and message type. |
| 506 | 506 | * |
| 507 | - * @return EE_Message_Template_Group|null |
|
| 507 | + * @return null|EE_Base_Class |
|
| 508 | 508 | * @throws EE_Error |
| 509 | 509 | * @throws InvalidArgumentException |
| 510 | 510 | * @throws InvalidDataTypeException |
@@ -659,7 +659,7 @@ discard block |
||
| 659 | 659 | * @param EE_Messages_Addressee $recipient |
| 660 | 660 | * @param array $templates formatted array of templates used for parsing data. |
| 661 | 661 | * @param EE_Message_Template_Group $message_template_group |
| 662 | - * @return bool|EE_Message |
|
| 662 | + * @return EE_Message |
|
| 663 | 663 | * @throws EE_Error |
| 664 | 664 | * @throws InvalidArgumentException |
| 665 | 665 | * @throws InvalidDataTypeException |
@@ -17,997 +17,997 @@ |
||
| 17 | 17 | { |
| 18 | 18 | |
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * @type EE_Messages_Data_Handler_Collection |
|
| 22 | - */ |
|
| 23 | - protected $_data_handler_collection; |
|
| 24 | - |
|
| 25 | - /** |
|
| 26 | - * @type EE_Message_Template_Group_Collection |
|
| 27 | - */ |
|
| 28 | - protected $_template_collection; |
|
| 29 | - |
|
| 30 | - /** |
|
| 31 | - * This will hold the data handler for the current EE_Message being generated. |
|
| 32 | - * |
|
| 33 | - * @type EE_Messages_incoming_data |
|
| 34 | - */ |
|
| 35 | - protected $_current_data_handler; |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * This holds the EE_Messages_Queue that contains the messages to generate. |
|
| 39 | - * |
|
| 40 | - * @type EE_Messages_Queue |
|
| 41 | - */ |
|
| 42 | - protected $_generation_queue; |
|
| 43 | - |
|
| 44 | - /** |
|
| 45 | - * This holds the EE_Messages_Queue that will store the generated EE_Message objects. |
|
| 46 | - * |
|
| 47 | - * @type EE_Messages_Queue |
|
| 48 | - */ |
|
| 49 | - protected $_ready_queue; |
|
| 50 | - |
|
| 51 | - /** |
|
| 52 | - * This is a container for any error messages that get created through the generation |
|
| 53 | - * process. |
|
| 54 | - * |
|
| 55 | - * @type array |
|
| 56 | - */ |
|
| 57 | - protected $_error_msg = array(); |
|
| 58 | - |
|
| 59 | - /** |
|
| 60 | - * Flag used to set when the current EE_Message in the generation queue has been verified. |
|
| 61 | - * |
|
| 62 | - * @type bool |
|
| 63 | - */ |
|
| 64 | - protected $_verified = false; |
|
| 65 | - |
|
| 66 | - /** |
|
| 67 | - * This will hold the current messenger object corresponding with the current EE_Message in the generation queue. |
|
| 68 | - * |
|
| 69 | - * @type EE_messenger |
|
| 70 | - */ |
|
| 71 | - protected $_current_messenger; |
|
| 72 | - |
|
| 73 | - /** |
|
| 74 | - * This will hold the current message type object corresponding with the current EE_Message in the generation queue. |
|
| 75 | - * |
|
| 76 | - * @type EE_message_type |
|
| 77 | - */ |
|
| 78 | - protected $_current_message_type; |
|
| 79 | - |
|
| 80 | - /** |
|
| 81 | - * @type EEH_Parse_Shortcodes |
|
| 82 | - */ |
|
| 83 | - protected $_shortcode_parser; |
|
| 84 | - |
|
| 85 | - |
|
| 86 | - /** |
|
| 87 | - * @param EE_Messages_Queue $generation_queue |
|
| 88 | - * @param \EE_Messages_Queue $ready_queue |
|
| 89 | - * @param \EE_Messages_Data_Handler_Collection $data_handler_collection |
|
| 90 | - * @param \EE_Message_Template_Group_Collection $template_collection |
|
| 91 | - * @param \EEH_Parse_Shortcodes $shortcode_parser |
|
| 92 | - */ |
|
| 93 | - public function __construct( |
|
| 94 | - EE_Messages_Queue $generation_queue, |
|
| 95 | - EE_Messages_Queue $ready_queue, |
|
| 96 | - EE_Messages_Data_Handler_Collection $data_handler_collection, |
|
| 97 | - EE_Message_Template_Group_Collection $template_collection, |
|
| 98 | - EEH_Parse_Shortcodes $shortcode_parser |
|
| 99 | - ) { |
|
| 100 | - $this->_generation_queue = $generation_queue; |
|
| 101 | - $this->_ready_queue = $ready_queue; |
|
| 102 | - $this->_data_handler_collection = $data_handler_collection; |
|
| 103 | - $this->_template_collection = $template_collection; |
|
| 104 | - $this->_shortcode_parser = $shortcode_parser; |
|
| 105 | - } |
|
| 106 | - |
|
| 107 | - |
|
| 108 | - /** |
|
| 109 | - * @return EE_Messages_Queue |
|
| 110 | - */ |
|
| 111 | - public function generation_queue() |
|
| 112 | - { |
|
| 113 | - return $this->_generation_queue; |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - |
|
| 117 | - /** |
|
| 118 | - * This iterates through the provided queue and generates the EE_Message objects. |
|
| 119 | - * When iterating through the queue, the queued item that served as the base for generating other EE_Message |
|
| 120 | - * objects gets removed and the new EE_Message objects get added to a NEW queue. The NEW queue is then returned |
|
| 121 | - * for the caller to decide what to do with it. |
|
| 122 | - * |
|
| 123 | - * @param bool $save Whether to save the EE_Message objects in the new queue or just return. |
|
| 124 | - * @return EE_Messages_Queue The new queue for holding generated EE_Message objects. |
|
| 125 | - * @throws EE_Error |
|
| 126 | - * @throws InvalidArgumentException |
|
| 127 | - * @throws InvalidDataTypeException |
|
| 128 | - * @throws InvalidInterfaceException |
|
| 129 | - * @throws ReflectionException |
|
| 130 | - */ |
|
| 131 | - public function generate($save = true) |
|
| 132 | - { |
|
| 133 | - // iterate through the messages in the queue, generate, and add to new queue. |
|
| 134 | - $this->_generation_queue->get_message_repository()->rewind(); |
|
| 135 | - while ($this->_generation_queue->get_message_repository()->valid()) { |
|
| 136 | - // reset "current" properties |
|
| 137 | - $this->_reset_current_properties(); |
|
| 138 | - |
|
| 139 | - /** @type EE_Message $msg */ |
|
| 140 | - $msg = $this->_generation_queue->get_message_repository()->current(); |
|
| 141 | - |
|
| 142 | - /** |
|
| 143 | - * need to get the next object and capture it for setting manually after deletes. The reason is that when |
|
| 144 | - * an object is removed from the repo then valid for the next object will fail. |
|
| 145 | - */ |
|
| 146 | - $this->_generation_queue->get_message_repository()->next(); |
|
| 147 | - $next_msg = $this->_generation_queue->get_message_repository()->current(); |
|
| 148 | - // restore pointer to current item |
|
| 149 | - $this->_generation_queue->get_message_repository()->set_current($msg); |
|
| 150 | - |
|
| 151 | - // skip and delete if the current $msg is NOT incomplete (queued for generation) |
|
| 152 | - if ($msg->STS_ID() !== EEM_Message::status_incomplete) { |
|
| 153 | - // we keep this item in the db just remove from the repo. |
|
| 154 | - $this->_generation_queue->get_message_repository()->remove($msg); |
|
| 155 | - // next item |
|
| 156 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
| 157 | - continue; |
|
| 158 | - } |
|
| 159 | - |
|
| 160 | - if ($this->_verify()) { |
|
| 161 | - // let's get generating! |
|
| 162 | - $this->_generate(); |
|
| 163 | - } |
|
| 164 | - |
|
| 165 | - // don't persist debug_only messages if the messages system is not in debug mode. |
|
| 166 | - if ($msg->STS_ID() === EEM_Message::status_debug_only |
|
| 167 | - && ! EEM_Message::debug() |
|
| 168 | - ) { |
|
| 169 | - do_action( |
|
| 170 | - 'AHEE__EE_Messages_Generator__generate__before_debug_delete', |
|
| 171 | - $msg, |
|
| 172 | - $this->_error_msg, |
|
| 173 | - $this->_current_messenger, |
|
| 174 | - $this->_current_message_type, |
|
| 175 | - $this->_current_data_handler |
|
| 176 | - ); |
|
| 177 | - $this->_generation_queue->get_message_repository()->delete(); |
|
| 178 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
| 179 | - continue; |
|
| 180 | - } |
|
| 181 | - |
|
| 182 | - // if there are error messages then let's set the status and the error message. |
|
| 183 | - if ($this->_error_msg) { |
|
| 184 | - // if the status is already debug only, then let's leave it at that. |
|
| 185 | - if ($msg->STS_ID() !== EEM_Message::status_debug_only) { |
|
| 186 | - $msg->set_STS_ID(EEM_Message::status_failed); |
|
| 187 | - } |
|
| 188 | - do_action( |
|
| 189 | - 'AHEE__EE_Messages_Generator__generate__processing_failed_message', |
|
| 190 | - $msg, |
|
| 191 | - $this->_error_msg, |
|
| 192 | - $this->_current_messenger, |
|
| 193 | - $this->_current_message_type, |
|
| 194 | - $this->_current_data_handler |
|
| 195 | - ); |
|
| 196 | - $msg->set_error_message( |
|
| 197 | - esc_html__('Message failed to generate for the following reasons: ', 'event_espresso') |
|
| 198 | - . "\n" |
|
| 199 | - . implode("\n", $this->_error_msg) |
|
| 200 | - ); |
|
| 201 | - $msg->set_modified(time()); |
|
| 202 | - } else { |
|
| 203 | - do_action( |
|
| 204 | - 'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete', |
|
| 205 | - $msg, |
|
| 206 | - $this->_error_msg, |
|
| 207 | - $this->_current_messenger, |
|
| 208 | - $this->_current_message_type, |
|
| 209 | - $this->_current_data_handler |
|
| 210 | - ); |
|
| 211 | - // remove from db |
|
| 212 | - $this->_generation_queue->get_message_repository()->delete(); |
|
| 213 | - } |
|
| 214 | - // next item |
|
| 215 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
| 216 | - } |
|
| 217 | - |
|
| 218 | - // generation queue is ALWAYS saved to record any errors in the generation process. |
|
| 219 | - $this->_generation_queue->save(); |
|
| 220 | - |
|
| 221 | - /** |
|
| 222 | - * save _ready_queue if flag set. |
|
| 223 | - * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method. This |
|
| 224 | - * means if a field was added that is not a valid database column. The EE_Message was already saved to the db |
|
| 225 | - * so a EE_Extra_Meta entry could be created and attached to the EE_Message. In those cases the save flag is |
|
| 226 | - * irrelevant. |
|
| 227 | - */ |
|
| 228 | - if ($save) { |
|
| 229 | - $this->_ready_queue->save(); |
|
| 230 | - } |
|
| 231 | - |
|
| 232 | - // final reset of properties |
|
| 233 | - $this->_reset_current_properties(); |
|
| 234 | - |
|
| 235 | - return $this->_ready_queue; |
|
| 236 | - } |
|
| 237 | - |
|
| 238 | - |
|
| 239 | - /** |
|
| 240 | - * This resets all the properties used for holding "current" values corresponding to the current EE_Message object |
|
| 241 | - * in the generation queue. |
|
| 242 | - */ |
|
| 243 | - protected function _reset_current_properties() |
|
| 244 | - { |
|
| 245 | - $this->_verified = false; |
|
| 246 | - // make sure any _data value in the current message type is reset |
|
| 247 | - if ($this->_current_message_type instanceof EE_message_type) { |
|
| 248 | - $this->_current_message_type->reset_data(); |
|
| 249 | - } |
|
| 250 | - $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null; |
|
| 251 | - } |
|
| 252 | - |
|
| 253 | - |
|
| 254 | - /** |
|
| 255 | - * This proceeds with the actual generation of a message. By the time this is called, there should already be a |
|
| 256 | - * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the |
|
| 257 | - * _generating_queue. |
|
| 258 | - * |
|
| 259 | - * @return bool Whether the message was successfully generated or not. |
|
| 260 | - * @throws EE_Error |
|
| 261 | - * @throws InvalidArgumentException |
|
| 262 | - * @throws InvalidDataTypeException |
|
| 263 | - * @throws InvalidInterfaceException |
|
| 264 | - * @throws ReflectionException |
|
| 265 | - */ |
|
| 266 | - protected function _generate() |
|
| 267 | - { |
|
| 268 | - // double check verification has run and that everything is ready to work with (saves us having to validate |
|
| 269 | - // everything again). |
|
| 270 | - if (! $this->_verified) { |
|
| 271 | - return false; // get out because we don't have a valid setup to work with. |
|
| 272 | - } |
|
| 273 | - |
|
| 274 | - |
|
| 275 | - try { |
|
| 276 | - $addressees = $this->_current_message_type->get_addressees( |
|
| 277 | - $this->_current_data_handler, |
|
| 278 | - $this->_generation_queue->get_message_repository()->current()->context() |
|
| 279 | - ); |
|
| 280 | - } catch (EE_Error $e) { |
|
| 281 | - $this->_error_msg[] = $e->getMessage(); |
|
| 282 | - return false; |
|
| 283 | - } |
|
| 284 | - |
|
| 285 | - |
|
| 286 | - // if no addressees then get out because there is nothing to generation (possible bad data). |
|
| 287 | - if (! $this->_valid_addressees($addressees)) { |
|
| 288 | - do_action( |
|
| 289 | - 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
|
| 290 | - $this->_generation_queue->get_message_repository()->current(), |
|
| 291 | - $addressees, |
|
| 292 | - $this->_current_messenger, |
|
| 293 | - $this->_current_message_type, |
|
| 294 | - $this->_current_data_handler |
|
| 295 | - ); |
|
| 296 | - $this->_generation_queue->get_message_repository()->current()->set_STS_ID( |
|
| 297 | - EEM_Message::status_debug_only |
|
| 298 | - ); |
|
| 299 | - $this->_error_msg[] = esc_html__( |
|
| 300 | - 'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects. There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.', |
|
| 301 | - 'event_espresso' |
|
| 302 | - ); |
|
| 303 | - return false; |
|
| 304 | - } |
|
| 305 | - |
|
| 306 | - $message_template_group = $this->_get_message_template_group(); |
|
| 307 | - |
|
| 308 | - // in the unlikely event there is no EE_Message_Template_Group available, get out! |
|
| 309 | - if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
| 310 | - $this->_error_msg[] = esc_html__( |
|
| 311 | - 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
|
| 312 | - 'event_espresso' |
|
| 313 | - ); |
|
| 314 | - return false; |
|
| 315 | - } |
|
| 316 | - |
|
| 317 | - // get formatted templates for using to parse and setup EE_Message objects. |
|
| 318 | - $templates = $this->_get_templates($message_template_group); |
|
| 319 | - |
|
| 320 | - |
|
| 321 | - // setup new EE_Message objects (and add to _ready_queue) |
|
| 322 | - return $this->_assemble_messages($addressees, $templates, $message_template_group); |
|
| 323 | - } |
|
| 324 | - |
|
| 325 | - |
|
| 326 | - /** |
|
| 327 | - * Retrieves the message template group being used for generating messages. |
|
| 328 | - * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times. |
|
| 329 | - * |
|
| 330 | - * @return EE_Message_Template_Group|null |
|
| 331 | - * @throws EE_Error |
|
| 332 | - * @throws InvalidArgumentException |
|
| 333 | - * @throws InvalidDataTypeException |
|
| 334 | - * @throws InvalidInterfaceException |
|
| 335 | - * @throws ReflectionException |
|
| 336 | - */ |
|
| 337 | - protected function _get_message_template_group() |
|
| 338 | - { |
|
| 339 | - // first see if there is a specific message template group requested (current message in the queue has a |
|
| 340 | - // specific GRP_ID |
|
| 341 | - $message_template_group = $this->_specific_message_template_group_from_queue(); |
|
| 342 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 343 | - return $message_template_group; |
|
| 344 | - } |
|
| 345 | - |
|
| 346 | - // get event_ids from the datahandler so we can check to see if there's already a message template group for |
|
| 347 | - // them in the collection. |
|
| 348 | - $event_ids = $this->_get_event_ids_from_current_data_handler(); |
|
| 349 | - $message_template_group = $this->_template_collection->get_by_key( |
|
| 350 | - $this->_template_collection->getKey( |
|
| 351 | - $this->_current_messenger->name, |
|
| 352 | - $this->_current_message_type->name, |
|
| 353 | - $event_ids |
|
| 354 | - ) |
|
| 355 | - ); |
|
| 356 | - |
|
| 357 | - // if we have a message template group then no need to hit the database, just return it. |
|
| 358 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 359 | - return $message_template_group; |
|
| 360 | - } |
|
| 361 | - |
|
| 362 | - // okay made it here, so let's get the global group first for this messenger and message type to ensure |
|
| 363 | - // there is no override set. |
|
| 364 | - $global_message_template_group = |
|
| 365 | - $this->_get_global_message_template_group_for_current_messenger_and_message_type(); |
|
| 366 | - |
|
| 367 | - if ($global_message_template_group instanceof EE_Message_Template_Group |
|
| 368 | - && $global_message_template_group->get('MTP_is_override') |
|
| 369 | - ) { |
|
| 370 | - return $global_message_template_group; |
|
| 371 | - } |
|
| 372 | - |
|
| 373 | - // if we're still here, that means there was no message template group for the events in the collection and |
|
| 374 | - // the global message template group for the messenger and message type is not set for override. So next step |
|
| 375 | - // is to see if there is a common shared custom message template group for this set of events. |
|
| 376 | - $message_template_group = $this->_get_shared_message_template_for_events($event_ids); |
|
| 377 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 378 | - return $message_template_group; |
|
| 379 | - } |
|
| 380 | - |
|
| 381 | - // STILL here? Okay that means the fallback is to just use the global message template group for this event |
|
| 382 | - // set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this |
|
| 383 | - // request) and return it. |
|
| 384 | - if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 385 | - $this->_template_collection->add( |
|
| 386 | - $global_message_template_group, |
|
| 387 | - $event_ids |
|
| 388 | - ); |
|
| 389 | - return $global_message_template_group; |
|
| 390 | - } |
|
| 391 | - |
|
| 392 | - // if we land here that means there's NO active message template group for this set. |
|
| 393 | - // TODO this will be a good target for some optimization down the road. Whenever there is no active message |
|
| 394 | - // template group for a given event set then cache that result so we don't repeat the logic. However, for now, |
|
| 395 | - // this should likely bit hit rarely enough that it's not a significant issue. |
|
| 396 | - return null; |
|
| 397 | - } |
|
| 398 | - |
|
| 399 | - |
|
| 400 | - /** |
|
| 401 | - * This checks the current message in the queue and determines if there is a specific Message Template Group |
|
| 402 | - * requested for that message. |
|
| 403 | - * |
|
| 404 | - * @return EE_Message_Template_Group|null |
|
| 405 | - * @throws EE_Error |
|
| 406 | - * @throws InvalidArgumentException |
|
| 407 | - * @throws InvalidDataTypeException |
|
| 408 | - * @throws InvalidInterfaceException |
|
| 409 | - */ |
|
| 410 | - protected function _specific_message_template_group_from_queue() |
|
| 411 | - { |
|
| 412 | - // is there a GRP_ID already on the EE_Message object? If there is, then a specific template has been requested |
|
| 413 | - // so let's use that. |
|
| 414 | - $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID(); |
|
| 415 | - |
|
| 416 | - if ($GRP_ID) { |
|
| 417 | - // attempt to retrieve from repo first |
|
| 418 | - $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
|
| 419 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 420 | - return $message_template_group; // got it! |
|
| 421 | - } |
|
| 422 | - |
|
| 423 | - // nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
|
| 424 | - // is not valid, so we'll continue on in the code assuming there's NO GRP_ID. |
|
| 425 | - $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID); |
|
| 426 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 427 | - $this->_template_collection->add($message_template_group); |
|
| 428 | - return $message_template_group; |
|
| 429 | - } |
|
| 430 | - } |
|
| 431 | - return null; |
|
| 432 | - } |
|
| 433 | - |
|
| 434 | - |
|
| 435 | - /** |
|
| 436 | - * Returns whether the event ids passed in all share the same message template group for the current message type |
|
| 437 | - * and messenger. |
|
| 438 | - * |
|
| 439 | - * @param array $event_ids |
|
| 440 | - * @return bool true means they DO share the same message template group, false means they don't. |
|
| 441 | - * @throws EE_Error |
|
| 442 | - * @throws InvalidArgumentException |
|
| 443 | - * @throws InvalidDataTypeException |
|
| 444 | - * @throws InvalidInterfaceException |
|
| 445 | - */ |
|
| 446 | - protected function _queue_shares_same_message_template_group_for_events(array $event_ids) |
|
| 447 | - { |
|
| 448 | - foreach ($this->_current_data_handler->events as $event) { |
|
| 449 | - $event_ids[ $event['ID'] ] = $event['ID']; |
|
| 450 | - } |
|
| 451 | - $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count( |
|
| 452 | - array( |
|
| 453 | - array( |
|
| 454 | - 'Event.EVT_ID' => array('IN', $event_ids), |
|
| 455 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
| 456 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
| 457 | - ), |
|
| 458 | - ), |
|
| 459 | - 'GRP_ID', |
|
| 460 | - true |
|
| 461 | - ); |
|
| 462 | - return $count_of_message_template_groups === 1; |
|
| 463 | - } |
|
| 464 | - |
|
| 465 | - |
|
| 466 | - /** |
|
| 467 | - * This will get the shared message template group for events that are in the current data handler but ONLY if |
|
| 468 | - * there's a single shared message template group among all the events. Otherwise it returns null. |
|
| 469 | - * |
|
| 470 | - * @param array $event_ids |
|
| 471 | - * @return EE_Message_Template_Group|null |
|
| 472 | - * @throws EE_Error |
|
| 473 | - * @throws InvalidArgumentException |
|
| 474 | - * @throws InvalidDataTypeException |
|
| 475 | - * @throws InvalidInterfaceException |
|
| 476 | - */ |
|
| 477 | - protected function _get_shared_message_template_for_events(array $event_ids) |
|
| 478 | - { |
|
| 479 | - $message_template_group = null; |
|
| 480 | - if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) { |
|
| 481 | - $message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
| 482 | - array( |
|
| 483 | - array( |
|
| 484 | - 'Event.EVT_ID' => array('IN', $event_ids), |
|
| 485 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
| 486 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
| 487 | - 'MTP_is_active' => true, |
|
| 488 | - ), |
|
| 489 | - 'group_by' => 'GRP_ID', |
|
| 490 | - ) |
|
| 491 | - ); |
|
| 492 | - // store this in the collection if its valid |
|
| 493 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 494 | - $this->_template_collection->add( |
|
| 495 | - $message_template_group, |
|
| 496 | - $event_ids |
|
| 497 | - ); |
|
| 498 | - } |
|
| 499 | - } |
|
| 500 | - return $message_template_group; |
|
| 501 | - } |
|
| 502 | - |
|
| 503 | - |
|
| 504 | - /** |
|
| 505 | - * Retrieves the global message template group for the current messenger and message type. |
|
| 506 | - * |
|
| 507 | - * @return EE_Message_Template_Group|null |
|
| 508 | - * @throws EE_Error |
|
| 509 | - * @throws InvalidArgumentException |
|
| 510 | - * @throws InvalidDataTypeException |
|
| 511 | - * @throws InvalidInterfaceException |
|
| 512 | - */ |
|
| 513 | - protected function _get_global_message_template_group_for_current_messenger_and_message_type() |
|
| 514 | - { |
|
| 515 | - // first check the collection (we use an array with 0 in it to represent global groups). |
|
| 516 | - $global_message_template_group = $this->_template_collection->get_by_key( |
|
| 517 | - $this->_template_collection->getKey( |
|
| 518 | - $this->_current_messenger->name, |
|
| 519 | - $this->_current_message_type->name, |
|
| 520 | - array(0) |
|
| 521 | - ) |
|
| 522 | - ); |
|
| 523 | - |
|
| 524 | - // if we don't have a group lets hit the db. |
|
| 525 | - if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 526 | - $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
| 527 | - array( |
|
| 528 | - array( |
|
| 529 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
| 530 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
| 531 | - 'MTP_is_active' => true, |
|
| 532 | - 'MTP_is_global' => true, |
|
| 533 | - ), |
|
| 534 | - ) |
|
| 535 | - ); |
|
| 536 | - // if we have a group, add it to the collection. |
|
| 537 | - if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 538 | - $this->_template_collection->add( |
|
| 539 | - $global_message_template_group, |
|
| 540 | - array(0) |
|
| 541 | - ); |
|
| 542 | - } |
|
| 543 | - } |
|
| 544 | - return $global_message_template_group; |
|
| 545 | - } |
|
| 546 | - |
|
| 547 | - |
|
| 548 | - /** |
|
| 549 | - * Returns an array of event ids for all the events within the current data handler. |
|
| 550 | - * |
|
| 551 | - * @return array |
|
| 552 | - */ |
|
| 553 | - protected function _get_event_ids_from_current_data_handler() |
|
| 554 | - { |
|
| 555 | - $event_ids = array(); |
|
| 556 | - foreach ($this->_current_data_handler->events as $event) { |
|
| 557 | - $event_ids[ $event['ID'] ] = $event['ID']; |
|
| 558 | - } |
|
| 559 | - return $event_ids; |
|
| 560 | - } |
|
| 561 | - |
|
| 562 | - |
|
| 563 | - /** |
|
| 564 | - * Retrieves formatted array of template information for each context specific to the given |
|
| 565 | - * EE_Message_Template_Group |
|
| 566 | - * |
|
| 567 | - * @param EE_Message_Template_Group $message_template_group |
|
| 568 | - * @return array The returned array is in this structure: |
|
| 569 | - * array( |
|
| 570 | - * 'field_name' => array( |
|
| 571 | - * 'context' => 'content' |
|
| 572 | - * ) |
|
| 573 | - * ) |
|
| 574 | - * @throws EE_Error |
|
| 575 | - * @throws InvalidArgumentException |
|
| 576 | - * @throws InvalidDataTypeException |
|
| 577 | - * @throws InvalidInterfaceException |
|
| 578 | - * @throws ReflectionException |
|
| 579 | - */ |
|
| 580 | - protected function _get_templates(EE_Message_Template_Group $message_template_group) |
|
| 581 | - { |
|
| 582 | - $templates = array(); |
|
| 583 | - $context_templates = $message_template_group->context_templates(); |
|
| 584 | - foreach ($context_templates as $context => $template_fields) { |
|
| 585 | - foreach ($template_fields as $template_field => $template_obj) { |
|
| 586 | - if (! $template_obj instanceof EE_Message_Template) { |
|
| 587 | - continue; |
|
| 588 | - } |
|
| 589 | - $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content'); |
|
| 590 | - } |
|
| 591 | - } |
|
| 592 | - return $templates; |
|
| 593 | - } |
|
| 594 | - |
|
| 595 | - |
|
| 596 | - /** |
|
| 597 | - * Assembles new fully generated EE_Message objects and adds to _ready_queue |
|
| 598 | - * |
|
| 599 | - * @param array $addressees Array of EE_Messages_Addressee objects indexed by message type |
|
| 600 | - * context. |
|
| 601 | - * @param array $templates formatted array of templates used for parsing data. |
|
| 602 | - * @param EE_Message_Template_Group $message_template_group |
|
| 603 | - * @return bool true if message generation went a-ok. false if some sort of exception occurred. Note: The |
|
| 604 | - * method will attempt to generate ALL EE_Message objects and add to |
|
| 605 | - * the _ready_queue. Successfully generated messages get added to the |
|
| 606 | - * queue with EEM_Message::status_idle, unsuccessfully generated |
|
| 607 | - * messages will get added to the queue as EEM_Message::status_failed. |
|
| 608 | - * Very rarely should "false" be returned from this method. |
|
| 609 | - * @throws EE_Error |
|
| 610 | - * @throws InvalidArgumentException |
|
| 611 | - * @throws InvalidDataTypeException |
|
| 612 | - * @throws InvalidIdentifierException |
|
| 613 | - * @throws InvalidInterfaceException |
|
| 614 | - * @throws ReflectionException |
|
| 615 | - */ |
|
| 616 | - protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group) |
|
| 617 | - { |
|
| 618 | - |
|
| 619 | - // if templates are empty then get out because we can't generate anything. |
|
| 620 | - if (! $templates) { |
|
| 621 | - $this->_error_msg[] = esc_html__( |
|
| 622 | - 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
|
| 623 | - 'event_espresso' |
|
| 624 | - ); |
|
| 625 | - return false; |
|
| 626 | - } |
|
| 627 | - |
|
| 628 | - // We use this as the counter for generated messages because don't forget we may be executing this inside of a |
|
| 629 | - // generation_queue. So _ready_queue may have generated EE_Message objects already. |
|
| 630 | - $generated_count = 0; |
|
| 631 | - foreach ($addressees as $context => $recipients) { |
|
| 632 | - foreach ($recipients as $recipient) { |
|
| 633 | - $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group); |
|
| 634 | - if ($message instanceof EE_Message) { |
|
| 635 | - $this->_ready_queue->add( |
|
| 636 | - $message, |
|
| 637 | - array(), |
|
| 638 | - $this->_generation_queue->get_message_repository()->is_preview(), |
|
| 639 | - $this->_generation_queue->get_message_repository()->is_test_send() |
|
| 640 | - ); |
|
| 641 | - $generated_count++; |
|
| 642 | - } |
|
| 643 | - |
|
| 644 | - // if the current MSG being generated is for a test send then we'll only use ONE message in the |
|
| 645 | - // generation. |
|
| 646 | - if ($this->_generation_queue->get_message_repository()->is_test_send()) { |
|
| 647 | - break 2; |
|
| 648 | - } |
|
| 649 | - } |
|
| 650 | - } |
|
| 651 | - |
|
| 652 | - // if there are no generated messages then something else fatal went wrong. |
|
| 653 | - return $generated_count > 0; |
|
| 654 | - } |
|
| 655 | - |
|
| 656 | - |
|
| 657 | - /** |
|
| 658 | - * @param string $context The context for the generated message. |
|
| 659 | - * @param EE_Messages_Addressee $recipient |
|
| 660 | - * @param array $templates formatted array of templates used for parsing data. |
|
| 661 | - * @param EE_Message_Template_Group $message_template_group |
|
| 662 | - * @return bool|EE_Message |
|
| 663 | - * @throws EE_Error |
|
| 664 | - * @throws InvalidArgumentException |
|
| 665 | - * @throws InvalidDataTypeException |
|
| 666 | - * @throws InvalidInterfaceException |
|
| 667 | - * @throws ReflectionException |
|
| 668 | - * @throws InvalidIdentifierException |
|
| 669 | - */ |
|
| 670 | - protected function _setup_message_object( |
|
| 671 | - $context, |
|
| 672 | - EE_Messages_Addressee $recipient, |
|
| 673 | - $templates, |
|
| 674 | - EE_Message_Template_Group $message_template_group |
|
| 675 | - ) { |
|
| 676 | - // stuff we already know |
|
| 677 | - $transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0; |
|
| 678 | - $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction |
|
| 679 | - ? $this->_current_data_handler->txn->ID() |
|
| 680 | - : $transaction_id; |
|
| 681 | - $message_fields = array( |
|
| 682 | - 'GRP_ID' => $message_template_group->ID(), |
|
| 683 | - 'TXN_ID' => $transaction_id, |
|
| 684 | - 'MSG_messenger' => $this->_current_messenger->name, |
|
| 685 | - 'MSG_message_type' => $this->_current_message_type->name, |
|
| 686 | - 'MSG_context' => $context, |
|
| 687 | - ); |
|
| 688 | - |
|
| 689 | - // recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab |
|
| 690 | - // the info from the att_obj found in the EE_Messages_Addressee object. |
|
| 691 | - if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) { |
|
| 692 | - $message_fields['MSG_recipient_ID'] = $recipient->att_obj instanceof EE_Attendee |
|
| 693 | - ? $recipient->att_obj->ID() |
|
| 694 | - : 0; |
|
| 695 | - $message_fields['MSG_recipient_type'] = 'Attendee'; |
|
| 696 | - } else { |
|
| 697 | - $message_fields['MSG_recipient_ID'] = $recipient->recipient_id; |
|
| 698 | - $message_fields['MSG_recipient_type'] = $recipient->recipient_type; |
|
| 699 | - } |
|
| 700 | - $message = EE_Message_Factory::create($message_fields); |
|
| 701 | - |
|
| 702 | - // grab valid shortcodes for shortcode parser |
|
| 703 | - $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes(); |
|
| 704 | - $m_shortcodes = $this->_current_messenger->get_valid_shortcodes(); |
|
| 705 | - |
|
| 706 | - // if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing |
|
| 707 | - if (! $this->_generation_queue->get_message_repository()->is_preview() |
|
| 708 | - && ( |
|
| 709 | - ( |
|
| 710 | - empty($templates['to'][ $context ]) |
|
| 711 | - && ! $this->_current_messenger->allow_empty_to_field() |
|
| 712 | - ) |
|
| 713 | - || ! $message_template_group->is_context_active($context) |
|
| 714 | - ) |
|
| 715 | - ) { |
|
| 716 | - // we silently exit here and do NOT record a fail because the message is "turned off" by having no "to" |
|
| 717 | - // field. |
|
| 718 | - return false; |
|
| 719 | - } |
|
| 720 | - $error_msg = array(); |
|
| 721 | - foreach ($templates as $field => $field_context) { |
|
| 722 | - $error_msg = array(); |
|
| 723 | - // let's setup the valid shortcodes for the incoming context. |
|
| 724 | - $valid_shortcodes = $mt_shortcodes[ $context ]; |
|
| 725 | - // merge in valid shortcodes for the field. |
|
| 726 | - $shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes; |
|
| 727 | - if (isset($templates[ $field ][ $context ])) { |
|
| 728 | - // prefix field. |
|
| 729 | - $column_name = 'MSG_' . $field; |
|
| 730 | - try { |
|
| 731 | - $content = $this->_shortcode_parser->parse_message_template( |
|
| 732 | - $templates[ $field ][ $context ], |
|
| 733 | - $recipient, |
|
| 734 | - $shortcodes, |
|
| 735 | - $this->_current_message_type, |
|
| 736 | - $this->_current_messenger, |
|
| 737 | - $message |
|
| 738 | - ); |
|
| 739 | - // the model field removes slashes when setting (usually necessary when the input is from the |
|
| 740 | - // request) but this value is from another model and has no slashes. So add them so it matchces |
|
| 741 | - // what the field expected (otherwise slashes will have been stripped from this an extra time) |
|
| 742 | - $message->set_field_or_extra_meta($column_name, addslashes($content)); |
|
| 743 | - } catch (EE_Error $e) { |
|
| 744 | - $error_msg[] = sprintf( |
|
| 745 | - /* Translators: First place holder is message model field name. |
|
| 20 | + /** |
|
| 21 | + * @type EE_Messages_Data_Handler_Collection |
|
| 22 | + */ |
|
| 23 | + protected $_data_handler_collection; |
|
| 24 | + |
|
| 25 | + /** |
|
| 26 | + * @type EE_Message_Template_Group_Collection |
|
| 27 | + */ |
|
| 28 | + protected $_template_collection; |
|
| 29 | + |
|
| 30 | + /** |
|
| 31 | + * This will hold the data handler for the current EE_Message being generated. |
|
| 32 | + * |
|
| 33 | + * @type EE_Messages_incoming_data |
|
| 34 | + */ |
|
| 35 | + protected $_current_data_handler; |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * This holds the EE_Messages_Queue that contains the messages to generate. |
|
| 39 | + * |
|
| 40 | + * @type EE_Messages_Queue |
|
| 41 | + */ |
|
| 42 | + protected $_generation_queue; |
|
| 43 | + |
|
| 44 | + /** |
|
| 45 | + * This holds the EE_Messages_Queue that will store the generated EE_Message objects. |
|
| 46 | + * |
|
| 47 | + * @type EE_Messages_Queue |
|
| 48 | + */ |
|
| 49 | + protected $_ready_queue; |
|
| 50 | + |
|
| 51 | + /** |
|
| 52 | + * This is a container for any error messages that get created through the generation |
|
| 53 | + * process. |
|
| 54 | + * |
|
| 55 | + * @type array |
|
| 56 | + */ |
|
| 57 | + protected $_error_msg = array(); |
|
| 58 | + |
|
| 59 | + /** |
|
| 60 | + * Flag used to set when the current EE_Message in the generation queue has been verified. |
|
| 61 | + * |
|
| 62 | + * @type bool |
|
| 63 | + */ |
|
| 64 | + protected $_verified = false; |
|
| 65 | + |
|
| 66 | + /** |
|
| 67 | + * This will hold the current messenger object corresponding with the current EE_Message in the generation queue. |
|
| 68 | + * |
|
| 69 | + * @type EE_messenger |
|
| 70 | + */ |
|
| 71 | + protected $_current_messenger; |
|
| 72 | + |
|
| 73 | + /** |
|
| 74 | + * This will hold the current message type object corresponding with the current EE_Message in the generation queue. |
|
| 75 | + * |
|
| 76 | + * @type EE_message_type |
|
| 77 | + */ |
|
| 78 | + protected $_current_message_type; |
|
| 79 | + |
|
| 80 | + /** |
|
| 81 | + * @type EEH_Parse_Shortcodes |
|
| 82 | + */ |
|
| 83 | + protected $_shortcode_parser; |
|
| 84 | + |
|
| 85 | + |
|
| 86 | + /** |
|
| 87 | + * @param EE_Messages_Queue $generation_queue |
|
| 88 | + * @param \EE_Messages_Queue $ready_queue |
|
| 89 | + * @param \EE_Messages_Data_Handler_Collection $data_handler_collection |
|
| 90 | + * @param \EE_Message_Template_Group_Collection $template_collection |
|
| 91 | + * @param \EEH_Parse_Shortcodes $shortcode_parser |
|
| 92 | + */ |
|
| 93 | + public function __construct( |
|
| 94 | + EE_Messages_Queue $generation_queue, |
|
| 95 | + EE_Messages_Queue $ready_queue, |
|
| 96 | + EE_Messages_Data_Handler_Collection $data_handler_collection, |
|
| 97 | + EE_Message_Template_Group_Collection $template_collection, |
|
| 98 | + EEH_Parse_Shortcodes $shortcode_parser |
|
| 99 | + ) { |
|
| 100 | + $this->_generation_queue = $generation_queue; |
|
| 101 | + $this->_ready_queue = $ready_queue; |
|
| 102 | + $this->_data_handler_collection = $data_handler_collection; |
|
| 103 | + $this->_template_collection = $template_collection; |
|
| 104 | + $this->_shortcode_parser = $shortcode_parser; |
|
| 105 | + } |
|
| 106 | + |
|
| 107 | + |
|
| 108 | + /** |
|
| 109 | + * @return EE_Messages_Queue |
|
| 110 | + */ |
|
| 111 | + public function generation_queue() |
|
| 112 | + { |
|
| 113 | + return $this->_generation_queue; |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + |
|
| 117 | + /** |
|
| 118 | + * This iterates through the provided queue and generates the EE_Message objects. |
|
| 119 | + * When iterating through the queue, the queued item that served as the base for generating other EE_Message |
|
| 120 | + * objects gets removed and the new EE_Message objects get added to a NEW queue. The NEW queue is then returned |
|
| 121 | + * for the caller to decide what to do with it. |
|
| 122 | + * |
|
| 123 | + * @param bool $save Whether to save the EE_Message objects in the new queue or just return. |
|
| 124 | + * @return EE_Messages_Queue The new queue for holding generated EE_Message objects. |
|
| 125 | + * @throws EE_Error |
|
| 126 | + * @throws InvalidArgumentException |
|
| 127 | + * @throws InvalidDataTypeException |
|
| 128 | + * @throws InvalidInterfaceException |
|
| 129 | + * @throws ReflectionException |
|
| 130 | + */ |
|
| 131 | + public function generate($save = true) |
|
| 132 | + { |
|
| 133 | + // iterate through the messages in the queue, generate, and add to new queue. |
|
| 134 | + $this->_generation_queue->get_message_repository()->rewind(); |
|
| 135 | + while ($this->_generation_queue->get_message_repository()->valid()) { |
|
| 136 | + // reset "current" properties |
|
| 137 | + $this->_reset_current_properties(); |
|
| 138 | + |
|
| 139 | + /** @type EE_Message $msg */ |
|
| 140 | + $msg = $this->_generation_queue->get_message_repository()->current(); |
|
| 141 | + |
|
| 142 | + /** |
|
| 143 | + * need to get the next object and capture it for setting manually after deletes. The reason is that when |
|
| 144 | + * an object is removed from the repo then valid for the next object will fail. |
|
| 145 | + */ |
|
| 146 | + $this->_generation_queue->get_message_repository()->next(); |
|
| 147 | + $next_msg = $this->_generation_queue->get_message_repository()->current(); |
|
| 148 | + // restore pointer to current item |
|
| 149 | + $this->_generation_queue->get_message_repository()->set_current($msg); |
|
| 150 | + |
|
| 151 | + // skip and delete if the current $msg is NOT incomplete (queued for generation) |
|
| 152 | + if ($msg->STS_ID() !== EEM_Message::status_incomplete) { |
|
| 153 | + // we keep this item in the db just remove from the repo. |
|
| 154 | + $this->_generation_queue->get_message_repository()->remove($msg); |
|
| 155 | + // next item |
|
| 156 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
| 157 | + continue; |
|
| 158 | + } |
|
| 159 | + |
|
| 160 | + if ($this->_verify()) { |
|
| 161 | + // let's get generating! |
|
| 162 | + $this->_generate(); |
|
| 163 | + } |
|
| 164 | + |
|
| 165 | + // don't persist debug_only messages if the messages system is not in debug mode. |
|
| 166 | + if ($msg->STS_ID() === EEM_Message::status_debug_only |
|
| 167 | + && ! EEM_Message::debug() |
|
| 168 | + ) { |
|
| 169 | + do_action( |
|
| 170 | + 'AHEE__EE_Messages_Generator__generate__before_debug_delete', |
|
| 171 | + $msg, |
|
| 172 | + $this->_error_msg, |
|
| 173 | + $this->_current_messenger, |
|
| 174 | + $this->_current_message_type, |
|
| 175 | + $this->_current_data_handler |
|
| 176 | + ); |
|
| 177 | + $this->_generation_queue->get_message_repository()->delete(); |
|
| 178 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
| 179 | + continue; |
|
| 180 | + } |
|
| 181 | + |
|
| 182 | + // if there are error messages then let's set the status and the error message. |
|
| 183 | + if ($this->_error_msg) { |
|
| 184 | + // if the status is already debug only, then let's leave it at that. |
|
| 185 | + if ($msg->STS_ID() !== EEM_Message::status_debug_only) { |
|
| 186 | + $msg->set_STS_ID(EEM_Message::status_failed); |
|
| 187 | + } |
|
| 188 | + do_action( |
|
| 189 | + 'AHEE__EE_Messages_Generator__generate__processing_failed_message', |
|
| 190 | + $msg, |
|
| 191 | + $this->_error_msg, |
|
| 192 | + $this->_current_messenger, |
|
| 193 | + $this->_current_message_type, |
|
| 194 | + $this->_current_data_handler |
|
| 195 | + ); |
|
| 196 | + $msg->set_error_message( |
|
| 197 | + esc_html__('Message failed to generate for the following reasons: ', 'event_espresso') |
|
| 198 | + . "\n" |
|
| 199 | + . implode("\n", $this->_error_msg) |
|
| 200 | + ); |
|
| 201 | + $msg->set_modified(time()); |
|
| 202 | + } else { |
|
| 203 | + do_action( |
|
| 204 | + 'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete', |
|
| 205 | + $msg, |
|
| 206 | + $this->_error_msg, |
|
| 207 | + $this->_current_messenger, |
|
| 208 | + $this->_current_message_type, |
|
| 209 | + $this->_current_data_handler |
|
| 210 | + ); |
|
| 211 | + // remove from db |
|
| 212 | + $this->_generation_queue->get_message_repository()->delete(); |
|
| 213 | + } |
|
| 214 | + // next item |
|
| 215 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
| 216 | + } |
|
| 217 | + |
|
| 218 | + // generation queue is ALWAYS saved to record any errors in the generation process. |
|
| 219 | + $this->_generation_queue->save(); |
|
| 220 | + |
|
| 221 | + /** |
|
| 222 | + * save _ready_queue if flag set. |
|
| 223 | + * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method. This |
|
| 224 | + * means if a field was added that is not a valid database column. The EE_Message was already saved to the db |
|
| 225 | + * so a EE_Extra_Meta entry could be created and attached to the EE_Message. In those cases the save flag is |
|
| 226 | + * irrelevant. |
|
| 227 | + */ |
|
| 228 | + if ($save) { |
|
| 229 | + $this->_ready_queue->save(); |
|
| 230 | + } |
|
| 231 | + |
|
| 232 | + // final reset of properties |
|
| 233 | + $this->_reset_current_properties(); |
|
| 234 | + |
|
| 235 | + return $this->_ready_queue; |
|
| 236 | + } |
|
| 237 | + |
|
| 238 | + |
|
| 239 | + /** |
|
| 240 | + * This resets all the properties used for holding "current" values corresponding to the current EE_Message object |
|
| 241 | + * in the generation queue. |
|
| 242 | + */ |
|
| 243 | + protected function _reset_current_properties() |
|
| 244 | + { |
|
| 245 | + $this->_verified = false; |
|
| 246 | + // make sure any _data value in the current message type is reset |
|
| 247 | + if ($this->_current_message_type instanceof EE_message_type) { |
|
| 248 | + $this->_current_message_type->reset_data(); |
|
| 249 | + } |
|
| 250 | + $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null; |
|
| 251 | + } |
|
| 252 | + |
|
| 253 | + |
|
| 254 | + /** |
|
| 255 | + * This proceeds with the actual generation of a message. By the time this is called, there should already be a |
|
| 256 | + * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the |
|
| 257 | + * _generating_queue. |
|
| 258 | + * |
|
| 259 | + * @return bool Whether the message was successfully generated or not. |
|
| 260 | + * @throws EE_Error |
|
| 261 | + * @throws InvalidArgumentException |
|
| 262 | + * @throws InvalidDataTypeException |
|
| 263 | + * @throws InvalidInterfaceException |
|
| 264 | + * @throws ReflectionException |
|
| 265 | + */ |
|
| 266 | + protected function _generate() |
|
| 267 | + { |
|
| 268 | + // double check verification has run and that everything is ready to work with (saves us having to validate |
|
| 269 | + // everything again). |
|
| 270 | + if (! $this->_verified) { |
|
| 271 | + return false; // get out because we don't have a valid setup to work with. |
|
| 272 | + } |
|
| 273 | + |
|
| 274 | + |
|
| 275 | + try { |
|
| 276 | + $addressees = $this->_current_message_type->get_addressees( |
|
| 277 | + $this->_current_data_handler, |
|
| 278 | + $this->_generation_queue->get_message_repository()->current()->context() |
|
| 279 | + ); |
|
| 280 | + } catch (EE_Error $e) { |
|
| 281 | + $this->_error_msg[] = $e->getMessage(); |
|
| 282 | + return false; |
|
| 283 | + } |
|
| 284 | + |
|
| 285 | + |
|
| 286 | + // if no addressees then get out because there is nothing to generation (possible bad data). |
|
| 287 | + if (! $this->_valid_addressees($addressees)) { |
|
| 288 | + do_action( |
|
| 289 | + 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
|
| 290 | + $this->_generation_queue->get_message_repository()->current(), |
|
| 291 | + $addressees, |
|
| 292 | + $this->_current_messenger, |
|
| 293 | + $this->_current_message_type, |
|
| 294 | + $this->_current_data_handler |
|
| 295 | + ); |
|
| 296 | + $this->_generation_queue->get_message_repository()->current()->set_STS_ID( |
|
| 297 | + EEM_Message::status_debug_only |
|
| 298 | + ); |
|
| 299 | + $this->_error_msg[] = esc_html__( |
|
| 300 | + 'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects. There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.', |
|
| 301 | + 'event_espresso' |
|
| 302 | + ); |
|
| 303 | + return false; |
|
| 304 | + } |
|
| 305 | + |
|
| 306 | + $message_template_group = $this->_get_message_template_group(); |
|
| 307 | + |
|
| 308 | + // in the unlikely event there is no EE_Message_Template_Group available, get out! |
|
| 309 | + if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
| 310 | + $this->_error_msg[] = esc_html__( |
|
| 311 | + 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
|
| 312 | + 'event_espresso' |
|
| 313 | + ); |
|
| 314 | + return false; |
|
| 315 | + } |
|
| 316 | + |
|
| 317 | + // get formatted templates for using to parse and setup EE_Message objects. |
|
| 318 | + $templates = $this->_get_templates($message_template_group); |
|
| 319 | + |
|
| 320 | + |
|
| 321 | + // setup new EE_Message objects (and add to _ready_queue) |
|
| 322 | + return $this->_assemble_messages($addressees, $templates, $message_template_group); |
|
| 323 | + } |
|
| 324 | + |
|
| 325 | + |
|
| 326 | + /** |
|
| 327 | + * Retrieves the message template group being used for generating messages. |
|
| 328 | + * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times. |
|
| 329 | + * |
|
| 330 | + * @return EE_Message_Template_Group|null |
|
| 331 | + * @throws EE_Error |
|
| 332 | + * @throws InvalidArgumentException |
|
| 333 | + * @throws InvalidDataTypeException |
|
| 334 | + * @throws InvalidInterfaceException |
|
| 335 | + * @throws ReflectionException |
|
| 336 | + */ |
|
| 337 | + protected function _get_message_template_group() |
|
| 338 | + { |
|
| 339 | + // first see if there is a specific message template group requested (current message in the queue has a |
|
| 340 | + // specific GRP_ID |
|
| 341 | + $message_template_group = $this->_specific_message_template_group_from_queue(); |
|
| 342 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 343 | + return $message_template_group; |
|
| 344 | + } |
|
| 345 | + |
|
| 346 | + // get event_ids from the datahandler so we can check to see if there's already a message template group for |
|
| 347 | + // them in the collection. |
|
| 348 | + $event_ids = $this->_get_event_ids_from_current_data_handler(); |
|
| 349 | + $message_template_group = $this->_template_collection->get_by_key( |
|
| 350 | + $this->_template_collection->getKey( |
|
| 351 | + $this->_current_messenger->name, |
|
| 352 | + $this->_current_message_type->name, |
|
| 353 | + $event_ids |
|
| 354 | + ) |
|
| 355 | + ); |
|
| 356 | + |
|
| 357 | + // if we have a message template group then no need to hit the database, just return it. |
|
| 358 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 359 | + return $message_template_group; |
|
| 360 | + } |
|
| 361 | + |
|
| 362 | + // okay made it here, so let's get the global group first for this messenger and message type to ensure |
|
| 363 | + // there is no override set. |
|
| 364 | + $global_message_template_group = |
|
| 365 | + $this->_get_global_message_template_group_for_current_messenger_and_message_type(); |
|
| 366 | + |
|
| 367 | + if ($global_message_template_group instanceof EE_Message_Template_Group |
|
| 368 | + && $global_message_template_group->get('MTP_is_override') |
|
| 369 | + ) { |
|
| 370 | + return $global_message_template_group; |
|
| 371 | + } |
|
| 372 | + |
|
| 373 | + // if we're still here, that means there was no message template group for the events in the collection and |
|
| 374 | + // the global message template group for the messenger and message type is not set for override. So next step |
|
| 375 | + // is to see if there is a common shared custom message template group for this set of events. |
|
| 376 | + $message_template_group = $this->_get_shared_message_template_for_events($event_ids); |
|
| 377 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 378 | + return $message_template_group; |
|
| 379 | + } |
|
| 380 | + |
|
| 381 | + // STILL here? Okay that means the fallback is to just use the global message template group for this event |
|
| 382 | + // set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this |
|
| 383 | + // request) and return it. |
|
| 384 | + if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 385 | + $this->_template_collection->add( |
|
| 386 | + $global_message_template_group, |
|
| 387 | + $event_ids |
|
| 388 | + ); |
|
| 389 | + return $global_message_template_group; |
|
| 390 | + } |
|
| 391 | + |
|
| 392 | + // if we land here that means there's NO active message template group for this set. |
|
| 393 | + // TODO this will be a good target for some optimization down the road. Whenever there is no active message |
|
| 394 | + // template group for a given event set then cache that result so we don't repeat the logic. However, for now, |
|
| 395 | + // this should likely bit hit rarely enough that it's not a significant issue. |
|
| 396 | + return null; |
|
| 397 | + } |
|
| 398 | + |
|
| 399 | + |
|
| 400 | + /** |
|
| 401 | + * This checks the current message in the queue and determines if there is a specific Message Template Group |
|
| 402 | + * requested for that message. |
|
| 403 | + * |
|
| 404 | + * @return EE_Message_Template_Group|null |
|
| 405 | + * @throws EE_Error |
|
| 406 | + * @throws InvalidArgumentException |
|
| 407 | + * @throws InvalidDataTypeException |
|
| 408 | + * @throws InvalidInterfaceException |
|
| 409 | + */ |
|
| 410 | + protected function _specific_message_template_group_from_queue() |
|
| 411 | + { |
|
| 412 | + // is there a GRP_ID already on the EE_Message object? If there is, then a specific template has been requested |
|
| 413 | + // so let's use that. |
|
| 414 | + $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID(); |
|
| 415 | + |
|
| 416 | + if ($GRP_ID) { |
|
| 417 | + // attempt to retrieve from repo first |
|
| 418 | + $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
|
| 419 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 420 | + return $message_template_group; // got it! |
|
| 421 | + } |
|
| 422 | + |
|
| 423 | + // nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
|
| 424 | + // is not valid, so we'll continue on in the code assuming there's NO GRP_ID. |
|
| 425 | + $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID); |
|
| 426 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 427 | + $this->_template_collection->add($message_template_group); |
|
| 428 | + return $message_template_group; |
|
| 429 | + } |
|
| 430 | + } |
|
| 431 | + return null; |
|
| 432 | + } |
|
| 433 | + |
|
| 434 | + |
|
| 435 | + /** |
|
| 436 | + * Returns whether the event ids passed in all share the same message template group for the current message type |
|
| 437 | + * and messenger. |
|
| 438 | + * |
|
| 439 | + * @param array $event_ids |
|
| 440 | + * @return bool true means they DO share the same message template group, false means they don't. |
|
| 441 | + * @throws EE_Error |
|
| 442 | + * @throws InvalidArgumentException |
|
| 443 | + * @throws InvalidDataTypeException |
|
| 444 | + * @throws InvalidInterfaceException |
|
| 445 | + */ |
|
| 446 | + protected function _queue_shares_same_message_template_group_for_events(array $event_ids) |
|
| 447 | + { |
|
| 448 | + foreach ($this->_current_data_handler->events as $event) { |
|
| 449 | + $event_ids[ $event['ID'] ] = $event['ID']; |
|
| 450 | + } |
|
| 451 | + $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count( |
|
| 452 | + array( |
|
| 453 | + array( |
|
| 454 | + 'Event.EVT_ID' => array('IN', $event_ids), |
|
| 455 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
| 456 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
| 457 | + ), |
|
| 458 | + ), |
|
| 459 | + 'GRP_ID', |
|
| 460 | + true |
|
| 461 | + ); |
|
| 462 | + return $count_of_message_template_groups === 1; |
|
| 463 | + } |
|
| 464 | + |
|
| 465 | + |
|
| 466 | + /** |
|
| 467 | + * This will get the shared message template group for events that are in the current data handler but ONLY if |
|
| 468 | + * there's a single shared message template group among all the events. Otherwise it returns null. |
|
| 469 | + * |
|
| 470 | + * @param array $event_ids |
|
| 471 | + * @return EE_Message_Template_Group|null |
|
| 472 | + * @throws EE_Error |
|
| 473 | + * @throws InvalidArgumentException |
|
| 474 | + * @throws InvalidDataTypeException |
|
| 475 | + * @throws InvalidInterfaceException |
|
| 476 | + */ |
|
| 477 | + protected function _get_shared_message_template_for_events(array $event_ids) |
|
| 478 | + { |
|
| 479 | + $message_template_group = null; |
|
| 480 | + if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) { |
|
| 481 | + $message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
| 482 | + array( |
|
| 483 | + array( |
|
| 484 | + 'Event.EVT_ID' => array('IN', $event_ids), |
|
| 485 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
| 486 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
| 487 | + 'MTP_is_active' => true, |
|
| 488 | + ), |
|
| 489 | + 'group_by' => 'GRP_ID', |
|
| 490 | + ) |
|
| 491 | + ); |
|
| 492 | + // store this in the collection if its valid |
|
| 493 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
| 494 | + $this->_template_collection->add( |
|
| 495 | + $message_template_group, |
|
| 496 | + $event_ids |
|
| 497 | + ); |
|
| 498 | + } |
|
| 499 | + } |
|
| 500 | + return $message_template_group; |
|
| 501 | + } |
|
| 502 | + |
|
| 503 | + |
|
| 504 | + /** |
|
| 505 | + * Retrieves the global message template group for the current messenger and message type. |
|
| 506 | + * |
|
| 507 | + * @return EE_Message_Template_Group|null |
|
| 508 | + * @throws EE_Error |
|
| 509 | + * @throws InvalidArgumentException |
|
| 510 | + * @throws InvalidDataTypeException |
|
| 511 | + * @throws InvalidInterfaceException |
|
| 512 | + */ |
|
| 513 | + protected function _get_global_message_template_group_for_current_messenger_and_message_type() |
|
| 514 | + { |
|
| 515 | + // first check the collection (we use an array with 0 in it to represent global groups). |
|
| 516 | + $global_message_template_group = $this->_template_collection->get_by_key( |
|
| 517 | + $this->_template_collection->getKey( |
|
| 518 | + $this->_current_messenger->name, |
|
| 519 | + $this->_current_message_type->name, |
|
| 520 | + array(0) |
|
| 521 | + ) |
|
| 522 | + ); |
|
| 523 | + |
|
| 524 | + // if we don't have a group lets hit the db. |
|
| 525 | + if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 526 | + $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
| 527 | + array( |
|
| 528 | + array( |
|
| 529 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
| 530 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
| 531 | + 'MTP_is_active' => true, |
|
| 532 | + 'MTP_is_global' => true, |
|
| 533 | + ), |
|
| 534 | + ) |
|
| 535 | + ); |
|
| 536 | + // if we have a group, add it to the collection. |
|
| 537 | + if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 538 | + $this->_template_collection->add( |
|
| 539 | + $global_message_template_group, |
|
| 540 | + array(0) |
|
| 541 | + ); |
|
| 542 | + } |
|
| 543 | + } |
|
| 544 | + return $global_message_template_group; |
|
| 545 | + } |
|
| 546 | + |
|
| 547 | + |
|
| 548 | + /** |
|
| 549 | + * Returns an array of event ids for all the events within the current data handler. |
|
| 550 | + * |
|
| 551 | + * @return array |
|
| 552 | + */ |
|
| 553 | + protected function _get_event_ids_from_current_data_handler() |
|
| 554 | + { |
|
| 555 | + $event_ids = array(); |
|
| 556 | + foreach ($this->_current_data_handler->events as $event) { |
|
| 557 | + $event_ids[ $event['ID'] ] = $event['ID']; |
|
| 558 | + } |
|
| 559 | + return $event_ids; |
|
| 560 | + } |
|
| 561 | + |
|
| 562 | + |
|
| 563 | + /** |
|
| 564 | + * Retrieves formatted array of template information for each context specific to the given |
|
| 565 | + * EE_Message_Template_Group |
|
| 566 | + * |
|
| 567 | + * @param EE_Message_Template_Group $message_template_group |
|
| 568 | + * @return array The returned array is in this structure: |
|
| 569 | + * array( |
|
| 570 | + * 'field_name' => array( |
|
| 571 | + * 'context' => 'content' |
|
| 572 | + * ) |
|
| 573 | + * ) |
|
| 574 | + * @throws EE_Error |
|
| 575 | + * @throws InvalidArgumentException |
|
| 576 | + * @throws InvalidDataTypeException |
|
| 577 | + * @throws InvalidInterfaceException |
|
| 578 | + * @throws ReflectionException |
|
| 579 | + */ |
|
| 580 | + protected function _get_templates(EE_Message_Template_Group $message_template_group) |
|
| 581 | + { |
|
| 582 | + $templates = array(); |
|
| 583 | + $context_templates = $message_template_group->context_templates(); |
|
| 584 | + foreach ($context_templates as $context => $template_fields) { |
|
| 585 | + foreach ($template_fields as $template_field => $template_obj) { |
|
| 586 | + if (! $template_obj instanceof EE_Message_Template) { |
|
| 587 | + continue; |
|
| 588 | + } |
|
| 589 | + $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content'); |
|
| 590 | + } |
|
| 591 | + } |
|
| 592 | + return $templates; |
|
| 593 | + } |
|
| 594 | + |
|
| 595 | + |
|
| 596 | + /** |
|
| 597 | + * Assembles new fully generated EE_Message objects and adds to _ready_queue |
|
| 598 | + * |
|
| 599 | + * @param array $addressees Array of EE_Messages_Addressee objects indexed by message type |
|
| 600 | + * context. |
|
| 601 | + * @param array $templates formatted array of templates used for parsing data. |
|
| 602 | + * @param EE_Message_Template_Group $message_template_group |
|
| 603 | + * @return bool true if message generation went a-ok. false if some sort of exception occurred. Note: The |
|
| 604 | + * method will attempt to generate ALL EE_Message objects and add to |
|
| 605 | + * the _ready_queue. Successfully generated messages get added to the |
|
| 606 | + * queue with EEM_Message::status_idle, unsuccessfully generated |
|
| 607 | + * messages will get added to the queue as EEM_Message::status_failed. |
|
| 608 | + * Very rarely should "false" be returned from this method. |
|
| 609 | + * @throws EE_Error |
|
| 610 | + * @throws InvalidArgumentException |
|
| 611 | + * @throws InvalidDataTypeException |
|
| 612 | + * @throws InvalidIdentifierException |
|
| 613 | + * @throws InvalidInterfaceException |
|
| 614 | + * @throws ReflectionException |
|
| 615 | + */ |
|
| 616 | + protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group) |
|
| 617 | + { |
|
| 618 | + |
|
| 619 | + // if templates are empty then get out because we can't generate anything. |
|
| 620 | + if (! $templates) { |
|
| 621 | + $this->_error_msg[] = esc_html__( |
|
| 622 | + 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
|
| 623 | + 'event_espresso' |
|
| 624 | + ); |
|
| 625 | + return false; |
|
| 626 | + } |
|
| 627 | + |
|
| 628 | + // We use this as the counter for generated messages because don't forget we may be executing this inside of a |
|
| 629 | + // generation_queue. So _ready_queue may have generated EE_Message objects already. |
|
| 630 | + $generated_count = 0; |
|
| 631 | + foreach ($addressees as $context => $recipients) { |
|
| 632 | + foreach ($recipients as $recipient) { |
|
| 633 | + $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group); |
|
| 634 | + if ($message instanceof EE_Message) { |
|
| 635 | + $this->_ready_queue->add( |
|
| 636 | + $message, |
|
| 637 | + array(), |
|
| 638 | + $this->_generation_queue->get_message_repository()->is_preview(), |
|
| 639 | + $this->_generation_queue->get_message_repository()->is_test_send() |
|
| 640 | + ); |
|
| 641 | + $generated_count++; |
|
| 642 | + } |
|
| 643 | + |
|
| 644 | + // if the current MSG being generated is for a test send then we'll only use ONE message in the |
|
| 645 | + // generation. |
|
| 646 | + if ($this->_generation_queue->get_message_repository()->is_test_send()) { |
|
| 647 | + break 2; |
|
| 648 | + } |
|
| 649 | + } |
|
| 650 | + } |
|
| 651 | + |
|
| 652 | + // if there are no generated messages then something else fatal went wrong. |
|
| 653 | + return $generated_count > 0; |
|
| 654 | + } |
|
| 655 | + |
|
| 656 | + |
|
| 657 | + /** |
|
| 658 | + * @param string $context The context for the generated message. |
|
| 659 | + * @param EE_Messages_Addressee $recipient |
|
| 660 | + * @param array $templates formatted array of templates used for parsing data. |
|
| 661 | + * @param EE_Message_Template_Group $message_template_group |
|
| 662 | + * @return bool|EE_Message |
|
| 663 | + * @throws EE_Error |
|
| 664 | + * @throws InvalidArgumentException |
|
| 665 | + * @throws InvalidDataTypeException |
|
| 666 | + * @throws InvalidInterfaceException |
|
| 667 | + * @throws ReflectionException |
|
| 668 | + * @throws InvalidIdentifierException |
|
| 669 | + */ |
|
| 670 | + protected function _setup_message_object( |
|
| 671 | + $context, |
|
| 672 | + EE_Messages_Addressee $recipient, |
|
| 673 | + $templates, |
|
| 674 | + EE_Message_Template_Group $message_template_group |
|
| 675 | + ) { |
|
| 676 | + // stuff we already know |
|
| 677 | + $transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0; |
|
| 678 | + $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction |
|
| 679 | + ? $this->_current_data_handler->txn->ID() |
|
| 680 | + : $transaction_id; |
|
| 681 | + $message_fields = array( |
|
| 682 | + 'GRP_ID' => $message_template_group->ID(), |
|
| 683 | + 'TXN_ID' => $transaction_id, |
|
| 684 | + 'MSG_messenger' => $this->_current_messenger->name, |
|
| 685 | + 'MSG_message_type' => $this->_current_message_type->name, |
|
| 686 | + 'MSG_context' => $context, |
|
| 687 | + ); |
|
| 688 | + |
|
| 689 | + // recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab |
|
| 690 | + // the info from the att_obj found in the EE_Messages_Addressee object. |
|
| 691 | + if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) { |
|
| 692 | + $message_fields['MSG_recipient_ID'] = $recipient->att_obj instanceof EE_Attendee |
|
| 693 | + ? $recipient->att_obj->ID() |
|
| 694 | + : 0; |
|
| 695 | + $message_fields['MSG_recipient_type'] = 'Attendee'; |
|
| 696 | + } else { |
|
| 697 | + $message_fields['MSG_recipient_ID'] = $recipient->recipient_id; |
|
| 698 | + $message_fields['MSG_recipient_type'] = $recipient->recipient_type; |
|
| 699 | + } |
|
| 700 | + $message = EE_Message_Factory::create($message_fields); |
|
| 701 | + |
|
| 702 | + // grab valid shortcodes for shortcode parser |
|
| 703 | + $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes(); |
|
| 704 | + $m_shortcodes = $this->_current_messenger->get_valid_shortcodes(); |
|
| 705 | + |
|
| 706 | + // if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing |
|
| 707 | + if (! $this->_generation_queue->get_message_repository()->is_preview() |
|
| 708 | + && ( |
|
| 709 | + ( |
|
| 710 | + empty($templates['to'][ $context ]) |
|
| 711 | + && ! $this->_current_messenger->allow_empty_to_field() |
|
| 712 | + ) |
|
| 713 | + || ! $message_template_group->is_context_active($context) |
|
| 714 | + ) |
|
| 715 | + ) { |
|
| 716 | + // we silently exit here and do NOT record a fail because the message is "turned off" by having no "to" |
|
| 717 | + // field. |
|
| 718 | + return false; |
|
| 719 | + } |
|
| 720 | + $error_msg = array(); |
|
| 721 | + foreach ($templates as $field => $field_context) { |
|
| 722 | + $error_msg = array(); |
|
| 723 | + // let's setup the valid shortcodes for the incoming context. |
|
| 724 | + $valid_shortcodes = $mt_shortcodes[ $context ]; |
|
| 725 | + // merge in valid shortcodes for the field. |
|
| 726 | + $shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes; |
|
| 727 | + if (isset($templates[ $field ][ $context ])) { |
|
| 728 | + // prefix field. |
|
| 729 | + $column_name = 'MSG_' . $field; |
|
| 730 | + try { |
|
| 731 | + $content = $this->_shortcode_parser->parse_message_template( |
|
| 732 | + $templates[ $field ][ $context ], |
|
| 733 | + $recipient, |
|
| 734 | + $shortcodes, |
|
| 735 | + $this->_current_message_type, |
|
| 736 | + $this->_current_messenger, |
|
| 737 | + $message |
|
| 738 | + ); |
|
| 739 | + // the model field removes slashes when setting (usually necessary when the input is from the |
|
| 740 | + // request) but this value is from another model and has no slashes. So add them so it matchces |
|
| 741 | + // what the field expected (otherwise slashes will have been stripped from this an extra time) |
|
| 742 | + $message->set_field_or_extra_meta($column_name, addslashes($content)); |
|
| 743 | + } catch (EE_Error $e) { |
|
| 744 | + $error_msg[] = sprintf( |
|
| 745 | + /* Translators: First place holder is message model field name. |
|
| 746 | 746 | * Second placeholder is exception error message */ |
| 747 | - esc_html__( |
|
| 748 | - 'There was a problem generating the content for the field %s: %s', |
|
| 749 | - 'event_espresso' |
|
| 750 | - ), |
|
| 751 | - $field, |
|
| 752 | - $e->getMessage() |
|
| 753 | - ); |
|
| 754 | - $message->set_STS_ID(EEM_Message::status_failed); |
|
| 755 | - } |
|
| 756 | - } |
|
| 757 | - } |
|
| 758 | - |
|
| 759 | - if ($message->STS_ID() === EEM_Message::status_failed) { |
|
| 760 | - $error_msg = esc_html__('There were problems generating this message:', 'event_espresso') |
|
| 761 | - . "\n" |
|
| 762 | - . implode("\n", $error_msg); |
|
| 763 | - $message->set_error_message($error_msg); |
|
| 764 | - } else { |
|
| 765 | - $message->set_STS_ID(EEM_Message::status_idle); |
|
| 766 | - } |
|
| 767 | - return $message; |
|
| 768 | - } |
|
| 769 | - |
|
| 770 | - |
|
| 771 | - /** |
|
| 772 | - * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate |
|
| 773 | - * error message if either is missing. |
|
| 774 | - * |
|
| 775 | - * @return bool true means there were no errors, false means there were errors. |
|
| 776 | - */ |
|
| 777 | - protected function _verify() |
|
| 778 | - { |
|
| 779 | - // reset error message to an empty array. |
|
| 780 | - $this->_error_msg = array(); |
|
| 781 | - $valid = true; |
|
| 782 | - $valid = $valid ? $this->_validate_messenger_and_message_type() : $valid; |
|
| 783 | - $valid = $valid ? $this->_validate_and_setup_data() : $valid; |
|
| 784 | - |
|
| 785 | - // set the verified flag so we know everything has been validated. |
|
| 786 | - $this->_verified = $valid; |
|
| 787 | - |
|
| 788 | - return $valid; |
|
| 789 | - } |
|
| 790 | - |
|
| 791 | - |
|
| 792 | - /** |
|
| 793 | - * This accepts an array and validates that it is an array indexed by context with each value being an array of |
|
| 794 | - * EE_Messages_Addressee objects. |
|
| 795 | - * |
|
| 796 | - * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[] |
|
| 797 | - * @return bool |
|
| 798 | - */ |
|
| 799 | - protected function _valid_addressees($addressees) |
|
| 800 | - { |
|
| 801 | - if (! $addressees || ! is_array($addressees)) { |
|
| 802 | - return false; |
|
| 803 | - } |
|
| 804 | - |
|
| 805 | - foreach ($addressees as $addressee_array) { |
|
| 806 | - foreach ($addressee_array as $addressee) { |
|
| 807 | - if (! $addressee instanceof EE_Messages_Addressee) { |
|
| 808 | - return false; |
|
| 809 | - } |
|
| 810 | - } |
|
| 811 | - } |
|
| 812 | - return true; |
|
| 813 | - } |
|
| 814 | - |
|
| 815 | - |
|
| 816 | - /** |
|
| 817 | - * This validates the messenger, message type, and presences of generation data for the current EE_Message in the |
|
| 818 | - * queue. This process sets error messages if something is wrong. |
|
| 819 | - * |
|
| 820 | - * @return bool true is if there are no errors. false is if there is. |
|
| 821 | - */ |
|
| 822 | - protected function _validate_messenger_and_message_type() |
|
| 823 | - { |
|
| 824 | - |
|
| 825 | - // first are there any existing error messages? If so then return. |
|
| 826 | - if ($this->_error_msg) { |
|
| 827 | - return false; |
|
| 828 | - } |
|
| 829 | - /** @type EE_Message $message */ |
|
| 830 | - $message = $this->_generation_queue->get_message_repository()->current(); |
|
| 831 | - try { |
|
| 832 | - $this->_current_messenger = $message->valid_messenger(true) |
|
| 833 | - ? $message->messenger_object() |
|
| 834 | - : null; |
|
| 835 | - } catch (Exception $e) { |
|
| 836 | - $this->_error_msg[] = $e->getMessage(); |
|
| 837 | - } |
|
| 838 | - try { |
|
| 839 | - $this->_current_message_type = $message->valid_message_type(true) |
|
| 840 | - ? $message->message_type_object() |
|
| 841 | - : null; |
|
| 842 | - } catch (Exception $e) { |
|
| 843 | - $this->_error_msg[] = $e->getMessage(); |
|
| 844 | - } |
|
| 845 | - |
|
| 846 | - /** |
|
| 847 | - * Check if there is any generation data, but only if this is not for a preview. |
|
| 848 | - */ |
|
| 849 | - if (! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
| 850 | - && ( |
|
| 851 | - ! $this->_generation_queue->get_message_repository()->is_preview() |
|
| 852 | - && $this->_generation_queue->get_message_repository()->get_data_handler() |
|
| 853 | - !== 'EE_Messages_Preview_incoming_data' |
|
| 854 | - ) |
|
| 855 | - ) { |
|
| 856 | - $this->_error_msg[] = esc_html__( |
|
| 857 | - 'There is no generation data for this message. Unable to generate.', |
|
| 858 | - 'event_espresso' |
|
| 859 | - ); |
|
| 860 | - } |
|
| 861 | - |
|
| 862 | - return empty($this->_error_msg); |
|
| 863 | - } |
|
| 864 | - |
|
| 865 | - |
|
| 866 | - /** |
|
| 867 | - * This method retrieves the expected data handler for the message type and validates the generation data for that |
|
| 868 | - * data handler. |
|
| 869 | - * |
|
| 870 | - * @return bool true means there are no errors. false means there were errors (and handler did not get setup). |
|
| 871 | - */ |
|
| 872 | - protected function _validate_and_setup_data() |
|
| 873 | - { |
|
| 874 | - |
|
| 875 | - // First, are there any existing error messages? If so, return because if there were errors elsewhere this |
|
| 876 | - // can't be used anyways. |
|
| 877 | - if ($this->_error_msg) { |
|
| 878 | - return false; |
|
| 879 | - } |
|
| 880 | - |
|
| 881 | - $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data(); |
|
| 882 | - |
|
| 883 | - /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/ |
|
| 884 | - $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
|
| 885 | - ? $this->_generation_queue->get_message_repository()->get_data_handler() |
|
| 886 | - : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
| 887 | - |
|
| 888 | - // If this EE_Message is for a preview, then let's switch out to the preview data handler. |
|
| 889 | - if ($this->_generation_queue->get_message_repository()->is_preview()) { |
|
| 890 | - $data_handler_class_name = 'EE_Messages_Preview_incoming_data'; |
|
| 891 | - } |
|
| 892 | - |
|
| 893 | - // First get the class name for the data handler (and also verifies it exists. |
|
| 894 | - if (! class_exists($data_handler_class_name)) { |
|
| 895 | - $this->_error_msg[] = sprintf( |
|
| 896 | - /* Translators: Both placeholders are the names of php classes. */ |
|
| 897 | - esc_html__( |
|
| 898 | - 'The included data handler class name does not match any valid, accessible, "%1$s" classes. Looking for %2$s.', |
|
| 899 | - 'event_espresso' |
|
| 900 | - ), |
|
| 901 | - 'EE_Messages_incoming_data', |
|
| 902 | - $data_handler_class_name |
|
| 903 | - ); |
|
| 904 | - return false; |
|
| 905 | - } |
|
| 906 | - |
|
| 907 | - // convert generation_data for data_handler_instantiation. |
|
| 908 | - $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data); |
|
| 909 | - |
|
| 910 | - // note, this may set error messages as well. |
|
| 911 | - $this->_set_data_handler($generation_data, $data_handler_class_name); |
|
| 912 | - |
|
| 913 | - return empty($this->_error_msg); |
|
| 914 | - } |
|
| 915 | - |
|
| 916 | - |
|
| 917 | - /** |
|
| 918 | - * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and |
|
| 919 | - * adds it to the _data repository. |
|
| 920 | - * |
|
| 921 | - * @param mixed $generating_data This is data expected by the instantiated data handler. |
|
| 922 | - * @param string $data_handler_class_name This is the reference string indicating what data handler is being |
|
| 923 | - * instantiated. |
|
| 924 | - */ |
|
| 925 | - protected function _set_data_handler($generating_data, $data_handler_class_name) |
|
| 926 | - { |
|
| 927 | - // valid classname for the data handler. Now let's setup the key for the data handler repository to see if |
|
| 928 | - // there is already a ready data handler in the repository. |
|
| 929 | - $this->_current_data_handler = $this->_data_handler_collection->get_by_key( |
|
| 930 | - $this->_data_handler_collection->get_key( |
|
| 931 | - $data_handler_class_name, |
|
| 932 | - $generating_data |
|
| 933 | - ) |
|
| 934 | - ); |
|
| 935 | - if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
| 936 | - // no saved data_handler in the repo so let's set one up and add it to the repo. |
|
| 937 | - try { |
|
| 938 | - $this->_current_data_handler = new $data_handler_class_name($generating_data); |
|
| 939 | - $this->_data_handler_collection->add($this->_current_data_handler, $generating_data); |
|
| 940 | - } catch (Exception $e) { |
|
| 941 | - $this->_error_msg[] = $e->getMessage(); |
|
| 942 | - } |
|
| 943 | - } |
|
| 944 | - } |
|
| 945 | - |
|
| 946 | - |
|
| 947 | - /** |
|
| 948 | - * The queued EE_Message for generation does not save the data used for generation as objects |
|
| 949 | - * because serialization of those objects could be problematic if the data is saved to the db. |
|
| 950 | - * So this method calls the static method on the associated data_handler for the given message_type |
|
| 951 | - * and that preps the data for later instantiation when generating. |
|
| 952 | - * |
|
| 953 | - * @param EE_Message_To_Generate $message_to_generate |
|
| 954 | - * @param bool $preview Indicate whether this is being used for a preview or not. |
|
| 955 | - * @return mixed Prepped data for persisting to the queue. false is returned if unable to prep data. |
|
| 956 | - */ |
|
| 957 | - protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview) |
|
| 958 | - { |
|
| 959 | - /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
|
| 960 | - $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
|
| 961 | - if (! $message_to_generate->valid()) { |
|
| 962 | - return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
|
| 963 | - } |
|
| 964 | - return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
|
| 965 | - } |
|
| 966 | - |
|
| 967 | - |
|
| 968 | - /** |
|
| 969 | - * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue. |
|
| 970 | - * |
|
| 971 | - * @param EE_Message_To_Generate $message_to_generate |
|
| 972 | - * @param bool $test_send Whether this is just a test send or not. Typically used for previews. |
|
| 973 | - * @throws InvalidArgumentException |
|
| 974 | - * @throws InvalidDataTypeException |
|
| 975 | - * @throws InvalidInterfaceException |
|
| 976 | - */ |
|
| 977 | - public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false) |
|
| 978 | - { |
|
| 979 | - // prep data |
|
| 980 | - $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview()); |
|
| 981 | - $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface'); |
|
| 982 | - |
|
| 983 | - $message = $message_to_generate->get_EE_Message(); |
|
| 984 | - $GRP_ID = $request->getRequestParam('GRP_ID', 0); |
|
| 985 | - |
|
| 986 | - $GRP_ID = apply_filters( |
|
| 987 | - 'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID', |
|
| 988 | - $GRP_ID > 0 ? $GRP_ID : $message->GRP_ID(), |
|
| 989 | - $message, |
|
| 990 | - $message_to_generate, |
|
| 991 | - $test_send |
|
| 992 | - ); |
|
| 993 | - |
|
| 994 | - if ($GRP_ID > 0) { |
|
| 995 | - $message->set_GRP_ID($GRP_ID); |
|
| 996 | - } |
|
| 997 | - |
|
| 998 | - if ($data === false) { |
|
| 999 | - $message->set_STS_ID(EEM_Message::status_failed); |
|
| 1000 | - $message->set_error_message( |
|
| 1001 | - esc_html__( |
|
| 1002 | - 'Unable to prepare data for persistence to the database.', |
|
| 1003 | - 'event_espresso' |
|
| 1004 | - ) |
|
| 1005 | - ); |
|
| 1006 | - } else { |
|
| 1007 | - // make sure that the data handler is cached on the message as well |
|
| 1008 | - $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name(); |
|
| 1009 | - } |
|
| 1010 | - |
|
| 1011 | - $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send); |
|
| 1012 | - } |
|
| 747 | + esc_html__( |
|
| 748 | + 'There was a problem generating the content for the field %s: %s', |
|
| 749 | + 'event_espresso' |
|
| 750 | + ), |
|
| 751 | + $field, |
|
| 752 | + $e->getMessage() |
|
| 753 | + ); |
|
| 754 | + $message->set_STS_ID(EEM_Message::status_failed); |
|
| 755 | + } |
|
| 756 | + } |
|
| 757 | + } |
|
| 758 | + |
|
| 759 | + if ($message->STS_ID() === EEM_Message::status_failed) { |
|
| 760 | + $error_msg = esc_html__('There were problems generating this message:', 'event_espresso') |
|
| 761 | + . "\n" |
|
| 762 | + . implode("\n", $error_msg); |
|
| 763 | + $message->set_error_message($error_msg); |
|
| 764 | + } else { |
|
| 765 | + $message->set_STS_ID(EEM_Message::status_idle); |
|
| 766 | + } |
|
| 767 | + return $message; |
|
| 768 | + } |
|
| 769 | + |
|
| 770 | + |
|
| 771 | + /** |
|
| 772 | + * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate |
|
| 773 | + * error message if either is missing. |
|
| 774 | + * |
|
| 775 | + * @return bool true means there were no errors, false means there were errors. |
|
| 776 | + */ |
|
| 777 | + protected function _verify() |
|
| 778 | + { |
|
| 779 | + // reset error message to an empty array. |
|
| 780 | + $this->_error_msg = array(); |
|
| 781 | + $valid = true; |
|
| 782 | + $valid = $valid ? $this->_validate_messenger_and_message_type() : $valid; |
|
| 783 | + $valid = $valid ? $this->_validate_and_setup_data() : $valid; |
|
| 784 | + |
|
| 785 | + // set the verified flag so we know everything has been validated. |
|
| 786 | + $this->_verified = $valid; |
|
| 787 | + |
|
| 788 | + return $valid; |
|
| 789 | + } |
|
| 790 | + |
|
| 791 | + |
|
| 792 | + /** |
|
| 793 | + * This accepts an array and validates that it is an array indexed by context with each value being an array of |
|
| 794 | + * EE_Messages_Addressee objects. |
|
| 795 | + * |
|
| 796 | + * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[] |
|
| 797 | + * @return bool |
|
| 798 | + */ |
|
| 799 | + protected function _valid_addressees($addressees) |
|
| 800 | + { |
|
| 801 | + if (! $addressees || ! is_array($addressees)) { |
|
| 802 | + return false; |
|
| 803 | + } |
|
| 804 | + |
|
| 805 | + foreach ($addressees as $addressee_array) { |
|
| 806 | + foreach ($addressee_array as $addressee) { |
|
| 807 | + if (! $addressee instanceof EE_Messages_Addressee) { |
|
| 808 | + return false; |
|
| 809 | + } |
|
| 810 | + } |
|
| 811 | + } |
|
| 812 | + return true; |
|
| 813 | + } |
|
| 814 | + |
|
| 815 | + |
|
| 816 | + /** |
|
| 817 | + * This validates the messenger, message type, and presences of generation data for the current EE_Message in the |
|
| 818 | + * queue. This process sets error messages if something is wrong. |
|
| 819 | + * |
|
| 820 | + * @return bool true is if there are no errors. false is if there is. |
|
| 821 | + */ |
|
| 822 | + protected function _validate_messenger_and_message_type() |
|
| 823 | + { |
|
| 824 | + |
|
| 825 | + // first are there any existing error messages? If so then return. |
|
| 826 | + if ($this->_error_msg) { |
|
| 827 | + return false; |
|
| 828 | + } |
|
| 829 | + /** @type EE_Message $message */ |
|
| 830 | + $message = $this->_generation_queue->get_message_repository()->current(); |
|
| 831 | + try { |
|
| 832 | + $this->_current_messenger = $message->valid_messenger(true) |
|
| 833 | + ? $message->messenger_object() |
|
| 834 | + : null; |
|
| 835 | + } catch (Exception $e) { |
|
| 836 | + $this->_error_msg[] = $e->getMessage(); |
|
| 837 | + } |
|
| 838 | + try { |
|
| 839 | + $this->_current_message_type = $message->valid_message_type(true) |
|
| 840 | + ? $message->message_type_object() |
|
| 841 | + : null; |
|
| 842 | + } catch (Exception $e) { |
|
| 843 | + $this->_error_msg[] = $e->getMessage(); |
|
| 844 | + } |
|
| 845 | + |
|
| 846 | + /** |
|
| 847 | + * Check if there is any generation data, but only if this is not for a preview. |
|
| 848 | + */ |
|
| 849 | + if (! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
| 850 | + && ( |
|
| 851 | + ! $this->_generation_queue->get_message_repository()->is_preview() |
|
| 852 | + && $this->_generation_queue->get_message_repository()->get_data_handler() |
|
| 853 | + !== 'EE_Messages_Preview_incoming_data' |
|
| 854 | + ) |
|
| 855 | + ) { |
|
| 856 | + $this->_error_msg[] = esc_html__( |
|
| 857 | + 'There is no generation data for this message. Unable to generate.', |
|
| 858 | + 'event_espresso' |
|
| 859 | + ); |
|
| 860 | + } |
|
| 861 | + |
|
| 862 | + return empty($this->_error_msg); |
|
| 863 | + } |
|
| 864 | + |
|
| 865 | + |
|
| 866 | + /** |
|
| 867 | + * This method retrieves the expected data handler for the message type and validates the generation data for that |
|
| 868 | + * data handler. |
|
| 869 | + * |
|
| 870 | + * @return bool true means there are no errors. false means there were errors (and handler did not get setup). |
|
| 871 | + */ |
|
| 872 | + protected function _validate_and_setup_data() |
|
| 873 | + { |
|
| 874 | + |
|
| 875 | + // First, are there any existing error messages? If so, return because if there were errors elsewhere this |
|
| 876 | + // can't be used anyways. |
|
| 877 | + if ($this->_error_msg) { |
|
| 878 | + return false; |
|
| 879 | + } |
|
| 880 | + |
|
| 881 | + $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data(); |
|
| 882 | + |
|
| 883 | + /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/ |
|
| 884 | + $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
|
| 885 | + ? $this->_generation_queue->get_message_repository()->get_data_handler() |
|
| 886 | + : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
| 887 | + |
|
| 888 | + // If this EE_Message is for a preview, then let's switch out to the preview data handler. |
|
| 889 | + if ($this->_generation_queue->get_message_repository()->is_preview()) { |
|
| 890 | + $data_handler_class_name = 'EE_Messages_Preview_incoming_data'; |
|
| 891 | + } |
|
| 892 | + |
|
| 893 | + // First get the class name for the data handler (and also verifies it exists. |
|
| 894 | + if (! class_exists($data_handler_class_name)) { |
|
| 895 | + $this->_error_msg[] = sprintf( |
|
| 896 | + /* Translators: Both placeholders are the names of php classes. */ |
|
| 897 | + esc_html__( |
|
| 898 | + 'The included data handler class name does not match any valid, accessible, "%1$s" classes. Looking for %2$s.', |
|
| 899 | + 'event_espresso' |
|
| 900 | + ), |
|
| 901 | + 'EE_Messages_incoming_data', |
|
| 902 | + $data_handler_class_name |
|
| 903 | + ); |
|
| 904 | + return false; |
|
| 905 | + } |
|
| 906 | + |
|
| 907 | + // convert generation_data for data_handler_instantiation. |
|
| 908 | + $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data); |
|
| 909 | + |
|
| 910 | + // note, this may set error messages as well. |
|
| 911 | + $this->_set_data_handler($generation_data, $data_handler_class_name); |
|
| 912 | + |
|
| 913 | + return empty($this->_error_msg); |
|
| 914 | + } |
|
| 915 | + |
|
| 916 | + |
|
| 917 | + /** |
|
| 918 | + * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and |
|
| 919 | + * adds it to the _data repository. |
|
| 920 | + * |
|
| 921 | + * @param mixed $generating_data This is data expected by the instantiated data handler. |
|
| 922 | + * @param string $data_handler_class_name This is the reference string indicating what data handler is being |
|
| 923 | + * instantiated. |
|
| 924 | + */ |
|
| 925 | + protected function _set_data_handler($generating_data, $data_handler_class_name) |
|
| 926 | + { |
|
| 927 | + // valid classname for the data handler. Now let's setup the key for the data handler repository to see if |
|
| 928 | + // there is already a ready data handler in the repository. |
|
| 929 | + $this->_current_data_handler = $this->_data_handler_collection->get_by_key( |
|
| 930 | + $this->_data_handler_collection->get_key( |
|
| 931 | + $data_handler_class_name, |
|
| 932 | + $generating_data |
|
| 933 | + ) |
|
| 934 | + ); |
|
| 935 | + if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
| 936 | + // no saved data_handler in the repo so let's set one up and add it to the repo. |
|
| 937 | + try { |
|
| 938 | + $this->_current_data_handler = new $data_handler_class_name($generating_data); |
|
| 939 | + $this->_data_handler_collection->add($this->_current_data_handler, $generating_data); |
|
| 940 | + } catch (Exception $e) { |
|
| 941 | + $this->_error_msg[] = $e->getMessage(); |
|
| 942 | + } |
|
| 943 | + } |
|
| 944 | + } |
|
| 945 | + |
|
| 946 | + |
|
| 947 | + /** |
|
| 948 | + * The queued EE_Message for generation does not save the data used for generation as objects |
|
| 949 | + * because serialization of those objects could be problematic if the data is saved to the db. |
|
| 950 | + * So this method calls the static method on the associated data_handler for the given message_type |
|
| 951 | + * and that preps the data for later instantiation when generating. |
|
| 952 | + * |
|
| 953 | + * @param EE_Message_To_Generate $message_to_generate |
|
| 954 | + * @param bool $preview Indicate whether this is being used for a preview or not. |
|
| 955 | + * @return mixed Prepped data for persisting to the queue. false is returned if unable to prep data. |
|
| 956 | + */ |
|
| 957 | + protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview) |
|
| 958 | + { |
|
| 959 | + /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
|
| 960 | + $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
|
| 961 | + if (! $message_to_generate->valid()) { |
|
| 962 | + return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
|
| 963 | + } |
|
| 964 | + return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
|
| 965 | + } |
|
| 966 | + |
|
| 967 | + |
|
| 968 | + /** |
|
| 969 | + * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue. |
|
| 970 | + * |
|
| 971 | + * @param EE_Message_To_Generate $message_to_generate |
|
| 972 | + * @param bool $test_send Whether this is just a test send or not. Typically used for previews. |
|
| 973 | + * @throws InvalidArgumentException |
|
| 974 | + * @throws InvalidDataTypeException |
|
| 975 | + * @throws InvalidInterfaceException |
|
| 976 | + */ |
|
| 977 | + public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false) |
|
| 978 | + { |
|
| 979 | + // prep data |
|
| 980 | + $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview()); |
|
| 981 | + $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface'); |
|
| 982 | + |
|
| 983 | + $message = $message_to_generate->get_EE_Message(); |
|
| 984 | + $GRP_ID = $request->getRequestParam('GRP_ID', 0); |
|
| 985 | + |
|
| 986 | + $GRP_ID = apply_filters( |
|
| 987 | + 'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID', |
|
| 988 | + $GRP_ID > 0 ? $GRP_ID : $message->GRP_ID(), |
|
| 989 | + $message, |
|
| 990 | + $message_to_generate, |
|
| 991 | + $test_send |
|
| 992 | + ); |
|
| 993 | + |
|
| 994 | + if ($GRP_ID > 0) { |
|
| 995 | + $message->set_GRP_ID($GRP_ID); |
|
| 996 | + } |
|
| 997 | + |
|
| 998 | + if ($data === false) { |
|
| 999 | + $message->set_STS_ID(EEM_Message::status_failed); |
|
| 1000 | + $message->set_error_message( |
|
| 1001 | + esc_html__( |
|
| 1002 | + 'Unable to prepare data for persistence to the database.', |
|
| 1003 | + 'event_espresso' |
|
| 1004 | + ) |
|
| 1005 | + ); |
|
| 1006 | + } else { |
|
| 1007 | + // make sure that the data handler is cached on the message as well |
|
| 1008 | + $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name(); |
|
| 1009 | + } |
|
| 1010 | + |
|
| 1011 | + $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send); |
|
| 1012 | + } |
|
| 1013 | 1013 | } |
@@ -267,7 +267,7 @@ discard block |
||
| 267 | 267 | { |
| 268 | 268 | // double check verification has run and that everything is ready to work with (saves us having to validate |
| 269 | 269 | // everything again). |
| 270 | - if (! $this->_verified) { |
|
| 270 | + if ( ! $this->_verified) { |
|
| 271 | 271 | return false; // get out because we don't have a valid setup to work with. |
| 272 | 272 | } |
| 273 | 273 | |
@@ -284,7 +284,7 @@ discard block |
||
| 284 | 284 | |
| 285 | 285 | |
| 286 | 286 | // if no addressees then get out because there is nothing to generation (possible bad data). |
| 287 | - if (! $this->_valid_addressees($addressees)) { |
|
| 287 | + if ( ! $this->_valid_addressees($addressees)) { |
|
| 288 | 288 | do_action( |
| 289 | 289 | 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
| 290 | 290 | $this->_generation_queue->get_message_repository()->current(), |
@@ -306,7 +306,7 @@ discard block |
||
| 306 | 306 | $message_template_group = $this->_get_message_template_group(); |
| 307 | 307 | |
| 308 | 308 | // in the unlikely event there is no EE_Message_Template_Group available, get out! |
| 309 | - if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
| 309 | + if ( ! $message_template_group instanceof EE_Message_Template_Group) { |
|
| 310 | 310 | $this->_error_msg[] = esc_html__( |
| 311 | 311 | 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
| 312 | 312 | 'event_espresso' |
@@ -417,7 +417,7 @@ discard block |
||
| 417 | 417 | // attempt to retrieve from repo first |
| 418 | 418 | $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
| 419 | 419 | if ($message_template_group instanceof EE_Message_Template_Group) { |
| 420 | - return $message_template_group; // got it! |
|
| 420 | + return $message_template_group; // got it! |
|
| 421 | 421 | } |
| 422 | 422 | |
| 423 | 423 | // nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
@@ -446,7 +446,7 @@ discard block |
||
| 446 | 446 | protected function _queue_shares_same_message_template_group_for_events(array $event_ids) |
| 447 | 447 | { |
| 448 | 448 | foreach ($this->_current_data_handler->events as $event) { |
| 449 | - $event_ids[ $event['ID'] ] = $event['ID']; |
|
| 449 | + $event_ids[$event['ID']] = $event['ID']; |
|
| 450 | 450 | } |
| 451 | 451 | $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count( |
| 452 | 452 | array( |
@@ -522,7 +522,7 @@ discard block |
||
| 522 | 522 | ); |
| 523 | 523 | |
| 524 | 524 | // if we don't have a group lets hit the db. |
| 525 | - if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 525 | + if ( ! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
| 526 | 526 | $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
| 527 | 527 | array( |
| 528 | 528 | array( |
@@ -554,7 +554,7 @@ discard block |
||
| 554 | 554 | { |
| 555 | 555 | $event_ids = array(); |
| 556 | 556 | foreach ($this->_current_data_handler->events as $event) { |
| 557 | - $event_ids[ $event['ID'] ] = $event['ID']; |
|
| 557 | + $event_ids[$event['ID']] = $event['ID']; |
|
| 558 | 558 | } |
| 559 | 559 | return $event_ids; |
| 560 | 560 | } |
@@ -583,10 +583,10 @@ discard block |
||
| 583 | 583 | $context_templates = $message_template_group->context_templates(); |
| 584 | 584 | foreach ($context_templates as $context => $template_fields) { |
| 585 | 585 | foreach ($template_fields as $template_field => $template_obj) { |
| 586 | - if (! $template_obj instanceof EE_Message_Template) { |
|
| 586 | + if ( ! $template_obj instanceof EE_Message_Template) { |
|
| 587 | 587 | continue; |
| 588 | 588 | } |
| 589 | - $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content'); |
|
| 589 | + $templates[$template_field][$context] = $template_obj->get('MTP_content'); |
|
| 590 | 590 | } |
| 591 | 591 | } |
| 592 | 592 | return $templates; |
@@ -617,7 +617,7 @@ discard block |
||
| 617 | 617 | { |
| 618 | 618 | |
| 619 | 619 | // if templates are empty then get out because we can't generate anything. |
| 620 | - if (! $templates) { |
|
| 620 | + if ( ! $templates) { |
|
| 621 | 621 | $this->_error_msg[] = esc_html__( |
| 622 | 622 | 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
| 623 | 623 | 'event_espresso' |
@@ -704,10 +704,10 @@ discard block |
||
| 704 | 704 | $m_shortcodes = $this->_current_messenger->get_valid_shortcodes(); |
| 705 | 705 | |
| 706 | 706 | // if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing |
| 707 | - if (! $this->_generation_queue->get_message_repository()->is_preview() |
|
| 707 | + if ( ! $this->_generation_queue->get_message_repository()->is_preview() |
|
| 708 | 708 | && ( |
| 709 | 709 | ( |
| 710 | - empty($templates['to'][ $context ]) |
|
| 710 | + empty($templates['to'][$context]) |
|
| 711 | 711 | && ! $this->_current_messenger->allow_empty_to_field() |
| 712 | 712 | ) |
| 713 | 713 | || ! $message_template_group->is_context_active($context) |
@@ -721,15 +721,15 @@ discard block |
||
| 721 | 721 | foreach ($templates as $field => $field_context) { |
| 722 | 722 | $error_msg = array(); |
| 723 | 723 | // let's setup the valid shortcodes for the incoming context. |
| 724 | - $valid_shortcodes = $mt_shortcodes[ $context ]; |
|
| 724 | + $valid_shortcodes = $mt_shortcodes[$context]; |
|
| 725 | 725 | // merge in valid shortcodes for the field. |
| 726 | - $shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes; |
|
| 727 | - if (isset($templates[ $field ][ $context ])) { |
|
| 726 | + $shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes; |
|
| 727 | + if (isset($templates[$field][$context])) { |
|
| 728 | 728 | // prefix field. |
| 729 | - $column_name = 'MSG_' . $field; |
|
| 729 | + $column_name = 'MSG_'.$field; |
|
| 730 | 730 | try { |
| 731 | 731 | $content = $this->_shortcode_parser->parse_message_template( |
| 732 | - $templates[ $field ][ $context ], |
|
| 732 | + $templates[$field][$context], |
|
| 733 | 733 | $recipient, |
| 734 | 734 | $shortcodes, |
| 735 | 735 | $this->_current_message_type, |
@@ -798,13 +798,13 @@ discard block |
||
| 798 | 798 | */ |
| 799 | 799 | protected function _valid_addressees($addressees) |
| 800 | 800 | { |
| 801 | - if (! $addressees || ! is_array($addressees)) { |
|
| 801 | + if ( ! $addressees || ! is_array($addressees)) { |
|
| 802 | 802 | return false; |
| 803 | 803 | } |
| 804 | 804 | |
| 805 | 805 | foreach ($addressees as $addressee_array) { |
| 806 | 806 | foreach ($addressee_array as $addressee) { |
| 807 | - if (! $addressee instanceof EE_Messages_Addressee) { |
|
| 807 | + if ( ! $addressee instanceof EE_Messages_Addressee) { |
|
| 808 | 808 | return false; |
| 809 | 809 | } |
| 810 | 810 | } |
@@ -846,7 +846,7 @@ discard block |
||
| 846 | 846 | /** |
| 847 | 847 | * Check if there is any generation data, but only if this is not for a preview. |
| 848 | 848 | */ |
| 849 | - if (! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
| 849 | + if ( ! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
| 850 | 850 | && ( |
| 851 | 851 | ! $this->_generation_queue->get_message_repository()->is_preview() |
| 852 | 852 | && $this->_generation_queue->get_message_repository()->get_data_handler() |
@@ -883,7 +883,7 @@ discard block |
||
| 883 | 883 | /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/ |
| 884 | 884 | $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
| 885 | 885 | ? $this->_generation_queue->get_message_repository()->get_data_handler() |
| 886 | - : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
| 886 | + : 'EE_Messages_'.$this->_current_message_type->get_data_handler($generation_data).'_incoming_data'; |
|
| 887 | 887 | |
| 888 | 888 | // If this EE_Message is for a preview, then let's switch out to the preview data handler. |
| 889 | 889 | if ($this->_generation_queue->get_message_repository()->is_preview()) { |
@@ -891,7 +891,7 @@ discard block |
||
| 891 | 891 | } |
| 892 | 892 | |
| 893 | 893 | // First get the class name for the data handler (and also verifies it exists. |
| 894 | - if (! class_exists($data_handler_class_name)) { |
|
| 894 | + if ( ! class_exists($data_handler_class_name)) { |
|
| 895 | 895 | $this->_error_msg[] = sprintf( |
| 896 | 896 | /* Translators: Both placeholders are the names of php classes. */ |
| 897 | 897 | esc_html__( |
@@ -932,7 +932,7 @@ discard block |
||
| 932 | 932 | $generating_data |
| 933 | 933 | ) |
| 934 | 934 | ); |
| 935 | - if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
| 935 | + if ( ! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
| 936 | 936 | // no saved data_handler in the repo so let's set one up and add it to the repo. |
| 937 | 937 | try { |
| 938 | 938 | $this->_current_data_handler = new $data_handler_class_name($generating_data); |
@@ -958,7 +958,7 @@ discard block |
||
| 958 | 958 | { |
| 959 | 959 | /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
| 960 | 960 | $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
| 961 | - if (! $message_to_generate->valid()) { |
|
| 961 | + if ( ! $message_to_generate->valid()) { |
|
| 962 | 962 | return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
| 963 | 963 | } |
| 964 | 964 | return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
@@ -15,880 +15,880 @@ |
||
| 15 | 15 | abstract class EE_Data_Migration_Script_Base extends EE_Data_Migration_Class_Base |
| 16 | 16 | { |
| 17 | 17 | |
| 18 | - /** |
|
| 19 | - * Set by client code to indicate this DMS is being ran as part of a proper migration, |
|
| 20 | - * instead of being used to merely setup (or verify) the database structure. |
|
| 21 | - * Defaults to TRUE, so client code that's NOT using this DMS as part of a proper migration |
|
| 22 | - * should call EE_Data_Migration_Script_Base::set_migrating( FALSE ) |
|
| 23 | - * |
|
| 24 | - * @var boolean |
|
| 25 | - */ |
|
| 26 | - protected $_migrating = true; |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * numerically-indexed array where each value is EE_Data_Migration_Script_Stage object |
|
| 30 | - * |
|
| 31 | - * @var EE_Data_Migration_Script_Stage[] $migration_functions |
|
| 32 | - */ |
|
| 33 | - protected $_migration_stages = array(); |
|
| 34 | - |
|
| 35 | - /** |
|
| 36 | - * Indicates we've already ran the schema changes that needed to happen BEFORE the data migration |
|
| 37 | - * |
|
| 38 | - * @var boolean |
|
| 39 | - */ |
|
| 40 | - protected $_schema_changes_before_migration_ran = null; |
|
| 41 | - |
|
| 42 | - /** |
|
| 43 | - * Indicates we've already ran the schema changes that needed to happen AFTER the data migration |
|
| 44 | - * |
|
| 45 | - * @var boolean |
|
| 46 | - */ |
|
| 47 | - protected $_schema_changes_after_migration_ran = null; |
|
| 48 | - |
|
| 49 | - /** |
|
| 50 | - * String which describes what's currently happening in this migration |
|
| 51 | - * |
|
| 52 | - * @var string |
|
| 53 | - */ |
|
| 54 | - protected $_feedback_message; |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * Indicates the script's priority. Like wp's add_action and add_filter, lower numbers |
|
| 58 | - * correspond to earlier execution |
|
| 59 | - * |
|
| 60 | - * @var int |
|
| 61 | - */ |
|
| 62 | - protected $_priority = 5; |
|
| 63 | - |
|
| 64 | - /** |
|
| 65 | - * Multi-dimensional array that defines the mapping from OLD table Primary Keys |
|
| 66 | - * to NEW table Primary Keys. |
|
| 67 | - * Top-level array keys are OLD table names (minus the "wp_" part), |
|
| 68 | - * 2nd-level array keys are NEW table names (again, minus the "wp_" part), |
|
| 69 | - * 3rd-level array keys are the OLD table primary keys |
|
| 70 | - * and 3rd-level array values are the NEW table primary keys |
|
| 71 | - * |
|
| 72 | - * @var array |
|
| 73 | - */ |
|
| 74 | - protected $_mappings = array(); |
|
| 75 | - |
|
| 76 | - |
|
| 77 | - /** |
|
| 78 | - * Returns whether or not this data migration script can operate on the given version of the database. |
|
| 79 | - * Eg, if this migration script can migrate from 3.1.26 or higher (but not anything after 4.0.0), and |
|
| 80 | - * it's passed a string like '3.1.38B', it should return true. |
|
| 81 | - * If this DMS is to migrate data from an EE3 addon, you will probably want to use |
|
| 82 | - * EventEspresso\core\services\database\TableAnalysis::tableExists() to check for old EE3 tables, and |
|
| 83 | - * EE_Data_Migration_Manager::get_migration_ran() to check that core was already |
|
| 84 | - * migrated from EE3 to EE4 (ie, this DMS probably relies on some migration data generated |
|
| 85 | - * during the Core 4.1.0 DMS. If core didn't run that DMS, you probably don't want |
|
| 86 | - * to run this DMS). |
|
| 87 | - * If this DMS migrates data from a previous version of this EE4 addon, just |
|
| 88 | - * comparing $current_database_state_of[ $this->slug() ] will probably suffice. |
|
| 89 | - * If this DMS should never migrate data, because it's only used to define the initial |
|
| 90 | - * database state, just return FALSE (and core's activation process will take care |
|
| 91 | - * of calling its schema_changes_before_migration() and |
|
| 92 | - * schema_changes_after_migration() for you. ) |
|
| 93 | - * |
|
| 94 | - * @param array $current_database_state_of keys are EE plugin slugs (eg 'Core', 'Calendar', 'Mailchimp', etc) |
|
| 95 | - * @return boolean |
|
| 96 | - */ |
|
| 97 | - abstract public function can_migrate_from_version($current_database_state_of); |
|
| 98 | - |
|
| 99 | - |
|
| 100 | - /** |
|
| 101 | - * Performs database schema changes that need to occur BEFORE the data is migrated. |
|
| 102 | - * Eg, if we were going to change user passwords from plaintext to encoded versions |
|
| 103 | - * during this migration, this would probably add a new column called something like |
|
| 104 | - * "encoded_password". |
|
| 105 | - * |
|
| 106 | - * @return boolean of success |
|
| 107 | - */ |
|
| 108 | - abstract public function schema_changes_before_migration(); |
|
| 109 | - |
|
| 110 | - |
|
| 111 | - /** |
|
| 112 | - * Performs the database schema changes that need to occur AFTER the data has been migrated. |
|
| 113 | - * Usually this will mean we'll be removing old columns. Eg, if we were changing passwords |
|
| 114 | - * from plaintext to encoded versions, and we had added a column called "encoded_password", |
|
| 115 | - * this function would probably remove the old column "password" (which still holds the plaintext password) |
|
| 116 | - * and possibly rename "encoded_password" to "password" |
|
| 117 | - * |
|
| 118 | - * @return boolean of success |
|
| 119 | - */ |
|
| 120 | - abstract public function schema_changes_after_migration(); |
|
| 121 | - |
|
| 122 | - |
|
| 123 | - /** |
|
| 124 | - * All children of this must call parent::__construct() |
|
| 125 | - * at the end of their constructor or suffer the consequences! |
|
| 126 | - * |
|
| 127 | - * @param TableManager $table_manager |
|
| 128 | - * @param TableAnalysis $table_analysis |
|
| 129 | - */ |
|
| 130 | - public function __construct(TableManager $table_manager = null, TableAnalysis $table_analysis = null) |
|
| 131 | - { |
|
| 132 | - $this->_migration_stages = (array) apply_filters( |
|
| 133 | - 'FHEE__' . get_class($this) . '__construct__migration_stages', |
|
| 134 | - $this->_migration_stages |
|
| 135 | - ); |
|
| 136 | - foreach ($this->_migration_stages as $migration_stage) { |
|
| 137 | - if ($migration_stage instanceof EE_Data_Migration_Script_Stage) { |
|
| 138 | - $migration_stage->_construct_finalize($this); |
|
| 139 | - } |
|
| 140 | - } |
|
| 141 | - parent::__construct($table_manager, $table_analysis); |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - |
|
| 145 | - /** |
|
| 146 | - * Place to add hooks and filters for tweaking the migrations page, in order |
|
| 147 | - * to customize it |
|
| 148 | - */ |
|
| 149 | - public function migration_page_hooks() |
|
| 150 | - { |
|
| 151 | - // by default none are added because we normally like the default look of the migration page |
|
| 152 | - } |
|
| 153 | - |
|
| 154 | - |
|
| 155 | - /** |
|
| 156 | - * Sets the mapping from old table primary keys to new table primary keys. |
|
| 157 | - * This mapping is automatically persisted as a property on the migration |
|
| 158 | - * |
|
| 159 | - * @param string $old_table with wpdb prefix (wp_). Eg: wp_events_detail |
|
| 160 | - * @param int|string $old_pk old primary key. Eg events_detail.id's value |
|
| 161 | - * @param string $new_table with wpdb prefix (wp_). Eg: wp_posts |
|
| 162 | - * @param int|string $new_pk eg posts.ID |
|
| 163 | - * @return void |
|
| 164 | - */ |
|
| 165 | - public function set_mapping($old_table, $old_pk, $new_table, $new_pk) |
|
| 166 | - { |
|
| 167 | - // make sure it has the needed keys |
|
| 168 | - if (! isset($this->_mappings[ $old_table ]) || ! isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 169 | - $this->_mappings[ $old_table ][ $new_table ] = $this->_get_mapping_option($old_table, $new_table); |
|
| 170 | - } |
|
| 171 | - $this->_mappings[ $old_table ][ $new_table ][ $old_pk ] = $new_pk; |
|
| 172 | - } |
|
| 173 | - |
|
| 174 | - |
|
| 175 | - /** |
|
| 176 | - * Gets the new primary key, if provided with the OLD table and the primary key |
|
| 177 | - * of an item in the old table, and the new table |
|
| 178 | - * |
|
| 179 | - * @param string $old_table with wpdb prefix (wp_). Eg: wp_events_detail |
|
| 180 | - * @param int|string $old_pk old primary key. Eg events_detail.id's value |
|
| 181 | - * @param string $new_table with wpdb prefix (wp_). Eg: wp_posts |
|
| 182 | - * @return mixed the primary key on the new table |
|
| 183 | - */ |
|
| 184 | - public function get_mapping_new_pk($old_table, $old_pk, $new_table) |
|
| 185 | - { |
|
| 186 | - if (! isset($this->_mappings[ $old_table ]) || |
|
| 187 | - ! isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 188 | - // try fetching the option |
|
| 189 | - $this->_mappings[ $old_table ][ $new_table ] = $this->_get_mapping_option($old_table, $new_table); |
|
| 190 | - } |
|
| 191 | - return isset($this->_mappings[ $old_table ][ $new_table ][ $old_pk ]) |
|
| 192 | - ? $this->_mappings[ $old_table ][ $new_table ][ $old_pk ] : null; |
|
| 193 | - } |
|
| 194 | - |
|
| 195 | - |
|
| 196 | - /** |
|
| 197 | - * Gets the old primary key, if provided with the OLD table, |
|
| 198 | - * and the new table and the primary key of an item in the new table |
|
| 199 | - * |
|
| 200 | - * @param string $old_table with wpdb prefix (wp_). Eg: wp_events_detail |
|
| 201 | - * @param string $new_table with wpdb prefix (wp_). Eg: wp_posts |
|
| 202 | - * @param mixed $new_pk |
|
| 203 | - * @return mixed |
|
| 204 | - */ |
|
| 205 | - public function get_mapping_old_pk($old_table, $new_table, $new_pk) |
|
| 206 | - { |
|
| 207 | - if (! isset($this->_mappings[ $old_table ]) || |
|
| 208 | - ! isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 209 | - // try fetching the option |
|
| 210 | - $this->_mappings[ $old_table ][ $new_table ] = $this->_get_mapping_option($old_table, $new_table); |
|
| 211 | - } |
|
| 212 | - if (isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 213 | - $new_pk_to_old_pk = array_flip($this->_mappings[ $old_table ][ $new_table ]); |
|
| 214 | - if (isset($new_pk_to_old_pk[ $new_pk ])) { |
|
| 215 | - return $new_pk_to_old_pk[ $new_pk ]; |
|
| 216 | - } |
|
| 217 | - } |
|
| 218 | - return null; |
|
| 219 | - } |
|
| 220 | - |
|
| 221 | - |
|
| 222 | - /** |
|
| 223 | - * Gets the mapping array option specified by the table names |
|
| 224 | - * |
|
| 225 | - * @param string $old_table_name |
|
| 226 | - * @param string $new_table_name |
|
| 227 | - * @return array |
|
| 228 | - */ |
|
| 229 | - protected function _get_mapping_option($old_table_name, $new_table_name) |
|
| 230 | - { |
|
| 231 | - $option = get_option($this->_get_mapping_option_name($old_table_name, $new_table_name), array()); |
|
| 232 | - return $option; |
|
| 233 | - } |
|
| 234 | - |
|
| 235 | - |
|
| 236 | - /** |
|
| 237 | - * Updates the mapping option specified by the table names with the array provided |
|
| 238 | - * |
|
| 239 | - * @param string $old_table_name |
|
| 240 | - * @param string $new_table_name |
|
| 241 | - * @param array $mapping_array |
|
| 242 | - * @return boolean success of updating option |
|
| 243 | - */ |
|
| 244 | - protected function _set_mapping_option($old_table_name, $new_table_name, $mapping_array) |
|
| 245 | - { |
|
| 246 | - $success = update_option($this->_get_mapping_option_name($old_table_name, $new_table_name), $mapping_array, false); |
|
| 247 | - return $success; |
|
| 248 | - } |
|
| 249 | - |
|
| 250 | - |
|
| 251 | - /** |
|
| 252 | - * Gets the option name for this script to map from $old_table_name to $new_table_name |
|
| 253 | - * |
|
| 254 | - * @param string $old_table_name |
|
| 255 | - * @param string $new_table_name |
|
| 256 | - * @return string |
|
| 257 | - */ |
|
| 258 | - protected function _get_mapping_option_name($old_table_name, $new_table_name) |
|
| 259 | - { |
|
| 260 | - global $wpdb; |
|
| 261 | - $old_table_name_sans_wp = str_replace($wpdb->prefix, "", $old_table_name); |
|
| 262 | - $new_table_name_sans_wp = str_replace($wpdb->prefix, "", $new_table_name); |
|
| 263 | - $migrates_to = EE_Data_Migration_Manager::instance()->script_migrates_to_version(get_class($this)); |
|
| 264 | - return substr( |
|
| 265 | - EE_Data_Migration_Manager::data_migration_script_mapping_option_prefix . $migrates_to ['slug'] . '_' . $migrates_to['version'] . '_' . $old_table_name_sans_wp . '_' . $new_table_name_sans_wp, |
|
| 266 | - 0, |
|
| 267 | - 64 |
|
| 268 | - ); |
|
| 269 | - } |
|
| 270 | - |
|
| 271 | - |
|
| 272 | - /** |
|
| 273 | - * Counts all the records that will be migrated during this data migration. |
|
| 274 | - * For example, if we were changing old user passwords from plaintext to encoded versions, |
|
| 275 | - * this would be a count of all users who have passwords. If we were going to also split |
|
| 276 | - * attendee records into transactions, registrations, and attendee records, this would include |
|
| 277 | - * the count of all attendees currently in existence in the DB (ie, users + attendees). |
|
| 278 | - * If you can't determine how many records there are to migrate, just provide a guess: this |
|
| 279 | - * number will only be used in calculating the percent complete. If you estimate there to be |
|
| 280 | - * 100 records to migrate, and it turns out there's 120, we'll just show the migration as being at |
|
| 281 | - * 99% until the function "migration_step" returns EE_Data_Migration_Script_Base::status_complete. |
|
| 282 | - * |
|
| 283 | - * @return int |
|
| 284 | - */ |
|
| 285 | - protected function _count_records_to_migrate() |
|
| 286 | - { |
|
| 287 | - $count = 0; |
|
| 288 | - foreach ($this->stages() as $stage) { |
|
| 289 | - $count += $stage->count_records_to_migrate(); |
|
| 290 | - } |
|
| 291 | - return $count; |
|
| 292 | - } |
|
| 293 | - |
|
| 294 | - |
|
| 295 | - /** |
|
| 296 | - * Returns the number of records updated so far. Usually this is easiest to do |
|
| 297 | - * by just setting a transient and updating it after each migration_step |
|
| 298 | - * |
|
| 299 | - * @return int |
|
| 300 | - */ |
|
| 301 | - public function count_records_migrated() |
|
| 302 | - { |
|
| 303 | - $count = 0; |
|
| 304 | - foreach ($this->stages() as $stage) { |
|
| 305 | - $count += $stage->count_records_migrated(); |
|
| 306 | - } |
|
| 307 | - $this->_records_migrated = $count; |
|
| 308 | - return $count; |
|
| 309 | - } |
|
| 310 | - |
|
| 311 | - |
|
| 312 | - /** |
|
| 313 | - * @param int $num_records_to_migrate_limit |
|
| 314 | - * @return int |
|
| 315 | - * @throws EE_Error |
|
| 316 | - * @throws Exception |
|
| 317 | - */ |
|
| 318 | - public function migration_step($num_records_to_migrate_limit) |
|
| 319 | - { |
|
| 320 | - // reset the feedback message |
|
| 321 | - $this->_feedback_message = ''; |
|
| 322 | - // if we haven't yet done the 1st schema changes, do them now. buffer any output |
|
| 323 | - $this->_maybe_do_schema_changes(true); |
|
| 324 | - |
|
| 325 | - $num_records_actually_migrated = 0; |
|
| 326 | - $records_migrated_per_stage = array(); |
|
| 327 | - // setup the 'stage' variable, which should hold the last run stage of the migration (or none at all if nothing runs) |
|
| 328 | - $stage = null; |
|
| 329 | - // get the next stage that isn't complete |
|
| 330 | - foreach ($this->stages() as $stage) { |
|
| 331 | - if ($stage->get_status() == EE_Data_Migration_Manager::status_continue) { |
|
| 332 | - try { |
|
| 333 | - $records_migrated_during_stage = $stage->migration_step( |
|
| 334 | - $num_records_to_migrate_limit - $num_records_actually_migrated |
|
| 335 | - ); |
|
| 336 | - $num_records_actually_migrated += $records_migrated_during_stage; |
|
| 337 | - $records_migrated_per_stage[ $stage->pretty_name() ] = $records_migrated_during_stage; |
|
| 338 | - } catch (Exception $e) { |
|
| 339 | - // yes if we catch an exception here, we consider that migration stage borked. |
|
| 340 | - $stage->set_status(EE_Data_Migration_Manager::status_fatal_error); |
|
| 341 | - $this->set_status(EE_Data_Migration_Manager::status_fatal_error); |
|
| 342 | - $stage->add_error($e->getMessage() . ". Stack-trace:" . $e->getTraceAsString()); |
|
| 343 | - throw $e; |
|
| 344 | - } |
|
| 345 | - // check that the migration stage didn't mark itself as having a fatal error |
|
| 346 | - if ($stage->is_broken()) { |
|
| 347 | - $this->set_broken(); |
|
| 348 | - throw new EE_Error($stage->get_last_error()); |
|
| 349 | - } |
|
| 350 | - } |
|
| 351 | - // once we've migrated all the number we intended to (possibly from different stages), stop migrating |
|
| 352 | - // or if we had a fatal error |
|
| 353 | - // or if the current script stopped early- its not done, but it's done all it thinks we should do on this step |
|
| 354 | - if ($num_records_actually_migrated >= $num_records_to_migrate_limit |
|
| 355 | - || $stage->is_broken() |
|
| 356 | - || $stage->has_more_to_do() |
|
| 357 | - ) { |
|
| 358 | - break; |
|
| 359 | - } |
|
| 360 | - } |
|
| 361 | - // check if we're all done this data migration... |
|
| 362 | - // which is indicated by being done early AND the last stage claims to be done |
|
| 363 | - if ($stage == null) { |
|
| 364 | - // this migration script apparently has NO stages... which is super weird, but whatever |
|
| 365 | - $this->set_completed(); |
|
| 366 | - $this->_maybe_do_schema_changes(false); |
|
| 367 | - } elseif ($num_records_actually_migrated < $num_records_to_migrate_limit && ! $stage->has_more_to_do()) { |
|
| 368 | - // apparently we're done, because we couldn't migrate the number we intended to |
|
| 369 | - $this->set_completed(); |
|
| 370 | - $this->_update_feedback_message(array_reverse($records_migrated_per_stage)); |
|
| 371 | - // do schema changes for after the migration now |
|
| 372 | - // first double-check we haven't already done this |
|
| 373 | - $this->_maybe_do_schema_changes(false); |
|
| 374 | - } else { |
|
| 375 | - // update feedback message, keeping in mind that we show them with the most recent at the top |
|
| 376 | - $this->_update_feedback_message(array_reverse($records_migrated_per_stage)); |
|
| 377 | - } |
|
| 378 | - return $num_records_actually_migrated; |
|
| 379 | - } |
|
| 380 | - |
|
| 381 | - |
|
| 382 | - /** |
|
| 383 | - * Updates the feedback message according to what was done during this migration stage. |
|
| 384 | - * |
|
| 385 | - * @param array $records_migrated_per_stage KEYS are pretty names for each stage; values are the count of records |
|
| 386 | - * migrated from that stage |
|
| 387 | - * @return void |
|
| 388 | - */ |
|
| 389 | - private function _update_feedback_message($records_migrated_per_stage) |
|
| 390 | - { |
|
| 391 | - $feedback_message_array = array(); |
|
| 392 | - foreach ($records_migrated_per_stage as $migration_stage_name => $num_records_migrated) { |
|
| 393 | - $feedback_message_array[] = sprintf( |
|
| 394 | - __("Migrated %d records successfully during %s", "event_espresso"), |
|
| 395 | - $num_records_migrated, |
|
| 396 | - $migration_stage_name |
|
| 397 | - ); |
|
| 398 | - } |
|
| 399 | - $this->_feedback_message .= implode("<br>", $feedback_message_array); |
|
| 400 | - } |
|
| 401 | - |
|
| 402 | - |
|
| 403 | - /** |
|
| 404 | - * Calls either schema_changes_before_migration() (if $before==true) or schema_changes_after_migration |
|
| 405 | - * (if $before==false). Buffers their outputs and stores them on the class. |
|
| 406 | - * |
|
| 407 | - * @param boolean $before |
|
| 408 | - * @throws Exception |
|
| 409 | - * @return void |
|
| 410 | - */ |
|
| 411 | - private function _maybe_do_schema_changes($before = true) |
|
| 412 | - { |
|
| 413 | - // so this property will be either _schema_changes_after_migration_ran or _schema_changes_before_migration_ran |
|
| 414 | - $property_name = '_schema_changes_' . ($before ? 'before' : 'after') . '_migration_ran'; |
|
| 415 | - if (! $this->{$property_name}) { |
|
| 416 | - try { |
|
| 417 | - ob_start(); |
|
| 418 | - if ($before) { |
|
| 419 | - $this->schema_changes_before_migration(); |
|
| 420 | - } else { |
|
| 421 | - $this->schema_changes_after_migration(); |
|
| 422 | - } |
|
| 423 | - $output = ob_get_contents(); |
|
| 424 | - ob_end_clean(); |
|
| 425 | - } catch (Exception $e) { |
|
| 426 | - $this->set_status(EE_Data_Migration_Manager::status_fatal_error); |
|
| 427 | - throw $e; |
|
| 428 | - } |
|
| 429 | - // record that we've done these schema changes |
|
| 430 | - $this->{$property_name} = true; |
|
| 431 | - // if there were any warnings etc, record them as non-fatal errors |
|
| 432 | - if ($output) { |
|
| 433 | - // there were some warnings |
|
| 434 | - $this->_errors[] = $output; |
|
| 435 | - } |
|
| 436 | - } |
|
| 437 | - } |
|
| 438 | - |
|
| 439 | - |
|
| 440 | - /** |
|
| 441 | - * Wrapper for EEH_Activation::create_table. However, takes into account the request type when |
|
| 442 | - * deciding what to pass for its 4th arg, $drop_pre_existing_tables. Using this function, instead |
|
| 443 | - * of _table_should_exist_previously, indicates that this table should be new to the EE version being migrated to |
|
| 444 | - * or |
|
| 445 | - * activated currently. If this is a brand new activation or a migration, and we're indicating this table should |
|
| 446 | - * not |
|
| 447 | - * previously exist, then we want to set $drop_pre_existing_tables to TRUE (ie, we shouldn't discover that this |
|
| 448 | - * table exists in the DB in EEH_Activation::create_table- if it DOES exist, something's wrong and the old table |
|
| 449 | - * should be nuked. |
|
| 450 | - * |
|
| 451 | - * Just for a bit of context, the migration script's db_schema_changes_* methods |
|
| 452 | - * are called basically in 3 cases: on brand new activation of EE4 (ie no previous version of EE existed and the |
|
| 453 | - * plugin is being activated and we want to add all the brand new tables), upon reactivation of EE4 (it was |
|
| 454 | - * deactivated and then reactivated, in which case we want to just verify the DB structure is ok) that table should |
|
| 455 | - * be dropped), and during a migration when we're moving the DB to the state of the migration script |
|
| 456 | - * |
|
| 457 | - * @param string $table_name |
|
| 458 | - * @param string $table_definition_sql |
|
| 459 | - * @param string $engine_string |
|
| 460 | - */ |
|
| 461 | - protected function _table_is_new_in_this_version( |
|
| 462 | - $table_name, |
|
| 463 | - $table_definition_sql, |
|
| 464 | - $engine_string = 'ENGINE=InnoDB ' |
|
| 465 | - ) { |
|
| 466 | - $this->_create_table_and_catch_errors( |
|
| 467 | - $table_name, |
|
| 468 | - $table_definition_sql, |
|
| 469 | - $engine_string, |
|
| 470 | - $this->_pre_existing_table_should_be_dropped(true) |
|
| 471 | - ); |
|
| 472 | - } |
|
| 473 | - |
|
| 474 | - /** |
|
| 475 | - * Like _table_is_new_in_this_version and _table_should_exist_previously, this function verifies the given table |
|
| 476 | - * exists. But we understand that this table has CHANGED in this version since the previous version. So it's not |
|
| 477 | - * completely new, but it's different. So we need to treat it like a new table in terms of verifying it's schema is |
|
| 478 | - * correct on activations, migrations, upgrades; but if it exists when it shouldn't, we need to be as lenient as |
|
| 479 | - * _table_should_exist_previously. |
|
| 480 | - * 8656]{Assumes only this plugin could have added this table (ie, if its a new activation of this plugin, the |
|
| 481 | - * table shouldn't exist). |
|
| 482 | - * |
|
| 483 | - * @param string $table_name |
|
| 484 | - * @param string $table_definition_sql |
|
| 485 | - * @param string $engine_string |
|
| 486 | - */ |
|
| 487 | - protected function _table_is_changed_in_this_version( |
|
| 488 | - $table_name, |
|
| 489 | - $table_definition_sql, |
|
| 490 | - $engine_string = 'ENGINE=MyISAM' |
|
| 491 | - ) { |
|
| 492 | - $this->_create_table_and_catch_errors( |
|
| 493 | - $table_name, |
|
| 494 | - $table_definition_sql, |
|
| 495 | - $engine_string, |
|
| 496 | - $this->_pre_existing_table_should_be_dropped(false) |
|
| 497 | - ); |
|
| 498 | - } |
|
| 499 | - |
|
| 500 | - |
|
| 501 | - /** |
|
| 502 | - * _old_table_exists |
|
| 503 | - * returns TRUE if the requested table exists in the current database |
|
| 504 | - * |
|
| 505 | - * @param string $table_name |
|
| 506 | - * @return boolean |
|
| 507 | - */ |
|
| 508 | - protected function _old_table_exists($table_name) |
|
| 509 | - { |
|
| 510 | - return $this->_get_table_analysis()->tableExists($table_name); |
|
| 511 | - } |
|
| 512 | - |
|
| 513 | - |
|
| 514 | - /** |
|
| 515 | - * _delete_table_if_empty |
|
| 516 | - * returns TRUE if the requested table was empty and successfully empty |
|
| 517 | - * |
|
| 518 | - * @param string $table_name |
|
| 519 | - * @return boolean |
|
| 520 | - */ |
|
| 521 | - protected function _delete_table_if_empty($table_name) |
|
| 522 | - { |
|
| 523 | - return EEH_Activation::delete_db_table_if_empty($table_name); |
|
| 524 | - } |
|
| 525 | - |
|
| 526 | - |
|
| 527 | - /** |
|
| 528 | - * It is preferred to use _table_has_not_changed_since_previous or _table_is_changed_in_this_version |
|
| 529 | - * as these are significantly more efficient or explicit. |
|
| 530 | - * Please see description of _table_is_new_in_this_version. This function will only set |
|
| 531 | - * EEH_Activation::create_table's $drop_pre_existing_tables to TRUE if it's a brand |
|
| 532 | - * new activation. ie, a more accurate name for this method would be "_table_added_previously_by_this_plugin" |
|
| 533 | - * because the table will be cleared out if this is a new activation (ie, if its a new activation, it actually |
|
| 534 | - * should exist previously). Otherwise, we'll always set $drop_pre_existing_tables to FALSE because the table |
|
| 535 | - * should have existed. Note, if the table is being MODIFIED in this version being activated or migrated to, then |
|
| 536 | - * you want _table_is_changed_in_this_version NOT this one. We don't check this table's structure during migrations |
|
| 537 | - * because apparently it hasn't changed since the previous one, right? |
|
| 538 | - * |
|
| 539 | - * @param string $table_name |
|
| 540 | - * @param string $table_definition_sql |
|
| 541 | - * @param string $engine_string |
|
| 542 | - */ |
|
| 543 | - protected function _table_should_exist_previously( |
|
| 544 | - $table_name, |
|
| 545 | - $table_definition_sql, |
|
| 546 | - $engine_string = 'ENGINE=MyISAM' |
|
| 547 | - ) { |
|
| 548 | - $this->_create_table_and_catch_errors( |
|
| 549 | - $table_name, |
|
| 550 | - $table_definition_sql, |
|
| 551 | - $engine_string, |
|
| 552 | - $this->_pre_existing_table_should_be_dropped(false) |
|
| 553 | - ); |
|
| 554 | - } |
|
| 555 | - |
|
| 556 | - /** |
|
| 557 | - * Exactly the same as _table_should_exist_previously(), except if this migration script is currently doing |
|
| 558 | - * a migration, we skip checking this table's structure in the database and just assume it's correct. |
|
| 559 | - * So this is useful only to improve efficiency when doing migrations (not a big deal for single site installs, |
|
| 560 | - * but important for multisite where migrations can take a very long time otherwise). |
|
| 561 | - * If the table is known to have changed since previous version, use _table_is_changed_in_this_version(). |
|
| 562 | - * Assumes only this plugin could have added this table (ie, if its a new activation of this plugin, the table |
|
| 563 | - * shouldn't exist). |
|
| 564 | - * |
|
| 565 | - * @param string $table_name |
|
| 566 | - * @param string $table_definition_sql |
|
| 567 | - * @param string $engine_string |
|
| 568 | - */ |
|
| 569 | - protected function _table_has_not_changed_since_previous( |
|
| 570 | - $table_name, |
|
| 571 | - $table_definition_sql, |
|
| 572 | - $engine_string = 'ENGINE=MyISAM' |
|
| 573 | - ) { |
|
| 574 | - if ($this->_currently_migrating()) { |
|
| 575 | - // if we're doing a migration, and this table apparently already exists, then we don't need do anything right? |
|
| 576 | - return; |
|
| 577 | - } |
|
| 578 | - $this->_create_table_and_catch_errors( |
|
| 579 | - $table_name, |
|
| 580 | - $table_definition_sql, |
|
| 581 | - $engine_string, |
|
| 582 | - $this->_pre_existing_table_should_be_dropped(false) |
|
| 583 | - ); |
|
| 584 | - } |
|
| 585 | - |
|
| 586 | - /** |
|
| 587 | - * Returns whether or not this migration script is being used as part of an actual migration |
|
| 588 | - * |
|
| 589 | - * @return boolean |
|
| 590 | - */ |
|
| 591 | - protected function _currently_migrating() |
|
| 592 | - { |
|
| 593 | - // 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) |
|
| 594 | - return $this->_migrating && |
|
| 595 | - $this->can_migrate_from_version( |
|
| 596 | - EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set() |
|
| 597 | - ) && |
|
| 598 | - EE_Maintenance_Mode::instance()->real_level() == EE_Maintenance_Mode::level_2_complete_maintenance; |
|
| 599 | - } |
|
| 600 | - |
|
| 601 | - /** |
|
| 602 | - * Determines if a table should be dropped, based on whether it's reported to be new in $table_is_new, |
|
| 603 | - * and the plugin's request type. |
|
| 604 | - * Assumes only this plugin could have added the table (ie, if its a new activation of this plugin, the table |
|
| 605 | - * shouldn't exist no matter what). |
|
| 606 | - * |
|
| 607 | - * @param boolean $table_is_new |
|
| 608 | - * @return boolean |
|
| 609 | - */ |
|
| 610 | - protected function _pre_existing_table_should_be_dropped($table_is_new) |
|
| 611 | - { |
|
| 612 | - if ($table_is_new) { |
|
| 613 | - if ($this->_get_req_type_for_plugin_corresponding_to_this_dms() == EE_System::req_type_new_activation |
|
| 614 | - || $this->_currently_migrating() |
|
| 615 | - ) { |
|
| 616 | - return true; |
|
| 617 | - } else { |
|
| 618 | - return false; |
|
| 619 | - } |
|
| 620 | - } else { |
|
| 621 | - if (in_array( |
|
| 622 | - $this->_get_req_type_for_plugin_corresponding_to_this_dms(), |
|
| 623 | - array(EE_System::req_type_new_activation) |
|
| 624 | - )) { |
|
| 625 | - return true; |
|
| 626 | - } else { |
|
| 627 | - return false; |
|
| 628 | - } |
|
| 629 | - } |
|
| 630 | - } |
|
| 631 | - |
|
| 632 | - /** |
|
| 633 | - * Just wraps EEH_Activation::create_table, but catches any errors it may throw and adds them as errors on the DMS |
|
| 634 | - * |
|
| 635 | - * @param string $table_name |
|
| 636 | - * @param string $table_definition_sql |
|
| 637 | - * @param string $engine_string |
|
| 638 | - * @param boolean $drop_pre_existing_tables |
|
| 639 | - */ |
|
| 640 | - private function _create_table_and_catch_errors( |
|
| 641 | - $table_name, |
|
| 642 | - $table_definition_sql, |
|
| 643 | - $engine_string = 'ENGINE=MyISAM', |
|
| 644 | - $drop_pre_existing_tables = false |
|
| 645 | - ) { |
|
| 646 | - try { |
|
| 647 | - EEH_Activation::create_table($table_name, $table_definition_sql, $engine_string, $drop_pre_existing_tables); |
|
| 648 | - } catch (EE_Error $e) { |
|
| 649 | - $message = $e->getMessage() . '<br>Stack Trace:' . $e->getTraceAsString(); |
|
| 650 | - $this->add_error($message); |
|
| 651 | - $this->_feedback_message .= $message; |
|
| 652 | - } |
|
| 653 | - } |
|
| 654 | - |
|
| 655 | - |
|
| 656 | - /** |
|
| 657 | - * Gets the request type for the plugin (core or addon) that corresponds to this DMS |
|
| 658 | - * |
|
| 659 | - * @return int one of EE_System::_req_type_* constants |
|
| 660 | - * @throws EE_Error |
|
| 661 | - */ |
|
| 662 | - private function _get_req_type_for_plugin_corresponding_to_this_dms() |
|
| 663 | - { |
|
| 664 | - if ($this->slug() == 'Core') { |
|
| 665 | - return EE_System::instance()->detect_req_type(); |
|
| 666 | - } else {// it must be for an addon |
|
| 667 | - $addon_name = $this->slug(); |
|
| 668 | - if (EE_Registry::instance()->get_addon_by_name($addon_name)) { |
|
| 669 | - return EE_Registry::instance()->get_addon_by_name($addon_name)->detect_req_type(); |
|
| 670 | - } else { |
|
| 671 | - throw new EE_Error( |
|
| 672 | - sprintf( |
|
| 673 | - __( |
|
| 674 | - "The DMS slug '%s' should correspond to the addon's name, which should also be '%s', but no such addon was registered. These are the registered addons' names: %s", |
|
| 675 | - "event_espresso" |
|
| 676 | - ), |
|
| 677 | - $this->slug(), |
|
| 678 | - $addon_name, |
|
| 679 | - implode(",", array_keys(EE_Registry::instance()->get_addons_by_name())) |
|
| 680 | - ) |
|
| 681 | - ); |
|
| 682 | - } |
|
| 683 | - } |
|
| 684 | - } |
|
| 685 | - |
|
| 686 | - |
|
| 687 | - /** |
|
| 688 | - * returns an array of strings describing errors by all the script's stages |
|
| 689 | - * |
|
| 690 | - * @return array |
|
| 691 | - */ |
|
| 692 | - public function get_errors() |
|
| 693 | - { |
|
| 694 | - $all_errors = $this->_errors; |
|
| 695 | - if (! is_array($all_errors)) { |
|
| 696 | - $all_errors = array(); |
|
| 697 | - } |
|
| 698 | - foreach ($this->stages() as $stage) { |
|
| 699 | - $all_errors = array_merge($stage->get_errors(), $all_errors); |
|
| 700 | - } |
|
| 701 | - return $all_errors; |
|
| 702 | - } |
|
| 703 | - |
|
| 704 | - |
|
| 705 | - /** |
|
| 706 | - * Indicates whether or not this migration script should continue |
|
| 707 | - * |
|
| 708 | - * @return boolean |
|
| 709 | - */ |
|
| 710 | - public function can_continue() |
|
| 711 | - { |
|
| 712 | - return in_array( |
|
| 713 | - $this->get_status(), |
|
| 714 | - EE_Data_Migration_Manager::instance()->stati_that_indicate_to_continue_single_migration_script |
|
| 715 | - ); |
|
| 716 | - } |
|
| 717 | - |
|
| 718 | - |
|
| 719 | - /** |
|
| 720 | - * Gets all the data migration stages associated with this script. Note: |
|
| 721 | - * addons can filter this list to add their own stages, and because the list is |
|
| 722 | - * numerically-indexed, they can insert their stage wherever they like and it will |
|
| 723 | - * get ordered by the indexes |
|
| 724 | - * |
|
| 725 | - * @return EE_Data_Migration_Script_Stage[] |
|
| 726 | - */ |
|
| 727 | - protected function stages() |
|
| 728 | - { |
|
| 729 | - $stages = apply_filters('FHEE__' . get_class($this) . '__stages', $this->_migration_stages); |
|
| 730 | - ksort($stages); |
|
| 731 | - return $stages; |
|
| 732 | - } |
|
| 733 | - |
|
| 734 | - |
|
| 735 | - /** |
|
| 736 | - * Gets a string which should describe what's going on currently with this migration, which |
|
| 737 | - * can be displayed to the user |
|
| 738 | - * |
|
| 739 | - * @return string |
|
| 740 | - */ |
|
| 741 | - public function get_feedback_message() |
|
| 742 | - { |
|
| 743 | - return $this->_feedback_message; |
|
| 744 | - } |
|
| 745 | - |
|
| 746 | - |
|
| 747 | - /** |
|
| 748 | - * A lot like "__sleep()" magic method in purpose, this is meant for persisting this class' |
|
| 749 | - * properties to the DB. However, we don't want to use __sleep() because its quite |
|
| 750 | - * possible that this class is defined when it goes to sleep, but NOT available when it |
|
| 751 | - * awakes (eg, this class is part of an addon that is deactivated at some point). |
|
| 752 | - */ |
|
| 753 | - public function properties_as_array() |
|
| 754 | - { |
|
| 755 | - $properties = parent::properties_as_array(); |
|
| 756 | - $properties['_migration_stages'] = array(); |
|
| 757 | - foreach ($this->_migration_stages as $migration_stage_priority => $migration_stage_class) { |
|
| 758 | - $properties['_migration_stages'][ $migration_stage_priority ] = $migration_stage_class->properties_as_array( |
|
| 759 | - ); |
|
| 760 | - } |
|
| 761 | - unset($properties['_mappings']); |
|
| 762 | - |
|
| 763 | - foreach ($this->_mappings as $old_table_name => $mapping_to_new_table) { |
|
| 764 | - foreach ($mapping_to_new_table as $new_table_name => $mapping) { |
|
| 765 | - $this->_set_mapping_option($old_table_name, $new_table_name, $mapping); |
|
| 766 | - } |
|
| 767 | - } |
|
| 768 | - return $properties; |
|
| 769 | - } |
|
| 770 | - |
|
| 771 | - |
|
| 772 | - /** |
|
| 773 | - * Sets all of the properties of this script stage to match what's in the array, which is assumed |
|
| 774 | - * to have been made from the properties_as_array() function. |
|
| 775 | - * |
|
| 776 | - * @param array $array_of_properties like what's produced from properties_as_array() method |
|
| 777 | - * @return void |
|
| 778 | - */ |
|
| 779 | - public function instantiate_from_array_of_properties($array_of_properties) |
|
| 780 | - { |
|
| 781 | - $stages_properties_arrays = $array_of_properties['_migration_stages']; |
|
| 782 | - unset($array_of_properties['_migration_stages']); |
|
| 783 | - unset($array_of_properties['class']); |
|
| 784 | - foreach ($array_of_properties as $property_name => $property_value) { |
|
| 785 | - $this->{$property_name} = $property_value; |
|
| 786 | - } |
|
| 787 | - // _migration_stages are already instantiated, but have only default data |
|
| 788 | - foreach ($this->_migration_stages as $stage) { |
|
| 789 | - $stage_data = $this->_find_migration_stage_data_with_classname( |
|
| 790 | - get_class($stage), |
|
| 791 | - $stages_properties_arrays |
|
| 792 | - ); |
|
| 793 | - // SO, if we found the stage data that was saved, use it. Otherwise, I guess the stage is new? (maybe added by |
|
| 794 | - // an addon? Unlikely... not sure why it wouldn't exist, but if it doesn't just treat it like it was never started yet) |
|
| 795 | - if ($stage_data) { |
|
| 796 | - $stage->instantiate_from_array_of_properties($stage_data); |
|
| 797 | - } |
|
| 798 | - } |
|
| 799 | - } |
|
| 800 | - |
|
| 801 | - |
|
| 802 | - /** |
|
| 803 | - * Gets the migration data from the array $migration_stage_data_arrays (which is an array of arrays, each of which |
|
| 804 | - * is pretty well identical to EE_Data_Migration_Stage objects except all their properties are array indexes) |
|
| 805 | - * for the given classname |
|
| 806 | - * |
|
| 807 | - * @param string $classname |
|
| 808 | - * @param array $migration_stage_data_arrays |
|
| 809 | - * @return null |
|
| 810 | - */ |
|
| 811 | - private function _find_migration_stage_data_with_classname($classname, $migration_stage_data_arrays) |
|
| 812 | - { |
|
| 813 | - foreach ($migration_stage_data_arrays as $migration_stage_data_array) { |
|
| 814 | - if (isset($migration_stage_data_array['class']) && $migration_stage_data_array['class'] == $classname) { |
|
| 815 | - return $migration_stage_data_array; |
|
| 816 | - } |
|
| 817 | - } |
|
| 818 | - return null; |
|
| 819 | - } |
|
| 820 | - |
|
| 821 | - |
|
| 822 | - /** |
|
| 823 | - * Returns the version that this script migrates to, based on the script's name. |
|
| 824 | - * Cannot be overwritten because lots of code needs to know which version a script |
|
| 825 | - * migrates to knowing only its name. |
|
| 826 | - * |
|
| 827 | - * @return array where the first key is the plugin's slug, the 2nd is the version of that plugin |
|
| 828 | - * that will be updated to. Eg array('Core','4.1.0') |
|
| 829 | - */ |
|
| 830 | - final public function migrates_to_version() |
|
| 831 | - { |
|
| 832 | - return EE_Data_Migration_Manager::instance()->script_migrates_to_version(get_class($this)); |
|
| 833 | - } |
|
| 834 | - |
|
| 835 | - |
|
| 836 | - /** |
|
| 837 | - * Gets this addon's slug as it would appear in the current_db_state wp option, |
|
| 838 | - * and if this migration script is for an addon, it SHOULD match the addon's slug |
|
| 839 | - * (and also the addon's classname, minus the 'EE_' prefix.). Eg, 'Calendar' for the EE_Calendar addon. |
|
| 840 | - * Or 'Core' for core (non-addon). |
|
| 841 | - * |
|
| 842 | - * @return string |
|
| 843 | - */ |
|
| 844 | - public function slug() |
|
| 845 | - { |
|
| 846 | - $migrates_to_version_info = $this->migrates_to_version(); |
|
| 847 | - // the slug is the first part of the array |
|
| 848 | - return $migrates_to_version_info['slug']; |
|
| 849 | - } |
|
| 850 | - |
|
| 851 | - |
|
| 852 | - /** |
|
| 853 | - * Returns the script's priority relative to DMSs from other addons. However, when |
|
| 854 | - * two DMSs from the same addon/core apply, this is ignored (and instead the version that |
|
| 855 | - * the script migrates to is used to determine which to run first). The default is 5, but all core DMSs |
|
| 856 | - * normally have priority 10. (So if you want a DMS "A" to run before DMS "B", both of which are from addons, |
|
| 857 | - * and both of which CAN run at the same time (ie, "B" doesn't depend on "A" to set |
|
| 858 | - * the database up so it can run), then you can set "A" to priority 3 or something. |
|
| 859 | - * |
|
| 860 | - * @return int |
|
| 861 | - */ |
|
| 862 | - public function priority() |
|
| 863 | - { |
|
| 864 | - return $this->_priority; |
|
| 865 | - } |
|
| 866 | - |
|
| 867 | - |
|
| 868 | - /** |
|
| 869 | - * Sets whether or not this DMS is being ran as part of a migration, instead of |
|
| 870 | - * just being used to setup (or verify) the current database structure matches |
|
| 871 | - * what the latest DMS indicates it should be |
|
| 872 | - * |
|
| 873 | - * @param boolean $migrating |
|
| 874 | - * @return void |
|
| 875 | - */ |
|
| 876 | - public function set_migrating($migrating = true) |
|
| 877 | - { |
|
| 878 | - $this->_migrating = $migrating; |
|
| 879 | - } |
|
| 880 | - |
|
| 881 | - /** |
|
| 882 | - * Marks that we think this migration class can continue to migrate |
|
| 883 | - */ |
|
| 884 | - public function reattempt() |
|
| 885 | - { |
|
| 886 | - parent::reattempt(); |
|
| 887 | - // also, we want to reattempt any stages that were marked as borked |
|
| 888 | - foreach ($this->stages() as $stage) { |
|
| 889 | - if ($stage->is_broken()) { |
|
| 890 | - $stage->reattempt(); |
|
| 891 | - } |
|
| 892 | - } |
|
| 893 | - } |
|
| 18 | + /** |
|
| 19 | + * Set by client code to indicate this DMS is being ran as part of a proper migration, |
|
| 20 | + * instead of being used to merely setup (or verify) the database structure. |
|
| 21 | + * Defaults to TRUE, so client code that's NOT using this DMS as part of a proper migration |
|
| 22 | + * should call EE_Data_Migration_Script_Base::set_migrating( FALSE ) |
|
| 23 | + * |
|
| 24 | + * @var boolean |
|
| 25 | + */ |
|
| 26 | + protected $_migrating = true; |
|
| 27 | + |
|
| 28 | + /** |
|
| 29 | + * numerically-indexed array where each value is EE_Data_Migration_Script_Stage object |
|
| 30 | + * |
|
| 31 | + * @var EE_Data_Migration_Script_Stage[] $migration_functions |
|
| 32 | + */ |
|
| 33 | + protected $_migration_stages = array(); |
|
| 34 | + |
|
| 35 | + /** |
|
| 36 | + * Indicates we've already ran the schema changes that needed to happen BEFORE the data migration |
|
| 37 | + * |
|
| 38 | + * @var boolean |
|
| 39 | + */ |
|
| 40 | + protected $_schema_changes_before_migration_ran = null; |
|
| 41 | + |
|
| 42 | + /** |
|
| 43 | + * Indicates we've already ran the schema changes that needed to happen AFTER the data migration |
|
| 44 | + * |
|
| 45 | + * @var boolean |
|
| 46 | + */ |
|
| 47 | + protected $_schema_changes_after_migration_ran = null; |
|
| 48 | + |
|
| 49 | + /** |
|
| 50 | + * String which describes what's currently happening in this migration |
|
| 51 | + * |
|
| 52 | + * @var string |
|
| 53 | + */ |
|
| 54 | + protected $_feedback_message; |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * Indicates the script's priority. Like wp's add_action and add_filter, lower numbers |
|
| 58 | + * correspond to earlier execution |
|
| 59 | + * |
|
| 60 | + * @var int |
|
| 61 | + */ |
|
| 62 | + protected $_priority = 5; |
|
| 63 | + |
|
| 64 | + /** |
|
| 65 | + * Multi-dimensional array that defines the mapping from OLD table Primary Keys |
|
| 66 | + * to NEW table Primary Keys. |
|
| 67 | + * Top-level array keys are OLD table names (minus the "wp_" part), |
|
| 68 | + * 2nd-level array keys are NEW table names (again, minus the "wp_" part), |
|
| 69 | + * 3rd-level array keys are the OLD table primary keys |
|
| 70 | + * and 3rd-level array values are the NEW table primary keys |
|
| 71 | + * |
|
| 72 | + * @var array |
|
| 73 | + */ |
|
| 74 | + protected $_mappings = array(); |
|
| 75 | + |
|
| 76 | + |
|
| 77 | + /** |
|
| 78 | + * Returns whether or not this data migration script can operate on the given version of the database. |
|
| 79 | + * Eg, if this migration script can migrate from 3.1.26 or higher (but not anything after 4.0.0), and |
|
| 80 | + * it's passed a string like '3.1.38B', it should return true. |
|
| 81 | + * If this DMS is to migrate data from an EE3 addon, you will probably want to use |
|
| 82 | + * EventEspresso\core\services\database\TableAnalysis::tableExists() to check for old EE3 tables, and |
|
| 83 | + * EE_Data_Migration_Manager::get_migration_ran() to check that core was already |
|
| 84 | + * migrated from EE3 to EE4 (ie, this DMS probably relies on some migration data generated |
|
| 85 | + * during the Core 4.1.0 DMS. If core didn't run that DMS, you probably don't want |
|
| 86 | + * to run this DMS). |
|
| 87 | + * If this DMS migrates data from a previous version of this EE4 addon, just |
|
| 88 | + * comparing $current_database_state_of[ $this->slug() ] will probably suffice. |
|
| 89 | + * If this DMS should never migrate data, because it's only used to define the initial |
|
| 90 | + * database state, just return FALSE (and core's activation process will take care |
|
| 91 | + * of calling its schema_changes_before_migration() and |
|
| 92 | + * schema_changes_after_migration() for you. ) |
|
| 93 | + * |
|
| 94 | + * @param array $current_database_state_of keys are EE plugin slugs (eg 'Core', 'Calendar', 'Mailchimp', etc) |
|
| 95 | + * @return boolean |
|
| 96 | + */ |
|
| 97 | + abstract public function can_migrate_from_version($current_database_state_of); |
|
| 98 | + |
|
| 99 | + |
|
| 100 | + /** |
|
| 101 | + * Performs database schema changes that need to occur BEFORE the data is migrated. |
|
| 102 | + * Eg, if we were going to change user passwords from plaintext to encoded versions |
|
| 103 | + * during this migration, this would probably add a new column called something like |
|
| 104 | + * "encoded_password". |
|
| 105 | + * |
|
| 106 | + * @return boolean of success |
|
| 107 | + */ |
|
| 108 | + abstract public function schema_changes_before_migration(); |
|
| 109 | + |
|
| 110 | + |
|
| 111 | + /** |
|
| 112 | + * Performs the database schema changes that need to occur AFTER the data has been migrated. |
|
| 113 | + * Usually this will mean we'll be removing old columns. Eg, if we were changing passwords |
|
| 114 | + * from plaintext to encoded versions, and we had added a column called "encoded_password", |
|
| 115 | + * this function would probably remove the old column "password" (which still holds the plaintext password) |
|
| 116 | + * and possibly rename "encoded_password" to "password" |
|
| 117 | + * |
|
| 118 | + * @return boolean of success |
|
| 119 | + */ |
|
| 120 | + abstract public function schema_changes_after_migration(); |
|
| 121 | + |
|
| 122 | + |
|
| 123 | + /** |
|
| 124 | + * All children of this must call parent::__construct() |
|
| 125 | + * at the end of their constructor or suffer the consequences! |
|
| 126 | + * |
|
| 127 | + * @param TableManager $table_manager |
|
| 128 | + * @param TableAnalysis $table_analysis |
|
| 129 | + */ |
|
| 130 | + public function __construct(TableManager $table_manager = null, TableAnalysis $table_analysis = null) |
|
| 131 | + { |
|
| 132 | + $this->_migration_stages = (array) apply_filters( |
|
| 133 | + 'FHEE__' . get_class($this) . '__construct__migration_stages', |
|
| 134 | + $this->_migration_stages |
|
| 135 | + ); |
|
| 136 | + foreach ($this->_migration_stages as $migration_stage) { |
|
| 137 | + if ($migration_stage instanceof EE_Data_Migration_Script_Stage) { |
|
| 138 | + $migration_stage->_construct_finalize($this); |
|
| 139 | + } |
|
| 140 | + } |
|
| 141 | + parent::__construct($table_manager, $table_analysis); |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + |
|
| 145 | + /** |
|
| 146 | + * Place to add hooks and filters for tweaking the migrations page, in order |
|
| 147 | + * to customize it |
|
| 148 | + */ |
|
| 149 | + public function migration_page_hooks() |
|
| 150 | + { |
|
| 151 | + // by default none are added because we normally like the default look of the migration page |
|
| 152 | + } |
|
| 153 | + |
|
| 154 | + |
|
| 155 | + /** |
|
| 156 | + * Sets the mapping from old table primary keys to new table primary keys. |
|
| 157 | + * This mapping is automatically persisted as a property on the migration |
|
| 158 | + * |
|
| 159 | + * @param string $old_table with wpdb prefix (wp_). Eg: wp_events_detail |
|
| 160 | + * @param int|string $old_pk old primary key. Eg events_detail.id's value |
|
| 161 | + * @param string $new_table with wpdb prefix (wp_). Eg: wp_posts |
|
| 162 | + * @param int|string $new_pk eg posts.ID |
|
| 163 | + * @return void |
|
| 164 | + */ |
|
| 165 | + public function set_mapping($old_table, $old_pk, $new_table, $new_pk) |
|
| 166 | + { |
|
| 167 | + // make sure it has the needed keys |
|
| 168 | + if (! isset($this->_mappings[ $old_table ]) || ! isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 169 | + $this->_mappings[ $old_table ][ $new_table ] = $this->_get_mapping_option($old_table, $new_table); |
|
| 170 | + } |
|
| 171 | + $this->_mappings[ $old_table ][ $new_table ][ $old_pk ] = $new_pk; |
|
| 172 | + } |
|
| 173 | + |
|
| 174 | + |
|
| 175 | + /** |
|
| 176 | + * Gets the new primary key, if provided with the OLD table and the primary key |
|
| 177 | + * of an item in the old table, and the new table |
|
| 178 | + * |
|
| 179 | + * @param string $old_table with wpdb prefix (wp_). Eg: wp_events_detail |
|
| 180 | + * @param int|string $old_pk old primary key. Eg events_detail.id's value |
|
| 181 | + * @param string $new_table with wpdb prefix (wp_). Eg: wp_posts |
|
| 182 | + * @return mixed the primary key on the new table |
|
| 183 | + */ |
|
| 184 | + public function get_mapping_new_pk($old_table, $old_pk, $new_table) |
|
| 185 | + { |
|
| 186 | + if (! isset($this->_mappings[ $old_table ]) || |
|
| 187 | + ! isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 188 | + // try fetching the option |
|
| 189 | + $this->_mappings[ $old_table ][ $new_table ] = $this->_get_mapping_option($old_table, $new_table); |
|
| 190 | + } |
|
| 191 | + return isset($this->_mappings[ $old_table ][ $new_table ][ $old_pk ]) |
|
| 192 | + ? $this->_mappings[ $old_table ][ $new_table ][ $old_pk ] : null; |
|
| 193 | + } |
|
| 194 | + |
|
| 195 | + |
|
| 196 | + /** |
|
| 197 | + * Gets the old primary key, if provided with the OLD table, |
|
| 198 | + * and the new table and the primary key of an item in the new table |
|
| 199 | + * |
|
| 200 | + * @param string $old_table with wpdb prefix (wp_). Eg: wp_events_detail |
|
| 201 | + * @param string $new_table with wpdb prefix (wp_). Eg: wp_posts |
|
| 202 | + * @param mixed $new_pk |
|
| 203 | + * @return mixed |
|
| 204 | + */ |
|
| 205 | + public function get_mapping_old_pk($old_table, $new_table, $new_pk) |
|
| 206 | + { |
|
| 207 | + if (! isset($this->_mappings[ $old_table ]) || |
|
| 208 | + ! isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 209 | + // try fetching the option |
|
| 210 | + $this->_mappings[ $old_table ][ $new_table ] = $this->_get_mapping_option($old_table, $new_table); |
|
| 211 | + } |
|
| 212 | + if (isset($this->_mappings[ $old_table ][ $new_table ])) { |
|
| 213 | + $new_pk_to_old_pk = array_flip($this->_mappings[ $old_table ][ $new_table ]); |
|
| 214 | + if (isset($new_pk_to_old_pk[ $new_pk ])) { |
|
| 215 | + return $new_pk_to_old_pk[ $new_pk ]; |
|
| 216 | + } |
|
| 217 | + } |
|
| 218 | + return null; |
|
| 219 | + } |
|
| 220 | + |
|
| 221 | + |
|
| 222 | + /** |
|
| 223 | + * Gets the mapping array option specified by the table names |
|
| 224 | + * |
|
| 225 | + * @param string $old_table_name |
|
| 226 | + * @param string $new_table_name |
|
| 227 | + * @return array |
|
| 228 | + */ |
|
| 229 | + protected function _get_mapping_option($old_table_name, $new_table_name) |
|
| 230 | + { |
|
| 231 | + $option = get_option($this->_get_mapping_option_name($old_table_name, $new_table_name), array()); |
|
| 232 | + return $option; |
|
| 233 | + } |
|
| 234 | + |
|
| 235 | + |
|
| 236 | + /** |
|
| 237 | + * Updates the mapping option specified by the table names with the array provided |
|
| 238 | + * |
|
| 239 | + * @param string $old_table_name |
|
| 240 | + * @param string $new_table_name |
|
| 241 | + * @param array $mapping_array |
|
| 242 | + * @return boolean success of updating option |
|
| 243 | + */ |
|
| 244 | + protected function _set_mapping_option($old_table_name, $new_table_name, $mapping_array) |
|
| 245 | + { |
|
| 246 | + $success = update_option($this->_get_mapping_option_name($old_table_name, $new_table_name), $mapping_array, false); |
|
| 247 | + return $success; |
|
| 248 | + } |
|
| 249 | + |
|
| 250 | + |
|
| 251 | + /** |
|
| 252 | + * Gets the option name for this script to map from $old_table_name to $new_table_name |
|
| 253 | + * |
|
| 254 | + * @param string $old_table_name |
|
| 255 | + * @param string $new_table_name |
|
| 256 | + * @return string |
|
| 257 | + */ |
|
| 258 | + protected function _get_mapping_option_name($old_table_name, $new_table_name) |
|
| 259 | + { |
|
| 260 | + global $wpdb; |
|
| 261 | + $old_table_name_sans_wp = str_replace($wpdb->prefix, "", $old_table_name); |
|
| 262 | + $new_table_name_sans_wp = str_replace($wpdb->prefix, "", $new_table_name); |
|
| 263 | + $migrates_to = EE_Data_Migration_Manager::instance()->script_migrates_to_version(get_class($this)); |
|
| 264 | + return substr( |
|
| 265 | + EE_Data_Migration_Manager::data_migration_script_mapping_option_prefix . $migrates_to ['slug'] . '_' . $migrates_to['version'] . '_' . $old_table_name_sans_wp . '_' . $new_table_name_sans_wp, |
|
| 266 | + 0, |
|
| 267 | + 64 |
|
| 268 | + ); |
|
| 269 | + } |
|
| 270 | + |
|
| 271 | + |
|
| 272 | + /** |
|
| 273 | + * Counts all the records that will be migrated during this data migration. |
|
| 274 | + * For example, if we were changing old user passwords from plaintext to encoded versions, |
|
| 275 | + * this would be a count of all users who have passwords. If we were going to also split |
|
| 276 | + * attendee records into transactions, registrations, and attendee records, this would include |
|
| 277 | + * the count of all attendees currently in existence in the DB (ie, users + attendees). |
|
| 278 | + * If you can't determine how many records there are to migrate, just provide a guess: this |
|
| 279 | + * number will only be used in calculating the percent complete. If you estimate there to be |
|
| 280 | + * 100 records to migrate, and it turns out there's 120, we'll just show the migration as being at |
|
| 281 | + * 99% until the function "migration_step" returns EE_Data_Migration_Script_Base::status_complete. |
|
| 282 | + * |
|
| 283 | + * @return int |
|
| 284 | + */ |
|
| 285 | + protected function _count_records_to_migrate() |
|
| 286 | + { |
|
| 287 | + $count = 0; |
|
| 288 | + foreach ($this->stages() as $stage) { |
|
| 289 | + $count += $stage->count_records_to_migrate(); |
|
| 290 | + } |
|
| 291 | + return $count; |
|
| 292 | + } |
|
| 293 | + |
|
| 294 | + |
|
| 295 | + /** |
|
| 296 | + * Returns the number of records updated so far. Usually this is easiest to do |
|
| 297 | + * by just setting a transient and updating it after each migration_step |
|
| 298 | + * |
|
| 299 | + * @return int |
|
| 300 | + */ |
|
| 301 | + public function count_records_migrated() |
|
| 302 | + { |
|
| 303 | + $count = 0; |
|
| 304 | + foreach ($this->stages() as $stage) { |
|
| 305 | + $count += $stage->count_records_migrated(); |
|
| 306 | + } |
|
| 307 | + $this->_records_migrated = $count; |
|
| 308 | + return $count; |
|
| 309 | + } |
|
| 310 | + |
|
| 311 | + |
|
| 312 | + /** |
|
| 313 | + * @param int $num_records_to_migrate_limit |
|
| 314 | + * @return int |
|
| 315 | + * @throws EE_Error |
|
| 316 | + * @throws Exception |
|
| 317 | + */ |
|
| 318 | + public function migration_step($num_records_to_migrate_limit) |
|
| 319 | + { |
|
| 320 | + // reset the feedback message |
|
| 321 | + $this->_feedback_message = ''; |
|
| 322 | + // if we haven't yet done the 1st schema changes, do them now. buffer any output |
|
| 323 | + $this->_maybe_do_schema_changes(true); |
|
| 324 | + |
|
| 325 | + $num_records_actually_migrated = 0; |
|
| 326 | + $records_migrated_per_stage = array(); |
|
| 327 | + // setup the 'stage' variable, which should hold the last run stage of the migration (or none at all if nothing runs) |
|
| 328 | + $stage = null; |
|
| 329 | + // get the next stage that isn't complete |
|
| 330 | + foreach ($this->stages() as $stage) { |
|
| 331 | + if ($stage->get_status() == EE_Data_Migration_Manager::status_continue) { |
|
| 332 | + try { |
|
| 333 | + $records_migrated_during_stage = $stage->migration_step( |
|
| 334 | + $num_records_to_migrate_limit - $num_records_actually_migrated |
|
| 335 | + ); |
|
| 336 | + $num_records_actually_migrated += $records_migrated_during_stage; |
|
| 337 | + $records_migrated_per_stage[ $stage->pretty_name() ] = $records_migrated_during_stage; |
|
| 338 | + } catch (Exception $e) { |
|
| 339 | + // yes if we catch an exception here, we consider that migration stage borked. |
|
| 340 | + $stage->set_status(EE_Data_Migration_Manager::status_fatal_error); |
|
| 341 | + $this->set_status(EE_Data_Migration_Manager::status_fatal_error); |
|
| 342 | + $stage->add_error($e->getMessage() . ". Stack-trace:" . $e->getTraceAsString()); |
|
| 343 | + throw $e; |
|
| 344 | + } |
|
| 345 | + // check that the migration stage didn't mark itself as having a fatal error |
|
| 346 | + if ($stage->is_broken()) { |
|
| 347 | + $this->set_broken(); |
|
| 348 | + throw new EE_Error($stage->get_last_error()); |
|
| 349 | + } |
|
| 350 | + } |
|
| 351 | + // once we've migrated all the number we intended to (possibly from different stages), stop migrating |
|
| 352 | + // or if we had a fatal error |
|
| 353 | + // or if the current script stopped early- its not done, but it's done all it thinks we should do on this step |
|
| 354 | + if ($num_records_actually_migrated >= $num_records_to_migrate_limit |
|
| 355 | + || $stage->is_broken() |
|
| 356 | + || $stage->has_more_to_do() |
|
| 357 | + ) { |
|
| 358 | + break; |
|
| 359 | + } |
|
| 360 | + } |
|
| 361 | + // check if we're all done this data migration... |
|
| 362 | + // which is indicated by being done early AND the last stage claims to be done |
|
| 363 | + if ($stage == null) { |
|
| 364 | + // this migration script apparently has NO stages... which is super weird, but whatever |
|
| 365 | + $this->set_completed(); |
|
| 366 | + $this->_maybe_do_schema_changes(false); |
|
| 367 | + } elseif ($num_records_actually_migrated < $num_records_to_migrate_limit && ! $stage->has_more_to_do()) { |
|
| 368 | + // apparently we're done, because we couldn't migrate the number we intended to |
|
| 369 | + $this->set_completed(); |
|
| 370 | + $this->_update_feedback_message(array_reverse($records_migrated_per_stage)); |
|
| 371 | + // do schema changes for after the migration now |
|
| 372 | + // first double-check we haven't already done this |
|
| 373 | + $this->_maybe_do_schema_changes(false); |
|
| 374 | + } else { |
|
| 375 | + // update feedback message, keeping in mind that we show them with the most recent at the top |
|
| 376 | + $this->_update_feedback_message(array_reverse($records_migrated_per_stage)); |
|
| 377 | + } |
|
| 378 | + return $num_records_actually_migrated; |
|
| 379 | + } |
|
| 380 | + |
|
| 381 | + |
|
| 382 | + /** |
|
| 383 | + * Updates the feedback message according to what was done during this migration stage. |
|
| 384 | + * |
|
| 385 | + * @param array $records_migrated_per_stage KEYS are pretty names for each stage; values are the count of records |
|
| 386 | + * migrated from that stage |
|
| 387 | + * @return void |
|
| 388 | + */ |
|
| 389 | + private function _update_feedback_message($records_migrated_per_stage) |
|
| 390 | + { |
|
| 391 | + $feedback_message_array = array(); |
|
| 392 | + foreach ($records_migrated_per_stage as $migration_stage_name => $num_records_migrated) { |
|
| 393 | + $feedback_message_array[] = sprintf( |
|
| 394 | + __("Migrated %d records successfully during %s", "event_espresso"), |
|
| 395 | + $num_records_migrated, |
|
| 396 | + $migration_stage_name |
|
| 397 | + ); |
|
| 398 | + } |
|
| 399 | + $this->_feedback_message .= implode("<br>", $feedback_message_array); |
|
| 400 | + } |
|
| 401 | + |
|
| 402 | + |
|
| 403 | + /** |
|
| 404 | + * Calls either schema_changes_before_migration() (if $before==true) or schema_changes_after_migration |
|
| 405 | + * (if $before==false). Buffers their outputs and stores them on the class. |
|
| 406 | + * |
|
| 407 | + * @param boolean $before |
|
| 408 | + * @throws Exception |
|
| 409 | + * @return void |
|
| 410 | + */ |
|
| 411 | + private function _maybe_do_schema_changes($before = true) |
|
| 412 | + { |
|
| 413 | + // so this property will be either _schema_changes_after_migration_ran or _schema_changes_before_migration_ran |
|
| 414 | + $property_name = '_schema_changes_' . ($before ? 'before' : 'after') . '_migration_ran'; |
|
| 415 | + if (! $this->{$property_name}) { |
|
| 416 | + try { |
|
| 417 | + ob_start(); |
|
| 418 | + if ($before) { |
|
| 419 | + $this->schema_changes_before_migration(); |
|
| 420 | + } else { |
|
| 421 | + $this->schema_changes_after_migration(); |
|
| 422 | + } |
|
| 423 | + $output = ob_get_contents(); |
|
| 424 | + ob_end_clean(); |
|
| 425 | + } catch (Exception $e) { |
|
| 426 | + $this->set_status(EE_Data_Migration_Manager::status_fatal_error); |
|
| 427 | + throw $e; |
|
| 428 | + } |
|
| 429 | + // record that we've done these schema changes |
|
| 430 | + $this->{$property_name} = true; |
|
| 431 | + // if there were any warnings etc, record them as non-fatal errors |
|
| 432 | + if ($output) { |
|
| 433 | + // there were some warnings |
|
| 434 | + $this->_errors[] = $output; |
|
| 435 | + } |
|
| 436 | + } |
|
| 437 | + } |
|
| 438 | + |
|
| 439 | + |
|
| 440 | + /** |
|
| 441 | + * Wrapper for EEH_Activation::create_table. However, takes into account the request type when |
|
| 442 | + * deciding what to pass for its 4th arg, $drop_pre_existing_tables. Using this function, instead |
|
| 443 | + * of _table_should_exist_previously, indicates that this table should be new to the EE version being migrated to |
|
| 444 | + * or |
|
| 445 | + * activated currently. If this is a brand new activation or a migration, and we're indicating this table should |
|
| 446 | + * not |
|
| 447 | + * previously exist, then we want to set $drop_pre_existing_tables to TRUE (ie, we shouldn't discover that this |
|
| 448 | + * table exists in the DB in EEH_Activation::create_table- if it DOES exist, something's wrong and the old table |
|
| 449 | + * should be nuked. |
|
| 450 | + * |
|
| 451 | + * Just for a bit of context, the migration script's db_schema_changes_* methods |
|
| 452 | + * are called basically in 3 cases: on brand new activation of EE4 (ie no previous version of EE existed and the |
|
| 453 | + * plugin is being activated and we want to add all the brand new tables), upon reactivation of EE4 (it was |
|
| 454 | + * deactivated and then reactivated, in which case we want to just verify the DB structure is ok) that table should |
|
| 455 | + * be dropped), and during a migration when we're moving the DB to the state of the migration script |
|
| 456 | + * |
|
| 457 | + * @param string $table_name |
|
| 458 | + * @param string $table_definition_sql |
|
| 459 | + * @param string $engine_string |
|
| 460 | + */ |
|
| 461 | + protected function _table_is_new_in_this_version( |
|
| 462 | + $table_name, |
|
| 463 | + $table_definition_sql, |
|
| 464 | + $engine_string = 'ENGINE=InnoDB ' |
|
| 465 | + ) { |
|
| 466 | + $this->_create_table_and_catch_errors( |
|
| 467 | + $table_name, |
|
| 468 | + $table_definition_sql, |
|
| 469 | + $engine_string, |
|
| 470 | + $this->_pre_existing_table_should_be_dropped(true) |
|
| 471 | + ); |
|
| 472 | + } |
|
| 473 | + |
|
| 474 | + /** |
|
| 475 | + * Like _table_is_new_in_this_version and _table_should_exist_previously, this function verifies the given table |
|
| 476 | + * exists. But we understand that this table has CHANGED in this version since the previous version. So it's not |
|
| 477 | + * completely new, but it's different. So we need to treat it like a new table in terms of verifying it's schema is |
|
| 478 | + * correct on activations, migrations, upgrades; but if it exists when it shouldn't, we need to be as lenient as |
|
| 479 | + * _table_should_exist_previously. |
|
| 480 | + * 8656]{Assumes only this plugin could have added this table (ie, if its a new activation of this plugin, the |
|
| 481 | + * table shouldn't exist). |
|
| 482 | + * |
|
| 483 | + * @param string $table_name |
|
| 484 | + * @param string $table_definition_sql |
|
| 485 | + * @param string $engine_string |
|
| 486 | + */ |
|
| 487 | + protected function _table_is_changed_in_this_version( |
|
| 488 | + $table_name, |
|
| 489 | + $table_definition_sql, |
|
| 490 | + $engine_string = 'ENGINE=MyISAM' |
|
| 491 | + ) { |
|
| 492 | + $this->_create_table_and_catch_errors( |
|
| 493 | + $table_name, |
|
| 494 | + $table_definition_sql, |
|
| 495 | + $engine_string, |
|
| 496 | + $this->_pre_existing_table_should_be_dropped(false) |
|
| 497 | + ); |
|
| 498 | + } |
|
| 499 | + |
|
| 500 | + |
|
| 501 | + /** |
|
| 502 | + * _old_table_exists |
|
| 503 | + * returns TRUE if the requested table exists in the current database |
|
| 504 | + * |
|
| 505 | + * @param string $table_name |
|
| 506 | + * @return boolean |
|
| 507 | + */ |
|
| 508 | + protected function _old_table_exists($table_name) |
|
| 509 | + { |
|
| 510 | + return $this->_get_table_analysis()->tableExists($table_name); |
|
| 511 | + } |
|
| 512 | + |
|
| 513 | + |
|
| 514 | + /** |
|
| 515 | + * _delete_table_if_empty |
|
| 516 | + * returns TRUE if the requested table was empty and successfully empty |
|
| 517 | + * |
|
| 518 | + * @param string $table_name |
|
| 519 | + * @return boolean |
|
| 520 | + */ |
|
| 521 | + protected function _delete_table_if_empty($table_name) |
|
| 522 | + { |
|
| 523 | + return EEH_Activation::delete_db_table_if_empty($table_name); |
|
| 524 | + } |
|
| 525 | + |
|
| 526 | + |
|
| 527 | + /** |
|
| 528 | + * It is preferred to use _table_has_not_changed_since_previous or _table_is_changed_in_this_version |
|
| 529 | + * as these are significantly more efficient or explicit. |
|
| 530 | + * Please see description of _table_is_new_in_this_version. This function will only set |
|
| 531 | + * EEH_Activation::create_table's $drop_pre_existing_tables to TRUE if it's a brand |
|
| 532 | + * new activation. ie, a more accurate name for this method would be "_table_added_previously_by_this_plugin" |
|
| 533 | + * because the table will be cleared out if this is a new activation (ie, if its a new activation, it actually |
|
| 534 | + * should exist previously). Otherwise, we'll always set $drop_pre_existing_tables to FALSE because the table |
|
| 535 | + * should have existed. Note, if the table is being MODIFIED in this version being activated or migrated to, then |
|
| 536 | + * you want _table_is_changed_in_this_version NOT this one. We don't check this table's structure during migrations |
|
| 537 | + * because apparently it hasn't changed since the previous one, right? |
|
| 538 | + * |
|
| 539 | + * @param string $table_name |
|
| 540 | + * @param string $table_definition_sql |
|
| 541 | + * @param string $engine_string |
|
| 542 | + */ |
|
| 543 | + protected function _table_should_exist_previously( |
|
| 544 | + $table_name, |
|
| 545 | + $table_definition_sql, |
|
| 546 | + $engine_string = 'ENGINE=MyISAM' |
|
| 547 | + ) { |
|
| 548 | + $this->_create_table_and_catch_errors( |
|
| 549 | + $table_name, |
|
| 550 | + $table_definition_sql, |
|
| 551 | + $engine_string, |
|
| 552 | + $this->_pre_existing_table_should_be_dropped(false) |
|
| 553 | + ); |
|
| 554 | + } |
|
| 555 | + |
|
| 556 | + /** |
|
| 557 | + * Exactly the same as _table_should_exist_previously(), except if this migration script is currently doing |
|
| 558 | + * a migration, we skip checking this table's structure in the database and just assume it's correct. |
|
| 559 | + * So this is useful only to improve efficiency when doing migrations (not a big deal for single site installs, |
|
| 560 | + * but important for multisite where migrations can take a very long time otherwise). |
|
| 561 | + * If the table is known to have changed since previous version, use _table_is_changed_in_this_version(). |
|
| 562 | + * Assumes only this plugin could have added this table (ie, if its a new activation of this plugin, the table |
|
| 563 | + * shouldn't exist). |
|
| 564 | + * |
|
| 565 | + * @param string $table_name |
|
| 566 | + * @param string $table_definition_sql |
|
| 567 | + * @param string $engine_string |
|
| 568 | + */ |
|
| 569 | + protected function _table_has_not_changed_since_previous( |
|
| 570 | + $table_name, |
|
| 571 | + $table_definition_sql, |
|
| 572 | + $engine_string = 'ENGINE=MyISAM' |
|
| 573 | + ) { |
|
| 574 | + if ($this->_currently_migrating()) { |
|
| 575 | + // if we're doing a migration, and this table apparently already exists, then we don't need do anything right? |
|
| 576 | + return; |
|
| 577 | + } |
|
| 578 | + $this->_create_table_and_catch_errors( |
|
| 579 | + $table_name, |
|
| 580 | + $table_definition_sql, |
|
| 581 | + $engine_string, |
|
| 582 | + $this->_pre_existing_table_should_be_dropped(false) |
|
| 583 | + ); |
|
| 584 | + } |
|
| 585 | + |
|
| 586 | + /** |
|
| 587 | + * Returns whether or not this migration script is being used as part of an actual migration |
|
| 588 | + * |
|
| 589 | + * @return boolean |
|
| 590 | + */ |
|
| 591 | + protected function _currently_migrating() |
|
| 592 | + { |
|
| 593 | + // 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) |
|
| 594 | + return $this->_migrating && |
|
| 595 | + $this->can_migrate_from_version( |
|
| 596 | + EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set() |
|
| 597 | + ) && |
|
| 598 | + EE_Maintenance_Mode::instance()->real_level() == EE_Maintenance_Mode::level_2_complete_maintenance; |
|
| 599 | + } |
|
| 600 | + |
|
| 601 | + /** |
|
| 602 | + * Determines if a table should be dropped, based on whether it's reported to be new in $table_is_new, |
|
| 603 | + * and the plugin's request type. |
|
| 604 | + * Assumes only this plugin could have added the table (ie, if its a new activation of this plugin, the table |
|
| 605 | + * shouldn't exist no matter what). |
|
| 606 | + * |
|
| 607 | + * @param boolean $table_is_new |
|
| 608 | + * @return boolean |
|
| 609 | + */ |
|
| 610 | + protected function _pre_existing_table_should_be_dropped($table_is_new) |
|
| 611 | + { |
|
| 612 | + if ($table_is_new) { |
|
| 613 | + if ($this->_get_req_type_for_plugin_corresponding_to_this_dms() == EE_System::req_type_new_activation |
|
| 614 | + || $this->_currently_migrating() |
|
| 615 | + ) { |
|
| 616 | + return true; |
|
| 617 | + } else { |
|
| 618 | + return false; |
|
| 619 | + } |
|
| 620 | + } else { |
|
| 621 | + if (in_array( |
|
| 622 | + $this->_get_req_type_for_plugin_corresponding_to_this_dms(), |
|
| 623 | + array(EE_System::req_type_new_activation) |
|
| 624 | + )) { |
|
| 625 | + return true; |
|
| 626 | + } else { |
|
| 627 | + return false; |
|
| 628 | + } |
|
| 629 | + } |
|
| 630 | + } |
|
| 631 | + |
|
| 632 | + /** |
|
| 633 | + * Just wraps EEH_Activation::create_table, but catches any errors it may throw and adds them as errors on the DMS |
|
| 634 | + * |
|
| 635 | + * @param string $table_name |
|
| 636 | + * @param string $table_definition_sql |
|
| 637 | + * @param string $engine_string |
|
| 638 | + * @param boolean $drop_pre_existing_tables |
|
| 639 | + */ |
|
| 640 | + private function _create_table_and_catch_errors( |
|
| 641 | + $table_name, |
|
| 642 | + $table_definition_sql, |
|
| 643 | + $engine_string = 'ENGINE=MyISAM', |
|
| 644 | + $drop_pre_existing_tables = false |
|
| 645 | + ) { |
|
| 646 | + try { |
|
| 647 | + EEH_Activation::create_table($table_name, $table_definition_sql, $engine_string, $drop_pre_existing_tables); |
|
| 648 | + } catch (EE_Error $e) { |
|
| 649 | + $message = $e->getMessage() . '<br>Stack Trace:' . $e->getTraceAsString(); |
|
| 650 | + $this->add_error($message); |
|
| 651 | + $this->_feedback_message .= $message; |
|
| 652 | + } |
|
| 653 | + } |
|
| 654 | + |
|
| 655 | + |
|
| 656 | + /** |
|
| 657 | + * Gets the request type for the plugin (core or addon) that corresponds to this DMS |
|
| 658 | + * |
|
| 659 | + * @return int one of EE_System::_req_type_* constants |
|
| 660 | + * @throws EE_Error |
|
| 661 | + */ |
|
| 662 | + private function _get_req_type_for_plugin_corresponding_to_this_dms() |
|
| 663 | + { |
|
| 664 | + if ($this->slug() == 'Core') { |
|
| 665 | + return EE_System::instance()->detect_req_type(); |
|
| 666 | + } else {// it must be for an addon |
|
| 667 | + $addon_name = $this->slug(); |
|
| 668 | + if (EE_Registry::instance()->get_addon_by_name($addon_name)) { |
|
| 669 | + return EE_Registry::instance()->get_addon_by_name($addon_name)->detect_req_type(); |
|
| 670 | + } else { |
|
| 671 | + throw new EE_Error( |
|
| 672 | + sprintf( |
|
| 673 | + __( |
|
| 674 | + "The DMS slug '%s' should correspond to the addon's name, which should also be '%s', but no such addon was registered. These are the registered addons' names: %s", |
|
| 675 | + "event_espresso" |
|
| 676 | + ), |
|
| 677 | + $this->slug(), |
|
| 678 | + $addon_name, |
|
| 679 | + implode(",", array_keys(EE_Registry::instance()->get_addons_by_name())) |
|
| 680 | + ) |
|
| 681 | + ); |
|
| 682 | + } |
|
| 683 | + } |
|
| 684 | + } |
|
| 685 | + |
|
| 686 | + |
|
| 687 | + /** |
|
| 688 | + * returns an array of strings describing errors by all the script's stages |
|
| 689 | + * |
|
| 690 | + * @return array |
|
| 691 | + */ |
|
| 692 | + public function get_errors() |
|
| 693 | + { |
|
| 694 | + $all_errors = $this->_errors; |
|
| 695 | + if (! is_array($all_errors)) { |
|
| 696 | + $all_errors = array(); |
|
| 697 | + } |
|
| 698 | + foreach ($this->stages() as $stage) { |
|
| 699 | + $all_errors = array_merge($stage->get_errors(), $all_errors); |
|
| 700 | + } |
|
| 701 | + return $all_errors; |
|
| 702 | + } |
|
| 703 | + |
|
| 704 | + |
|
| 705 | + /** |
|
| 706 | + * Indicates whether or not this migration script should continue |
|
| 707 | + * |
|
| 708 | + * @return boolean |
|
| 709 | + */ |
|
| 710 | + public function can_continue() |
|
| 711 | + { |
|
| 712 | + return in_array( |
|
| 713 | + $this->get_status(), |
|
| 714 | + EE_Data_Migration_Manager::instance()->stati_that_indicate_to_continue_single_migration_script |
|
| 715 | + ); |
|
| 716 | + } |
|
| 717 | + |
|
| 718 | + |
|
| 719 | + /** |
|
| 720 | + * Gets all the data migration stages associated with this script. Note: |
|
| 721 | + * addons can filter this list to add their own stages, and because the list is |
|
| 722 | + * numerically-indexed, they can insert their stage wherever they like and it will |
|
| 723 | + * get ordered by the indexes |
|
| 724 | + * |
|
| 725 | + * @return EE_Data_Migration_Script_Stage[] |
|
| 726 | + */ |
|
| 727 | + protected function stages() |
|
| 728 | + { |
|
| 729 | + $stages = apply_filters('FHEE__' . get_class($this) . '__stages', $this->_migration_stages); |
|
| 730 | + ksort($stages); |
|
| 731 | + return $stages; |
|
| 732 | + } |
|
| 733 | + |
|
| 734 | + |
|
| 735 | + /** |
|
| 736 | + * Gets a string which should describe what's going on currently with this migration, which |
|
| 737 | + * can be displayed to the user |
|
| 738 | + * |
|
| 739 | + * @return string |
|
| 740 | + */ |
|
| 741 | + public function get_feedback_message() |
|
| 742 | + { |
|
| 743 | + return $this->_feedback_message; |
|
| 744 | + } |
|
| 745 | + |
|
| 746 | + |
|
| 747 | + /** |
|
| 748 | + * A lot like "__sleep()" magic method in purpose, this is meant for persisting this class' |
|
| 749 | + * properties to the DB. However, we don't want to use __sleep() because its quite |
|
| 750 | + * possible that this class is defined when it goes to sleep, but NOT available when it |
|
| 751 | + * awakes (eg, this class is part of an addon that is deactivated at some point). |
|
| 752 | + */ |
|
| 753 | + public function properties_as_array() |
|
| 754 | + { |
|
| 755 | + $properties = parent::properties_as_array(); |
|
| 756 | + $properties['_migration_stages'] = array(); |
|
| 757 | + foreach ($this->_migration_stages as $migration_stage_priority => $migration_stage_class) { |
|
| 758 | + $properties['_migration_stages'][ $migration_stage_priority ] = $migration_stage_class->properties_as_array( |
|
| 759 | + ); |
|
| 760 | + } |
|
| 761 | + unset($properties['_mappings']); |
|
| 762 | + |
|
| 763 | + foreach ($this->_mappings as $old_table_name => $mapping_to_new_table) { |
|
| 764 | + foreach ($mapping_to_new_table as $new_table_name => $mapping) { |
|
| 765 | + $this->_set_mapping_option($old_table_name, $new_table_name, $mapping); |
|
| 766 | + } |
|
| 767 | + } |
|
| 768 | + return $properties; |
|
| 769 | + } |
|
| 770 | + |
|
| 771 | + |
|
| 772 | + /** |
|
| 773 | + * Sets all of the properties of this script stage to match what's in the array, which is assumed |
|
| 774 | + * to have been made from the properties_as_array() function. |
|
| 775 | + * |
|
| 776 | + * @param array $array_of_properties like what's produced from properties_as_array() method |
|
| 777 | + * @return void |
|
| 778 | + */ |
|
| 779 | + public function instantiate_from_array_of_properties($array_of_properties) |
|
| 780 | + { |
|
| 781 | + $stages_properties_arrays = $array_of_properties['_migration_stages']; |
|
| 782 | + unset($array_of_properties['_migration_stages']); |
|
| 783 | + unset($array_of_properties['class']); |
|
| 784 | + foreach ($array_of_properties as $property_name => $property_value) { |
|
| 785 | + $this->{$property_name} = $property_value; |
|
| 786 | + } |
|
| 787 | + // _migration_stages are already instantiated, but have only default data |
|
| 788 | + foreach ($this->_migration_stages as $stage) { |
|
| 789 | + $stage_data = $this->_find_migration_stage_data_with_classname( |
|
| 790 | + get_class($stage), |
|
| 791 | + $stages_properties_arrays |
|
| 792 | + ); |
|
| 793 | + // SO, if we found the stage data that was saved, use it. Otherwise, I guess the stage is new? (maybe added by |
|
| 794 | + // an addon? Unlikely... not sure why it wouldn't exist, but if it doesn't just treat it like it was never started yet) |
|
| 795 | + if ($stage_data) { |
|
| 796 | + $stage->instantiate_from_array_of_properties($stage_data); |
|
| 797 | + } |
|
| 798 | + } |
|
| 799 | + } |
|
| 800 | + |
|
| 801 | + |
|
| 802 | + /** |
|
| 803 | + * Gets the migration data from the array $migration_stage_data_arrays (which is an array of arrays, each of which |
|
| 804 | + * is pretty well identical to EE_Data_Migration_Stage objects except all their properties are array indexes) |
|
| 805 | + * for the given classname |
|
| 806 | + * |
|
| 807 | + * @param string $classname |
|
| 808 | + * @param array $migration_stage_data_arrays |
|
| 809 | + * @return null |
|
| 810 | + */ |
|
| 811 | + private function _find_migration_stage_data_with_classname($classname, $migration_stage_data_arrays) |
|
| 812 | + { |
|
| 813 | + foreach ($migration_stage_data_arrays as $migration_stage_data_array) { |
|
| 814 | + if (isset($migration_stage_data_array['class']) && $migration_stage_data_array['class'] == $classname) { |
|
| 815 | + return $migration_stage_data_array; |
|
| 816 | + } |
|
| 817 | + } |
|
| 818 | + return null; |
|
| 819 | + } |
|
| 820 | + |
|
| 821 | + |
|
| 822 | + /** |
|
| 823 | + * Returns the version that this script migrates to, based on the script's name. |
|
| 824 | + * Cannot be overwritten because lots of code needs to know which version a script |
|
| 825 | + * migrates to knowing only its name. |
|
| 826 | + * |
|
| 827 | + * @return array where the first key is the plugin's slug, the 2nd is the version of that plugin |
|
| 828 | + * that will be updated to. Eg array('Core','4.1.0') |
|
| 829 | + */ |
|
| 830 | + final public function migrates_to_version() |
|
| 831 | + { |
|
| 832 | + return EE_Data_Migration_Manager::instance()->script_migrates_to_version(get_class($this)); |
|
| 833 | + } |
|
| 834 | + |
|
| 835 | + |
|
| 836 | + /** |
|
| 837 | + * Gets this addon's slug as it would appear in the current_db_state wp option, |
|
| 838 | + * and if this migration script is for an addon, it SHOULD match the addon's slug |
|
| 839 | + * (and also the addon's classname, minus the 'EE_' prefix.). Eg, 'Calendar' for the EE_Calendar addon. |
|
| 840 | + * Or 'Core' for core (non-addon). |
|
| 841 | + * |
|
| 842 | + * @return string |
|
| 843 | + */ |
|
| 844 | + public function slug() |
|
| 845 | + { |
|
| 846 | + $migrates_to_version_info = $this->migrates_to_version(); |
|
| 847 | + // the slug is the first part of the array |
|
| 848 | + return $migrates_to_version_info['slug']; |
|
| 849 | + } |
|
| 850 | + |
|
| 851 | + |
|
| 852 | + /** |
|
| 853 | + * Returns the script's priority relative to DMSs from other addons. However, when |
|
| 854 | + * two DMSs from the same addon/core apply, this is ignored (and instead the version that |
|
| 855 | + * the script migrates to is used to determine which to run first). The default is 5, but all core DMSs |
|
| 856 | + * normally have priority 10. (So if you want a DMS "A" to run before DMS "B", both of which are from addons, |
|
| 857 | + * and both of which CAN run at the same time (ie, "B" doesn't depend on "A" to set |
|
| 858 | + * the database up so it can run), then you can set "A" to priority 3 or something. |
|
| 859 | + * |
|
| 860 | + * @return int |
|
| 861 | + */ |
|
| 862 | + public function priority() |
|
| 863 | + { |
|
| 864 | + return $this->_priority; |
|
| 865 | + } |
|
| 866 | + |
|
| 867 | + |
|
| 868 | + /** |
|
| 869 | + * Sets whether or not this DMS is being ran as part of a migration, instead of |
|
| 870 | + * just being used to setup (or verify) the current database structure matches |
|
| 871 | + * what the latest DMS indicates it should be |
|
| 872 | + * |
|
| 873 | + * @param boolean $migrating |
|
| 874 | + * @return void |
|
| 875 | + */ |
|
| 876 | + public function set_migrating($migrating = true) |
|
| 877 | + { |
|
| 878 | + $this->_migrating = $migrating; |
|
| 879 | + } |
|
| 880 | + |
|
| 881 | + /** |
|
| 882 | + * Marks that we think this migration class can continue to migrate |
|
| 883 | + */ |
|
| 884 | + public function reattempt() |
|
| 885 | + { |
|
| 886 | + parent::reattempt(); |
|
| 887 | + // also, we want to reattempt any stages that were marked as borked |
|
| 888 | + foreach ($this->stages() as $stage) { |
|
| 889 | + if ($stage->is_broken()) { |
|
| 890 | + $stage->reattempt(); |
|
| 891 | + } |
|
| 892 | + } |
|
| 893 | + } |
|
| 894 | 894 | } |