Completed
Branch EDTR/refactor-master (e18acd)
by
unknown
11:03 queued 02:08
created
core/admin/EE_Admin_Page.core.php 3 patches
Doc Comments   +6 added lines, -3 removed lines patch added patch discarded remove patch
@@ -798,6 +798,9 @@  discard block
 block discarded – undo
798 798
     }
799 799
 
800 800
 
801
+    /**
802
+     * @param string $wp_page_slug
803
+     */
801 804
     public function set_wp_page_slug($wp_page_slug)
802 805
     {
803 806
         $this->_wp_page_slug = $wp_page_slug;
@@ -899,7 +902,7 @@  discard block
 block discarded – undo
899 902
      * this method simply verifies a given route and makes sure its an actual route available for the loaded page
900 903
      *
901 904
      * @param  string $route the route name we're verifying
902
-     * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
905
+     * @return boolean (bool|Exception)      we'll throw an exception if this isn't a valid route.
903 906
      * @throws EE_Error
904 907
      */
905 908
     protected function _verify_route($route)
@@ -4049,7 +4052,7 @@  discard block
 block discarded – undo
4049 4052
 
4050 4053
 
4051 4054
     /**
4052
-     * @return mixed
4055
+     * @return string[]
4053 4056
      */
4054 4057
     public function default_espresso_metaboxes()
4055 4058
     {
@@ -4067,7 +4070,7 @@  discard block
 block discarded – undo
4067 4070
 
4068 4071
 
4069 4072
     /**
4070
-     * @return mixed
4073
+     * @return string
4071 4074
      */
4072 4075
     public function wp_page_slug()
4073 4076
     {
Please login to merge, or discard this patch.
Spacing   +186 added lines, -186 removed lines patch added patch discarded remove patch
@@ -515,7 +515,7 @@  discard block
 block discarded – undo
515 515
         );
516 516
         global $ee_menu_slugs;
517 517
         $ee_menu_slugs = (array) $ee_menu_slugs;
518
-        if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
518
+        if ( ! defined('DOING_AJAX') && ( ! $this->_current_page || ! isset($ee_menu_slugs[$this->_current_page]))) {
519 519
             return;
520 520
         }
521 521
         // 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
@@ -539,7 +539,7 @@  discard block
 block discarded – undo
539 539
             ? $this->_req_data['route']
540 540
             : $this->_req_action;
541 541
         $this->_current_view = $this->_req_action;
542
-        $this->_req_nonce = $this->_req_action . '_nonce';
542
+        $this->_req_nonce = $this->_req_action.'_nonce';
543 543
         $this->_define_page_props();
544 544
         $this->_current_page_view_url = add_query_arg(
545 545
             array('page' => $this->_current_page, 'action' => $this->_current_view),
@@ -573,21 +573,21 @@  discard block
 block discarded – undo
573 573
         }
574 574
         // filter routes and page_config so addons can add their stuff. Filtering done per class
575 575
         $this->_page_routes = apply_filters(
576
-            'FHEE__' . get_class($this) . '__page_setup__page_routes',
576
+            'FHEE__'.get_class($this).'__page_setup__page_routes',
577 577
             $this->_page_routes,
578 578
             $this
579 579
         );
580 580
         $this->_page_config = apply_filters(
581
-            'FHEE__' . get_class($this) . '__page_setup__page_config',
581
+            'FHEE__'.get_class($this).'__page_setup__page_config',
582 582
             $this->_page_config,
583 583
             $this
584 584
         );
585 585
         // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
586 586
         // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
587
-        if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
587
+        if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view)) {
588 588
             add_action(
589 589
                 'AHEE__EE_Admin_Page__route_admin_request',
590
-                array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
590
+                array($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view),
591 591
                 10,
592 592
                 2
593 593
             );
@@ -600,8 +600,8 @@  discard block
 block discarded – undo
600 600
             if ($this->_is_UI_request) {
601 601
                 // admin_init stuff - global, all views for this page class, specific view
602 602
                 add_action('admin_init', array($this, 'admin_init'), 10);
603
-                if (method_exists($this, 'admin_init_' . $this->_current_view)) {
604
-                    add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
603
+                if (method_exists($this, 'admin_init_'.$this->_current_view)) {
604
+                    add_action('admin_init', array($this, 'admin_init_'.$this->_current_view), 15);
605 605
                 }
606 606
             } else {
607 607
                 // hijack regular WP loading and route admin request immediately
@@ -621,12 +621,12 @@  discard block
 block discarded – undo
621 621
      */
622 622
     private function _do_other_page_hooks()
623 623
     {
624
-        $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
624
+        $registered_pages = apply_filters('FHEE_do_other_page_hooks_'.$this->page_slug, array());
625 625
         foreach ($registered_pages as $page) {
626 626
             // now let's setup the file name and class that should be present
627 627
             $classname = str_replace('.class.php', '', $page);
628 628
             // autoloaders should take care of loading file
629
-            if (! class_exists($classname)) {
629
+            if ( ! class_exists($classname)) {
630 630
                 $error_msg[] = sprintf(
631 631
                     esc_html__(
632 632
                         'Something went wrong with loading the %s admin hooks page.',
@@ -643,7 +643,7 @@  discard block
 block discarded – undo
643 643
                                    ),
644 644
                                    $page,
645 645
                                    '<br />',
646
-                                   '<strong>' . $classname . '</strong>'
646
+                                   '<strong>'.$classname.'</strong>'
647 647
                                );
648 648
                 throw new EE_Error(implode('||', $error_msg));
649 649
             }
@@ -691,13 +691,13 @@  discard block
 block discarded – undo
691 691
         // load admin_notices - global, page class, and view specific
692 692
         add_action('admin_notices', array($this, 'admin_notices_global'), 5);
693 693
         add_action('admin_notices', array($this, 'admin_notices'), 10);
694
-        if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
695
-            add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
694
+        if (method_exists($this, 'admin_notices_'.$this->_current_view)) {
695
+            add_action('admin_notices', array($this, 'admin_notices_'.$this->_current_view), 15);
696 696
         }
697 697
         // load network admin_notices - global, page class, and view specific
698 698
         add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
699
-        if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
700
-            add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
699
+        if (method_exists($this, 'network_admin_notices_'.$this->_current_view)) {
700
+            add_action('network_admin_notices', array($this, 'network_admin_notices_'.$this->_current_view));
701 701
         }
702 702
         // this will save any per_page screen options if they are present
703 703
         $this->_set_per_page_screen_options();
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
      */
819 819
     protected function _verify_routes()
820 820
     {
821
-        if (! $this->_current_page && ! defined('DOING_AJAX')) {
821
+        if ( ! $this->_current_page && ! defined('DOING_AJAX')) {
822 822
             return false;
823 823
         }
824 824
         $this->_route = false;
@@ -830,7 +830,7 @@  discard block
 block discarded – undo
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
                           . esc_html__(
835 835
                               ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
836 836
                               'event_espresso'
@@ -839,9 +839,9 @@  discard block
 block discarded – undo
839 839
         }
840 840
         // and that the requested page route exists
841 841
         if (array_key_exists($this->_req_action, $this->_page_routes)) {
842
-            $this->_route = $this->_page_routes[ $this->_req_action ];
843
-            $this->_route_config = isset($this->_page_config[ $this->_req_action ])
844
-                ? $this->_page_config[ $this->_req_action ] : array();
842
+            $this->_route = $this->_page_routes[$this->_req_action];
843
+            $this->_route_config = isset($this->_page_config[$this->_req_action])
844
+                ? $this->_page_config[$this->_req_action] : array();
845 845
         } else {
846 846
             // user error msg
847 847
             $error_msg = sprintf(
@@ -852,7 +852,7 @@  discard block
 block discarded – undo
852 852
                 $this->_admin_page_title
853 853
             );
854 854
             // developer error msg
855
-            $error_msg .= '||' . $error_msg
855
+            $error_msg .= '||'.$error_msg
856 856
                           . sprintf(
857 857
                               esc_html__(
858 858
                                   ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
             throw new EE_Error($error_msg);
864 864
         }
865 865
         // and that a default route exists
866
-        if (! array_key_exists('default', $this->_page_routes)) {
866
+        if ( ! array_key_exists('default', $this->_page_routes)) {
867 867
             // user error msg
868 868
             $error_msg = sprintf(
869 869
                 esc_html__(
@@ -873,7 +873,7 @@  discard block
 block discarded – undo
873 873
                 $this->_admin_page_title
874 874
             );
875 875
             // developer error msg
876
-            $error_msg .= '||' . $error_msg
876
+            $error_msg .= '||'.$error_msg
877 877
                           . esc_html__(
878 878
                               ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
879 879
                               'event_espresso'
@@ -913,7 +913,7 @@  discard block
 block discarded – undo
913 913
             $this->_admin_page_title
914 914
         );
915 915
         // developer error msg
916
-        $error_msg .= '||' . $error_msg
916
+        $error_msg .= '||'.$error_msg
917 917
                       . sprintf(
918 918
                           esc_html__(
919 919
                               ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
@@ -941,7 +941,7 @@  discard block
 block discarded – undo
941 941
     protected function _verify_nonce($nonce, $nonce_ref)
942 942
     {
943 943
         // verify nonce against expected value
944
-        if (! wp_verify_nonce($nonce, $nonce_ref)) {
944
+        if ( ! wp_verify_nonce($nonce, $nonce_ref)) {
945 945
             // these are not the droids you are looking for !!!
946 946
             $msg = sprintf(
947 947
                 esc_html__('%sNonce Fail.%s', 'event_espresso'),
@@ -958,7 +958,7 @@  discard block
 block discarded – undo
958 958
                             __CLASS__
959 959
                         );
960 960
             }
961
-            if (! defined('DOING_AJAX')) {
961
+            if ( ! defined('DOING_AJAX')) {
962 962
                 wp_die($msg);
963 963
             } else {
964 964
                 EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
@@ -983,7 +983,7 @@  discard block
 block discarded – undo
983 983
      */
984 984
     protected function _route_admin_request()
985 985
     {
986
-        if (! $this->_is_UI_request) {
986
+        if ( ! $this->_is_UI_request) {
987 987
             $this->_verify_routes();
988 988
         }
989 989
         $nonce_check = isset($this->_route_config['require_nonce'])
@@ -991,8 +991,8 @@  discard block
 block discarded – undo
991 991
             : true;
992 992
         if ($this->_req_action !== 'default' && $nonce_check) {
993 993
             // set nonce from post data
994
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
995
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
994
+            $nonce = isset($this->_req_data[$this->_req_nonce])
995
+                ? sanitize_text_field($this->_req_data[$this->_req_nonce])
996 996
                 : '';
997 997
             $this->_verify_nonce($nonce, $this->_req_nonce);
998 998
         }
@@ -1007,7 +1007,7 @@  discard block
 block discarded – undo
1007 1007
         $error_msg = '';
1008 1008
         // action right before calling route
1009 1009
         // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1010
-        if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1010
+        if ( ! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1011 1011
             do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1012 1012
         }
1013 1013
         // right before calling the route, let's remove _wp_http_referer from the
@@ -1016,7 +1016,7 @@  discard block
 block discarded – undo
1016 1016
             '_wp_http_referer',
1017 1017
             wp_unslash($_SERVER['REQUEST_URI'])
1018 1018
         );
1019
-        if (! empty($func)) {
1019
+        if ( ! empty($func)) {
1020 1020
             if (is_array($func)) {
1021 1021
                 list($class, $method) = $func;
1022 1022
             } elseif (strpos($func, '::') !== false) {
@@ -1025,7 +1025,7 @@  discard block
 block discarded – undo
1025 1025
                 $class = $this;
1026 1026
                 $method = $func;
1027 1027
             }
1028
-            if (! (is_object($class) && $class === $this)) {
1028
+            if ( ! (is_object($class) && $class === $this)) {
1029 1029
                 // send along this admin page object for access by addons.
1030 1030
                 $args['admin_page_object'] = $this;
1031 1031
             }
@@ -1058,7 +1058,7 @@  discard block
 block discarded – undo
1058 1058
                     $method
1059 1059
                 );
1060 1060
             }
1061
-            if (! empty($error_msg)) {
1061
+            if ( ! empty($error_msg)) {
1062 1062
                 throw new EE_Error($error_msg);
1063 1063
             }
1064 1064
         }
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
                 if (strpos($key, 'nonce') !== false) {
1142 1142
                     continue;
1143 1143
                 }
1144
-                $args[ 'wp_referer[' . $key . ']' ] = $value;
1144
+                $args['wp_referer['.$key.']'] = $value;
1145 1145
             }
1146 1146
         }
1147 1147
         return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
@@ -1181,10 +1181,10 @@  discard block
 block discarded – undo
1181 1181
     protected function _add_help_tabs()
1182 1182
     {
1183 1183
         $tour_buttons = '';
1184
-        if (isset($this->_page_config[ $this->_req_action ])) {
1185
-            $config = $this->_page_config[ $this->_req_action ];
1184
+        if (isset($this->_page_config[$this->_req_action])) {
1185
+            $config = $this->_page_config[$this->_req_action];
1186 1186
             // is there a help tour for the current route?  if there is let's setup the tour buttons
1187
-            if (isset($this->_help_tour[ $this->_req_action ])) {
1187
+            if (isset($this->_help_tour[$this->_req_action])) {
1188 1188
                 $tb = array();
1189 1189
                 $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1190 1190
                 foreach ($this->_help_tour['tours'] as $tour) {
@@ -1204,7 +1204,7 @@  discard block
 block discarded – undo
1204 1204
             // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1205 1205
             if (is_array($config) && isset($config['help_sidebar'])) {
1206 1206
                 // check that the callback given is valid
1207
-                if (! method_exists($this, $config['help_sidebar'])) {
1207
+                if ( ! method_exists($this, $config['help_sidebar'])) {
1208 1208
                     throw new EE_Error(
1209 1209
                         sprintf(
1210 1210
                             esc_html__(
@@ -1217,7 +1217,7 @@  discard block
 block discarded – undo
1217 1217
                     );
1218 1218
                 }
1219 1219
                 $content = apply_filters(
1220
-                    'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1220
+                    'FHEE__'.get_class($this).'__add_help_tabs__help_sidebar',
1221 1221
                     $this->{$config['help_sidebar']}()
1222 1222
                 );
1223 1223
                 $content .= $tour_buttons; // add help tour buttons.
@@ -1225,30 +1225,30 @@  discard block
 block discarded – undo
1225 1225
                 $this->_current_screen->set_help_sidebar($content);
1226 1226
             }
1227 1227
             // if there ARE tour buttons...
1228
-            if (! empty($tour_buttons)) {
1228
+            if ( ! empty($tour_buttons)) {
1229 1229
                 // if we DON'T have config help sidebar then we'll just add the tour buttons to the sidebar.
1230
-                if (! isset($config['help_sidebar'])) {
1230
+                if ( ! isset($config['help_sidebar'])) {
1231 1231
                     $this->_current_screen->set_help_sidebar($tour_buttons);
1232 1232
                 }
1233 1233
                 // handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1234
-                if (! isset($config['help_tabs'])) {
1234
+                if ( ! isset($config['help_tabs'])) {
1235 1235
                     $_ht['id'] = $this->page_slug;
1236 1236
                     $_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1237 1237
                     $_ht['content'] = '<p>'
1238 1238
                                       . esc_html__(
1239 1239
                                           'The buttons to the right allow you to start/restart any help tours available for this page',
1240 1240
                                           'event_espresso'
1241
-                                      ) . '</p>';
1241
+                                      ).'</p>';
1242 1242
                     $this->_current_screen->add_help_tab($_ht);
1243 1243
                 }
1244 1244
             }
1245
-            if (! isset($config['help_tabs'])) {
1245
+            if ( ! isset($config['help_tabs'])) {
1246 1246
                 return;
1247 1247
             } //no help tabs for this route
1248 1248
             foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1249 1249
                 // we're here so there ARE help tabs!
1250 1250
                 // make sure we've got what we need
1251
-                if (! isset($cfg['title'])) {
1251
+                if ( ! isset($cfg['title'])) {
1252 1252
                     throw new EE_Error(
1253 1253
                         esc_html__(
1254 1254
                             'The _page_config array is not set up properly for help tabs.  It is missing a title',
@@ -1256,7 +1256,7 @@  discard block
 block discarded – undo
1256 1256
                         )
1257 1257
                     );
1258 1258
                 }
1259
-                if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1259
+                if ( ! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1260 1260
                     throw new EE_Error(
1261 1261
                         esc_html__(
1262 1262
                             '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',
@@ -1265,11 +1265,11 @@  discard block
 block discarded – undo
1265 1265
                     );
1266 1266
                 }
1267 1267
                 // first priority goes to content.
1268
-                if (! empty($cfg['content'])) {
1268
+                if ( ! empty($cfg['content'])) {
1269 1269
                     $content = ! empty($cfg['content']) ? $cfg['content'] : null;
1270 1270
                     // second priority goes to filename
1271
-                } elseif (! empty($cfg['filename'])) {
1272
-                    $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1271
+                } elseif ( ! empty($cfg['filename'])) {
1272
+                    $file_path = $this->_get_dir().'/help_tabs/'.$cfg['filename'].'.help_tab.php';
1273 1273
                     // 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)
1274 1274
                     $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1275 1275
                                                              . basename($this->_get_dir())
@@ -1277,7 +1277,7 @@  discard block
 block discarded – undo
1277 1277
                                                              . $cfg['filename']
1278 1278
                                                              . '.help_tab.php' : $file_path;
1279 1279
                     // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1280
-                    if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1280
+                    if ( ! isset($cfg['callback']) && ! is_readable($file_path)) {
1281 1281
                         EE_Error::add_error(
1282 1282
                             sprintf(
1283 1283
                                 esc_html__(
@@ -1323,7 +1323,7 @@  discard block
 block discarded – undo
1323 1323
                     return;
1324 1324
                 }
1325 1325
                 // setup config array for help tab method
1326
-                $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1326
+                $id = $this->page_slug.'-'.$this->_req_action.'-'.$tab_id;
1327 1327
                 $_ht = array(
1328 1328
                     'id'       => $id,
1329 1329
                     'title'    => $cfg['title'],
@@ -1367,7 +1367,7 @@  discard block
 block discarded – undo
1367 1367
             }
1368 1368
             if (isset($config['help_tour'])) {
1369 1369
                 foreach ($config['help_tour'] as $tour) {
1370
-                    $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1370
+                    $file_path = $this->_get_dir().'/help_tours/'.$tour.'.class.php';
1371 1371
                     // let's see if we can get that file...
1372 1372
                     // if not its possible this is a decaf route not set in caffeinated
1373 1373
                     // so lets try and get the caffeinated equivalent
@@ -1377,7 +1377,7 @@  discard block
 block discarded – undo
1377 1377
                                                              . $tour
1378 1378
                                                              . '.class.php' : $file_path;
1379 1379
                     // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1380
-                    if (! is_readable($file_path)) {
1380
+                    if ( ! is_readable($file_path)) {
1381 1381
                         EE_Error::add_error(
1382 1382
                             sprintf(
1383 1383
                                 esc_html__(
@@ -1394,12 +1394,12 @@  discard block
 block discarded – undo
1394 1394
                         return;
1395 1395
                     }
1396 1396
                     require_once $file_path;
1397
-                    if (! class_exists($tour)) {
1397
+                    if ( ! class_exists($tour)) {
1398 1398
                         $error_msg[] = sprintf(
1399 1399
                             esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1400 1400
                             $tour
1401 1401
                         );
1402
-                        $error_msg[] = $error_msg[0] . "\r\n"
1402
+                        $error_msg[] = $error_msg[0]."\r\n"
1403 1403
                                        . sprintf(
1404 1404
                                            esc_html__(
1405 1405
                                                '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.',
@@ -1415,16 +1415,16 @@  discard block
 block discarded – undo
1415 1415
                     }
1416 1416
                     $tour_obj = new $tour($this->_is_caf);
1417 1417
                     $tours[] = $tour_obj;
1418
-                    $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1418
+                    $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($tour_obj);
1419 1419
                 }
1420 1420
                 // let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1421 1421
                 $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1422 1422
                 $tours[] = $end_stop_tour;
1423
-                $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1423
+                $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1424 1424
             }
1425 1425
         }
1426 1426
 
1427
-        if (! empty($tours)) {
1427
+        if ( ! empty($tours)) {
1428 1428
             $this->_help_tour['tours'] = $tours;
1429 1429
         }
1430 1430
         // that's it!  Now that the $_help_tours property is set (or not)
@@ -1450,8 +1450,8 @@  discard block
 block discarded – undo
1450 1450
             $qtips = (array) $this->_route_config['qtips'];
1451 1451
             // load qtip loader
1452 1452
             $path = array(
1453
-                $this->_get_dir() . '/qtips/',
1454
-                EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1453
+                $this->_get_dir().'/qtips/',
1454
+                EE_ADMIN_PAGES.basename($this->_get_dir()).'/qtips/',
1455 1455
             );
1456 1456
             EEH_Qtip_Loader::instance()->register($qtips, $path);
1457 1457
         }
@@ -1473,7 +1473,7 @@  discard block
 block discarded – undo
1473 1473
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1474 1474
         $i = 0;
1475 1475
         foreach ($this->_page_config as $slug => $config) {
1476
-            if (! is_array($config)
1476
+            if ( ! is_array($config)
1477 1477
                 || (
1478 1478
                     is_array($config)
1479 1479
                     && (
@@ -1490,12 +1490,12 @@  discard block
 block discarded – undo
1490 1490
                 // nav tab is only to appear when route requested.
1491 1491
                 continue;
1492 1492
             }
1493
-            if (! $this->check_user_access($slug, true)) {
1493
+            if ( ! $this->check_user_access($slug, true)) {
1494 1494
                 // no nav tab because current user does not have access.
1495 1495
                 continue;
1496 1496
             }
1497
-            $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1498
-            $this->_nav_tabs[ $slug ] = array(
1497
+            $css_class = isset($config['css_class']) ? $config['css_class'].' ' : '';
1498
+            $this->_nav_tabs[$slug] = array(
1499 1499
                 'url'       => isset($config['nav']['url'])
1500 1500
                     ? $config['nav']['url']
1501 1501
                     : self::add_query_args_and_nonce(
@@ -1507,14 +1507,14 @@  discard block
 block discarded – undo
1507 1507
                     : ucwords(
1508 1508
                         str_replace('_', ' ', $slug)
1509 1509
                     ),
1510
-                'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1510
+                'css_class' => $this->_req_action === $slug ? $css_class.'nav-tab-active' : $css_class,
1511 1511
                 'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1512 1512
             );
1513 1513
             $i++;
1514 1514
         }
1515 1515
         // if $this->_nav_tabs is empty then lets set the default
1516 1516
         if (empty($this->_nav_tabs)) {
1517
-            $this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1517
+            $this->_nav_tabs[$this->_default_nav_tab_name] = array(
1518 1518
                 'url'       => $this->_admin_base_url,
1519 1519
                 'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1520 1520
                 'css_class' => 'nav-tab-active',
@@ -1539,10 +1539,10 @@  discard block
 block discarded – undo
1539 1539
             foreach ($this->_route_config['labels'] as $label => $text) {
1540 1540
                 if (is_array($text)) {
1541 1541
                     foreach ($text as $sublabel => $subtext) {
1542
-                        $this->_labels[ $label ][ $sublabel ] = $subtext;
1542
+                        $this->_labels[$label][$sublabel] = $subtext;
1543 1543
                     }
1544 1544
                 } else {
1545
-                    $this->_labels[ $label ] = $text;
1545
+                    $this->_labels[$label] = $text;
1546 1546
                 }
1547 1547
             }
1548 1548
         }
@@ -1564,12 +1564,12 @@  discard block
 block discarded – undo
1564 1564
     {
1565 1565
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1566 1566
         $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1567
-        $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1567
+        $capability = ! empty($route_to_check) && isset($this->_page_routes[$route_to_check])
1568 1568
                       && is_array(
1569
-                          $this->_page_routes[ $route_to_check ]
1569
+                          $this->_page_routes[$route_to_check]
1570 1570
                       )
1571
-                      && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1572
-            ? $this->_page_routes[ $route_to_check ]['capability'] : null;
1571
+                      && ! empty($this->_page_routes[$route_to_check]['capability'])
1572
+            ? $this->_page_routes[$route_to_check]['capability'] : null;
1573 1573
         if (empty($capability) && empty($route_to_check)) {
1574 1574
             $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1575 1575
                 : $this->_route['capability'];
@@ -1577,7 +1577,7 @@  discard block
 block discarded – undo
1577 1577
             $capability = empty($capability) ? 'manage_options' : $capability;
1578 1578
         }
1579 1579
         $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1580
-        if (! defined('DOING_AJAX')
1580
+        if ( ! defined('DOING_AJAX')
1581 1581
             && (
1582 1582
                 ! function_exists('is_admin')
1583 1583
                 || ! EE_Registry::instance()->CAP->current_user_can(
@@ -1682,17 +1682,17 @@  discard block
 block discarded – undo
1682 1682
     public function admin_footer_global()
1683 1683
     {
1684 1684
         // dialog container for dialog helper
1685
-        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1685
+        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">'."\n";
1686 1686
         $d_cont .= '<div class="ee-notices"></div>';
1687 1687
         $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1688 1688
         $d_cont .= '</div>';
1689 1689
         echo $d_cont;
1690 1690
         // help tour stuff?
1691
-        if (isset($this->_help_tour[ $this->_req_action ])) {
1692
-            echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1691
+        if (isset($this->_help_tour[$this->_req_action])) {
1692
+            echo implode('<br />', $this->_help_tour[$this->_req_action]);
1693 1693
         }
1694 1694
         // current set timezone for timezone js
1695
-        echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1695
+        echo '<span id="current_timezone" class="hidden">'.EEH_DTT_Helper::get_timezone().'</span>';
1696 1696
     }
1697 1697
 
1698 1698
 
@@ -1726,7 +1726,7 @@  discard block
 block discarded – undo
1726 1726
         // loop through the array and setup content
1727 1727
         foreach ($help_array as $trigger => $help) {
1728 1728
             // make sure the array is setup properly
1729
-            if (! isset($help['title'], $help['content'])) {
1729
+            if ( ! isset($help['title'], $help['content'])) {
1730 1730
                 throw new EE_Error(
1731 1731
                     esc_html__(
1732 1732
                         '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',
@@ -1741,7 +1741,7 @@  discard block
 block discarded – undo
1741 1741
                 'help_popup_content' => $help['content'],
1742 1742
             );
1743 1743
             $content .= EEH_Template::display_template(
1744
-                EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1744
+                EE_ADMIN_TEMPLATE.'admin_help_popup.template.php',
1745 1745
                 $template_args,
1746 1746
                 true
1747 1747
             );
@@ -1763,15 +1763,15 @@  discard block
 block discarded – undo
1763 1763
     private function _get_help_content()
1764 1764
     {
1765 1765
         // what is the method we're looking for?
1766
-        $method_name = '_help_popup_content_' . $this->_req_action;
1766
+        $method_name = '_help_popup_content_'.$this->_req_action;
1767 1767
         // if method doesn't exist let's get out.
1768
-        if (! method_exists($this, $method_name)) {
1768
+        if ( ! method_exists($this, $method_name)) {
1769 1769
             return array();
1770 1770
         }
1771 1771
         // k we're good to go let's retrieve the help array
1772 1772
         $help_array = $this->{$method_name}();
1773 1773
         // make sure we've got an array!
1774
-        if (! is_array($help_array)) {
1774
+        if ( ! is_array($help_array)) {
1775 1775
             throw new EE_Error(
1776 1776
                 esc_html__(
1777 1777
                     'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
@@ -1803,8 +1803,8 @@  discard block
 block discarded – undo
1803 1803
         // 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
1804 1804
         $help_array = $this->_get_help_content();
1805 1805
         $help_content = '';
1806
-        if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1807
-            $help_array[ $trigger_id ] = array(
1806
+        if (empty($help_array) || ! isset($help_array[$trigger_id])) {
1807
+            $help_array[$trigger_id] = array(
1808 1808
                 'title'   => esc_html__('Missing Content', 'event_espresso'),
1809 1809
                 'content' => esc_html__(
1810 1810
                     '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.)',
@@ -1880,15 +1880,15 @@  discard block
 block discarded – undo
1880 1880
         // register all styles
1881 1881
         wp_register_style(
1882 1882
             'espresso-ui-theme',
1883
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1883
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1884 1884
             array(),
1885 1885
             EVENT_ESPRESSO_VERSION
1886 1886
         );
1887
-        wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1887
+        wp_register_style('ee-admin-css', EE_ADMIN_URL.'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1888 1888
         // helpers styles
1889 1889
         wp_register_style(
1890 1890
             'ee-text-links',
1891
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1891
+            EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.css',
1892 1892
             array(),
1893 1893
             EVENT_ESPRESSO_VERSION
1894 1894
         );
@@ -1896,21 +1896,21 @@  discard block
 block discarded – undo
1896 1896
         // register all scripts
1897 1897
         wp_register_script(
1898 1898
             'ee-dialog',
1899
-            EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1899
+            EE_ADMIN_URL.'assets/ee-dialog-helper.js',
1900 1900
             array('jquery', 'jquery-ui-draggable'),
1901 1901
             EVENT_ESPRESSO_VERSION,
1902 1902
             true
1903 1903
         );
1904 1904
         wp_register_script(
1905 1905
             'ee_admin_js',
1906
-            EE_ADMIN_URL . 'assets/ee-admin-page.js',
1906
+            EE_ADMIN_URL.'assets/ee-admin-page.js',
1907 1907
             array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1908 1908
             EVENT_ESPRESSO_VERSION,
1909 1909
             true
1910 1910
         );
1911 1911
         wp_register_script(
1912 1912
             'jquery-ui-timepicker-addon',
1913
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1913
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery-ui-timepicker-addon.js',
1914 1914
             array('jquery-ui-datepicker', 'jquery-ui-slider'),
1915 1915
             EVENT_ESPRESSO_VERSION,
1916 1916
             true
@@ -1921,7 +1921,7 @@  discard block
 block discarded – undo
1921 1921
         // script for sorting tables
1922 1922
         wp_register_script(
1923 1923
             'espresso_ajax_table_sorting',
1924
-            EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1924
+            EE_ADMIN_URL.'assets/espresso_ajax_table_sorting.js',
1925 1925
             array('ee_admin_js', 'jquery-ui-sortable'),
1926 1926
             EVENT_ESPRESSO_VERSION,
1927 1927
             true
@@ -1929,7 +1929,7 @@  discard block
 block discarded – undo
1929 1929
         // script for parsing uri's
1930 1930
         wp_register_script(
1931 1931
             'ee-parse-uri',
1932
-            EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1932
+            EE_GLOBAL_ASSETS_URL.'scripts/parseuri.js',
1933 1933
             array(),
1934 1934
             EVENT_ESPRESSO_VERSION,
1935 1935
             true
@@ -1937,7 +1937,7 @@  discard block
 block discarded – undo
1937 1937
         // and parsing associative serialized form elements
1938 1938
         wp_register_script(
1939 1939
             'ee-serialize-full-array',
1940
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1940
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.serializefullarray.js',
1941 1941
             array('jquery'),
1942 1942
             EVENT_ESPRESSO_VERSION,
1943 1943
             true
@@ -1945,28 +1945,28 @@  discard block
 block discarded – undo
1945 1945
         // helpers scripts
1946 1946
         wp_register_script(
1947 1947
             'ee-text-links',
1948
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1948
+            EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.js',
1949 1949
             array('jquery'),
1950 1950
             EVENT_ESPRESSO_VERSION,
1951 1951
             true
1952 1952
         );
1953 1953
         wp_register_script(
1954 1954
             'ee-moment-core',
1955
-            EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1955
+            EE_THIRD_PARTY_URL.'moment/moment-with-locales.min.js',
1956 1956
             array(),
1957 1957
             EVENT_ESPRESSO_VERSION,
1958 1958
             true
1959 1959
         );
1960 1960
         wp_register_script(
1961 1961
             'ee-moment',
1962
-            EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1962
+            EE_THIRD_PARTY_URL.'moment/moment-timezone-with-data.min.js',
1963 1963
             array('ee-moment-core'),
1964 1964
             EVENT_ESPRESSO_VERSION,
1965 1965
             true
1966 1966
         );
1967 1967
         wp_register_script(
1968 1968
             'ee-datepicker',
1969
-            EE_ADMIN_URL . 'assets/ee-datepicker.js',
1969
+            EE_ADMIN_URL.'assets/ee-datepicker.js',
1970 1970
             array('jquery-ui-timepicker-addon', 'ee-moment'),
1971 1971
             EVENT_ESPRESSO_VERSION,
1972 1972
             true
@@ -1999,11 +1999,11 @@  discard block
 block discarded – undo
1999 1999
         /**
2000 2000
          * help tour stuff
2001 2001
          */
2002
-        if (! empty($this->_help_tour)) {
2002
+        if ( ! empty($this->_help_tour)) {
2003 2003
             // register the js for kicking things off
2004 2004
             wp_enqueue_script(
2005 2005
                 'ee-help-tour',
2006
-                EE_ADMIN_URL . 'assets/ee-help-tour.js',
2006
+                EE_ADMIN_URL.'assets/ee-help-tour.js',
2007 2007
                 array('jquery-joyride'),
2008 2008
                 EVENT_ESPRESSO_VERSION,
2009 2009
                 true
@@ -2103,12 +2103,12 @@  discard block
 block discarded – undo
2103 2103
     protected function _set_list_table()
2104 2104
     {
2105 2105
         // first is this a list_table view?
2106
-        if (! isset($this->_route_config['list_table'])) {
2106
+        if ( ! isset($this->_route_config['list_table'])) {
2107 2107
             return;
2108 2108
         } //not a list_table view so get out.
2109 2109
         // list table functions are per view specific (because some admin pages might have more than one list table!)
2110
-        $list_table_view = '_set_list_table_views_' . $this->_req_action;
2111
-        if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2110
+        $list_table_view = '_set_list_table_views_'.$this->_req_action;
2111
+        if ( ! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2112 2112
             // user error msg
2113 2113
             $error_msg = esc_html__(
2114 2114
                 'An error occurred. The requested list table views could not be found.',
@@ -2128,10 +2128,10 @@  discard block
 block discarded – undo
2128 2128
         }
2129 2129
         // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2130 2130
         $this->_views = apply_filters(
2131
-            'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2131
+            'FHEE_list_table_views_'.$this->page_slug.'_'.$this->_req_action,
2132 2132
             $this->_views
2133 2133
         );
2134
-        $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2134
+        $this->_views = apply_filters('FHEE_list_table_views_'.$this->page_slug, $this->_views);
2135 2135
         $this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2136 2136
         $this->_set_list_table_view();
2137 2137
         $this->_set_list_table_object();
@@ -2147,7 +2147,7 @@  discard block
 block discarded – undo
2147 2147
     {
2148 2148
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2149 2149
         // looking at active items or dumpster diving ?
2150
-        if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2150
+        if ( ! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2151 2151
             $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2152 2152
         } else {
2153 2153
             $this->_view = sanitize_key($this->_req_data['status']);
@@ -2168,7 +2168,7 @@  discard block
 block discarded – undo
2168 2168
     protected function _set_list_table_object()
2169 2169
     {
2170 2170
         if (isset($this->_route_config['list_table'])) {
2171
-            if (! class_exists($this->_route_config['list_table'])) {
2171
+            if ( ! class_exists($this->_route_config['list_table'])) {
2172 2172
                 throw new EE_Error(
2173 2173
                     sprintf(
2174 2174
                         esc_html__(
@@ -2206,17 +2206,17 @@  discard block
 block discarded – undo
2206 2206
         foreach ($this->_views as $key => $view) {
2207 2207
             $query_args = array();
2208 2208
             // check for current view
2209
-            $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2209
+            $this->_views[$key]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2210 2210
             $query_args['action'] = $this->_req_action;
2211
-            $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2211
+            $query_args[$this->_req_action.'_nonce'] = wp_create_nonce($query_args['action'].'_nonce');
2212 2212
             $query_args['status'] = $view['slug'];
2213 2213
             // merge any other arguments sent in.
2214
-            if (isset($extra_query_args[ $view['slug'] ])) {
2215
-                foreach ($extra_query_args[ $view['slug'] ] as $extra_query_arg) {
2214
+            if (isset($extra_query_args[$view['slug']])) {
2215
+                foreach ($extra_query_args[$view['slug']] as $extra_query_arg) {
2216 2216
                     $query_args[] = $extra_query_arg;
2217 2217
                 }
2218 2218
             }
2219
-            $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2219
+            $this->_views[$key]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2220 2220
         }
2221 2221
         return $this->_views;
2222 2222
     }
@@ -2235,7 +2235,7 @@  discard block
 block discarded – undo
2235 2235
     {
2236 2236
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2237 2237
         $values = array(10, 25, 50, 100);
2238
-        $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2238
+        $per_page = ( ! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2239 2239
         if ($max_entries) {
2240 2240
             $values[] = $max_entries;
2241 2241
             sort($values);
@@ -2247,14 +2247,14 @@  discard block
 block discarded – undo
2247 2247
 					<select id="entries-per-page-slct" name="entries-per-page-slct">';
2248 2248
         foreach ($values as $value) {
2249 2249
             if ($value < $max_entries) {
2250
-                $selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2250
+                $selected = $value === $per_page ? ' selected="'.$per_page.'"' : '';
2251 2251
                 $entries_per_page_dropdown .= '
2252
-						<option value="' . $value . '"' . $selected . '>' . $value . '&nbsp;&nbsp;</option>';
2252
+						<option value="' . $value.'"'.$selected.'>'.$value.'&nbsp;&nbsp;</option>';
2253 2253
             }
2254 2254
         }
2255
-        $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2255
+        $selected = $max_entries === $per_page ? ' selected="'.$per_page.'"' : '';
2256 2256
         $entries_per_page_dropdown .= '
2257
-						<option value="' . $max_entries . '"' . $selected . '>All&nbsp;&nbsp;</option>';
2257
+						<option value="' . $max_entries.'"'.$selected.'>All&nbsp;&nbsp;</option>';
2258 2258
         $entries_per_page_dropdown .= '
2259 2259
 					</select>
2260 2260
 					entries
@@ -2278,7 +2278,7 @@  discard block
 block discarded – undo
2278 2278
             empty($this->_search_btn_label) ? $this->page_label
2279 2279
                 : $this->_search_btn_label
2280 2280
         );
2281
-        $this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2281
+        $this->_template_args['search']['callback'] = 'search_'.$this->page_slug;
2282 2282
     }
2283 2283
 
2284 2284
 
@@ -2364,7 +2364,7 @@  discard block
 block discarded – undo
2364 2364
             $total_columns = ! empty($screen_columns)
2365 2365
                 ? $screen_columns
2366 2366
                 : $this->_route_config['columns'][1];
2367
-            $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2367
+            $this->_template_args['current_screen_widget_class'] = 'columns-'.$total_columns;
2368 2368
             $this->_template_args['current_page'] = $this->_wp_page_slug;
2369 2369
             $this->_template_args['screen'] = $this->_current_screen;
2370 2370
             $this->_column_template_path = EE_ADMIN_TEMPLATE
@@ -2409,7 +2409,7 @@  discard block
 block discarded – undo
2409 2409
      */
2410 2410
     protected function _espresso_ratings_request()
2411 2411
     {
2412
-        if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2412
+        if ( ! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2413 2413
             return;
2414 2414
         }
2415 2415
         $ratings_box_title = apply_filters(
@@ -2436,7 +2436,7 @@  discard block
 block discarded – undo
2436 2436
      */
2437 2437
     public function espresso_ratings_request()
2438 2438
     {
2439
-        EEH_Template::display_template(EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php');
2439
+        EEH_Template::display_template(EE_ADMIN_TEMPLATE.'espresso_ratings_request_content.template.php');
2440 2440
     }
2441 2441
 
2442 2442
 
@@ -2447,17 +2447,17 @@  discard block
 block discarded – undo
2447 2447
                    . '</p><p class="hide-if-js">'
2448 2448
                    . esc_html__('This widget requires JavaScript.', 'event_espresso')
2449 2449
                    . '</p>';
2450
-        $pre = '<div class="espresso-rss-display">' . "\n\t";
2451
-        $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2452
-        $post = '</div>' . "\n";
2453
-        $cache_key = 'ee_rss_' . md5($rss_id);
2450
+        $pre = '<div class="espresso-rss-display">'."\n\t";
2451
+        $pre .= '<span id="'.$rss_id.'_url" class="hidden">'.$url.'</span>';
2452
+        $post = '</div>'."\n";
2453
+        $cache_key = 'ee_rss_'.md5($rss_id);
2454 2454
         $output = get_transient($cache_key);
2455 2455
         if ($output !== false) {
2456
-            echo $pre . $output . $post;
2456
+            echo $pre.$output.$post;
2457 2457
             return true;
2458 2458
         }
2459
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2460
-            echo $pre . $loading . $post;
2459
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
2460
+            echo $pre.$loading.$post;
2461 2461
             return false;
2462 2462
         }
2463 2463
         ob_start();
@@ -2524,19 +2524,19 @@  discard block
 block discarded – undo
2524 2524
     public function espresso_sponsors_post_box()
2525 2525
     {
2526 2526
         EEH_Template::display_template(
2527
-            EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2527
+            EE_ADMIN_TEMPLATE.'admin_general_metabox_contents_espresso_sponsors.template.php'
2528 2528
         );
2529 2529
     }
2530 2530
 
2531 2531
 
2532 2532
     private function _publish_post_box()
2533 2533
     {
2534
-        $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2534
+        $meta_box_ref = 'espresso_'.$this->page_slug.'_editor_overview';
2535 2535
         // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2536 2536
         // then we'll use that for the metabox label.
2537 2537
         // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2538
-        if (! empty($this->_labels['publishbox'])) {
2539
-            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2538
+        if ( ! empty($this->_labels['publishbox'])) {
2539
+            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][$this->_req_action]
2540 2540
                 : $this->_labels['publishbox'];
2541 2541
         } else {
2542 2542
             $box_label = esc_html__('Publish', 'event_espresso');
@@ -2565,7 +2565,7 @@  discard block
 block discarded – undo
2565 2565
             ? $this->_template_args['publish_box_extra_content']
2566 2566
             : '';
2567 2567
         echo EEH_Template::display_template(
2568
-            EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2568
+            EE_ADMIN_TEMPLATE.'admin_details_publish_metabox.template.php',
2569 2569
             $this->_template_args,
2570 2570
             true
2571 2571
         );
@@ -2655,8 +2655,8 @@  discard block
 block discarded – undo
2655 2655
             );
2656 2656
         }
2657 2657
         $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2658
-        if (! empty($name) && ! empty($id)) {
2659
-            $hidden_field_arr[ $name ] = array(
2658
+        if ( ! empty($name) && ! empty($id)) {
2659
+            $hidden_field_arr[$name] = array(
2660 2660
                 'type'  => 'hidden',
2661 2661
                 'value' => $id,
2662 2662
             );
@@ -2666,7 +2666,7 @@  discard block
 block discarded – undo
2666 2666
         }
2667 2667
         // add hidden field
2668 2668
         $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2669
-            ? $hf[ $name ]['field']
2669
+            ? $hf[$name]['field']
2670 2670
             : $hf;
2671 2671
     }
2672 2672
 
@@ -2768,7 +2768,7 @@  discard block
 block discarded – undo
2768 2768
         }
2769 2769
         // 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)
2770 2770
         $call_back_func = $create_func
2771
-            ? static function ($post, $metabox) {
2771
+            ? static function($post, $metabox) {
2772 2772
                 do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2773 2773
                 echo EEH_Template::display_template(
2774 2774
                     $metabox['args']['template_path'],
@@ -2778,7 +2778,7 @@  discard block
 block discarded – undo
2778 2778
             }
2779 2779
             : $callback;
2780 2780
         add_meta_box(
2781
-            str_replace('_', '-', $action) . '-mbox',
2781
+            str_replace('_', '-', $action).'-mbox',
2782 2782
             $title,
2783 2783
             $call_back_func,
2784 2784
             $this->_wp_page_slug,
@@ -2885,9 +2885,9 @@  discard block
 block discarded – undo
2885 2885
             : 'espresso-default-admin';
2886 2886
         $template_path = $sidebar
2887 2887
             ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2888
-            : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2888
+            : EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar.template.php';
2889 2889
         if (defined('DOING_AJAX') && DOING_AJAX) {
2890
-            $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2890
+            $template_path = EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar_ajax.template.php';
2891 2891
         }
2892 2892
         $template_path = ! empty($this->_column_template_path)
2893 2893
             ? $this->_column_template_path : $template_path;
@@ -2952,7 +2952,7 @@  discard block
 block discarded – undo
2952 2952
             )
2953 2953
             : $this->_template_args['preview_action_button'];
2954 2954
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2955
-            EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2955
+            EE_ADMIN_TEMPLATE.'admin_caf_full_page_preview.template.php',
2956 2956
             $this->_template_args,
2957 2957
             true
2958 2958
         );
@@ -3010,7 +3010,7 @@  discard block
 block discarded – undo
3010 3010
         // setup search attributes
3011 3011
         $this->_set_search_attributes();
3012 3012
         $this->_template_args['current_page'] = $this->_wp_page_slug;
3013
-        $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3013
+        $template_path = EE_ADMIN_TEMPLATE.'admin_list_wrapper.template.php';
3014 3014
         $this->_template_args['table_url'] = defined('DOING_AJAX')
3015 3015
             ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3016 3016
             : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
@@ -3018,10 +3018,10 @@  discard block
 block discarded – undo
3018 3018
         $this->_template_args['current_route'] = $this->_req_action;
3019 3019
         $this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3020 3020
         $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
3021
-        if (! empty($ajax_sorting_callback)) {
3021
+        if ( ! empty($ajax_sorting_callback)) {
3022 3022
             $sortable_list_table_form_fields = wp_nonce_field(
3023
-                $ajax_sorting_callback . '_nonce',
3024
-                $ajax_sorting_callback . '_nonce',
3023
+                $ajax_sorting_callback.'_nonce',
3024
+                $ajax_sorting_callback.'_nonce',
3025 3025
                 false,
3026 3026
                 false
3027 3027
             );
@@ -3038,7 +3038,7 @@  discard block
 block discarded – undo
3038 3038
         $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
3039 3039
             ? $this->_template_args['list_table_hidden_fields']
3040 3040
             : '';
3041
-        $nonce_ref = $this->_req_action . '_nonce';
3041
+        $nonce_ref = $this->_req_action.'_nonce';
3042 3042
         $hidden_form_fields .= '<input type="hidden" name="'
3043 3043
                                . $nonce_ref
3044 3044
                                . '" value="'
@@ -3047,10 +3047,10 @@  discard block
 block discarded – undo
3047 3047
         $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3048 3048
         // display message about search results?
3049 3049
         $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3050
-            ? '<p class="ee-search-results">' . sprintf(
3050
+            ? '<p class="ee-search-results">'.sprintf(
3051 3051
                 esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3052 3052
                 trim($this->_req_data['s'], '%')
3053
-            ) . '</p>'
3053
+            ).'</p>'
3054 3054
             : '';
3055 3055
         // filter before_list_table template arg
3056 3056
         $this->_template_args['before_list_table'] = apply_filters(
@@ -3131,7 +3131,7 @@  discard block
 block discarded – undo
3131 3131
             $this
3132 3132
         );
3133 3133
         return EEH_Template::display_template(
3134
-            EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3134
+            EE_ADMIN_TEMPLATE.'admin_details_legend.template.php',
3135 3135
             $this->_template_args,
3136 3136
             true
3137 3137
         );
@@ -3363,17 +3363,17 @@  discard block
 block discarded – undo
3363 3363
         // add in a hidden index for the current page (so save and close redirects properly)
3364 3364
         $this->_template_args['save_buttons'] = $referrer_url;
3365 3365
         foreach ($button_text as $key => $button) {
3366
-            $ref = $default_names[ $key ];
3366
+            $ref = $default_names[$key];
3367 3367
             $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3368 3368
                                                      . $ref
3369 3369
                                                      . '" value="'
3370 3370
                                                      . $button
3371 3371
                                                      . '" name="'
3372
-                                                     . (! empty($actions) ? $actions[ $key ] : $ref)
3372
+                                                     . ( ! empty($actions) ? $actions[$key] : $ref)
3373 3373
                                                      . '" id="'
3374
-                                                     . $this->_current_view . '_' . $ref
3374
+                                                     . $this->_current_view.'_'.$ref
3375 3375
                                                      . '" />';
3376
-            if (! $both) {
3376
+            if ( ! $both) {
3377 3377
                 break;
3378 3378
             }
3379 3379
         }
@@ -3408,13 +3408,13 @@  discard block
 block discarded – undo
3408 3408
                 'An error occurred. No action was set for this page\'s form.',
3409 3409
                 'event_espresso'
3410 3410
             );
3411
-            $dev_msg = $user_msg . "\n"
3411
+            $dev_msg = $user_msg."\n"
3412 3412
                        . sprintf(
3413 3413
                            esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3414 3414
                            __FUNCTION__,
3415 3415
                            __CLASS__
3416 3416
                        );
3417
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3417
+            EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__);
3418 3418
         }
3419 3419
         // open form
3420 3420
         $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
@@ -3423,8 +3423,8 @@  discard block
 block discarded – undo
3423 3423
                                                              . $route
3424 3424
                                                              . '_event_form" >';
3425 3425
         // add nonce
3426
-        $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3427
-        $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3426
+        $nonce = wp_nonce_field($route.'_nonce', $route.'_nonce', false, false);
3427
+        $this->_template_args['before_admin_page_content'] .= "\n\t".$nonce;
3428 3428
         // add REQUIRED form action
3429 3429
         $hidden_fields = array(
3430 3430
             'action' => array('type' => 'hidden', 'value' => $route),
@@ -3437,7 +3437,7 @@  discard block
 block discarded – undo
3437 3437
         $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3438 3438
         // add fields to form
3439 3439
         foreach ((array) $form_fields as $field_name => $form_field) {
3440
-            $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3440
+            $this->_template_args['before_admin_page_content'] .= "\n\t".$form_field['field'];
3441 3441
         }
3442 3442
         // close form
3443 3443
         $this->_template_args['after_admin_page_content'] = '</form>';
@@ -3491,12 +3491,12 @@  discard block
 block discarded – undo
3491 3491
         foreach ($this->_req_data as $ref => $value) {
3492 3492
             // unset nonces
3493 3493
             if (strpos($ref, 'nonce') !== false) {
3494
-                unset($this->_req_data[ $ref ]);
3494
+                unset($this->_req_data[$ref]);
3495 3495
                 continue;
3496 3496
             }
3497 3497
             // urlencode values.
3498 3498
             $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3499
-            $this->_req_data[ $ref ] = $value;
3499
+            $this->_req_data[$ref] = $value;
3500 3500
         }
3501 3501
         return array_merge($this->_req_data, $new_route_data);
3502 3502
     }
@@ -3534,10 +3534,10 @@  discard block
 block discarded – undo
3534 3534
         $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3535 3535
         $notices = EE_Error::get_notices(false);
3536 3536
         // overwrite default success messages //BUT ONLY if overwrite not overridden
3537
-        if (! $override_overwrite || ! empty($notices['errors'])) {
3537
+        if ( ! $override_overwrite || ! empty($notices['errors'])) {
3538 3538
             EE_Error::overwrite_success();
3539 3539
         }
3540
-        if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3540
+        if ( ! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3541 3541
             // how many records affected ? more than one record ? or just one ?
3542 3542
             if ($success > 1) {
3543 3543
                 // set plural msg
@@ -3566,7 +3566,7 @@  discard block
 block discarded – undo
3566 3566
             }
3567 3567
         }
3568 3568
         // check that $query_args isn't something crazy
3569
-        if (! is_array($query_args)) {
3569
+        if ( ! is_array($query_args)) {
3570 3570
             $query_args = array();
3571 3571
         }
3572 3572
         /**
@@ -3591,7 +3591,7 @@  discard block
 block discarded – undo
3591 3591
             $redirect_url = admin_url('admin.php');
3592 3592
         }
3593 3593
         // merge any default query_args set in _default_route_query_args property
3594
-        if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3594
+        if ( ! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3595 3595
             $args_to_merge = array();
3596 3596
             foreach ($this->_default_route_query_args as $query_param => $query_value) {
3597 3597
                 // is there a wp_referer array in our _default_route_query_args property?
@@ -3603,15 +3603,15 @@  discard block
 block discarded – undo
3603 3603
                         }
3604 3604
                         // finally we will override any arguments in the referer with
3605 3605
                         // what might be set on the _default_route_query_args array.
3606
-                        if (isset($this->_default_route_query_args[ $reference ])) {
3607
-                            $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3606
+                        if (isset($this->_default_route_query_args[$reference])) {
3607
+                            $args_to_merge[$reference] = urlencode($this->_default_route_query_args[$reference]);
3608 3608
                         } else {
3609
-                            $args_to_merge[ $reference ] = urlencode($value);
3609
+                            $args_to_merge[$reference] = urlencode($value);
3610 3610
                         }
3611 3611
                     }
3612 3612
                     continue;
3613 3613
                 }
3614
-                $args_to_merge[ $query_param ] = $query_value;
3614
+                $args_to_merge[$query_param] = $query_value;
3615 3615
             }
3616 3616
             // now let's merge these arguments but override with what was specifically sent in to the
3617 3617
             // redirect.
@@ -3623,13 +3623,13 @@  discard block
 block discarded – undo
3623 3623
         if (isset($query_args['action'])) {
3624 3624
             // manually generate wp_nonce and merge that with the query vars
3625 3625
             // becuz the wp_nonce_url function wrecks havoc on some vars
3626
-            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3626
+            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'].'_nonce');
3627 3627
         }
3628 3628
         // we're adding some hooks and filters in here for processing any things just before redirects
3629 3629
         // (example: an admin page has done an insert or update and we want to run something after that).
3630
-        do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3630
+        do_action('AHEE_redirect_'.$classname.$this->_req_action, $query_args);
3631 3631
         $redirect_url = apply_filters(
3632
-            'FHEE_redirect_' . $classname . $this->_req_action,
3632
+            'FHEE_redirect_'.$classname.$this->_req_action,
3633 3633
             self::add_query_args_and_nonce($query_args, $redirect_url),
3634 3634
             $query_args
3635 3635
         );
@@ -3685,7 +3685,7 @@  discard block
 block discarded – undo
3685 3685
         }
3686 3686
         $this->_template_args['notices'] = EE_Error::get_notices();
3687 3687
         // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3688
-        if (! defined('DOING_AJAX') || $sticky_notices) {
3688
+        if ( ! defined('DOING_AJAX') || $sticky_notices) {
3689 3689
             $route = isset($query_args['action']) ? $query_args['action'] : 'default';
3690 3690
             $this->_add_transient(
3691 3691
                 $route,
@@ -3725,7 +3725,7 @@  discard block
 block discarded – undo
3725 3725
         $exclude_nonce = false
3726 3726
     ) {
3727 3727
         // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3728
-        if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3728
+        if (empty($base_url) && ! isset($this->_page_routes[$action])) {
3729 3729
             throw new EE_Error(
3730 3730
                 sprintf(
3731 3731
                     esc_html__(
@@ -3736,7 +3736,7 @@  discard block
 block discarded – undo
3736 3736
                 )
3737 3737
             );
3738 3738
         }
3739
-        if (! isset($this->_labels['buttons'][ $type ])) {
3739
+        if ( ! isset($this->_labels['buttons'][$type])) {
3740 3740
             throw new EE_Error(
3741 3741
                 sprintf(
3742 3742
                     __(
@@ -3749,7 +3749,7 @@  discard block
 block discarded – undo
3749 3749
         }
3750 3750
         // finally check user access for this button.
3751 3751
         $has_access = $this->check_user_access($action, true);
3752
-        if (! $has_access) {
3752
+        if ( ! $has_access) {
3753 3753
             return '';
3754 3754
         }
3755 3755
         $_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
@@ -3757,11 +3757,11 @@  discard block
 block discarded – undo
3757 3757
             'action' => $action,
3758 3758
         );
3759 3759
         // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3760
-        if (! empty($extra_request)) {
3760
+        if ( ! empty($extra_request)) {
3761 3761
             $query_args = array_merge($extra_request, $query_args);
3762 3762
         }
3763 3763
         $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3764
-        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3764
+        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][$type], $class);
3765 3765
     }
3766 3766
 
3767 3767
 
@@ -3787,7 +3787,7 @@  discard block
 block discarded – undo
3787 3787
                 'FHEE__EE_Admin_Page___per_page_screen_options__default',
3788 3788
                 20
3789 3789
             ),
3790
-            'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3790
+            'option'  => $this->_current_page.'_'.$this->_current_view.'_per_page',
3791 3791
         );
3792 3792
         // ONLY add the screen option if the user has access to it.
3793 3793
         if ($this->check_user_access($this->_current_view, true)) {
@@ -3808,7 +3808,7 @@  discard block
 block discarded – undo
3808 3808
     {
3809 3809
         if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3810 3810
             check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3811
-            if (! $user = wp_get_current_user()) {
3811
+            if ( ! $user = wp_get_current_user()) {
3812 3812
                 return;
3813 3813
             }
3814 3814
             $option = $_POST['wp_screen_options']['option'];
@@ -3819,7 +3819,7 @@  discard block
 block discarded – undo
3819 3819
             $map_option = $option;
3820 3820
             $option = str_replace('-', '_', $option);
3821 3821
             switch ($map_option) {
3822
-                case $this->_current_page . '_' . $this->_current_view . '_per_page':
3822
+                case $this->_current_page.'_'.$this->_current_view.'_per_page':
3823 3823
                     $value = (int) $value;
3824 3824
                     $max_value = apply_filters(
3825 3825
                         'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
@@ -3877,13 +3877,13 @@  discard block
 block discarded – undo
3877 3877
     protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3878 3878
     {
3879 3879
         $user_id = get_current_user_id();
3880
-        if (! $skip_route_verify) {
3880
+        if ( ! $skip_route_verify) {
3881 3881
             $this->_verify_route($route);
3882 3882
         }
3883 3883
         // now let's set the string for what kind of transient we're setting
3884 3884
         $transient = $notices
3885
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3886
-            : 'rte_tx_' . $route . '_' . $user_id;
3885
+            ? 'ee_rte_n_tx_'.$route.'_'.$user_id
3886
+            : 'rte_tx_'.$route.'_'.$user_id;
3887 3887
         $data = $notices ? array('notices' => $data) : $data;
3888 3888
         // is there already a transient for this route?  If there is then let's ADD to that transient
3889 3889
         $existing = is_multisite() && is_network_admin()
@@ -3912,8 +3912,8 @@  discard block
 block discarded – undo
3912 3912
         $user_id = get_current_user_id();
3913 3913
         $route = ! $route ? $this->_req_action : $route;
3914 3914
         $transient = $notices
3915
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3916
-            : 'rte_tx_' . $route . '_' . $user_id;
3915
+            ? 'ee_rte_n_tx_'.$route.'_'.$user_id
3916
+            : 'rte_tx_'.$route.'_'.$user_id;
3917 3917
         $data = is_multisite() && is_network_admin()
3918 3918
             ? get_site_transient($transient)
3919 3919
             : get_transient($transient);
@@ -4132,7 +4132,7 @@  discard block
 block discarded – undo
4132 4132
      */
4133 4133
     protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4134 4134
     {
4135
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4135
+        return '<a class="'.$class.'" href="'.$url.'"></a>';
4136 4136
     }
4137 4137
 
4138 4138
 
@@ -4145,7 +4145,7 @@  discard block
 block discarded – undo
4145 4145
      */
4146 4146
     protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4147 4147
     {
4148
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4148
+        return '<a class="'.$class.'" href="'.$url.'"></a>';
4149 4149
     }
4150 4150
 
4151 4151
 
Please login to merge, or discard this patch.
Indentation   +4126 added lines, -4126 removed lines patch added patch discarded remove patch
@@ -17,4194 +17,4194 @@
 block discarded – undo
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
-    // nav tabs
46
-    protected $_nav_tabs;
45
+	// nav tabs
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
-    // boolean
74
-    protected $_is_UI_request; // this starts at null so we can have no header routes progress through two states.
73
+	// boolean
74
+	protected $_is_UI_request; // 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;
104
+	/**
105
+	 * @var array $_route_config
106
+	 */
107
+	protected $_route_config;
108 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;
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
-    }
201
-
202
-
203
-    /**
204
-     * This logic used to be in the constructor, but that caused a chicken <--> egg scenario
205
-     * for child classes that needed to set properties prior to these methods getting called,
206
-     * but also needed the parent class to have its construction completed as well.
207
-     * Bottom line is that constructors should ONLY be used for setting initial properties
208
-     * and any complex initialization logic should only run after instantiation is complete.
209
-     *
210
-     * This method gets called immediately after construction from within
211
-     *      EE_Admin_Page_Init::_initialize_admin_page()
212
-     *
213
-     * @throws EE_Error
214
-     * @throws InvalidArgumentException
215
-     * @throws InvalidDataTypeException
216
-     * @throws InvalidInterfaceException
217
-     * @throws ReflectionException
218
-     * @since $VID:$
219
-     */
220
-    public function initializePage()
221
-    {
222
-        // set initial page props (child method)
223
-        $this->_init_page_props();
224
-        // set global defaults
225
-        $this->_set_defaults();
226
-        // set early because incoming requests could be ajax related and we need to register those hooks.
227
-        $this->_global_ajax_hooks();
228
-        $this->_ajax_hooks();
229
-        // other_page_hooks have to be early too.
230
-        $this->_do_other_page_hooks();
231
-        // This just allows us to have extending classes do something specific
232
-        // before the parent constructor runs _page_setup().
233
-        if (method_exists($this, '_before_page_setup')) {
234
-            $this->_before_page_setup();
235
-        }
236
-        // set up page dependencies
237
-        $this->_page_setup();
238
-    }
239
-
240
-
241
-    /**
242
-     * _init_page_props
243
-     * Child classes use to set at least the following properties:
244
-     * $page_slug.
245
-     * $page_label.
246
-     *
247
-     * @abstract
248
-     * @return void
249
-     */
250
-    abstract protected function _init_page_props();
251
-
252
-
253
-    /**
254
-     * _ajax_hooks
255
-     * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
256
-     * Note: within the ajax callback methods.
257
-     *
258
-     * @abstract
259
-     * @return void
260
-     */
261
-    abstract protected function _ajax_hooks();
262
-
263
-
264
-    /**
265
-     * _define_page_props
266
-     * child classes define page properties in here.  Must include at least:
267
-     * $_admin_base_url = base_url for all admin pages
268
-     * $_admin_page_title = default admin_page_title for admin pages
269
-     * $_labels = array of default labels for various automatically generated elements:
270
-     *    array(
271
-     *        'buttons' => array(
272
-     *            'add' => esc_html__('label for add new button'),
273
-     *            'edit' => esc_html__('label for edit button'),
274
-     *            'delete' => esc_html__('label for delete button')
275
-     *            )
276
-     *        )
277
-     *
278
-     * @abstract
279
-     * @return void
280
-     */
281
-    abstract protected function _define_page_props();
282
-
283
-
284
-    /**
285
-     * _set_page_routes
286
-     * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
287
-     * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
288
-     * have a 'default' route. Here's the format
289
-     * $this->_page_routes = array(
290
-     *        'default' => array(
291
-     *            'func' => '_default_method_handling_route',
292
-     *            'args' => array('array','of','args'),
293
-     *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
294
-     *            ajax request, backend processing)
295
-     *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
296
-     *            headers route after.  The string you enter here should match the defined route reference for a
297
-     *            headers sent route.
298
-     *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
299
-     *            this route.
300
-     *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
301
-     *            checks).
302
-     *        ),
303
-     *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
304
-     *        handling method.
305
-     *        )
306
-     * )
307
-     *
308
-     * @abstract
309
-     * @return void
310
-     */
311
-    abstract protected function _set_page_routes();
312
-
313
-
314
-    /**
315
-     * _set_page_config
316
-     * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
317
-     * array corresponds to the page_route for the loaded page. Format:
318
-     * $this->_page_config = array(
319
-     *        'default' => array(
320
-     *            'labels' => array(
321
-     *                'buttons' => array(
322
-     *                    'add' => esc_html__('label for adding item'),
323
-     *                    'edit' => esc_html__('label for editing item'),
324
-     *                    'delete' => esc_html__('label for deleting item')
325
-     *                ),
326
-     *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
327
-     *            ), //optional an array of custom labels for various automatically generated elements to use on the
328
-     *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
329
-     *            _define_page_props() method
330
-     *            'nav' => array(
331
-     *                'label' => esc_html__('Label for Tab', 'event_espresso').
332
-     *                'url' => 'http://someurl', //automatically generated UNLESS you define
333
-     *                'css_class' => 'css-class', //automatically generated UNLESS you define
334
-     *                'order' => 10, //required to indicate tab position.
335
-     *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
336
-     *                displayed then add this parameter.
337
-     *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
338
-     *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
339
-     *            metaboxes set for eventespresso admin pages.
340
-     *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
341
-     *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
342
-     *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
343
-     *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
344
-     *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
345
-     *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
346
-     *            array indicates the max number of columns (4) and the default number of columns on page load (2).
347
-     *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
348
-     *            want to display.
349
-     *            'help_tabs' => array( //this is used for adding help tabs to a page
350
-     *                'tab_id' => array(
351
-     *                    'title' => 'tab_title',
352
-     *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
353
-     *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
354
-     *                    should match a file in the admin folder's "help_tabs" dir (ie..
355
-     *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
356
-     *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
357
-     *                    attempt to use the callback which should match the name of a method in the class
358
-     *                    ),
359
-     *                'tab2_id' => array(
360
-     *                    'title' => 'tab2 title',
361
-     *                    'filename' => 'file_name_2'
362
-     *                    'callback' => 'callback_method_for_content',
363
-     *                 ),
364
-     *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
365
-     *            help tab area on an admin page. @link
366
-     *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
367
-     *            'help_tour' => array(
368
-     *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
369
-     *                in a folder for this admin page named "help_tours", a file name matching the key given here
370
-     *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
371
-     *            ),
372
-     *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
373
-     *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
374
-     *            just set
375
-     *            'require_nonce' to FALSE
376
-     *            )
377
-     * )
378
-     *
379
-     * @abstract
380
-     * @return void
381
-     */
382
-    abstract protected function _set_page_config();
383
-
384
-
385
-
386
-
387
-
388
-    /** end sample help_tour methods **/
389
-    /**
390
-     * _add_screen_options
391
-     * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
392
-     * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
393
-     * to a particular view.
394
-     *
395
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
396
-     *         see also WP_Screen object documents...
397
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
398
-     * @abstract
399
-     * @return void
400
-     */
401
-    abstract protected function _add_screen_options();
402
-
403
-
404
-    /**
405
-     * _add_feature_pointers
406
-     * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
407
-     * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
408
-     * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
409
-     * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
410
-     * extended) also see:
411
-     *
412
-     * @link   http://eamann.com/tech/wordpress-portland/
413
-     * @abstract
414
-     * @return void
415
-     */
416
-    abstract protected function _add_feature_pointers();
417
-
418
-
419
-    /**
420
-     * load_scripts_styles
421
-     * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
422
-     * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
423
-     * scripts/styles per view by putting them in a dynamic function in this format
424
-     * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
425
-     *
426
-     * @abstract
427
-     * @return void
428
-     */
429
-    abstract public function load_scripts_styles();
430
-
431
-
432
-    /**
433
-     * admin_init
434
-     * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
435
-     * all pages/views loaded by child class.
436
-     *
437
-     * @abstract
438
-     * @return void
439
-     */
440
-    abstract public function admin_init();
441
-
442
-
443
-    /**
444
-     * admin_notices
445
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
446
-     * all pages/views loaded by child class.
447
-     *
448
-     * @abstract
449
-     * @return void
450
-     */
451
-    abstract public function admin_notices();
452
-
453
-
454
-    /**
455
-     * admin_footer_scripts
456
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
457
-     * will apply to all pages/views loaded by child class.
458
-     *
459
-     * @return void
460
-     */
461
-    abstract public function admin_footer_scripts();
462
-
463
-
464
-    /**
465
-     * admin_footer
466
-     * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
467
-     * apply to all pages/views loaded by child class.
468
-     *
469
-     * @return void
470
-     */
471
-    public function admin_footer()
472
-    {
473
-    }
474
-
475
-
476
-    /**
477
-     * _global_ajax_hooks
478
-     * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
479
-     * Note: within the ajax callback methods.
480
-     *
481
-     * @abstract
482
-     * @return void
483
-     */
484
-    protected function _global_ajax_hooks()
485
-    {
486
-        // for lazy loading of metabox content
487
-        add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
488
-    }
489
-
490
-
491
-    public function ajax_metabox_content()
492
-    {
493
-        $contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
494
-        $url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
495
-        self::cached_rss_display($contentid, $url);
496
-        wp_die();
497
-    }
498
-
499
-
500
-    /**
501
-     * _page_setup
502
-     * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
503
-     * doesn't match the object.
504
-     *
505
-     * @final
506
-     * @return void
507
-     * @throws EE_Error
508
-     * @throws InvalidArgumentException
509
-     * @throws ReflectionException
510
-     * @throws InvalidDataTypeException
511
-     * @throws InvalidInterfaceException
512
-     */
513
-    final protected function _page_setup()
514
-    {
515
-        // requires?
516
-        // admin_init stuff - global - we're setting this REALLY early
517
-        // so if EE_Admin pages have to hook into other WP pages they can.
518
-        // But keep in mind, not everything is available from the EE_Admin Page object at this point.
519
-        add_action('admin_init', array($this, 'admin_init_global'), 5);
520
-        // next verify if we need to load anything...
521
-        $this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
522
-        $this->page_folder = strtolower(
523
-            str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
524
-        );
525
-        global $ee_menu_slugs;
526
-        $ee_menu_slugs = (array) $ee_menu_slugs;
527
-        if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
528
-            return;
529
-        }
530
-        // 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
531
-        if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') {
532
-            $this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1'
533
-                ? $this->_req_data['action2']
534
-                : $this->_req_data['action'];
535
-        }
536
-        // then set blank or -1 action values to 'default'
537
-        $this->_req_action = isset($this->_req_data['action'])
538
-                             && ! empty($this->_req_data['action'])
539
-                             && $this->_req_data['action'] !== '-1'
540
-            ? sanitize_key($this->_req_data['action'])
541
-            : 'default';
542
-        // if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
543
-        //  This covers cases where we're coming in from a list table that isn't on the default route.
544
-        $this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
545
-            ? $this->_req_data['route'] : $this->_req_action;
546
-        // however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
547
-        $this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route'])
548
-            ? $this->_req_data['route']
549
-            : $this->_req_action;
550
-        $this->_current_view = $this->_req_action;
551
-        $this->_req_nonce = $this->_req_action . '_nonce';
552
-        $this->_define_page_props();
553
-        $this->_current_page_view_url = add_query_arg(
554
-            array('page' => $this->_current_page, 'action' => $this->_current_view),
555
-            $this->_admin_base_url
556
-        );
557
-        // default things
558
-        $this->_default_espresso_metaboxes = array(
559
-            '_espresso_news_post_box',
560
-            '_espresso_links_post_box',
561
-            '_espresso_ratings_request',
562
-            '_espresso_sponsors_post_box',
563
-        );
564
-        // set page configs
565
-        $this->_set_page_routes();
566
-        $this->_set_page_config();
567
-        // let's include any referrer data in our default_query_args for this route for "stickiness".
568
-        if (isset($this->_req_data['wp_referer'])) {
569
-            $this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
570
-        }
571
-        // for caffeinated and other extended functionality.
572
-        //  If there is a _extend_page_config method
573
-        // then let's run that to modify the all the various page configuration arrays
574
-        if (method_exists($this, '_extend_page_config')) {
575
-            $this->_extend_page_config();
576
-        }
577
-        // for CPT and other extended functionality.
578
-        // If there is an _extend_page_config_for_cpt
579
-        // then let's run that to modify all the various page configuration arrays.
580
-        if (method_exists($this, '_extend_page_config_for_cpt')) {
581
-            $this->_extend_page_config_for_cpt();
582
-        }
583
-        // filter routes and page_config so addons can add their stuff. Filtering done per class
584
-        $this->_page_routes = apply_filters(
585
-            'FHEE__' . get_class($this) . '__page_setup__page_routes',
586
-            $this->_page_routes,
587
-            $this
588
-        );
589
-        $this->_page_config = apply_filters(
590
-            'FHEE__' . get_class($this) . '__page_setup__page_config',
591
-            $this->_page_config,
592
-            $this
593
-        );
594
-        // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
595
-        // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
596
-        if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
597
-            add_action(
598
-                'AHEE__EE_Admin_Page__route_admin_request',
599
-                array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
600
-                10,
601
-                2
602
-            );
603
-        }
604
-        // next route only if routing enabled
605
-        if ($this->_routing && ! defined('DOING_AJAX')) {
606
-            $this->_verify_routes();
607
-            // next let's just check user_access and kill if no access
608
-            $this->check_user_access();
609
-            if ($this->_is_UI_request) {
610
-                // admin_init stuff - global, all views for this page class, specific view
611
-                add_action('admin_init', array($this, 'admin_init'), 10);
612
-                if (method_exists($this, 'admin_init_' . $this->_current_view)) {
613
-                    add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
614
-                }
615
-            } else {
616
-                // hijack regular WP loading and route admin request immediately
617
-                @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
618
-                $this->route_admin_request();
619
-            }
620
-        }
621
-    }
622
-
623
-
624
-    /**
625
-     * Provides a way for related child admin pages to load stuff on the loaded admin page.
626
-     *
627
-     * @return void
628
-     * @throws ReflectionException
629
-     * @throws EE_Error
630
-     */
631
-    private function _do_other_page_hooks()
632
-    {
633
-        $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
634
-        foreach ($registered_pages as $page) {
635
-            // now let's setup the file name and class that should be present
636
-            $classname = str_replace('.class.php', '', $page);
637
-            // autoloaders should take care of loading file
638
-            if (! class_exists($classname)) {
639
-                $error_msg[] = sprintf(
640
-                    esc_html__(
641
-                        'Something went wrong with loading the %s admin hooks page.',
642
-                        'event_espresso'
643
-                    ),
644
-                    $page
645
-                );
646
-                $error_msg[] = $error_msg[0]
647
-                               . "\r\n"
648
-                               . sprintf(
649
-                                   esc_html__(
650
-                                       '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',
651
-                                       'event_espresso'
652
-                                   ),
653
-                                   $page,
654
-                                   '<br />',
655
-                                   '<strong>' . $classname . '</strong>'
656
-                               );
657
-                throw new EE_Error(implode('||', $error_msg));
658
-            }
659
-            // // notice we are passing the instance of this class to the hook object.
660
-            $this->loader->getShared($classname, [$this]);
661
-        }
662
-    }
663
-
664
-
665
-    /**
666
-     * @throws DomainException
667
-     * @throws EE_Error
668
-     * @throws InvalidArgumentException
669
-     * @throws InvalidDataTypeException
670
-     * @throws InvalidInterfaceException
671
-     * @throws ReflectionException
672
-     * @since $VID:$
673
-     */
674
-    public function load_page_dependencies()
675
-    {
676
-        try {
677
-            $this->_load_page_dependencies();
678
-        } catch (EE_Error $e) {
679
-            $e->get_error();
680
-        }
681
-    }
682
-
683
-
684
-    /**
685
-     * load_page_dependencies
686
-     * loads things specific to this page class when its loaded.  Really helps with efficiency.
687
-     *
688
-     * @return void
689
-     * @throws DomainException
690
-     * @throws EE_Error
691
-     * @throws InvalidArgumentException
692
-     * @throws InvalidDataTypeException
693
-     * @throws InvalidInterfaceException
694
-     * @throws ReflectionException
695
-     */
696
-    protected function _load_page_dependencies()
697
-    {
698
-        // let's set the current_screen and screen options to override what WP set
699
-        $this->_current_screen = get_current_screen();
700
-        // load admin_notices - global, page class, and view specific
701
-        add_action('admin_notices', array($this, 'admin_notices_global'), 5);
702
-        add_action('admin_notices', array($this, 'admin_notices'), 10);
703
-        if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
704
-            add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
705
-        }
706
-        // load network admin_notices - global, page class, and view specific
707
-        add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
708
-        if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
709
-            add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
710
-        }
711
-        // this will save any per_page screen options if they are present
712
-        $this->_set_per_page_screen_options();
713
-        // setup list table properties
714
-        $this->_set_list_table();
715
-        // child classes can "register" a metabox to be automatically handled via the _page_config array property.
716
-        // However in some cases the metaboxes will need to be added within a route handling callback.
717
-        $this->_add_registered_meta_boxes();
718
-        $this->_add_screen_columns();
719
-        // add screen options - global, page child class, and view specific
720
-        $this->_add_global_screen_options();
721
-        $this->_add_screen_options();
722
-        $add_screen_options = "_add_screen_options_{$this->_current_view}";
723
-        if (method_exists($this, $add_screen_options)) {
724
-            $this->{$add_screen_options}();
725
-        }
726
-        // add help tab(s) and tours- set via page_config and qtips.
727
-        $this->_add_help_tour();
728
-        $this->_add_help_tabs();
729
-        $this->_add_qtips();
730
-        // add feature_pointers - global, page child class, and view specific
731
-        $this->_add_feature_pointers();
732
-        $this->_add_global_feature_pointers();
733
-        $add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
734
-        if (method_exists($this, $add_feature_pointer)) {
735
-            $this->{$add_feature_pointer}();
736
-        }
737
-        // enqueue scripts/styles - global, page class, and view specific
738
-        add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
739
-        add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
740
-        if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
741
-            add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
742
-        }
743
-        add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
744
-        // admin_print_footer_scripts - global, page child class, and view specific.
745
-        // NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
746
-        // In most cases that's doing_it_wrong().  But adding hidden container elements etc.
747
-        // is a good use case. Notice the late priority we're giving these
748
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
749
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
750
-        if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
751
-            add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
752
-        }
753
-        // admin footer scripts
754
-        add_action('admin_footer', array($this, 'admin_footer_global'), 99);
755
-        add_action('admin_footer', array($this, 'admin_footer'), 100);
756
-        if (method_exists($this, "admin_footer_{$this->_current_view}")) {
757
-            add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
758
-        }
759
-        do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
760
-        // targeted hook
761
-        do_action(
762
-            "FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
763
-        );
764
-    }
765
-
766
-
767
-    /**
768
-     * _set_defaults
769
-     * This sets some global defaults for class properties.
770
-     */
771
-    private function _set_defaults()
772
-    {
773
-        $this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
774
-        $this->_event = $this->_template_path = $this->_column_template_path = null;
775
-        $this->_nav_tabs = $this->_views = $this->_page_routes = array();
776
-        $this->_page_config = $this->_default_route_query_args = array();
777
-        $this->_default_nav_tab_name = 'overview';
778
-        // init template args
779
-        $this->_template_args = array(
780
-            'admin_page_header'  => '',
781
-            'admin_page_content' => '',
782
-            'post_body_content'  => '',
783
-            'before_list_table'  => '',
784
-            'after_list_table'   => '',
785
-        );
786
-    }
787
-
788
-
789
-    /**
790
-     * route_admin_request
791
-     *
792
-     * @see    _route_admin_request()
793
-     * @return exception|void error
794
-     * @throws InvalidArgumentException
795
-     * @throws InvalidInterfaceException
796
-     * @throws InvalidDataTypeException
797
-     * @throws EE_Error
798
-     * @throws ReflectionException
799
-     */
800
-    public function route_admin_request()
801
-    {
802
-        try {
803
-            $this->_route_admin_request();
804
-        } catch (EE_Error $e) {
805
-            $e->get_error();
806
-        }
807
-    }
808
-
809
-
810
-    public function set_wp_page_slug($wp_page_slug)
811
-    {
812
-        $this->_wp_page_slug = $wp_page_slug;
813
-        // if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
814
-        if (is_network_admin()) {
815
-            $this->_wp_page_slug .= '-network';
816
-        }
817
-    }
818
-
819
-
820
-    /**
821
-     * _verify_routes
822
-     * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
823
-     * we know if we need to drop out.
824
-     *
825
-     * @return bool
826
-     * @throws EE_Error
827
-     */
828
-    protected function _verify_routes()
829
-    {
830
-        if (! $this->_current_page && ! defined('DOING_AJAX')) {
831
-            return false;
832
-        }
833
-        $this->_route = false;
834
-        // check that the page_routes array is not empty
835
-        if (empty($this->_page_routes)) {
836
-            // user error msg
837
-            $error_msg = sprintf(
838
-                esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
839
-                $this->_admin_page_title
840
-            );
841
-            // developer error msg
842
-            $error_msg .= '||' . $error_msg
843
-                          . esc_html__(
844
-                              ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
845
-                              'event_espresso'
846
-                          );
847
-            throw new EE_Error($error_msg);
848
-        }
849
-        // and that the requested page route exists
850
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
851
-            $this->_route = $this->_page_routes[ $this->_req_action ];
852
-            $this->_route_config = isset($this->_page_config[ $this->_req_action ])
853
-                ? $this->_page_config[ $this->_req_action ] : array();
854
-        } else {
855
-            // user error msg
856
-            $error_msg = sprintf(
857
-                esc_html__(
858
-                    'The requested page route does not exist for the %s admin page.',
859
-                    'event_espresso'
860
-                ),
861
-                $this->_admin_page_title
862
-            );
863
-            // developer error msg
864
-            $error_msg .= '||' . $error_msg
865
-                          . sprintf(
866
-                              esc_html__(
867
-                                  ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
868
-                                  'event_espresso'
869
-                              ),
870
-                              $this->_req_action
871
-                          );
872
-            throw new EE_Error($error_msg);
873
-        }
874
-        // and that a default route exists
875
-        if (! array_key_exists('default', $this->_page_routes)) {
876
-            // user error msg
877
-            $error_msg = sprintf(
878
-                esc_html__(
879
-                    'A default page route has not been set for the % admin page.',
880
-                    'event_espresso'
881
-                ),
882
-                $this->_admin_page_title
883
-            );
884
-            // developer error msg
885
-            $error_msg .= '||' . $error_msg
886
-                          . esc_html__(
887
-                              ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
888
-                              'event_espresso'
889
-                          );
890
-            throw new EE_Error($error_msg);
891
-        }
892
-
893
-        // first lets' catch if the UI request has EVER been set.
894
-        if ($this->_is_UI_request === null) {
895
-            // lets set if this is a UI request or not.
896
-            $this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
897
-            // wait a minute... we might have a noheader in the route array
898
-            $this->_is_UI_request = is_array($this->_route)
899
-                                    && isset($this->_route['noheader'])
900
-                                    && $this->_route['noheader'] ? false : $this->_is_UI_request;
901
-        }
902
-        $this->_set_current_labels();
903
-        return true;
904
-    }
905
-
906
-
907
-    /**
908
-     * this method simply verifies a given route and makes sure its an actual route available for the loaded page
909
-     *
910
-     * @param  string $route the route name we're verifying
911
-     * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
912
-     * @throws EE_Error
913
-     */
914
-    protected function _verify_route($route)
915
-    {
916
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
917
-            return true;
918
-        }
919
-        // user error msg
920
-        $error_msg = sprintf(
921
-            esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
922
-            $this->_admin_page_title
923
-        );
924
-        // developer error msg
925
-        $error_msg .= '||' . $error_msg
926
-                      . sprintf(
927
-                          esc_html__(
928
-                              ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
929
-                              'event_espresso'
930
-                          ),
931
-                          $route
932
-                      );
933
-        throw new EE_Error($error_msg);
934
-    }
935
-
936
-
937
-    /**
938
-     * perform nonce verification
939
-     * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
940
-     * using this method (and save retyping!)
941
-     *
942
-     * @param string $nonce     The nonce sent
943
-     * @param string $nonce_ref The nonce reference string (name0)
944
-     * @return void
945
-     * @throws EE_Error
946
-     * @throws InvalidArgumentException
947
-     * @throws InvalidDataTypeException
948
-     * @throws InvalidInterfaceException
949
-     */
950
-    protected function _verify_nonce($nonce, $nonce_ref)
951
-    {
952
-        // verify nonce against expected value
953
-        if (! wp_verify_nonce($nonce, $nonce_ref)) {
954
-            // these are not the droids you are looking for !!!
955
-            $msg = sprintf(
956
-                esc_html__('%sNonce Fail.%s', 'event_espresso'),
957
-                '<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
958
-                '</a>'
959
-            );
960
-            if (WP_DEBUG) {
961
-                $msg .= "\n  "
962
-                        . sprintf(
963
-                            esc_html__(
964
-                                'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
965
-                                'event_espresso'
966
-                            ),
967
-                            __CLASS__
968
-                        );
969
-            }
970
-            if (! defined('DOING_AJAX')) {
971
-                wp_die($msg);
972
-            } else {
973
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
974
-                $this->_return_json();
975
-            }
976
-        }
977
-    }
978
-
979
-
980
-    /**
981
-     * _route_admin_request()
982
-     * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if there are
983
-     * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
984
-     * in the page routes and then will try to load the corresponding method.
985
-     *
986
-     * @return void
987
-     * @throws EE_Error
988
-     * @throws InvalidArgumentException
989
-     * @throws InvalidDataTypeException
990
-     * @throws InvalidInterfaceException
991
-     * @throws ReflectionException
992
-     */
993
-    protected function _route_admin_request()
994
-    {
995
-        if (! $this->_is_UI_request) {
996
-            $this->_verify_routes();
997
-        }
998
-        $nonce_check = isset($this->_route_config['require_nonce'])
999
-            ? $this->_route_config['require_nonce']
1000
-            : true;
1001
-        if ($this->_req_action !== 'default' && $nonce_check) {
1002
-            // set nonce from post data
1003
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
1004
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
1005
-                : '';
1006
-            $this->_verify_nonce($nonce, $this->_req_nonce);
1007
-        }
1008
-        // set the nav_tabs array but ONLY if this is  UI_request
1009
-        if ($this->_is_UI_request) {
1010
-            $this->_set_nav_tabs();
1011
-        }
1012
-        // grab callback function
1013
-        $func = is_array($this->_route) ? $this->_route['func'] : $this->_route;
1014
-        // check if callback has args
1015
-        $args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
1016
-        $error_msg = '';
1017
-        // action right before calling route
1018
-        // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1019
-        if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1020
-            do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1021
-        }
1022
-        // right before calling the route, let's remove _wp_http_referer from the
1023
-        // $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
1024
-        $_SERVER['REQUEST_URI'] = remove_query_arg(
1025
-            '_wp_http_referer',
1026
-            wp_unslash($_SERVER['REQUEST_URI'])
1027
-        );
1028
-        if (! empty($func)) {
1029
-            if (is_array($func)) {
1030
-                list($class, $method) = $func;
1031
-            } elseif (strpos($func, '::') !== false) {
1032
-                list($class, $method) = explode('::', $func);
1033
-            } else {
1034
-                $class = $this;
1035
-                $method = $func;
1036
-            }
1037
-            if (! (is_object($class) && $class === $this)) {
1038
-                // send along this admin page object for access by addons.
1039
-                $args['admin_page_object'] = $this;
1040
-            }
1041
-            // is it a method on a class that doesn't work?
1042
-            if (((method_exists($class, $method)
1043
-                  && call_user_func_array(array($class, $method), $args) === false)
1044
-                 && (// is it a standalone function that doesn't work?
1045
-                     function_exists($method)
1046
-                     && call_user_func_array(
1047
-                         $func,
1048
-                         array_merge(array('admin_page_object' => $this), $args)
1049
-                     ) === false
1050
-                 )) || (// is it neither a class method NOR a standalone function?
1051
-                    ! function_exists($method)
1052
-                    && ! method_exists($class, $method)
1053
-                )
1054
-            ) {
1055
-                // user error msg
1056
-                $error_msg = esc_html__(
1057
-                    'An error occurred. The  requested page route could not be found.',
1058
-                    'event_espresso'
1059
-                );
1060
-                // developer error msg
1061
-                $error_msg .= '||';
1062
-                $error_msg .= sprintf(
1063
-                    esc_html__(
1064
-                        'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1065
-                        'event_espresso'
1066
-                    ),
1067
-                    $method
1068
-                );
1069
-            }
1070
-            if (! empty($error_msg)) {
1071
-                throw new EE_Error($error_msg);
1072
-            }
1073
-        }
1074
-        // if we've routed and this route has a no headers route AND a sent_headers_route,
1075
-        // then we need to reset the routing properties to the new route.
1076
-        // 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.
1077
-        if ($this->_is_UI_request === false
1078
-            && is_array($this->_route)
1079
-            && ! empty($this->_route['headers_sent_route'])
1080
-        ) {
1081
-            $this->_reset_routing_properties($this->_route['headers_sent_route']);
1082
-        }
1083
-    }
1084
-
1085
-
1086
-    /**
1087
-     * This method just allows the resetting of page properties in the case where a no headers
1088
-     * route redirects to a headers route in its route config.
1089
-     *
1090
-     * @since   4.3.0
1091
-     * @param  string $new_route New (non header) route to redirect to.
1092
-     * @return   void
1093
-     * @throws ReflectionException
1094
-     * @throws InvalidArgumentException
1095
-     * @throws InvalidInterfaceException
1096
-     * @throws InvalidDataTypeException
1097
-     * @throws EE_Error
1098
-     */
1099
-    protected function _reset_routing_properties($new_route)
1100
-    {
1101
-        $this->_is_UI_request = true;
1102
-        // now we set the current route to whatever the headers_sent_route is set at
1103
-        $this->_req_data['action'] = $new_route;
1104
-        // rerun page setup
1105
-        $this->_page_setup();
1106
-    }
1107
-
1108
-
1109
-    /**
1110
-     * _add_query_arg
1111
-     * adds nonce to array of arguments then calls WP add_query_arg function
1112
-     *(internally just uses EEH_URL's function with the same name)
1113
-     *
1114
-     * @param array  $args
1115
-     * @param string $url
1116
-     * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1117
-     *                                        generated url in an associative array indexed by the key 'wp_referer';
1118
-     *                                        Example usage: If the current page is:
1119
-     *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1120
-     *                                        &action=default&event_id=20&month_range=March%202015
1121
-     *                                        &_wpnonce=5467821
1122
-     *                                        and you call:
1123
-     *                                        EE_Admin_Page::add_query_args_and_nonce(
1124
-     *                                        array(
1125
-     *                                        'action' => 'resend_something',
1126
-     *                                        'page=>espresso_registrations'
1127
-     *                                        ),
1128
-     *                                        $some_url,
1129
-     *                                        true
1130
-     *                                        );
1131
-     *                                        It will produce a url in this structure:
1132
-     *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1133
-     *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1134
-     *                                        month_range]=March%202015
1135
-     * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1136
-     * @return string
1137
-     */
1138
-    public static function add_query_args_and_nonce(
1139
-        $args = array(),
1140
-        $url = '',
1141
-        $sticky = false,
1142
-        $exclude_nonce = false
1143
-    ) {
1144
-        // if there is a _wp_http_referer include the values from the request but only if sticky = true
1145
-        if ($sticky) {
1146
-            $request = $_REQUEST;
1147
-            unset($request['_wp_http_referer'], $request['wp_referer']);
1148
-            foreach ($request as $key => $value) {
1149
-                // do not add nonces
1150
-                if (strpos($key, 'nonce') !== false) {
1151
-                    continue;
1152
-                }
1153
-                $args[ 'wp_referer[' . $key . ']' ] = $value;
1154
-            }
1155
-        }
1156
-        return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1157
-    }
1158
-
1159
-
1160
-    /**
1161
-     * This returns a generated link that will load the related help tab.
1162
-     *
1163
-     * @param  string $help_tab_id the id for the connected help tab
1164
-     * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1165
-     * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1166
-     * @uses EEH_Template::get_help_tab_link()
1167
-     * @return string              generated link
1168
-     */
1169
-    protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1170
-    {
1171
-        return EEH_Template::get_help_tab_link(
1172
-            $help_tab_id,
1173
-            $this->page_slug,
1174
-            $this->_req_action,
1175
-            $icon_style,
1176
-            $help_text
1177
-        );
1178
-    }
1179
-
1180
-
1181
-    /**
1182
-     * _add_help_tabs
1183
-     * Note child classes define their help tabs within the page_config array.
1184
-     *
1185
-     * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1186
-     * @return void
1187
-     * @throws DomainException
1188
-     * @throws EE_Error
1189
-     */
1190
-    protected function _add_help_tabs()
1191
-    {
1192
-        $tour_buttons = '';
1193
-        if (isset($this->_page_config[ $this->_req_action ])) {
1194
-            $config = $this->_page_config[ $this->_req_action ];
1195
-            // is there a help tour for the current route?  if there is let's setup the tour buttons
1196
-            if (isset($this->_help_tour[ $this->_req_action ])) {
1197
-                $tb = array();
1198
-                $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1199
-                foreach ($this->_help_tour['tours'] as $tour) {
1200
-                    // if this is the end tour then we don't need to setup a button
1201
-                    if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1202
-                        continue;
1203
-                    }
1204
-                    $tb[] = '<button id="trigger-tour-'
1205
-                            . $tour->get_slug()
1206
-                            . '" class="button-primary trigger-ee-help-tour">'
1207
-                            . $tour->get_label()
1208
-                            . '</button>';
1209
-                }
1210
-                $tour_buttons .= implode('<br />', $tb);
1211
-                $tour_buttons .= '</div></div>';
1212
-            }
1213
-            // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1214
-            if (is_array($config) && isset($config['help_sidebar'])) {
1215
-                // check that the callback given is valid
1216
-                if (! method_exists($this, $config['help_sidebar'])) {
1217
-                    throw new EE_Error(
1218
-                        sprintf(
1219
-                            esc_html__(
1220
-                                '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',
1221
-                                'event_espresso'
1222
-                            ),
1223
-                            $config['help_sidebar'],
1224
-                            get_class($this)
1225
-                        )
1226
-                    );
1227
-                }
1228
-                $content = apply_filters(
1229
-                    'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1230
-                    $this->{$config['help_sidebar']}()
1231
-                );
1232
-                $content .= $tour_buttons; // add help tour buttons.
1233
-                // do we have any help tours setup?  Cause if we do we want to add the buttons
1234
-                $this->_current_screen->set_help_sidebar($content);
1235
-            }
1236
-            // if there ARE tour buttons...
1237
-            if (! empty($tour_buttons)) {
1238
-                // if we DON'T have config help sidebar then we'll just add the tour buttons to the sidebar.
1239
-                if (! isset($config['help_sidebar'])) {
1240
-                    $this->_current_screen->set_help_sidebar($tour_buttons);
1241
-                }
1242
-                // handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1243
-                if (! isset($config['help_tabs'])) {
1244
-                    $_ht['id'] = $this->page_slug;
1245
-                    $_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1246
-                    $_ht['content'] = '<p>'
1247
-                                      . esc_html__(
1248
-                                          'The buttons to the right allow you to start/restart any help tours available for this page',
1249
-                                          'event_espresso'
1250
-                                      ) . '</p>';
1251
-                    $this->_current_screen->add_help_tab($_ht);
1252
-                }
1253
-            }
1254
-            if (! isset($config['help_tabs'])) {
1255
-                return;
1256
-            } //no help tabs for this route
1257
-            foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1258
-                // we're here so there ARE help tabs!
1259
-                // make sure we've got what we need
1260
-                if (! isset($cfg['title'])) {
1261
-                    throw new EE_Error(
1262
-                        esc_html__(
1263
-                            'The _page_config array is not set up properly for help tabs.  It is missing a title',
1264
-                            'event_espresso'
1265
-                        )
1266
-                    );
1267
-                }
1268
-                if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1269
-                    throw new EE_Error(
1270
-                        esc_html__(
1271
-                            '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',
1272
-                            'event_espresso'
1273
-                        )
1274
-                    );
1275
-                }
1276
-                // first priority goes to content.
1277
-                if (! empty($cfg['content'])) {
1278
-                    $content = ! empty($cfg['content']) ? $cfg['content'] : null;
1279
-                    // second priority goes to filename
1280
-                } elseif (! empty($cfg['filename'])) {
1281
-                    $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1282
-                    // 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)
1283
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1284
-                                                             . basename($this->_get_dir())
1285
-                                                             . '/help_tabs/'
1286
-                                                             . $cfg['filename']
1287
-                                                             . '.help_tab.php' : $file_path;
1288
-                    // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1289
-                    if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1290
-                        EE_Error::add_error(
1291
-                            sprintf(
1292
-                                esc_html__(
1293
-                                    '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',
1294
-                                    'event_espresso'
1295
-                                ),
1296
-                                $tab_id,
1297
-                                key($config),
1298
-                                $file_path
1299
-                            ),
1300
-                            __FILE__,
1301
-                            __FUNCTION__,
1302
-                            __LINE__
1303
-                        );
1304
-                        return;
1305
-                    }
1306
-                    $template_args['admin_page_obj'] = $this;
1307
-                    $content = EEH_Template::display_template(
1308
-                        $file_path,
1309
-                        $template_args,
1310
-                        true
1311
-                    );
1312
-                } else {
1313
-                    $content = '';
1314
-                }
1315
-                // check if callback is valid
1316
-                if (empty($content) && (
1317
-                        ! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1318
-                    )
1319
-                ) {
1320
-                    EE_Error::add_error(
1321
-                        sprintf(
1322
-                            esc_html__(
1323
-                                '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.',
1324
-                                'event_espresso'
1325
-                            ),
1326
-                            $cfg['title']
1327
-                        ),
1328
-                        __FILE__,
1329
-                        __FUNCTION__,
1330
-                        __LINE__
1331
-                    );
1332
-                    return;
1333
-                }
1334
-                // setup config array for help tab method
1335
-                $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1336
-                $_ht = array(
1337
-                    'id'       => $id,
1338
-                    'title'    => $cfg['title'],
1339
-                    'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1340
-                    'content'  => $content,
1341
-                );
1342
-                $this->_current_screen->add_help_tab($_ht);
1343
-            }
1344
-        }
1345
-    }
1346
-
1347
-
1348
-    /**
1349
-     * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1350
-     * an array with properties for setting up usage of the joyride plugin
1351
-     *
1352
-     * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1353
-     * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1354
-     *         _set_page_config() comments
1355
-     * @return void
1356
-     * @throws EE_Error
1357
-     * @throws InvalidArgumentException
1358
-     * @throws InvalidDataTypeException
1359
-     * @throws InvalidInterfaceException
1360
-     */
1361
-    protected function _add_help_tour()
1362
-    {
1363
-        $tours = array();
1364
-        $this->_help_tour = array();
1365
-        // exit early if help tours are turned off globally
1366
-        if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1367
-            || ! EE_Registry::instance()->CFG->admin->help_tour_activation
1368
-        ) {
1369
-            return;
1370
-        }
1371
-        // loop through _page_config to find any help_tour defined
1372
-        foreach ($this->_page_config as $route => $config) {
1373
-            // we're only going to set things up for this route
1374
-            if ($route !== $this->_req_action) {
1375
-                continue;
1376
-            }
1377
-            if (isset($config['help_tour'])) {
1378
-                foreach ($config['help_tour'] as $tour) {
1379
-                    $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1380
-                    // let's see if we can get that file...
1381
-                    // if not its possible this is a decaf route not set in caffeinated
1382
-                    // so lets try and get the caffeinated equivalent
1383
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1384
-                                                             . basename($this->_get_dir())
1385
-                                                             . '/help_tours/'
1386
-                                                             . $tour
1387
-                                                             . '.class.php' : $file_path;
1388
-                    // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1389
-                    if (! is_readable($file_path)) {
1390
-                        EE_Error::add_error(
1391
-                            sprintf(
1392
-                                esc_html__(
1393
-                                    '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',
1394
-                                    'event_espresso'
1395
-                                ),
1396
-                                $file_path,
1397
-                                $tour
1398
-                            ),
1399
-                            __FILE__,
1400
-                            __FUNCTION__,
1401
-                            __LINE__
1402
-                        );
1403
-                        return;
1404
-                    }
1405
-                    require_once $file_path;
1406
-                    if (! class_exists($tour)) {
1407
-                        $error_msg[] = sprintf(
1408
-                            esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1409
-                            $tour
1410
-                        );
1411
-                        $error_msg[] = $error_msg[0] . "\r\n"
1412
-                                       . sprintf(
1413
-                                           esc_html__(
1414
-                                               '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.',
1415
-                                               'event_espresso'
1416
-                                           ),
1417
-                                           $tour,
1418
-                                           '<br />',
1419
-                                           $tour,
1420
-                                           $this->_req_action,
1421
-                                           get_class($this)
1422
-                                       );
1423
-                        throw new EE_Error(implode('||', $error_msg));
1424
-                    }
1425
-                    $tour_obj = new $tour($this->_is_caf);
1426
-                    $tours[] = $tour_obj;
1427
-                    $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1428
-                }
1429
-                // let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1430
-                $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1431
-                $tours[] = $end_stop_tour;
1432
-                $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1433
-            }
1434
-        }
1435
-
1436
-        if (! empty($tours)) {
1437
-            $this->_help_tour['tours'] = $tours;
1438
-        }
1439
-        // that's it!  Now that the $_help_tours property is set (or not)
1440
-        // the scripts and html should be taken care of automatically.
1441
-
1442
-        /**
1443
-         * Allow extending the help tours variable.
1444
-         *
1445
-         * @param Array $_help_tour The array containing all help tour information to be displayed.
1446
-         */
1447
-        $this->_help_tour = apply_filters('FHEE__EE_Admin_Page___add_help_tour___help_tour', $this->_help_tour);
1448
-    }
1449
-
1450
-
1451
-    /**
1452
-     * This simply sets up any qtips that have been defined in the page config
1453
-     *
1454
-     * @return void
1455
-     */
1456
-    protected function _add_qtips()
1457
-    {
1458
-        if (isset($this->_route_config['qtips'])) {
1459
-            $qtips = (array) $this->_route_config['qtips'];
1460
-            // load qtip loader
1461
-            $path = array(
1462
-                $this->_get_dir() . '/qtips/',
1463
-                EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1464
-            );
1465
-            EEH_Qtip_Loader::instance()->register($qtips, $path);
1466
-        }
1467
-    }
1468
-
1469
-
1470
-    /**
1471
-     * _set_nav_tabs
1472
-     * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1473
-     * wish to add additional tabs or modify accordingly.
1474
-     *
1475
-     * @return void
1476
-     * @throws InvalidArgumentException
1477
-     * @throws InvalidInterfaceException
1478
-     * @throws InvalidDataTypeException
1479
-     */
1480
-    protected function _set_nav_tabs()
1481
-    {
1482
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1483
-        $i = 0;
1484
-        foreach ($this->_page_config as $slug => $config) {
1485
-            if (! is_array($config)
1486
-                || (
1487
-                    is_array($config)
1488
-                    && (
1489
-                        (isset($config['nav']) && ! $config['nav'])
1490
-                        || ! isset($config['nav'])
1491
-                    )
1492
-                )
1493
-            ) {
1494
-                continue;
1495
-            }
1496
-            // no nav tab for this config
1497
-            // check for persistent flag
1498
-            if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1499
-                // nav tab is only to appear when route requested.
1500
-                continue;
1501
-            }
1502
-            if (! $this->check_user_access($slug, true)) {
1503
-                // no nav tab because current user does not have access.
1504
-                continue;
1505
-            }
1506
-            $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1507
-            $this->_nav_tabs[ $slug ] = array(
1508
-                'url'       => isset($config['nav']['url'])
1509
-                    ? $config['nav']['url']
1510
-                    : self::add_query_args_and_nonce(
1511
-                        array('action' => $slug),
1512
-                        $this->_admin_base_url
1513
-                    ),
1514
-                'link_text' => isset($config['nav']['label'])
1515
-                    ? $config['nav']['label']
1516
-                    : ucwords(
1517
-                        str_replace('_', ' ', $slug)
1518
-                    ),
1519
-                'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1520
-                'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1521
-            );
1522
-            $i++;
1523
-        }
1524
-        // if $this->_nav_tabs is empty then lets set the default
1525
-        if (empty($this->_nav_tabs)) {
1526
-            $this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1527
-                'url'       => $this->_admin_base_url,
1528
-                'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1529
-                'css_class' => 'nav-tab-active',
1530
-                'order'     => 10,
1531
-            );
1532
-        }
1533
-        // now let's sort the tabs according to order
1534
-        usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1535
-    }
1536
-
1537
-
1538
-    /**
1539
-     * _set_current_labels
1540
-     * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1541
-     * property array
1542
-     *
1543
-     * @return void
1544
-     */
1545
-    private function _set_current_labels()
1546
-    {
1547
-        if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1548
-            foreach ($this->_route_config['labels'] as $label => $text) {
1549
-                if (is_array($text)) {
1550
-                    foreach ($text as $sublabel => $subtext) {
1551
-                        $this->_labels[ $label ][ $sublabel ] = $subtext;
1552
-                    }
1553
-                } else {
1554
-                    $this->_labels[ $label ] = $text;
1555
-                }
1556
-            }
1557
-        }
1558
-    }
1559
-
1560
-
1561
-    /**
1562
-     *        verifies user access for this admin page
1563
-     *
1564
-     * @param string $route_to_check if present then the capability for the route matching this string is checked.
1565
-     * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1566
-     *                               return false if verify fail.
1567
-     * @return bool
1568
-     * @throws InvalidArgumentException
1569
-     * @throws InvalidDataTypeException
1570
-     * @throws InvalidInterfaceException
1571
-     */
1572
-    public function check_user_access($route_to_check = '', $verify_only = false)
1573
-    {
1574
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1575
-        $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1576
-        $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1577
-                      && is_array(
1578
-                          $this->_page_routes[ $route_to_check ]
1579
-                      )
1580
-                      && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1581
-            ? $this->_page_routes[ $route_to_check ]['capability'] : null;
1582
-        if (empty($capability) && empty($route_to_check)) {
1583
-            $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1584
-                : $this->_route['capability'];
1585
-        } else {
1586
-            $capability = empty($capability) ? 'manage_options' : $capability;
1587
-        }
1588
-        $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1589
-        if (! defined('DOING_AJAX')
1590
-            && (
1591
-                ! function_exists('is_admin')
1592
-                || ! EE_Registry::instance()->CAP->current_user_can(
1593
-                    $capability,
1594
-                    $this->page_slug
1595
-                    . '_'
1596
-                    . $route_to_check,
1597
-                    $id
1598
-                )
1599
-            )
1600
-        ) {
1601
-            if ($verify_only) {
1602
-                return false;
1603
-            }
1604
-            if (is_user_logged_in()) {
1605
-                wp_die(__('You do not have access to this route.', 'event_espresso'));
1606
-            } else {
1607
-                return false;
1608
-            }
1609
-        }
1610
-        return true;
1611
-    }
1612
-
1613
-
1614
-    /**
1615
-     * admin_init_global
1616
-     * This runs all the code that we want executed within the WP admin_init hook.
1617
-     * This method executes for ALL EE Admin pages.
1618
-     *
1619
-     * @return void
1620
-     */
1621
-    public function admin_init_global()
1622
-    {
1623
-    }
1624
-
1625
-
1626
-    /**
1627
-     * wp_loaded_global
1628
-     * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1629
-     * EE_Admin page and will execute on every EE Admin Page load
1630
-     *
1631
-     * @return void
1632
-     */
1633
-    public function wp_loaded()
1634
-    {
1635
-    }
1636
-
1637
-
1638
-    /**
1639
-     * admin_notices
1640
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1641
-     * ALL EE_Admin pages.
1642
-     *
1643
-     * @return void
1644
-     */
1645
-    public function admin_notices_global()
1646
-    {
1647
-        $this->_display_no_javascript_warning();
1648
-        $this->_display_espresso_notices();
1649
-    }
1650
-
1651
-
1652
-    public function network_admin_notices_global()
1653
-    {
1654
-        $this->_display_no_javascript_warning();
1655
-        $this->_display_espresso_notices();
1656
-    }
1657
-
1658
-
1659
-    /**
1660
-     * admin_footer_scripts_global
1661
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1662
-     * will apply on ALL EE_Admin pages.
1663
-     *
1664
-     * @return void
1665
-     */
1666
-    public function admin_footer_scripts_global()
1667
-    {
1668
-        $this->_add_admin_page_ajax_loading_img();
1669
-        $this->_add_admin_page_overlay();
1670
-        // if metaboxes are present we need to add the nonce field
1671
-        if (isset($this->_route_config['metaboxes'])
1672
-            || isset($this->_route_config['list_table'])
1673
-            || (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1674
-        ) {
1675
-            wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1676
-            wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1677
-        }
1678
-    }
1679
-
1680
-
1681
-    /**
1682
-     * admin_footer_global
1683
-     * Anything triggered by the wp 'admin_footer' wp hook should be put in here.
1684
-     * This particular method will apply on ALL EE_Admin Pages.
1685
-     *
1686
-     * @return void
1687
-     * @throws InvalidArgumentException
1688
-     * @throws InvalidDataTypeException
1689
-     * @throws InvalidInterfaceException
1690
-     */
1691
-    public function admin_footer_global()
1692
-    {
1693
-        // dialog container for dialog helper
1694
-        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1695
-        $d_cont .= '<div class="ee-notices"></div>';
1696
-        $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1697
-        $d_cont .= '</div>';
1698
-        echo $d_cont;
1699
-        // help tour stuff?
1700
-        if (isset($this->_help_tour[ $this->_req_action ])) {
1701
-            echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1702
-        }
1703
-        // current set timezone for timezone js
1704
-        echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1705
-    }
1706
-
1707
-
1708
-    /**
1709
-     * This function sees if there is a method for help popup content existing for the given route.  If there is then
1710
-     * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1711
-     * help popups then in your templates or your content you set "triggers" for the content using the
1712
-     * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1713
-     * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1714
-     * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1715
-     * for the
1716
-     * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1717
-     * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1718
-     *    'help_trigger_id' => array(
1719
-     *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1720
-     *        'content' => esc_html__('localized content for popup', 'event_espresso')
1721
-     *    )
1722
-     * );
1723
-     * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1724
-     *
1725
-     * @param array $help_array
1726
-     * @param bool  $display
1727
-     * @return string content
1728
-     * @throws DomainException
1729
-     * @throws EE_Error
1730
-     */
1731
-    protected function _set_help_popup_content($help_array = array(), $display = false)
1732
-    {
1733
-        $content = '';
1734
-        $help_array = empty($help_array) ? $this->_get_help_content() : $help_array;
1735
-        // loop through the array and setup content
1736
-        foreach ($help_array as $trigger => $help) {
1737
-            // make sure the array is setup properly
1738
-            if (! isset($help['title'], $help['content'])) {
1739
-                throw new EE_Error(
1740
-                    esc_html__(
1741
-                        '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',
1742
-                        'event_espresso'
1743
-                    )
1744
-                );
1745
-            }
1746
-            // we're good so let'd setup the template vars and then assign parsed template content to our content.
1747
-            $template_args = array(
1748
-                'help_popup_id'      => $trigger,
1749
-                'help_popup_title'   => $help['title'],
1750
-                'help_popup_content' => $help['content'],
1751
-            );
1752
-            $content .= EEH_Template::display_template(
1753
-                EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1754
-                $template_args,
1755
-                true
1756
-            );
1757
-        }
1758
-        if ($display) {
1759
-            echo $content;
1760
-            return '';
1761
-        }
1762
-        return $content;
1763
-    }
1764
-
1765
-
1766
-    /**
1767
-     * All this does is retrieve the help content array if set by the EE_Admin_Page child
1768
-     *
1769
-     * @return array properly formatted array for help popup content
1770
-     * @throws EE_Error
1771
-     */
1772
-    private function _get_help_content()
1773
-    {
1774
-        // what is the method we're looking for?
1775
-        $method_name = '_help_popup_content_' . $this->_req_action;
1776
-        // if method doesn't exist let's get out.
1777
-        if (! method_exists($this, $method_name)) {
1778
-            return array();
1779
-        }
1780
-        // k we're good to go let's retrieve the help array
1781
-        $help_array = $this->{$method_name}();
1782
-        // make sure we've got an array!
1783
-        if (! is_array($help_array)) {
1784
-            throw new EE_Error(
1785
-                esc_html__(
1786
-                    'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1787
-                    'event_espresso'
1788
-                )
1789
-            );
1790
-        }
1791
-        return $help_array;
1792
-    }
1793
-
1794
-
1795
-    /**
1796
-     * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1797
-     * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1798
-     * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1799
-     *
1800
-     * @param string  $trigger_id reference for retrieving the trigger content for the popup
1801
-     * @param boolean $display    if false then we return the trigger string
1802
-     * @param array   $dimensions an array of dimensions for the box (array(h,w))
1803
-     * @return string
1804
-     * @throws DomainException
1805
-     * @throws EE_Error
1806
-     */
1807
-    protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1808
-    {
1809
-        if (defined('DOING_AJAX')) {
1810
-            return '';
1811
-        }
1812
-        // 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
1813
-        $help_array = $this->_get_help_content();
1814
-        $help_content = '';
1815
-        if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1816
-            $help_array[ $trigger_id ] = array(
1817
-                'title'   => esc_html__('Missing Content', 'event_espresso'),
1818
-                'content' => esc_html__(
1819
-                    '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.)',
1820
-                    'event_espresso'
1821
-                ),
1822
-            );
1823
-            $help_content = $this->_set_help_popup_content($help_array);
1824
-        }
1825
-        // let's setup the trigger
1826
-        $content = '<a class="ee-dialog" href="?height='
1827
-                   . $dimensions[0]
1828
-                   . '&width='
1829
-                   . $dimensions[1]
1830
-                   . '&inlineId='
1831
-                   . $trigger_id
1832
-                   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1833
-        $content .= $help_content;
1834
-        if ($display) {
1835
-            echo $content;
1836
-            return '';
1837
-        }
1838
-        return $content;
1839
-    }
1840
-
1841
-
1842
-    /**
1843
-     * _add_global_screen_options
1844
-     * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1845
-     * This particular method will add_screen_options on ALL EE_Admin Pages
1846
-     *
1847
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1848
-     *         see also WP_Screen object documents...
1849
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1850
-     * @abstract
1851
-     * @return void
1852
-     */
1853
-    private function _add_global_screen_options()
1854
-    {
1855
-    }
1856
-
1857
-
1858
-    /**
1859
-     * _add_global_feature_pointers
1860
-     * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1861
-     * This particular method will implement feature pointers for ALL EE_Admin pages.
1862
-     * Note: this is just a placeholder for now.  Implementation will come down the road
1863
-     *
1864
-     * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1865
-     *         extended) also see:
1866
-     * @link   http://eamann.com/tech/wordpress-portland/
1867
-     * @abstract
1868
-     * @return void
1869
-     */
1870
-    private function _add_global_feature_pointers()
1871
-    {
1872
-    }
1873
-
1874
-
1875
-    /**
1876
-     * load_global_scripts_styles
1877
-     * The scripts and styles enqueued in here will be loaded on every EE Admin page
1878
-     *
1879
-     * @return void
1880
-     * @throws EE_Error
1881
-     */
1882
-    public function load_global_scripts_styles()
1883
-    {
1884
-        /** STYLES **/
1885
-        // add debugging styles
1886
-        if (WP_DEBUG) {
1887
-            add_action('admin_head', array($this, 'add_xdebug_style'));
1888
-        }
1889
-        // register all styles
1890
-        wp_register_style(
1891
-            'espresso-ui-theme',
1892
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1893
-            array(),
1894
-            EVENT_ESPRESSO_VERSION
1895
-        );
1896
-        wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1897
-        // helpers styles
1898
-        wp_register_style(
1899
-            'ee-text-links',
1900
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1901
-            array(),
1902
-            EVENT_ESPRESSO_VERSION
1903
-        );
1904
-        /** SCRIPTS **/
1905
-        // register all scripts
1906
-        wp_register_script(
1907
-            'ee-dialog',
1908
-            EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1909
-            array('jquery', 'jquery-ui-draggable'),
1910
-            EVENT_ESPRESSO_VERSION,
1911
-            true
1912
-        );
1913
-        wp_register_script(
1914
-            'ee_admin_js',
1915
-            EE_ADMIN_URL . 'assets/ee-admin-page.js',
1916
-            array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1917
-            EVENT_ESPRESSO_VERSION,
1918
-            true
1919
-        );
1920
-        wp_register_script(
1921
-            'jquery-ui-timepicker-addon',
1922
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1923
-            array('jquery-ui-datepicker', 'jquery-ui-slider'),
1924
-            EVENT_ESPRESSO_VERSION,
1925
-            true
1926
-        );
1927
-        if (EE_Registry::instance()->CFG->admin->help_tour_activation) {
1928
-            add_filter('FHEE_load_joyride', '__return_true');
1929
-        }
1930
-        // script for sorting tables
1931
-        wp_register_script(
1932
-            'espresso_ajax_table_sorting',
1933
-            EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1934
-            array('ee_admin_js', 'jquery-ui-sortable'),
1935
-            EVENT_ESPRESSO_VERSION,
1936
-            true
1937
-        );
1938
-        // script for parsing uri's
1939
-        wp_register_script(
1940
-            'ee-parse-uri',
1941
-            EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1942
-            array(),
1943
-            EVENT_ESPRESSO_VERSION,
1944
-            true
1945
-        );
1946
-        // and parsing associative serialized form elements
1947
-        wp_register_script(
1948
-            'ee-serialize-full-array',
1949
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1950
-            array('jquery'),
1951
-            EVENT_ESPRESSO_VERSION,
1952
-            true
1953
-        );
1954
-        // helpers scripts
1955
-        wp_register_script(
1956
-            'ee-text-links',
1957
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1958
-            array('jquery'),
1959
-            EVENT_ESPRESSO_VERSION,
1960
-            true
1961
-        );
1962
-        wp_register_script(
1963
-            'ee-moment-core',
1964
-            EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1965
-            array(),
1966
-            EVENT_ESPRESSO_VERSION,
1967
-            true
1968
-        );
1969
-        wp_register_script(
1970
-            'ee-moment',
1971
-            EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1972
-            array('ee-moment-core'),
1973
-            EVENT_ESPRESSO_VERSION,
1974
-            true
1975
-        );
1976
-        wp_register_script(
1977
-            'ee-datepicker',
1978
-            EE_ADMIN_URL . 'assets/ee-datepicker.js',
1979
-            array('jquery-ui-timepicker-addon', 'ee-moment'),
1980
-            EVENT_ESPRESSO_VERSION,
1981
-            true
1982
-        );
1983
-        // google charts
1984
-        wp_register_script(
1985
-            'google-charts',
1986
-            'https://www.gstatic.com/charts/loader.js',
1987
-            array(),
1988
-            EVENT_ESPRESSO_VERSION
1989
-        );
1990
-        // ENQUEUE ALL BASICS BY DEFAULT
1991
-        wp_enqueue_style('ee-admin-css');
1992
-        wp_enqueue_script('ee_admin_js');
1993
-        wp_enqueue_script('ee-accounting');
1994
-        wp_enqueue_script('jquery-validate');
1995
-        // taking care of metaboxes
1996
-        if (empty($this->_cpt_route)
1997
-            && (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
1998
-        ) {
1999
-            wp_enqueue_script('dashboard');
2000
-        }
2001
-        // LOCALIZED DATA
2002
-        // localize script for ajax lazy loading
2003
-        $lazy_loader_container_ids = apply_filters(
2004
-            'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
2005
-            array('espresso_news_post_box_content')
2006
-        );
2007
-        wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
2008
-        /**
2009
-         * help tour stuff
2010
-         */
2011
-        if (! empty($this->_help_tour)) {
2012
-            // register the js for kicking things off
2013
-            wp_enqueue_script(
2014
-                'ee-help-tour',
2015
-                EE_ADMIN_URL . 'assets/ee-help-tour.js',
2016
-                array('jquery-joyride'),
2017
-                EVENT_ESPRESSO_VERSION,
2018
-                true
2019
-            );
2020
-            $tours = array();
2021
-            // setup tours for the js tour object
2022
-            foreach ($this->_help_tour['tours'] as $tour) {
2023
-                if ($tour instanceof EE_Help_Tour) {
2024
-                    $tours[] = array(
2025
-                        'id'      => $tour->get_slug(),
2026
-                        'options' => $tour->get_options(),
2027
-                    );
2028
-                }
2029
-            }
2030
-            wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2031
-            // admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2032
-        }
2033
-    }
2034
-
2035
-
2036
-    /**
2037
-     *        admin_footer_scripts_eei18n_js_strings
2038
-     *
2039
-     * @return        void
2040
-     */
2041
-    public function admin_footer_scripts_eei18n_js_strings()
2042
-    {
2043
-        EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL;
2044
-        EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__(
2045
-            '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!!!',
2046
-            'event_espresso'
2047
-        );
2048
-        EE_Registry::$i18n_js_strings['January'] = esc_html__('January', 'event_espresso');
2049
-        EE_Registry::$i18n_js_strings['February'] = esc_html__('February', 'event_espresso');
2050
-        EE_Registry::$i18n_js_strings['March'] = esc_html__('March', 'event_espresso');
2051
-        EE_Registry::$i18n_js_strings['April'] = esc_html__('April', 'event_espresso');
2052
-        EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2053
-        EE_Registry::$i18n_js_strings['June'] = esc_html__('June', 'event_espresso');
2054
-        EE_Registry::$i18n_js_strings['July'] = esc_html__('July', 'event_espresso');
2055
-        EE_Registry::$i18n_js_strings['August'] = esc_html__('August', 'event_espresso');
2056
-        EE_Registry::$i18n_js_strings['September'] = esc_html__('September', 'event_espresso');
2057
-        EE_Registry::$i18n_js_strings['October'] = esc_html__('October', 'event_espresso');
2058
-        EE_Registry::$i18n_js_strings['November'] = esc_html__('November', 'event_espresso');
2059
-        EE_Registry::$i18n_js_strings['December'] = esc_html__('December', 'event_espresso');
2060
-        EE_Registry::$i18n_js_strings['Jan'] = esc_html__('Jan', 'event_espresso');
2061
-        EE_Registry::$i18n_js_strings['Feb'] = esc_html__('Feb', 'event_espresso');
2062
-        EE_Registry::$i18n_js_strings['Mar'] = esc_html__('Mar', 'event_espresso');
2063
-        EE_Registry::$i18n_js_strings['Apr'] = esc_html__('Apr', 'event_espresso');
2064
-        EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2065
-        EE_Registry::$i18n_js_strings['Jun'] = esc_html__('Jun', 'event_espresso');
2066
-        EE_Registry::$i18n_js_strings['Jul'] = esc_html__('Jul', 'event_espresso');
2067
-        EE_Registry::$i18n_js_strings['Aug'] = esc_html__('Aug', 'event_espresso');
2068
-        EE_Registry::$i18n_js_strings['Sep'] = esc_html__('Sep', 'event_espresso');
2069
-        EE_Registry::$i18n_js_strings['Oct'] = esc_html__('Oct', 'event_espresso');
2070
-        EE_Registry::$i18n_js_strings['Nov'] = esc_html__('Nov', 'event_espresso');
2071
-        EE_Registry::$i18n_js_strings['Dec'] = esc_html__('Dec', 'event_espresso');
2072
-        EE_Registry::$i18n_js_strings['Sunday'] = esc_html__('Sunday', 'event_espresso');
2073
-        EE_Registry::$i18n_js_strings['Monday'] = esc_html__('Monday', 'event_espresso');
2074
-        EE_Registry::$i18n_js_strings['Tuesday'] = esc_html__('Tuesday', 'event_espresso');
2075
-        EE_Registry::$i18n_js_strings['Wednesday'] = esc_html__('Wednesday', 'event_espresso');
2076
-        EE_Registry::$i18n_js_strings['Thursday'] = esc_html__('Thursday', 'event_espresso');
2077
-        EE_Registry::$i18n_js_strings['Friday'] = esc_html__('Friday', 'event_espresso');
2078
-        EE_Registry::$i18n_js_strings['Saturday'] = esc_html__('Saturday', 'event_espresso');
2079
-        EE_Registry::$i18n_js_strings['Sun'] = esc_html__('Sun', 'event_espresso');
2080
-        EE_Registry::$i18n_js_strings['Mon'] = esc_html__('Mon', 'event_espresso');
2081
-        EE_Registry::$i18n_js_strings['Tue'] = esc_html__('Tue', 'event_espresso');
2082
-        EE_Registry::$i18n_js_strings['Wed'] = esc_html__('Wed', 'event_espresso');
2083
-        EE_Registry::$i18n_js_strings['Thu'] = esc_html__('Thu', 'event_espresso');
2084
-        EE_Registry::$i18n_js_strings['Fri'] = esc_html__('Fri', 'event_espresso');
2085
-        EE_Registry::$i18n_js_strings['Sat'] = esc_html__('Sat', 'event_espresso');
2086
-    }
2087
-
2088
-
2089
-    /**
2090
-     *        load enhanced xdebug styles for ppl with failing eyesight
2091
-     *
2092
-     * @return        void
2093
-     */
2094
-    public function add_xdebug_style()
2095
-    {
2096
-        echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2097
-    }
2098
-
2099
-
2100
-    /************************/
2101
-    /** LIST TABLE METHODS **/
2102
-    /************************/
2103
-    /**
2104
-     * this sets up the list table if the current view requires it.
2105
-     *
2106
-     * @return void
2107
-     * @throws EE_Error
2108
-     * @throws InvalidArgumentException
2109
-     * @throws InvalidDataTypeException
2110
-     * @throws InvalidInterfaceException
2111
-     */
2112
-    protected function _set_list_table()
2113
-    {
2114
-        // first is this a list_table view?
2115
-        if (! isset($this->_route_config['list_table'])) {
2116
-            return;
2117
-        } //not a list_table view so get out.
2118
-        // list table functions are per view specific (because some admin pages might have more than one list table!)
2119
-        $list_table_view = '_set_list_table_views_' . $this->_req_action;
2120
-        if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2121
-            // user error msg
2122
-            $error_msg = esc_html__(
2123
-                'An error occurred. The requested list table views could not be found.',
2124
-                'event_espresso'
2125
-            );
2126
-            // developer error msg
2127
-            $error_msg .= '||'
2128
-                          . sprintf(
2129
-                              esc_html__(
2130
-                                  '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.',
2131
-                                  'event_espresso'
2132
-                              ),
2133
-                              $this->_req_action,
2134
-                              $list_table_view
2135
-                          );
2136
-            throw new EE_Error($error_msg);
2137
-        }
2138
-        // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2139
-        $this->_views = apply_filters(
2140
-            'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2141
-            $this->_views
2142
-        );
2143
-        $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2144
-        $this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2145
-        $this->_set_list_table_view();
2146
-        $this->_set_list_table_object();
2147
-    }
2148
-
2149
-
2150
-    /**
2151
-     * set current view for List Table
2152
-     *
2153
-     * @return void
2154
-     */
2155
-    protected function _set_list_table_view()
2156
-    {
2157
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2158
-        // looking at active items or dumpster diving ?
2159
-        if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2160
-            $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2161
-        } else {
2162
-            $this->_view = sanitize_key($this->_req_data['status']);
2163
-        }
2164
-    }
2165
-
2166
-
2167
-    /**
2168
-     * _set_list_table_object
2169
-     * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2170
-     *
2171
-     * @throws InvalidInterfaceException
2172
-     * @throws InvalidArgumentException
2173
-     * @throws InvalidDataTypeException
2174
-     * @throws EE_Error
2175
-     * @throws InvalidInterfaceException
2176
-     */
2177
-    protected function _set_list_table_object()
2178
-    {
2179
-        if (isset($this->_route_config['list_table'])) {
2180
-            if (! class_exists($this->_route_config['list_table'])) {
2181
-                throw new EE_Error(
2182
-                    sprintf(
2183
-                        esc_html__(
2184
-                            '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.',
2185
-                            'event_espresso'
2186
-                        ),
2187
-                        $this->_route_config['list_table'],
2188
-                        get_class($this)
2189
-                    )
2190
-                );
2191
-            }
2192
-            $this->_list_table_object = $this->loader->getShared(
2193
-                $this->_route_config['list_table'],
2194
-                array($this)
2195
-            );
2196
-        }
2197
-    }
2198
-
2199
-
2200
-    /**
2201
-     * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2202
-     *
2203
-     * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2204
-     *                                                    urls.  The array should be indexed by the view it is being
2205
-     *                                                    added to.
2206
-     * @return array
2207
-     */
2208
-    public function get_list_table_view_RLs($extra_query_args = array())
2209
-    {
2210
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2211
-        if (empty($this->_views)) {
2212
-            $this->_views = array();
2213
-        }
2214
-        // cycle thru views
2215
-        foreach ($this->_views as $key => $view) {
2216
-            $query_args = array();
2217
-            // check for current view
2218
-            $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2219
-            $query_args['action'] = $this->_req_action;
2220
-            $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2221
-            $query_args['status'] = $view['slug'];
2222
-            // merge any other arguments sent in.
2223
-            if (isset($extra_query_args[ $view['slug'] ])) {
2224
-                foreach ($extra_query_args[ $view['slug'] ] as $extra_query_arg) {
2225
-                    $query_args[] = $extra_query_arg;
2226
-                }
2227
-            }
2228
-            $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2229
-        }
2230
-        return $this->_views;
2231
-    }
2232
-
2233
-
2234
-    /**
2235
-     * _entries_per_page_dropdown
2236
-     * generates a drop down box for selecting the number of visible rows in an admin page list table
2237
-     *
2238
-     * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2239
-     *         WP does it.
2240
-     * @param int $max_entries total number of rows in the table
2241
-     * @return string
2242
-     */
2243
-    protected function _entries_per_page_dropdown($max_entries = 0)
2244
-    {
2245
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2246
-        $values = array(10, 25, 50, 100);
2247
-        $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2248
-        if ($max_entries) {
2249
-            $values[] = $max_entries;
2250
-            sort($values);
2251
-        }
2252
-        $entries_per_page_dropdown = '
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;
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
+	}
201
+
202
+
203
+	/**
204
+	 * This logic used to be in the constructor, but that caused a chicken <--> egg scenario
205
+	 * for child classes that needed to set properties prior to these methods getting called,
206
+	 * but also needed the parent class to have its construction completed as well.
207
+	 * Bottom line is that constructors should ONLY be used for setting initial properties
208
+	 * and any complex initialization logic should only run after instantiation is complete.
209
+	 *
210
+	 * This method gets called immediately after construction from within
211
+	 *      EE_Admin_Page_Init::_initialize_admin_page()
212
+	 *
213
+	 * @throws EE_Error
214
+	 * @throws InvalidArgumentException
215
+	 * @throws InvalidDataTypeException
216
+	 * @throws InvalidInterfaceException
217
+	 * @throws ReflectionException
218
+	 * @since $VID:$
219
+	 */
220
+	public function initializePage()
221
+	{
222
+		// set initial page props (child method)
223
+		$this->_init_page_props();
224
+		// set global defaults
225
+		$this->_set_defaults();
226
+		// set early because incoming requests could be ajax related and we need to register those hooks.
227
+		$this->_global_ajax_hooks();
228
+		$this->_ajax_hooks();
229
+		// other_page_hooks have to be early too.
230
+		$this->_do_other_page_hooks();
231
+		// This just allows us to have extending classes do something specific
232
+		// before the parent constructor runs _page_setup().
233
+		if (method_exists($this, '_before_page_setup')) {
234
+			$this->_before_page_setup();
235
+		}
236
+		// set up page dependencies
237
+		$this->_page_setup();
238
+	}
239
+
240
+
241
+	/**
242
+	 * _init_page_props
243
+	 * Child classes use to set at least the following properties:
244
+	 * $page_slug.
245
+	 * $page_label.
246
+	 *
247
+	 * @abstract
248
+	 * @return void
249
+	 */
250
+	abstract protected function _init_page_props();
251
+
252
+
253
+	/**
254
+	 * _ajax_hooks
255
+	 * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
256
+	 * Note: within the ajax callback methods.
257
+	 *
258
+	 * @abstract
259
+	 * @return void
260
+	 */
261
+	abstract protected function _ajax_hooks();
262
+
263
+
264
+	/**
265
+	 * _define_page_props
266
+	 * child classes define page properties in here.  Must include at least:
267
+	 * $_admin_base_url = base_url for all admin pages
268
+	 * $_admin_page_title = default admin_page_title for admin pages
269
+	 * $_labels = array of default labels for various automatically generated elements:
270
+	 *    array(
271
+	 *        'buttons' => array(
272
+	 *            'add' => esc_html__('label for add new button'),
273
+	 *            'edit' => esc_html__('label for edit button'),
274
+	 *            'delete' => esc_html__('label for delete button')
275
+	 *            )
276
+	 *        )
277
+	 *
278
+	 * @abstract
279
+	 * @return void
280
+	 */
281
+	abstract protected function _define_page_props();
282
+
283
+
284
+	/**
285
+	 * _set_page_routes
286
+	 * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
287
+	 * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
288
+	 * have a 'default' route. Here's the format
289
+	 * $this->_page_routes = array(
290
+	 *        'default' => array(
291
+	 *            'func' => '_default_method_handling_route',
292
+	 *            'args' => array('array','of','args'),
293
+	 *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
294
+	 *            ajax request, backend processing)
295
+	 *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
296
+	 *            headers route after.  The string you enter here should match the defined route reference for a
297
+	 *            headers sent route.
298
+	 *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
299
+	 *            this route.
300
+	 *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
301
+	 *            checks).
302
+	 *        ),
303
+	 *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
304
+	 *        handling method.
305
+	 *        )
306
+	 * )
307
+	 *
308
+	 * @abstract
309
+	 * @return void
310
+	 */
311
+	abstract protected function _set_page_routes();
312
+
313
+
314
+	/**
315
+	 * _set_page_config
316
+	 * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
317
+	 * array corresponds to the page_route for the loaded page. Format:
318
+	 * $this->_page_config = array(
319
+	 *        'default' => array(
320
+	 *            'labels' => array(
321
+	 *                'buttons' => array(
322
+	 *                    'add' => esc_html__('label for adding item'),
323
+	 *                    'edit' => esc_html__('label for editing item'),
324
+	 *                    'delete' => esc_html__('label for deleting item')
325
+	 *                ),
326
+	 *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
327
+	 *            ), //optional an array of custom labels for various automatically generated elements to use on the
328
+	 *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
329
+	 *            _define_page_props() method
330
+	 *            'nav' => array(
331
+	 *                'label' => esc_html__('Label for Tab', 'event_espresso').
332
+	 *                'url' => 'http://someurl', //automatically generated UNLESS you define
333
+	 *                'css_class' => 'css-class', //automatically generated UNLESS you define
334
+	 *                'order' => 10, //required to indicate tab position.
335
+	 *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
336
+	 *                displayed then add this parameter.
337
+	 *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
338
+	 *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
339
+	 *            metaboxes set for eventespresso admin pages.
340
+	 *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
341
+	 *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
342
+	 *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
343
+	 *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
344
+	 *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
345
+	 *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
346
+	 *            array indicates the max number of columns (4) and the default number of columns on page load (2).
347
+	 *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
348
+	 *            want to display.
349
+	 *            'help_tabs' => array( //this is used for adding help tabs to a page
350
+	 *                'tab_id' => array(
351
+	 *                    'title' => 'tab_title',
352
+	 *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
353
+	 *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
354
+	 *                    should match a file in the admin folder's "help_tabs" dir (ie..
355
+	 *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
356
+	 *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
357
+	 *                    attempt to use the callback which should match the name of a method in the class
358
+	 *                    ),
359
+	 *                'tab2_id' => array(
360
+	 *                    'title' => 'tab2 title',
361
+	 *                    'filename' => 'file_name_2'
362
+	 *                    'callback' => 'callback_method_for_content',
363
+	 *                 ),
364
+	 *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
365
+	 *            help tab area on an admin page. @link
366
+	 *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
367
+	 *            'help_tour' => array(
368
+	 *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
369
+	 *                in a folder for this admin page named "help_tours", a file name matching the key given here
370
+	 *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
371
+	 *            ),
372
+	 *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
373
+	 *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
374
+	 *            just set
375
+	 *            'require_nonce' to FALSE
376
+	 *            )
377
+	 * )
378
+	 *
379
+	 * @abstract
380
+	 * @return void
381
+	 */
382
+	abstract protected function _set_page_config();
383
+
384
+
385
+
386
+
387
+
388
+	/** end sample help_tour methods **/
389
+	/**
390
+	 * _add_screen_options
391
+	 * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
392
+	 * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
393
+	 * to a particular view.
394
+	 *
395
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
396
+	 *         see also WP_Screen object documents...
397
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
398
+	 * @abstract
399
+	 * @return void
400
+	 */
401
+	abstract protected function _add_screen_options();
402
+
403
+
404
+	/**
405
+	 * _add_feature_pointers
406
+	 * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
407
+	 * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
408
+	 * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
409
+	 * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
410
+	 * extended) also see:
411
+	 *
412
+	 * @link   http://eamann.com/tech/wordpress-portland/
413
+	 * @abstract
414
+	 * @return void
415
+	 */
416
+	abstract protected function _add_feature_pointers();
417
+
418
+
419
+	/**
420
+	 * load_scripts_styles
421
+	 * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
422
+	 * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
423
+	 * scripts/styles per view by putting them in a dynamic function in this format
424
+	 * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
425
+	 *
426
+	 * @abstract
427
+	 * @return void
428
+	 */
429
+	abstract public function load_scripts_styles();
430
+
431
+
432
+	/**
433
+	 * admin_init
434
+	 * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
435
+	 * all pages/views loaded by child class.
436
+	 *
437
+	 * @abstract
438
+	 * @return void
439
+	 */
440
+	abstract public function admin_init();
441
+
442
+
443
+	/**
444
+	 * admin_notices
445
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
446
+	 * all pages/views loaded by child class.
447
+	 *
448
+	 * @abstract
449
+	 * @return void
450
+	 */
451
+	abstract public function admin_notices();
452
+
453
+
454
+	/**
455
+	 * admin_footer_scripts
456
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
457
+	 * will apply to all pages/views loaded by child class.
458
+	 *
459
+	 * @return void
460
+	 */
461
+	abstract public function admin_footer_scripts();
462
+
463
+
464
+	/**
465
+	 * admin_footer
466
+	 * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
467
+	 * apply to all pages/views loaded by child class.
468
+	 *
469
+	 * @return void
470
+	 */
471
+	public function admin_footer()
472
+	{
473
+	}
474
+
475
+
476
+	/**
477
+	 * _global_ajax_hooks
478
+	 * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
479
+	 * Note: within the ajax callback methods.
480
+	 *
481
+	 * @abstract
482
+	 * @return void
483
+	 */
484
+	protected function _global_ajax_hooks()
485
+	{
486
+		// for lazy loading of metabox content
487
+		add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
488
+	}
489
+
490
+
491
+	public function ajax_metabox_content()
492
+	{
493
+		$contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
494
+		$url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
495
+		self::cached_rss_display($contentid, $url);
496
+		wp_die();
497
+	}
498
+
499
+
500
+	/**
501
+	 * _page_setup
502
+	 * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
503
+	 * doesn't match the object.
504
+	 *
505
+	 * @final
506
+	 * @return void
507
+	 * @throws EE_Error
508
+	 * @throws InvalidArgumentException
509
+	 * @throws ReflectionException
510
+	 * @throws InvalidDataTypeException
511
+	 * @throws InvalidInterfaceException
512
+	 */
513
+	final protected function _page_setup()
514
+	{
515
+		// requires?
516
+		// admin_init stuff - global - we're setting this REALLY early
517
+		// so if EE_Admin pages have to hook into other WP pages they can.
518
+		// But keep in mind, not everything is available from the EE_Admin Page object at this point.
519
+		add_action('admin_init', array($this, 'admin_init_global'), 5);
520
+		// next verify if we need to load anything...
521
+		$this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
522
+		$this->page_folder = strtolower(
523
+			str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
524
+		);
525
+		global $ee_menu_slugs;
526
+		$ee_menu_slugs = (array) $ee_menu_slugs;
527
+		if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
528
+			return;
529
+		}
530
+		// 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
531
+		if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') {
532
+			$this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1'
533
+				? $this->_req_data['action2']
534
+				: $this->_req_data['action'];
535
+		}
536
+		// then set blank or -1 action values to 'default'
537
+		$this->_req_action = isset($this->_req_data['action'])
538
+							 && ! empty($this->_req_data['action'])
539
+							 && $this->_req_data['action'] !== '-1'
540
+			? sanitize_key($this->_req_data['action'])
541
+			: 'default';
542
+		// if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
543
+		//  This covers cases where we're coming in from a list table that isn't on the default route.
544
+		$this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
545
+			? $this->_req_data['route'] : $this->_req_action;
546
+		// however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
547
+		$this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route'])
548
+			? $this->_req_data['route']
549
+			: $this->_req_action;
550
+		$this->_current_view = $this->_req_action;
551
+		$this->_req_nonce = $this->_req_action . '_nonce';
552
+		$this->_define_page_props();
553
+		$this->_current_page_view_url = add_query_arg(
554
+			array('page' => $this->_current_page, 'action' => $this->_current_view),
555
+			$this->_admin_base_url
556
+		);
557
+		// default things
558
+		$this->_default_espresso_metaboxes = array(
559
+			'_espresso_news_post_box',
560
+			'_espresso_links_post_box',
561
+			'_espresso_ratings_request',
562
+			'_espresso_sponsors_post_box',
563
+		);
564
+		// set page configs
565
+		$this->_set_page_routes();
566
+		$this->_set_page_config();
567
+		// let's include any referrer data in our default_query_args for this route for "stickiness".
568
+		if (isset($this->_req_data['wp_referer'])) {
569
+			$this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
570
+		}
571
+		// for caffeinated and other extended functionality.
572
+		//  If there is a _extend_page_config method
573
+		// then let's run that to modify the all the various page configuration arrays
574
+		if (method_exists($this, '_extend_page_config')) {
575
+			$this->_extend_page_config();
576
+		}
577
+		// for CPT and other extended functionality.
578
+		// If there is an _extend_page_config_for_cpt
579
+		// then let's run that to modify all the various page configuration arrays.
580
+		if (method_exists($this, '_extend_page_config_for_cpt')) {
581
+			$this->_extend_page_config_for_cpt();
582
+		}
583
+		// filter routes and page_config so addons can add their stuff. Filtering done per class
584
+		$this->_page_routes = apply_filters(
585
+			'FHEE__' . get_class($this) . '__page_setup__page_routes',
586
+			$this->_page_routes,
587
+			$this
588
+		);
589
+		$this->_page_config = apply_filters(
590
+			'FHEE__' . get_class($this) . '__page_setup__page_config',
591
+			$this->_page_config,
592
+			$this
593
+		);
594
+		// if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
595
+		// then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
596
+		if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
597
+			add_action(
598
+				'AHEE__EE_Admin_Page__route_admin_request',
599
+				array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
600
+				10,
601
+				2
602
+			);
603
+		}
604
+		// next route only if routing enabled
605
+		if ($this->_routing && ! defined('DOING_AJAX')) {
606
+			$this->_verify_routes();
607
+			// next let's just check user_access and kill if no access
608
+			$this->check_user_access();
609
+			if ($this->_is_UI_request) {
610
+				// admin_init stuff - global, all views for this page class, specific view
611
+				add_action('admin_init', array($this, 'admin_init'), 10);
612
+				if (method_exists($this, 'admin_init_' . $this->_current_view)) {
613
+					add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
614
+				}
615
+			} else {
616
+				// hijack regular WP loading and route admin request immediately
617
+				@ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
618
+				$this->route_admin_request();
619
+			}
620
+		}
621
+	}
622
+
623
+
624
+	/**
625
+	 * Provides a way for related child admin pages to load stuff on the loaded admin page.
626
+	 *
627
+	 * @return void
628
+	 * @throws ReflectionException
629
+	 * @throws EE_Error
630
+	 */
631
+	private function _do_other_page_hooks()
632
+	{
633
+		$registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
634
+		foreach ($registered_pages as $page) {
635
+			// now let's setup the file name and class that should be present
636
+			$classname = str_replace('.class.php', '', $page);
637
+			// autoloaders should take care of loading file
638
+			if (! class_exists($classname)) {
639
+				$error_msg[] = sprintf(
640
+					esc_html__(
641
+						'Something went wrong with loading the %s admin hooks page.',
642
+						'event_espresso'
643
+					),
644
+					$page
645
+				);
646
+				$error_msg[] = $error_msg[0]
647
+							   . "\r\n"
648
+							   . sprintf(
649
+								   esc_html__(
650
+									   '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',
651
+									   'event_espresso'
652
+								   ),
653
+								   $page,
654
+								   '<br />',
655
+								   '<strong>' . $classname . '</strong>'
656
+							   );
657
+				throw new EE_Error(implode('||', $error_msg));
658
+			}
659
+			// // notice we are passing the instance of this class to the hook object.
660
+			$this->loader->getShared($classname, [$this]);
661
+		}
662
+	}
663
+
664
+
665
+	/**
666
+	 * @throws DomainException
667
+	 * @throws EE_Error
668
+	 * @throws InvalidArgumentException
669
+	 * @throws InvalidDataTypeException
670
+	 * @throws InvalidInterfaceException
671
+	 * @throws ReflectionException
672
+	 * @since $VID:$
673
+	 */
674
+	public function load_page_dependencies()
675
+	{
676
+		try {
677
+			$this->_load_page_dependencies();
678
+		} catch (EE_Error $e) {
679
+			$e->get_error();
680
+		}
681
+	}
682
+
683
+
684
+	/**
685
+	 * load_page_dependencies
686
+	 * loads things specific to this page class when its loaded.  Really helps with efficiency.
687
+	 *
688
+	 * @return void
689
+	 * @throws DomainException
690
+	 * @throws EE_Error
691
+	 * @throws InvalidArgumentException
692
+	 * @throws InvalidDataTypeException
693
+	 * @throws InvalidInterfaceException
694
+	 * @throws ReflectionException
695
+	 */
696
+	protected function _load_page_dependencies()
697
+	{
698
+		// let's set the current_screen and screen options to override what WP set
699
+		$this->_current_screen = get_current_screen();
700
+		// load admin_notices - global, page class, and view specific
701
+		add_action('admin_notices', array($this, 'admin_notices_global'), 5);
702
+		add_action('admin_notices', array($this, 'admin_notices'), 10);
703
+		if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
704
+			add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
705
+		}
706
+		// load network admin_notices - global, page class, and view specific
707
+		add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
708
+		if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
709
+			add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
710
+		}
711
+		// this will save any per_page screen options if they are present
712
+		$this->_set_per_page_screen_options();
713
+		// setup list table properties
714
+		$this->_set_list_table();
715
+		// child classes can "register" a metabox to be automatically handled via the _page_config array property.
716
+		// However in some cases the metaboxes will need to be added within a route handling callback.
717
+		$this->_add_registered_meta_boxes();
718
+		$this->_add_screen_columns();
719
+		// add screen options - global, page child class, and view specific
720
+		$this->_add_global_screen_options();
721
+		$this->_add_screen_options();
722
+		$add_screen_options = "_add_screen_options_{$this->_current_view}";
723
+		if (method_exists($this, $add_screen_options)) {
724
+			$this->{$add_screen_options}();
725
+		}
726
+		// add help tab(s) and tours- set via page_config and qtips.
727
+		$this->_add_help_tour();
728
+		$this->_add_help_tabs();
729
+		$this->_add_qtips();
730
+		// add feature_pointers - global, page child class, and view specific
731
+		$this->_add_feature_pointers();
732
+		$this->_add_global_feature_pointers();
733
+		$add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
734
+		if (method_exists($this, $add_feature_pointer)) {
735
+			$this->{$add_feature_pointer}();
736
+		}
737
+		// enqueue scripts/styles - global, page class, and view specific
738
+		add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
739
+		add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
740
+		if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
741
+			add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
742
+		}
743
+		add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
744
+		// admin_print_footer_scripts - global, page child class, and view specific.
745
+		// NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
746
+		// In most cases that's doing_it_wrong().  But adding hidden container elements etc.
747
+		// is a good use case. Notice the late priority we're giving these
748
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
749
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
750
+		if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
751
+			add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
752
+		}
753
+		// admin footer scripts
754
+		add_action('admin_footer', array($this, 'admin_footer_global'), 99);
755
+		add_action('admin_footer', array($this, 'admin_footer'), 100);
756
+		if (method_exists($this, "admin_footer_{$this->_current_view}")) {
757
+			add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
758
+		}
759
+		do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
760
+		// targeted hook
761
+		do_action(
762
+			"FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
763
+		);
764
+	}
765
+
766
+
767
+	/**
768
+	 * _set_defaults
769
+	 * This sets some global defaults for class properties.
770
+	 */
771
+	private function _set_defaults()
772
+	{
773
+		$this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
774
+		$this->_event = $this->_template_path = $this->_column_template_path = null;
775
+		$this->_nav_tabs = $this->_views = $this->_page_routes = array();
776
+		$this->_page_config = $this->_default_route_query_args = array();
777
+		$this->_default_nav_tab_name = 'overview';
778
+		// init template args
779
+		$this->_template_args = array(
780
+			'admin_page_header'  => '',
781
+			'admin_page_content' => '',
782
+			'post_body_content'  => '',
783
+			'before_list_table'  => '',
784
+			'after_list_table'   => '',
785
+		);
786
+	}
787
+
788
+
789
+	/**
790
+	 * route_admin_request
791
+	 *
792
+	 * @see    _route_admin_request()
793
+	 * @return exception|void error
794
+	 * @throws InvalidArgumentException
795
+	 * @throws InvalidInterfaceException
796
+	 * @throws InvalidDataTypeException
797
+	 * @throws EE_Error
798
+	 * @throws ReflectionException
799
+	 */
800
+	public function route_admin_request()
801
+	{
802
+		try {
803
+			$this->_route_admin_request();
804
+		} catch (EE_Error $e) {
805
+			$e->get_error();
806
+		}
807
+	}
808
+
809
+
810
+	public function set_wp_page_slug($wp_page_slug)
811
+	{
812
+		$this->_wp_page_slug = $wp_page_slug;
813
+		// if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
814
+		if (is_network_admin()) {
815
+			$this->_wp_page_slug .= '-network';
816
+		}
817
+	}
818
+
819
+
820
+	/**
821
+	 * _verify_routes
822
+	 * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
823
+	 * we know if we need to drop out.
824
+	 *
825
+	 * @return bool
826
+	 * @throws EE_Error
827
+	 */
828
+	protected function _verify_routes()
829
+	{
830
+		if (! $this->_current_page && ! defined('DOING_AJAX')) {
831
+			return false;
832
+		}
833
+		$this->_route = false;
834
+		// check that the page_routes array is not empty
835
+		if (empty($this->_page_routes)) {
836
+			// user error msg
837
+			$error_msg = sprintf(
838
+				esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
839
+				$this->_admin_page_title
840
+			);
841
+			// developer error msg
842
+			$error_msg .= '||' . $error_msg
843
+						  . esc_html__(
844
+							  ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
845
+							  'event_espresso'
846
+						  );
847
+			throw new EE_Error($error_msg);
848
+		}
849
+		// and that the requested page route exists
850
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
851
+			$this->_route = $this->_page_routes[ $this->_req_action ];
852
+			$this->_route_config = isset($this->_page_config[ $this->_req_action ])
853
+				? $this->_page_config[ $this->_req_action ] : array();
854
+		} else {
855
+			// user error msg
856
+			$error_msg = sprintf(
857
+				esc_html__(
858
+					'The requested page route does not exist for the %s admin page.',
859
+					'event_espresso'
860
+				),
861
+				$this->_admin_page_title
862
+			);
863
+			// developer error msg
864
+			$error_msg .= '||' . $error_msg
865
+						  . sprintf(
866
+							  esc_html__(
867
+								  ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
868
+								  'event_espresso'
869
+							  ),
870
+							  $this->_req_action
871
+						  );
872
+			throw new EE_Error($error_msg);
873
+		}
874
+		// and that a default route exists
875
+		if (! array_key_exists('default', $this->_page_routes)) {
876
+			// user error msg
877
+			$error_msg = sprintf(
878
+				esc_html__(
879
+					'A default page route has not been set for the % admin page.',
880
+					'event_espresso'
881
+				),
882
+				$this->_admin_page_title
883
+			);
884
+			// developer error msg
885
+			$error_msg .= '||' . $error_msg
886
+						  . esc_html__(
887
+							  ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
888
+							  'event_espresso'
889
+						  );
890
+			throw new EE_Error($error_msg);
891
+		}
892
+
893
+		// first lets' catch if the UI request has EVER been set.
894
+		if ($this->_is_UI_request === null) {
895
+			// lets set if this is a UI request or not.
896
+			$this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
897
+			// wait a minute... we might have a noheader in the route array
898
+			$this->_is_UI_request = is_array($this->_route)
899
+									&& isset($this->_route['noheader'])
900
+									&& $this->_route['noheader'] ? false : $this->_is_UI_request;
901
+		}
902
+		$this->_set_current_labels();
903
+		return true;
904
+	}
905
+
906
+
907
+	/**
908
+	 * this method simply verifies a given route and makes sure its an actual route available for the loaded page
909
+	 *
910
+	 * @param  string $route the route name we're verifying
911
+	 * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
912
+	 * @throws EE_Error
913
+	 */
914
+	protected function _verify_route($route)
915
+	{
916
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
917
+			return true;
918
+		}
919
+		// user error msg
920
+		$error_msg = sprintf(
921
+			esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
922
+			$this->_admin_page_title
923
+		);
924
+		// developer error msg
925
+		$error_msg .= '||' . $error_msg
926
+					  . sprintf(
927
+						  esc_html__(
928
+							  ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
929
+							  'event_espresso'
930
+						  ),
931
+						  $route
932
+					  );
933
+		throw new EE_Error($error_msg);
934
+	}
935
+
936
+
937
+	/**
938
+	 * perform nonce verification
939
+	 * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
940
+	 * using this method (and save retyping!)
941
+	 *
942
+	 * @param string $nonce     The nonce sent
943
+	 * @param string $nonce_ref The nonce reference string (name0)
944
+	 * @return void
945
+	 * @throws EE_Error
946
+	 * @throws InvalidArgumentException
947
+	 * @throws InvalidDataTypeException
948
+	 * @throws InvalidInterfaceException
949
+	 */
950
+	protected function _verify_nonce($nonce, $nonce_ref)
951
+	{
952
+		// verify nonce against expected value
953
+		if (! wp_verify_nonce($nonce, $nonce_ref)) {
954
+			// these are not the droids you are looking for !!!
955
+			$msg = sprintf(
956
+				esc_html__('%sNonce Fail.%s', 'event_espresso'),
957
+				'<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
958
+				'</a>'
959
+			);
960
+			if (WP_DEBUG) {
961
+				$msg .= "\n  "
962
+						. sprintf(
963
+							esc_html__(
964
+								'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
965
+								'event_espresso'
966
+							),
967
+							__CLASS__
968
+						);
969
+			}
970
+			if (! defined('DOING_AJAX')) {
971
+				wp_die($msg);
972
+			} else {
973
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
974
+				$this->_return_json();
975
+			}
976
+		}
977
+	}
978
+
979
+
980
+	/**
981
+	 * _route_admin_request()
982
+	 * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if there are
983
+	 * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
984
+	 * in the page routes and then will try to load the corresponding method.
985
+	 *
986
+	 * @return void
987
+	 * @throws EE_Error
988
+	 * @throws InvalidArgumentException
989
+	 * @throws InvalidDataTypeException
990
+	 * @throws InvalidInterfaceException
991
+	 * @throws ReflectionException
992
+	 */
993
+	protected function _route_admin_request()
994
+	{
995
+		if (! $this->_is_UI_request) {
996
+			$this->_verify_routes();
997
+		}
998
+		$nonce_check = isset($this->_route_config['require_nonce'])
999
+			? $this->_route_config['require_nonce']
1000
+			: true;
1001
+		if ($this->_req_action !== 'default' && $nonce_check) {
1002
+			// set nonce from post data
1003
+			$nonce = isset($this->_req_data[ $this->_req_nonce ])
1004
+				? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
1005
+				: '';
1006
+			$this->_verify_nonce($nonce, $this->_req_nonce);
1007
+		}
1008
+		// set the nav_tabs array but ONLY if this is  UI_request
1009
+		if ($this->_is_UI_request) {
1010
+			$this->_set_nav_tabs();
1011
+		}
1012
+		// grab callback function
1013
+		$func = is_array($this->_route) ? $this->_route['func'] : $this->_route;
1014
+		// check if callback has args
1015
+		$args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
1016
+		$error_msg = '';
1017
+		// action right before calling route
1018
+		// (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1019
+		if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1020
+			do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1021
+		}
1022
+		// right before calling the route, let's remove _wp_http_referer from the
1023
+		// $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
1024
+		$_SERVER['REQUEST_URI'] = remove_query_arg(
1025
+			'_wp_http_referer',
1026
+			wp_unslash($_SERVER['REQUEST_URI'])
1027
+		);
1028
+		if (! empty($func)) {
1029
+			if (is_array($func)) {
1030
+				list($class, $method) = $func;
1031
+			} elseif (strpos($func, '::') !== false) {
1032
+				list($class, $method) = explode('::', $func);
1033
+			} else {
1034
+				$class = $this;
1035
+				$method = $func;
1036
+			}
1037
+			if (! (is_object($class) && $class === $this)) {
1038
+				// send along this admin page object for access by addons.
1039
+				$args['admin_page_object'] = $this;
1040
+			}
1041
+			// is it a method on a class that doesn't work?
1042
+			if (((method_exists($class, $method)
1043
+				  && call_user_func_array(array($class, $method), $args) === false)
1044
+				 && (// is it a standalone function that doesn't work?
1045
+					 function_exists($method)
1046
+					 && call_user_func_array(
1047
+						 $func,
1048
+						 array_merge(array('admin_page_object' => $this), $args)
1049
+					 ) === false
1050
+				 )) || (// is it neither a class method NOR a standalone function?
1051
+					! function_exists($method)
1052
+					&& ! method_exists($class, $method)
1053
+				)
1054
+			) {
1055
+				// user error msg
1056
+				$error_msg = esc_html__(
1057
+					'An error occurred. The  requested page route could not be found.',
1058
+					'event_espresso'
1059
+				);
1060
+				// developer error msg
1061
+				$error_msg .= '||';
1062
+				$error_msg .= sprintf(
1063
+					esc_html__(
1064
+						'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1065
+						'event_espresso'
1066
+					),
1067
+					$method
1068
+				);
1069
+			}
1070
+			if (! empty($error_msg)) {
1071
+				throw new EE_Error($error_msg);
1072
+			}
1073
+		}
1074
+		// if we've routed and this route has a no headers route AND a sent_headers_route,
1075
+		// then we need to reset the routing properties to the new route.
1076
+		// 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.
1077
+		if ($this->_is_UI_request === false
1078
+			&& is_array($this->_route)
1079
+			&& ! empty($this->_route['headers_sent_route'])
1080
+		) {
1081
+			$this->_reset_routing_properties($this->_route['headers_sent_route']);
1082
+		}
1083
+	}
1084
+
1085
+
1086
+	/**
1087
+	 * This method just allows the resetting of page properties in the case where a no headers
1088
+	 * route redirects to a headers route in its route config.
1089
+	 *
1090
+	 * @since   4.3.0
1091
+	 * @param  string $new_route New (non header) route to redirect to.
1092
+	 * @return   void
1093
+	 * @throws ReflectionException
1094
+	 * @throws InvalidArgumentException
1095
+	 * @throws InvalidInterfaceException
1096
+	 * @throws InvalidDataTypeException
1097
+	 * @throws EE_Error
1098
+	 */
1099
+	protected function _reset_routing_properties($new_route)
1100
+	{
1101
+		$this->_is_UI_request = true;
1102
+		// now we set the current route to whatever the headers_sent_route is set at
1103
+		$this->_req_data['action'] = $new_route;
1104
+		// rerun page setup
1105
+		$this->_page_setup();
1106
+	}
1107
+
1108
+
1109
+	/**
1110
+	 * _add_query_arg
1111
+	 * adds nonce to array of arguments then calls WP add_query_arg function
1112
+	 *(internally just uses EEH_URL's function with the same name)
1113
+	 *
1114
+	 * @param array  $args
1115
+	 * @param string $url
1116
+	 * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1117
+	 *                                        generated url in an associative array indexed by the key 'wp_referer';
1118
+	 *                                        Example usage: If the current page is:
1119
+	 *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1120
+	 *                                        &action=default&event_id=20&month_range=March%202015
1121
+	 *                                        &_wpnonce=5467821
1122
+	 *                                        and you call:
1123
+	 *                                        EE_Admin_Page::add_query_args_and_nonce(
1124
+	 *                                        array(
1125
+	 *                                        'action' => 'resend_something',
1126
+	 *                                        'page=>espresso_registrations'
1127
+	 *                                        ),
1128
+	 *                                        $some_url,
1129
+	 *                                        true
1130
+	 *                                        );
1131
+	 *                                        It will produce a url in this structure:
1132
+	 *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1133
+	 *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1134
+	 *                                        month_range]=March%202015
1135
+	 * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1136
+	 * @return string
1137
+	 */
1138
+	public static function add_query_args_and_nonce(
1139
+		$args = array(),
1140
+		$url = '',
1141
+		$sticky = false,
1142
+		$exclude_nonce = false
1143
+	) {
1144
+		// if there is a _wp_http_referer include the values from the request but only if sticky = true
1145
+		if ($sticky) {
1146
+			$request = $_REQUEST;
1147
+			unset($request['_wp_http_referer'], $request['wp_referer']);
1148
+			foreach ($request as $key => $value) {
1149
+				// do not add nonces
1150
+				if (strpos($key, 'nonce') !== false) {
1151
+					continue;
1152
+				}
1153
+				$args[ 'wp_referer[' . $key . ']' ] = $value;
1154
+			}
1155
+		}
1156
+		return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1157
+	}
1158
+
1159
+
1160
+	/**
1161
+	 * This returns a generated link that will load the related help tab.
1162
+	 *
1163
+	 * @param  string $help_tab_id the id for the connected help tab
1164
+	 * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1165
+	 * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1166
+	 * @uses EEH_Template::get_help_tab_link()
1167
+	 * @return string              generated link
1168
+	 */
1169
+	protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1170
+	{
1171
+		return EEH_Template::get_help_tab_link(
1172
+			$help_tab_id,
1173
+			$this->page_slug,
1174
+			$this->_req_action,
1175
+			$icon_style,
1176
+			$help_text
1177
+		);
1178
+	}
1179
+
1180
+
1181
+	/**
1182
+	 * _add_help_tabs
1183
+	 * Note child classes define their help tabs within the page_config array.
1184
+	 *
1185
+	 * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1186
+	 * @return void
1187
+	 * @throws DomainException
1188
+	 * @throws EE_Error
1189
+	 */
1190
+	protected function _add_help_tabs()
1191
+	{
1192
+		$tour_buttons = '';
1193
+		if (isset($this->_page_config[ $this->_req_action ])) {
1194
+			$config = $this->_page_config[ $this->_req_action ];
1195
+			// is there a help tour for the current route?  if there is let's setup the tour buttons
1196
+			if (isset($this->_help_tour[ $this->_req_action ])) {
1197
+				$tb = array();
1198
+				$tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1199
+				foreach ($this->_help_tour['tours'] as $tour) {
1200
+					// if this is the end tour then we don't need to setup a button
1201
+					if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1202
+						continue;
1203
+					}
1204
+					$tb[] = '<button id="trigger-tour-'
1205
+							. $tour->get_slug()
1206
+							. '" class="button-primary trigger-ee-help-tour">'
1207
+							. $tour->get_label()
1208
+							. '</button>';
1209
+				}
1210
+				$tour_buttons .= implode('<br />', $tb);
1211
+				$tour_buttons .= '</div></div>';
1212
+			}
1213
+			// let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1214
+			if (is_array($config) && isset($config['help_sidebar'])) {
1215
+				// check that the callback given is valid
1216
+				if (! method_exists($this, $config['help_sidebar'])) {
1217
+					throw new EE_Error(
1218
+						sprintf(
1219
+							esc_html__(
1220
+								'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',
1221
+								'event_espresso'
1222
+							),
1223
+							$config['help_sidebar'],
1224
+							get_class($this)
1225
+						)
1226
+					);
1227
+				}
1228
+				$content = apply_filters(
1229
+					'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1230
+					$this->{$config['help_sidebar']}()
1231
+				);
1232
+				$content .= $tour_buttons; // add help tour buttons.
1233
+				// do we have any help tours setup?  Cause if we do we want to add the buttons
1234
+				$this->_current_screen->set_help_sidebar($content);
1235
+			}
1236
+			// if there ARE tour buttons...
1237
+			if (! empty($tour_buttons)) {
1238
+				// if we DON'T have config help sidebar then we'll just add the tour buttons to the sidebar.
1239
+				if (! isset($config['help_sidebar'])) {
1240
+					$this->_current_screen->set_help_sidebar($tour_buttons);
1241
+				}
1242
+				// handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1243
+				if (! isset($config['help_tabs'])) {
1244
+					$_ht['id'] = $this->page_slug;
1245
+					$_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1246
+					$_ht['content'] = '<p>'
1247
+									  . esc_html__(
1248
+										  'The buttons to the right allow you to start/restart any help tours available for this page',
1249
+										  'event_espresso'
1250
+									  ) . '</p>';
1251
+					$this->_current_screen->add_help_tab($_ht);
1252
+				}
1253
+			}
1254
+			if (! isset($config['help_tabs'])) {
1255
+				return;
1256
+			} //no help tabs for this route
1257
+			foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1258
+				// we're here so there ARE help tabs!
1259
+				// make sure we've got what we need
1260
+				if (! isset($cfg['title'])) {
1261
+					throw new EE_Error(
1262
+						esc_html__(
1263
+							'The _page_config array is not set up properly for help tabs.  It is missing a title',
1264
+							'event_espresso'
1265
+						)
1266
+					);
1267
+				}
1268
+				if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1269
+					throw new EE_Error(
1270
+						esc_html__(
1271
+							'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',
1272
+							'event_espresso'
1273
+						)
1274
+					);
1275
+				}
1276
+				// first priority goes to content.
1277
+				if (! empty($cfg['content'])) {
1278
+					$content = ! empty($cfg['content']) ? $cfg['content'] : null;
1279
+					// second priority goes to filename
1280
+				} elseif (! empty($cfg['filename'])) {
1281
+					$file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1282
+					// 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)
1283
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1284
+															 . basename($this->_get_dir())
1285
+															 . '/help_tabs/'
1286
+															 . $cfg['filename']
1287
+															 . '.help_tab.php' : $file_path;
1288
+					// if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1289
+					if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1290
+						EE_Error::add_error(
1291
+							sprintf(
1292
+								esc_html__(
1293
+									'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',
1294
+									'event_espresso'
1295
+								),
1296
+								$tab_id,
1297
+								key($config),
1298
+								$file_path
1299
+							),
1300
+							__FILE__,
1301
+							__FUNCTION__,
1302
+							__LINE__
1303
+						);
1304
+						return;
1305
+					}
1306
+					$template_args['admin_page_obj'] = $this;
1307
+					$content = EEH_Template::display_template(
1308
+						$file_path,
1309
+						$template_args,
1310
+						true
1311
+					);
1312
+				} else {
1313
+					$content = '';
1314
+				}
1315
+				// check if callback is valid
1316
+				if (empty($content) && (
1317
+						! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1318
+					)
1319
+				) {
1320
+					EE_Error::add_error(
1321
+						sprintf(
1322
+							esc_html__(
1323
+								'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.',
1324
+								'event_espresso'
1325
+							),
1326
+							$cfg['title']
1327
+						),
1328
+						__FILE__,
1329
+						__FUNCTION__,
1330
+						__LINE__
1331
+					);
1332
+					return;
1333
+				}
1334
+				// setup config array for help tab method
1335
+				$id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1336
+				$_ht = array(
1337
+					'id'       => $id,
1338
+					'title'    => $cfg['title'],
1339
+					'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1340
+					'content'  => $content,
1341
+				);
1342
+				$this->_current_screen->add_help_tab($_ht);
1343
+			}
1344
+		}
1345
+	}
1346
+
1347
+
1348
+	/**
1349
+	 * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1350
+	 * an array with properties for setting up usage of the joyride plugin
1351
+	 *
1352
+	 * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1353
+	 * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1354
+	 *         _set_page_config() comments
1355
+	 * @return void
1356
+	 * @throws EE_Error
1357
+	 * @throws InvalidArgumentException
1358
+	 * @throws InvalidDataTypeException
1359
+	 * @throws InvalidInterfaceException
1360
+	 */
1361
+	protected function _add_help_tour()
1362
+	{
1363
+		$tours = array();
1364
+		$this->_help_tour = array();
1365
+		// exit early if help tours are turned off globally
1366
+		if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1367
+			|| ! EE_Registry::instance()->CFG->admin->help_tour_activation
1368
+		) {
1369
+			return;
1370
+		}
1371
+		// loop through _page_config to find any help_tour defined
1372
+		foreach ($this->_page_config as $route => $config) {
1373
+			// we're only going to set things up for this route
1374
+			if ($route !== $this->_req_action) {
1375
+				continue;
1376
+			}
1377
+			if (isset($config['help_tour'])) {
1378
+				foreach ($config['help_tour'] as $tour) {
1379
+					$file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1380
+					// let's see if we can get that file...
1381
+					// if not its possible this is a decaf route not set in caffeinated
1382
+					// so lets try and get the caffeinated equivalent
1383
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1384
+															 . basename($this->_get_dir())
1385
+															 . '/help_tours/'
1386
+															 . $tour
1387
+															 . '.class.php' : $file_path;
1388
+					// if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1389
+					if (! is_readable($file_path)) {
1390
+						EE_Error::add_error(
1391
+							sprintf(
1392
+								esc_html__(
1393
+									'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',
1394
+									'event_espresso'
1395
+								),
1396
+								$file_path,
1397
+								$tour
1398
+							),
1399
+							__FILE__,
1400
+							__FUNCTION__,
1401
+							__LINE__
1402
+						);
1403
+						return;
1404
+					}
1405
+					require_once $file_path;
1406
+					if (! class_exists($tour)) {
1407
+						$error_msg[] = sprintf(
1408
+							esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1409
+							$tour
1410
+						);
1411
+						$error_msg[] = $error_msg[0] . "\r\n"
1412
+									   . sprintf(
1413
+										   esc_html__(
1414
+											   '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.',
1415
+											   'event_espresso'
1416
+										   ),
1417
+										   $tour,
1418
+										   '<br />',
1419
+										   $tour,
1420
+										   $this->_req_action,
1421
+										   get_class($this)
1422
+									   );
1423
+						throw new EE_Error(implode('||', $error_msg));
1424
+					}
1425
+					$tour_obj = new $tour($this->_is_caf);
1426
+					$tours[] = $tour_obj;
1427
+					$this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1428
+				}
1429
+				// let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1430
+				$end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1431
+				$tours[] = $end_stop_tour;
1432
+				$this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1433
+			}
1434
+		}
1435
+
1436
+		if (! empty($tours)) {
1437
+			$this->_help_tour['tours'] = $tours;
1438
+		}
1439
+		// that's it!  Now that the $_help_tours property is set (or not)
1440
+		// the scripts and html should be taken care of automatically.
1441
+
1442
+		/**
1443
+		 * Allow extending the help tours variable.
1444
+		 *
1445
+		 * @param Array $_help_tour The array containing all help tour information to be displayed.
1446
+		 */
1447
+		$this->_help_tour = apply_filters('FHEE__EE_Admin_Page___add_help_tour___help_tour', $this->_help_tour);
1448
+	}
1449
+
1450
+
1451
+	/**
1452
+	 * This simply sets up any qtips that have been defined in the page config
1453
+	 *
1454
+	 * @return void
1455
+	 */
1456
+	protected function _add_qtips()
1457
+	{
1458
+		if (isset($this->_route_config['qtips'])) {
1459
+			$qtips = (array) $this->_route_config['qtips'];
1460
+			// load qtip loader
1461
+			$path = array(
1462
+				$this->_get_dir() . '/qtips/',
1463
+				EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1464
+			);
1465
+			EEH_Qtip_Loader::instance()->register($qtips, $path);
1466
+		}
1467
+	}
1468
+
1469
+
1470
+	/**
1471
+	 * _set_nav_tabs
1472
+	 * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1473
+	 * wish to add additional tabs or modify accordingly.
1474
+	 *
1475
+	 * @return void
1476
+	 * @throws InvalidArgumentException
1477
+	 * @throws InvalidInterfaceException
1478
+	 * @throws InvalidDataTypeException
1479
+	 */
1480
+	protected function _set_nav_tabs()
1481
+	{
1482
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1483
+		$i = 0;
1484
+		foreach ($this->_page_config as $slug => $config) {
1485
+			if (! is_array($config)
1486
+				|| (
1487
+					is_array($config)
1488
+					&& (
1489
+						(isset($config['nav']) && ! $config['nav'])
1490
+						|| ! isset($config['nav'])
1491
+					)
1492
+				)
1493
+			) {
1494
+				continue;
1495
+			}
1496
+			// no nav tab for this config
1497
+			// check for persistent flag
1498
+			if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1499
+				// nav tab is only to appear when route requested.
1500
+				continue;
1501
+			}
1502
+			if (! $this->check_user_access($slug, true)) {
1503
+				// no nav tab because current user does not have access.
1504
+				continue;
1505
+			}
1506
+			$css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1507
+			$this->_nav_tabs[ $slug ] = array(
1508
+				'url'       => isset($config['nav']['url'])
1509
+					? $config['nav']['url']
1510
+					: self::add_query_args_and_nonce(
1511
+						array('action' => $slug),
1512
+						$this->_admin_base_url
1513
+					),
1514
+				'link_text' => isset($config['nav']['label'])
1515
+					? $config['nav']['label']
1516
+					: ucwords(
1517
+						str_replace('_', ' ', $slug)
1518
+					),
1519
+				'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1520
+				'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1521
+			);
1522
+			$i++;
1523
+		}
1524
+		// if $this->_nav_tabs is empty then lets set the default
1525
+		if (empty($this->_nav_tabs)) {
1526
+			$this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1527
+				'url'       => $this->_admin_base_url,
1528
+				'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1529
+				'css_class' => 'nav-tab-active',
1530
+				'order'     => 10,
1531
+			);
1532
+		}
1533
+		// now let's sort the tabs according to order
1534
+		usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1535
+	}
1536
+
1537
+
1538
+	/**
1539
+	 * _set_current_labels
1540
+	 * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1541
+	 * property array
1542
+	 *
1543
+	 * @return void
1544
+	 */
1545
+	private function _set_current_labels()
1546
+	{
1547
+		if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1548
+			foreach ($this->_route_config['labels'] as $label => $text) {
1549
+				if (is_array($text)) {
1550
+					foreach ($text as $sublabel => $subtext) {
1551
+						$this->_labels[ $label ][ $sublabel ] = $subtext;
1552
+					}
1553
+				} else {
1554
+					$this->_labels[ $label ] = $text;
1555
+				}
1556
+			}
1557
+		}
1558
+	}
1559
+
1560
+
1561
+	/**
1562
+	 *        verifies user access for this admin page
1563
+	 *
1564
+	 * @param string $route_to_check if present then the capability for the route matching this string is checked.
1565
+	 * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1566
+	 *                               return false if verify fail.
1567
+	 * @return bool
1568
+	 * @throws InvalidArgumentException
1569
+	 * @throws InvalidDataTypeException
1570
+	 * @throws InvalidInterfaceException
1571
+	 */
1572
+	public function check_user_access($route_to_check = '', $verify_only = false)
1573
+	{
1574
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1575
+		$route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1576
+		$capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1577
+					  && is_array(
1578
+						  $this->_page_routes[ $route_to_check ]
1579
+					  )
1580
+					  && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1581
+			? $this->_page_routes[ $route_to_check ]['capability'] : null;
1582
+		if (empty($capability) && empty($route_to_check)) {
1583
+			$capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1584
+				: $this->_route['capability'];
1585
+		} else {
1586
+			$capability = empty($capability) ? 'manage_options' : $capability;
1587
+		}
1588
+		$id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1589
+		if (! defined('DOING_AJAX')
1590
+			&& (
1591
+				! function_exists('is_admin')
1592
+				|| ! EE_Registry::instance()->CAP->current_user_can(
1593
+					$capability,
1594
+					$this->page_slug
1595
+					. '_'
1596
+					. $route_to_check,
1597
+					$id
1598
+				)
1599
+			)
1600
+		) {
1601
+			if ($verify_only) {
1602
+				return false;
1603
+			}
1604
+			if (is_user_logged_in()) {
1605
+				wp_die(__('You do not have access to this route.', 'event_espresso'));
1606
+			} else {
1607
+				return false;
1608
+			}
1609
+		}
1610
+		return true;
1611
+	}
1612
+
1613
+
1614
+	/**
1615
+	 * admin_init_global
1616
+	 * This runs all the code that we want executed within the WP admin_init hook.
1617
+	 * This method executes for ALL EE Admin pages.
1618
+	 *
1619
+	 * @return void
1620
+	 */
1621
+	public function admin_init_global()
1622
+	{
1623
+	}
1624
+
1625
+
1626
+	/**
1627
+	 * wp_loaded_global
1628
+	 * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1629
+	 * EE_Admin page and will execute on every EE Admin Page load
1630
+	 *
1631
+	 * @return void
1632
+	 */
1633
+	public function wp_loaded()
1634
+	{
1635
+	}
1636
+
1637
+
1638
+	/**
1639
+	 * admin_notices
1640
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1641
+	 * ALL EE_Admin pages.
1642
+	 *
1643
+	 * @return void
1644
+	 */
1645
+	public function admin_notices_global()
1646
+	{
1647
+		$this->_display_no_javascript_warning();
1648
+		$this->_display_espresso_notices();
1649
+	}
1650
+
1651
+
1652
+	public function network_admin_notices_global()
1653
+	{
1654
+		$this->_display_no_javascript_warning();
1655
+		$this->_display_espresso_notices();
1656
+	}
1657
+
1658
+
1659
+	/**
1660
+	 * admin_footer_scripts_global
1661
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1662
+	 * will apply on ALL EE_Admin pages.
1663
+	 *
1664
+	 * @return void
1665
+	 */
1666
+	public function admin_footer_scripts_global()
1667
+	{
1668
+		$this->_add_admin_page_ajax_loading_img();
1669
+		$this->_add_admin_page_overlay();
1670
+		// if metaboxes are present we need to add the nonce field
1671
+		if (isset($this->_route_config['metaboxes'])
1672
+			|| isset($this->_route_config['list_table'])
1673
+			|| (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1674
+		) {
1675
+			wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1676
+			wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1677
+		}
1678
+	}
1679
+
1680
+
1681
+	/**
1682
+	 * admin_footer_global
1683
+	 * Anything triggered by the wp 'admin_footer' wp hook should be put in here.
1684
+	 * This particular method will apply on ALL EE_Admin Pages.
1685
+	 *
1686
+	 * @return void
1687
+	 * @throws InvalidArgumentException
1688
+	 * @throws InvalidDataTypeException
1689
+	 * @throws InvalidInterfaceException
1690
+	 */
1691
+	public function admin_footer_global()
1692
+	{
1693
+		// dialog container for dialog helper
1694
+		$d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1695
+		$d_cont .= '<div class="ee-notices"></div>';
1696
+		$d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1697
+		$d_cont .= '</div>';
1698
+		echo $d_cont;
1699
+		// help tour stuff?
1700
+		if (isset($this->_help_tour[ $this->_req_action ])) {
1701
+			echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1702
+		}
1703
+		// current set timezone for timezone js
1704
+		echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1705
+	}
1706
+
1707
+
1708
+	/**
1709
+	 * This function sees if there is a method for help popup content existing for the given route.  If there is then
1710
+	 * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1711
+	 * help popups then in your templates or your content you set "triggers" for the content using the
1712
+	 * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1713
+	 * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1714
+	 * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1715
+	 * for the
1716
+	 * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1717
+	 * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1718
+	 *    'help_trigger_id' => array(
1719
+	 *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1720
+	 *        'content' => esc_html__('localized content for popup', 'event_espresso')
1721
+	 *    )
1722
+	 * );
1723
+	 * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1724
+	 *
1725
+	 * @param array $help_array
1726
+	 * @param bool  $display
1727
+	 * @return string content
1728
+	 * @throws DomainException
1729
+	 * @throws EE_Error
1730
+	 */
1731
+	protected function _set_help_popup_content($help_array = array(), $display = false)
1732
+	{
1733
+		$content = '';
1734
+		$help_array = empty($help_array) ? $this->_get_help_content() : $help_array;
1735
+		// loop through the array and setup content
1736
+		foreach ($help_array as $trigger => $help) {
1737
+			// make sure the array is setup properly
1738
+			if (! isset($help['title'], $help['content'])) {
1739
+				throw new EE_Error(
1740
+					esc_html__(
1741
+						'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',
1742
+						'event_espresso'
1743
+					)
1744
+				);
1745
+			}
1746
+			// we're good so let'd setup the template vars and then assign parsed template content to our content.
1747
+			$template_args = array(
1748
+				'help_popup_id'      => $trigger,
1749
+				'help_popup_title'   => $help['title'],
1750
+				'help_popup_content' => $help['content'],
1751
+			);
1752
+			$content .= EEH_Template::display_template(
1753
+				EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1754
+				$template_args,
1755
+				true
1756
+			);
1757
+		}
1758
+		if ($display) {
1759
+			echo $content;
1760
+			return '';
1761
+		}
1762
+		return $content;
1763
+	}
1764
+
1765
+
1766
+	/**
1767
+	 * All this does is retrieve the help content array if set by the EE_Admin_Page child
1768
+	 *
1769
+	 * @return array properly formatted array for help popup content
1770
+	 * @throws EE_Error
1771
+	 */
1772
+	private function _get_help_content()
1773
+	{
1774
+		// what is the method we're looking for?
1775
+		$method_name = '_help_popup_content_' . $this->_req_action;
1776
+		// if method doesn't exist let's get out.
1777
+		if (! method_exists($this, $method_name)) {
1778
+			return array();
1779
+		}
1780
+		// k we're good to go let's retrieve the help array
1781
+		$help_array = $this->{$method_name}();
1782
+		// make sure we've got an array!
1783
+		if (! is_array($help_array)) {
1784
+			throw new EE_Error(
1785
+				esc_html__(
1786
+					'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1787
+					'event_espresso'
1788
+				)
1789
+			);
1790
+		}
1791
+		return $help_array;
1792
+	}
1793
+
1794
+
1795
+	/**
1796
+	 * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1797
+	 * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1798
+	 * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1799
+	 *
1800
+	 * @param string  $trigger_id reference for retrieving the trigger content for the popup
1801
+	 * @param boolean $display    if false then we return the trigger string
1802
+	 * @param array   $dimensions an array of dimensions for the box (array(h,w))
1803
+	 * @return string
1804
+	 * @throws DomainException
1805
+	 * @throws EE_Error
1806
+	 */
1807
+	protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1808
+	{
1809
+		if (defined('DOING_AJAX')) {
1810
+			return '';
1811
+		}
1812
+		// 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
1813
+		$help_array = $this->_get_help_content();
1814
+		$help_content = '';
1815
+		if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1816
+			$help_array[ $trigger_id ] = array(
1817
+				'title'   => esc_html__('Missing Content', 'event_espresso'),
1818
+				'content' => esc_html__(
1819
+					'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.)',
1820
+					'event_espresso'
1821
+				),
1822
+			);
1823
+			$help_content = $this->_set_help_popup_content($help_array);
1824
+		}
1825
+		// let's setup the trigger
1826
+		$content = '<a class="ee-dialog" href="?height='
1827
+				   . $dimensions[0]
1828
+				   . '&width='
1829
+				   . $dimensions[1]
1830
+				   . '&inlineId='
1831
+				   . $trigger_id
1832
+				   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1833
+		$content .= $help_content;
1834
+		if ($display) {
1835
+			echo $content;
1836
+			return '';
1837
+		}
1838
+		return $content;
1839
+	}
1840
+
1841
+
1842
+	/**
1843
+	 * _add_global_screen_options
1844
+	 * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1845
+	 * This particular method will add_screen_options on ALL EE_Admin Pages
1846
+	 *
1847
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1848
+	 *         see also WP_Screen object documents...
1849
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1850
+	 * @abstract
1851
+	 * @return void
1852
+	 */
1853
+	private function _add_global_screen_options()
1854
+	{
1855
+	}
1856
+
1857
+
1858
+	/**
1859
+	 * _add_global_feature_pointers
1860
+	 * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1861
+	 * This particular method will implement feature pointers for ALL EE_Admin pages.
1862
+	 * Note: this is just a placeholder for now.  Implementation will come down the road
1863
+	 *
1864
+	 * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1865
+	 *         extended) also see:
1866
+	 * @link   http://eamann.com/tech/wordpress-portland/
1867
+	 * @abstract
1868
+	 * @return void
1869
+	 */
1870
+	private function _add_global_feature_pointers()
1871
+	{
1872
+	}
1873
+
1874
+
1875
+	/**
1876
+	 * load_global_scripts_styles
1877
+	 * The scripts and styles enqueued in here will be loaded on every EE Admin page
1878
+	 *
1879
+	 * @return void
1880
+	 * @throws EE_Error
1881
+	 */
1882
+	public function load_global_scripts_styles()
1883
+	{
1884
+		/** STYLES **/
1885
+		// add debugging styles
1886
+		if (WP_DEBUG) {
1887
+			add_action('admin_head', array($this, 'add_xdebug_style'));
1888
+		}
1889
+		// register all styles
1890
+		wp_register_style(
1891
+			'espresso-ui-theme',
1892
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1893
+			array(),
1894
+			EVENT_ESPRESSO_VERSION
1895
+		);
1896
+		wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1897
+		// helpers styles
1898
+		wp_register_style(
1899
+			'ee-text-links',
1900
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1901
+			array(),
1902
+			EVENT_ESPRESSO_VERSION
1903
+		);
1904
+		/** SCRIPTS **/
1905
+		// register all scripts
1906
+		wp_register_script(
1907
+			'ee-dialog',
1908
+			EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1909
+			array('jquery', 'jquery-ui-draggable'),
1910
+			EVENT_ESPRESSO_VERSION,
1911
+			true
1912
+		);
1913
+		wp_register_script(
1914
+			'ee_admin_js',
1915
+			EE_ADMIN_URL . 'assets/ee-admin-page.js',
1916
+			array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1917
+			EVENT_ESPRESSO_VERSION,
1918
+			true
1919
+		);
1920
+		wp_register_script(
1921
+			'jquery-ui-timepicker-addon',
1922
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1923
+			array('jquery-ui-datepicker', 'jquery-ui-slider'),
1924
+			EVENT_ESPRESSO_VERSION,
1925
+			true
1926
+		);
1927
+		if (EE_Registry::instance()->CFG->admin->help_tour_activation) {
1928
+			add_filter('FHEE_load_joyride', '__return_true');
1929
+		}
1930
+		// script for sorting tables
1931
+		wp_register_script(
1932
+			'espresso_ajax_table_sorting',
1933
+			EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1934
+			array('ee_admin_js', 'jquery-ui-sortable'),
1935
+			EVENT_ESPRESSO_VERSION,
1936
+			true
1937
+		);
1938
+		// script for parsing uri's
1939
+		wp_register_script(
1940
+			'ee-parse-uri',
1941
+			EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1942
+			array(),
1943
+			EVENT_ESPRESSO_VERSION,
1944
+			true
1945
+		);
1946
+		// and parsing associative serialized form elements
1947
+		wp_register_script(
1948
+			'ee-serialize-full-array',
1949
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1950
+			array('jquery'),
1951
+			EVENT_ESPRESSO_VERSION,
1952
+			true
1953
+		);
1954
+		// helpers scripts
1955
+		wp_register_script(
1956
+			'ee-text-links',
1957
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1958
+			array('jquery'),
1959
+			EVENT_ESPRESSO_VERSION,
1960
+			true
1961
+		);
1962
+		wp_register_script(
1963
+			'ee-moment-core',
1964
+			EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1965
+			array(),
1966
+			EVENT_ESPRESSO_VERSION,
1967
+			true
1968
+		);
1969
+		wp_register_script(
1970
+			'ee-moment',
1971
+			EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1972
+			array('ee-moment-core'),
1973
+			EVENT_ESPRESSO_VERSION,
1974
+			true
1975
+		);
1976
+		wp_register_script(
1977
+			'ee-datepicker',
1978
+			EE_ADMIN_URL . 'assets/ee-datepicker.js',
1979
+			array('jquery-ui-timepicker-addon', 'ee-moment'),
1980
+			EVENT_ESPRESSO_VERSION,
1981
+			true
1982
+		);
1983
+		// google charts
1984
+		wp_register_script(
1985
+			'google-charts',
1986
+			'https://www.gstatic.com/charts/loader.js',
1987
+			array(),
1988
+			EVENT_ESPRESSO_VERSION
1989
+		);
1990
+		// ENQUEUE ALL BASICS BY DEFAULT
1991
+		wp_enqueue_style('ee-admin-css');
1992
+		wp_enqueue_script('ee_admin_js');
1993
+		wp_enqueue_script('ee-accounting');
1994
+		wp_enqueue_script('jquery-validate');
1995
+		// taking care of metaboxes
1996
+		if (empty($this->_cpt_route)
1997
+			&& (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
1998
+		) {
1999
+			wp_enqueue_script('dashboard');
2000
+		}
2001
+		// LOCALIZED DATA
2002
+		// localize script for ajax lazy loading
2003
+		$lazy_loader_container_ids = apply_filters(
2004
+			'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
2005
+			array('espresso_news_post_box_content')
2006
+		);
2007
+		wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
2008
+		/**
2009
+		 * help tour stuff
2010
+		 */
2011
+		if (! empty($this->_help_tour)) {
2012
+			// register the js for kicking things off
2013
+			wp_enqueue_script(
2014
+				'ee-help-tour',
2015
+				EE_ADMIN_URL . 'assets/ee-help-tour.js',
2016
+				array('jquery-joyride'),
2017
+				EVENT_ESPRESSO_VERSION,
2018
+				true
2019
+			);
2020
+			$tours = array();
2021
+			// setup tours for the js tour object
2022
+			foreach ($this->_help_tour['tours'] as $tour) {
2023
+				if ($tour instanceof EE_Help_Tour) {
2024
+					$tours[] = array(
2025
+						'id'      => $tour->get_slug(),
2026
+						'options' => $tour->get_options(),
2027
+					);
2028
+				}
2029
+			}
2030
+			wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2031
+			// admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2032
+		}
2033
+	}
2034
+
2035
+
2036
+	/**
2037
+	 *        admin_footer_scripts_eei18n_js_strings
2038
+	 *
2039
+	 * @return        void
2040
+	 */
2041
+	public function admin_footer_scripts_eei18n_js_strings()
2042
+	{
2043
+		EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL;
2044
+		EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__(
2045
+			'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!!!',
2046
+			'event_espresso'
2047
+		);
2048
+		EE_Registry::$i18n_js_strings['January'] = esc_html__('January', 'event_espresso');
2049
+		EE_Registry::$i18n_js_strings['February'] = esc_html__('February', 'event_espresso');
2050
+		EE_Registry::$i18n_js_strings['March'] = esc_html__('March', 'event_espresso');
2051
+		EE_Registry::$i18n_js_strings['April'] = esc_html__('April', 'event_espresso');
2052
+		EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2053
+		EE_Registry::$i18n_js_strings['June'] = esc_html__('June', 'event_espresso');
2054
+		EE_Registry::$i18n_js_strings['July'] = esc_html__('July', 'event_espresso');
2055
+		EE_Registry::$i18n_js_strings['August'] = esc_html__('August', 'event_espresso');
2056
+		EE_Registry::$i18n_js_strings['September'] = esc_html__('September', 'event_espresso');
2057
+		EE_Registry::$i18n_js_strings['October'] = esc_html__('October', 'event_espresso');
2058
+		EE_Registry::$i18n_js_strings['November'] = esc_html__('November', 'event_espresso');
2059
+		EE_Registry::$i18n_js_strings['December'] = esc_html__('December', 'event_espresso');
2060
+		EE_Registry::$i18n_js_strings['Jan'] = esc_html__('Jan', 'event_espresso');
2061
+		EE_Registry::$i18n_js_strings['Feb'] = esc_html__('Feb', 'event_espresso');
2062
+		EE_Registry::$i18n_js_strings['Mar'] = esc_html__('Mar', 'event_espresso');
2063
+		EE_Registry::$i18n_js_strings['Apr'] = esc_html__('Apr', 'event_espresso');
2064
+		EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2065
+		EE_Registry::$i18n_js_strings['Jun'] = esc_html__('Jun', 'event_espresso');
2066
+		EE_Registry::$i18n_js_strings['Jul'] = esc_html__('Jul', 'event_espresso');
2067
+		EE_Registry::$i18n_js_strings['Aug'] = esc_html__('Aug', 'event_espresso');
2068
+		EE_Registry::$i18n_js_strings['Sep'] = esc_html__('Sep', 'event_espresso');
2069
+		EE_Registry::$i18n_js_strings['Oct'] = esc_html__('Oct', 'event_espresso');
2070
+		EE_Registry::$i18n_js_strings['Nov'] = esc_html__('Nov', 'event_espresso');
2071
+		EE_Registry::$i18n_js_strings['Dec'] = esc_html__('Dec', 'event_espresso');
2072
+		EE_Registry::$i18n_js_strings['Sunday'] = esc_html__('Sunday', 'event_espresso');
2073
+		EE_Registry::$i18n_js_strings['Monday'] = esc_html__('Monday', 'event_espresso');
2074
+		EE_Registry::$i18n_js_strings['Tuesday'] = esc_html__('Tuesday', 'event_espresso');
2075
+		EE_Registry::$i18n_js_strings['Wednesday'] = esc_html__('Wednesday', 'event_espresso');
2076
+		EE_Registry::$i18n_js_strings['Thursday'] = esc_html__('Thursday', 'event_espresso');
2077
+		EE_Registry::$i18n_js_strings['Friday'] = esc_html__('Friday', 'event_espresso');
2078
+		EE_Registry::$i18n_js_strings['Saturday'] = esc_html__('Saturday', 'event_espresso');
2079
+		EE_Registry::$i18n_js_strings['Sun'] = esc_html__('Sun', 'event_espresso');
2080
+		EE_Registry::$i18n_js_strings['Mon'] = esc_html__('Mon', 'event_espresso');
2081
+		EE_Registry::$i18n_js_strings['Tue'] = esc_html__('Tue', 'event_espresso');
2082
+		EE_Registry::$i18n_js_strings['Wed'] = esc_html__('Wed', 'event_espresso');
2083
+		EE_Registry::$i18n_js_strings['Thu'] = esc_html__('Thu', 'event_espresso');
2084
+		EE_Registry::$i18n_js_strings['Fri'] = esc_html__('Fri', 'event_espresso');
2085
+		EE_Registry::$i18n_js_strings['Sat'] = esc_html__('Sat', 'event_espresso');
2086
+	}
2087
+
2088
+
2089
+	/**
2090
+	 *        load enhanced xdebug styles for ppl with failing eyesight
2091
+	 *
2092
+	 * @return        void
2093
+	 */
2094
+	public function add_xdebug_style()
2095
+	{
2096
+		echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2097
+	}
2098
+
2099
+
2100
+	/************************/
2101
+	/** LIST TABLE METHODS **/
2102
+	/************************/
2103
+	/**
2104
+	 * this sets up the list table if the current view requires it.
2105
+	 *
2106
+	 * @return void
2107
+	 * @throws EE_Error
2108
+	 * @throws InvalidArgumentException
2109
+	 * @throws InvalidDataTypeException
2110
+	 * @throws InvalidInterfaceException
2111
+	 */
2112
+	protected function _set_list_table()
2113
+	{
2114
+		// first is this a list_table view?
2115
+		if (! isset($this->_route_config['list_table'])) {
2116
+			return;
2117
+		} //not a list_table view so get out.
2118
+		// list table functions are per view specific (because some admin pages might have more than one list table!)
2119
+		$list_table_view = '_set_list_table_views_' . $this->_req_action;
2120
+		if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2121
+			// user error msg
2122
+			$error_msg = esc_html__(
2123
+				'An error occurred. The requested list table views could not be found.',
2124
+				'event_espresso'
2125
+			);
2126
+			// developer error msg
2127
+			$error_msg .= '||'
2128
+						  . sprintf(
2129
+							  esc_html__(
2130
+								  '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.',
2131
+								  'event_espresso'
2132
+							  ),
2133
+							  $this->_req_action,
2134
+							  $list_table_view
2135
+						  );
2136
+			throw new EE_Error($error_msg);
2137
+		}
2138
+		// let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2139
+		$this->_views = apply_filters(
2140
+			'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2141
+			$this->_views
2142
+		);
2143
+		$this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2144
+		$this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2145
+		$this->_set_list_table_view();
2146
+		$this->_set_list_table_object();
2147
+	}
2148
+
2149
+
2150
+	/**
2151
+	 * set current view for List Table
2152
+	 *
2153
+	 * @return void
2154
+	 */
2155
+	protected function _set_list_table_view()
2156
+	{
2157
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2158
+		// looking at active items or dumpster diving ?
2159
+		if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2160
+			$this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2161
+		} else {
2162
+			$this->_view = sanitize_key($this->_req_data['status']);
2163
+		}
2164
+	}
2165
+
2166
+
2167
+	/**
2168
+	 * _set_list_table_object
2169
+	 * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2170
+	 *
2171
+	 * @throws InvalidInterfaceException
2172
+	 * @throws InvalidArgumentException
2173
+	 * @throws InvalidDataTypeException
2174
+	 * @throws EE_Error
2175
+	 * @throws InvalidInterfaceException
2176
+	 */
2177
+	protected function _set_list_table_object()
2178
+	{
2179
+		if (isset($this->_route_config['list_table'])) {
2180
+			if (! class_exists($this->_route_config['list_table'])) {
2181
+				throw new EE_Error(
2182
+					sprintf(
2183
+						esc_html__(
2184
+							'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.',
2185
+							'event_espresso'
2186
+						),
2187
+						$this->_route_config['list_table'],
2188
+						get_class($this)
2189
+					)
2190
+				);
2191
+			}
2192
+			$this->_list_table_object = $this->loader->getShared(
2193
+				$this->_route_config['list_table'],
2194
+				array($this)
2195
+			);
2196
+		}
2197
+	}
2198
+
2199
+
2200
+	/**
2201
+	 * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2202
+	 *
2203
+	 * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2204
+	 *                                                    urls.  The array should be indexed by the view it is being
2205
+	 *                                                    added to.
2206
+	 * @return array
2207
+	 */
2208
+	public function get_list_table_view_RLs($extra_query_args = array())
2209
+	{
2210
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2211
+		if (empty($this->_views)) {
2212
+			$this->_views = array();
2213
+		}
2214
+		// cycle thru views
2215
+		foreach ($this->_views as $key => $view) {
2216
+			$query_args = array();
2217
+			// check for current view
2218
+			$this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2219
+			$query_args['action'] = $this->_req_action;
2220
+			$query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2221
+			$query_args['status'] = $view['slug'];
2222
+			// merge any other arguments sent in.
2223
+			if (isset($extra_query_args[ $view['slug'] ])) {
2224
+				foreach ($extra_query_args[ $view['slug'] ] as $extra_query_arg) {
2225
+					$query_args[] = $extra_query_arg;
2226
+				}
2227
+			}
2228
+			$this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2229
+		}
2230
+		return $this->_views;
2231
+	}
2232
+
2233
+
2234
+	/**
2235
+	 * _entries_per_page_dropdown
2236
+	 * generates a drop down box for selecting the number of visible rows in an admin page list table
2237
+	 *
2238
+	 * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2239
+	 *         WP does it.
2240
+	 * @param int $max_entries total number of rows in the table
2241
+	 * @return string
2242
+	 */
2243
+	protected function _entries_per_page_dropdown($max_entries = 0)
2244
+	{
2245
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2246
+		$values = array(10, 25, 50, 100);
2247
+		$per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2248
+		if ($max_entries) {
2249
+			$values[] = $max_entries;
2250
+			sort($values);
2251
+		}
2252
+		$entries_per_page_dropdown = '
2253 2253
 			<div id="entries-per-page-dv" class="alignleft actions">
2254 2254
 				<label class="hide-if-no-js">
2255 2255
 					Show
2256 2256
 					<select id="entries-per-page-slct" name="entries-per-page-slct">';
2257
-        foreach ($values as $value) {
2258
-            if ($value < $max_entries) {
2259
-                $selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2260
-                $entries_per_page_dropdown .= '
2257
+		foreach ($values as $value) {
2258
+			if ($value < $max_entries) {
2259
+				$selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2260
+				$entries_per_page_dropdown .= '
2261 2261
 						<option value="' . $value . '"' . $selected . '>' . $value . '&nbsp;&nbsp;</option>';
2262
-            }
2263
-        }
2264
-        $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2265
-        $entries_per_page_dropdown .= '
2262
+			}
2263
+		}
2264
+		$selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2265
+		$entries_per_page_dropdown .= '
2266 2266
 						<option value="' . $max_entries . '"' . $selected . '>All&nbsp;&nbsp;</option>';
2267
-        $entries_per_page_dropdown .= '
2267
+		$entries_per_page_dropdown .= '
2268 2268
 					</select>
2269 2269
 					entries
2270 2270
 				</label>
2271 2271
 				<input id="entries-per-page-btn" class="button-secondary" type="submit" value="Go" >
2272 2272
 			</div>
2273 2273
 		';
2274
-        return $entries_per_page_dropdown;
2275
-    }
2276
-
2277
-
2278
-    /**
2279
-     *        _set_search_attributes
2280
-     *
2281
-     * @return        void
2282
-     */
2283
-    public function _set_search_attributes()
2284
-    {
2285
-        $this->_template_args['search']['btn_label'] = sprintf(
2286
-            esc_html__('Search %s', 'event_espresso'),
2287
-            empty($this->_search_btn_label) ? $this->page_label
2288
-                : $this->_search_btn_label
2289
-        );
2290
-        $this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2291
-    }
2292
-
2293
-
2294
-
2295
-    /*** END LIST TABLE METHODS **/
2296
-
2297
-
2298
-    /**
2299
-     * _add_registered_metaboxes
2300
-     *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2301
-     *
2302
-     * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2303
-     * @return void
2304
-     * @throws EE_Error
2305
-     */
2306
-    private function _add_registered_meta_boxes()
2307
-    {
2308
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2309
-        // we only add meta boxes if the page_route calls for it
2310
-        if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2311
-            && is_array(
2312
-                $this->_route_config['metaboxes']
2313
-            )
2314
-        ) {
2315
-            // this simply loops through the callbacks provided
2316
-            // and checks if there is a corresponding callback registered by the child
2317
-            // if there is then we go ahead and process the metabox loader.
2318
-            foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2319
-                // first check for Closures
2320
-                if ($metabox_callback instanceof Closure) {
2321
-                    $result = $metabox_callback();
2322
-                } elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2323
-                    $result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2324
-                } else {
2325
-                    $result = $this->{$metabox_callback}();
2326
-                }
2327
-                if ($result === false) {
2328
-                    // user error msg
2329
-                    $error_msg = esc_html__(
2330
-                        'An error occurred. The  requested metabox could not be found.',
2331
-                        'event_espresso'
2332
-                    );
2333
-                    // developer error msg
2334
-                    $error_msg .= '||'
2335
-                                  . sprintf(
2336
-                                      esc_html__(
2337
-                                          '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.',
2338
-                                          'event_espresso'
2339
-                                      ),
2340
-                                      $metabox_callback
2341
-                                  );
2342
-                    throw new EE_Error($error_msg);
2343
-                }
2344
-            }
2345
-        }
2346
-    }
2347
-
2348
-
2349
-    /**
2350
-     * _add_screen_columns
2351
-     * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2352
-     * the dynamic column template and we'll setup the column options for the page.
2353
-     *
2354
-     * @return void
2355
-     */
2356
-    private function _add_screen_columns()
2357
-    {
2358
-        if (is_array($this->_route_config)
2359
-            && isset($this->_route_config['columns'])
2360
-            && is_array($this->_route_config['columns'])
2361
-            && count($this->_route_config['columns']) === 2
2362
-        ) {
2363
-            add_screen_option(
2364
-                'layout_columns',
2365
-                array(
2366
-                    'max'     => (int) $this->_route_config['columns'][0],
2367
-                    'default' => (int) $this->_route_config['columns'][1],
2368
-                )
2369
-            );
2370
-            $this->_template_args['num_columns'] = $this->_route_config['columns'][0];
2371
-            $screen_id = $this->_current_screen->id;
2372
-            $screen_columns = (int) get_user_option("screen_layout_{$screen_id}");
2373
-            $total_columns = ! empty($screen_columns)
2374
-                ? $screen_columns
2375
-                : $this->_route_config['columns'][1];
2376
-            $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2377
-            $this->_template_args['current_page'] = $this->_wp_page_slug;
2378
-            $this->_template_args['screen'] = $this->_current_screen;
2379
-            $this->_column_template_path = EE_ADMIN_TEMPLATE
2380
-                                           . 'admin_details_metabox_column_wrapper.template.php';
2381
-            // finally if we don't have has_metaboxes set in the route config
2382
-            // let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2383
-            $this->_route_config['has_metaboxes'] = true;
2384
-        }
2385
-    }
2386
-
2387
-
2388
-
2389
-    /** GLOBALLY AVAILABLE METABOXES **/
2390
-
2391
-
2392
-    /**
2393
-     * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2394
-     * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2395
-     * these get loaded on.
2396
-     */
2397
-    private function _espresso_news_post_box()
2398
-    {
2399
-        $news_box_title = apply_filters(
2400
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2401
-            esc_html__('New @ Event Espresso', 'event_espresso')
2402
-        );
2403
-        add_meta_box(
2404
-            'espresso_news_post_box',
2405
-            $news_box_title,
2406
-            array(
2407
-                $this,
2408
-                'espresso_news_post_box',
2409
-            ),
2410
-            $this->_wp_page_slug,
2411
-            'side'
2412
-        );
2413
-    }
2414
-
2415
-
2416
-    /**
2417
-     * Code for setting up espresso ratings request metabox.
2418
-     */
2419
-    protected function _espresso_ratings_request()
2420
-    {
2421
-        if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2422
-            return;
2423
-        }
2424
-        $ratings_box_title = apply_filters(
2425
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2426
-            esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2427
-        );
2428
-        add_meta_box(
2429
-            'espresso_ratings_request',
2430
-            $ratings_box_title,
2431
-            array(
2432
-                $this,
2433
-                'espresso_ratings_request',
2434
-            ),
2435
-            $this->_wp_page_slug,
2436
-            'side'
2437
-        );
2438
-    }
2439
-
2440
-
2441
-    /**
2442
-     * Code for setting up espresso ratings request metabox content.
2443
-     *
2444
-     * @throws DomainException
2445
-     */
2446
-    public function espresso_ratings_request()
2447
-    {
2448
-        EEH_Template::display_template(EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php');
2449
-    }
2450
-
2451
-
2452
-    public static function cached_rss_display($rss_id, $url)
2453
-    {
2454
-        $loading = '<p class="widget-loading hide-if-no-js">'
2455
-                   . __('Loading&#8230;', 'event_espresso')
2456
-                   . '</p><p class="hide-if-js">'
2457
-                   . esc_html__('This widget requires JavaScript.', 'event_espresso')
2458
-                   . '</p>';
2459
-        $pre = '<div class="espresso-rss-display">' . "\n\t";
2460
-        $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2461
-        $post = '</div>' . "\n";
2462
-        $cache_key = 'ee_rss_' . md5($rss_id);
2463
-        $output = get_transient($cache_key);
2464
-        if ($output !== false) {
2465
-            echo $pre . $output . $post;
2466
-            return true;
2467
-        }
2468
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2469
-            echo $pre . $loading . $post;
2470
-            return false;
2471
-        }
2472
-        ob_start();
2473
-        wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2474
-        set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2475
-        return true;
2476
-    }
2477
-
2478
-
2479
-    public function espresso_news_post_box()
2480
-    {
2481
-        ?>
2274
+		return $entries_per_page_dropdown;
2275
+	}
2276
+
2277
+
2278
+	/**
2279
+	 *        _set_search_attributes
2280
+	 *
2281
+	 * @return        void
2282
+	 */
2283
+	public function _set_search_attributes()
2284
+	{
2285
+		$this->_template_args['search']['btn_label'] = sprintf(
2286
+			esc_html__('Search %s', 'event_espresso'),
2287
+			empty($this->_search_btn_label) ? $this->page_label
2288
+				: $this->_search_btn_label
2289
+		);
2290
+		$this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2291
+	}
2292
+
2293
+
2294
+
2295
+	/*** END LIST TABLE METHODS **/
2296
+
2297
+
2298
+	/**
2299
+	 * _add_registered_metaboxes
2300
+	 *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2301
+	 *
2302
+	 * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2303
+	 * @return void
2304
+	 * @throws EE_Error
2305
+	 */
2306
+	private function _add_registered_meta_boxes()
2307
+	{
2308
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2309
+		// we only add meta boxes if the page_route calls for it
2310
+		if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2311
+			&& is_array(
2312
+				$this->_route_config['metaboxes']
2313
+			)
2314
+		) {
2315
+			// this simply loops through the callbacks provided
2316
+			// and checks if there is a corresponding callback registered by the child
2317
+			// if there is then we go ahead and process the metabox loader.
2318
+			foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2319
+				// first check for Closures
2320
+				if ($metabox_callback instanceof Closure) {
2321
+					$result = $metabox_callback();
2322
+				} elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2323
+					$result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2324
+				} else {
2325
+					$result = $this->{$metabox_callback}();
2326
+				}
2327
+				if ($result === false) {
2328
+					// user error msg
2329
+					$error_msg = esc_html__(
2330
+						'An error occurred. The  requested metabox could not be found.',
2331
+						'event_espresso'
2332
+					);
2333
+					// developer error msg
2334
+					$error_msg .= '||'
2335
+								  . sprintf(
2336
+									  esc_html__(
2337
+										  '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.',
2338
+										  'event_espresso'
2339
+									  ),
2340
+									  $metabox_callback
2341
+								  );
2342
+					throw new EE_Error($error_msg);
2343
+				}
2344
+			}
2345
+		}
2346
+	}
2347
+
2348
+
2349
+	/**
2350
+	 * _add_screen_columns
2351
+	 * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2352
+	 * the dynamic column template and we'll setup the column options for the page.
2353
+	 *
2354
+	 * @return void
2355
+	 */
2356
+	private function _add_screen_columns()
2357
+	{
2358
+		if (is_array($this->_route_config)
2359
+			&& isset($this->_route_config['columns'])
2360
+			&& is_array($this->_route_config['columns'])
2361
+			&& count($this->_route_config['columns']) === 2
2362
+		) {
2363
+			add_screen_option(
2364
+				'layout_columns',
2365
+				array(
2366
+					'max'     => (int) $this->_route_config['columns'][0],
2367
+					'default' => (int) $this->_route_config['columns'][1],
2368
+				)
2369
+			);
2370
+			$this->_template_args['num_columns'] = $this->_route_config['columns'][0];
2371
+			$screen_id = $this->_current_screen->id;
2372
+			$screen_columns = (int) get_user_option("screen_layout_{$screen_id}");
2373
+			$total_columns = ! empty($screen_columns)
2374
+				? $screen_columns
2375
+				: $this->_route_config['columns'][1];
2376
+			$this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2377
+			$this->_template_args['current_page'] = $this->_wp_page_slug;
2378
+			$this->_template_args['screen'] = $this->_current_screen;
2379
+			$this->_column_template_path = EE_ADMIN_TEMPLATE
2380
+										   . 'admin_details_metabox_column_wrapper.template.php';
2381
+			// finally if we don't have has_metaboxes set in the route config
2382
+			// let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2383
+			$this->_route_config['has_metaboxes'] = true;
2384
+		}
2385
+	}
2386
+
2387
+
2388
+
2389
+	/** GLOBALLY AVAILABLE METABOXES **/
2390
+
2391
+
2392
+	/**
2393
+	 * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2394
+	 * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2395
+	 * these get loaded on.
2396
+	 */
2397
+	private function _espresso_news_post_box()
2398
+	{
2399
+		$news_box_title = apply_filters(
2400
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2401
+			esc_html__('New @ Event Espresso', 'event_espresso')
2402
+		);
2403
+		add_meta_box(
2404
+			'espresso_news_post_box',
2405
+			$news_box_title,
2406
+			array(
2407
+				$this,
2408
+				'espresso_news_post_box',
2409
+			),
2410
+			$this->_wp_page_slug,
2411
+			'side'
2412
+		);
2413
+	}
2414
+
2415
+
2416
+	/**
2417
+	 * Code for setting up espresso ratings request metabox.
2418
+	 */
2419
+	protected function _espresso_ratings_request()
2420
+	{
2421
+		if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2422
+			return;
2423
+		}
2424
+		$ratings_box_title = apply_filters(
2425
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2426
+			esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2427
+		);
2428
+		add_meta_box(
2429
+			'espresso_ratings_request',
2430
+			$ratings_box_title,
2431
+			array(
2432
+				$this,
2433
+				'espresso_ratings_request',
2434
+			),
2435
+			$this->_wp_page_slug,
2436
+			'side'
2437
+		);
2438
+	}
2439
+
2440
+
2441
+	/**
2442
+	 * Code for setting up espresso ratings request metabox content.
2443
+	 *
2444
+	 * @throws DomainException
2445
+	 */
2446
+	public function espresso_ratings_request()
2447
+	{
2448
+		EEH_Template::display_template(EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php');
2449
+	}
2450
+
2451
+
2452
+	public static function cached_rss_display($rss_id, $url)
2453
+	{
2454
+		$loading = '<p class="widget-loading hide-if-no-js">'
2455
+				   . __('Loading&#8230;', 'event_espresso')
2456
+				   . '</p><p class="hide-if-js">'
2457
+				   . esc_html__('This widget requires JavaScript.', 'event_espresso')
2458
+				   . '</p>';
2459
+		$pre = '<div class="espresso-rss-display">' . "\n\t";
2460
+		$pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2461
+		$post = '</div>' . "\n";
2462
+		$cache_key = 'ee_rss_' . md5($rss_id);
2463
+		$output = get_transient($cache_key);
2464
+		if ($output !== false) {
2465
+			echo $pre . $output . $post;
2466
+			return true;
2467
+		}
2468
+		if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2469
+			echo $pre . $loading . $post;
2470
+			return false;
2471
+		}
2472
+		ob_start();
2473
+		wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2474
+		set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2475
+		return true;
2476
+	}
2477
+
2478
+
2479
+	public function espresso_news_post_box()
2480
+	{
2481
+		?>
2482 2482
         <div class="padding">
2483 2483
             <div id="espresso_news_post_box_content" class="infolinks">
2484 2484
                 <?php
2485
-                // Get RSS Feed(s)
2486
-                self::cached_rss_display(
2487
-                    'espresso_news_post_box_content',
2488
-                    urlencode(
2489
-                        apply_filters(
2490
-                            'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2491
-                            'http://eventespresso.com/feed/'
2492
-                        )
2493
-                    )
2494
-                );
2495
-                ?>
2485
+				// Get RSS Feed(s)
2486
+				self::cached_rss_display(
2487
+					'espresso_news_post_box_content',
2488
+					urlencode(
2489
+						apply_filters(
2490
+							'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2491
+							'http://eventespresso.com/feed/'
2492
+						)
2493
+					)
2494
+				);
2495
+				?>
2496 2496
             </div>
2497 2497
             <?php do_action('AHEE__EE_Admin_Page__espresso_news_post_box__after_content'); ?>
2498 2498
         </div>
2499 2499
         <?php
2500
-    }
2501
-
2502
-
2503
-    private function _espresso_links_post_box()
2504
-    {
2505
-        // Hiding until we actually have content to put in here...
2506
-        // 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');
2507
-    }
2508
-
2509
-
2510
-    public function espresso_links_post_box()
2511
-    {
2512
-        // Hiding until we actually have content to put in here...
2513
-        // EEH_Template::display_template(
2514
-        //     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2515
-        // );
2516
-    }
2517
-
2518
-
2519
-    protected function _espresso_sponsors_post_box()
2520
-    {
2521
-        if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2522
-            add_meta_box(
2523
-                'espresso_sponsors_post_box',
2524
-                esc_html__('Event Espresso Highlights', 'event_espresso'),
2525
-                array($this, 'espresso_sponsors_post_box'),
2526
-                $this->_wp_page_slug,
2527
-                'side'
2528
-            );
2529
-        }
2530
-    }
2531
-
2532
-
2533
-    public function espresso_sponsors_post_box()
2534
-    {
2535
-        EEH_Template::display_template(
2536
-            EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2537
-        );
2538
-    }
2539
-
2540
-
2541
-    private function _publish_post_box()
2542
-    {
2543
-        $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2544
-        // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2545
-        // then we'll use that for the metabox label.
2546
-        // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2547
-        if (! empty($this->_labels['publishbox'])) {
2548
-            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2549
-                : $this->_labels['publishbox'];
2550
-        } else {
2551
-            $box_label = esc_html__('Publish', 'event_espresso');
2552
-        }
2553
-        $box_label = apply_filters(
2554
-            'FHEE__EE_Admin_Page___publish_post_box__box_label',
2555
-            $box_label,
2556
-            $this->_req_action,
2557
-            $this
2558
-        );
2559
-        add_meta_box(
2560
-            $meta_box_ref,
2561
-            $box_label,
2562
-            array($this, 'editor_overview'),
2563
-            $this->_current_screen->id,
2564
-            'side',
2565
-            'high'
2566
-        );
2567
-    }
2568
-
2569
-
2570
-    public function editor_overview()
2571
-    {
2572
-        // if we have extra content set let's add it in if not make sure its empty
2573
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2574
-            ? $this->_template_args['publish_box_extra_content']
2575
-            : '';
2576
-        echo EEH_Template::display_template(
2577
-            EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2578
-            $this->_template_args,
2579
-            true
2580
-        );
2581
-    }
2582
-
2583
-
2584
-    /** end of globally available metaboxes section **/
2585
-
2586
-
2587
-    /**
2588
-     * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2589
-     * protected method.
2590
-     *
2591
-     * @see   $this->_set_publish_post_box_vars for param details
2592
-     * @since 4.6.0
2593
-     * @param string $name
2594
-     * @param int    $id
2595
-     * @param bool   $delete
2596
-     * @param string $save_close_redirect_URL
2597
-     * @param bool   $both_btns
2598
-     * @throws EE_Error
2599
-     * @throws InvalidArgumentException
2600
-     * @throws InvalidDataTypeException
2601
-     * @throws InvalidInterfaceException
2602
-     */
2603
-    public function set_publish_post_box_vars(
2604
-        $name = '',
2605
-        $id = 0,
2606
-        $delete = false,
2607
-        $save_close_redirect_URL = '',
2608
-        $both_btns = true
2609
-    ) {
2610
-        $this->_set_publish_post_box_vars(
2611
-            $name,
2612
-            $id,
2613
-            $delete,
2614
-            $save_close_redirect_URL,
2615
-            $both_btns
2616
-        );
2617
-    }
2618
-
2619
-
2620
-    /**
2621
-     * Sets the _template_args arguments used by the _publish_post_box shortcut
2622
-     * Note: currently there is no validation for this.  However if you want the delete button, the
2623
-     * save, and save and close buttons to work properly, then you will want to include a
2624
-     * values for the name and id arguments.
2625
-     *
2626
-     * @todo  Add in validation for name/id arguments.
2627
-     * @param    string  $name                    key used for the action ID (i.e. event_id)
2628
-     * @param    int     $id                      id attached to the item published
2629
-     * @param    string  $delete                  page route callback for the delete action
2630
-     * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2631
-     * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2632
-     *                                            the Save button
2633
-     * @throws EE_Error
2634
-     * @throws InvalidArgumentException
2635
-     * @throws InvalidDataTypeException
2636
-     * @throws InvalidInterfaceException
2637
-     */
2638
-    protected function _set_publish_post_box_vars(
2639
-        $name = '',
2640
-        $id = 0,
2641
-        $delete = '',
2642
-        $save_close_redirect_URL = '',
2643
-        $both_btns = true
2644
-    ) {
2645
-        // if Save & Close, use a custom redirect URL or default to the main page?
2646
-        $save_close_redirect_URL = ! empty($save_close_redirect_URL)
2647
-            ? $save_close_redirect_URL
2648
-            : $this->_admin_base_url;
2649
-        // create the Save & Close and Save buttons
2650
-        $this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2651
-        // if we have extra content set let's add it in if not make sure its empty
2652
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2653
-            ? $this->_template_args['publish_box_extra_content']
2654
-            : '';
2655
-        if ($delete && ! empty($id)) {
2656
-            // make sure we have a default if just true is sent.
2657
-            $delete = ! empty($delete) ? $delete : 'delete';
2658
-            $delete_link_args = array($name => $id);
2659
-            $delete = $this->get_action_link_or_button(
2660
-                $delete,
2661
-                $delete,
2662
-                $delete_link_args,
2663
-                'submitdelete deletion'
2664
-            );
2665
-        }
2666
-        $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2667
-        if (! empty($name) && ! empty($id)) {
2668
-            $hidden_field_arr[ $name ] = array(
2669
-                'type'  => 'hidden',
2670
-                'value' => $id,
2671
-            );
2672
-            $hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2673
-        } else {
2674
-            $hf = '';
2675
-        }
2676
-        // add hidden field
2677
-        $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2678
-            ? $hf[ $name ]['field']
2679
-            : $hf;
2680
-    }
2681
-
2682
-
2683
-    /**
2684
-     * displays an error message to ppl who have javascript disabled
2685
-     *
2686
-     * @return void
2687
-     */
2688
-    private function _display_no_javascript_warning()
2689
-    {
2690
-        ?>
2500
+	}
2501
+
2502
+
2503
+	private function _espresso_links_post_box()
2504
+	{
2505
+		// Hiding until we actually have content to put in here...
2506
+		// 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');
2507
+	}
2508
+
2509
+
2510
+	public function espresso_links_post_box()
2511
+	{
2512
+		// Hiding until we actually have content to put in here...
2513
+		// EEH_Template::display_template(
2514
+		//     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2515
+		// );
2516
+	}
2517
+
2518
+
2519
+	protected function _espresso_sponsors_post_box()
2520
+	{
2521
+		if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2522
+			add_meta_box(
2523
+				'espresso_sponsors_post_box',
2524
+				esc_html__('Event Espresso Highlights', 'event_espresso'),
2525
+				array($this, 'espresso_sponsors_post_box'),
2526
+				$this->_wp_page_slug,
2527
+				'side'
2528
+			);
2529
+		}
2530
+	}
2531
+
2532
+
2533
+	public function espresso_sponsors_post_box()
2534
+	{
2535
+		EEH_Template::display_template(
2536
+			EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2537
+		);
2538
+	}
2539
+
2540
+
2541
+	private function _publish_post_box()
2542
+	{
2543
+		$meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2544
+		// if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2545
+		// then we'll use that for the metabox label.
2546
+		// Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2547
+		if (! empty($this->_labels['publishbox'])) {
2548
+			$box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2549
+				: $this->_labels['publishbox'];
2550
+		} else {
2551
+			$box_label = esc_html__('Publish', 'event_espresso');
2552
+		}
2553
+		$box_label = apply_filters(
2554
+			'FHEE__EE_Admin_Page___publish_post_box__box_label',
2555
+			$box_label,
2556
+			$this->_req_action,
2557
+			$this
2558
+		);
2559
+		add_meta_box(
2560
+			$meta_box_ref,
2561
+			$box_label,
2562
+			array($this, 'editor_overview'),
2563
+			$this->_current_screen->id,
2564
+			'side',
2565
+			'high'
2566
+		);
2567
+	}
2568
+
2569
+
2570
+	public function editor_overview()
2571
+	{
2572
+		// if we have extra content set let's add it in if not make sure its empty
2573
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2574
+			? $this->_template_args['publish_box_extra_content']
2575
+			: '';
2576
+		echo EEH_Template::display_template(
2577
+			EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2578
+			$this->_template_args,
2579
+			true
2580
+		);
2581
+	}
2582
+
2583
+
2584
+	/** end of globally available metaboxes section **/
2585
+
2586
+
2587
+	/**
2588
+	 * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2589
+	 * protected method.
2590
+	 *
2591
+	 * @see   $this->_set_publish_post_box_vars for param details
2592
+	 * @since 4.6.0
2593
+	 * @param string $name
2594
+	 * @param int    $id
2595
+	 * @param bool   $delete
2596
+	 * @param string $save_close_redirect_URL
2597
+	 * @param bool   $both_btns
2598
+	 * @throws EE_Error
2599
+	 * @throws InvalidArgumentException
2600
+	 * @throws InvalidDataTypeException
2601
+	 * @throws InvalidInterfaceException
2602
+	 */
2603
+	public function set_publish_post_box_vars(
2604
+		$name = '',
2605
+		$id = 0,
2606
+		$delete = false,
2607
+		$save_close_redirect_URL = '',
2608
+		$both_btns = true
2609
+	) {
2610
+		$this->_set_publish_post_box_vars(
2611
+			$name,
2612
+			$id,
2613
+			$delete,
2614
+			$save_close_redirect_URL,
2615
+			$both_btns
2616
+		);
2617
+	}
2618
+
2619
+
2620
+	/**
2621
+	 * Sets the _template_args arguments used by the _publish_post_box shortcut
2622
+	 * Note: currently there is no validation for this.  However if you want the delete button, the
2623
+	 * save, and save and close buttons to work properly, then you will want to include a
2624
+	 * values for the name and id arguments.
2625
+	 *
2626
+	 * @todo  Add in validation for name/id arguments.
2627
+	 * @param    string  $name                    key used for the action ID (i.e. event_id)
2628
+	 * @param    int     $id                      id attached to the item published
2629
+	 * @param    string  $delete                  page route callback for the delete action
2630
+	 * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2631
+	 * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2632
+	 *                                            the Save button
2633
+	 * @throws EE_Error
2634
+	 * @throws InvalidArgumentException
2635
+	 * @throws InvalidDataTypeException
2636
+	 * @throws InvalidInterfaceException
2637
+	 */
2638
+	protected function _set_publish_post_box_vars(
2639
+		$name = '',
2640
+		$id = 0,
2641
+		$delete = '',
2642
+		$save_close_redirect_URL = '',
2643
+		$both_btns = true
2644
+	) {
2645
+		// if Save & Close, use a custom redirect URL or default to the main page?
2646
+		$save_close_redirect_URL = ! empty($save_close_redirect_URL)
2647
+			? $save_close_redirect_URL
2648
+			: $this->_admin_base_url;
2649
+		// create the Save & Close and Save buttons
2650
+		$this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2651
+		// if we have extra content set let's add it in if not make sure its empty
2652
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2653
+			? $this->_template_args['publish_box_extra_content']
2654
+			: '';
2655
+		if ($delete && ! empty($id)) {
2656
+			// make sure we have a default if just true is sent.
2657
+			$delete = ! empty($delete) ? $delete : 'delete';
2658
+			$delete_link_args = array($name => $id);
2659
+			$delete = $this->get_action_link_or_button(
2660
+				$delete,
2661
+				$delete,
2662
+				$delete_link_args,
2663
+				'submitdelete deletion'
2664
+			);
2665
+		}
2666
+		$this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2667
+		if (! empty($name) && ! empty($id)) {
2668
+			$hidden_field_arr[ $name ] = array(
2669
+				'type'  => 'hidden',
2670
+				'value' => $id,
2671
+			);
2672
+			$hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2673
+		} else {
2674
+			$hf = '';
2675
+		}
2676
+		// add hidden field
2677
+		$this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2678
+			? $hf[ $name ]['field']
2679
+			: $hf;
2680
+	}
2681
+
2682
+
2683
+	/**
2684
+	 * displays an error message to ppl who have javascript disabled
2685
+	 *
2686
+	 * @return void
2687
+	 */
2688
+	private function _display_no_javascript_warning()
2689
+	{
2690
+		?>
2691 2691
         <noscript>
2692 2692
             <div id="no-js-message" class="error">
2693 2693
                 <p style="font-size:1.3em;">
2694 2694
                     <span style="color:red;"><?php esc_html_e('Warning!', 'event_espresso'); ?></span>
2695 2695
                     <?php esc_html_e(
2696
-                        '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.',
2697
-                        'event_espresso'
2698
-                    ); ?>
2696
+						'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.',
2697
+						'event_espresso'
2698
+					); ?>
2699 2699
                 </p>
2700 2700
             </div>
2701 2701
         </noscript>
2702 2702
         <?php
2703
-    }
2704
-
2705
-
2706
-    /**
2707
-     * displays espresso success and/or error notices
2708
-     *
2709
-     * @return void
2710
-     */
2711
-    private function _display_espresso_notices()
2712
-    {
2713
-        $notices = $this->_get_transient(true);
2714
-        echo stripslashes($notices);
2715
-    }
2716
-
2717
-
2718
-    /**
2719
-     * spinny things pacify the masses
2720
-     *
2721
-     * @return void
2722
-     */
2723
-    protected function _add_admin_page_ajax_loading_img()
2724
-    {
2725
-        ?>
2703
+	}
2704
+
2705
+
2706
+	/**
2707
+	 * displays espresso success and/or error notices
2708
+	 *
2709
+	 * @return void
2710
+	 */
2711
+	private function _display_espresso_notices()
2712
+	{
2713
+		$notices = $this->_get_transient(true);
2714
+		echo stripslashes($notices);
2715
+	}
2716
+
2717
+
2718
+	/**
2719
+	 * spinny things pacify the masses
2720
+	 *
2721
+	 * @return void
2722
+	 */
2723
+	protected function _add_admin_page_ajax_loading_img()
2724
+	{
2725
+		?>
2726 2726
         <div id="espresso-ajax-loading" class="ajax-loading-grey">
2727 2727
             <span class="ee-spinner ee-spin"></span><span class="hidden"><?php
2728
-                esc_html_e('loading...', 'event_espresso'); ?></span>
2728
+				esc_html_e('loading...', 'event_espresso'); ?></span>
2729 2729
         </div>
2730 2730
         <?php
2731
-    }
2731
+	}
2732 2732
 
2733 2733
 
2734
-    /**
2735
-     * add admin page overlay for modal boxes
2736
-     *
2737
-     * @return void
2738
-     */
2739
-    protected function _add_admin_page_overlay()
2740
-    {
2741
-        ?>
2734
+	/**
2735
+	 * add admin page overlay for modal boxes
2736
+	 *
2737
+	 * @return void
2738
+	 */
2739
+	protected function _add_admin_page_overlay()
2740
+	{
2741
+		?>
2742 2742
         <div id="espresso-admin-page-overlay-dv" class=""></div>
2743 2743
         <?php
2744
-    }
2745
-
2746
-
2747
-    /**
2748
-     * facade for add_meta_box
2749
-     *
2750
-     * @param string  $action        where the metabox get's displayed
2751
-     * @param string  $title         Title of Metabox (output in metabox header)
2752
-     * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2753
-     *                               instead of the one created in here.
2754
-     * @param array   $callback_args an array of args supplied for the metabox
2755
-     * @param string  $column        what metabox column
2756
-     * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2757
-     * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2758
-     *                               created but just set our own callback for wp's add_meta_box.
2759
-     * @throws DomainException
2760
-     */
2761
-    public function _add_admin_page_meta_box(
2762
-        $action,
2763
-        $title,
2764
-        $callback,
2765
-        $callback_args,
2766
-        $column = 'normal',
2767
-        $priority = 'high',
2768
-        $create_func = true
2769
-    ) {
2770
-        do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2771
-        // 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.
2772
-        if (empty($callback_args) && $create_func) {
2773
-            $callback_args = array(
2774
-                'template_path' => $this->_template_path,
2775
-                'template_args' => $this->_template_args,
2776
-            );
2777
-        }
2778
-        // 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)
2779
-        $call_back_func = $create_func
2780
-            ? static function ($post, $metabox) {
2781
-                do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2782
-                echo EEH_Template::display_template(
2783
-                    $metabox['args']['template_path'],
2784
-                    $metabox['args']['template_args'],
2785
-                    true
2786
-                );
2787
-            }
2788
-            : $callback;
2789
-        add_meta_box(
2790
-            str_replace('_', '-', $action) . '-mbox',
2791
-            $title,
2792
-            $call_back_func,
2793
-            $this->_wp_page_slug,
2794
-            $column,
2795
-            $priority,
2796
-            $callback_args
2797
-        );
2798
-    }
2799
-
2800
-
2801
-    /**
2802
-     * generates HTML wrapper for and admin details page that contains metaboxes in columns
2803
-     *
2804
-     * @throws DomainException
2805
-     * @throws EE_Error
2806
-     * @throws InvalidArgumentException
2807
-     * @throws InvalidDataTypeException
2808
-     * @throws InvalidInterfaceException
2809
-     */
2810
-    public function display_admin_page_with_metabox_columns()
2811
-    {
2812
-        $this->_template_args['post_body_content'] = $this->_template_args['admin_page_content'];
2813
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2814
-            $this->_column_template_path,
2815
-            $this->_template_args,
2816
-            true
2817
-        );
2818
-        // the final wrapper
2819
-        $this->admin_page_wrapper();
2820
-    }
2821
-
2822
-
2823
-    /**
2824
-     * generates  HTML wrapper for an admin details page
2825
-     *
2826
-     * @return void
2827
-     * @throws DomainException
2828
-     * @throws EE_Error
2829
-     * @throws InvalidArgumentException
2830
-     * @throws InvalidDataTypeException
2831
-     * @throws InvalidInterfaceException
2832
-     */
2833
-    public function display_admin_page_with_sidebar()
2834
-    {
2835
-        $this->_display_admin_page(true);
2836
-    }
2837
-
2838
-
2839
-    /**
2840
-     * generates  HTML wrapper for an admin details page (except no sidebar)
2841
-     *
2842
-     * @return void
2843
-     * @throws DomainException
2844
-     * @throws EE_Error
2845
-     * @throws InvalidArgumentException
2846
-     * @throws InvalidDataTypeException
2847
-     * @throws InvalidInterfaceException
2848
-     */
2849
-    public function display_admin_page_with_no_sidebar()
2850
-    {
2851
-        $this->_display_admin_page();
2852
-    }
2853
-
2854
-
2855
-    /**
2856
-     * generates HTML wrapper for an EE about admin page (no sidebar)
2857
-     *
2858
-     * @return void
2859
-     * @throws DomainException
2860
-     * @throws EE_Error
2861
-     * @throws InvalidArgumentException
2862
-     * @throws InvalidDataTypeException
2863
-     * @throws InvalidInterfaceException
2864
-     */
2865
-    public function display_about_admin_page()
2866
-    {
2867
-        $this->_display_admin_page(false, true);
2868
-    }
2869
-
2870
-
2871
-    /**
2872
-     * display_admin_page
2873
-     * contains the code for actually displaying an admin page
2874
-     *
2875
-     * @param boolean $sidebar true with sidebar, false without
2876
-     * @param boolean $about   use the about admin wrapper instead of the default.
2877
-     * @return void
2878
-     * @throws DomainException
2879
-     * @throws EE_Error
2880
-     * @throws InvalidArgumentException
2881
-     * @throws InvalidDataTypeException
2882
-     * @throws InvalidInterfaceException
2883
-     */
2884
-    private function _display_admin_page($sidebar = false, $about = false)
2885
-    {
2886
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2887
-        // custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2888
-        do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2889
-        // set current wp page slug - looks like: event-espresso_page_event_categories
2890
-        // keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2891
-        $this->_template_args['current_page'] = $this->_wp_page_slug;
2892
-        $this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2893
-            ? 'poststuff'
2894
-            : 'espresso-default-admin';
2895
-        $template_path = $sidebar
2896
-            ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2897
-            : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2898
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2899
-            $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2900
-        }
2901
-        $template_path = ! empty($this->_column_template_path)
2902
-            ? $this->_column_template_path : $template_path;
2903
-        $this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content'])
2904
-            ? $this->_template_args['admin_page_content']
2905
-            : '';
2906
-        $this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2907
-            ? $this->_template_args['before_admin_page_content']
2908
-            : '';
2909
-        $this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content'])
2910
-            ? $this->_template_args['after_admin_page_content']
2911
-            : '';
2912
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2913
-            $template_path,
2914
-            $this->_template_args,
2915
-            true
2916
-        );
2917
-        // the final template wrapper
2918
-        $this->admin_page_wrapper($about);
2919
-    }
2920
-
2921
-
2922
-    /**
2923
-     * This is used to display caf preview pages.
2924
-     *
2925
-     * @since 4.3.2
2926
-     * @param string $utm_campaign_source what is the key used for google analytics link
2927
-     * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2928
-     *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2929
-     * @return void
2930
-     * @throws DomainException
2931
-     * @throws EE_Error
2932
-     * @throws InvalidArgumentException
2933
-     * @throws InvalidDataTypeException
2934
-     * @throws InvalidInterfaceException
2935
-     */
2936
-    public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2937
-    {
2938
-        // let's generate a default preview action button if there isn't one already present.
2939
-        $this->_labels['buttons']['buy_now'] = esc_html__(
2940
-            'Upgrade to Event Espresso 4 Right Now',
2941
-            'event_espresso'
2942
-        );
2943
-        $buy_now_url = add_query_arg(
2944
-            array(
2945
-                'ee_ver'       => 'ee4',
2946
-                'utm_source'   => 'ee4_plugin_admin',
2947
-                'utm_medium'   => 'link',
2948
-                'utm_campaign' => $utm_campaign_source,
2949
-                'utm_content'  => 'buy_now_button',
2950
-            ),
2951
-            'http://eventespresso.com/pricing/'
2952
-        );
2953
-        $this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2954
-            ? $this->get_action_link_or_button(
2955
-                '',
2956
-                'buy_now',
2957
-                array(),
2958
-                'button-primary button-large',
2959
-                $buy_now_url,
2960
-                true
2961
-            )
2962
-            : $this->_template_args['preview_action_button'];
2963
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2964
-            EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2965
-            $this->_template_args,
2966
-            true
2967
-        );
2968
-        $this->_display_admin_page($display_sidebar);
2969
-    }
2970
-
2971
-
2972
-    /**
2973
-     * display_admin_list_table_page_with_sidebar
2974
-     * generates HTML wrapper for an admin_page with list_table
2975
-     *
2976
-     * @return void
2977
-     * @throws DomainException
2978
-     * @throws EE_Error
2979
-     * @throws InvalidArgumentException
2980
-     * @throws InvalidDataTypeException
2981
-     * @throws InvalidInterfaceException
2982
-     */
2983
-    public function display_admin_list_table_page_with_sidebar()
2984
-    {
2985
-        $this->_display_admin_list_table_page(true);
2986
-    }
2987
-
2988
-
2989
-    /**
2990
-     * display_admin_list_table_page_with_no_sidebar
2991
-     * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
2992
-     *
2993
-     * @return void
2994
-     * @throws DomainException
2995
-     * @throws EE_Error
2996
-     * @throws InvalidArgumentException
2997
-     * @throws InvalidDataTypeException
2998
-     * @throws InvalidInterfaceException
2999
-     */
3000
-    public function display_admin_list_table_page_with_no_sidebar()
3001
-    {
3002
-        $this->_display_admin_list_table_page();
3003
-    }
3004
-
3005
-
3006
-    /**
3007
-     * generates html wrapper for an admin_list_table page
3008
-     *
3009
-     * @param boolean $sidebar whether to display with sidebar or not.
3010
-     * @return void
3011
-     * @throws DomainException
3012
-     * @throws EE_Error
3013
-     * @throws InvalidArgumentException
3014
-     * @throws InvalidDataTypeException
3015
-     * @throws InvalidInterfaceException
3016
-     */
3017
-    private function _display_admin_list_table_page($sidebar = false)
3018
-    {
3019
-        // setup search attributes
3020
-        $this->_set_search_attributes();
3021
-        $this->_template_args['current_page'] = $this->_wp_page_slug;
3022
-        $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3023
-        $this->_template_args['table_url'] = defined('DOING_AJAX')
3024
-            ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3025
-            : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
3026
-        $this->_template_args['list_table'] = $this->_list_table_object;
3027
-        $this->_template_args['current_route'] = $this->_req_action;
3028
-        $this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3029
-        $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
3030
-        if (! empty($ajax_sorting_callback)) {
3031
-            $sortable_list_table_form_fields = wp_nonce_field(
3032
-                $ajax_sorting_callback . '_nonce',
3033
-                $ajax_sorting_callback . '_nonce',
3034
-                false,
3035
-                false
3036
-            );
3037
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
3038
-                                                . $this->page_slug
3039
-                                                . '" />';
3040
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
3041
-                                                . $ajax_sorting_callback
3042
-                                                . '" />';
3043
-        } else {
3044
-            $sortable_list_table_form_fields = '';
3045
-        }
3046
-        $this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
3047
-        $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
3048
-            ? $this->_template_args['list_table_hidden_fields']
3049
-            : '';
3050
-        $nonce_ref = $this->_req_action . '_nonce';
3051
-        $hidden_form_fields .= '<input type="hidden" name="'
3052
-                               . $nonce_ref
3053
-                               . '" value="'
3054
-                               . wp_create_nonce($nonce_ref)
3055
-                               . '">';
3056
-        $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3057
-        // display message about search results?
3058
-        $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3059
-            ? '<p class="ee-search-results">' . sprintf(
3060
-                esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3061
-                trim($this->_req_data['s'], '%')
3062
-            ) . '</p>'
3063
-            : '';
3064
-        // filter before_list_table template arg
3065
-        $this->_template_args['before_list_table'] = apply_filters(
3066
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3067
-            $this->_template_args['before_list_table'],
3068
-            $this->page_slug,
3069
-            $this->_req_data,
3070
-            $this->_req_action
3071
-        );
3072
-        // convert to array and filter again
3073
-        // arrays are easier to inject new items in a specific location,
3074
-        // but would not be backwards compatible, so we have to add a new filter
3075
-        $this->_template_args['before_list_table'] = implode(
3076
-            " \n",
3077
-            (array) apply_filters(
3078
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3079
-                (array) $this->_template_args['before_list_table'],
3080
-                $this->page_slug,
3081
-                $this->_req_data,
3082
-                $this->_req_action
3083
-            )
3084
-        );
3085
-        // filter after_list_table template arg
3086
-        $this->_template_args['after_list_table'] = apply_filters(
3087
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3088
-            $this->_template_args['after_list_table'],
3089
-            $this->page_slug,
3090
-            $this->_req_data,
3091
-            $this->_req_action
3092
-        );
3093
-        // convert to array and filter again
3094
-        // arrays are easier to inject new items in a specific location,
3095
-        // but would not be backwards compatible, so we have to add a new filter
3096
-        $this->_template_args['after_list_table'] = implode(
3097
-            " \n",
3098
-            (array) apply_filters(
3099
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3100
-                (array) $this->_template_args['after_list_table'],
3101
-                $this->page_slug,
3102
-                $this->_req_data,
3103
-                $this->_req_action
3104
-            )
3105
-        );
3106
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3107
-            $template_path,
3108
-            $this->_template_args,
3109
-            true
3110
-        );
3111
-        // the final template wrapper
3112
-        if ($sidebar) {
3113
-            $this->display_admin_page_with_sidebar();
3114
-        } else {
3115
-            $this->display_admin_page_with_no_sidebar();
3116
-        }
3117
-    }
3118
-
3119
-
3120
-    /**
3121
-     * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3122
-     * html string for the legend.
3123
-     * $items are expected in an array in the following format:
3124
-     * $legend_items = array(
3125
-     *        'item_id' => array(
3126
-     *            'icon' => 'http://url_to_icon_being_described.png',
3127
-     *            'desc' => esc_html__('localized description of item');
3128
-     *        )
3129
-     * );
3130
-     *
3131
-     * @param  array $items see above for format of array
3132
-     * @return string html string of legend
3133
-     * @throws DomainException
3134
-     */
3135
-    protected function _display_legend($items)
3136
-    {
3137
-        $this->_template_args['items'] = apply_filters(
3138
-            'FHEE__EE_Admin_Page___display_legend__items',
3139
-            (array) $items,
3140
-            $this
3141
-        );
3142
-        return EEH_Template::display_template(
3143
-            EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3144
-            $this->_template_args,
3145
-            true
3146
-        );
3147
-    }
3148
-
3149
-
3150
-    /**
3151
-     * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3152
-     * The returned json object is created from an array in the following format:
3153
-     * array(
3154
-     *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3155
-     *  'success' => FALSE, //(default FALSE) - contains any special success message.
3156
-     *  'notices' => '', // - contains any EE_Error formatted notices
3157
-     *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3158
-     *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3159
-     *  We're also going to include the template args with every package (so js can pick out any specific template args
3160
-     *  that might be included in here)
3161
-     * )
3162
-     * The json object is populated by whatever is set in the $_template_args property.
3163
-     *
3164
-     * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3165
-     *                                 instead of displayed.
3166
-     * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3167
-     * @return void
3168
-     * @throws EE_Error
3169
-     * @throws InvalidArgumentException
3170
-     * @throws InvalidDataTypeException
3171
-     * @throws InvalidInterfaceException
3172
-     */
3173
-    protected function _return_json($sticky_notices = false, $notices_arguments = array())
3174
-    {
3175
-        // make sure any EE_Error notices have been handled.
3176
-        $this->_process_notices($notices_arguments, true, $sticky_notices);
3177
-        $data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3178
-        unset($this->_template_args['data']);
3179
-        $json = array(
3180
-            'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3181
-            'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3182
-            'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3183
-            'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3184
-            'notices'   => EE_Error::get_notices(),
3185
-            'content'   => isset($this->_template_args['admin_page_content'])
3186
-                ? $this->_template_args['admin_page_content'] : '',
3187
-            'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3188
-            'isEEajax'  => true
3189
-            // special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3190
-        );
3191
-        // make sure there are no php errors or headers_sent.  Then we can set correct json header.
3192
-        if (null === error_get_last() || ! headers_sent()) {
3193
-            header('Content-Type: application/json; charset=UTF-8');
3194
-        }
3195
-        echo wp_json_encode($json);
3196
-        exit();
3197
-    }
3198
-
3199
-
3200
-    /**
3201
-     * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3202
-     *
3203
-     * @return void
3204
-     * @throws EE_Error
3205
-     * @throws InvalidArgumentException
3206
-     * @throws InvalidDataTypeException
3207
-     * @throws InvalidInterfaceException
3208
-     */
3209
-    public function return_json()
3210
-    {
3211
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3212
-            $this->_return_json();
3213
-        } else {
3214
-            throw new EE_Error(
3215
-                sprintf(
3216
-                    esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3217
-                    __FUNCTION__
3218
-                )
3219
-            );
3220
-        }
3221
-    }
3222
-
3223
-
3224
-    /**
3225
-     * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3226
-     * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3227
-     *
3228
-     * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3229
-     */
3230
-    public function set_hook_object(EE_Admin_Hooks $hook_obj)
3231
-    {
3232
-        $this->_hook_obj = $hook_obj;
3233
-    }
3234
-
3235
-
3236
-    /**
3237
-     *        generates  HTML wrapper with Tabbed nav for an admin page
3238
-     *
3239
-     * @param boolean $about whether to use the special about page wrapper or default.
3240
-     * @return void
3241
-     * @throws DomainException
3242
-     * @throws EE_Error
3243
-     * @throws InvalidArgumentException
3244
-     * @throws InvalidDataTypeException
3245
-     * @throws InvalidInterfaceException
3246
-     */
3247
-    public function admin_page_wrapper($about = false)
3248
-    {
3249
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3250
-        $this->_nav_tabs = $this->_get_main_nav_tabs();
3251
-        $this->_template_args['nav_tabs'] = $this->_nav_tabs;
3252
-        $this->_template_args['admin_page_title'] = $this->_admin_page_title;
3253
-        $this->_template_args['before_admin_page_content'] = apply_filters(
3254
-            "FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3255
-            isset($this->_template_args['before_admin_page_content'])
3256
-                ? $this->_template_args['before_admin_page_content']
3257
-                : ''
3258
-        );
3259
-        $this->_template_args['after_admin_page_content'] = apply_filters(
3260
-            "FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3261
-            isset($this->_template_args['after_admin_page_content'])
3262
-                ? $this->_template_args['after_admin_page_content']
3263
-                : ''
3264
-        );
3265
-        $this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content();
3266
-        // load settings page wrapper template
3267
-        $template_path = ! defined('DOING_AJAX')
3268
-            ? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3269
-            : EE_ADMIN_TEMPLATE
3270
-              . 'admin_wrapper_ajax.template.php';
3271
-        // about page?
3272
-        $template_path = $about
3273
-            ? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3274
-            : $template_path;
3275
-        if (defined('DOING_AJAX')) {
3276
-            $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3277
-                $template_path,
3278
-                $this->_template_args,
3279
-                true
3280
-            );
3281
-            $this->_return_json();
3282
-        } else {
3283
-            EEH_Template::display_template($template_path, $this->_template_args);
3284
-        }
3285
-    }
3286
-
3287
-
3288
-    /**
3289
-     * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3290
-     *
3291
-     * @return string html
3292
-     * @throws EE_Error
3293
-     */
3294
-    protected function _get_main_nav_tabs()
3295
-    {
3296
-        // let's generate the html using the EEH_Tabbed_Content helper.
3297
-        // We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3298
-        // (rather than setting in the page_routes array)
3299
-        return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3300
-    }
3301
-
3302
-
3303
-    /**
3304
-     *        sort nav tabs
3305
-     *
3306
-     * @param $a
3307
-     * @param $b
3308
-     * @return int
3309
-     */
3310
-    private function _sort_nav_tabs($a, $b)
3311
-    {
3312
-        if ($a['order'] === $b['order']) {
3313
-            return 0;
3314
-        }
3315
-        return ($a['order'] < $b['order']) ? -1 : 1;
3316
-    }
3317
-
3318
-
3319
-    /**
3320
-     *    generates HTML for the forms used on admin pages
3321
-     *
3322
-     * @param    array $input_vars - array of input field details
3323
-     * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3324
-     *                             use)
3325
-     * @param bool     $id
3326
-     * @return string
3327
-     * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3328
-     * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3329
-     */
3330
-    protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3331
-    {
3332
-        $content = $generator === 'string'
3333
-            ? EEH_Form_Fields::get_form_fields($input_vars, $id)
3334
-            : EEH_Form_Fields::get_form_fields_array($input_vars);
3335
-        return $content;
3336
-    }
3337
-
3338
-
3339
-    /**
3340
-     * generates the "Save" and "Save & Close" buttons for edit forms
3341
-     *
3342
-     * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3343
-     *                                   Close" button.
3344
-     * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3345
-     *                                   'Save', [1] => 'save & close')
3346
-     * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3347
-     *                                   via the "name" value in the button).  We can also use this to just dump
3348
-     *                                   default actions by submitting some other value.
3349
-     * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3350
-     *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3351
-     *                                   close (normal form handling).
3352
-     */
3353
-    protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3354
-    {
3355
-        // make sure $text and $actions are in an array
3356
-        $text = (array) $text;
3357
-        $actions = (array) $actions;
3358
-        $referrer_url = empty($referrer)
3359
-            ? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3360
-              . $_SERVER['REQUEST_URI']
3361
-              . '" />'
3362
-            : '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3363
-              . $referrer
3364
-              . '" />';
3365
-        $button_text = ! empty($text)
3366
-            ? $text
3367
-            : array(
3368
-                esc_html__('Save', 'event_espresso'),
3369
-                esc_html__('Save and Close', 'event_espresso'),
3370
-            );
3371
-        $default_names = array('save', 'save_and_close');
3372
-        // add in a hidden index for the current page (so save and close redirects properly)
3373
-        $this->_template_args['save_buttons'] = $referrer_url;
3374
-        foreach ($button_text as $key => $button) {
3375
-            $ref = $default_names[ $key ];
3376
-            $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3377
-                                                     . $ref
3378
-                                                     . '" value="'
3379
-                                                     . $button
3380
-                                                     . '" name="'
3381
-                                                     . (! empty($actions) ? $actions[ $key ] : $ref)
3382
-                                                     . '" id="'
3383
-                                                     . $this->_current_view . '_' . $ref
3384
-                                                     . '" />';
3385
-            if (! $both) {
3386
-                break;
3387
-            }
3388
-        }
3389
-    }
3390
-
3391
-
3392
-    /**
3393
-     * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3394
-     *
3395
-     * @see   $this->_set_add_edit_form_tags() for details on params
3396
-     * @since 4.6.0
3397
-     * @param string $route
3398
-     * @param array  $additional_hidden_fields
3399
-     */
3400
-    public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3401
-    {
3402
-        $this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3403
-    }
3404
-
3405
-
3406
-    /**
3407
-     * set form open and close tags on add/edit pages.
3408
-     *
3409
-     * @param string $route                    the route you want the form to direct to
3410
-     * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3411
-     * @return void
3412
-     */
3413
-    protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3414
-    {
3415
-        if (empty($route)) {
3416
-            $user_msg = esc_html__(
3417
-                'An error occurred. No action was set for this page\'s form.',
3418
-                'event_espresso'
3419
-            );
3420
-            $dev_msg = $user_msg . "\n"
3421
-                       . sprintf(
3422
-                           esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3423
-                           __FUNCTION__,
3424
-                           __CLASS__
3425
-                       );
3426
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3427
-        }
3428
-        // open form
3429
-        $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3430
-                                                             . $this->_admin_base_url
3431
-                                                             . '" id="'
3432
-                                                             . $route
3433
-                                                             . '_event_form" >';
3434
-        // add nonce
3435
-        $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3436
-        $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3437
-        // add REQUIRED form action
3438
-        $hidden_fields = array(
3439
-            'action' => array('type' => 'hidden', 'value' => $route),
3440
-        );
3441
-        // merge arrays
3442
-        $hidden_fields = is_array($additional_hidden_fields)
3443
-            ? array_merge($hidden_fields, $additional_hidden_fields)
3444
-            : $hidden_fields;
3445
-        // generate form fields
3446
-        $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3447
-        // add fields to form
3448
-        foreach ((array) $form_fields as $field_name => $form_field) {
3449
-            $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3450
-        }
3451
-        // close form
3452
-        $this->_template_args['after_admin_page_content'] = '</form>';
3453
-    }
3454
-
3455
-
3456
-    /**
3457
-     * Public Wrapper for _redirect_after_action() method since its
3458
-     * discovered it would be useful for external code to have access.
3459
-     *
3460
-     * @param bool   $success
3461
-     * @param string $what
3462
-     * @param string $action_desc
3463
-     * @param array  $query_args
3464
-     * @param bool   $override_overwrite
3465
-     * @throws EE_Error
3466
-     * @throws InvalidArgumentException
3467
-     * @throws InvalidDataTypeException
3468
-     * @throws InvalidInterfaceException
3469
-     * @see   EE_Admin_Page::_redirect_after_action() for params.
3470
-     * @since 4.5.0
3471
-     */
3472
-    public function redirect_after_action(
3473
-        $success = false,
3474
-        $what = 'item',
3475
-        $action_desc = 'processed',
3476
-        $query_args = array(),
3477
-        $override_overwrite = false
3478
-    ) {
3479
-        $this->_redirect_after_action(
3480
-            $success,
3481
-            $what,
3482
-            $action_desc,
3483
-            $query_args,
3484
-            $override_overwrite
3485
-        );
3486
-    }
3487
-
3488
-
3489
-    /**
3490
-     * Helper method for merging existing request data with the returned redirect url.
3491
-     *
3492
-     * This is typically used for redirects after an action so that if the original view was a filtered view those
3493
-     * filters are still applied.
3494
-     *
3495
-     * @param array $new_route_data
3496
-     * @return array
3497
-     */
3498
-    protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data)
3499
-    {
3500
-        foreach ($this->_req_data as $ref => $value) {
3501
-            // unset nonces
3502
-            if (strpos($ref, 'nonce') !== false) {
3503
-                unset($this->_req_data[ $ref ]);
3504
-                continue;
3505
-            }
3506
-            // urlencode values.
3507
-            $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3508
-            $this->_req_data[ $ref ] = $value;
3509
-        }
3510
-        return array_merge($this->_req_data, $new_route_data);
3511
-    }
3512
-
3513
-
3514
-    /**
3515
-     *    _redirect_after_action
3516
-     *
3517
-     * @param int    $success            - whether success was for two or more records, or just one, or none
3518
-     * @param string $what               - what the action was performed on
3519
-     * @param string $action_desc        - what was done ie: updated, deleted, etc
3520
-     * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3521
-     *                                   action is completed
3522
-     * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3523
-     *                                   override this so that they show.
3524
-     * @return void
3525
-     * @throws EE_Error
3526
-     * @throws InvalidArgumentException
3527
-     * @throws InvalidDataTypeException
3528
-     * @throws InvalidInterfaceException
3529
-     */
3530
-    protected function _redirect_after_action(
3531
-        $success = 0,
3532
-        $what = 'item',
3533
-        $action_desc = 'processed',
3534
-        $query_args = array(),
3535
-        $override_overwrite = false
3536
-    ) {
3537
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3538
-        // class name for actions/filters.
3539
-        $classname = get_class($this);
3540
-        // set redirect url.
3541
-        // Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3542
-        // otherwise we go with whatever is set as the _admin_base_url
3543
-        $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3544
-        $notices = EE_Error::get_notices(false);
3545
-        // overwrite default success messages //BUT ONLY if overwrite not overridden
3546
-        if (! $override_overwrite || ! empty($notices['errors'])) {
3547
-            EE_Error::overwrite_success();
3548
-        }
3549
-        if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3550
-            // how many records affected ? more than one record ? or just one ?
3551
-            if ($success > 1) {
3552
-                // set plural msg
3553
-                EE_Error::add_success(
3554
-                    sprintf(
3555
-                        esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3556
-                        $what,
3557
-                        $action_desc
3558
-                    ),
3559
-                    __FILE__,
3560
-                    __FUNCTION__,
3561
-                    __LINE__
3562
-                );
3563
-            } elseif ($success === 1) {
3564
-                // set singular msg
3565
-                EE_Error::add_success(
3566
-                    sprintf(
3567
-                        esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3568
-                        $what,
3569
-                        $action_desc
3570
-                    ),
3571
-                    __FILE__,
3572
-                    __FUNCTION__,
3573
-                    __LINE__
3574
-                );
3575
-            }
3576
-        }
3577
-        // check that $query_args isn't something crazy
3578
-        if (! is_array($query_args)) {
3579
-            $query_args = array();
3580
-        }
3581
-        /**
3582
-         * Allow injecting actions before the query_args are modified for possible different
3583
-         * redirections on save and close actions
3584
-         *
3585
-         * @since 4.2.0
3586
-         * @param array $query_args       The original query_args array coming into the
3587
-         *                                method.
3588
-         */
3589
-        do_action(
3590
-            "AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3591
-            $query_args
3592
-        );
3593
-        // calculate where we're going (if we have a "save and close" button pushed)
3594
-        if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3595
-            // even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3596
-            $parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3597
-            // regenerate query args array from referrer URL
3598
-            parse_str($parsed_url['query'], $query_args);
3599
-            // correct page and action will be in the query args now
3600
-            $redirect_url = admin_url('admin.php');
3601
-        }
3602
-        // merge any default query_args set in _default_route_query_args property
3603
-        if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3604
-            $args_to_merge = array();
3605
-            foreach ($this->_default_route_query_args as $query_param => $query_value) {
3606
-                // is there a wp_referer array in our _default_route_query_args property?
3607
-                if ($query_param === 'wp_referer') {
3608
-                    $query_value = (array) $query_value;
3609
-                    foreach ($query_value as $reference => $value) {
3610
-                        if (strpos($reference, 'nonce') !== false) {
3611
-                            continue;
3612
-                        }
3613
-                        // finally we will override any arguments in the referer with
3614
-                        // what might be set on the _default_route_query_args array.
3615
-                        if (isset($this->_default_route_query_args[ $reference ])) {
3616
-                            $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3617
-                        } else {
3618
-                            $args_to_merge[ $reference ] = urlencode($value);
3619
-                        }
3620
-                    }
3621
-                    continue;
3622
-                }
3623
-                $args_to_merge[ $query_param ] = $query_value;
3624
-            }
3625
-            // now let's merge these arguments but override with what was specifically sent in to the
3626
-            // redirect.
3627
-            $query_args = array_merge($args_to_merge, $query_args);
3628
-        }
3629
-        $this->_process_notices($query_args);
3630
-        // generate redirect url
3631
-        // if redirecting to anything other than the main page, add a nonce
3632
-        if (isset($query_args['action'])) {
3633
-            // manually generate wp_nonce and merge that with the query vars
3634
-            // becuz the wp_nonce_url function wrecks havoc on some vars
3635
-            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3636
-        }
3637
-        // we're adding some hooks and filters in here for processing any things just before redirects
3638
-        // (example: an admin page has done an insert or update and we want to run something after that).
3639
-        do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3640
-        $redirect_url = apply_filters(
3641
-            'FHEE_redirect_' . $classname . $this->_req_action,
3642
-            self::add_query_args_and_nonce($query_args, $redirect_url),
3643
-            $query_args
3644
-        );
3645
-        // check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3646
-        if (defined('DOING_AJAX')) {
3647
-            $default_data = array(
3648
-                'close'        => true,
3649
-                'redirect_url' => $redirect_url,
3650
-                'where'        => 'main',
3651
-                'what'         => 'append',
3652
-            );
3653
-            $this->_template_args['success'] = $success;
3654
-            $this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge(
3655
-                $default_data,
3656
-                $this->_template_args['data']
3657
-            ) : $default_data;
3658
-            $this->_return_json();
3659
-        }
3660
-        wp_safe_redirect($redirect_url);
3661
-        exit();
3662
-    }
3663
-
3664
-
3665
-    /**
3666
-     * process any notices before redirecting (or returning ajax request)
3667
-     * This method sets the $this->_template_args['notices'] attribute;
3668
-     *
3669
-     * @param array $query_args         any query args that need to be used for notice transient ('action')
3670
-     * @param bool  $skip_route_verify  This is typically used when we are processing notices REALLY early and
3671
-     *                                  page_routes haven't been defined yet.
3672
-     * @param bool  $sticky_notices     This is used to flag that regardless of whether this is doing_ajax or not, we
3673
-     *                                  still save a transient for the notice.
3674
-     * @return void
3675
-     * @throws EE_Error
3676
-     * @throws InvalidArgumentException
3677
-     * @throws InvalidDataTypeException
3678
-     * @throws InvalidInterfaceException
3679
-     */
3680
-    protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3681
-    {
3682
-        // first let's set individual error properties if doing_ajax and the properties aren't already set.
3683
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3684
-            $notices = EE_Error::get_notices(false);
3685
-            if (empty($this->_template_args['success'])) {
3686
-                $this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3687
-            }
3688
-            if (empty($this->_template_args['errors'])) {
3689
-                $this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3690
-            }
3691
-            if (empty($this->_template_args['attention'])) {
3692
-                $this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3693
-            }
3694
-        }
3695
-        $this->_template_args['notices'] = EE_Error::get_notices();
3696
-        // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3697
-        if (! defined('DOING_AJAX') || $sticky_notices) {
3698
-            $route = isset($query_args['action']) ? $query_args['action'] : 'default';
3699
-            $this->_add_transient(
3700
-                $route,
3701
-                $this->_template_args['notices'],
3702
-                true,
3703
-                $skip_route_verify
3704
-            );
3705
-        }
3706
-    }
3707
-
3708
-
3709
-    /**
3710
-     * get_action_link_or_button
3711
-     * returns the button html for adding, editing, or deleting an item (depending on given type)
3712
-     *
3713
-     * @param string $action        use this to indicate which action the url is generated with.
3714
-     * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3715
-     *                              property.
3716
-     * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3717
-     * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3718
-     * @param string $base_url      If this is not provided
3719
-     *                              the _admin_base_url will be used as the default for the button base_url.
3720
-     *                              Otherwise this value will be used.
3721
-     * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3722
-     * @return string
3723
-     * @throws InvalidArgumentException
3724
-     * @throws InvalidInterfaceException
3725
-     * @throws InvalidDataTypeException
3726
-     * @throws EE_Error
3727
-     */
3728
-    public function get_action_link_or_button(
3729
-        $action,
3730
-        $type = 'add',
3731
-        $extra_request = array(),
3732
-        $class = 'button-primary',
3733
-        $base_url = '',
3734
-        $exclude_nonce = false
3735
-    ) {
3736
-        // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3737
-        if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3738
-            throw new EE_Error(
3739
-                sprintf(
3740
-                    esc_html__(
3741
-                        'There is no page route for given action for the button.  This action was given: %s',
3742
-                        'event_espresso'
3743
-                    ),
3744
-                    $action
3745
-                )
3746
-            );
3747
-        }
3748
-        if (! isset($this->_labels['buttons'][ $type ])) {
3749
-            throw new EE_Error(
3750
-                sprintf(
3751
-                    __(
3752
-                        'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3753
-                        'event_espresso'
3754
-                    ),
3755
-                    $type
3756
-                )
3757
-            );
3758
-        }
3759
-        // finally check user access for this button.
3760
-        $has_access = $this->check_user_access($action, true);
3761
-        if (! $has_access) {
3762
-            return '';
3763
-        }
3764
-        $_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
3765
-        $query_args = array(
3766
-            'action' => $action,
3767
-        );
3768
-        // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3769
-        if (! empty($extra_request)) {
3770
-            $query_args = array_merge($extra_request, $query_args);
3771
-        }
3772
-        $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3773
-        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3774
-    }
3775
-
3776
-
3777
-    /**
3778
-     * _per_page_screen_option
3779
-     * Utility function for adding in a per_page_option in the screen_options_dropdown.
3780
-     *
3781
-     * @return void
3782
-     * @throws InvalidArgumentException
3783
-     * @throws InvalidInterfaceException
3784
-     * @throws InvalidDataTypeException
3785
-     */
3786
-    protected function _per_page_screen_option()
3787
-    {
3788
-        $option = 'per_page';
3789
-        $args = array(
3790
-            'label'   => apply_filters(
3791
-                'FHEE__EE_Admin_Page___per_page_screen_options___label',
3792
-                $this->_admin_page_title,
3793
-                $this
3794
-            ),
3795
-            'default' => (int) apply_filters(
3796
-                'FHEE__EE_Admin_Page___per_page_screen_options__default',
3797
-                20
3798
-            ),
3799
-            'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3800
-        );
3801
-        // ONLY add the screen option if the user has access to it.
3802
-        if ($this->check_user_access($this->_current_view, true)) {
3803
-            add_screen_option($option, $args);
3804
-        }
3805
-    }
3806
-
3807
-
3808
-    /**
3809
-     * set_per_page_screen_option
3810
-     * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3811
-     * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3812
-     * admin_menu.
3813
-     *
3814
-     * @return void
3815
-     */
3816
-    private function _set_per_page_screen_options()
3817
-    {
3818
-        if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3819
-            check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3820
-            if (! $user = wp_get_current_user()) {
3821
-                return;
3822
-            }
3823
-            $option = $_POST['wp_screen_options']['option'];
3824
-            $value = $_POST['wp_screen_options']['value'];
3825
-            if ($option !== sanitize_key($option)) {
3826
-                return;
3827
-            }
3828
-            $map_option = $option;
3829
-            $option = str_replace('-', '_', $option);
3830
-            switch ($map_option) {
3831
-                case $this->_current_page . '_' . $this->_current_view . '_per_page':
3832
-                    $value = (int) $value;
3833
-                    $max_value = apply_filters(
3834
-                        'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
3835
-                        999,
3836
-                        $this->_current_page,
3837
-                        $this->_current_view
3838
-                    );
3839
-                    if ($value < 1) {
3840
-                        return;
3841
-                    }
3842
-                    $value = min($value, $max_value);
3843
-                    break;
3844
-                default:
3845
-                    $value = apply_filters(
3846
-                        'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3847
-                        false,
3848
-                        $option,
3849
-                        $value
3850
-                    );
3851
-                    if (false === $value) {
3852
-                        return;
3853
-                    }
3854
-                    break;
3855
-            }
3856
-            update_user_meta($user->ID, $option, $value);
3857
-            wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3858
-            exit;
3859
-        }
3860
-    }
3861
-
3862
-
3863
-    /**
3864
-     * This just allows for setting the $_template_args property if it needs to be set outside the object
3865
-     *
3866
-     * @param array $data array that will be assigned to template args.
3867
-     */
3868
-    public function set_template_args($data)
3869
-    {
3870
-        $this->_template_args = array_merge($this->_template_args, (array) $data);
3871
-    }
3872
-
3873
-
3874
-    /**
3875
-     * This makes available the WP transient system for temporarily moving data between routes
3876
-     *
3877
-     * @param string $route             the route that should receive the transient
3878
-     * @param array  $data              the data that gets sent
3879
-     * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3880
-     *                                  normal route transient.
3881
-     * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3882
-     *                                  when we are adding a transient before page_routes have been defined.
3883
-     * @return void
3884
-     * @throws EE_Error
3885
-     */
3886
-    protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3887
-    {
3888
-        $user_id = get_current_user_id();
3889
-        if (! $skip_route_verify) {
3890
-            $this->_verify_route($route);
3891
-        }
3892
-        // now let's set the string for what kind of transient we're setting
3893
-        $transient = $notices
3894
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3895
-            : 'rte_tx_' . $route . '_' . $user_id;
3896
-        $data = $notices ? array('notices' => $data) : $data;
3897
-        // is there already a transient for this route?  If there is then let's ADD to that transient
3898
-        $existing = is_multisite() && is_network_admin()
3899
-            ? get_site_transient($transient)
3900
-            : get_transient($transient);
3901
-        if ($existing) {
3902
-            $data = array_merge((array) $data, (array) $existing);
3903
-        }
3904
-        if (is_multisite() && is_network_admin()) {
3905
-            set_site_transient($transient, $data, 8);
3906
-        } else {
3907
-            set_transient($transient, $data, 8);
3908
-        }
3909
-    }
3910
-
3911
-
3912
-    /**
3913
-     * this retrieves the temporary transient that has been set for moving data between routes.
3914
-     *
3915
-     * @param bool   $notices true we get notices transient. False we just return normal route transient
3916
-     * @param string $route
3917
-     * @return mixed data
3918
-     */
3919
-    protected function _get_transient($notices = false, $route = '')
3920
-    {
3921
-        $user_id = get_current_user_id();
3922
-        $route = ! $route ? $this->_req_action : $route;
3923
-        $transient = $notices
3924
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3925
-            : 'rte_tx_' . $route . '_' . $user_id;
3926
-        $data = is_multisite() && is_network_admin()
3927
-            ? get_site_transient($transient)
3928
-            : get_transient($transient);
3929
-        // delete transient after retrieval (just in case it hasn't expired);
3930
-        if (is_multisite() && is_network_admin()) {
3931
-            delete_site_transient($transient);
3932
-        } else {
3933
-            delete_transient($transient);
3934
-        }
3935
-        return $notices && isset($data['notices']) ? $data['notices'] : $data;
3936
-    }
3937
-
3938
-
3939
-    /**
3940
-     * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3941
-     * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3942
-     * default route callback on the EE_Admin page you want it run.)
3943
-     *
3944
-     * @return void
3945
-     */
3946
-    protected function _transient_garbage_collection()
3947
-    {
3948
-        global $wpdb;
3949
-        // retrieve all existing transients
3950
-        $query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3951
-        if ($results = $wpdb->get_results($query)) {
3952
-            foreach ($results as $result) {
3953
-                $transient = str_replace('_transient_', '', $result->option_name);
3954
-                get_transient($transient);
3955
-                if (is_multisite() && is_network_admin()) {
3956
-                    get_site_transient($transient);
3957
-                }
3958
-            }
3959
-        }
3960
-    }
3961
-
3962
-
3963
-    /**
3964
-     * get_view
3965
-     *
3966
-     * @return string content of _view property
3967
-     */
3968
-    public function get_view()
3969
-    {
3970
-        return $this->_view;
3971
-    }
3972
-
3973
-
3974
-    /**
3975
-     * getter for the protected $_views property
3976
-     *
3977
-     * @return array
3978
-     */
3979
-    public function get_views()
3980
-    {
3981
-        return $this->_views;
3982
-    }
3983
-
3984
-
3985
-    /**
3986
-     * get_current_page
3987
-     *
3988
-     * @return string _current_page property value
3989
-     */
3990
-    public function get_current_page()
3991
-    {
3992
-        return $this->_current_page;
3993
-    }
3994
-
3995
-
3996
-    /**
3997
-     * get_current_view
3998
-     *
3999
-     * @return string _current_view property value
4000
-     */
4001
-    public function get_current_view()
4002
-    {
4003
-        return $this->_current_view;
4004
-    }
4005
-
4006
-
4007
-    /**
4008
-     * get_current_screen
4009
-     *
4010
-     * @return object The current WP_Screen object
4011
-     */
4012
-    public function get_current_screen()
4013
-    {
4014
-        return $this->_current_screen;
4015
-    }
4016
-
4017
-
4018
-    /**
4019
-     * get_current_page_view_url
4020
-     *
4021
-     * @return string This returns the url for the current_page_view.
4022
-     */
4023
-    public function get_current_page_view_url()
4024
-    {
4025
-        return $this->_current_page_view_url;
4026
-    }
4027
-
4028
-
4029
-    /**
4030
-     * just returns the _req_data property
4031
-     *
4032
-     * @return array
4033
-     */
4034
-    public function get_request_data()
4035
-    {
4036
-        return $this->_req_data;
4037
-    }
4038
-
4039
-
4040
-    /**
4041
-     * returns the _req_data protected property
4042
-     *
4043
-     * @return string
4044
-     */
4045
-    public function get_req_action()
4046
-    {
4047
-        return $this->_req_action;
4048
-    }
4049
-
4050
-
4051
-    /**
4052
-     * @return bool  value of $_is_caf property
4053
-     */
4054
-    public function is_caf()
4055
-    {
4056
-        return $this->_is_caf;
4057
-    }
4058
-
4059
-
4060
-    /**
4061
-     * @return mixed
4062
-     */
4063
-    public function default_espresso_metaboxes()
4064
-    {
4065
-        return $this->_default_espresso_metaboxes;
4066
-    }
4067
-
4068
-
4069
-    /**
4070
-     * @return mixed
4071
-     */
4072
-    public function admin_base_url()
4073
-    {
4074
-        return $this->_admin_base_url;
4075
-    }
4076
-
4077
-
4078
-    /**
4079
-     * @return mixed
4080
-     */
4081
-    public function wp_page_slug()
4082
-    {
4083
-        return $this->_wp_page_slug;
4084
-    }
4085
-
4086
-
4087
-    /**
4088
-     * updates  espresso configuration settings
4089
-     *
4090
-     * @param string                   $tab
4091
-     * @param EE_Config_Base|EE_Config $config
4092
-     * @param string                   $file file where error occurred
4093
-     * @param string                   $func function  where error occurred
4094
-     * @param string                   $line line no where error occurred
4095
-     * @return boolean
4096
-     */
4097
-    protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4098
-    {
4099
-        // remove any options that are NOT going to be saved with the config settings.
4100
-        if (isset($config->core->ee_ueip_optin)) {
4101
-            // TODO: remove the following two lines and make sure values are migrated from 3.1
4102
-            update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4103
-            update_option('ee_ueip_has_notified', true);
4104
-        }
4105
-        // and save it (note we're also doing the network save here)
4106
-        $net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4107
-        $config_saved = EE_Config::instance()->update_espresso_config(false, false);
4108
-        if ($config_saved && $net_saved) {
4109
-            EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4110
-            return true;
4111
-        }
4112
-        EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4113
-        return false;
4114
-    }
4115
-
4116
-
4117
-    /**
4118
-     * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4119
-     *
4120
-     * @return array
4121
-     */
4122
-    public function get_yes_no_values()
4123
-    {
4124
-        return $this->_yes_no_values;
4125
-    }
4126
-
4127
-
4128
-    protected function _get_dir()
4129
-    {
4130
-        $reflector = new ReflectionClass(get_class($this));
4131
-        return dirname($reflector->getFileName());
4132
-    }
4133
-
4134
-
4135
-    /**
4136
-     * A helper for getting a "next link".
4137
-     *
4138
-     * @param string $url   The url to link to
4139
-     * @param string $class The class to use.
4140
-     * @return string
4141
-     */
4142
-    protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4143
-    {
4144
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4145
-    }
4146
-
4147
-
4148
-    /**
4149
-     * A helper for getting a "previous link".
4150
-     *
4151
-     * @param string $url   The url to link to
4152
-     * @param string $class The class to use.
4153
-     * @return string
4154
-     */
4155
-    protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4156
-    {
4157
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4158
-    }
4159
-
4160
-
4161
-
4162
-
4163
-
4164
-
4165
-
4166
-    // below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4167
-
4168
-
4169
-    /**
4170
-     * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4171
-     * 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
4172
-     * _req_data array.
4173
-     *
4174
-     * @return bool success/fail
4175
-     * @throws EE_Error
4176
-     * @throws InvalidArgumentException
4177
-     * @throws ReflectionException
4178
-     * @throws InvalidDataTypeException
4179
-     * @throws InvalidInterfaceException
4180
-     */
4181
-    protected function _process_resend_registration()
4182
-    {
4183
-        $this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4184
-        do_action(
4185
-            'AHEE__EE_Admin_Page___process_resend_registration',
4186
-            $this->_template_args['success'],
4187
-            $this->_req_data
4188
-        );
4189
-        return $this->_template_args['success'];
4190
-    }
4191
-
4192
-
4193
-    /**
4194
-     * This automatically processes any payment message notifications when manual payment has been applied.
4195
-     *
4196
-     * @param EE_Payment $payment
4197
-     * @return bool success/fail
4198
-     */
4199
-    protected function _process_payment_notification(EE_Payment $payment)
4200
-    {
4201
-        add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4202
-        do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4203
-        $this->_template_args['success'] = apply_filters(
4204
-            'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4205
-            false,
4206
-            $payment
4207
-        );
4208
-        return $this->_template_args['success'];
4209
-    }
2744
+	}
2745
+
2746
+
2747
+	/**
2748
+	 * facade for add_meta_box
2749
+	 *
2750
+	 * @param string  $action        where the metabox get's displayed
2751
+	 * @param string  $title         Title of Metabox (output in metabox header)
2752
+	 * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2753
+	 *                               instead of the one created in here.
2754
+	 * @param array   $callback_args an array of args supplied for the metabox
2755
+	 * @param string  $column        what metabox column
2756
+	 * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2757
+	 * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2758
+	 *                               created but just set our own callback for wp's add_meta_box.
2759
+	 * @throws DomainException
2760
+	 */
2761
+	public function _add_admin_page_meta_box(
2762
+		$action,
2763
+		$title,
2764
+		$callback,
2765
+		$callback_args,
2766
+		$column = 'normal',
2767
+		$priority = 'high',
2768
+		$create_func = true
2769
+	) {
2770
+		do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2771
+		// 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.
2772
+		if (empty($callback_args) && $create_func) {
2773
+			$callback_args = array(
2774
+				'template_path' => $this->_template_path,
2775
+				'template_args' => $this->_template_args,
2776
+			);
2777
+		}
2778
+		// 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)
2779
+		$call_back_func = $create_func
2780
+			? static function ($post, $metabox) {
2781
+				do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2782
+				echo EEH_Template::display_template(
2783
+					$metabox['args']['template_path'],
2784
+					$metabox['args']['template_args'],
2785
+					true
2786
+				);
2787
+			}
2788
+			: $callback;
2789
+		add_meta_box(
2790
+			str_replace('_', '-', $action) . '-mbox',
2791
+			$title,
2792
+			$call_back_func,
2793
+			$this->_wp_page_slug,
2794
+			$column,
2795
+			$priority,
2796
+			$callback_args
2797
+		);
2798
+	}
2799
+
2800
+
2801
+	/**
2802
+	 * generates HTML wrapper for and admin details page that contains metaboxes in columns
2803
+	 *
2804
+	 * @throws DomainException
2805
+	 * @throws EE_Error
2806
+	 * @throws InvalidArgumentException
2807
+	 * @throws InvalidDataTypeException
2808
+	 * @throws InvalidInterfaceException
2809
+	 */
2810
+	public function display_admin_page_with_metabox_columns()
2811
+	{
2812
+		$this->_template_args['post_body_content'] = $this->_template_args['admin_page_content'];
2813
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2814
+			$this->_column_template_path,
2815
+			$this->_template_args,
2816
+			true
2817
+		);
2818
+		// the final wrapper
2819
+		$this->admin_page_wrapper();
2820
+	}
2821
+
2822
+
2823
+	/**
2824
+	 * generates  HTML wrapper for an admin details page
2825
+	 *
2826
+	 * @return void
2827
+	 * @throws DomainException
2828
+	 * @throws EE_Error
2829
+	 * @throws InvalidArgumentException
2830
+	 * @throws InvalidDataTypeException
2831
+	 * @throws InvalidInterfaceException
2832
+	 */
2833
+	public function display_admin_page_with_sidebar()
2834
+	{
2835
+		$this->_display_admin_page(true);
2836
+	}
2837
+
2838
+
2839
+	/**
2840
+	 * generates  HTML wrapper for an admin details page (except no sidebar)
2841
+	 *
2842
+	 * @return void
2843
+	 * @throws DomainException
2844
+	 * @throws EE_Error
2845
+	 * @throws InvalidArgumentException
2846
+	 * @throws InvalidDataTypeException
2847
+	 * @throws InvalidInterfaceException
2848
+	 */
2849
+	public function display_admin_page_with_no_sidebar()
2850
+	{
2851
+		$this->_display_admin_page();
2852
+	}
2853
+
2854
+
2855
+	/**
2856
+	 * generates HTML wrapper for an EE about admin page (no sidebar)
2857
+	 *
2858
+	 * @return void
2859
+	 * @throws DomainException
2860
+	 * @throws EE_Error
2861
+	 * @throws InvalidArgumentException
2862
+	 * @throws InvalidDataTypeException
2863
+	 * @throws InvalidInterfaceException
2864
+	 */
2865
+	public function display_about_admin_page()
2866
+	{
2867
+		$this->_display_admin_page(false, true);
2868
+	}
2869
+
2870
+
2871
+	/**
2872
+	 * display_admin_page
2873
+	 * contains the code for actually displaying an admin page
2874
+	 *
2875
+	 * @param boolean $sidebar true with sidebar, false without
2876
+	 * @param boolean $about   use the about admin wrapper instead of the default.
2877
+	 * @return void
2878
+	 * @throws DomainException
2879
+	 * @throws EE_Error
2880
+	 * @throws InvalidArgumentException
2881
+	 * @throws InvalidDataTypeException
2882
+	 * @throws InvalidInterfaceException
2883
+	 */
2884
+	private function _display_admin_page($sidebar = false, $about = false)
2885
+	{
2886
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2887
+		// custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2888
+		do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2889
+		// set current wp page slug - looks like: event-espresso_page_event_categories
2890
+		// keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2891
+		$this->_template_args['current_page'] = $this->_wp_page_slug;
2892
+		$this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2893
+			? 'poststuff'
2894
+			: 'espresso-default-admin';
2895
+		$template_path = $sidebar
2896
+			? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2897
+			: EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2898
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2899
+			$template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2900
+		}
2901
+		$template_path = ! empty($this->_column_template_path)
2902
+			? $this->_column_template_path : $template_path;
2903
+		$this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content'])
2904
+			? $this->_template_args['admin_page_content']
2905
+			: '';
2906
+		$this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2907
+			? $this->_template_args['before_admin_page_content']
2908
+			: '';
2909
+		$this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content'])
2910
+			? $this->_template_args['after_admin_page_content']
2911
+			: '';
2912
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2913
+			$template_path,
2914
+			$this->_template_args,
2915
+			true
2916
+		);
2917
+		// the final template wrapper
2918
+		$this->admin_page_wrapper($about);
2919
+	}
2920
+
2921
+
2922
+	/**
2923
+	 * This is used to display caf preview pages.
2924
+	 *
2925
+	 * @since 4.3.2
2926
+	 * @param string $utm_campaign_source what is the key used for google analytics link
2927
+	 * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2928
+	 *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2929
+	 * @return void
2930
+	 * @throws DomainException
2931
+	 * @throws EE_Error
2932
+	 * @throws InvalidArgumentException
2933
+	 * @throws InvalidDataTypeException
2934
+	 * @throws InvalidInterfaceException
2935
+	 */
2936
+	public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2937
+	{
2938
+		// let's generate a default preview action button if there isn't one already present.
2939
+		$this->_labels['buttons']['buy_now'] = esc_html__(
2940
+			'Upgrade to Event Espresso 4 Right Now',
2941
+			'event_espresso'
2942
+		);
2943
+		$buy_now_url = add_query_arg(
2944
+			array(
2945
+				'ee_ver'       => 'ee4',
2946
+				'utm_source'   => 'ee4_plugin_admin',
2947
+				'utm_medium'   => 'link',
2948
+				'utm_campaign' => $utm_campaign_source,
2949
+				'utm_content'  => 'buy_now_button',
2950
+			),
2951
+			'http://eventespresso.com/pricing/'
2952
+		);
2953
+		$this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2954
+			? $this->get_action_link_or_button(
2955
+				'',
2956
+				'buy_now',
2957
+				array(),
2958
+				'button-primary button-large',
2959
+				$buy_now_url,
2960
+				true
2961
+			)
2962
+			: $this->_template_args['preview_action_button'];
2963
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2964
+			EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2965
+			$this->_template_args,
2966
+			true
2967
+		);
2968
+		$this->_display_admin_page($display_sidebar);
2969
+	}
2970
+
2971
+
2972
+	/**
2973
+	 * display_admin_list_table_page_with_sidebar
2974
+	 * generates HTML wrapper for an admin_page with list_table
2975
+	 *
2976
+	 * @return void
2977
+	 * @throws DomainException
2978
+	 * @throws EE_Error
2979
+	 * @throws InvalidArgumentException
2980
+	 * @throws InvalidDataTypeException
2981
+	 * @throws InvalidInterfaceException
2982
+	 */
2983
+	public function display_admin_list_table_page_with_sidebar()
2984
+	{
2985
+		$this->_display_admin_list_table_page(true);
2986
+	}
2987
+
2988
+
2989
+	/**
2990
+	 * display_admin_list_table_page_with_no_sidebar
2991
+	 * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
2992
+	 *
2993
+	 * @return void
2994
+	 * @throws DomainException
2995
+	 * @throws EE_Error
2996
+	 * @throws InvalidArgumentException
2997
+	 * @throws InvalidDataTypeException
2998
+	 * @throws InvalidInterfaceException
2999
+	 */
3000
+	public function display_admin_list_table_page_with_no_sidebar()
3001
+	{
3002
+		$this->_display_admin_list_table_page();
3003
+	}
3004
+
3005
+
3006
+	/**
3007
+	 * generates html wrapper for an admin_list_table page
3008
+	 *
3009
+	 * @param boolean $sidebar whether to display with sidebar or not.
3010
+	 * @return void
3011
+	 * @throws DomainException
3012
+	 * @throws EE_Error
3013
+	 * @throws InvalidArgumentException
3014
+	 * @throws InvalidDataTypeException
3015
+	 * @throws InvalidInterfaceException
3016
+	 */
3017
+	private function _display_admin_list_table_page($sidebar = false)
3018
+	{
3019
+		// setup search attributes
3020
+		$this->_set_search_attributes();
3021
+		$this->_template_args['current_page'] = $this->_wp_page_slug;
3022
+		$template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3023
+		$this->_template_args['table_url'] = defined('DOING_AJAX')
3024
+			? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3025
+			: add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
3026
+		$this->_template_args['list_table'] = $this->_list_table_object;
3027
+		$this->_template_args['current_route'] = $this->_req_action;
3028
+		$this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3029
+		$ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
3030
+		if (! empty($ajax_sorting_callback)) {
3031
+			$sortable_list_table_form_fields = wp_nonce_field(
3032
+				$ajax_sorting_callback . '_nonce',
3033
+				$ajax_sorting_callback . '_nonce',
3034
+				false,
3035
+				false
3036
+			);
3037
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
3038
+												. $this->page_slug
3039
+												. '" />';
3040
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
3041
+												. $ajax_sorting_callback
3042
+												. '" />';
3043
+		} else {
3044
+			$sortable_list_table_form_fields = '';
3045
+		}
3046
+		$this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
3047
+		$hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
3048
+			? $this->_template_args['list_table_hidden_fields']
3049
+			: '';
3050
+		$nonce_ref = $this->_req_action . '_nonce';
3051
+		$hidden_form_fields .= '<input type="hidden" name="'
3052
+							   . $nonce_ref
3053
+							   . '" value="'
3054
+							   . wp_create_nonce($nonce_ref)
3055
+							   . '">';
3056
+		$this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3057
+		// display message about search results?
3058
+		$this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3059
+			? '<p class="ee-search-results">' . sprintf(
3060
+				esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3061
+				trim($this->_req_data['s'], '%')
3062
+			) . '</p>'
3063
+			: '';
3064
+		// filter before_list_table template arg
3065
+		$this->_template_args['before_list_table'] = apply_filters(
3066
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3067
+			$this->_template_args['before_list_table'],
3068
+			$this->page_slug,
3069
+			$this->_req_data,
3070
+			$this->_req_action
3071
+		);
3072
+		// convert to array and filter again
3073
+		// arrays are easier to inject new items in a specific location,
3074
+		// but would not be backwards compatible, so we have to add a new filter
3075
+		$this->_template_args['before_list_table'] = implode(
3076
+			" \n",
3077
+			(array) apply_filters(
3078
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3079
+				(array) $this->_template_args['before_list_table'],
3080
+				$this->page_slug,
3081
+				$this->_req_data,
3082
+				$this->_req_action
3083
+			)
3084
+		);
3085
+		// filter after_list_table template arg
3086
+		$this->_template_args['after_list_table'] = apply_filters(
3087
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3088
+			$this->_template_args['after_list_table'],
3089
+			$this->page_slug,
3090
+			$this->_req_data,
3091
+			$this->_req_action
3092
+		);
3093
+		// convert to array and filter again
3094
+		// arrays are easier to inject new items in a specific location,
3095
+		// but would not be backwards compatible, so we have to add a new filter
3096
+		$this->_template_args['after_list_table'] = implode(
3097
+			" \n",
3098
+			(array) apply_filters(
3099
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3100
+				(array) $this->_template_args['after_list_table'],
3101
+				$this->page_slug,
3102
+				$this->_req_data,
3103
+				$this->_req_action
3104
+			)
3105
+		);
3106
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3107
+			$template_path,
3108
+			$this->_template_args,
3109
+			true
3110
+		);
3111
+		// the final template wrapper
3112
+		if ($sidebar) {
3113
+			$this->display_admin_page_with_sidebar();
3114
+		} else {
3115
+			$this->display_admin_page_with_no_sidebar();
3116
+		}
3117
+	}
3118
+
3119
+
3120
+	/**
3121
+	 * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3122
+	 * html string for the legend.
3123
+	 * $items are expected in an array in the following format:
3124
+	 * $legend_items = array(
3125
+	 *        'item_id' => array(
3126
+	 *            'icon' => 'http://url_to_icon_being_described.png',
3127
+	 *            'desc' => esc_html__('localized description of item');
3128
+	 *        )
3129
+	 * );
3130
+	 *
3131
+	 * @param  array $items see above for format of array
3132
+	 * @return string html string of legend
3133
+	 * @throws DomainException
3134
+	 */
3135
+	protected function _display_legend($items)
3136
+	{
3137
+		$this->_template_args['items'] = apply_filters(
3138
+			'FHEE__EE_Admin_Page___display_legend__items',
3139
+			(array) $items,
3140
+			$this
3141
+		);
3142
+		return EEH_Template::display_template(
3143
+			EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3144
+			$this->_template_args,
3145
+			true
3146
+		);
3147
+	}
3148
+
3149
+
3150
+	/**
3151
+	 * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3152
+	 * The returned json object is created from an array in the following format:
3153
+	 * array(
3154
+	 *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3155
+	 *  'success' => FALSE, //(default FALSE) - contains any special success message.
3156
+	 *  'notices' => '', // - contains any EE_Error formatted notices
3157
+	 *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3158
+	 *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3159
+	 *  We're also going to include the template args with every package (so js can pick out any specific template args
3160
+	 *  that might be included in here)
3161
+	 * )
3162
+	 * The json object is populated by whatever is set in the $_template_args property.
3163
+	 *
3164
+	 * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3165
+	 *                                 instead of displayed.
3166
+	 * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3167
+	 * @return void
3168
+	 * @throws EE_Error
3169
+	 * @throws InvalidArgumentException
3170
+	 * @throws InvalidDataTypeException
3171
+	 * @throws InvalidInterfaceException
3172
+	 */
3173
+	protected function _return_json($sticky_notices = false, $notices_arguments = array())
3174
+	{
3175
+		// make sure any EE_Error notices have been handled.
3176
+		$this->_process_notices($notices_arguments, true, $sticky_notices);
3177
+		$data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3178
+		unset($this->_template_args['data']);
3179
+		$json = array(
3180
+			'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3181
+			'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3182
+			'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3183
+			'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3184
+			'notices'   => EE_Error::get_notices(),
3185
+			'content'   => isset($this->_template_args['admin_page_content'])
3186
+				? $this->_template_args['admin_page_content'] : '',
3187
+			'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3188
+			'isEEajax'  => true
3189
+			// special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3190
+		);
3191
+		// make sure there are no php errors or headers_sent.  Then we can set correct json header.
3192
+		if (null === error_get_last() || ! headers_sent()) {
3193
+			header('Content-Type: application/json; charset=UTF-8');
3194
+		}
3195
+		echo wp_json_encode($json);
3196
+		exit();
3197
+	}
3198
+
3199
+
3200
+	/**
3201
+	 * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3202
+	 *
3203
+	 * @return void
3204
+	 * @throws EE_Error
3205
+	 * @throws InvalidArgumentException
3206
+	 * @throws InvalidDataTypeException
3207
+	 * @throws InvalidInterfaceException
3208
+	 */
3209
+	public function return_json()
3210
+	{
3211
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3212
+			$this->_return_json();
3213
+		} else {
3214
+			throw new EE_Error(
3215
+				sprintf(
3216
+					esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3217
+					__FUNCTION__
3218
+				)
3219
+			);
3220
+		}
3221
+	}
3222
+
3223
+
3224
+	/**
3225
+	 * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3226
+	 * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3227
+	 *
3228
+	 * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3229
+	 */
3230
+	public function set_hook_object(EE_Admin_Hooks $hook_obj)
3231
+	{
3232
+		$this->_hook_obj = $hook_obj;
3233
+	}
3234
+
3235
+
3236
+	/**
3237
+	 *        generates  HTML wrapper with Tabbed nav for an admin page
3238
+	 *
3239
+	 * @param boolean $about whether to use the special about page wrapper or default.
3240
+	 * @return void
3241
+	 * @throws DomainException
3242
+	 * @throws EE_Error
3243
+	 * @throws InvalidArgumentException
3244
+	 * @throws InvalidDataTypeException
3245
+	 * @throws InvalidInterfaceException
3246
+	 */
3247
+	public function admin_page_wrapper($about = false)
3248
+	{
3249
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3250
+		$this->_nav_tabs = $this->_get_main_nav_tabs();
3251
+		$this->_template_args['nav_tabs'] = $this->_nav_tabs;
3252
+		$this->_template_args['admin_page_title'] = $this->_admin_page_title;
3253
+		$this->_template_args['before_admin_page_content'] = apply_filters(
3254
+			"FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3255
+			isset($this->_template_args['before_admin_page_content'])
3256
+				? $this->_template_args['before_admin_page_content']
3257
+				: ''
3258
+		);
3259
+		$this->_template_args['after_admin_page_content'] = apply_filters(
3260
+			"FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3261
+			isset($this->_template_args['after_admin_page_content'])
3262
+				? $this->_template_args['after_admin_page_content']
3263
+				: ''
3264
+		);
3265
+		$this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content();
3266
+		// load settings page wrapper template
3267
+		$template_path = ! defined('DOING_AJAX')
3268
+			? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3269
+			: EE_ADMIN_TEMPLATE
3270
+			  . 'admin_wrapper_ajax.template.php';
3271
+		// about page?
3272
+		$template_path = $about
3273
+			? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3274
+			: $template_path;
3275
+		if (defined('DOING_AJAX')) {
3276
+			$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3277
+				$template_path,
3278
+				$this->_template_args,
3279
+				true
3280
+			);
3281
+			$this->_return_json();
3282
+		} else {
3283
+			EEH_Template::display_template($template_path, $this->_template_args);
3284
+		}
3285
+	}
3286
+
3287
+
3288
+	/**
3289
+	 * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3290
+	 *
3291
+	 * @return string html
3292
+	 * @throws EE_Error
3293
+	 */
3294
+	protected function _get_main_nav_tabs()
3295
+	{
3296
+		// let's generate the html using the EEH_Tabbed_Content helper.
3297
+		// We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3298
+		// (rather than setting in the page_routes array)
3299
+		return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3300
+	}
3301
+
3302
+
3303
+	/**
3304
+	 *        sort nav tabs
3305
+	 *
3306
+	 * @param $a
3307
+	 * @param $b
3308
+	 * @return int
3309
+	 */
3310
+	private function _sort_nav_tabs($a, $b)
3311
+	{
3312
+		if ($a['order'] === $b['order']) {
3313
+			return 0;
3314
+		}
3315
+		return ($a['order'] < $b['order']) ? -1 : 1;
3316
+	}
3317
+
3318
+
3319
+	/**
3320
+	 *    generates HTML for the forms used on admin pages
3321
+	 *
3322
+	 * @param    array $input_vars - array of input field details
3323
+	 * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3324
+	 *                             use)
3325
+	 * @param bool     $id
3326
+	 * @return string
3327
+	 * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3328
+	 * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3329
+	 */
3330
+	protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3331
+	{
3332
+		$content = $generator === 'string'
3333
+			? EEH_Form_Fields::get_form_fields($input_vars, $id)
3334
+			: EEH_Form_Fields::get_form_fields_array($input_vars);
3335
+		return $content;
3336
+	}
3337
+
3338
+
3339
+	/**
3340
+	 * generates the "Save" and "Save & Close" buttons for edit forms
3341
+	 *
3342
+	 * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3343
+	 *                                   Close" button.
3344
+	 * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3345
+	 *                                   'Save', [1] => 'save & close')
3346
+	 * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3347
+	 *                                   via the "name" value in the button).  We can also use this to just dump
3348
+	 *                                   default actions by submitting some other value.
3349
+	 * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3350
+	 *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3351
+	 *                                   close (normal form handling).
3352
+	 */
3353
+	protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3354
+	{
3355
+		// make sure $text and $actions are in an array
3356
+		$text = (array) $text;
3357
+		$actions = (array) $actions;
3358
+		$referrer_url = empty($referrer)
3359
+			? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3360
+			  . $_SERVER['REQUEST_URI']
3361
+			  . '" />'
3362
+			: '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3363
+			  . $referrer
3364
+			  . '" />';
3365
+		$button_text = ! empty($text)
3366
+			? $text
3367
+			: array(
3368
+				esc_html__('Save', 'event_espresso'),
3369
+				esc_html__('Save and Close', 'event_espresso'),
3370
+			);
3371
+		$default_names = array('save', 'save_and_close');
3372
+		// add in a hidden index for the current page (so save and close redirects properly)
3373
+		$this->_template_args['save_buttons'] = $referrer_url;
3374
+		foreach ($button_text as $key => $button) {
3375
+			$ref = $default_names[ $key ];
3376
+			$this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3377
+													 . $ref
3378
+													 . '" value="'
3379
+													 . $button
3380
+													 . '" name="'
3381
+													 . (! empty($actions) ? $actions[ $key ] : $ref)
3382
+													 . '" id="'
3383
+													 . $this->_current_view . '_' . $ref
3384
+													 . '" />';
3385
+			if (! $both) {
3386
+				break;
3387
+			}
3388
+		}
3389
+	}
3390
+
3391
+
3392
+	/**
3393
+	 * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3394
+	 *
3395
+	 * @see   $this->_set_add_edit_form_tags() for details on params
3396
+	 * @since 4.6.0
3397
+	 * @param string $route
3398
+	 * @param array  $additional_hidden_fields
3399
+	 */
3400
+	public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3401
+	{
3402
+		$this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3403
+	}
3404
+
3405
+
3406
+	/**
3407
+	 * set form open and close tags on add/edit pages.
3408
+	 *
3409
+	 * @param string $route                    the route you want the form to direct to
3410
+	 * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3411
+	 * @return void
3412
+	 */
3413
+	protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3414
+	{
3415
+		if (empty($route)) {
3416
+			$user_msg = esc_html__(
3417
+				'An error occurred. No action was set for this page\'s form.',
3418
+				'event_espresso'
3419
+			);
3420
+			$dev_msg = $user_msg . "\n"
3421
+					   . sprintf(
3422
+						   esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3423
+						   __FUNCTION__,
3424
+						   __CLASS__
3425
+					   );
3426
+			EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3427
+		}
3428
+		// open form
3429
+		$this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3430
+															 . $this->_admin_base_url
3431
+															 . '" id="'
3432
+															 . $route
3433
+															 . '_event_form" >';
3434
+		// add nonce
3435
+		$nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3436
+		$this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3437
+		// add REQUIRED form action
3438
+		$hidden_fields = array(
3439
+			'action' => array('type' => 'hidden', 'value' => $route),
3440
+		);
3441
+		// merge arrays
3442
+		$hidden_fields = is_array($additional_hidden_fields)
3443
+			? array_merge($hidden_fields, $additional_hidden_fields)
3444
+			: $hidden_fields;
3445
+		// generate form fields
3446
+		$form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3447
+		// add fields to form
3448
+		foreach ((array) $form_fields as $field_name => $form_field) {
3449
+			$this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3450
+		}
3451
+		// close form
3452
+		$this->_template_args['after_admin_page_content'] = '</form>';
3453
+	}
3454
+
3455
+
3456
+	/**
3457
+	 * Public Wrapper for _redirect_after_action() method since its
3458
+	 * discovered it would be useful for external code to have access.
3459
+	 *
3460
+	 * @param bool   $success
3461
+	 * @param string $what
3462
+	 * @param string $action_desc
3463
+	 * @param array  $query_args
3464
+	 * @param bool   $override_overwrite
3465
+	 * @throws EE_Error
3466
+	 * @throws InvalidArgumentException
3467
+	 * @throws InvalidDataTypeException
3468
+	 * @throws InvalidInterfaceException
3469
+	 * @see   EE_Admin_Page::_redirect_after_action() for params.
3470
+	 * @since 4.5.0
3471
+	 */
3472
+	public function redirect_after_action(
3473
+		$success = false,
3474
+		$what = 'item',
3475
+		$action_desc = 'processed',
3476
+		$query_args = array(),
3477
+		$override_overwrite = false
3478
+	) {
3479
+		$this->_redirect_after_action(
3480
+			$success,
3481
+			$what,
3482
+			$action_desc,
3483
+			$query_args,
3484
+			$override_overwrite
3485
+		);
3486
+	}
3487
+
3488
+
3489
+	/**
3490
+	 * Helper method for merging existing request data with the returned redirect url.
3491
+	 *
3492
+	 * This is typically used for redirects after an action so that if the original view was a filtered view those
3493
+	 * filters are still applied.
3494
+	 *
3495
+	 * @param array $new_route_data
3496
+	 * @return array
3497
+	 */
3498
+	protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data)
3499
+	{
3500
+		foreach ($this->_req_data as $ref => $value) {
3501
+			// unset nonces
3502
+			if (strpos($ref, 'nonce') !== false) {
3503
+				unset($this->_req_data[ $ref ]);
3504
+				continue;
3505
+			}
3506
+			// urlencode values.
3507
+			$value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3508
+			$this->_req_data[ $ref ] = $value;
3509
+		}
3510
+		return array_merge($this->_req_data, $new_route_data);
3511
+	}
3512
+
3513
+
3514
+	/**
3515
+	 *    _redirect_after_action
3516
+	 *
3517
+	 * @param int    $success            - whether success was for two or more records, or just one, or none
3518
+	 * @param string $what               - what the action was performed on
3519
+	 * @param string $action_desc        - what was done ie: updated, deleted, etc
3520
+	 * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3521
+	 *                                   action is completed
3522
+	 * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3523
+	 *                                   override this so that they show.
3524
+	 * @return void
3525
+	 * @throws EE_Error
3526
+	 * @throws InvalidArgumentException
3527
+	 * @throws InvalidDataTypeException
3528
+	 * @throws InvalidInterfaceException
3529
+	 */
3530
+	protected function _redirect_after_action(
3531
+		$success = 0,
3532
+		$what = 'item',
3533
+		$action_desc = 'processed',
3534
+		$query_args = array(),
3535
+		$override_overwrite = false
3536
+	) {
3537
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3538
+		// class name for actions/filters.
3539
+		$classname = get_class($this);
3540
+		// set redirect url.
3541
+		// Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3542
+		// otherwise we go with whatever is set as the _admin_base_url
3543
+		$redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3544
+		$notices = EE_Error::get_notices(false);
3545
+		// overwrite default success messages //BUT ONLY if overwrite not overridden
3546
+		if (! $override_overwrite || ! empty($notices['errors'])) {
3547
+			EE_Error::overwrite_success();
3548
+		}
3549
+		if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3550
+			// how many records affected ? more than one record ? or just one ?
3551
+			if ($success > 1) {
3552
+				// set plural msg
3553
+				EE_Error::add_success(
3554
+					sprintf(
3555
+						esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3556
+						$what,
3557
+						$action_desc
3558
+					),
3559
+					__FILE__,
3560
+					__FUNCTION__,
3561
+					__LINE__
3562
+				);
3563
+			} elseif ($success === 1) {
3564
+				// set singular msg
3565
+				EE_Error::add_success(
3566
+					sprintf(
3567
+						esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3568
+						$what,
3569
+						$action_desc
3570
+					),
3571
+					__FILE__,
3572
+					__FUNCTION__,
3573
+					__LINE__
3574
+				);
3575
+			}
3576
+		}
3577
+		// check that $query_args isn't something crazy
3578
+		if (! is_array($query_args)) {
3579
+			$query_args = array();
3580
+		}
3581
+		/**
3582
+		 * Allow injecting actions before the query_args are modified for possible different
3583
+		 * redirections on save and close actions
3584
+		 *
3585
+		 * @since 4.2.0
3586
+		 * @param array $query_args       The original query_args array coming into the
3587
+		 *                                method.
3588
+		 */
3589
+		do_action(
3590
+			"AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3591
+			$query_args
3592
+		);
3593
+		// calculate where we're going (if we have a "save and close" button pushed)
3594
+		if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3595
+			// even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3596
+			$parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3597
+			// regenerate query args array from referrer URL
3598
+			parse_str($parsed_url['query'], $query_args);
3599
+			// correct page and action will be in the query args now
3600
+			$redirect_url = admin_url('admin.php');
3601
+		}
3602
+		// merge any default query_args set in _default_route_query_args property
3603
+		if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3604
+			$args_to_merge = array();
3605
+			foreach ($this->_default_route_query_args as $query_param => $query_value) {
3606
+				// is there a wp_referer array in our _default_route_query_args property?
3607
+				if ($query_param === 'wp_referer') {
3608
+					$query_value = (array) $query_value;
3609
+					foreach ($query_value as $reference => $value) {
3610
+						if (strpos($reference, 'nonce') !== false) {
3611
+							continue;
3612
+						}
3613
+						// finally we will override any arguments in the referer with
3614
+						// what might be set on the _default_route_query_args array.
3615
+						if (isset($this->_default_route_query_args[ $reference ])) {
3616
+							$args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3617
+						} else {
3618
+							$args_to_merge[ $reference ] = urlencode($value);
3619
+						}
3620
+					}
3621
+					continue;
3622
+				}
3623
+				$args_to_merge[ $query_param ] = $query_value;
3624
+			}
3625
+			// now let's merge these arguments but override with what was specifically sent in to the
3626
+			// redirect.
3627
+			$query_args = array_merge($args_to_merge, $query_args);
3628
+		}
3629
+		$this->_process_notices($query_args);
3630
+		// generate redirect url
3631
+		// if redirecting to anything other than the main page, add a nonce
3632
+		if (isset($query_args['action'])) {
3633
+			// manually generate wp_nonce and merge that with the query vars
3634
+			// becuz the wp_nonce_url function wrecks havoc on some vars
3635
+			$query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3636
+		}
3637
+		// we're adding some hooks and filters in here for processing any things just before redirects
3638
+		// (example: an admin page has done an insert or update and we want to run something after that).
3639
+		do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3640
+		$redirect_url = apply_filters(
3641
+			'FHEE_redirect_' . $classname . $this->_req_action,
3642
+			self::add_query_args_and_nonce($query_args, $redirect_url),
3643
+			$query_args
3644
+		);
3645
+		// check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3646
+		if (defined('DOING_AJAX')) {
3647
+			$default_data = array(
3648
+				'close'        => true,
3649
+				'redirect_url' => $redirect_url,
3650
+				'where'        => 'main',
3651
+				'what'         => 'append',
3652
+			);
3653
+			$this->_template_args['success'] = $success;
3654
+			$this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge(
3655
+				$default_data,
3656
+				$this->_template_args['data']
3657
+			) : $default_data;
3658
+			$this->_return_json();
3659
+		}
3660
+		wp_safe_redirect($redirect_url);
3661
+		exit();
3662
+	}
3663
+
3664
+
3665
+	/**
3666
+	 * process any notices before redirecting (or returning ajax request)
3667
+	 * This method sets the $this->_template_args['notices'] attribute;
3668
+	 *
3669
+	 * @param array $query_args         any query args that need to be used for notice transient ('action')
3670
+	 * @param bool  $skip_route_verify  This is typically used when we are processing notices REALLY early and
3671
+	 *                                  page_routes haven't been defined yet.
3672
+	 * @param bool  $sticky_notices     This is used to flag that regardless of whether this is doing_ajax or not, we
3673
+	 *                                  still save a transient for the notice.
3674
+	 * @return void
3675
+	 * @throws EE_Error
3676
+	 * @throws InvalidArgumentException
3677
+	 * @throws InvalidDataTypeException
3678
+	 * @throws InvalidInterfaceException
3679
+	 */
3680
+	protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3681
+	{
3682
+		// first let's set individual error properties if doing_ajax and the properties aren't already set.
3683
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3684
+			$notices = EE_Error::get_notices(false);
3685
+			if (empty($this->_template_args['success'])) {
3686
+				$this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3687
+			}
3688
+			if (empty($this->_template_args['errors'])) {
3689
+				$this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3690
+			}
3691
+			if (empty($this->_template_args['attention'])) {
3692
+				$this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3693
+			}
3694
+		}
3695
+		$this->_template_args['notices'] = EE_Error::get_notices();
3696
+		// IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3697
+		if (! defined('DOING_AJAX') || $sticky_notices) {
3698
+			$route = isset($query_args['action']) ? $query_args['action'] : 'default';
3699
+			$this->_add_transient(
3700
+				$route,
3701
+				$this->_template_args['notices'],
3702
+				true,
3703
+				$skip_route_verify
3704
+			);
3705
+		}
3706
+	}
3707
+
3708
+
3709
+	/**
3710
+	 * get_action_link_or_button
3711
+	 * returns the button html for adding, editing, or deleting an item (depending on given type)
3712
+	 *
3713
+	 * @param string $action        use this to indicate which action the url is generated with.
3714
+	 * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3715
+	 *                              property.
3716
+	 * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3717
+	 * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3718
+	 * @param string $base_url      If this is not provided
3719
+	 *                              the _admin_base_url will be used as the default for the button base_url.
3720
+	 *                              Otherwise this value will be used.
3721
+	 * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3722
+	 * @return string
3723
+	 * @throws InvalidArgumentException
3724
+	 * @throws InvalidInterfaceException
3725
+	 * @throws InvalidDataTypeException
3726
+	 * @throws EE_Error
3727
+	 */
3728
+	public function get_action_link_or_button(
3729
+		$action,
3730
+		$type = 'add',
3731
+		$extra_request = array(),
3732
+		$class = 'button-primary',
3733
+		$base_url = '',
3734
+		$exclude_nonce = false
3735
+	) {
3736
+		// first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3737
+		if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3738
+			throw new EE_Error(
3739
+				sprintf(
3740
+					esc_html__(
3741
+						'There is no page route for given action for the button.  This action was given: %s',
3742
+						'event_espresso'
3743
+					),
3744
+					$action
3745
+				)
3746
+			);
3747
+		}
3748
+		if (! isset($this->_labels['buttons'][ $type ])) {
3749
+			throw new EE_Error(
3750
+				sprintf(
3751
+					__(
3752
+						'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3753
+						'event_espresso'
3754
+					),
3755
+					$type
3756
+				)
3757
+			);
3758
+		}
3759
+		// finally check user access for this button.
3760
+		$has_access = $this->check_user_access($action, true);
3761
+		if (! $has_access) {
3762
+			return '';
3763
+		}
3764
+		$_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
3765
+		$query_args = array(
3766
+			'action' => $action,
3767
+		);
3768
+		// merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3769
+		if (! empty($extra_request)) {
3770
+			$query_args = array_merge($extra_request, $query_args);
3771
+		}
3772
+		$url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3773
+		return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3774
+	}
3775
+
3776
+
3777
+	/**
3778
+	 * _per_page_screen_option
3779
+	 * Utility function for adding in a per_page_option in the screen_options_dropdown.
3780
+	 *
3781
+	 * @return void
3782
+	 * @throws InvalidArgumentException
3783
+	 * @throws InvalidInterfaceException
3784
+	 * @throws InvalidDataTypeException
3785
+	 */
3786
+	protected function _per_page_screen_option()
3787
+	{
3788
+		$option = 'per_page';
3789
+		$args = array(
3790
+			'label'   => apply_filters(
3791
+				'FHEE__EE_Admin_Page___per_page_screen_options___label',
3792
+				$this->_admin_page_title,
3793
+				$this
3794
+			),
3795
+			'default' => (int) apply_filters(
3796
+				'FHEE__EE_Admin_Page___per_page_screen_options__default',
3797
+				20
3798
+			),
3799
+			'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3800
+		);
3801
+		// ONLY add the screen option if the user has access to it.
3802
+		if ($this->check_user_access($this->_current_view, true)) {
3803
+			add_screen_option($option, $args);
3804
+		}
3805
+	}
3806
+
3807
+
3808
+	/**
3809
+	 * set_per_page_screen_option
3810
+	 * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3811
+	 * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3812
+	 * admin_menu.
3813
+	 *
3814
+	 * @return void
3815
+	 */
3816
+	private function _set_per_page_screen_options()
3817
+	{
3818
+		if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3819
+			check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3820
+			if (! $user = wp_get_current_user()) {
3821
+				return;
3822
+			}
3823
+			$option = $_POST['wp_screen_options']['option'];
3824
+			$value = $_POST['wp_screen_options']['value'];
3825
+			if ($option !== sanitize_key($option)) {
3826
+				return;
3827
+			}
3828
+			$map_option = $option;
3829
+			$option = str_replace('-', '_', $option);
3830
+			switch ($map_option) {
3831
+				case $this->_current_page . '_' . $this->_current_view . '_per_page':
3832
+					$value = (int) $value;
3833
+					$max_value = apply_filters(
3834
+						'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
3835
+						999,
3836
+						$this->_current_page,
3837
+						$this->_current_view
3838
+					);
3839
+					if ($value < 1) {
3840
+						return;
3841
+					}
3842
+					$value = min($value, $max_value);
3843
+					break;
3844
+				default:
3845
+					$value = apply_filters(
3846
+						'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3847
+						false,
3848
+						$option,
3849
+						$value
3850
+					);
3851
+					if (false === $value) {
3852
+						return;
3853
+					}
3854
+					break;
3855
+			}
3856
+			update_user_meta($user->ID, $option, $value);
3857
+			wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3858
+			exit;
3859
+		}
3860
+	}
3861
+
3862
+
3863
+	/**
3864
+	 * This just allows for setting the $_template_args property if it needs to be set outside the object
3865
+	 *
3866
+	 * @param array $data array that will be assigned to template args.
3867
+	 */
3868
+	public function set_template_args($data)
3869
+	{
3870
+		$this->_template_args = array_merge($this->_template_args, (array) $data);
3871
+	}
3872
+
3873
+
3874
+	/**
3875
+	 * This makes available the WP transient system for temporarily moving data between routes
3876
+	 *
3877
+	 * @param string $route             the route that should receive the transient
3878
+	 * @param array  $data              the data that gets sent
3879
+	 * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3880
+	 *                                  normal route transient.
3881
+	 * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3882
+	 *                                  when we are adding a transient before page_routes have been defined.
3883
+	 * @return void
3884
+	 * @throws EE_Error
3885
+	 */
3886
+	protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3887
+	{
3888
+		$user_id = get_current_user_id();
3889
+		if (! $skip_route_verify) {
3890
+			$this->_verify_route($route);
3891
+		}
3892
+		// now let's set the string for what kind of transient we're setting
3893
+		$transient = $notices
3894
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3895
+			: 'rte_tx_' . $route . '_' . $user_id;
3896
+		$data = $notices ? array('notices' => $data) : $data;
3897
+		// is there already a transient for this route?  If there is then let's ADD to that transient
3898
+		$existing = is_multisite() && is_network_admin()
3899
+			? get_site_transient($transient)
3900
+			: get_transient($transient);
3901
+		if ($existing) {
3902
+			$data = array_merge((array) $data, (array) $existing);
3903
+		}
3904
+		if (is_multisite() && is_network_admin()) {
3905
+			set_site_transient($transient, $data, 8);
3906
+		} else {
3907
+			set_transient($transient, $data, 8);
3908
+		}
3909
+	}
3910
+
3911
+
3912
+	/**
3913
+	 * this retrieves the temporary transient that has been set for moving data between routes.
3914
+	 *
3915
+	 * @param bool   $notices true we get notices transient. False we just return normal route transient
3916
+	 * @param string $route
3917
+	 * @return mixed data
3918
+	 */
3919
+	protected function _get_transient($notices = false, $route = '')
3920
+	{
3921
+		$user_id = get_current_user_id();
3922
+		$route = ! $route ? $this->_req_action : $route;
3923
+		$transient = $notices
3924
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3925
+			: 'rte_tx_' . $route . '_' . $user_id;
3926
+		$data = is_multisite() && is_network_admin()
3927
+			? get_site_transient($transient)
3928
+			: get_transient($transient);
3929
+		// delete transient after retrieval (just in case it hasn't expired);
3930
+		if (is_multisite() && is_network_admin()) {
3931
+			delete_site_transient($transient);
3932
+		} else {
3933
+			delete_transient($transient);
3934
+		}
3935
+		return $notices && isset($data['notices']) ? $data['notices'] : $data;
3936
+	}
3937
+
3938
+
3939
+	/**
3940
+	 * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3941
+	 * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3942
+	 * default route callback on the EE_Admin page you want it run.)
3943
+	 *
3944
+	 * @return void
3945
+	 */
3946
+	protected function _transient_garbage_collection()
3947
+	{
3948
+		global $wpdb;
3949
+		// retrieve all existing transients
3950
+		$query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3951
+		if ($results = $wpdb->get_results($query)) {
3952
+			foreach ($results as $result) {
3953
+				$transient = str_replace('_transient_', '', $result->option_name);
3954
+				get_transient($transient);
3955
+				if (is_multisite() && is_network_admin()) {
3956
+					get_site_transient($transient);
3957
+				}
3958
+			}
3959
+		}
3960
+	}
3961
+
3962
+
3963
+	/**
3964
+	 * get_view
3965
+	 *
3966
+	 * @return string content of _view property
3967
+	 */
3968
+	public function get_view()
3969
+	{
3970
+		return $this->_view;
3971
+	}
3972
+
3973
+
3974
+	/**
3975
+	 * getter for the protected $_views property
3976
+	 *
3977
+	 * @return array
3978
+	 */
3979
+	public function get_views()
3980
+	{
3981
+		return $this->_views;
3982
+	}
3983
+
3984
+
3985
+	/**
3986
+	 * get_current_page
3987
+	 *
3988
+	 * @return string _current_page property value
3989
+	 */
3990
+	public function get_current_page()
3991
+	{
3992
+		return $this->_current_page;
3993
+	}
3994
+
3995
+
3996
+	/**
3997
+	 * get_current_view
3998
+	 *
3999
+	 * @return string _current_view property value
4000
+	 */
4001
+	public function get_current_view()
4002
+	{
4003
+		return $this->_current_view;
4004
+	}
4005
+
4006
+
4007
+	/**
4008
+	 * get_current_screen
4009
+	 *
4010
+	 * @return object The current WP_Screen object
4011
+	 */
4012
+	public function get_current_screen()
4013
+	{
4014
+		return $this->_current_screen;
4015
+	}
4016
+
4017
+
4018
+	/**
4019
+	 * get_current_page_view_url
4020
+	 *
4021
+	 * @return string This returns the url for the current_page_view.
4022
+	 */
4023
+	public function get_current_page_view_url()
4024
+	{
4025
+		return $this->_current_page_view_url;
4026
+	}
4027
+
4028
+
4029
+	/**
4030
+	 * just returns the _req_data property
4031
+	 *
4032
+	 * @return array
4033
+	 */
4034
+	public function get_request_data()
4035
+	{
4036
+		return $this->_req_data;
4037
+	}
4038
+
4039
+
4040
+	/**
4041
+	 * returns the _req_data protected property
4042
+	 *
4043
+	 * @return string
4044
+	 */
4045
+	public function get_req_action()
4046
+	{
4047
+		return $this->_req_action;
4048
+	}
4049
+
4050
+
4051
+	/**
4052
+	 * @return bool  value of $_is_caf property
4053
+	 */
4054
+	public function is_caf()
4055
+	{
4056
+		return $this->_is_caf;
4057
+	}
4058
+
4059
+
4060
+	/**
4061
+	 * @return mixed
4062
+	 */
4063
+	public function default_espresso_metaboxes()
4064
+	{
4065
+		return $this->_default_espresso_metaboxes;
4066
+	}
4067
+
4068
+
4069
+	/**
4070
+	 * @return mixed
4071
+	 */
4072
+	public function admin_base_url()
4073
+	{
4074
+		return $this->_admin_base_url;
4075
+	}
4076
+
4077
+
4078
+	/**
4079
+	 * @return mixed
4080
+	 */
4081
+	public function wp_page_slug()
4082
+	{
4083
+		return $this->_wp_page_slug;
4084
+	}
4085
+
4086
+
4087
+	/**
4088
+	 * updates  espresso configuration settings
4089
+	 *
4090
+	 * @param string                   $tab
4091
+	 * @param EE_Config_Base|EE_Config $config
4092
+	 * @param string                   $file file where error occurred
4093
+	 * @param string                   $func function  where error occurred
4094
+	 * @param string                   $line line no where error occurred
4095
+	 * @return boolean
4096
+	 */
4097
+	protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4098
+	{
4099
+		// remove any options that are NOT going to be saved with the config settings.
4100
+		if (isset($config->core->ee_ueip_optin)) {
4101
+			// TODO: remove the following two lines and make sure values are migrated from 3.1
4102
+			update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4103
+			update_option('ee_ueip_has_notified', true);
4104
+		}
4105
+		// and save it (note we're also doing the network save here)
4106
+		$net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4107
+		$config_saved = EE_Config::instance()->update_espresso_config(false, false);
4108
+		if ($config_saved && $net_saved) {
4109
+			EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4110
+			return true;
4111
+		}
4112
+		EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4113
+		return false;
4114
+	}
4115
+
4116
+
4117
+	/**
4118
+	 * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4119
+	 *
4120
+	 * @return array
4121
+	 */
4122
+	public function get_yes_no_values()
4123
+	{
4124
+		return $this->_yes_no_values;
4125
+	}
4126
+
4127
+
4128
+	protected function _get_dir()
4129
+	{
4130
+		$reflector = new ReflectionClass(get_class($this));
4131
+		return dirname($reflector->getFileName());
4132
+	}
4133
+
4134
+
4135
+	/**
4136
+	 * A helper for getting a "next link".
4137
+	 *
4138
+	 * @param string $url   The url to link to
4139
+	 * @param string $class The class to use.
4140
+	 * @return string
4141
+	 */
4142
+	protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4143
+	{
4144
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4145
+	}
4146
+
4147
+
4148
+	/**
4149
+	 * A helper for getting a "previous link".
4150
+	 *
4151
+	 * @param string $url   The url to link to
4152
+	 * @param string $class The class to use.
4153
+	 * @return string
4154
+	 */
4155
+	protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4156
+	{
4157
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4158
+	}
4159
+
4160
+
4161
+
4162
+
4163
+
4164
+
4165
+
4166
+	// below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4167
+
4168
+
4169
+	/**
4170
+	 * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4171
+	 * 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
4172
+	 * _req_data array.
4173
+	 *
4174
+	 * @return bool success/fail
4175
+	 * @throws EE_Error
4176
+	 * @throws InvalidArgumentException
4177
+	 * @throws ReflectionException
4178
+	 * @throws InvalidDataTypeException
4179
+	 * @throws InvalidInterfaceException
4180
+	 */
4181
+	protected function _process_resend_registration()
4182
+	{
4183
+		$this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4184
+		do_action(
4185
+			'AHEE__EE_Admin_Page___process_resend_registration',
4186
+			$this->_template_args['success'],
4187
+			$this->_req_data
4188
+		);
4189
+		return $this->_template_args['success'];
4190
+	}
4191
+
4192
+
4193
+	/**
4194
+	 * This automatically processes any payment message notifications when manual payment has been applied.
4195
+	 *
4196
+	 * @param EE_Payment $payment
4197
+	 * @return bool success/fail
4198
+	 */
4199
+	protected function _process_payment_notification(EE_Payment $payment)
4200
+	{
4201
+		add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4202
+		do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4203
+		$this->_template_args['success'] = apply_filters(
4204
+			'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4205
+			false,
4206
+			$payment
4207
+		);
4208
+		return $this->_template_args['success'];
4209
+	}
4210 4210
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Init.core.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -432,7 +432,7 @@
 block discarded – undo
432 432
 
433 433
 
434 434
     /**
435
-     * @return mixed
435
+     * @return EE_Admin_Page
436 436
      */
437 437
     public function loaded_page_object()
438 438
     {
Please login to merge, or discard this patch.
Indentation   +447 added lines, -447 removed lines patch added patch discarded remove patch
@@ -17,451 +17,451 @@
 block discarded – undo
17 17
 abstract class EE_Admin_Page_Init extends EE_Base
18 18
 {
19 19
 
20
-    /**
21
-     * @var LoaderInterface $loader
22
-     */
23
-    protected $loader;
24
-
25
-    // identity properties (set in _set_defaults and _set_init_properties)
26
-    public $label;
27
-
28
-    /**
29
-     * Menu map has a capability.  However, this allows admin pages to have separate capability requirements for menus
30
-     * and accessing pages.  If capability is NOT set, then it defaults to the menu_map capability.
31
-     *
32
-     * @var string
33
-     */
34
-    public $capability;
35
-
36
-
37
-    /**
38
-     * This holds the menu map object for this admin page.
39
-     *
40
-     * @var EE_Admin_Page_Menu_Map
41
-     */
42
-    protected $_menu_map;
43
-
44
-    /**
45
-     * deprecated
46
-     */
47
-    public $menu_label;
48
-    public $menu_slug;
49
-
50
-
51
-    // set in _set_defaults
52
-    protected $_folder_name;
53
-    protected $_folder_path;
54
-    protected $_file_name;
55
-    public $hook_file;
56
-    protected $_wp_page_slug;
57
-    protected $_routing;
58
-
59
-
60
-    /**
61
-     * This holds the page object.
62
-     *
63
-     * @var EE_Admin_Page
64
-     */
65
-    protected $_loaded_page_object;
66
-
67
-
68
-    // for caf
69
-    protected $_files_hooked;
70
-    protected $_hook_paths;
71
-
72
-    // load_page?
73
-    private $_load_page;
74
-
75
-
76
-    /**
77
-     * @throws InvalidArgumentException
78
-     * @throws InvalidDataTypeException
79
-     * @throws InvalidInterfaceException
80
-     */
81
-    public function __construct()
82
-    {
83
-        $this->loader = LoaderFactory::getLoader();
84
-        // set global defaults
85
-        $this->_set_defaults();
86
-        // set properties that are always available with objects.
87
-        $this->_set_init_properties();
88
-        // global styles/scripts across all wp admin pages
89
-        add_action('admin_enqueue_scripts', array($this, 'load_wp_global_scripts_styles'), 5);
90
-        // load initial stuff.
91
-        $this->_set_file_and_folder_name();
92
-        $this->_set_menu_map();
93
-        if (empty($this->_menu_map) || is_array($this->_menu_map)) {
94
-            EE_Error::doing_it_wrong(
95
-                get_class($this) . '::$_menu_map',
96
-                sprintf(
97
-                    __(
98
-                        'The EE4 addon with the class %s is setting up the _menu_map property incorrectly for this version of EE core.  Please see Admin_Page_Init class examples in core for the new way of setting this property up.',
99
-                        'event_espresso'
100
-                    ),
101
-                    get_class($this)
102
-                ),
103
-                '4.4.0'
104
-            );
105
-            return;
106
-        }
107
-        // set default capability
108
-        $this->_set_capability();
109
-    }
110
-
111
-
112
-    /**
113
-     * _set_init_properties
114
-     * Child classes use to set the following properties:
115
-     * $label
116
-     *
117
-     * @abstract
118
-     * @access protected
119
-     * @return void
120
-     */
121
-    abstract protected function _set_init_properties();
122
-
123
-
124
-    /**
125
-     * _set_menu_map is a function that child classes use to set the menu_map property (which should be an instance of
126
-     * EE_Admin_Page_Menu_Map.  Their menu can either be EE_Admin_Page_Main_Menu or EE_Admin_Page_Sub_Menu.
127
-     *
128
-     * @since 4.4.0
129
-     * @ return void.
130
-     */
131
-    protected function _set_menu_map()
132
-    {
133
-        return array();
134
-    }
135
-
136
-
137
-    /**
138
-     * returns the menu map for this admin page
139
-     *
140
-     * @since 4.4.0
141
-     * @return EE_Admin_Page_Menu_Map
142
-     */
143
-    public function get_menu_map()
144
-    {
145
-        return $this->_menu_map;
146
-    }
147
-
148
-
149
-    /**
150
-     * This loads scripts and styles for the EE_Admin system
151
-     * that must be available on ALL WP admin pages (i.e. EE_menu items)
152
-     *
153
-     * @return void
154
-     */
155
-    public function load_wp_global_scripts_styles()
156
-    {
157
-        wp_register_style(
158
-            'espresso_menu',
159
-            EE_ADMIN_URL . 'assets/admin-menu-styles.css',
160
-            array('dashicons'),
161
-            EVENT_ESPRESSO_VERSION
162
-        );
163
-        wp_enqueue_style('espresso_menu');
164
-    }
165
-
166
-
167
-    /**
168
-     * this sets default properties (might be overridden in _set_init_properties);
169
-     *
170
-     * @access private
171
-     * @return  void
172
-     */
173
-    private function _set_defaults()
174
-    {
175
-        $this->_file_name = $this->_folder_name = $this->_wp_page_slug = $this->capability = null;
176
-        $this->_routing = true;
177
-        $this->_load_page = false;
178
-        $this->_files_hooked = $this->_hook_paths = array();
179
-        // menu_map
180
-        $this->_menu_map = $this->get_menu_map();
181
-    }
182
-
183
-
184
-    protected function _set_capability()
185
-    {
186
-        $capability = empty($this->capability) ? $this->_menu_map->capability : $this->capability;
187
-        $this->capability = apply_filters('FHEE_' . $this->_menu_map->menu_slug . '_capability', $capability);
188
-    }
189
-
190
-
191
-    /**
192
-     * initialize_admin_page
193
-     * This method is what executes the loading of the specific page class for the given dir_name as called by the
194
-     * EE_Admin_Init class.
195
-     *
196
-     * @access  public
197
-     * @return void
198
-     * @throws EE_Error
199
-     * @throws InvalidArgumentException
200
-     * @throws InvalidDataTypeException
201
-     * @throws InvalidInterfaceException
202
-     * @throws ReflectionException
203
-     * @uses    _initialize_admin_page()
204
-     */
205
-    public function initialize_admin_page()
206
-    {
207
-        // let's check user access first
208
-        $this->_check_user_access();
209
-        if (! is_object($this->_loaded_page_object)) {
210
-            return;
211
-        }
212
-        $this->_loaded_page_object->route_admin_request();
213
-    }
214
-
215
-
216
-    /**
217
-     * @param string $wp_page_slug
218
-     * @throws EE_Error
219
-     * @since $VID:$
220
-     */
221
-    public function set_page_dependencies($wp_page_slug)
222
-    {
223
-        if (! $this->_load_page) {
224
-            return;
225
-        }
226
-        if (! is_object($this->_loaded_page_object)) {
227
-            $msg[] = __(
228
-                'We can\'t load the page because we\'re missing a valid page object that tells us what to load',
229
-                'event_espresso'
230
-            );
231
-            $msg[] = $msg[0] . "\r\n"
232
-                     . sprintf(
233
-                         __(
234
-                             'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory',
235
-                             'event_espresso'
236
-                         ),
237
-                         $this->_file_name,
238
-                         $this->_file_name,
239
-                         $this->_folder_path . $this->_file_name,
240
-                         $this->_menu_map->menu_slug
241
-                     );
242
-            throw new EE_Error(implode('||', $msg));
243
-        }
244
-        $this->_loaded_page_object->set_wp_page_slug($wp_page_slug);
245
-        $page_hook = 'load-' . $wp_page_slug;
246
-        // hook into page load hook so all page specific stuff get's loaded.
247
-        if (! empty($wp_page_slug)) {
248
-            add_action($page_hook, array($this->_loaded_page_object, 'load_page_dependencies'));
249
-        }
250
-    }
251
-
252
-
253
-    /**
254
-     * This executes the initial page loads for EE_Admin pages to take care of any ajax or other code needing to run
255
-     * before the load-page... hook. Note, the page loads are happening around the wp_init hook.
256
-     *
257
-     * @return void
258
-     * @throws EE_Error
259
-     * @throws InvalidArgumentException
260
-     * @throws InvalidDataTypeException
261
-     * @throws InvalidInterfaceException
262
-     * @throws ReflectionException
263
-     */
264
-    public function do_initial_loads()
265
-    {
266
-        // no loading or initializing if menu map is setup incorrectly.
267
-        if (empty($this->_menu_map) || is_array($this->_menu_map)) {
268
-            return;
269
-        }
270
-        $this->_initialize_admin_page();
271
-    }
272
-
273
-
274
-    /**
275
-     * all we're doing here is setting the $_file_name property for later use.
276
-     *
277
-     * @access private
278
-     * @return void
279
-     */
280
-    private function _set_file_and_folder_name()
281
-    {
282
-        $bt = debug_backtrace();
283
-        // for more reliable determination of folder name
284
-        // we're using this to get the actual folder name of the CALLING class (i.e. the child class that extends this).  Why?  Because $this->menu_slug may be different than the folder name (to avoid conflicts with other plugins)
285
-        $class = get_class($this);
286
-        foreach ($bt as $index => $values) {
287
-            if (isset($values['class']) && $values['class'] === $class) {
288
-                $file_index = $index - 1;
289
-                $this->_folder_name = basename(dirname($bt[ $file_index ]['file']));
290
-                if (! empty($this->_folder_name)) {
291
-                    break;
292
-                }
293
-            }
294
-        }
295
-        $this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/';
296
-        $this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name);
297
-        $this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name));
298
-        $this->_file_name = str_replace(' ', '_', $this->_file_name);
299
-    }
300
-
301
-
302
-    /**
303
-     * This automatically checks if we have a hook class in the loaded child directory.  If we DO then we will register
304
-     * it with the appropriate pages.  That way all we have to do is make sure the file is named correctly and
305
-     * "dropped" in. Example: if we wanted to set this up for Messages hooking into Events then we would do:
306
-     * events_Messages_Hooks.class.php
307
-     *
308
-     * @param bool $extend This indicates whether we're checking the extend directory for any register_hooks
309
-     *                     files/classes
310
-     * @return array
311
-     */
312
-    public function register_hooks($extend = false)
313
-    {
314
-
315
-        // get a list of files in the directory that have the "Hook" in their name an
316
-        // if this is an extended check (i.e. caf is active) then we will scan the caffeinated/extend directory first and any hook files that are found will be have their reference added to the $_files_hook array property.  Then, we make sure that when we loop through the core decaf directories to find hook files that we skip over any hooks files that have already been set by caf.
317
-        if ($extend) {
318
-            $hook_files_glob_path = apply_filters(
319
-                'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path__extend',
320
-                EE_CORE_CAF_ADMIN_EXTEND
321
-                . $this->_folder_name
322
-                . '/*'
323
-                . $this->_file_name
324
-                . '_Hooks_Extend.class.php'
325
-            );
326
-            $this->_hook_paths = $this->_register_hook_files($hook_files_glob_path, $extend);
327
-        }
328
-        // loop through decaf folders
329
-        $hook_files_glob_path = apply_filters(
330
-            'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path',
331
-            $this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php'
332
-        );
333
-        $this->_hook_paths = array_merge(
334
-            $this->_register_hook_files($hook_files_glob_path),
335
-            $this->_hook_paths
336
-        );  // making sure any extended hook paths are later in the array than the core hook paths!
337
-        return $this->_hook_paths;
338
-    }
339
-
340
-
341
-    protected function _register_hook_files($hook_files_glob_path, $extend = false)
342
-    {
343
-        $hook_paths = array();
344
-        if ($hook_files = glob($hook_files_glob_path)) {
345
-            if (empty($hook_files)) {
346
-                return array();
347
-            }
348
-            foreach ($hook_files as $file) {
349
-                // lets get the linked admin.
350
-                $hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file)
351
-                    : str_replace($this->_folder_path, '', $file);
352
-                $replace = $extend
353
-                    ? '_' . $this->_file_name . '_Hooks_Extend.class.php'
354
-                    : '_'
355
-                      . $this->_file_name
356
-                      . '_Hooks.class.php';
357
-                $rel_admin = str_replace($replace, '', $hook_file);
358
-                $rel_admin = strtolower($rel_admin);
359
-                $hook_paths[] = $file;
360
-                // make sure we haven't already got a hook setup for this page path
361
-                if (in_array($rel_admin, $this->_files_hooked, true)) {
362
-                    continue;
363
-                }
364
-                $this->hook_file = $hook_file;
365
-                $rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin;
366
-                add_filter($rel_admin_hook, array($this, 'load_admin_hook'));
367
-                $this->_files_hooked[] = $rel_admin;
368
-            }
369
-        }
370
-        return $hook_paths;
371
-    }
372
-
373
-
374
-    public function load_admin_hook($registered_pages)
375
-    {
376
-        $this->hook_file;
377
-        $hook_file = (array) $this->hook_file;
378
-        return array_merge($hook_file, $registered_pages);
379
-    }
380
-
381
-
382
-    /**
383
-     * _initialize_admin_page
384
-     *
385
-     * @throws EE_Error
386
-     * @throws InvalidArgumentException
387
-     * @throws InvalidDataTypeException
388
-     * @throws InvalidInterfaceException
389
-     * @throws ReflectionException
390
-     * @see  initialize_admin_page() for info
391
-     */
392
-    protected function _initialize_admin_page()
393
-    {
394
-        // just check we're on right page and if not get out
395
-        if ((! isset($_REQUEST['page']) || $_REQUEST['page'] !== $this->_menu_map->menu_slug) && $this->_routing) {
396
-            return;
397
-        }
398
-        $this->_load_page = true;
399
-
400
-        // we don't need to do a page_request check here because it's only called via WP menu system.
401
-        $admin_page = $this->_file_name . '_Admin_Page';
402
-        $hook_suffix = $this->_menu_map->menu_slug . '_' . $admin_page;
403
-        $admin_page = apply_filters(
404
-            "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$hook_suffix}",
405
-            $admin_page
406
-        );
407
-        // define requested admin page class name then load the file and instantiate
408
-        $path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path . $admin_page . '.core.php');
409
-        $path_to_file = apply_filters(
410
-            "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$hook_suffix}",
411
-            $path_to_file
412
-        );// so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page
413
-        if (is_readable($path_to_file)) {
414
-            // This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place
415
-            do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization');
416
-            do_action(
417
-                'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_' . $this->_menu_map->menu_slug
418
-            );
419
-            require_once($path_to_file);
420
-            $this->_loaded_page_object = $this->loader->getShared($admin_page, [$this->_routing]);
421
-            $this->_loaded_page_object->initializePage();
422
-        }
423
-        do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization');
424
-        do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_' . $this->_menu_map->menu_slug);
425
-    }
426
-
427
-
428
-    public function get_admin_page_name()
429
-    {
430
-        return $this->_file_name . '_Admin_Page';
431
-    }
432
-
433
-
434
-    /**
435
-     * @return mixed
436
-     */
437
-    public function loaded_page_object()
438
-    {
439
-        return $this->_loaded_page_object;
440
-    }
441
-
442
-
443
-    // public function set_autoloaders($className)
444
-    // {
445
-    //     $dir_ref = array(
446
-    //         $this->_folder_path => array('core', 'class'),
447
-    //     );
448
-    //     EEH_Autoloader::try_autoload($dir_ref, $className);
449
-    // }
450
-    /**
451
-     * _check_user_access
452
-     * verifies user access for this admin page.  If no user access is available then let's gracefully exit with a
453
-     * WordPress die message.
454
-     *
455
-     * @return bool true if pass (or admin) wp_die if fail
456
-     */
457
-    private function _check_user_access()
458
-    {
459
-        if (! EE_Registry::instance()->CAP->current_user_can(
460
-            $this->_menu_map->capability,
461
-            $this->_menu_map->menu_slug
462
-        )) {
463
-            wp_die(__('You don\'t have access to this page.', 'event_espresso'), '', array('back_link' => true));
464
-        }
465
-        return true;
466
-    }
20
+	/**
21
+	 * @var LoaderInterface $loader
22
+	 */
23
+	protected $loader;
24
+
25
+	// identity properties (set in _set_defaults and _set_init_properties)
26
+	public $label;
27
+
28
+	/**
29
+	 * Menu map has a capability.  However, this allows admin pages to have separate capability requirements for menus
30
+	 * and accessing pages.  If capability is NOT set, then it defaults to the menu_map capability.
31
+	 *
32
+	 * @var string
33
+	 */
34
+	public $capability;
35
+
36
+
37
+	/**
38
+	 * This holds the menu map object for this admin page.
39
+	 *
40
+	 * @var EE_Admin_Page_Menu_Map
41
+	 */
42
+	protected $_menu_map;
43
+
44
+	/**
45
+	 * deprecated
46
+	 */
47
+	public $menu_label;
48
+	public $menu_slug;
49
+
50
+
51
+	// set in _set_defaults
52
+	protected $_folder_name;
53
+	protected $_folder_path;
54
+	protected $_file_name;
55
+	public $hook_file;
56
+	protected $_wp_page_slug;
57
+	protected $_routing;
58
+
59
+
60
+	/**
61
+	 * This holds the page object.
62
+	 *
63
+	 * @var EE_Admin_Page
64
+	 */
65
+	protected $_loaded_page_object;
66
+
67
+
68
+	// for caf
69
+	protected $_files_hooked;
70
+	protected $_hook_paths;
71
+
72
+	// load_page?
73
+	private $_load_page;
74
+
75
+
76
+	/**
77
+	 * @throws InvalidArgumentException
78
+	 * @throws InvalidDataTypeException
79
+	 * @throws InvalidInterfaceException
80
+	 */
81
+	public function __construct()
82
+	{
83
+		$this->loader = LoaderFactory::getLoader();
84
+		// set global defaults
85
+		$this->_set_defaults();
86
+		// set properties that are always available with objects.
87
+		$this->_set_init_properties();
88
+		// global styles/scripts across all wp admin pages
89
+		add_action('admin_enqueue_scripts', array($this, 'load_wp_global_scripts_styles'), 5);
90
+		// load initial stuff.
91
+		$this->_set_file_and_folder_name();
92
+		$this->_set_menu_map();
93
+		if (empty($this->_menu_map) || is_array($this->_menu_map)) {
94
+			EE_Error::doing_it_wrong(
95
+				get_class($this) . '::$_menu_map',
96
+				sprintf(
97
+					__(
98
+						'The EE4 addon with the class %s is setting up the _menu_map property incorrectly for this version of EE core.  Please see Admin_Page_Init class examples in core for the new way of setting this property up.',
99
+						'event_espresso'
100
+					),
101
+					get_class($this)
102
+				),
103
+				'4.4.0'
104
+			);
105
+			return;
106
+		}
107
+		// set default capability
108
+		$this->_set_capability();
109
+	}
110
+
111
+
112
+	/**
113
+	 * _set_init_properties
114
+	 * Child classes use to set the following properties:
115
+	 * $label
116
+	 *
117
+	 * @abstract
118
+	 * @access protected
119
+	 * @return void
120
+	 */
121
+	abstract protected function _set_init_properties();
122
+
123
+
124
+	/**
125
+	 * _set_menu_map is a function that child classes use to set the menu_map property (which should be an instance of
126
+	 * EE_Admin_Page_Menu_Map.  Their menu can either be EE_Admin_Page_Main_Menu or EE_Admin_Page_Sub_Menu.
127
+	 *
128
+	 * @since 4.4.0
129
+	 * @ return void.
130
+	 */
131
+	protected function _set_menu_map()
132
+	{
133
+		return array();
134
+	}
135
+
136
+
137
+	/**
138
+	 * returns the menu map for this admin page
139
+	 *
140
+	 * @since 4.4.0
141
+	 * @return EE_Admin_Page_Menu_Map
142
+	 */
143
+	public function get_menu_map()
144
+	{
145
+		return $this->_menu_map;
146
+	}
147
+
148
+
149
+	/**
150
+	 * This loads scripts and styles for the EE_Admin system
151
+	 * that must be available on ALL WP admin pages (i.e. EE_menu items)
152
+	 *
153
+	 * @return void
154
+	 */
155
+	public function load_wp_global_scripts_styles()
156
+	{
157
+		wp_register_style(
158
+			'espresso_menu',
159
+			EE_ADMIN_URL . 'assets/admin-menu-styles.css',
160
+			array('dashicons'),
161
+			EVENT_ESPRESSO_VERSION
162
+		);
163
+		wp_enqueue_style('espresso_menu');
164
+	}
165
+
166
+
167
+	/**
168
+	 * this sets default properties (might be overridden in _set_init_properties);
169
+	 *
170
+	 * @access private
171
+	 * @return  void
172
+	 */
173
+	private function _set_defaults()
174
+	{
175
+		$this->_file_name = $this->_folder_name = $this->_wp_page_slug = $this->capability = null;
176
+		$this->_routing = true;
177
+		$this->_load_page = false;
178
+		$this->_files_hooked = $this->_hook_paths = array();
179
+		// menu_map
180
+		$this->_menu_map = $this->get_menu_map();
181
+	}
182
+
183
+
184
+	protected function _set_capability()
185
+	{
186
+		$capability = empty($this->capability) ? $this->_menu_map->capability : $this->capability;
187
+		$this->capability = apply_filters('FHEE_' . $this->_menu_map->menu_slug . '_capability', $capability);
188
+	}
189
+
190
+
191
+	/**
192
+	 * initialize_admin_page
193
+	 * This method is what executes the loading of the specific page class for the given dir_name as called by the
194
+	 * EE_Admin_Init class.
195
+	 *
196
+	 * @access  public
197
+	 * @return void
198
+	 * @throws EE_Error
199
+	 * @throws InvalidArgumentException
200
+	 * @throws InvalidDataTypeException
201
+	 * @throws InvalidInterfaceException
202
+	 * @throws ReflectionException
203
+	 * @uses    _initialize_admin_page()
204
+	 */
205
+	public function initialize_admin_page()
206
+	{
207
+		// let's check user access first
208
+		$this->_check_user_access();
209
+		if (! is_object($this->_loaded_page_object)) {
210
+			return;
211
+		}
212
+		$this->_loaded_page_object->route_admin_request();
213
+	}
214
+
215
+
216
+	/**
217
+	 * @param string $wp_page_slug
218
+	 * @throws EE_Error
219
+	 * @since $VID:$
220
+	 */
221
+	public function set_page_dependencies($wp_page_slug)
222
+	{
223
+		if (! $this->_load_page) {
224
+			return;
225
+		}
226
+		if (! is_object($this->_loaded_page_object)) {
227
+			$msg[] = __(
228
+				'We can\'t load the page because we\'re missing a valid page object that tells us what to load',
229
+				'event_espresso'
230
+			);
231
+			$msg[] = $msg[0] . "\r\n"
232
+					 . sprintf(
233
+						 __(
234
+							 'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory',
235
+							 'event_espresso'
236
+						 ),
237
+						 $this->_file_name,
238
+						 $this->_file_name,
239
+						 $this->_folder_path . $this->_file_name,
240
+						 $this->_menu_map->menu_slug
241
+					 );
242
+			throw new EE_Error(implode('||', $msg));
243
+		}
244
+		$this->_loaded_page_object->set_wp_page_slug($wp_page_slug);
245
+		$page_hook = 'load-' . $wp_page_slug;
246
+		// hook into page load hook so all page specific stuff get's loaded.
247
+		if (! empty($wp_page_slug)) {
248
+			add_action($page_hook, array($this->_loaded_page_object, 'load_page_dependencies'));
249
+		}
250
+	}
251
+
252
+
253
+	/**
254
+	 * This executes the initial page loads for EE_Admin pages to take care of any ajax or other code needing to run
255
+	 * before the load-page... hook. Note, the page loads are happening around the wp_init hook.
256
+	 *
257
+	 * @return void
258
+	 * @throws EE_Error
259
+	 * @throws InvalidArgumentException
260
+	 * @throws InvalidDataTypeException
261
+	 * @throws InvalidInterfaceException
262
+	 * @throws ReflectionException
263
+	 */
264
+	public function do_initial_loads()
265
+	{
266
+		// no loading or initializing if menu map is setup incorrectly.
267
+		if (empty($this->_menu_map) || is_array($this->_menu_map)) {
268
+			return;
269
+		}
270
+		$this->_initialize_admin_page();
271
+	}
272
+
273
+
274
+	/**
275
+	 * all we're doing here is setting the $_file_name property for later use.
276
+	 *
277
+	 * @access private
278
+	 * @return void
279
+	 */
280
+	private function _set_file_and_folder_name()
281
+	{
282
+		$bt = debug_backtrace();
283
+		// for more reliable determination of folder name
284
+		// we're using this to get the actual folder name of the CALLING class (i.e. the child class that extends this).  Why?  Because $this->menu_slug may be different than the folder name (to avoid conflicts with other plugins)
285
+		$class = get_class($this);
286
+		foreach ($bt as $index => $values) {
287
+			if (isset($values['class']) && $values['class'] === $class) {
288
+				$file_index = $index - 1;
289
+				$this->_folder_name = basename(dirname($bt[ $file_index ]['file']));
290
+				if (! empty($this->_folder_name)) {
291
+					break;
292
+				}
293
+			}
294
+		}
295
+		$this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/';
296
+		$this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name);
297
+		$this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name));
298
+		$this->_file_name = str_replace(' ', '_', $this->_file_name);
299
+	}
300
+
301
+
302
+	/**
303
+	 * This automatically checks if we have a hook class in the loaded child directory.  If we DO then we will register
304
+	 * it with the appropriate pages.  That way all we have to do is make sure the file is named correctly and
305
+	 * "dropped" in. Example: if we wanted to set this up for Messages hooking into Events then we would do:
306
+	 * events_Messages_Hooks.class.php
307
+	 *
308
+	 * @param bool $extend This indicates whether we're checking the extend directory for any register_hooks
309
+	 *                     files/classes
310
+	 * @return array
311
+	 */
312
+	public function register_hooks($extend = false)
313
+	{
314
+
315
+		// get a list of files in the directory that have the "Hook" in their name an
316
+		// if this is an extended check (i.e. caf is active) then we will scan the caffeinated/extend directory first and any hook files that are found will be have their reference added to the $_files_hook array property.  Then, we make sure that when we loop through the core decaf directories to find hook files that we skip over any hooks files that have already been set by caf.
317
+		if ($extend) {
318
+			$hook_files_glob_path = apply_filters(
319
+				'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path__extend',
320
+				EE_CORE_CAF_ADMIN_EXTEND
321
+				. $this->_folder_name
322
+				. '/*'
323
+				. $this->_file_name
324
+				. '_Hooks_Extend.class.php'
325
+			);
326
+			$this->_hook_paths = $this->_register_hook_files($hook_files_glob_path, $extend);
327
+		}
328
+		// loop through decaf folders
329
+		$hook_files_glob_path = apply_filters(
330
+			'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path',
331
+			$this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php'
332
+		);
333
+		$this->_hook_paths = array_merge(
334
+			$this->_register_hook_files($hook_files_glob_path),
335
+			$this->_hook_paths
336
+		);  // making sure any extended hook paths are later in the array than the core hook paths!
337
+		return $this->_hook_paths;
338
+	}
339
+
340
+
341
+	protected function _register_hook_files($hook_files_glob_path, $extend = false)
342
+	{
343
+		$hook_paths = array();
344
+		if ($hook_files = glob($hook_files_glob_path)) {
345
+			if (empty($hook_files)) {
346
+				return array();
347
+			}
348
+			foreach ($hook_files as $file) {
349
+				// lets get the linked admin.
350
+				$hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file)
351
+					: str_replace($this->_folder_path, '', $file);
352
+				$replace = $extend
353
+					? '_' . $this->_file_name . '_Hooks_Extend.class.php'
354
+					: '_'
355
+					  . $this->_file_name
356
+					  . '_Hooks.class.php';
357
+				$rel_admin = str_replace($replace, '', $hook_file);
358
+				$rel_admin = strtolower($rel_admin);
359
+				$hook_paths[] = $file;
360
+				// make sure we haven't already got a hook setup for this page path
361
+				if (in_array($rel_admin, $this->_files_hooked, true)) {
362
+					continue;
363
+				}
364
+				$this->hook_file = $hook_file;
365
+				$rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin;
366
+				add_filter($rel_admin_hook, array($this, 'load_admin_hook'));
367
+				$this->_files_hooked[] = $rel_admin;
368
+			}
369
+		}
370
+		return $hook_paths;
371
+	}
372
+
373
+
374
+	public function load_admin_hook($registered_pages)
375
+	{
376
+		$this->hook_file;
377
+		$hook_file = (array) $this->hook_file;
378
+		return array_merge($hook_file, $registered_pages);
379
+	}
380
+
381
+
382
+	/**
383
+	 * _initialize_admin_page
384
+	 *
385
+	 * @throws EE_Error
386
+	 * @throws InvalidArgumentException
387
+	 * @throws InvalidDataTypeException
388
+	 * @throws InvalidInterfaceException
389
+	 * @throws ReflectionException
390
+	 * @see  initialize_admin_page() for info
391
+	 */
392
+	protected function _initialize_admin_page()
393
+	{
394
+		// just check we're on right page and if not get out
395
+		if ((! isset($_REQUEST['page']) || $_REQUEST['page'] !== $this->_menu_map->menu_slug) && $this->_routing) {
396
+			return;
397
+		}
398
+		$this->_load_page = true;
399
+
400
+		// we don't need to do a page_request check here because it's only called via WP menu system.
401
+		$admin_page = $this->_file_name . '_Admin_Page';
402
+		$hook_suffix = $this->_menu_map->menu_slug . '_' . $admin_page;
403
+		$admin_page = apply_filters(
404
+			"FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$hook_suffix}",
405
+			$admin_page
406
+		);
407
+		// define requested admin page class name then load the file and instantiate
408
+		$path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path . $admin_page . '.core.php');
409
+		$path_to_file = apply_filters(
410
+			"FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$hook_suffix}",
411
+			$path_to_file
412
+		);// so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page
413
+		if (is_readable($path_to_file)) {
414
+			// This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place
415
+			do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization');
416
+			do_action(
417
+				'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_' . $this->_menu_map->menu_slug
418
+			);
419
+			require_once($path_to_file);
420
+			$this->_loaded_page_object = $this->loader->getShared($admin_page, [$this->_routing]);
421
+			$this->_loaded_page_object->initializePage();
422
+		}
423
+		do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization');
424
+		do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_' . $this->_menu_map->menu_slug);
425
+	}
426
+
427
+
428
+	public function get_admin_page_name()
429
+	{
430
+		return $this->_file_name . '_Admin_Page';
431
+	}
432
+
433
+
434
+	/**
435
+	 * @return mixed
436
+	 */
437
+	public function loaded_page_object()
438
+	{
439
+		return $this->_loaded_page_object;
440
+	}
441
+
442
+
443
+	// public function set_autoloaders($className)
444
+	// {
445
+	//     $dir_ref = array(
446
+	//         $this->_folder_path => array('core', 'class'),
447
+	//     );
448
+	//     EEH_Autoloader::try_autoload($dir_ref, $className);
449
+	// }
450
+	/**
451
+	 * _check_user_access
452
+	 * verifies user access for this admin page.  If no user access is available then let's gracefully exit with a
453
+	 * WordPress die message.
454
+	 *
455
+	 * @return bool true if pass (or admin) wp_die if fail
456
+	 */
457
+	private function _check_user_access()
458
+	{
459
+		if (! EE_Registry::instance()->CAP->current_user_can(
460
+			$this->_menu_map->capability,
461
+			$this->_menu_map->menu_slug
462
+		)) {
463
+			wp_die(__('You don\'t have access to this page.', 'event_espresso'), '', array('back_link' => true));
464
+		}
465
+		return true;
466
+	}
467 467
 }
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
         $this->_set_menu_map();
93 93
         if (empty($this->_menu_map) || is_array($this->_menu_map)) {
94 94
             EE_Error::doing_it_wrong(
95
-                get_class($this) . '::$_menu_map',
95
+                get_class($this).'::$_menu_map',
96 96
                 sprintf(
97 97
                     __(
98 98
                         'The EE4 addon with the class %s is setting up the _menu_map property incorrectly for this version of EE core.  Please see Admin_Page_Init class examples in core for the new way of setting this property up.',
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
     {
157 157
         wp_register_style(
158 158
             'espresso_menu',
159
-            EE_ADMIN_URL . 'assets/admin-menu-styles.css',
159
+            EE_ADMIN_URL.'assets/admin-menu-styles.css',
160 160
             array('dashicons'),
161 161
             EVENT_ESPRESSO_VERSION
162 162
         );
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
     protected function _set_capability()
185 185
     {
186 186
         $capability = empty($this->capability) ? $this->_menu_map->capability : $this->capability;
187
-        $this->capability = apply_filters('FHEE_' . $this->_menu_map->menu_slug . '_capability', $capability);
187
+        $this->capability = apply_filters('FHEE_'.$this->_menu_map->menu_slug.'_capability', $capability);
188 188
     }
189 189
 
190 190
 
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
     {
207 207
         // let's check user access first
208 208
         $this->_check_user_access();
209
-        if (! is_object($this->_loaded_page_object)) {
209
+        if ( ! is_object($this->_loaded_page_object)) {
210 210
             return;
211 211
         }
212 212
         $this->_loaded_page_object->route_admin_request();
@@ -220,15 +220,15 @@  discard block
 block discarded – undo
220 220
      */
221 221
     public function set_page_dependencies($wp_page_slug)
222 222
     {
223
-        if (! $this->_load_page) {
223
+        if ( ! $this->_load_page) {
224 224
             return;
225 225
         }
226
-        if (! is_object($this->_loaded_page_object)) {
226
+        if ( ! is_object($this->_loaded_page_object)) {
227 227
             $msg[] = __(
228 228
                 'We can\'t load the page because we\'re missing a valid page object that tells us what to load',
229 229
                 'event_espresso'
230 230
             );
231
-            $msg[] = $msg[0] . "\r\n"
231
+            $msg[] = $msg[0]."\r\n"
232 232
                      . sprintf(
233 233
                          __(
234 234
                              'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory',
@@ -236,15 +236,15 @@  discard block
 block discarded – undo
236 236
                          ),
237 237
                          $this->_file_name,
238 238
                          $this->_file_name,
239
-                         $this->_folder_path . $this->_file_name,
239
+                         $this->_folder_path.$this->_file_name,
240 240
                          $this->_menu_map->menu_slug
241 241
                      );
242 242
             throw new EE_Error(implode('||', $msg));
243 243
         }
244 244
         $this->_loaded_page_object->set_wp_page_slug($wp_page_slug);
245
-        $page_hook = 'load-' . $wp_page_slug;
245
+        $page_hook = 'load-'.$wp_page_slug;
246 246
         // hook into page load hook so all page specific stuff get's loaded.
247
-        if (! empty($wp_page_slug)) {
247
+        if ( ! empty($wp_page_slug)) {
248 248
             add_action($page_hook, array($this->_loaded_page_object, 'load_page_dependencies'));
249 249
         }
250 250
     }
@@ -286,13 +286,13 @@  discard block
 block discarded – undo
286 286
         foreach ($bt as $index => $values) {
287 287
             if (isset($values['class']) && $values['class'] === $class) {
288 288
                 $file_index = $index - 1;
289
-                $this->_folder_name = basename(dirname($bt[ $file_index ]['file']));
290
-                if (! empty($this->_folder_name)) {
289
+                $this->_folder_name = basename(dirname($bt[$file_index]['file']));
290
+                if ( ! empty($this->_folder_name)) {
291 291
                     break;
292 292
                 }
293 293
             }
294 294
         }
295
-        $this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/';
295
+        $this->_folder_path = EE_ADMIN_PAGES.$this->_folder_name.'/';
296 296
         $this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name);
297 297
         $this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name));
298 298
         $this->_file_name = str_replace(' ', '_', $this->_file_name);
@@ -328,12 +328,12 @@  discard block
 block discarded – undo
328 328
         // loop through decaf folders
329 329
         $hook_files_glob_path = apply_filters(
330 330
             'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path',
331
-            $this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php'
331
+            $this->_folder_path.'*'.$this->_file_name.'_Hooks.class.php'
332 332
         );
333 333
         $this->_hook_paths = array_merge(
334 334
             $this->_register_hook_files($hook_files_glob_path),
335 335
             $this->_hook_paths
336
-        );  // making sure any extended hook paths are later in the array than the core hook paths!
336
+        ); // making sure any extended hook paths are later in the array than the core hook paths!
337 337
         return $this->_hook_paths;
338 338
     }
339 339
 
@@ -347,10 +347,10 @@  discard block
 block discarded – undo
347 347
             }
348 348
             foreach ($hook_files as $file) {
349 349
                 // lets get the linked admin.
350
-                $hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file)
350
+                $hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND.$this->_folder_name.'/', '', $file)
351 351
                     : str_replace($this->_folder_path, '', $file);
352 352
                 $replace = $extend
353
-                    ? '_' . $this->_file_name . '_Hooks_Extend.class.php'
353
+                    ? '_'.$this->_file_name.'_Hooks_Extend.class.php'
354 354
                     : '_'
355 355
                       . $this->_file_name
356 356
                       . '_Hooks.class.php';
@@ -362,7 +362,7 @@  discard block
 block discarded – undo
362 362
                     continue;
363 363
                 }
364 364
                 $this->hook_file = $hook_file;
365
-                $rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin;
365
+                $rel_admin_hook = 'FHEE_do_other_page_hooks_'.$rel_admin;
366 366
                 add_filter($rel_admin_hook, array($this, 'load_admin_hook'));
367 367
                 $this->_files_hooked[] = $rel_admin;
368 368
             }
@@ -392,42 +392,42 @@  discard block
 block discarded – undo
392 392
     protected function _initialize_admin_page()
393 393
     {
394 394
         // just check we're on right page and if not get out
395
-        if ((! isset($_REQUEST['page']) || $_REQUEST['page'] !== $this->_menu_map->menu_slug) && $this->_routing) {
395
+        if (( ! isset($_REQUEST['page']) || $_REQUEST['page'] !== $this->_menu_map->menu_slug) && $this->_routing) {
396 396
             return;
397 397
         }
398 398
         $this->_load_page = true;
399 399
 
400 400
         // we don't need to do a page_request check here because it's only called via WP menu system.
401
-        $admin_page = $this->_file_name . '_Admin_Page';
402
-        $hook_suffix = $this->_menu_map->menu_slug . '_' . $admin_page;
401
+        $admin_page = $this->_file_name.'_Admin_Page';
402
+        $hook_suffix = $this->_menu_map->menu_slug.'_'.$admin_page;
403 403
         $admin_page = apply_filters(
404 404
             "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$hook_suffix}",
405 405
             $admin_page
406 406
         );
407 407
         // define requested admin page class name then load the file and instantiate
408
-        $path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path . $admin_page . '.core.php');
408
+        $path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path.$admin_page.'.core.php');
409 409
         $path_to_file = apply_filters(
410 410
             "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$hook_suffix}",
411 411
             $path_to_file
412
-        );// so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page
412
+        ); // so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page
413 413
         if (is_readable($path_to_file)) {
414 414
             // This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place
415 415
             do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization');
416 416
             do_action(
417
-                'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_' . $this->_menu_map->menu_slug
417
+                'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_'.$this->_menu_map->menu_slug
418 418
             );
419 419
             require_once($path_to_file);
420 420
             $this->_loaded_page_object = $this->loader->getShared($admin_page, [$this->_routing]);
421 421
             $this->_loaded_page_object->initializePage();
422 422
         }
423 423
         do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization');
424
-        do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_' . $this->_menu_map->menu_slug);
424
+        do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_'.$this->_menu_map->menu_slug);
425 425
     }
426 426
 
427 427
 
428 428
     public function get_admin_page_name()
429 429
     {
430
-        return $this->_file_name . '_Admin_Page';
430
+        return $this->_file_name.'_Admin_Page';
431 431
     }
432 432
 
433 433
 
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
      */
457 457
     private function _check_user_access()
458 458
     {
459
-        if (! EE_Registry::instance()->CAP->current_user_can(
459
+        if ( ! EE_Registry::instance()->CAP->current_user_can(
460 460
             $this->_menu_map->capability,
461 461
             $this->_menu_map->menu_slug
462 462
         )) {
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Menu_Map.core.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -122,7 +122,7 @@
 block discarded – undo
122 122
      *
123 123
      * @param array $menu_args            An array of arguments used to setup the menu
124 124
      *                                    properties on construct.
125
-     * @param array $required             An array of keys that should be in the $menu_args, this
125
+     * @param string[] $required             An array of keys that should be in the $menu_args, this
126 126
      *                                    is used to validate that the items that should be defined
127 127
      *                                    are present.
128 128
      * @return void
Please login to merge, or discard this patch.
Indentation   +355 added lines, -355 removed lines patch added patch discarded remove patch
@@ -11,261 +11,261 @@  discard block
 block discarded – undo
11 11
 {
12 12
 
13 13
 
14
-    /**
15
-     * The title for the menu page. (the page the menu links to)
16
-     *
17
-     * @since  4.4.0
18
-     * @var string
19
-     */
20
-    public $title;
21
-
22
-
23
-    /**
24
-     * The label for the menu item. (What shows up in the actual menu).
25
-     *
26
-     * @since 4.4.0
27
-     * @var string
28
-     */
29
-    public $menu_label;
30
-
31
-
32
-    /**
33
-     * What menu item is the parent of this menu item.
34
-     *
35
-     * @since 4.4.0
36
-     * @var string
37
-     */
38
-    public $parent_slug;
39
-
40
-
41
-    /**
42
-     * What capability is required to access this page.
43
-     *
44
-     * @since 4.4.0
45
-     * @var string
46
-     */
47
-    public $capability = 'administrator';
48
-
49
-
50
-    /**
51
-     * What slug should be used to reference this menu item.
52
-     *
53
-     * @since 4.4.0
54
-     * @var string
55
-     */
56
-    public $menu_slug;
57
-
58
-
59
-    /**
60
-     * The callback for displaying the page that the menu references.
61
-     *
62
-     * @since 4.4.0
63
-     * @var string
64
-     */
65
-    public $menu_callback;
66
-
67
-
68
-    /**
69
-     * The EE_Admin_Page_Init attached to this map.
70
-     *
71
-     * @var EE_Admin_Page_Init
72
-     */
73
-    public $admin_init_page;
74
-
75
-
76
-    /**
77
-     * The EE specific group this menu item belongs in (group slug).
78
-     *
79
-     * @since 4.4.0
80
-     * @var string
81
-     */
82
-    public $menu_group;
83
-
84
-
85
-    /**
86
-     * What order this item should be in the menu.
87
-     *
88
-     * @since 4.4.0
89
-     * @var int
90
-     */
91
-    public $menu_order;
92
-
93
-
94
-    const NONE = 0;
95
-    const BLOG_ADMIN_ONLY = 1;
96
-    const BLOG_AND_NETWORK_ADMIN = 2;
97
-    const NETWORK_ADMIN_ONLY = 3;
98
-
99
-
100
-    /**
101
-     * Whether this item is displayed in the menu or not.
102
-     * Sometimes an EE Admin Page needs to register itself but is not accessible via the WordPress
103
-     * admin menu.
104
-     *
105
-     * @since 4.4.0
106
-     * @var int
107
-     */
108
-    public $show_on_menu = self::BLOG_ADMIN_ONLY;
109
-
110
-
111
-    /**
112
-     * Menu maps can define a parent slug that gets used instead of the main parent slug for the menu when
113
-     * EE_Maintenance_Mode::level_2_complete_maintenance is active.
114
-     *
115
-     * @var bool
116
-     */
117
-    public $maintenance_mode_parent = '';
118
-
119
-
120
-    /**
121
-     * Constructor.
122
-     *
123
-     * @param array $menu_args            An array of arguments used to setup the menu
124
-     *                                    properties on construct.
125
-     * @param array $required             An array of keys that should be in the $menu_args, this
126
-     *                                    is used to validate that the items that should be defined
127
-     *                                    are present.
128
-     * @return void
129
-     * @throws EE_Error
130
-     * @since 4.4.0
131
-     */
132
-    public function __construct($menu_args, $required)
133
-    {
134
-        // filter all args before processing so plugins can manipulate various settings for menus.
135
-        $menu_args = apply_filters(
136
-            'FHEE__EE_Admin_Page_Menu_Map__construct__menu_args',
137
-            $menu_args,
138
-            $required,
139
-            get_class($this)
140
-        );
141
-
142
-
143
-        // verify that required keys are present in the incoming array.
144
-        $missing = array_diff((array) $required, array_keys((array) $menu_args));
145
-
146
-        if (! empty($missing)) {
147
-            throw new EE_Error(
148
-                sprintf(
149
-                    __(
150
-                        '%s is missing some expected keys in the argument array.  The following keys are missing: %s',
151
-                        'event_espresso'
152
-                    ),
153
-                    get_class($this),
154
-                    implode(', ', $missing)
155
-                )
156
-            );
157
-        }
158
-
159
-        // made it here okay, so let's set the properties!
160
-        foreach ($menu_args as $prop => $value) {
161
-            switch ($prop) {
162
-                case 'show_on_menu':
163
-                    $value = (int) $value;
164
-                    break;
165
-                case 'admin_init_page':
166
-                    if (! $value instanceof EE_Admin_Page_Init
167
-                        && in_array('admin_init_page', $required, true)
168
-                    ) {
169
-                        throw new EE_Error(
170
-                            sprintf(
171
-                                __(
172
-                                    'The value for the "admin_init_page" argument must be an instance of an EE_Admin_Page_Init object.  Instead %s was given as the value.',
173
-                                    'event_espresso'
174
-                                ),
175
-                                print_r($value, true)
176
-                            )
177
-                        );
178
-                    }
179
-                    break;
180
-                case 'menu_callback':
181
-                    break;
182
-
183
-                default:
184
-                    $value = (string) $value;
185
-                    break;
186
-            }
187
-            if (! EEH_Class_Tools::has_property($this, $prop)) {
188
-                throw new EE_Error(
189
-                    sprintf(
190
-                        __(
191
-                            'The $menu_args coming into %s has a index key (%s) representing a property that is not defined by the class.  Perhaps there is a typo?',
192
-                            'event_espresso'
193
-                        ),
194
-                        get_class($this),
195
-                        $prop
196
-                    )
197
-                );
198
-            }
199
-            $this->{$prop} = $value;
200
-        }
201
-
202
-        // filter capabilities (both static and dynamic)
203
-        $this->capability = apply_filters('FHEE_management_capability', $this->capability, null);
204
-        $this->capability = apply_filters('FHEE_' . $this->menu_slug . '_capability', $this->capability, null);
205
-
206
-        // Might need to change parent slug depending on maintenance mode.
207
-        if (! empty($this->maintenance_mode_parent)
208
-            && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
209
-        ) {
210
-            $this->parent_slug = $this->maintenance_mode_parent;
211
-        }
212
-
213
-        // if empty menu_callback let's set default (but only if we have admin page init object)
214
-        if (empty($this->menu_callback) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
215
-            $this->menu_callback = array($this->admin_init_page, 'initialize_admin_page');
216
-        }
217
-    }
218
-
219
-
220
-    /**
221
-     * This method should define how the menu page gets added for this particular item
222
-     * and go ahead and define it.  Note that child classes MUST also return the result of
223
-     * the function used to register the WordPress admin page (the wp_page_slug string)
224
-     *
225
-     * @since  4.4.0
226
-     * @return string wp_page_slug.
227
-     */
228
-    abstract protected function _add_menu_page();
229
-
230
-
231
-    /**
232
-     * Called by client code to use this menu map for registering a WordPress admin page
233
-     *
234
-     * @param boolean $network_admin whether this is being added to the network admin page or not
235
-     * @throws EE_Error
236
-     * @throws ReflectionException
237
-     * @since  4.4.0
238
-     */
239
-    public function add_menu_page($network_admin = false)
240
-    {
241
-
242
-        $show_on_menu_int = (int) $this->show_on_menu;
243
-        if (($network_admin
244
-             && in_array(
245
-                 $show_on_menu_int,
246
-                 array(self::BLOG_AND_NETWORK_ADMIN, self::NETWORK_ADMIN_ONLY),
247
-                 true
248
-             ))
249
-            ||
250
-            (! $network_admin
251
-             && in_array(
252
-                 $show_on_menu_int,
253
-                 array(self::BLOG_AND_NETWORK_ADMIN, self::BLOG_ADMIN_ONLY),
254
-                 true
255
-             ))) {
256
-            $wp_page_slug = $this->_add_menu_page();
257
-        } else {
258
-            $wp_page_slug = '';
259
-        }
260
-
261
-        if (! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
262
-            try {
263
-                $this->admin_init_page->set_page_dependencies($wp_page_slug);
264
-            } catch (EE_Error $e) {
265
-                $e->get_error();
266
-            }
267
-        }
268
-    }
14
+	/**
15
+	 * The title for the menu page. (the page the menu links to)
16
+	 *
17
+	 * @since  4.4.0
18
+	 * @var string
19
+	 */
20
+	public $title;
21
+
22
+
23
+	/**
24
+	 * The label for the menu item. (What shows up in the actual menu).
25
+	 *
26
+	 * @since 4.4.0
27
+	 * @var string
28
+	 */
29
+	public $menu_label;
30
+
31
+
32
+	/**
33
+	 * What menu item is the parent of this menu item.
34
+	 *
35
+	 * @since 4.4.0
36
+	 * @var string
37
+	 */
38
+	public $parent_slug;
39
+
40
+
41
+	/**
42
+	 * What capability is required to access this page.
43
+	 *
44
+	 * @since 4.4.0
45
+	 * @var string
46
+	 */
47
+	public $capability = 'administrator';
48
+
49
+
50
+	/**
51
+	 * What slug should be used to reference this menu item.
52
+	 *
53
+	 * @since 4.4.0
54
+	 * @var string
55
+	 */
56
+	public $menu_slug;
57
+
58
+
59
+	/**
60
+	 * The callback for displaying the page that the menu references.
61
+	 *
62
+	 * @since 4.4.0
63
+	 * @var string
64
+	 */
65
+	public $menu_callback;
66
+
67
+
68
+	/**
69
+	 * The EE_Admin_Page_Init attached to this map.
70
+	 *
71
+	 * @var EE_Admin_Page_Init
72
+	 */
73
+	public $admin_init_page;
74
+
75
+
76
+	/**
77
+	 * The EE specific group this menu item belongs in (group slug).
78
+	 *
79
+	 * @since 4.4.0
80
+	 * @var string
81
+	 */
82
+	public $menu_group;
83
+
84
+
85
+	/**
86
+	 * What order this item should be in the menu.
87
+	 *
88
+	 * @since 4.4.0
89
+	 * @var int
90
+	 */
91
+	public $menu_order;
92
+
93
+
94
+	const NONE = 0;
95
+	const BLOG_ADMIN_ONLY = 1;
96
+	const BLOG_AND_NETWORK_ADMIN = 2;
97
+	const NETWORK_ADMIN_ONLY = 3;
98
+
99
+
100
+	/**
101
+	 * Whether this item is displayed in the menu or not.
102
+	 * Sometimes an EE Admin Page needs to register itself but is not accessible via the WordPress
103
+	 * admin menu.
104
+	 *
105
+	 * @since 4.4.0
106
+	 * @var int
107
+	 */
108
+	public $show_on_menu = self::BLOG_ADMIN_ONLY;
109
+
110
+
111
+	/**
112
+	 * Menu maps can define a parent slug that gets used instead of the main parent slug for the menu when
113
+	 * EE_Maintenance_Mode::level_2_complete_maintenance is active.
114
+	 *
115
+	 * @var bool
116
+	 */
117
+	public $maintenance_mode_parent = '';
118
+
119
+
120
+	/**
121
+	 * Constructor.
122
+	 *
123
+	 * @param array $menu_args            An array of arguments used to setup the menu
124
+	 *                                    properties on construct.
125
+	 * @param array $required             An array of keys that should be in the $menu_args, this
126
+	 *                                    is used to validate that the items that should be defined
127
+	 *                                    are present.
128
+	 * @return void
129
+	 * @throws EE_Error
130
+	 * @since 4.4.0
131
+	 */
132
+	public function __construct($menu_args, $required)
133
+	{
134
+		// filter all args before processing so plugins can manipulate various settings for menus.
135
+		$menu_args = apply_filters(
136
+			'FHEE__EE_Admin_Page_Menu_Map__construct__menu_args',
137
+			$menu_args,
138
+			$required,
139
+			get_class($this)
140
+		);
141
+
142
+
143
+		// verify that required keys are present in the incoming array.
144
+		$missing = array_diff((array) $required, array_keys((array) $menu_args));
145
+
146
+		if (! empty($missing)) {
147
+			throw new EE_Error(
148
+				sprintf(
149
+					__(
150
+						'%s is missing some expected keys in the argument array.  The following keys are missing: %s',
151
+						'event_espresso'
152
+					),
153
+					get_class($this),
154
+					implode(', ', $missing)
155
+				)
156
+			);
157
+		}
158
+
159
+		// made it here okay, so let's set the properties!
160
+		foreach ($menu_args as $prop => $value) {
161
+			switch ($prop) {
162
+				case 'show_on_menu':
163
+					$value = (int) $value;
164
+					break;
165
+				case 'admin_init_page':
166
+					if (! $value instanceof EE_Admin_Page_Init
167
+						&& in_array('admin_init_page', $required, true)
168
+					) {
169
+						throw new EE_Error(
170
+							sprintf(
171
+								__(
172
+									'The value for the "admin_init_page" argument must be an instance of an EE_Admin_Page_Init object.  Instead %s was given as the value.',
173
+									'event_espresso'
174
+								),
175
+								print_r($value, true)
176
+							)
177
+						);
178
+					}
179
+					break;
180
+				case 'menu_callback':
181
+					break;
182
+
183
+				default:
184
+					$value = (string) $value;
185
+					break;
186
+			}
187
+			if (! EEH_Class_Tools::has_property($this, $prop)) {
188
+				throw new EE_Error(
189
+					sprintf(
190
+						__(
191
+							'The $menu_args coming into %s has a index key (%s) representing a property that is not defined by the class.  Perhaps there is a typo?',
192
+							'event_espresso'
193
+						),
194
+						get_class($this),
195
+						$prop
196
+					)
197
+				);
198
+			}
199
+			$this->{$prop} = $value;
200
+		}
201
+
202
+		// filter capabilities (both static and dynamic)
203
+		$this->capability = apply_filters('FHEE_management_capability', $this->capability, null);
204
+		$this->capability = apply_filters('FHEE_' . $this->menu_slug . '_capability', $this->capability, null);
205
+
206
+		// Might need to change parent slug depending on maintenance mode.
207
+		if (! empty($this->maintenance_mode_parent)
208
+			&& EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
209
+		) {
210
+			$this->parent_slug = $this->maintenance_mode_parent;
211
+		}
212
+
213
+		// if empty menu_callback let's set default (but only if we have admin page init object)
214
+		if (empty($this->menu_callback) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
215
+			$this->menu_callback = array($this->admin_init_page, 'initialize_admin_page');
216
+		}
217
+	}
218
+
219
+
220
+	/**
221
+	 * This method should define how the menu page gets added for this particular item
222
+	 * and go ahead and define it.  Note that child classes MUST also return the result of
223
+	 * the function used to register the WordPress admin page (the wp_page_slug string)
224
+	 *
225
+	 * @since  4.4.0
226
+	 * @return string wp_page_slug.
227
+	 */
228
+	abstract protected function _add_menu_page();
229
+
230
+
231
+	/**
232
+	 * Called by client code to use this menu map for registering a WordPress admin page
233
+	 *
234
+	 * @param boolean $network_admin whether this is being added to the network admin page or not
235
+	 * @throws EE_Error
236
+	 * @throws ReflectionException
237
+	 * @since  4.4.0
238
+	 */
239
+	public function add_menu_page($network_admin = false)
240
+	{
241
+
242
+		$show_on_menu_int = (int) $this->show_on_menu;
243
+		if (($network_admin
244
+			 && in_array(
245
+				 $show_on_menu_int,
246
+				 array(self::BLOG_AND_NETWORK_ADMIN, self::NETWORK_ADMIN_ONLY),
247
+				 true
248
+			 ))
249
+			||
250
+			(! $network_admin
251
+			 && in_array(
252
+				 $show_on_menu_int,
253
+				 array(self::BLOG_AND_NETWORK_ADMIN, self::BLOG_ADMIN_ONLY),
254
+				 true
255
+			 ))) {
256
+			$wp_page_slug = $this->_add_menu_page();
257
+		} else {
258
+			$wp_page_slug = '';
259
+		}
260
+
261
+		if (! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
262
+			try {
263
+				$this->admin_init_page->set_page_dependencies($wp_page_slug);
264
+			} catch (EE_Error $e) {
265
+				$e->get_error();
266
+			}
267
+		}
268
+	}
269 269
 }
270 270
 
271 271
 
@@ -279,75 +279,75 @@  discard block
 block discarded – undo
279 279
 class EE_Admin_Page_Main_Menu extends EE_Admin_Page_Menu_Map
280 280
 {
281 281
 
282
-    /**
283
-     * If included int incoming params, then this class will also register a Sub Menue Admin page with a different
284
-     * subtitle than the main menu item.
285
-     *
286
-     * @since 4.4.0
287
-     *
288
-     * @var string
289
-     */
290
-    public $subtitle;
291
-
292
-    /**
293
-     * The page to a icon used for this menu.
294
-     *
295
-     * @since  4.4.0
296
-     * @see    http://codex.wordpress.org/Function_Reference/add_menu_page#Parameters
297
-     *        for what can be set for this property.
298
-     * @var string
299
-     */
300
-    public $icon_url;
301
-
302
-
303
-    /**
304
-     * What position in the main menu order for the WP admin menu this menu item
305
-     * should show.
306
-     *
307
-     * @since  4.4.0
308
-     * @see    http://codex.wordpress.org/Function_Reference/add_menu_page#Parameters
309
-     *        for what can be set for this property.
310
-     * @var integer
311
-     */
312
-    public $position;
313
-
314
-
315
-    public function __construct($menu_args)
316
-    {
317
-        $required = array('menu_label', 'parent_slug', 'menu_slug', 'menu_group', 'menu_order', 'admin_init_page');
318
-
319
-        parent::__construct($menu_args, $required);
320
-
321
-        $this->position = ! empty($this->position) ? (int) $this->position : $this->position;
322
-    }
323
-
324
-
325
-    /**
326
-     * Uses the proper WP utility for registering a menu page for the main WP pages.
327
-     */
328
-    protected function _add_menu_page()
329
-    {
330
-        $main = add_menu_page(
331
-            $this->title,
332
-            $this->menu_label,
333
-            $this->capability,
334
-            $this->parent_slug,
335
-            $this->menu_callback,
336
-            $this->icon_url,
337
-            $this->position
338
-        );
339
-        if (! empty($this->subtitle)) {
340
-            add_submenu_page(
341
-                $this->parent_slug,
342
-                $this->subtitle,
343
-                $this->subtitle,
344
-                $this->capability,
345
-                $this->menu_slug,
346
-                $this->menu_callback
347
-            );
348
-        }
349
-        return $main;
350
-    }
282
+	/**
283
+	 * If included int incoming params, then this class will also register a Sub Menue Admin page with a different
284
+	 * subtitle than the main menu item.
285
+	 *
286
+	 * @since 4.4.0
287
+	 *
288
+	 * @var string
289
+	 */
290
+	public $subtitle;
291
+
292
+	/**
293
+	 * The page to a icon used for this menu.
294
+	 *
295
+	 * @since  4.4.0
296
+	 * @see    http://codex.wordpress.org/Function_Reference/add_menu_page#Parameters
297
+	 *        for what can be set for this property.
298
+	 * @var string
299
+	 */
300
+	public $icon_url;
301
+
302
+
303
+	/**
304
+	 * What position in the main menu order for the WP admin menu this menu item
305
+	 * should show.
306
+	 *
307
+	 * @since  4.4.0
308
+	 * @see    http://codex.wordpress.org/Function_Reference/add_menu_page#Parameters
309
+	 *        for what can be set for this property.
310
+	 * @var integer
311
+	 */
312
+	public $position;
313
+
314
+
315
+	public function __construct($menu_args)
316
+	{
317
+		$required = array('menu_label', 'parent_slug', 'menu_slug', 'menu_group', 'menu_order', 'admin_init_page');
318
+
319
+		parent::__construct($menu_args, $required);
320
+
321
+		$this->position = ! empty($this->position) ? (int) $this->position : $this->position;
322
+	}
323
+
324
+
325
+	/**
326
+	 * Uses the proper WP utility for registering a menu page for the main WP pages.
327
+	 */
328
+	protected function _add_menu_page()
329
+	{
330
+		$main = add_menu_page(
331
+			$this->title,
332
+			$this->menu_label,
333
+			$this->capability,
334
+			$this->parent_slug,
335
+			$this->menu_callback,
336
+			$this->icon_url,
337
+			$this->position
338
+		);
339
+		if (! empty($this->subtitle)) {
340
+			add_submenu_page(
341
+				$this->parent_slug,
342
+				$this->subtitle,
343
+				$this->subtitle,
344
+				$this->capability,
345
+				$this->menu_slug,
346
+				$this->menu_callback
347
+			);
348
+		}
349
+		return $main;
350
+	}
351 351
 } //end EE_Admin_Page_Main_Menu
352 352
 
353 353
 
@@ -361,17 +361,17 @@  discard block
 block discarded – undo
361 361
 class EE_Admin_Page_Sub_Menu extends EE_Admin_Page_Main_Menu
362 362
 {
363 363
 
364
-    protected function _add_menu_page()
365
-    {
366
-        return add_submenu_page(
367
-            $this->parent_slug,
368
-            $this->title,
369
-            $this->menu_label,
370
-            $this->capability,
371
-            $this->menu_slug,
372
-            $this->menu_callback
373
-        );
374
-    }
364
+	protected function _add_menu_page()
365
+	{
366
+		return add_submenu_page(
367
+			$this->parent_slug,
368
+			$this->title,
369
+			$this->menu_label,
370
+			$this->capability,
371
+			$this->menu_slug,
372
+			$this->menu_callback
373
+		);
374
+	}
375 375
 }
376 376
 
377 377
 
@@ -390,28 +390,28 @@  discard block
 block discarded – undo
390 390
 {
391 391
 
392 392
 
393
-    public function __construct($menu_args = array())
394
-    {
395
-        $required = array('menu_label', 'menu_slug', 'menu_order', 'parent_slug');
396
-        parent::__construct($menu_args, $required);
397
-    }
393
+	public function __construct($menu_args = array())
394
+	{
395
+		$required = array('menu_label', 'menu_slug', 'menu_order', 'parent_slug');
396
+		parent::__construct($menu_args, $required);
397
+	}
398 398
 
399 399
 
400
-    protected function _add_menu_page()
401
-    {
402
-        return add_submenu_page(
403
-            $this->parent_slug,
404
-            $this->menu_label,
405
-            $this->_group_link(),
406
-            $this->capability,
407
-            $this->menu_slug,
408
-            '__return_false'
409
-        );
410
-    }
400
+	protected function _add_menu_page()
401
+	{
402
+		return add_submenu_page(
403
+			$this->parent_slug,
404
+			$this->menu_label,
405
+			$this->_group_link(),
406
+			$this->capability,
407
+			$this->menu_slug,
408
+			'__return_false'
409
+		);
410
+	}
411 411
 
412 412
 
413
-    private function _group_link()
414
-    {
415
-        return '<span class="ee_menu_group"  onclick="return false;">' . $this->menu_label . '</span>';
416
-    }
413
+	private function _group_link()
414
+	{
415
+		return '<span class="ee_menu_group"  onclick="return false;">' . $this->menu_label . '</span>';
416
+	}
417 417
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -143,7 +143,7 @@  discard block
 block discarded – undo
143 143
         // verify that required keys are present in the incoming array.
144 144
         $missing = array_diff((array) $required, array_keys((array) $menu_args));
145 145
 
146
-        if (! empty($missing)) {
146
+        if ( ! empty($missing)) {
147 147
             throw new EE_Error(
148 148
                 sprintf(
149 149
                     __(
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
                     $value = (int) $value;
164 164
                     break;
165 165
                 case 'admin_init_page':
166
-                    if (! $value instanceof EE_Admin_Page_Init
166
+                    if ( ! $value instanceof EE_Admin_Page_Init
167 167
                         && in_array('admin_init_page', $required, true)
168 168
                     ) {
169 169
                         throw new EE_Error(
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
                     $value = (string) $value;
185 185
                     break;
186 186
             }
187
-            if (! EEH_Class_Tools::has_property($this, $prop)) {
187
+            if ( ! EEH_Class_Tools::has_property($this, $prop)) {
188 188
                 throw new EE_Error(
189 189
                     sprintf(
190 190
                         __(
@@ -201,10 +201,10 @@  discard block
 block discarded – undo
201 201
 
202 202
         // filter capabilities (both static and dynamic)
203 203
         $this->capability = apply_filters('FHEE_management_capability', $this->capability, null);
204
-        $this->capability = apply_filters('FHEE_' . $this->menu_slug . '_capability', $this->capability, null);
204
+        $this->capability = apply_filters('FHEE_'.$this->menu_slug.'_capability', $this->capability, null);
205 205
 
206 206
         // Might need to change parent slug depending on maintenance mode.
207
-        if (! empty($this->maintenance_mode_parent)
207
+        if ( ! empty($this->maintenance_mode_parent)
208 208
             && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
209 209
         ) {
210 210
             $this->parent_slug = $this->maintenance_mode_parent;
@@ -247,7 +247,7 @@  discard block
 block discarded – undo
247 247
                  true
248 248
              ))
249 249
             ||
250
-            (! $network_admin
250
+            ( ! $network_admin
251 251
              && in_array(
252 252
                  $show_on_menu_int,
253 253
                  array(self::BLOG_AND_NETWORK_ADMIN, self::BLOG_ADMIN_ONLY),
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
             $wp_page_slug = '';
259 259
         }
260 260
 
261
-        if (! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
261
+        if ( ! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
262 262
             try {
263 263
                 $this->admin_init_page->set_page_dependencies($wp_page_slug);
264 264
             } catch (EE_Error $e) {
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
             $this->icon_url,
337 337
             $this->position
338 338
         );
339
-        if (! empty($this->subtitle)) {
339
+        if ( ! empty($this->subtitle)) {
340 340
             add_submenu_page(
341 341
                 $this->parent_slug,
342 342
                 $this->subtitle,
@@ -412,6 +412,6 @@  discard block
 block discarded – undo
412 412
 
413 413
     private function _group_link()
414 414
     {
415
-        return '<span class="ee_menu_group"  onclick="return false;">' . $this->menu_label . '</span>';
415
+        return '<span class="ee_menu_group"  onclick="return false;">'.$this->menu_label.'</span>';
416 416
     }
417 417
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_CPT_Init.core.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -14,44 +14,44 @@
 block discarded – undo
14 14
 {
15 15
 
16 16
 
17
-    public function do_initial_loads()
18
-    {
19
-        // we want to use the corresponding admin page object (but not route it!).
20
-        // To do this we just set _routing to false.
21
-        // That way this page object is being loaded on all pages to make sure we hook into admin properly.
22
-        // But note... we are ONLY doing this if the given page is NOT pages we WANT to load ;)
23
-        // This is important because we have hooks that help redirect custom post type saves
24
-        $requested_page = isset($_REQUEST['page']) ? sanitize_text_field($_REQUEST['page']) : '';
25
-        if ($requested_page !== $this->_menu_map->menu_slug) {
26
-            $this->_routing = false;
27
-            $this->_initialize_admin_page();
28
-        } else {
29
-            // normal init loads
30
-            $this->_initialize_admin_page();
31
-            // added for 4.1 to completely disable autosave for our pages. This can be removed once we fully enable autosave functionality
32
-            remove_filter('wp_print_scripts', 'wp_just_in_time_script_localization');
33
-            add_filter('wp_print_scripts', array($this, 'wp_just_in_time_script_localization'), 100);
34
-            // end removal of autosave functionality.
35
-        }
36
-    }
17
+	public function do_initial_loads()
18
+	{
19
+		// we want to use the corresponding admin page object (but not route it!).
20
+		// To do this we just set _routing to false.
21
+		// That way this page object is being loaded on all pages to make sure we hook into admin properly.
22
+		// But note... we are ONLY doing this if the given page is NOT pages we WANT to load ;)
23
+		// This is important because we have hooks that help redirect custom post type saves
24
+		$requested_page = isset($_REQUEST['page']) ? sanitize_text_field($_REQUEST['page']) : '';
25
+		if ($requested_page !== $this->_menu_map->menu_slug) {
26
+			$this->_routing = false;
27
+			$this->_initialize_admin_page();
28
+		} else {
29
+			// normal init loads
30
+			$this->_initialize_admin_page();
31
+			// added for 4.1 to completely disable autosave for our pages. This can be removed once we fully enable autosave functionality
32
+			remove_filter('wp_print_scripts', 'wp_just_in_time_script_localization');
33
+			add_filter('wp_print_scripts', array($this, 'wp_just_in_time_script_localization'), 100);
34
+			// end removal of autosave functionality.
35
+		}
36
+	}
37 37
 
38 38
 
39
-    public function wp_just_in_time_script_localization()
40
-    {
41
-        wp_localize_script(
42
-            'autosave',
43
-            'autosaveL10n',
44
-            array(
45
-                'autosaveInterval' => 172800,
46
-                'savingText'       => __('Saving Draft&#8230;', 'event_espresso'),
47
-                'saveAlert'        => __('The changes you made will be lost if you navigate away from this page.', 'event_espresso'),
48
-            )
49
-        );
50
-    }
39
+	public function wp_just_in_time_script_localization()
40
+	{
41
+		wp_localize_script(
42
+			'autosave',
43
+			'autosaveL10n',
44
+			array(
45
+				'autosaveInterval' => 172800,
46
+				'savingText'       => __('Saving Draft&#8230;', 'event_espresso'),
47
+				'saveAlert'        => __('The changes you made will be lost if you navigate away from this page.', 'event_espresso'),
48
+			)
49
+		);
50
+	}
51 51
 
52 52
 
53
-    public function adjust_post_lock_window($interval)
54
-    {
55
-        return 172800;
56
-    }
53
+	public function adjust_post_lock_window($interval)
54
+	{
55
+		return 172800;
56
+	}
57 57
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_CPT.core.php 2 patches
Indentation   +1485 added lines, -1485 removed lines patch added patch discarded remove patch
@@ -27,474 +27,474 @@  discard block
 block discarded – undo
27 27
 {
28 28
 
29 29
 
30
-    /**
31
-     * This gets set in _setup_cpt
32
-     * It will contain the object for the custom post type.
33
-     *
34
-     * @var EE_CPT_Base
35
-     */
36
-    protected $_cpt_object;
37
-
38
-
39
-    /**
40
-     * a boolean flag to set whether the current route is a cpt route or not.
41
-     *
42
-     * @var bool
43
-     */
44
-    protected $_cpt_route = false;
45
-
46
-
47
-    /**
48
-     * This property allows cpt classes to define multiple routes as cpt routes.
49
-     * //in this array we define what the custom post type for this route is.
50
-     * array(
51
-     * 'route_name' => 'custom_post_type_slug'
52
-     * )
53
-     *
54
-     * @var array
55
-     */
56
-    protected $_cpt_routes = array();
57
-
58
-
59
-    /**
60
-     * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
61
-     * in this format:
62
-     * array(
63
-     * 'post_type_slug' => 'edit_route'
64
-     * )
65
-     *
66
-     * @var array
67
-     */
68
-    protected $_cpt_edit_routes = array();
69
-
70
-
71
-    /**
72
-     * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
73
-     * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
74
-     * _cpt_model_names property should be in the following format: array(
75
-     * 'route_defined_by_action_param' => 'Model_Name')
76
-     *
77
-     * @var array $_cpt_model_names
78
-     */
79
-    protected $_cpt_model_names = array();
80
-
81
-
82
-    /**
83
-     * @var EE_CPT_Base
84
-     */
85
-    protected $_cpt_model_obj = false;
86
-
87
-
88
-    /**
89
-     * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
90
-     * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
91
-     * the _register_autosave_containers() method so that we don't override any other containers already registered.
92
-     * Registration of containers should be done before load_page_dependencies() is run.
93
-     *
94
-     * @var array()
95
-     */
96
-    protected $_autosave_containers = array();
97
-    protected $_autosave_fields = array();
98
-
99
-    /**
100
-     * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
101
-     * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
102
-     *
103
-     * @var array
104
-     */
105
-    protected $_pagenow_map;
106
-
107
-
108
-    /**
109
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
110
-     * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
111
-     * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
112
-     * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
113
-     * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
114
-     *
115
-     * @access protected
116
-     * @abstract
117
-     * @param  string      $post_id The ID of the cpt that was saved (so you can link relationally)
118
-     * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
119
-     * @return void
120
-     */
121
-    abstract protected function _insert_update_cpt_item($post_id, $post);
122
-
123
-
124
-    /**
125
-     * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
126
-     *
127
-     * @abstract
128
-     * @access public
129
-     * @param  string $post_id The ID of the cpt that was trashed
130
-     * @return void
131
-     */
132
-    abstract public function trash_cpt_item($post_id);
133
-
134
-
135
-    /**
136
-     * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
137
-     *
138
-     * @param  string $post_id theID of the cpt that was untrashed
139
-     * @return void
140
-     */
141
-    abstract public function restore_cpt_item($post_id);
142
-
143
-
144
-    /**
145
-     * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
146
-     * from the db
147
-     *
148
-     * @param  string $post_id the ID of the cpt that was deleted
149
-     * @return void
150
-     */
151
-    abstract public function delete_cpt_item($post_id);
152
-
153
-
154
-    /**
155
-     * Just utilizing the method EE_Admin exposes for doing things before page setup.
156
-     *
157
-     * @access protected
158
-     * @return void
159
-     */
160
-    protected function _before_page_setup()
161
-    {
162
-        $page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
163
-        $this->_cpt_routes = array_merge(
164
-            array(
165
-                'create_new' => $this->page_slug,
166
-                'edit'       => $this->page_slug,
167
-                'trash'      => $this->page_slug,
168
-            ),
169
-            $this->_cpt_routes
170
-        );
171
-        // let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
172
-        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
173
-            ? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
174
-            : get_post_type_object($page);
175
-        // tweak pagenow for page loading.
176
-        if (! $this->_pagenow_map) {
177
-            $this->_pagenow_map = array(
178
-                'create_new' => 'post-new.php',
179
-                'edit'       => 'post.php',
180
-                'trash'      => 'post.php',
181
-            );
182
-        }
183
-        add_action('current_screen', array($this, 'modify_pagenow'));
184
-        // TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
185
-        // get current page from autosave
186
-        $current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
187
-            ? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
188
-            : null;
189
-        $this->_current_page = isset($this->_req_data['current_page'])
190
-            ? $this->_req_data['current_page']
191
-            : $current_page;
192
-        // autosave... make sure its only for the correct page
193
-        // if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
194
-        // setup autosave ajax hook
195
-        // add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
196
-        // }
197
-    }
198
-
199
-
200
-    /**
201
-     * Simply ensure that we simulate the correct post route for cpt screens
202
-     *
203
-     * @param WP_Screen $current_screen
204
-     * @return void
205
-     */
206
-    public function modify_pagenow($current_screen)
207
-    {
208
-        global $pagenow, $hook_suffix;
209
-        // possibly reset pagenow.
210
-        if (! empty($this->_req_data['page'])
211
-            && $this->_req_data['page'] == $this->page_slug
212
-            && ! empty($this->_req_data['action'])
213
-            && isset($this->_pagenow_map[ $this->_req_data['action'] ])
214
-        ) {
215
-            $pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
216
-            $hook_suffix = $pagenow;
217
-        }
218
-    }
219
-
220
-
221
-    /**
222
-     * This method is used to register additional autosave containers to the _autosave_containers property.
223
-     *
224
-     * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
225
-     *       automatically register the id for the post metabox as a container.
226
-     * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
227
-     *                    you would send along the id of a metabox container.
228
-     * @return void
229
-     */
230
-    protected function _register_autosave_containers($ids)
231
-    {
232
-        $this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
233
-    }
234
-
235
-
236
-    /**
237
-     * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
238
-     * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
239
-     */
240
-    protected function _set_autosave_containers()
241
-    {
242
-        global $wp_meta_boxes;
243
-        $containers = array();
244
-        if (empty($wp_meta_boxes)) {
245
-            return;
246
-        }
247
-        $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
248
-        foreach ($current_metaboxes as $box_context) {
249
-            foreach ($box_context as $box_details) {
250
-                foreach ($box_details as $box) {
251
-                    if (is_array($box['callback'])
252
-                        && (
253
-                            $box['callback'][0] instanceof EE_Admin_Page
254
-                            || $box['callback'][0] instanceof EE_Admin_Hooks
255
-                        )
256
-                    ) {
257
-                        $containers[] = $box['id'];
258
-                    }
259
-                }
260
-            }
261
-        }
262
-        $this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
263
-        // add hidden inputs container
264
-        $this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
265
-    }
266
-
267
-
268
-    protected function _load_autosave_scripts_styles()
269
-    {
270
-        /*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
30
+	/**
31
+	 * This gets set in _setup_cpt
32
+	 * It will contain the object for the custom post type.
33
+	 *
34
+	 * @var EE_CPT_Base
35
+	 */
36
+	protected $_cpt_object;
37
+
38
+
39
+	/**
40
+	 * a boolean flag to set whether the current route is a cpt route or not.
41
+	 *
42
+	 * @var bool
43
+	 */
44
+	protected $_cpt_route = false;
45
+
46
+
47
+	/**
48
+	 * This property allows cpt classes to define multiple routes as cpt routes.
49
+	 * //in this array we define what the custom post type for this route is.
50
+	 * array(
51
+	 * 'route_name' => 'custom_post_type_slug'
52
+	 * )
53
+	 *
54
+	 * @var array
55
+	 */
56
+	protected $_cpt_routes = array();
57
+
58
+
59
+	/**
60
+	 * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
61
+	 * in this format:
62
+	 * array(
63
+	 * 'post_type_slug' => 'edit_route'
64
+	 * )
65
+	 *
66
+	 * @var array
67
+	 */
68
+	protected $_cpt_edit_routes = array();
69
+
70
+
71
+	/**
72
+	 * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
73
+	 * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
74
+	 * _cpt_model_names property should be in the following format: array(
75
+	 * 'route_defined_by_action_param' => 'Model_Name')
76
+	 *
77
+	 * @var array $_cpt_model_names
78
+	 */
79
+	protected $_cpt_model_names = array();
80
+
81
+
82
+	/**
83
+	 * @var EE_CPT_Base
84
+	 */
85
+	protected $_cpt_model_obj = false;
86
+
87
+
88
+	/**
89
+	 * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
90
+	 * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
91
+	 * the _register_autosave_containers() method so that we don't override any other containers already registered.
92
+	 * Registration of containers should be done before load_page_dependencies() is run.
93
+	 *
94
+	 * @var array()
95
+	 */
96
+	protected $_autosave_containers = array();
97
+	protected $_autosave_fields = array();
98
+
99
+	/**
100
+	 * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
101
+	 * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
102
+	 *
103
+	 * @var array
104
+	 */
105
+	protected $_pagenow_map;
106
+
107
+
108
+	/**
109
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
110
+	 * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
111
+	 * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
112
+	 * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
113
+	 * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
114
+	 *
115
+	 * @access protected
116
+	 * @abstract
117
+	 * @param  string      $post_id The ID of the cpt that was saved (so you can link relationally)
118
+	 * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
119
+	 * @return void
120
+	 */
121
+	abstract protected function _insert_update_cpt_item($post_id, $post);
122
+
123
+
124
+	/**
125
+	 * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
126
+	 *
127
+	 * @abstract
128
+	 * @access public
129
+	 * @param  string $post_id The ID of the cpt that was trashed
130
+	 * @return void
131
+	 */
132
+	abstract public function trash_cpt_item($post_id);
133
+
134
+
135
+	/**
136
+	 * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
137
+	 *
138
+	 * @param  string $post_id theID of the cpt that was untrashed
139
+	 * @return void
140
+	 */
141
+	abstract public function restore_cpt_item($post_id);
142
+
143
+
144
+	/**
145
+	 * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
146
+	 * from the db
147
+	 *
148
+	 * @param  string $post_id the ID of the cpt that was deleted
149
+	 * @return void
150
+	 */
151
+	abstract public function delete_cpt_item($post_id);
152
+
153
+
154
+	/**
155
+	 * Just utilizing the method EE_Admin exposes for doing things before page setup.
156
+	 *
157
+	 * @access protected
158
+	 * @return void
159
+	 */
160
+	protected function _before_page_setup()
161
+	{
162
+		$page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
163
+		$this->_cpt_routes = array_merge(
164
+			array(
165
+				'create_new' => $this->page_slug,
166
+				'edit'       => $this->page_slug,
167
+				'trash'      => $this->page_slug,
168
+			),
169
+			$this->_cpt_routes
170
+		);
171
+		// let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
172
+		$this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
173
+			? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
174
+			: get_post_type_object($page);
175
+		// tweak pagenow for page loading.
176
+		if (! $this->_pagenow_map) {
177
+			$this->_pagenow_map = array(
178
+				'create_new' => 'post-new.php',
179
+				'edit'       => 'post.php',
180
+				'trash'      => 'post.php',
181
+			);
182
+		}
183
+		add_action('current_screen', array($this, 'modify_pagenow'));
184
+		// TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
185
+		// get current page from autosave
186
+		$current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
187
+			? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
188
+			: null;
189
+		$this->_current_page = isset($this->_req_data['current_page'])
190
+			? $this->_req_data['current_page']
191
+			: $current_page;
192
+		// autosave... make sure its only for the correct page
193
+		// if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
194
+		// setup autosave ajax hook
195
+		// add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
196
+		// }
197
+	}
198
+
199
+
200
+	/**
201
+	 * Simply ensure that we simulate the correct post route for cpt screens
202
+	 *
203
+	 * @param WP_Screen $current_screen
204
+	 * @return void
205
+	 */
206
+	public function modify_pagenow($current_screen)
207
+	{
208
+		global $pagenow, $hook_suffix;
209
+		// possibly reset pagenow.
210
+		if (! empty($this->_req_data['page'])
211
+			&& $this->_req_data['page'] == $this->page_slug
212
+			&& ! empty($this->_req_data['action'])
213
+			&& isset($this->_pagenow_map[ $this->_req_data['action'] ])
214
+		) {
215
+			$pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
216
+			$hook_suffix = $pagenow;
217
+		}
218
+	}
219
+
220
+
221
+	/**
222
+	 * This method is used to register additional autosave containers to the _autosave_containers property.
223
+	 *
224
+	 * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
225
+	 *       automatically register the id for the post metabox as a container.
226
+	 * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
227
+	 *                    you would send along the id of a metabox container.
228
+	 * @return void
229
+	 */
230
+	protected function _register_autosave_containers($ids)
231
+	{
232
+		$this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
233
+	}
234
+
235
+
236
+	/**
237
+	 * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
238
+	 * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
239
+	 */
240
+	protected function _set_autosave_containers()
241
+	{
242
+		global $wp_meta_boxes;
243
+		$containers = array();
244
+		if (empty($wp_meta_boxes)) {
245
+			return;
246
+		}
247
+		$current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
248
+		foreach ($current_metaboxes as $box_context) {
249
+			foreach ($box_context as $box_details) {
250
+				foreach ($box_details as $box) {
251
+					if (is_array($box['callback'])
252
+						&& (
253
+							$box['callback'][0] instanceof EE_Admin_Page
254
+							|| $box['callback'][0] instanceof EE_Admin_Hooks
255
+						)
256
+					) {
257
+						$containers[] = $box['id'];
258
+					}
259
+				}
260
+			}
261
+		}
262
+		$this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
263
+		// add hidden inputs container
264
+		$this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
265
+	}
266
+
267
+
268
+	protected function _load_autosave_scripts_styles()
269
+	{
270
+		/*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
271 271
         wp_enqueue_script('cpt-autosave');/**/ // todo re-enable when we start doing autosave again in 4.2
272 272
 
273
-        // filter _autosave_containers
274
-        $containers = apply_filters(
275
-            'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
276
-            $this->_autosave_containers,
277
-            $this
278
-        );
279
-        $containers = apply_filters(
280
-            'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
281
-            $containers,
282
-            $this
283
-        );
284
-
285
-        wp_localize_script(
286
-            'event_editor_js',
287
-            'EE_AUTOSAVE_IDS',
288
-            $containers
289
-        ); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
290
-
291
-        $unsaved_data_msg = array(
292
-            'eventmsg'     => sprintf(
293
-                __(
294
-                    "The changes you made to this %s will be lost if you navigate away from this page.",
295
-                    'event_espresso'
296
-                ),
297
-                $this->_cpt_object->labels->singular_name
298
-            ),
299
-            'inputChanged' => 0,
300
-        );
301
-        wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
302
-    }
303
-
304
-
305
-    public function load_page_dependencies()
306
-    {
307
-        try {
308
-            $this->_load_page_dependencies();
309
-        } catch (EE_Error $e) {
310
-            $e->get_error();
311
-        }
312
-    }
313
-
314
-
315
-    /**
316
-     * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
317
-     *
318
-     * @access protected
319
-     * @return void
320
-     */
321
-    protected function _load_page_dependencies()
322
-    {
323
-        // we only add stuff if this is a cpt_route!
324
-        if (! $this->_cpt_route) {
325
-            parent::_load_page_dependencies();
326
-            return;
327
-        }
328
-        // now let's do some automatic filters into the wp_system
329
-        // and we'll check to make sure the CHILD class
330
-        // automatically has the required methods in place.
331
-        // the following filters are for setting all the redirects
332
-        // on DEFAULT WP custom post type actions
333
-        // let's add a hidden input to the post-edit form
334
-        // so we know when we have to trigger our custom redirects!
335
-        // Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
336
-        add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
337
-        // inject our Admin page nav tabs...
338
-        // let's make sure the nav tabs are set if they aren't already
339
-        // if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
340
-        add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
341
-        // modify the post_updated messages array
342
-        add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
343
-        // add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
344
-        // cpts use the same format for shortlinks as posts!
345
-        add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
346
-        // This basically allows us to change the title of the "publish" metabox area
347
-        // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
348
-        if (! empty($this->_labels['publishbox'])) {
349
-            $box_label = is_array($this->_labels['publishbox'])
350
-                         && isset($this->_labels['publishbox'][ $this->_req_action ])
351
-                ? $this->_labels['publishbox'][ $this->_req_action ]
352
-                : $this->_labels['publishbox'];
353
-            add_meta_box(
354
-                'submitdiv',
355
-                $box_label,
356
-                'post_submit_meta_box',
357
-                $this->_cpt_routes[ $this->_req_action ],
358
-                'side',
359
-                'core'
360
-            );
361
-        }
362
-        // let's add page_templates metabox if this cpt added support for it.
363
-        if ($this->_supports_page_templates($this->_cpt_object->name)) {
364
-            add_meta_box(
365
-                'page_templates',
366
-                __('Page Template', 'event_espresso'),
367
-                array($this, 'page_template_meta_box'),
368
-                $this->_cpt_routes[ $this->_req_action ],
369
-                'side',
370
-                'default'
371
-            );
372
-        }
373
-        // this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
374
-        if (method_exists($this, 'extra_permalink_field_buttons')) {
375
-            add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
376
-        }
377
-        // add preview button
378
-        add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
379
-        // insert our own post_stati dropdown
380
-        add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
381
-        // This allows adding additional information to the publish post submitbox on the wp post edit form
382
-        if (method_exists($this, 'extra_misc_actions_publish_box')) {
383
-            add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
384
-        }
385
-        // This allows for adding additional stuff after the title field on the wp post edit form.
386
-        // This is also before the wp_editor for post description field.
387
-        if (method_exists($this, 'edit_form_after_title')) {
388
-            add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
389
-        }
390
-        /**
391
-         * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
392
-         */
393
-        add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
394
-        parent::_load_page_dependencies();
395
-        // notice we are ALSO going to load the pagenow hook set for this route
396
-        // (see _before_page_setup for the reset of the pagenow global ).
397
-        // This is for any plugins that are doing things properly
398
-        // and hooking into the load page hook for core wp cpt routes.
399
-        global $pagenow;
400
-        add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
401
-        do_action('load-' . $pagenow);
402
-        add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
403
-        // we route REALLY early.
404
-        try {
405
-            $this->_route_admin_request();
406
-        } catch (EE_Error $e) {
407
-            $e->get_error();
408
-        }
409
-    }
410
-
411
-
412
-    /**
413
-     * Since we don't want users going to default core wp routes, this will check any wp urls run through the
414
-     * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
415
-     * route instead.
416
-     *
417
-     * @param string $good_protocol_url The escaped url.
418
-     * @param string $original_url      The original url.
419
-     * @param string $_context          The context sent to the esc_url method.
420
-     * @return string possibly a new url for our route.
421
-     */
422
-    public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
423
-    {
424
-        $routes_to_match = array(
425
-            0 => array(
426
-                'edit.php?post_type=espresso_attendees',
427
-                'admin.php?page=espresso_registrations&action=contact_list',
428
-            ),
429
-            1 => array(
430
-                'edit.php?post_type=' . $this->_cpt_object->name,
431
-                'admin.php?page=' . $this->_cpt_object->name,
432
-            ),
433
-        );
434
-        foreach ($routes_to_match as $route_matches) {
435
-            if (strpos($good_protocol_url, $route_matches[0]) !== false) {
436
-                return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
437
-            }
438
-        }
439
-        return $good_protocol_url;
440
-    }
441
-
442
-
443
-    /**
444
-     * Determine whether the current cpt supports page templates or not.
445
-     *
446
-     * @since %VER%
447
-     * @param string $cpt_name The cpt slug we're checking on.
448
-     * @return bool True supported, false not.
449
-     * @throws InvalidArgumentException
450
-     * @throws InvalidDataTypeException
451
-     * @throws InvalidInterfaceException
452
-     */
453
-    private function _supports_page_templates($cpt_name)
454
-    {
455
-        /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
456
-        $custom_post_types = $this->loader->getShared(
457
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
458
-        );
459
-        $cpt_args = $custom_post_types->getDefinitions();
460
-        $cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
461
-        $cpt_has_support = ! empty($cpt_args['page_templates']);
462
-
463
-        // if the installed version of WP is > 4.7 we do some additional checks.
464
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
465
-            $post_templates = wp_get_theme()->get_post_templates();
466
-            // if there are $post_templates for this cpt, then we return false for this method because
467
-            // that means we aren't going to load our page template manager and leave that up to the native
468
-            // cpt template manager.
469
-            $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
470
-        }
471
-
472
-        return $cpt_has_support;
473
-    }
474
-
475
-
476
-    /**
477
-     * Callback for the page_templates metabox selector.
478
-     *
479
-     * @since %VER%
480
-     * @return void
481
-     */
482
-    public function page_template_meta_box()
483
-    {
484
-        global $post;
485
-        $template = '';
486
-
487
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
488
-            $page_template_count = count(get_page_templates());
489
-        } else {
490
-            $page_template_count = count(get_page_templates($post));
491
-        };
492
-
493
-        if ($page_template_count) {
494
-            $page_template = get_post_meta($post->ID, '_wp_page_template', true);
495
-            $template = ! empty($page_template) ? $page_template : '';
496
-        }
497
-        ?>
273
+		// filter _autosave_containers
274
+		$containers = apply_filters(
275
+			'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
276
+			$this->_autosave_containers,
277
+			$this
278
+		);
279
+		$containers = apply_filters(
280
+			'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
281
+			$containers,
282
+			$this
283
+		);
284
+
285
+		wp_localize_script(
286
+			'event_editor_js',
287
+			'EE_AUTOSAVE_IDS',
288
+			$containers
289
+		); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
290
+
291
+		$unsaved_data_msg = array(
292
+			'eventmsg'     => sprintf(
293
+				__(
294
+					"The changes you made to this %s will be lost if you navigate away from this page.",
295
+					'event_espresso'
296
+				),
297
+				$this->_cpt_object->labels->singular_name
298
+			),
299
+			'inputChanged' => 0,
300
+		);
301
+		wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
302
+	}
303
+
304
+
305
+	public function load_page_dependencies()
306
+	{
307
+		try {
308
+			$this->_load_page_dependencies();
309
+		} catch (EE_Error $e) {
310
+			$e->get_error();
311
+		}
312
+	}
313
+
314
+
315
+	/**
316
+	 * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
317
+	 *
318
+	 * @access protected
319
+	 * @return void
320
+	 */
321
+	protected function _load_page_dependencies()
322
+	{
323
+		// we only add stuff if this is a cpt_route!
324
+		if (! $this->_cpt_route) {
325
+			parent::_load_page_dependencies();
326
+			return;
327
+		}
328
+		// now let's do some automatic filters into the wp_system
329
+		// and we'll check to make sure the CHILD class
330
+		// automatically has the required methods in place.
331
+		// the following filters are for setting all the redirects
332
+		// on DEFAULT WP custom post type actions
333
+		// let's add a hidden input to the post-edit form
334
+		// so we know when we have to trigger our custom redirects!
335
+		// Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
336
+		add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
337
+		// inject our Admin page nav tabs...
338
+		// let's make sure the nav tabs are set if they aren't already
339
+		// if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
340
+		add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
341
+		// modify the post_updated messages array
342
+		add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
343
+		// add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
344
+		// cpts use the same format for shortlinks as posts!
345
+		add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
346
+		// This basically allows us to change the title of the "publish" metabox area
347
+		// on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
348
+		if (! empty($this->_labels['publishbox'])) {
349
+			$box_label = is_array($this->_labels['publishbox'])
350
+						 && isset($this->_labels['publishbox'][ $this->_req_action ])
351
+				? $this->_labels['publishbox'][ $this->_req_action ]
352
+				: $this->_labels['publishbox'];
353
+			add_meta_box(
354
+				'submitdiv',
355
+				$box_label,
356
+				'post_submit_meta_box',
357
+				$this->_cpt_routes[ $this->_req_action ],
358
+				'side',
359
+				'core'
360
+			);
361
+		}
362
+		// let's add page_templates metabox if this cpt added support for it.
363
+		if ($this->_supports_page_templates($this->_cpt_object->name)) {
364
+			add_meta_box(
365
+				'page_templates',
366
+				__('Page Template', 'event_espresso'),
367
+				array($this, 'page_template_meta_box'),
368
+				$this->_cpt_routes[ $this->_req_action ],
369
+				'side',
370
+				'default'
371
+			);
372
+		}
373
+		// this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
374
+		if (method_exists($this, 'extra_permalink_field_buttons')) {
375
+			add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
376
+		}
377
+		// add preview button
378
+		add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
379
+		// insert our own post_stati dropdown
380
+		add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
381
+		// This allows adding additional information to the publish post submitbox on the wp post edit form
382
+		if (method_exists($this, 'extra_misc_actions_publish_box')) {
383
+			add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
384
+		}
385
+		// This allows for adding additional stuff after the title field on the wp post edit form.
386
+		// This is also before the wp_editor for post description field.
387
+		if (method_exists($this, 'edit_form_after_title')) {
388
+			add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
389
+		}
390
+		/**
391
+		 * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
392
+		 */
393
+		add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
394
+		parent::_load_page_dependencies();
395
+		// notice we are ALSO going to load the pagenow hook set for this route
396
+		// (see _before_page_setup for the reset of the pagenow global ).
397
+		// This is for any plugins that are doing things properly
398
+		// and hooking into the load page hook for core wp cpt routes.
399
+		global $pagenow;
400
+		add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
401
+		do_action('load-' . $pagenow);
402
+		add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
403
+		// we route REALLY early.
404
+		try {
405
+			$this->_route_admin_request();
406
+		} catch (EE_Error $e) {
407
+			$e->get_error();
408
+		}
409
+	}
410
+
411
+
412
+	/**
413
+	 * Since we don't want users going to default core wp routes, this will check any wp urls run through the
414
+	 * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
415
+	 * route instead.
416
+	 *
417
+	 * @param string $good_protocol_url The escaped url.
418
+	 * @param string $original_url      The original url.
419
+	 * @param string $_context          The context sent to the esc_url method.
420
+	 * @return string possibly a new url for our route.
421
+	 */
422
+	public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
423
+	{
424
+		$routes_to_match = array(
425
+			0 => array(
426
+				'edit.php?post_type=espresso_attendees',
427
+				'admin.php?page=espresso_registrations&action=contact_list',
428
+			),
429
+			1 => array(
430
+				'edit.php?post_type=' . $this->_cpt_object->name,
431
+				'admin.php?page=' . $this->_cpt_object->name,
432
+			),
433
+		);
434
+		foreach ($routes_to_match as $route_matches) {
435
+			if (strpos($good_protocol_url, $route_matches[0]) !== false) {
436
+				return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
437
+			}
438
+		}
439
+		return $good_protocol_url;
440
+	}
441
+
442
+
443
+	/**
444
+	 * Determine whether the current cpt supports page templates or not.
445
+	 *
446
+	 * @since %VER%
447
+	 * @param string $cpt_name The cpt slug we're checking on.
448
+	 * @return bool True supported, false not.
449
+	 * @throws InvalidArgumentException
450
+	 * @throws InvalidDataTypeException
451
+	 * @throws InvalidInterfaceException
452
+	 */
453
+	private function _supports_page_templates($cpt_name)
454
+	{
455
+		/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
456
+		$custom_post_types = $this->loader->getShared(
457
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
458
+		);
459
+		$cpt_args = $custom_post_types->getDefinitions();
460
+		$cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
461
+		$cpt_has_support = ! empty($cpt_args['page_templates']);
462
+
463
+		// if the installed version of WP is > 4.7 we do some additional checks.
464
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
465
+			$post_templates = wp_get_theme()->get_post_templates();
466
+			// if there are $post_templates for this cpt, then we return false for this method because
467
+			// that means we aren't going to load our page template manager and leave that up to the native
468
+			// cpt template manager.
469
+			$cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
470
+		}
471
+
472
+		return $cpt_has_support;
473
+	}
474
+
475
+
476
+	/**
477
+	 * Callback for the page_templates metabox selector.
478
+	 *
479
+	 * @since %VER%
480
+	 * @return void
481
+	 */
482
+	public function page_template_meta_box()
483
+	{
484
+		global $post;
485
+		$template = '';
486
+
487
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
488
+			$page_template_count = count(get_page_templates());
489
+		} else {
490
+			$page_template_count = count(get_page_templates($post));
491
+		};
492
+
493
+		if ($page_template_count) {
494
+			$page_template = get_post_meta($post->ID, '_wp_page_template', true);
495
+			$template = ! empty($page_template) ? $page_template : '';
496
+		}
497
+		?>
498 498
         <p><strong><?php _e('Template', 'event_espresso') ?></strong></p>
499 499
         <label class="screen-reader-text" for="page_template"><?php _e('Page Template', 'event_espresso') ?></label><select
500 500
         name="page_template" id="page_template">
@@ -502,507 +502,507 @@  discard block
 block discarded – undo
502 502
         <?php page_template_dropdown($template); ?>
503 503
     </select>
504 504
         <?php
505
-    }
506
-
507
-
508
-    /**
509
-     * if this post is a draft or scheduled post then we provide a preview button for user to click
510
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
511
-     *
512
-     * @param  string $return    the current html
513
-     * @param  int    $id        the post id for the page
514
-     * @param  string $new_title What the title is
515
-     * @param  string $new_slug  what the slug is
516
-     * @return string            The new html string for the permalink area
517
-     */
518
-    public function preview_button_html($return, $id, $new_title, $new_slug)
519
-    {
520
-        $post = get_post($id);
521
-        if ('publish' !== get_post_status($post)) {
522
-            $return .= '<span_id="view-post-btn"><a target="_blank" href="'
523
-                       . get_preview_post_link($id)
524
-                       . '" class="button button-small">'
525
-                       . __('Preview', 'event_espresso')
526
-                       . '</a></span>'
527
-                       . "\n";
528
-        }
529
-        return $return;
530
-    }
531
-
532
-
533
-    /**
534
-     * add our custom post stati dropdown on the wp post page for this cpt
535
-     *
536
-     * @return void
537
-     */
538
-    public function custom_post_stati_dropdown()
539
-    {
540
-
541
-        $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
542
-        $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
543
-            ? $statuses[ $this->_cpt_model_obj->status() ]
544
-            : '';
545
-        $template_args = array(
546
-            'cur_status'            => $this->_cpt_model_obj->status(),
547
-            'statuses'              => $statuses,
548
-            'cur_status_label'      => $cur_status_label,
549
-            'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
550
-        );
551
-        // we'll add a trash post status (WP doesn't add one for some reason)
552
-        if ($this->_cpt_model_obj->status() === 'trash') {
553
-            $template_args['cur_status_label'] = __('Trashed', 'event_espresso');
554
-            $statuses['trash'] = __('Trashed', 'event_espresso');
555
-            $template_args['statuses'] = $statuses;
556
-        }
557
-
558
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
559
-        EEH_Template::display_template($template, $template_args);
560
-    }
561
-
562
-
563
-    public function setup_autosave_hooks()
564
-    {
565
-        $this->_set_autosave_containers();
566
-        $this->_load_autosave_scripts_styles();
567
-    }
568
-
569
-
570
-    /**
571
-     * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
572
-     * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
573
-     * for the nonce in here, but then this method looks for two things:
574
-     * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
575
-     * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
576
-     * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
577
-     * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
578
-     * template args.
579
-     *    1. $template_args['error'] = IF there is an error you can add the message in here.
580
-     *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
581
-     *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
582
-     *    $this->_template_args['data']['items'] = array(
583
-     *        'event-datetime-ids' => '1,2,3';
584
-     *    );
585
-     *    Keep in mind the following things:
586
-     *    - "where" index is for the input with the id as that string.
587
-     *    - "what" index is what will be used for the value of that input.
588
-     *
589
-     * @return void
590
-     */
591
-    public function do_extra_autosave_stuff()
592
-    {
593
-        // next let's check for the autosave nonce (we'll use _verify_nonce )
594
-        $nonce = isset($this->_req_data['autosavenonce'])
595
-            ? $this->_req_data['autosavenonce']
596
-            : null;
597
-        $this->_verify_nonce($nonce, 'autosave');
598
-        // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
599
-        if (! defined('DOING_AUTOSAVE')) {
600
-            define('DOING_AUTOSAVE', true);
601
-        }
602
-        // if we made it here then the nonce checked out.  Let's run our methods and actions
603
-        $autosave = "_ee_autosave_{$this->_current_view}";
604
-        if (method_exists($this, $autosave)) {
605
-            $this->$autosave();
606
-        } else {
607
-            $this->_template_args['success'] = true;
608
-        }
609
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
610
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
611
-        // now let's return json
612
-        $this->_return_json();
613
-    }
614
-
615
-
616
-    /**
617
-     * This takes care of setting up default routes and pages that utilize the core WP admin pages.
618
-     * Child classes can override the defaults (in cases for adding metaboxes etc.)
619
-     * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
620
-     *
621
-     * @access protected
622
-     * @throws EE_Error
623
-     * @return void
624
-     */
625
-    protected function _extend_page_config_for_cpt()
626
-    {
627
-        // before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
628
-        if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
629
-            return;
630
-        }
631
-        // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
632
-        if (! empty($this->_cpt_object)) {
633
-            $this->_page_routes = array_merge(
634
-                array(
635
-                    'create_new' => '_create_new_cpt_item',
636
-                    'edit'       => '_edit_cpt_item',
637
-                ),
638
-                $this->_page_routes
639
-            );
640
-            $this->_page_config = array_merge(
641
-                array(
642
-                    'create_new' => array(
643
-                        'nav'           => array(
644
-                            'label' => $this->_cpt_object->labels->add_new_item,
645
-                            'order' => 5,
646
-                        ),
647
-                        'require_nonce' => false,
648
-                    ),
649
-                    'edit'       => array(
650
-                        'nav'           => array(
651
-                            'label'      => $this->_cpt_object->labels->edit_item,
652
-                            'order'      => 5,
653
-                            'persistent' => false,
654
-                            'url'        => '',
655
-                        ),
656
-                        'require_nonce' => false,
657
-                    ),
658
-                ),
659
-                $this->_page_config
660
-            );
661
-        }
662
-        // load the next section only if this is a matching cpt route as set in the cpt routes array.
663
-        if (! isset($this->_cpt_routes[ $this->_req_action ])) {
664
-            return;
665
-        }
666
-        $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
667
-        // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
668
-        if (empty($this->_cpt_object)) {
669
-            $msg = sprintf(
670
-                __(
671
-                    'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
672
-                    'event_espresso'
673
-                ),
674
-                $this->page_slug,
675
-                $this->_req_action,
676
-                get_class($this)
677
-            );
678
-            throw new EE_Error($msg);
679
-        }
680
-        if ($this->_cpt_route) {
681
-            $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
682
-            $this->_set_model_object($id);
683
-        }
684
-    }
685
-
686
-
687
-    /**
688
-     * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
689
-     *
690
-     * @access protected
691
-     * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
692
-     * @param bool   $ignore_route_check
693
-     * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
694
-     * @throws EE_Error
695
-     * @throws InvalidArgumentException
696
-     * @throws InvalidDataTypeException
697
-     * @throws InvalidInterfaceException
698
-     * @throws ReflectionException
699
-     */
700
-    protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
701
-    {
702
-        $model = null;
703
-        if (empty($this->_cpt_model_names)
704
-            || (
705
-                ! $ignore_route_check
706
-                && ! isset($this->_cpt_routes[ $this->_req_action ])
707
-            ) || (
708
-                $this->_cpt_model_obj instanceof EE_CPT_Base
709
-                && $this->_cpt_model_obj->ID() === $id
710
-            )
711
-        ) {
712
-            // get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
713
-            return;
714
-        }
715
-        // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
716
-        if ($ignore_route_check) {
717
-            $post_type = get_post_type($id);
718
-            /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
719
-            $custom_post_types = $this->loader->getShared(
720
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
721
-            );
722
-            $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
723
-            if (isset($model_names[ $post_type ])) {
724
-                $model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
725
-            }
726
-        } else {
727
-            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
728
-        }
729
-        if ($model instanceof EEM_Base) {
730
-            $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
731
-        }
732
-        do_action(
733
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
734
-            $this->_cpt_model_obj,
735
-            $req_type
736
-        );
737
-    }
738
-
739
-
740
-    /**
741
-     * admin_init_global
742
-     * This runs all the code that we want executed within the WP admin_init hook.
743
-     * This method executes for ALL EE Admin pages.
744
-     *
745
-     * @access public
746
-     * @return void
747
-     */
748
-    public function admin_init_global()
749
-    {
750
-        $post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
751
-        // its possible this is a new save so let's catch that instead
752
-        $post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
753
-        $post_type = $post ? $post->post_type : false;
754
-        $current_route = isset($this->_req_data['current_route'])
755
-            ? $this->_req_data['current_route']
756
-            : 'shouldneverwork';
757
-        $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
758
-            ? $this->_cpt_routes[ $current_route ]
759
-            : '';
760
-        add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
761
-        add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
762
-        if ($post_type === $route_to_check) {
763
-            add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
764
-        }
765
-        // now let's filter redirect if we're on a revision page and the revision is for an event CPT.
766
-        $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
767
-        if (! empty($revision)) {
768
-            $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
769
-            // doing a restore?
770
-            if (! empty($action) && $action === 'restore') {
771
-                // get post for revision
772
-                $rev_post = get_post($revision);
773
-                $rev_parent = get_post($rev_post->post_parent);
774
-                // only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
775
-                if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
776
-                    add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
777
-                    // restores of revisions
778
-                    add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
779
-                }
780
-            }
781
-        }
782
-        // NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
783
-        if ($post_type && $post_type === $route_to_check) {
784
-            // $post_id, $post
785
-            add_action('save_post', array($this, 'insert_update'), 10, 3);
786
-            // $post_id
787
-            add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
788
-            add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
789
-            add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
790
-            add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
791
-        }
792
-    }
793
-
794
-
795
-    /**
796
-     * Callback for the WordPress trashed_post hook.
797
-     * Execute some basic checks before calling the trash_cpt_item declared in the child class.
798
-     *
799
-     * @param int $post_id
800
-     * @throws \EE_Error
801
-     */
802
-    public function before_trash_cpt_item($post_id)
803
-    {
804
-        $this->_set_model_object($post_id, true, 'trash');
805
-        // if our cpt object isn't existent then get out immediately.
806
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
807
-            return;
808
-        }
809
-        $this->trash_cpt_item($post_id);
810
-    }
811
-
812
-
813
-    /**
814
-     * Callback for the WordPress untrashed_post hook.
815
-     * Execute some basic checks before calling the restore_cpt_method in the child class.
816
-     *
817
-     * @param $post_id
818
-     * @throws \EE_Error
819
-     */
820
-    public function before_restore_cpt_item($post_id)
821
-    {
822
-        $this->_set_model_object($post_id, true, 'restore');
823
-        // if our cpt object isn't existent then get out immediately.
824
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
825
-            return;
826
-        }
827
-        $this->restore_cpt_item($post_id);
828
-    }
829
-
830
-
831
-    /**
832
-     * Callback for the WordPress after_delete_post hook.
833
-     * Execute some basic checks before calling the delete_cpt_item method in the child class.
834
-     *
835
-     * @param $post_id
836
-     * @throws \EE_Error
837
-     */
838
-    public function before_delete_cpt_item($post_id)
839
-    {
840
-        $this->_set_model_object($post_id, true, 'delete');
841
-        // if our cpt object isn't existent then get out immediately.
842
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
843
-            return;
844
-        }
845
-        $this->delete_cpt_item($post_id);
846
-    }
847
-
848
-
849
-    /**
850
-     * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
851
-     * accordingly.
852
-     *
853
-     * @return void
854
-     * @throws EE_Error
855
-     * @throws InvalidArgumentException
856
-     * @throws InvalidDataTypeException
857
-     * @throws InvalidInterfaceException
858
-     * @throws ReflectionException
859
-     */
860
-    public function verify_cpt_object()
861
-    {
862
-        $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
863
-        // verify event object
864
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
865
-            throw new EE_Error(
866
-                sprintf(
867
-                    __(
868
-                        'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
869
-                        'event_espresso'
870
-                    ),
871
-                    $label
872
-                )
873
-            );
874
-        }
875
-        // if auto-draft then throw an error
876
-        if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
877
-            EE_Error::overwrite_errors();
878
-            EE_Error::add_error(
879
-                sprintf(
880
-                    __(
881
-                        'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
882
-                        'event_espresso'
883
-                    ),
884
-                    $label
885
-                ),
886
-                __FILE__,
887
-                __FUNCTION__,
888
-                __LINE__
889
-            );
890
-        }
891
-        $this->loadEspressoEditorAssetManager();
892
-    }
893
-
894
-
895
-    /**
896
-     * admin_footer_scripts_global
897
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
898
-     * will apply on ALL EE_Admin pages.
899
-     *
900
-     * @access public
901
-     * @return void
902
-     */
903
-    public function admin_footer_scripts_global()
904
-    {
905
-        $this->_add_admin_page_ajax_loading_img();
906
-        $this->_add_admin_page_overlay();
907
-    }
908
-
909
-
910
-    /**
911
-     * add in any global scripts for cpt routes
912
-     *
913
-     * @return void
914
-     */
915
-    public function load_global_scripts_styles()
916
-    {
917
-        parent::load_global_scripts_styles();
918
-        if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
919
-            // setup custom post status object for localize script but only if we've got a cpt object
920
-            $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
921
-            if (! empty($statuses)) {
922
-                // get ALL statuses!
923
-                $statuses = $this->_cpt_model_obj->get_all_post_statuses();
924
-                // setup object
925
-                $ee_cpt_statuses = array();
926
-                foreach ($statuses as $status => $label) {
927
-                    $ee_cpt_statuses[ $status ] = array(
928
-                        'label'      => $label,
929
-                        'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label),
930
-                    );
931
-                }
932
-                wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
933
-            }
934
-        }
935
-    }
936
-
937
-
938
-    /**
939
-     * @throws InvalidArgumentException
940
-     * @throws InvalidDataTypeException
941
-     * @throws InvalidInterfaceException
942
-     */
943
-    private function loadEspressoEditorAssetManager()
944
-    {
945
-        EE_Dependency_Map::register_dependencies(
946
-            'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager',
947
-            array(
948
-                'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
949
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
950
-                'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
951
-            )
952
-        );
953
-        $this->loader->getShared(
954
-            'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager'
955
-        );
956
-        add_action('admin_enqueue_scripts', array($this, 'enqueueEspressoEditorAssets'), 100);
957
-    }
958
-
959
-
960
-    /**
961
-     * enqueue_scripts - Load the scripts and css
962
-     *
963
-     * @return void
964
-     * @throws DomainException
965
-     */
966
-    public function enqueueEspressoEditorAssets()
967
-    {
968
-        wp_enqueue_style(EspressoEditorAssetManager::CSS_HANDLE_EDITOR);
969
-        wp_enqueue_script(EspressoEditorAssetManager::JS_HANDLE_EDITOR);
970
-    }
971
-
972
-
973
-    /**
974
-     * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
975
-     * insert/updates
976
-     *
977
-     * @param  int     $post_id ID of post being updated
978
-     * @param  WP_Post $post    Post object from WP
979
-     * @param  bool    $update  Whether this is an update or a new save.
980
-     * @return void
981
-     * @throws \EE_Error
982
-     */
983
-    public function insert_update($post_id, $post, $update)
984
-    {
985
-        // make sure that if this is a revision OR trash action that we don't do any updates!
986
-        if (isset($this->_req_data['action'])
987
-            && (
988
-                $this->_req_data['action'] === 'restore'
989
-                || $this->_req_data['action'] === 'trash'
990
-            )
991
-        ) {
992
-            return;
993
-        }
994
-        $this->_set_model_object($post_id, true, 'insert_update');
995
-        // if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
996
-        if ($update
997
-            && (
998
-                ! $this->_cpt_model_obj instanceof EE_CPT_Base
999
-                || $this->_cpt_model_obj->ID() !== $post_id
1000
-            )
1001
-        ) {
1002
-            return;
1003
-        }
1004
-        // check for autosave and update our req_data property accordingly.
1005
-        /*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
505
+	}
506
+
507
+
508
+	/**
509
+	 * if this post is a draft or scheduled post then we provide a preview button for user to click
510
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
511
+	 *
512
+	 * @param  string $return    the current html
513
+	 * @param  int    $id        the post id for the page
514
+	 * @param  string $new_title What the title is
515
+	 * @param  string $new_slug  what the slug is
516
+	 * @return string            The new html string for the permalink area
517
+	 */
518
+	public function preview_button_html($return, $id, $new_title, $new_slug)
519
+	{
520
+		$post = get_post($id);
521
+		if ('publish' !== get_post_status($post)) {
522
+			$return .= '<span_id="view-post-btn"><a target="_blank" href="'
523
+					   . get_preview_post_link($id)
524
+					   . '" class="button button-small">'
525
+					   . __('Preview', 'event_espresso')
526
+					   . '</a></span>'
527
+					   . "\n";
528
+		}
529
+		return $return;
530
+	}
531
+
532
+
533
+	/**
534
+	 * add our custom post stati dropdown on the wp post page for this cpt
535
+	 *
536
+	 * @return void
537
+	 */
538
+	public function custom_post_stati_dropdown()
539
+	{
540
+
541
+		$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
542
+		$cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
543
+			? $statuses[ $this->_cpt_model_obj->status() ]
544
+			: '';
545
+		$template_args = array(
546
+			'cur_status'            => $this->_cpt_model_obj->status(),
547
+			'statuses'              => $statuses,
548
+			'cur_status_label'      => $cur_status_label,
549
+			'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
550
+		);
551
+		// we'll add a trash post status (WP doesn't add one for some reason)
552
+		if ($this->_cpt_model_obj->status() === 'trash') {
553
+			$template_args['cur_status_label'] = __('Trashed', 'event_espresso');
554
+			$statuses['trash'] = __('Trashed', 'event_espresso');
555
+			$template_args['statuses'] = $statuses;
556
+		}
557
+
558
+		$template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
559
+		EEH_Template::display_template($template, $template_args);
560
+	}
561
+
562
+
563
+	public function setup_autosave_hooks()
564
+	{
565
+		$this->_set_autosave_containers();
566
+		$this->_load_autosave_scripts_styles();
567
+	}
568
+
569
+
570
+	/**
571
+	 * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
572
+	 * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
573
+	 * for the nonce in here, but then this method looks for two things:
574
+	 * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
575
+	 * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
576
+	 * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
577
+	 * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
578
+	 * template args.
579
+	 *    1. $template_args['error'] = IF there is an error you can add the message in here.
580
+	 *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
581
+	 *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
582
+	 *    $this->_template_args['data']['items'] = array(
583
+	 *        'event-datetime-ids' => '1,2,3';
584
+	 *    );
585
+	 *    Keep in mind the following things:
586
+	 *    - "where" index is for the input with the id as that string.
587
+	 *    - "what" index is what will be used for the value of that input.
588
+	 *
589
+	 * @return void
590
+	 */
591
+	public function do_extra_autosave_stuff()
592
+	{
593
+		// next let's check for the autosave nonce (we'll use _verify_nonce )
594
+		$nonce = isset($this->_req_data['autosavenonce'])
595
+			? $this->_req_data['autosavenonce']
596
+			: null;
597
+		$this->_verify_nonce($nonce, 'autosave');
598
+		// make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
599
+		if (! defined('DOING_AUTOSAVE')) {
600
+			define('DOING_AUTOSAVE', true);
601
+		}
602
+		// if we made it here then the nonce checked out.  Let's run our methods and actions
603
+		$autosave = "_ee_autosave_{$this->_current_view}";
604
+		if (method_exists($this, $autosave)) {
605
+			$this->$autosave();
606
+		} else {
607
+			$this->_template_args['success'] = true;
608
+		}
609
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
610
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
611
+		// now let's return json
612
+		$this->_return_json();
613
+	}
614
+
615
+
616
+	/**
617
+	 * This takes care of setting up default routes and pages that utilize the core WP admin pages.
618
+	 * Child classes can override the defaults (in cases for adding metaboxes etc.)
619
+	 * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
620
+	 *
621
+	 * @access protected
622
+	 * @throws EE_Error
623
+	 * @return void
624
+	 */
625
+	protected function _extend_page_config_for_cpt()
626
+	{
627
+		// before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
628
+		if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
629
+			return;
630
+		}
631
+		// set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
632
+		if (! empty($this->_cpt_object)) {
633
+			$this->_page_routes = array_merge(
634
+				array(
635
+					'create_new' => '_create_new_cpt_item',
636
+					'edit'       => '_edit_cpt_item',
637
+				),
638
+				$this->_page_routes
639
+			);
640
+			$this->_page_config = array_merge(
641
+				array(
642
+					'create_new' => array(
643
+						'nav'           => array(
644
+							'label' => $this->_cpt_object->labels->add_new_item,
645
+							'order' => 5,
646
+						),
647
+						'require_nonce' => false,
648
+					),
649
+					'edit'       => array(
650
+						'nav'           => array(
651
+							'label'      => $this->_cpt_object->labels->edit_item,
652
+							'order'      => 5,
653
+							'persistent' => false,
654
+							'url'        => '',
655
+						),
656
+						'require_nonce' => false,
657
+					),
658
+				),
659
+				$this->_page_config
660
+			);
661
+		}
662
+		// load the next section only if this is a matching cpt route as set in the cpt routes array.
663
+		if (! isset($this->_cpt_routes[ $this->_req_action ])) {
664
+			return;
665
+		}
666
+		$this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
667
+		// add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
668
+		if (empty($this->_cpt_object)) {
669
+			$msg = sprintf(
670
+				__(
671
+					'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
672
+					'event_espresso'
673
+				),
674
+				$this->page_slug,
675
+				$this->_req_action,
676
+				get_class($this)
677
+			);
678
+			throw new EE_Error($msg);
679
+		}
680
+		if ($this->_cpt_route) {
681
+			$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
682
+			$this->_set_model_object($id);
683
+		}
684
+	}
685
+
686
+
687
+	/**
688
+	 * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
689
+	 *
690
+	 * @access protected
691
+	 * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
692
+	 * @param bool   $ignore_route_check
693
+	 * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
694
+	 * @throws EE_Error
695
+	 * @throws InvalidArgumentException
696
+	 * @throws InvalidDataTypeException
697
+	 * @throws InvalidInterfaceException
698
+	 * @throws ReflectionException
699
+	 */
700
+	protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
701
+	{
702
+		$model = null;
703
+		if (empty($this->_cpt_model_names)
704
+			|| (
705
+				! $ignore_route_check
706
+				&& ! isset($this->_cpt_routes[ $this->_req_action ])
707
+			) || (
708
+				$this->_cpt_model_obj instanceof EE_CPT_Base
709
+				&& $this->_cpt_model_obj->ID() === $id
710
+			)
711
+		) {
712
+			// get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
713
+			return;
714
+		}
715
+		// if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
716
+		if ($ignore_route_check) {
717
+			$post_type = get_post_type($id);
718
+			/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
719
+			$custom_post_types = $this->loader->getShared(
720
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
721
+			);
722
+			$model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
723
+			if (isset($model_names[ $post_type ])) {
724
+				$model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
725
+			}
726
+		} else {
727
+			$model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
728
+		}
729
+		if ($model instanceof EEM_Base) {
730
+			$this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
731
+		}
732
+		do_action(
733
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
734
+			$this->_cpt_model_obj,
735
+			$req_type
736
+		);
737
+	}
738
+
739
+
740
+	/**
741
+	 * admin_init_global
742
+	 * This runs all the code that we want executed within the WP admin_init hook.
743
+	 * This method executes for ALL EE Admin pages.
744
+	 *
745
+	 * @access public
746
+	 * @return void
747
+	 */
748
+	public function admin_init_global()
749
+	{
750
+		$post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
751
+		// its possible this is a new save so let's catch that instead
752
+		$post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
753
+		$post_type = $post ? $post->post_type : false;
754
+		$current_route = isset($this->_req_data['current_route'])
755
+			? $this->_req_data['current_route']
756
+			: 'shouldneverwork';
757
+		$route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
758
+			? $this->_cpt_routes[ $current_route ]
759
+			: '';
760
+		add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
761
+		add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
762
+		if ($post_type === $route_to_check) {
763
+			add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
764
+		}
765
+		// now let's filter redirect if we're on a revision page and the revision is for an event CPT.
766
+		$revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
767
+		if (! empty($revision)) {
768
+			$action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
769
+			// doing a restore?
770
+			if (! empty($action) && $action === 'restore') {
771
+				// get post for revision
772
+				$rev_post = get_post($revision);
773
+				$rev_parent = get_post($rev_post->post_parent);
774
+				// only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
775
+				if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
776
+					add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
777
+					// restores of revisions
778
+					add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
779
+				}
780
+			}
781
+		}
782
+		// NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
783
+		if ($post_type && $post_type === $route_to_check) {
784
+			// $post_id, $post
785
+			add_action('save_post', array($this, 'insert_update'), 10, 3);
786
+			// $post_id
787
+			add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
788
+			add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
789
+			add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
790
+			add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
791
+		}
792
+	}
793
+
794
+
795
+	/**
796
+	 * Callback for the WordPress trashed_post hook.
797
+	 * Execute some basic checks before calling the trash_cpt_item declared in the child class.
798
+	 *
799
+	 * @param int $post_id
800
+	 * @throws \EE_Error
801
+	 */
802
+	public function before_trash_cpt_item($post_id)
803
+	{
804
+		$this->_set_model_object($post_id, true, 'trash');
805
+		// if our cpt object isn't existent then get out immediately.
806
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
807
+			return;
808
+		}
809
+		$this->trash_cpt_item($post_id);
810
+	}
811
+
812
+
813
+	/**
814
+	 * Callback for the WordPress untrashed_post hook.
815
+	 * Execute some basic checks before calling the restore_cpt_method in the child class.
816
+	 *
817
+	 * @param $post_id
818
+	 * @throws \EE_Error
819
+	 */
820
+	public function before_restore_cpt_item($post_id)
821
+	{
822
+		$this->_set_model_object($post_id, true, 'restore');
823
+		// if our cpt object isn't existent then get out immediately.
824
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
825
+			return;
826
+		}
827
+		$this->restore_cpt_item($post_id);
828
+	}
829
+
830
+
831
+	/**
832
+	 * Callback for the WordPress after_delete_post hook.
833
+	 * Execute some basic checks before calling the delete_cpt_item method in the child class.
834
+	 *
835
+	 * @param $post_id
836
+	 * @throws \EE_Error
837
+	 */
838
+	public function before_delete_cpt_item($post_id)
839
+	{
840
+		$this->_set_model_object($post_id, true, 'delete');
841
+		// if our cpt object isn't existent then get out immediately.
842
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
843
+			return;
844
+		}
845
+		$this->delete_cpt_item($post_id);
846
+	}
847
+
848
+
849
+	/**
850
+	 * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
851
+	 * accordingly.
852
+	 *
853
+	 * @return void
854
+	 * @throws EE_Error
855
+	 * @throws InvalidArgumentException
856
+	 * @throws InvalidDataTypeException
857
+	 * @throws InvalidInterfaceException
858
+	 * @throws ReflectionException
859
+	 */
860
+	public function verify_cpt_object()
861
+	{
862
+		$label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
863
+		// verify event object
864
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
865
+			throw new EE_Error(
866
+				sprintf(
867
+					__(
868
+						'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
869
+						'event_espresso'
870
+					),
871
+					$label
872
+				)
873
+			);
874
+		}
875
+		// if auto-draft then throw an error
876
+		if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
877
+			EE_Error::overwrite_errors();
878
+			EE_Error::add_error(
879
+				sprintf(
880
+					__(
881
+						'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
882
+						'event_espresso'
883
+					),
884
+					$label
885
+				),
886
+				__FILE__,
887
+				__FUNCTION__,
888
+				__LINE__
889
+			);
890
+		}
891
+		$this->loadEspressoEditorAssetManager();
892
+	}
893
+
894
+
895
+	/**
896
+	 * admin_footer_scripts_global
897
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
898
+	 * will apply on ALL EE_Admin pages.
899
+	 *
900
+	 * @access public
901
+	 * @return void
902
+	 */
903
+	public function admin_footer_scripts_global()
904
+	{
905
+		$this->_add_admin_page_ajax_loading_img();
906
+		$this->_add_admin_page_overlay();
907
+	}
908
+
909
+
910
+	/**
911
+	 * add in any global scripts for cpt routes
912
+	 *
913
+	 * @return void
914
+	 */
915
+	public function load_global_scripts_styles()
916
+	{
917
+		parent::load_global_scripts_styles();
918
+		if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
919
+			// setup custom post status object for localize script but only if we've got a cpt object
920
+			$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
921
+			if (! empty($statuses)) {
922
+				// get ALL statuses!
923
+				$statuses = $this->_cpt_model_obj->get_all_post_statuses();
924
+				// setup object
925
+				$ee_cpt_statuses = array();
926
+				foreach ($statuses as $status => $label) {
927
+					$ee_cpt_statuses[ $status ] = array(
928
+						'label'      => $label,
929
+						'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label),
930
+					);
931
+				}
932
+				wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
933
+			}
934
+		}
935
+	}
936
+
937
+
938
+	/**
939
+	 * @throws InvalidArgumentException
940
+	 * @throws InvalidDataTypeException
941
+	 * @throws InvalidInterfaceException
942
+	 */
943
+	private function loadEspressoEditorAssetManager()
944
+	{
945
+		EE_Dependency_Map::register_dependencies(
946
+			'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager',
947
+			array(
948
+				'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
949
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
950
+				'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
951
+			)
952
+		);
953
+		$this->loader->getShared(
954
+			'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager'
955
+		);
956
+		add_action('admin_enqueue_scripts', array($this, 'enqueueEspressoEditorAssets'), 100);
957
+	}
958
+
959
+
960
+	/**
961
+	 * enqueue_scripts - Load the scripts and css
962
+	 *
963
+	 * @return void
964
+	 * @throws DomainException
965
+	 */
966
+	public function enqueueEspressoEditorAssets()
967
+	{
968
+		wp_enqueue_style(EspressoEditorAssetManager::CSS_HANDLE_EDITOR);
969
+		wp_enqueue_script(EspressoEditorAssetManager::JS_HANDLE_EDITOR);
970
+	}
971
+
972
+
973
+	/**
974
+	 * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
975
+	 * insert/updates
976
+	 *
977
+	 * @param  int     $post_id ID of post being updated
978
+	 * @param  WP_Post $post    Post object from WP
979
+	 * @param  bool    $update  Whether this is an update or a new save.
980
+	 * @return void
981
+	 * @throws \EE_Error
982
+	 */
983
+	public function insert_update($post_id, $post, $update)
984
+	{
985
+		// make sure that if this is a revision OR trash action that we don't do any updates!
986
+		if (isset($this->_req_data['action'])
987
+			&& (
988
+				$this->_req_data['action'] === 'restore'
989
+				|| $this->_req_data['action'] === 'trash'
990
+			)
991
+		) {
992
+			return;
993
+		}
994
+		$this->_set_model_object($post_id, true, 'insert_update');
995
+		// if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
996
+		if ($update
997
+			&& (
998
+				! $this->_cpt_model_obj instanceof EE_CPT_Base
999
+				|| $this->_cpt_model_obj->ID() !== $post_id
1000
+			)
1001
+		) {
1002
+			return;
1003
+		}
1004
+		// check for autosave and update our req_data property accordingly.
1005
+		/*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
1006 1006
             foreach( (array) $this->_req_data['ee_autosave_data'] as $id => $values ) {
1007 1007
 
1008 1008
                 foreach ( (array) $values as $key => $value ) {
@@ -1012,532 +1012,532 @@  discard block
 block discarded – undo
1012 1012
 
1013 1013
         }/**/ // TODO reactivate after autosave is implemented in 4.2
1014 1014
 
1015
-        // take care of updating any selected page_template IF this cpt supports it.
1016
-        if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
1017
-            // wp version aware.
1018
-            if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
1019
-                $page_templates = wp_get_theme()->get_page_templates();
1020
-            } else {
1021
-                $post->page_template = $this->_req_data['page_template'];
1022
-                $page_templates = wp_get_theme()->get_page_templates($post);
1023
-            }
1024
-            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1025
-                EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1026
-            } else {
1027
-                update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1028
-            }
1029
-        }
1030
-        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1031
-            return;
1032
-        } //TODO we'll remove this after reimplementing autosave in 4.2
1033
-        $this->_insert_update_cpt_item($post_id, $post);
1034
-    }
1035
-
1036
-
1037
-    /**
1038
-     * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1039
-     * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1040
-     * so we don't have to check for our CPT.
1041
-     *
1042
-     * @param  int $post_id ID of the post
1043
-     * @return void
1044
-     */
1045
-    public function dont_permanently_delete_ee_cpts($post_id)
1046
-    {
1047
-        // only do this if we're actually processing one of our CPTs
1048
-        // if our cpt object isn't existent then get out immediately.
1049
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1050
-            return;
1051
-        }
1052
-        delete_post_meta($post_id, '_wp_trash_meta_status');
1053
-        delete_post_meta($post_id, '_wp_trash_meta_time');
1054
-        // our cpts may have comments so let's take care of that too
1055
-        delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1056
-    }
1057
-
1058
-
1059
-    /**
1060
-     * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1061
-     * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1062
-     * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1063
-     *
1064
-     * @param  int $post_id     ID of cpt item
1065
-     * @param  int $revision_id ID of revision being restored
1066
-     * @return void
1067
-     */
1068
-    public function restore_revision($post_id, $revision_id)
1069
-    {
1070
-        $this->_restore_cpt_item($post_id, $revision_id);
1071
-        // global action
1072
-        do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1073
-        // class specific action so you can limit hooking into a specific page.
1074
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     * @see restore_revision() for details
1080
-     * @param  int $post_id     ID of cpt item
1081
-     * @param  int $revision_id ID of revision for item
1082
-     * @return void
1083
-     */
1084
-    abstract protected function _restore_cpt_item($post_id, $revision_id);
1085
-
1086
-
1087
-    /**
1088
-     * Execution of this method is added to the end of the load_page_dependencies method in the parent
1089
-     * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1090
-     * To fix we have to reset the current_screen using the page_slug
1091
-     * (which is identical - or should be - to our registered_post_type id.)
1092
-     * Also, since the core WP file loads the admin_header.php for WP
1093
-     * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1094
-     * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1095
-     *
1096
-     * @return void
1097
-     */
1098
-    public function modify_current_screen()
1099
-    {
1100
-        // ONLY do this if the current page_route IS a cpt route
1101
-        if (! $this->_cpt_route) {
1102
-            return;
1103
-        }
1104
-        // routing things REALLY early b/c this is a cpt admin page
1105
-        set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1106
-        $this->_current_screen = get_current_screen();
1107
-        $this->_current_screen->base = 'event-espresso';
1108
-        $this->_add_help_tabs(); // we make sure we add any help tabs back in!
1109
-        /*try {
1015
+		// take care of updating any selected page_template IF this cpt supports it.
1016
+		if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
1017
+			// wp version aware.
1018
+			if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
1019
+				$page_templates = wp_get_theme()->get_page_templates();
1020
+			} else {
1021
+				$post->page_template = $this->_req_data['page_template'];
1022
+				$page_templates = wp_get_theme()->get_page_templates($post);
1023
+			}
1024
+			if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1025
+				EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1026
+			} else {
1027
+				update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1028
+			}
1029
+		}
1030
+		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1031
+			return;
1032
+		} //TODO we'll remove this after reimplementing autosave in 4.2
1033
+		$this->_insert_update_cpt_item($post_id, $post);
1034
+	}
1035
+
1036
+
1037
+	/**
1038
+	 * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1039
+	 * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1040
+	 * so we don't have to check for our CPT.
1041
+	 *
1042
+	 * @param  int $post_id ID of the post
1043
+	 * @return void
1044
+	 */
1045
+	public function dont_permanently_delete_ee_cpts($post_id)
1046
+	{
1047
+		// only do this if we're actually processing one of our CPTs
1048
+		// if our cpt object isn't existent then get out immediately.
1049
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1050
+			return;
1051
+		}
1052
+		delete_post_meta($post_id, '_wp_trash_meta_status');
1053
+		delete_post_meta($post_id, '_wp_trash_meta_time');
1054
+		// our cpts may have comments so let's take care of that too
1055
+		delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1056
+	}
1057
+
1058
+
1059
+	/**
1060
+	 * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1061
+	 * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1062
+	 * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1063
+	 *
1064
+	 * @param  int $post_id     ID of cpt item
1065
+	 * @param  int $revision_id ID of revision being restored
1066
+	 * @return void
1067
+	 */
1068
+	public function restore_revision($post_id, $revision_id)
1069
+	{
1070
+		$this->_restore_cpt_item($post_id, $revision_id);
1071
+		// global action
1072
+		do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1073
+		// class specific action so you can limit hooking into a specific page.
1074
+		do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 * @see restore_revision() for details
1080
+	 * @param  int $post_id     ID of cpt item
1081
+	 * @param  int $revision_id ID of revision for item
1082
+	 * @return void
1083
+	 */
1084
+	abstract protected function _restore_cpt_item($post_id, $revision_id);
1085
+
1086
+
1087
+	/**
1088
+	 * Execution of this method is added to the end of the load_page_dependencies method in the parent
1089
+	 * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1090
+	 * To fix we have to reset the current_screen using the page_slug
1091
+	 * (which is identical - or should be - to our registered_post_type id.)
1092
+	 * Also, since the core WP file loads the admin_header.php for WP
1093
+	 * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1094
+	 * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1095
+	 *
1096
+	 * @return void
1097
+	 */
1098
+	public function modify_current_screen()
1099
+	{
1100
+		// ONLY do this if the current page_route IS a cpt route
1101
+		if (! $this->_cpt_route) {
1102
+			return;
1103
+		}
1104
+		// routing things REALLY early b/c this is a cpt admin page
1105
+		set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1106
+		$this->_current_screen = get_current_screen();
1107
+		$this->_current_screen->base = 'event-espresso';
1108
+		$this->_add_help_tabs(); // we make sure we add any help tabs back in!
1109
+		/*try {
1110 1110
             $this->_route_admin_request();
1111 1111
         } catch ( EE_Error $e ) {
1112 1112
             $e->get_error();
1113 1113
         }/**/
1114
-    }
1115
-
1116
-
1117
-    /**
1118
-     * This allows child classes to modify the default editor title that appears when people add a new or edit an
1119
-     * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1120
-     * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1121
-     * default to be.
1122
-     *
1123
-     * @param string $title The new title (or existing if there is no editor_title defined)
1124
-     * @return string
1125
-     */
1126
-    public function add_custom_editor_default_title($title)
1127
-    {
1128
-        return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1129
-            ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1130
-            : $title;
1131
-    }
1132
-
1133
-
1134
-    /**
1135
-     * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1136
-     *
1137
-     * @param string $shortlink   The already generated shortlink
1138
-     * @param int    $id          Post ID for this item
1139
-     * @param string $context     The context for the link
1140
-     * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1141
-     * @return string
1142
-     */
1143
-    public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1144
-    {
1145
-        if (! empty($id) && get_option('permalink_structure') !== '') {
1146
-            $post = get_post($id);
1147
-            if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1148
-                $shortlink = home_url('?p=' . $post->ID);
1149
-            }
1150
-        }
1151
-        return $shortlink;
1152
-    }
1153
-
1154
-
1155
-    /**
1156
-     * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1157
-     * already run in modify_current_screen())
1158
-     *
1159
-     * @return void
1160
-     */
1161
-    public function route_admin_request()
1162
-    {
1163
-        if ($this->_cpt_route) {
1164
-            return;
1165
-        }
1166
-        try {
1167
-            $this->_route_admin_request();
1168
-        } catch (EE_Error $e) {
1169
-            $e->get_error();
1170
-        }
1171
-    }
1172
-
1173
-
1174
-    /**
1175
-     * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1176
-     *
1177
-     * @return void
1178
-     */
1179
-    public function cpt_post_form_hidden_input()
1180
-    {
1181
-        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1182
-        // we're also going to add the route value and the current page so we can direct autosave parsing correctly
1183
-        echo '<div id="ee-cpt-hidden-inputs">';
1184
-        echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1185
-        echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1186
-        echo '</div>';
1187
-    }
1188
-
1189
-
1190
-    /**
1191
-     * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1192
-     *
1193
-     * @param  string $location Original location url
1194
-     * @param  int    $status   Status for http header
1195
-     * @return string           new (or original) url to redirect to.
1196
-     */
1197
-    public function revision_redirect($location, $status)
1198
-    {
1199
-        // get revision
1200
-        $rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1201
-        // can't do anything without revision so let's get out if not present
1202
-        if (empty($rev_id)) {
1203
-            return $location;
1204
-        }
1205
-        // get rev_post_data
1206
-        $rev = get_post($rev_id);
1207
-        $admin_url = $this->_admin_base_url;
1208
-        $query_args = array(
1209
-            'action'   => 'edit',
1210
-            'post'     => $rev->post_parent,
1211
-            'revision' => $rev_id,
1212
-            'message'  => 5,
1213
-        );
1214
-        $this->_process_notices($query_args, true);
1215
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1216
-    }
1217
-
1218
-
1219
-    /**
1220
-     * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1221
-     *
1222
-     * @param  string $link    the original generated link
1223
-     * @param  int    $id      post id
1224
-     * @param  string $context optional, defaults to display.  How to write the '&'
1225
-     * @return string          the link
1226
-     */
1227
-    public function modify_edit_post_link($link, $id, $context)
1228
-    {
1229
-        $post = get_post($id);
1230
-        if (! isset($this->_req_data['action'])
1231
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1232
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1233
-        ) {
1234
-            return $link;
1235
-        }
1236
-        $query_args = array(
1237
-            'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1238
-                ? $this->_cpt_edit_routes[ $post->post_type ]
1239
-                : 'edit',
1240
-            'post'   => $id,
1241
-        );
1242
-        return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1243
-    }
1244
-
1245
-
1246
-    /**
1247
-     * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1248
-     * our routes.
1249
-     *
1250
-     * @param  string $delete_link  original delete link
1251
-     * @param  int    $post_id      id of cpt object
1252
-     * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1253
-     * @return string new delete link
1254
-     * @throws EE_Error
1255
-     */
1256
-    public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1257
-    {
1258
-        $post = get_post($post_id);
1259
-
1260
-        if (empty($this->_req_data['action'])
1261
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1262
-            || ! $post instanceof WP_Post
1263
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1264
-        ) {
1265
-            return $delete_link;
1266
-        }
1267
-        $this->_set_model_object($post->ID, true);
1268
-
1269
-        // returns something like `trash_event` or `trash_attendee` or `trash_venue`
1270
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1271
-
1272
-        return EE_Admin_Page::add_query_args_and_nonce(
1273
-            array(
1274
-                'page'   => $this->_req_data['page'],
1275
-                'action' => $action,
1276
-                $this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1277
-                         => $post->ID,
1278
-            ),
1279
-            admin_url()
1280
-        );
1281
-    }
1282
-
1283
-
1284
-    /**
1285
-     * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1286
-     * so that we can hijack the default redirect locations for wp custom post types
1287
-     * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1288
-     *
1289
-     * @param  string $location This is the incoming currently set redirect location
1290
-     * @param  string $post_id  This is the 'ID' value of the wp_posts table
1291
-     * @return string           the new location to redirect to
1292
-     */
1293
-    public function cpt_post_location_redirect($location, $post_id)
1294
-    {
1295
-        // we DO have a match so let's setup the url
1296
-        // we have to get the post to determine our route
1297
-        $post = get_post($post_id);
1298
-        $edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1299
-        // shared query_args
1300
-        $query_args = array('action' => $edit_route, 'post' => $post_id);
1301
-        $admin_url = $this->_admin_base_url;
1302
-        if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1303
-            $status = get_post_status($post_id);
1304
-            if (isset($this->_req_data['publish'])) {
1305
-                switch ($status) {
1306
-                    case 'pending':
1307
-                        $message = 8;
1308
-                        break;
1309
-                    case 'future':
1310
-                        $message = 9;
1311
-                        break;
1312
-                    default:
1313
-                        $message = 6;
1314
-                }
1315
-            } else {
1316
-                $message = 'draft' === $status ? 10 : 1;
1317
-            }
1318
-        } elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1319
-            $message = 2;
1320
-        } elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1321
-            $message = 3;
1322
-        } elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1323
-            $message = 7;
1324
-        } else {
1325
-            $message = 4;
1326
-        }
1327
-        // change the message if the post type is not viewable on the frontend
1328
-        $this->_cpt_object = get_post_type_object($post->post_type);
1329
-        $message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1330
-        $query_args = array_merge(array('message' => $message), $query_args);
1331
-        $this->_process_notices($query_args, true);
1332
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1333
-    }
1334
-
1335
-
1336
-    /**
1337
-     * This method is called to inject nav tabs on core WP cpt pages
1338
-     *
1339
-     * @access public
1340
-     * @return void
1341
-     */
1342
-    public function inject_nav_tabs()
1343
-    {
1344
-        // can we hijack and insert the nav_tabs?
1345
-        $nav_tabs = $this->_get_main_nav_tabs();
1346
-        // first close off existing form tag
1347
-        $html = '>';
1348
-        $html .= $nav_tabs;
1349
-        // now let's handle the remaining tag ( missing ">" is CORRECT )
1350
-        $html .= '<span></span';
1351
-        echo $html;
1352
-    }
1353
-
1354
-
1355
-    /**
1356
-     * This just sets up the post update messages when an update form is loaded
1357
-     *
1358
-     * @access public
1359
-     * @param  array $messages the original messages array
1360
-     * @return array           the new messages array
1361
-     */
1362
-    public function post_update_messages($messages)
1363
-    {
1364
-        global $post;
1365
-        $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1366
-        $id = empty($id) && is_object($post) ? $post->ID : null;
1367
-        /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1114
+	}
1115
+
1116
+
1117
+	/**
1118
+	 * This allows child classes to modify the default editor title that appears when people add a new or edit an
1119
+	 * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1120
+	 * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1121
+	 * default to be.
1122
+	 *
1123
+	 * @param string $title The new title (or existing if there is no editor_title defined)
1124
+	 * @return string
1125
+	 */
1126
+	public function add_custom_editor_default_title($title)
1127
+	{
1128
+		return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1129
+			? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1130
+			: $title;
1131
+	}
1132
+
1133
+
1134
+	/**
1135
+	 * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1136
+	 *
1137
+	 * @param string $shortlink   The already generated shortlink
1138
+	 * @param int    $id          Post ID for this item
1139
+	 * @param string $context     The context for the link
1140
+	 * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1141
+	 * @return string
1142
+	 */
1143
+	public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1144
+	{
1145
+		if (! empty($id) && get_option('permalink_structure') !== '') {
1146
+			$post = get_post($id);
1147
+			if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1148
+				$shortlink = home_url('?p=' . $post->ID);
1149
+			}
1150
+		}
1151
+		return $shortlink;
1152
+	}
1153
+
1154
+
1155
+	/**
1156
+	 * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1157
+	 * already run in modify_current_screen())
1158
+	 *
1159
+	 * @return void
1160
+	 */
1161
+	public function route_admin_request()
1162
+	{
1163
+		if ($this->_cpt_route) {
1164
+			return;
1165
+		}
1166
+		try {
1167
+			$this->_route_admin_request();
1168
+		} catch (EE_Error $e) {
1169
+			$e->get_error();
1170
+		}
1171
+	}
1172
+
1173
+
1174
+	/**
1175
+	 * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1176
+	 *
1177
+	 * @return void
1178
+	 */
1179
+	public function cpt_post_form_hidden_input()
1180
+	{
1181
+		echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1182
+		// we're also going to add the route value and the current page so we can direct autosave parsing correctly
1183
+		echo '<div id="ee-cpt-hidden-inputs">';
1184
+		echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1185
+		echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1186
+		echo '</div>';
1187
+	}
1188
+
1189
+
1190
+	/**
1191
+	 * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1192
+	 *
1193
+	 * @param  string $location Original location url
1194
+	 * @param  int    $status   Status for http header
1195
+	 * @return string           new (or original) url to redirect to.
1196
+	 */
1197
+	public function revision_redirect($location, $status)
1198
+	{
1199
+		// get revision
1200
+		$rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1201
+		// can't do anything without revision so let's get out if not present
1202
+		if (empty($rev_id)) {
1203
+			return $location;
1204
+		}
1205
+		// get rev_post_data
1206
+		$rev = get_post($rev_id);
1207
+		$admin_url = $this->_admin_base_url;
1208
+		$query_args = array(
1209
+			'action'   => 'edit',
1210
+			'post'     => $rev->post_parent,
1211
+			'revision' => $rev_id,
1212
+			'message'  => 5,
1213
+		);
1214
+		$this->_process_notices($query_args, true);
1215
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1216
+	}
1217
+
1218
+
1219
+	/**
1220
+	 * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1221
+	 *
1222
+	 * @param  string $link    the original generated link
1223
+	 * @param  int    $id      post id
1224
+	 * @param  string $context optional, defaults to display.  How to write the '&'
1225
+	 * @return string          the link
1226
+	 */
1227
+	public function modify_edit_post_link($link, $id, $context)
1228
+	{
1229
+		$post = get_post($id);
1230
+		if (! isset($this->_req_data['action'])
1231
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1232
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1233
+		) {
1234
+			return $link;
1235
+		}
1236
+		$query_args = array(
1237
+			'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1238
+				? $this->_cpt_edit_routes[ $post->post_type ]
1239
+				: 'edit',
1240
+			'post'   => $id,
1241
+		);
1242
+		return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1243
+	}
1244
+
1245
+
1246
+	/**
1247
+	 * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1248
+	 * our routes.
1249
+	 *
1250
+	 * @param  string $delete_link  original delete link
1251
+	 * @param  int    $post_id      id of cpt object
1252
+	 * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1253
+	 * @return string new delete link
1254
+	 * @throws EE_Error
1255
+	 */
1256
+	public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1257
+	{
1258
+		$post = get_post($post_id);
1259
+
1260
+		if (empty($this->_req_data['action'])
1261
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1262
+			|| ! $post instanceof WP_Post
1263
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1264
+		) {
1265
+			return $delete_link;
1266
+		}
1267
+		$this->_set_model_object($post->ID, true);
1268
+
1269
+		// returns something like `trash_event` or `trash_attendee` or `trash_venue`
1270
+		$action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1271
+
1272
+		return EE_Admin_Page::add_query_args_and_nonce(
1273
+			array(
1274
+				'page'   => $this->_req_data['page'],
1275
+				'action' => $action,
1276
+				$this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1277
+						 => $post->ID,
1278
+			),
1279
+			admin_url()
1280
+		);
1281
+	}
1282
+
1283
+
1284
+	/**
1285
+	 * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1286
+	 * so that we can hijack the default redirect locations for wp custom post types
1287
+	 * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1288
+	 *
1289
+	 * @param  string $location This is the incoming currently set redirect location
1290
+	 * @param  string $post_id  This is the 'ID' value of the wp_posts table
1291
+	 * @return string           the new location to redirect to
1292
+	 */
1293
+	public function cpt_post_location_redirect($location, $post_id)
1294
+	{
1295
+		// we DO have a match so let's setup the url
1296
+		// we have to get the post to determine our route
1297
+		$post = get_post($post_id);
1298
+		$edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1299
+		// shared query_args
1300
+		$query_args = array('action' => $edit_route, 'post' => $post_id);
1301
+		$admin_url = $this->_admin_base_url;
1302
+		if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1303
+			$status = get_post_status($post_id);
1304
+			if (isset($this->_req_data['publish'])) {
1305
+				switch ($status) {
1306
+					case 'pending':
1307
+						$message = 8;
1308
+						break;
1309
+					case 'future':
1310
+						$message = 9;
1311
+						break;
1312
+					default:
1313
+						$message = 6;
1314
+				}
1315
+			} else {
1316
+				$message = 'draft' === $status ? 10 : 1;
1317
+			}
1318
+		} elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1319
+			$message = 2;
1320
+		} elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1321
+			$message = 3;
1322
+		} elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1323
+			$message = 7;
1324
+		} else {
1325
+			$message = 4;
1326
+		}
1327
+		// change the message if the post type is not viewable on the frontend
1328
+		$this->_cpt_object = get_post_type_object($post->post_type);
1329
+		$message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1330
+		$query_args = array_merge(array('message' => $message), $query_args);
1331
+		$this->_process_notices($query_args, true);
1332
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1333
+	}
1334
+
1335
+
1336
+	/**
1337
+	 * This method is called to inject nav tabs on core WP cpt pages
1338
+	 *
1339
+	 * @access public
1340
+	 * @return void
1341
+	 */
1342
+	public function inject_nav_tabs()
1343
+	{
1344
+		// can we hijack and insert the nav_tabs?
1345
+		$nav_tabs = $this->_get_main_nav_tabs();
1346
+		// first close off existing form tag
1347
+		$html = '>';
1348
+		$html .= $nav_tabs;
1349
+		// now let's handle the remaining tag ( missing ">" is CORRECT )
1350
+		$html .= '<span></span';
1351
+		echo $html;
1352
+	}
1353
+
1354
+
1355
+	/**
1356
+	 * This just sets up the post update messages when an update form is loaded
1357
+	 *
1358
+	 * @access public
1359
+	 * @param  array $messages the original messages array
1360
+	 * @return array           the new messages array
1361
+	 */
1362
+	public function post_update_messages($messages)
1363
+	{
1364
+		global $post;
1365
+		$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1366
+		$id = empty($id) && is_object($post) ? $post->ID : null;
1367
+		/*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1368 1368
 
1369 1369
         $route_to_check = $post_type && isset( $this->_cpt_routes[$current_route]) ? $this->_cpt_routes[$current_route] : '';/**/
1370
-        $messages[ $post->post_type ] = array(
1371
-            0  => '', // Unused. Messages start at index 1.
1372
-            1  => sprintf(
1373
-                __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1374
-                $this->_cpt_object->labels->singular_name,
1375
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1376
-                '</a>'
1377
-            ),
1378
-            2  => __('Custom field updated', 'event_espresso'),
1379
-            3  => __('Custom field deleted.', 'event_espresso'),
1380
-            4  => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1381
-            5  => isset($_GET['revision']) ? sprintf(
1382
-                __('%s restored to revision from %s', 'event_espresso'),
1383
-                $this->_cpt_object->labels->singular_name,
1384
-                wp_post_revision_title((int) $_GET['revision'], false)
1385
-            )
1386
-                : false,
1387
-            6  => sprintf(
1388
-                __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1389
-                $this->_cpt_object->labels->singular_name,
1390
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1391
-                '</a>'
1392
-            ),
1393
-            7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1394
-            8  => sprintf(
1395
-                __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1396
-                $this->_cpt_object->labels->singular_name,
1397
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1398
-                '</a>'
1399
-            ),
1400
-            9  => sprintf(
1401
-                __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1402
-                $this->_cpt_object->labels->singular_name,
1403
-                '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1404
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1405
-                '</a>'
1406
-            ),
1407
-            10 => sprintf(
1408
-                __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1409
-                $this->_cpt_object->labels->singular_name,
1410
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1411
-                '</a>'
1412
-            ),
1413
-        );
1414
-        return $messages;
1415
-    }
1416
-
1417
-
1418
-    /**
1419
-     * default method for the 'create_new' route for cpt admin pages.
1420
-     * For reference what to include in here, see wp-admin/post-new.php
1421
-     *
1422
-     * @access  protected
1423
-     * @return void
1424
-     */
1425
-    protected function _create_new_cpt_item()
1426
-    {
1427
-        // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1428
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1429
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1430
-        $post_type_object = $this->_cpt_object;
1431
-        $title = $post_type_object->labels->add_new_item;
1432
-        $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1433
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1434
-        // modify the default editor title field with default title.
1435
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1436
-        $this->loadEditorTemplate(true);
1437
-    }
1438
-
1439
-
1440
-    /**
1441
-     * Enqueues auto-save and loads the editor template
1442
-     *
1443
-     * @param bool $creating
1444
-     */
1445
-    private function loadEditorTemplate($creating = true)
1446
-    {
1447
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1448
-        // these vars are used by the template
1449
-        $editing = true;
1450
-        $post_ID = $post->ID;
1451
-        if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1452
-            // only enqueue autosave when creating event (necessary to get permalink/url generated)
1453
-            // otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1454
-            if ($creating) {
1455
-                wp_enqueue_script('autosave');
1456
-            } else {
1457
-                if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1458
-                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1459
-                ) {
1460
-                    $create_new_action = apply_filters(
1461
-                        'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1462
-                        'create_new',
1463
-                        $this
1464
-                    );
1465
-                    $post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1466
-                        array(
1467
-                            'action' => $create_new_action,
1468
-                            'page'   => $this->page_slug,
1469
-                        ),
1470
-                        'admin.php'
1471
-                    );
1472
-                }
1473
-            }
1474
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1475
-        }
1476
-    }
1477
-
1478
-
1479
-    public function add_new_admin_page_global()
1480
-    {
1481
-        $admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1482
-        ?>
1370
+		$messages[ $post->post_type ] = array(
1371
+			0  => '', // Unused. Messages start at index 1.
1372
+			1  => sprintf(
1373
+				__('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1374
+				$this->_cpt_object->labels->singular_name,
1375
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1376
+				'</a>'
1377
+			),
1378
+			2  => __('Custom field updated', 'event_espresso'),
1379
+			3  => __('Custom field deleted.', 'event_espresso'),
1380
+			4  => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1381
+			5  => isset($_GET['revision']) ? sprintf(
1382
+				__('%s restored to revision from %s', 'event_espresso'),
1383
+				$this->_cpt_object->labels->singular_name,
1384
+				wp_post_revision_title((int) $_GET['revision'], false)
1385
+			)
1386
+				: false,
1387
+			6  => sprintf(
1388
+				__('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1389
+				$this->_cpt_object->labels->singular_name,
1390
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1391
+				'</a>'
1392
+			),
1393
+			7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1394
+			8  => sprintf(
1395
+				__('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1396
+				$this->_cpt_object->labels->singular_name,
1397
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1398
+				'</a>'
1399
+			),
1400
+			9  => sprintf(
1401
+				__('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1402
+				$this->_cpt_object->labels->singular_name,
1403
+				'<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1404
+				'<a target="_blank" href="' . esc_url(get_permalink($id)),
1405
+				'</a>'
1406
+			),
1407
+			10 => sprintf(
1408
+				__('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1409
+				$this->_cpt_object->labels->singular_name,
1410
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1411
+				'</a>'
1412
+			),
1413
+		);
1414
+		return $messages;
1415
+	}
1416
+
1417
+
1418
+	/**
1419
+	 * default method for the 'create_new' route for cpt admin pages.
1420
+	 * For reference what to include in here, see wp-admin/post-new.php
1421
+	 *
1422
+	 * @access  protected
1423
+	 * @return void
1424
+	 */
1425
+	protected function _create_new_cpt_item()
1426
+	{
1427
+		// gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1428
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1429
+		$post_type = $this->_cpt_routes[ $this->_req_action ];
1430
+		$post_type_object = $this->_cpt_object;
1431
+		$title = $post_type_object->labels->add_new_item;
1432
+		$post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1433
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1434
+		// modify the default editor title field with default title.
1435
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1436
+		$this->loadEditorTemplate(true);
1437
+	}
1438
+
1439
+
1440
+	/**
1441
+	 * Enqueues auto-save and loads the editor template
1442
+	 *
1443
+	 * @param bool $creating
1444
+	 */
1445
+	private function loadEditorTemplate($creating = true)
1446
+	{
1447
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1448
+		// these vars are used by the template
1449
+		$editing = true;
1450
+		$post_ID = $post->ID;
1451
+		if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1452
+			// only enqueue autosave when creating event (necessary to get permalink/url generated)
1453
+			// otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1454
+			if ($creating) {
1455
+				wp_enqueue_script('autosave');
1456
+			} else {
1457
+				if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1458
+					&& ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1459
+				) {
1460
+					$create_new_action = apply_filters(
1461
+						'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1462
+						'create_new',
1463
+						$this
1464
+					);
1465
+					$post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1466
+						array(
1467
+							'action' => $create_new_action,
1468
+							'page'   => $this->page_slug,
1469
+						),
1470
+						'admin.php'
1471
+					);
1472
+				}
1473
+			}
1474
+			include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1475
+		}
1476
+	}
1477
+
1478
+
1479
+	public function add_new_admin_page_global()
1480
+	{
1481
+		$admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1482
+		?>
1483 1483
         <script type="text/javascript">
1484 1484
             adminpage = '<?php echo $admin_page; ?>';
1485 1485
         </script>
1486 1486
         <?php
1487
-    }
1488
-
1489
-
1490
-    /**
1491
-     * default method for the 'edit' route for cpt admin pages
1492
-     * For reference on what to put in here, refer to wp-admin/post.php
1493
-     *
1494
-     * @access protected
1495
-     * @return string   template for edit cpt form
1496
-     */
1497
-    protected function _edit_cpt_item()
1498
-    {
1499
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1500
-        $post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1501
-        $post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1502
-        if (empty($post)) {
1503
-            wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1504
-        }
1505
-        if (! empty($_GET['get-post-lock'])) {
1506
-            wp_set_post_lock($post_id);
1507
-            wp_redirect(get_edit_post_link($post_id, 'url'));
1508
-            exit();
1509
-        }
1510
-
1511
-        // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1512
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1513
-        $post_type_object = $this->_cpt_object;
1514
-
1515
-        if (! wp_check_post_lock($post->ID)) {
1516
-            wp_set_post_lock($post->ID);
1517
-        }
1518
-        add_action('admin_footer', '_admin_notice_post_locked');
1519
-        if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1520
-            wp_enqueue_script('admin-comments');
1521
-            enqueue_comment_hotkeys_js();
1522
-        }
1523
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1524
-        // modify the default editor title field with default title.
1525
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1526
-        $this->loadEditorTemplate(false);
1527
-    }
1528
-
1529
-
1530
-
1531
-    /**
1532
-     * some getters
1533
-     */
1534
-    /**
1535
-     * This returns the protected _cpt_model_obj property
1536
-     *
1537
-     * @return EE_CPT_Base
1538
-     */
1539
-    public function get_cpt_model_obj()
1540
-    {
1541
-        return $this->_cpt_model_obj;
1542
-    }
1487
+	}
1488
+
1489
+
1490
+	/**
1491
+	 * default method for the 'edit' route for cpt admin pages
1492
+	 * For reference on what to put in here, refer to wp-admin/post.php
1493
+	 *
1494
+	 * @access protected
1495
+	 * @return string   template for edit cpt form
1496
+	 */
1497
+	protected function _edit_cpt_item()
1498
+	{
1499
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1500
+		$post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1501
+		$post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1502
+		if (empty($post)) {
1503
+			wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1504
+		}
1505
+		if (! empty($_GET['get-post-lock'])) {
1506
+			wp_set_post_lock($post_id);
1507
+			wp_redirect(get_edit_post_link($post_id, 'url'));
1508
+			exit();
1509
+		}
1510
+
1511
+		// template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1512
+		$post_type = $this->_cpt_routes[ $this->_req_action ];
1513
+		$post_type_object = $this->_cpt_object;
1514
+
1515
+		if (! wp_check_post_lock($post->ID)) {
1516
+			wp_set_post_lock($post->ID);
1517
+		}
1518
+		add_action('admin_footer', '_admin_notice_post_locked');
1519
+		if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1520
+			wp_enqueue_script('admin-comments');
1521
+			enqueue_comment_hotkeys_js();
1522
+		}
1523
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1524
+		// modify the default editor title field with default title.
1525
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1526
+		$this->loadEditorTemplate(false);
1527
+	}
1528
+
1529
+
1530
+
1531
+	/**
1532
+	 * some getters
1533
+	 */
1534
+	/**
1535
+	 * This returns the protected _cpt_model_obj property
1536
+	 *
1537
+	 * @return EE_CPT_Base
1538
+	 */
1539
+	public function get_cpt_model_obj()
1540
+	{
1541
+		return $this->_cpt_model_obj;
1542
+	}
1543 1543
 }
Please login to merge, or discard this patch.
Spacing   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -169,11 +169,11 @@  discard block
 block discarded – undo
169 169
             $this->_cpt_routes
170 170
         );
171 171
         // let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
172
-        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
173
-            ? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
172
+        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[$this->_req_data['action']])
173
+            ? get_post_type_object($this->_cpt_routes[$this->_req_data['action']])
174 174
             : get_post_type_object($page);
175 175
         // tweak pagenow for page loading.
176
-        if (! $this->_pagenow_map) {
176
+        if ( ! $this->_pagenow_map) {
177 177
             $this->_pagenow_map = array(
178 178
                 'create_new' => 'post-new.php',
179 179
                 'edit'       => 'post.php',
@@ -207,12 +207,12 @@  discard block
 block discarded – undo
207 207
     {
208 208
         global $pagenow, $hook_suffix;
209 209
         // possibly reset pagenow.
210
-        if (! empty($this->_req_data['page'])
210
+        if ( ! empty($this->_req_data['page'])
211 211
             && $this->_req_data['page'] == $this->page_slug
212 212
             && ! empty($this->_req_data['action'])
213
-            && isset($this->_pagenow_map[ $this->_req_data['action'] ])
213
+            && isset($this->_pagenow_map[$this->_req_data['action']])
214 214
         ) {
215
-            $pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
215
+            $pagenow = $this->_pagenow_map[$this->_req_data['action']];
216 216
             $hook_suffix = $pagenow;
217 217
         }
218 218
     }
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
         if (empty($wp_meta_boxes)) {
245 245
             return;
246 246
         }
247
-        $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
247
+        $current_metaboxes = isset($wp_meta_boxes[$this->page_slug]) ? $wp_meta_boxes[$this->page_slug] : array();
248 248
         foreach ($current_metaboxes as $box_context) {
249 249
             foreach ($box_context as $box_details) {
250 250
                 foreach ($box_details as $box) {
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
             $this
278 278
         );
279 279
         $containers = apply_filters(
280
-            'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
280
+            'FHEE__EE_Admin_Page_CPT__'.get_class($this).'___load_autosave_scripts_styles__containers',
281 281
             $containers,
282 282
             $this
283 283
         );
@@ -321,7 +321,7 @@  discard block
 block discarded – undo
321 321
     protected function _load_page_dependencies()
322 322
     {
323 323
         // we only add stuff if this is a cpt_route!
324
-        if (! $this->_cpt_route) {
324
+        if ( ! $this->_cpt_route) {
325 325
             parent::_load_page_dependencies();
326 326
             return;
327 327
         }
@@ -345,16 +345,16 @@  discard block
 block discarded – undo
345 345
         add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
346 346
         // This basically allows us to change the title of the "publish" metabox area
347 347
         // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
348
-        if (! empty($this->_labels['publishbox'])) {
348
+        if ( ! empty($this->_labels['publishbox'])) {
349 349
             $box_label = is_array($this->_labels['publishbox'])
350
-                         && isset($this->_labels['publishbox'][ $this->_req_action ])
351
-                ? $this->_labels['publishbox'][ $this->_req_action ]
350
+                         && isset($this->_labels['publishbox'][$this->_req_action])
351
+                ? $this->_labels['publishbox'][$this->_req_action]
352 352
                 : $this->_labels['publishbox'];
353 353
             add_meta_box(
354 354
                 'submitdiv',
355 355
                 $box_label,
356 356
                 'post_submit_meta_box',
357
-                $this->_cpt_routes[ $this->_req_action ],
357
+                $this->_cpt_routes[$this->_req_action],
358 358
                 'side',
359 359
                 'core'
360 360
             );
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
                 'page_templates',
366 366
                 __('Page Template', 'event_espresso'),
367 367
                 array($this, 'page_template_meta_box'),
368
-                $this->_cpt_routes[ $this->_req_action ],
368
+                $this->_cpt_routes[$this->_req_action],
369 369
                 'side',
370 370
                 'default'
371 371
             );
@@ -397,8 +397,8 @@  discard block
 block discarded – undo
397 397
         // This is for any plugins that are doing things properly
398 398
         // and hooking into the load page hook for core wp cpt routes.
399 399
         global $pagenow;
400
-        add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
401
-        do_action('load-' . $pagenow);
400
+        add_action('load-'.$pagenow, array($this, 'modify_current_screen'), 20);
401
+        do_action('load-'.$pagenow);
402 402
         add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
403 403
         // we route REALLY early.
404 404
         try {
@@ -427,8 +427,8 @@  discard block
 block discarded – undo
427 427
                 'admin.php?page=espresso_registrations&action=contact_list',
428 428
             ),
429 429
             1 => array(
430
-                'edit.php?post_type=' . $this->_cpt_object->name,
431
-                'admin.php?page=' . $this->_cpt_object->name,
430
+                'edit.php?post_type='.$this->_cpt_object->name,
431
+                'admin.php?page='.$this->_cpt_object->name,
432 432
             ),
433 433
         );
434 434
         foreach ($routes_to_match as $route_matches) {
@@ -457,7 +457,7 @@  discard block
 block discarded – undo
457 457
             'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
458 458
         );
459 459
         $cpt_args = $custom_post_types->getDefinitions();
460
-        $cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
460
+        $cpt_args = isset($cpt_args[$cpt_name]) ? $cpt_args[$cpt_name]['args'] : array();
461 461
         $cpt_has_support = ! empty($cpt_args['page_templates']);
462 462
 
463 463
         // if the installed version of WP is > 4.7 we do some additional checks.
@@ -466,7 +466,7 @@  discard block
 block discarded – undo
466 466
             // if there are $post_templates for this cpt, then we return false for this method because
467 467
             // that means we aren't going to load our page template manager and leave that up to the native
468 468
             // cpt template manager.
469
-            $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
469
+            $cpt_has_support = ! isset($post_templates[$cpt_name]) ? $cpt_has_support : false;
470 470
         }
471 471
 
472 472
         return $cpt_has_support;
@@ -540,7 +540,7 @@  discard block
 block discarded – undo
540 540
 
541 541
         $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
542 542
         $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
543
-            ? $statuses[ $this->_cpt_model_obj->status() ]
543
+            ? $statuses[$this->_cpt_model_obj->status()]
544 544
             : '';
545 545
         $template_args = array(
546 546
             'cur_status'            => $this->_cpt_model_obj->status(),
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
             $template_args['statuses'] = $statuses;
556 556
         }
557 557
 
558
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
558
+        $template = EE_ADMIN_TEMPLATE.'status_dropdown.template.php';
559 559
         EEH_Template::display_template($template, $template_args);
560 560
     }
561 561
 
@@ -596,7 +596,7 @@  discard block
 block discarded – undo
596 596
             : null;
597 597
         $this->_verify_nonce($nonce, 'autosave');
598 598
         // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
599
-        if (! defined('DOING_AUTOSAVE')) {
599
+        if ( ! defined('DOING_AUTOSAVE')) {
600 600
             define('DOING_AUTOSAVE', true);
601 601
         }
602 602
         // if we made it here then the nonce checked out.  Let's run our methods and actions
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
             $this->_template_args['success'] = true;
608 608
         }
609 609
         do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
610
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
610
+        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_'.get_class($this), $this);
611 611
         // now let's return json
612 612
         $this->_return_json();
613 613
     }
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
             return;
630 630
         }
631 631
         // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
632
-        if (! empty($this->_cpt_object)) {
632
+        if ( ! empty($this->_cpt_object)) {
633 633
             $this->_page_routes = array_merge(
634 634
                 array(
635 635
                     'create_new' => '_create_new_cpt_item',
@@ -660,10 +660,10 @@  discard block
 block discarded – undo
660 660
             );
661 661
         }
662 662
         // load the next section only if this is a matching cpt route as set in the cpt routes array.
663
-        if (! isset($this->_cpt_routes[ $this->_req_action ])) {
663
+        if ( ! isset($this->_cpt_routes[$this->_req_action])) {
664 664
             return;
665 665
         }
666
-        $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
666
+        $this->_cpt_route = isset($this->_cpt_routes[$this->_req_action]) ? true : false;
667 667
         // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
668 668
         if (empty($this->_cpt_object)) {
669 669
             $msg = sprintf(
@@ -703,7 +703,7 @@  discard block
 block discarded – undo
703 703
         if (empty($this->_cpt_model_names)
704 704
             || (
705 705
                 ! $ignore_route_check
706
-                && ! isset($this->_cpt_routes[ $this->_req_action ])
706
+                && ! isset($this->_cpt_routes[$this->_req_action])
707 707
             ) || (
708 708
                 $this->_cpt_model_obj instanceof EE_CPT_Base
709 709
                 && $this->_cpt_model_obj->ID() === $id
@@ -720,11 +720,11 @@  discard block
 block discarded – undo
720 720
                 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
721 721
             );
722 722
             $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
723
-            if (isset($model_names[ $post_type ])) {
724
-                $model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
723
+            if (isset($model_names[$post_type])) {
724
+                $model = EE_Registry::instance()->load_model($model_names[$post_type]);
725 725
             }
726 726
         } else {
727
-            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
727
+            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[$this->_req_action]);
728 728
         }
729 729
         if ($model instanceof EEM_Base) {
730 730
             $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
@@ -754,8 +754,8 @@  discard block
 block discarded – undo
754 754
         $current_route = isset($this->_req_data['current_route'])
755 755
             ? $this->_req_data['current_route']
756 756
             : 'shouldneverwork';
757
-        $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
758
-            ? $this->_cpt_routes[ $current_route ]
757
+        $route_to_check = $post_type && isset($this->_cpt_routes[$current_route])
758
+            ? $this->_cpt_routes[$current_route]
759 759
             : '';
760 760
         add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
761 761
         add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
@@ -764,10 +764,10 @@  discard block
 block discarded – undo
764 764
         }
765 765
         // now let's filter redirect if we're on a revision page and the revision is for an event CPT.
766 766
         $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
767
-        if (! empty($revision)) {
767
+        if ( ! empty($revision)) {
768 768
             $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
769 769
             // doing a restore?
770
-            if (! empty($action) && $action === 'restore') {
770
+            if ( ! empty($action) && $action === 'restore') {
771 771
                 // get post for revision
772 772
                 $rev_post = get_post($revision);
773 773
                 $rev_parent = get_post($rev_post->post_parent);
@@ -803,7 +803,7 @@  discard block
 block discarded – undo
803 803
     {
804 804
         $this->_set_model_object($post_id, true, 'trash');
805 805
         // if our cpt object isn't existent then get out immediately.
806
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
806
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
807 807
             return;
808 808
         }
809 809
         $this->trash_cpt_item($post_id);
@@ -821,7 +821,7 @@  discard block
 block discarded – undo
821 821
     {
822 822
         $this->_set_model_object($post_id, true, 'restore');
823 823
         // if our cpt object isn't existent then get out immediately.
824
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
824
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
825 825
             return;
826 826
         }
827 827
         $this->restore_cpt_item($post_id);
@@ -839,7 +839,7 @@  discard block
 block discarded – undo
839 839
     {
840 840
         $this->_set_model_object($post_id, true, 'delete');
841 841
         // if our cpt object isn't existent then get out immediately.
842
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
842
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
843 843
             return;
844 844
         }
845 845
         $this->delete_cpt_item($post_id);
@@ -861,7 +861,7 @@  discard block
 block discarded – undo
861 861
     {
862 862
         $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
863 863
         // verify event object
864
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
864
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
865 865
             throw new EE_Error(
866 866
                 sprintf(
867 867
                     __(
@@ -918,13 +918,13 @@  discard block
 block discarded – undo
918 918
         if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
919 919
             // setup custom post status object for localize script but only if we've got a cpt object
920 920
             $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
921
-            if (! empty($statuses)) {
921
+            if ( ! empty($statuses)) {
922 922
                 // get ALL statuses!
923 923
                 $statuses = $this->_cpt_model_obj->get_all_post_statuses();
924 924
                 // setup object
925 925
                 $ee_cpt_statuses = array();
926 926
                 foreach ($statuses as $status => $label) {
927
-                    $ee_cpt_statuses[ $status ] = array(
927
+                    $ee_cpt_statuses[$status] = array(
928 928
                         'label'      => $label,
929 929
                         'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label),
930 930
                     );
@@ -1021,7 +1021,7 @@  discard block
 block discarded – undo
1021 1021
                 $post->page_template = $this->_req_data['page_template'];
1022 1022
                 $page_templates = wp_get_theme()->get_page_templates($post);
1023 1023
             }
1024
-            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1024
+            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[$this->_req_data['page_template']])) {
1025 1025
                 EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1026 1026
             } else {
1027 1027
                 update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
@@ -1046,7 +1046,7 @@  discard block
 block discarded – undo
1046 1046
     {
1047 1047
         // only do this if we're actually processing one of our CPTs
1048 1048
         // if our cpt object isn't existent then get out immediately.
1049
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1049
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1050 1050
             return;
1051 1051
         }
1052 1052
         delete_post_meta($post_id, '_wp_trash_meta_status');
@@ -1071,7 +1071,7 @@  discard block
 block discarded – undo
1071 1071
         // global action
1072 1072
         do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1073 1073
         // class specific action so you can limit hooking into a specific page.
1074
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1074
+        do_action('AHEE_EE_Admin_Page_CPT_'.get_class($this).'__restore_revision', $post_id, $revision_id);
1075 1075
     }
1076 1076
 
1077 1077
 
@@ -1098,11 +1098,11 @@  discard block
 block discarded – undo
1098 1098
     public function modify_current_screen()
1099 1099
     {
1100 1100
         // ONLY do this if the current page_route IS a cpt route
1101
-        if (! $this->_cpt_route) {
1101
+        if ( ! $this->_cpt_route) {
1102 1102
             return;
1103 1103
         }
1104 1104
         // routing things REALLY early b/c this is a cpt admin page
1105
-        set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1105
+        set_current_screen($this->_cpt_routes[$this->_req_action]);
1106 1106
         $this->_current_screen = get_current_screen();
1107 1107
         $this->_current_screen->base = 'event-espresso';
1108 1108
         $this->_add_help_tabs(); // we make sure we add any help tabs back in!
@@ -1125,8 +1125,8 @@  discard block
 block discarded – undo
1125 1125
      */
1126 1126
     public function add_custom_editor_default_title($title)
1127 1127
     {
1128
-        return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1129
-            ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1128
+        return isset($this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]])
1129
+            ? $this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]]
1130 1130
             : $title;
1131 1131
     }
1132 1132
 
@@ -1142,10 +1142,10 @@  discard block
 block discarded – undo
1142 1142
      */
1143 1143
     public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1144 1144
     {
1145
-        if (! empty($id) && get_option('permalink_structure') !== '') {
1145
+        if ( ! empty($id) && get_option('permalink_structure') !== '') {
1146 1146
             $post = get_post($id);
1147 1147
             if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1148
-                $shortlink = home_url('?p=' . $post->ID);
1148
+                $shortlink = home_url('?p='.$post->ID);
1149 1149
             }
1150 1150
         }
1151 1151
         return $shortlink;
@@ -1178,11 +1178,11 @@  discard block
 block discarded – undo
1178 1178
      */
1179 1179
     public function cpt_post_form_hidden_input()
1180 1180
     {
1181
-        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1181
+        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="'.$this->_admin_base_url.'" />';
1182 1182
         // we're also going to add the route value and the current page so we can direct autosave parsing correctly
1183 1183
         echo '<div id="ee-cpt-hidden-inputs">';
1184
-        echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1185
-        echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1184
+        echo '<input type="hidden" id="current_route" name="current_route" value="'.$this->_current_view.'" />';
1185
+        echo '<input type="hidden" id="current_page" name="current_page" value="'.$this->page_slug.'" />';
1186 1186
         echo '</div>';
1187 1187
     }
1188 1188
 
@@ -1227,15 +1227,15 @@  discard block
 block discarded – undo
1227 1227
     public function modify_edit_post_link($link, $id, $context)
1228 1228
     {
1229 1229
         $post = get_post($id);
1230
-        if (! isset($this->_req_data['action'])
1231
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1232
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1230
+        if ( ! isset($this->_req_data['action'])
1231
+            || ! isset($this->_cpt_routes[$this->_req_data['action']])
1232
+            || $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1233 1233
         ) {
1234 1234
             return $link;
1235 1235
         }
1236 1236
         $query_args = array(
1237
-            'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1238
-                ? $this->_cpt_edit_routes[ $post->post_type ]
1237
+            'action' => isset($this->_cpt_edit_routes[$post->post_type])
1238
+                ? $this->_cpt_edit_routes[$post->post_type]
1239 1239
                 : 'edit',
1240 1240
             'post'   => $id,
1241 1241
         );
@@ -1258,16 +1258,16 @@  discard block
 block discarded – undo
1258 1258
         $post = get_post($post_id);
1259 1259
 
1260 1260
         if (empty($this->_req_data['action'])
1261
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1261
+            || ! isset($this->_cpt_routes[$this->_req_data['action']])
1262 1262
             || ! $post instanceof WP_Post
1263
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1263
+            || $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1264 1264
         ) {
1265 1265
             return $delete_link;
1266 1266
         }
1267 1267
         $this->_set_model_object($post->ID, true);
1268 1268
 
1269 1269
         // returns something like `trash_event` or `trash_attendee` or `trash_venue`
1270
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1270
+        $action = 'trash_'.str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1271 1271
 
1272 1272
         return EE_Admin_Page::add_query_args_and_nonce(
1273 1273
             array(
@@ -1295,7 +1295,7 @@  discard block
 block discarded – undo
1295 1295
         // we DO have a match so let's setup the url
1296 1296
         // we have to get the post to determine our route
1297 1297
         $post = get_post($post_id);
1298
-        $edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1298
+        $edit_route = $this->_cpt_edit_routes[$post->post_type];
1299 1299
         // shared query_args
1300 1300
         $query_args = array('action' => $edit_route, 'post' => $post_id);
1301 1301
         $admin_url = $this->_admin_base_url;
@@ -1367,12 +1367,12 @@  discard block
 block discarded – undo
1367 1367
         /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1368 1368
 
1369 1369
         $route_to_check = $post_type && isset( $this->_cpt_routes[$current_route]) ? $this->_cpt_routes[$current_route] : '';/**/
1370
-        $messages[ $post->post_type ] = array(
1370
+        $messages[$post->post_type] = array(
1371 1371
             0  => '', // Unused. Messages start at index 1.
1372 1372
             1  => sprintf(
1373 1373
                 __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1374 1374
                 $this->_cpt_object->labels->singular_name,
1375
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1375
+                '<a href="'.esc_url(get_permalink($id)).'">',
1376 1376
                 '</a>'
1377 1377
             ),
1378 1378
             2  => __('Custom field updated', 'event_espresso'),
@@ -1387,27 +1387,27 @@  discard block
 block discarded – undo
1387 1387
             6  => sprintf(
1388 1388
                 __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1389 1389
                 $this->_cpt_object->labels->singular_name,
1390
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1390
+                '<a href="'.esc_url(get_permalink($id)).'">',
1391 1391
                 '</a>'
1392 1392
             ),
1393 1393
             7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1394 1394
             8  => sprintf(
1395 1395
                 __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1396 1396
                 $this->_cpt_object->labels->singular_name,
1397
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1397
+                '<a target="_blank" href="'.esc_url(add_query_arg('preview', 'true', get_permalink($id))).'">',
1398 1398
                 '</a>'
1399 1399
             ),
1400 1400
             9  => sprintf(
1401 1401
                 __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1402 1402
                 $this->_cpt_object->labels->singular_name,
1403
-                '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1404
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1403
+                '<strong>'.date_i18n('M j, Y @ G:i', strtotime($post->post_date)).'</strong>',
1404
+                '<a target="_blank" href="'.esc_url(get_permalink($id)),
1405 1405
                 '</a>'
1406 1406
             ),
1407 1407
             10 => sprintf(
1408 1408
                 __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1409 1409
                 $this->_cpt_object->labels->singular_name,
1410
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1410
+                '<a target="_blank" href="'.esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1411 1411
                 '</a>'
1412 1412
             ),
1413 1413
         );
@@ -1426,10 +1426,10 @@  discard block
 block discarded – undo
1426 1426
     {
1427 1427
         // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1428 1428
         global $post, $title, $is_IE, $post_type, $post_type_object;
1429
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1429
+        $post_type = $this->_cpt_routes[$this->_req_action];
1430 1430
         $post_type_object = $this->_cpt_object;
1431 1431
         $title = $post_type_object->labels->add_new_item;
1432
-        $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1432
+        $post = get_default_post_to_edit($this->_cpt_routes[$this->_req_action], true);
1433 1433
         add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1434 1434
         // modify the default editor title field with default title.
1435 1435
         add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
@@ -1454,8 +1454,8 @@  discard block
 block discarded – undo
1454 1454
             if ($creating) {
1455 1455
                 wp_enqueue_script('autosave');
1456 1456
             } else {
1457
-                if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1458
-                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1457
+                if (isset($this->_cpt_routes[$this->_req_data['action']])
1458
+                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][$this->_req_data['action']])
1459 1459
                 ) {
1460 1460
                     $create_new_action = apply_filters(
1461 1461
                         'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
@@ -1471,7 +1471,7 @@  discard block
 block discarded – undo
1471 1471
                     );
1472 1472
                 }
1473 1473
             }
1474
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1474
+            include_once WP_ADMIN_PATH.'edit-form-advanced.php';
1475 1475
         }
1476 1476
     }
1477 1477
 
@@ -1502,21 +1502,21 @@  discard block
 block discarded – undo
1502 1502
         if (empty($post)) {
1503 1503
             wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1504 1504
         }
1505
-        if (! empty($_GET['get-post-lock'])) {
1505
+        if ( ! empty($_GET['get-post-lock'])) {
1506 1506
             wp_set_post_lock($post_id);
1507 1507
             wp_redirect(get_edit_post_link($post_id, 'url'));
1508 1508
             exit();
1509 1509
         }
1510 1510
 
1511 1511
         // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1512
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1512
+        $post_type = $this->_cpt_routes[$this->_req_action];
1513 1513
         $post_type_object = $this->_cpt_object;
1514 1514
 
1515
-        if (! wp_check_post_lock($post->ID)) {
1515
+        if ( ! wp_check_post_lock($post->ID)) {
1516 1516
             wp_set_post_lock($post->ID);
1517 1517
         }
1518 1518
         add_action('admin_footer', '_admin_notice_post_locked');
1519
-        if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1519
+        if (post_type_supports($this->_cpt_routes[$this->_req_action], 'comments')) {
1520 1520
             wp_enqueue_script('admin-comments');
1521 1521
             enqueue_comment_hotkeys_js();
1522 1522
         }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Loader.core.php 2 patches
Indentation   +709 added lines, -709 removed lines patch added patch discarded remove patch
@@ -16,713 +16,713 @@
 block discarded – undo
16 16
 class EE_Admin_Page_Loader
17 17
 {
18 18
 
19
-    /**
20
-     * @var LoaderInterface $loader
21
-     */
22
-    protected $loader;
23
-
24
-    /**
25
-     * _installed_pages
26
-     * objects for page_init objects detected and loaded
27
-     *
28
-     * @access private
29
-     * @var EE_Admin_Page_Init[]
30
-     */
31
-    private $_installed_pages = array();
32
-
33
-
34
-    /**
35
-     * this is used to hold the registry of menu slugs for all the installed admin pages
36
-     *
37
-     * @var array
38
-     */
39
-    private $_menu_slugs = array();
40
-
41
-
42
-    /**
43
-     * _caffeinated_extends
44
-     * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
45
-     * pieces needed to do so).  This property is defined in the _set_caffeinated method.
46
-     *
47
-     * @var array
48
-     */
49
-    private $_caffeinated_extends = array();
50
-
51
-
52
-    /**
53
-     * _current_caf_extend_slug
54
-     * This property is used for holding the page slug that is required for referencing the correct
55
-     * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
56
-     *
57
-     * @var array
58
-     */
59
-    private $_current_caf_extend_slug;
60
-
61
-    /**
62
-     * _prepped_menu_maps
63
-     * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
64
-     *
65
-     * @since  4.4.0
66
-     * @var EE_Admin_Page_Menu_Map[]
67
-     */
68
-    private $_prepped_menu_maps = array();
69
-
70
-
71
-    /**
72
-     * _admin_menu_groups
73
-     * array that holds the group headings and details for
74
-     *
75
-     * @access private
76
-     * @var array
77
-     */
78
-    private $_admin_menu_groups = array();
79
-
80
-
81
-    /**
82
-     * This property will hold the hook file for setting up the filter that does all the connections between admin
83
-     * pages.
84
-     *
85
-     * @var string
86
-     */
87
-    public $hook_file;
88
-
89
-
90
-    /**
91
-     * constructor
92
-     *
93
-     * @access public
94
-     * @throws EE_Error
95
-     * @throws InvalidArgumentException
96
-     * @throws InvalidDataTypeException
97
-     * @throws ReflectionException
98
-     * @throws InvalidInterfaceException
99
-     */
100
-    public function __construct()
101
-    {
102
-        $this->loader = LoaderFactory::getLoader();
103
-        // load menu_map classes
104
-        EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
105
-        // define the default "groups" for the admin_pages
106
-        $this->_set_menu_groups();
107
-        // let's do a scan and see what installed pages we have
108
-        $this->_get_installed_pages();
109
-        // set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
110
-        add_action('admin_menu', array($this, 'set_menus'));
111
-        add_action('network_admin_menu', array($this, 'set_network_menus'));
112
-    }
113
-
114
-
115
-    /**
116
-     * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
117
-     * files in the caffeinated folder.
118
-     *
119
-     * @access private
120
-     * @return void
121
-     */
122
-    private function _define_caffeinated_constants()
123
-    {
124
-        if (! defined('EE_CORE_CAF_ADMIN')) {
125
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
126
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
127
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
128
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
129
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
130
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
131
-        }
132
-    }
133
-
134
-
135
-    /**
136
-     * _set_menu_groups
137
-     * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
138
-     *
139
-     * @access private
140
-     * @return void
141
-     * @throws EE_Error
142
-     */
143
-    private function _set_menu_groups()
144
-    {
145
-        // set array of EE_Admin_Page_Menu_Group objects
146
-        $groups = array(
147
-            'main'       => new EE_Admin_Page_Menu_Group(
148
-                array(
149
-                    'menu_label'   => __('Main', 'event_espresso'),
150
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
151
-                    'menu_slug'    => 'main',
152
-                    'capability'   => 'ee_read_ee',
153
-                    'menu_order'   => 0,
154
-                    'parent_slug'  => 'espresso_events',
155
-                )
156
-            ),
157
-            'management' => new EE_Admin_Page_Menu_Group(
158
-                array(
159
-                    'menu_label'   => __('Management', 'event_espresso'),
160
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
161
-                    'menu_slug'    => 'management',
162
-                    'capability'   => 'ee_read_ee',
163
-                    'menu_order'   => 10,
164
-                    'parent_slug'  => 'espresso_events',
165
-                )
166
-            ),
167
-            'settings'   => new EE_Admin_Page_Menu_Group(
168
-                array(
169
-                    'menu_label'   => __('Settings', 'event_espresso'),
170
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
171
-                    'menu_slug'    => 'settings',
172
-                    'capability'   => 'ee_read_ee',
173
-                    'menu_order'   => 30,
174
-                    'parent_slug'  => 'espresso_events',
175
-                )
176
-            ),
177
-            'templates'  => new EE_Admin_Page_Menu_Group(
178
-                array(
179
-                    'menu_label'   => __('Templates', 'event_espresso'),
180
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
181
-                    'menu_slug'    => 'templates',
182
-                    'capability'   => 'ee_read_ee',
183
-                    'menu_order'   => 40,
184
-                    'parent_slug'  => 'espresso_events',
185
-                )
186
-            ),
187
-            'extras'     => new EE_Admin_Page_Menu_Group(
188
-                array(
189
-                    'menu_label'              => __('Extras', 'event_espresso'),
190
-                    'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
191
-                    'menu_slug'               => 'extras',
192
-                    'capability'              => 'ee_read_ee',
193
-                    'menu_order'              => 50,
194
-                    'parent_slug'             => 'espresso_events',
195
-                    'maintenance_mode_parent' => 'espresso_maintenance_settings',
196
-                )
197
-            ),
198
-            'tools'      => new EE_Admin_Page_Menu_Group(
199
-                array(
200
-                    'menu_label'   => __('Tools', 'event_espresso'),
201
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
202
-                    'menu_slug'    => 'tools',
203
-                    'capability'   => 'ee_read_ee',
204
-                    'menu_order'   => 60,
205
-                    'parent_slug'  => 'espresso_events',
206
-                )
207
-            ),
208
-            'addons'     => new EE_Admin_Page_Menu_Group(
209
-                array(
210
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
211
-                    'menu_label'   => __('Add-ons', 'event_espresso'),
212
-                    'menu_slug'    => 'addons',
213
-                    'capability'   => 'ee_read_ee',
214
-                    'menu_order'   => 20,
215
-                    'parent_slug'  => 'espresso_events',
216
-                )
217
-            ),
218
-        );
219
-        $this->_admin_menu_groups = apply_filters(
220
-            'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
221
-            $groups
222
-        );
223
-    }
224
-
225
-
226
-    /**
227
-     * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
228
-     * slug.  The other utility with this function is it validates that all the groups are instances of
229
-     * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
230
-     *
231
-     * @return EE_Admin_Page_Menu_Group[]
232
-     * @throws EE_Error
233
-     * @since  4.4.0
234
-     */
235
-    private function _rearrange_menu_groups()
236
-    {
237
-        $groups = array();
238
-        // first let's order the menu groups by their internal menu order
239
-        // (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
240
-        usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
241
-        foreach ($this->_admin_menu_groups as $group) {
242
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
243
-                throw new EE_Error(
244
-                    sprintf(
245
-                        __(
246
-                            'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
247
-                            'event_espresso'
248
-                        ),
249
-                        print_r($group, true)
250
-                    )
251
-                );
252
-            }
253
-            $groups[ $group->menu_slug ] = $group;
254
-        }
255
-        return $groups;
256
-    }
257
-
258
-
259
-    /**
260
-     * _get_installed_pages
261
-     * This just gets the list of installed EE_Admin_pages.
262
-     *
263
-     * @access private
264
-     * @return void
265
-     * @throws EE_Error
266
-     * @throws InvalidArgumentException
267
-     * @throws InvalidDataTypeException
268
-     * @throws InvalidInterfaceException
269
-     * @throws ReflectionException
270
-     */
271
-    private function _get_installed_pages()
272
-    {
273
-        $installed_refs = array();
274
-        $exclude = array('assets', 'templates');
275
-        // grab everything in the  admin core directory
276
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
277
-        if ($admin_screens) {
278
-            foreach ($admin_screens as $admin_screen) {
279
-                $admin_screen_name = basename($admin_screen);
280
-                // files and anything in the exclude array need not apply
281
-                if (is_dir($admin_screen) && ! in_array($admin_screen_name, $exclude, true)) {
282
-                    // these folders represent the different EE admin pages
283
-                    $installed_refs[ $admin_screen_name ] = $admin_screen;
284
-                }
285
-            }
286
-        }
287
-        if (empty($installed_refs)) {
288
-            $error_msg[] = __(
289
-                'There are no EE_Admin pages detected, it looks like EE did not install properly',
290
-                'event_espresso'
291
-            );
292
-            $error_msg[] = $error_msg[0] . "\r\n"
293
-                           . sprintf(
294
-                               __(
295
-                                   'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
296
-                                   'event_espresso'
297
-                               ),
298
-                               EE_ADMIN_PAGES
299
-                           );
300
-            throw new EE_Error(implode('||', $error_msg));
301
-        }
302
-        // this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
303
-        $installed_refs = $this->_set_caffeinated($installed_refs);
304
-        // allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
305
-        $installed_refs = apply_filters(
306
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
307
-            $installed_refs
308
-        );
309
-        $this->_caffeinated_extends = apply_filters(
310
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
311
-            $this->_caffeinated_extends
312
-        );
313
-        // loop through admin pages and setup the $_installed_pages array.
314
-        $hooks_ref = [];
315
-        foreach ($installed_refs as $page => $path) {
316
-            // set autoloaders for our admin page classes based on included path information
317
-            EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
318
-            // build list of installed pages
319
-            $this->_installed_pages[ $page ] = $this->_load_admin_page($page, $path);
320
-            // verify returned object
321
-            if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) {
322
-                if (! $this->_installed_pages[ $page ]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
323
-                    continue;
324
-                }
325
-                // skip if in full maintenance mode and maintenance_mode_parent is set
326
-                $maintenance_mode_parent = $this->_installed_pages[ $page ]->get_menu_map()->maintenance_mode_parent;
327
-                if (empty($maintenance_mode_parent)
328
-                    && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
329
-                ) {
330
-                    unset($installed_refs[ $page ]);
331
-                    continue;
332
-                }
333
-                $menu_slug = $this->_installed_pages[ $page ]->get_menu_map()->menu_slug;
334
-                $this->_menu_slugs[ $menu_slug ] = $page;
335
-                // flag for register hooks on extended pages b/c extended pages use the default INIT.
336
-                $extend = false;
337
-                // now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
338
-                if (isset($this->_caffeinated_extends[ $page ])) {
339
-                    $this->_current_caf_extend_slug = $page;
340
-                    $admin_page_name = $this->_installed_pages[ $page ]->get_admin_page_name();
341
-                    $caf_path = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['path'];
342
-                    $caf_admin_page = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['admin_page'];
343
-                    add_filter(
344
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
345
-                        static function ($path_to_file) use ($caf_path) {
346
-                            return $caf_path;
347
-                        }
348
-                    );
349
-                    add_filter(
350
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
351
-                        static function ($admin_page) use ($caf_admin_page) {
352
-                            return $caf_admin_page;
353
-                        }
354
-                    );
355
-                    $extend = true;
356
-                }
357
-                // let's do the registered hooks
358
-                $extended_hooks = $this->_installed_pages[ $page ]->register_hooks($extend);
359
-                foreach ($extended_hooks as $key => $value) {
360
-                    $hooks_ref[] = $value;
361
-                }
362
-            }
363
-        }
364
-        // the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
365
-        // first make sure we've got unique values
366
-        $hooks_ref = array_unique($hooks_ref);
367
-        // now let's loop and require!
368
-        foreach ($hooks_ref as $path) {
369
-            require_once($path);
370
-        }
371
-        // make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
372
-        global $ee_menu_slugs;
373
-        $ee_menu_slugs = $this->_menu_slugs;
374
-        // we need to loop again to run any early code
375
-        foreach ($installed_refs as $page => $path) {
376
-            if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) {
377
-                $this->_installed_pages[ $page ]->do_initial_loads();
378
-            }
379
-        }
380
-        do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
381
-    }
382
-
383
-
384
-    /**
385
-     * get_admin_page_object
386
-     *
387
-     * @param string $page_slug
388
-     * @return EE_Admin_Page
389
-     */
390
-    public function get_admin_page_object($page_slug = '')
391
-    {
392
-        if (isset($this->_installed_pages[ $page_slug ])) {
393
-            return $this->_installed_pages[ $page_slug ]->loaded_page_object();
394
-        }
395
-        return null;
396
-    }
397
-
398
-
399
-    /**
400
-     * _get_classname_for_admin_page
401
-     * generates an "Admin Page" class based on the directory  name
402
-     *
403
-     * @param $dir_name
404
-     * @return string
405
-     */
406
-    private function _get_classname_for_admin_page($dir_name = '')
407
-    {
408
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
409
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
410
-    }
411
-
412
-
413
-    /**
414
-     * _get_classname_for_admin_init_page
415
-     * generates an "Admin Page Init" class based on the directory  name
416
-     *
417
-     * @param $dir_name
418
-     * @return string
419
-     */
420
-    private function _get_classname_for_admin_init_page($dir_name = '')
421
-    {
422
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
423
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
424
-    }
425
-
426
-
427
-    /**
428
-     * _load_admin_page
429
-     * Loads and instantiates page_init object for a single EE_admin page.
430
-     *
431
-     * @param string $page page_reference
432
-     * @param string $path
433
-     * @return object|bool  return page object if valid, bool false if not.
434
-     * @throws EE_Error
435
-     * @throws InvalidArgumentException
436
-     * @throws InvalidDataTypeException
437
-     * @throws ReflectionException
438
-     * @throws InvalidInterfaceException
439
-     */
440
-    private function _load_admin_page($page = '', $path = '')
441
-    {
442
-        $class_name = $this->_get_classname_for_admin_init_page($page);
443
-        EE_Registry::instance()->load_file($path, $class_name, 'core');
444
-        if (! class_exists($class_name)) {
445
-            $inner_error_msg = '<br />'
446
-                               . sprintf(
447
-                                   esc_html__(
448
-                                       'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
449
-                                       'event_espresso'
450
-                                   ),
451
-                                   '<strong>' . $class_name . '</strong>'
452
-                               );
453
-            $error_msg[] = sprintf(
454
-                __('Something went wrong with loading the %s admin page.', 'event_espresso'),
455
-                $page
456
-            );
457
-            $error_msg[] = $error_msg[0]
458
-                           . "\r\n"
459
-                           . sprintf(
460
-                               esc_html__(
461
-                                   'There is no Init class in place for the %s admin page.',
462
-                                   'event_espresso'
463
-                               ),
464
-                               $page
465
-                           )
466
-                           . $inner_error_msg;
467
-            throw new EE_Error(implode('||', $error_msg));
468
-        }
469
-        return $this->loader->getShared($class_name);
470
-    }
471
-
472
-
473
-    /**
474
-     * set_menus
475
-     * This method sets up the menus for EE Admin Pages
476
-     *
477
-     * @access private
478
-     * @return void
479
-     * @throws EE_Error
480
-     * @throws InvalidDataTypeException
481
-     * @throws ReflectionException
482
-     */
483
-    public function set_menus()
484
-    {
485
-        // prep the menu pages (sort, group.)
486
-        $this->_prep_pages();
487
-        foreach ($this->_prepped_menu_maps as $menu_map) {
488
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
489
-                $menu_map->add_menu_page();
490
-            }
491
-        }
492
-    }
493
-
494
-
495
-    /**
496
-     * set_network_menus
497
-     * This method sets up the menus for network EE Admin Pages.
498
-     * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
499
-     * are only added to the menu map if they are intended for the admin menu
500
-     *
501
-     * @return void
502
-     * @throws EE_Error
503
-     * @throws InvalidDataTypeException
504
-     * @throws ReflectionException
505
-     */
506
-    public function set_network_menus()
507
-    {
508
-        $this->_prep_pages();
509
-        foreach ($this->_prepped_menu_maps as $menu_map) {
510
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
511
-                $menu_map->add_menu_page(true);
512
-            }
513
-        }
514
-    }
515
-
516
-
517
-    /**
518
-     * _prep_pages
519
-     * sets the _prepped_menu_maps property
520
-     *
521
-     * @access private
522
-     * @return void
523
-     * @throws EE_Error
524
-     * @throws InvalidDataTypeException
525
-     */
526
-    private function _prep_pages()
527
-    {
528
-        $pages_array = array();
529
-        // rearrange _admin_menu_groups to be indexed by group slug.
530
-        $menu_groups = $this->_rearrange_menu_groups();
531
-        foreach ($this->_installed_pages as $page) {
532
-            if ($page instanceof EE_Admin_page_Init) {
533
-                $page_map = $page->get_menu_map();
534
-                // if we've got an array then the menu map is in the old format
535
-                // so let's throw a persistent notice that the admin system isn't setup correctly for this item.
536
-                if ($page_map === null || is_array($page_map)) {
537
-                    new PersistentAdminNotice(
538
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
539
-                        sprintf(
540
-                            __(
541
-                                'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
542
-                                'event_espresso'
543
-                            ),
544
-                            $page->label
545
-                        )
546
-                    );
547
-                    continue;
548
-                }
549
-                // if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
550
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
551
-                    throw new EE_Error(
552
-                        sprintf(
553
-                            __(
554
-                                'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
555
-                                'event_espresso'
556
-                            ),
557
-                            $page->label,
558
-                            $page_map
559
-                        )
560
-                    );
561
-                }
562
-                // use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
563
-                if (empty($page_map->maintenance_mode_parent)
564
-                    && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
565
-                ) {
566
-                    continue;
567
-                }
568
-                // assign to group (remember $page_map has the admin page stored in it).
569
-                $pages_array[ $page_map->menu_group ][] = $page_map;
570
-            }
571
-        }
572
-        if (empty($pages_array)) {
573
-            throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
574
-        }
575
-        // let's sort the groups, make sure it's a valid group, add header (if to show).
576
-        foreach ($pages_array as $group => $menu_maps) {
577
-            // valid_group?
578
-            if (! array_key_exists($group, $menu_groups)) {
579
-                continue;
580
-            }
581
-            // sort pages.
582
-            usort($menu_maps, array($this, '_sort_menu_maps'));
583
-            // prepend header
584
-            array_unshift($menu_maps, $menu_groups[ $group ]);
585
-            // reset $pages_array with prepped data
586
-            $pages_array[ $group ] = $menu_maps;
587
-        }
588
-
589
-        // now let's setup the _prepped_menu_maps property
590
-        foreach ($menu_groups as $group => $group_objs) {
591
-            if (isset($pages_array[ $group ])) {
592
-                foreach ($pages_array[ $group ] as $key => $value) {
593
-                    $this->_prepped_menu_maps[] = $value;
594
-                }
595
-            }
596
-        }
597
-    }
598
-
599
-
600
-    /**
601
-     * This method is the "workhorse" for detecting and setting up caffeinated functionality.
602
-     * In this method there are three checks being done:
603
-     * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
604
-     * array) etc.  (new page sets are found in caffeinated/new/{page})
605
-     * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
606
-     * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
607
-     * Extend_Events_Admin_Page extends Events_Admin_Page.
608
-     * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
609
-     * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
610
-     * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
611
-     * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
612
-     * admin_pages)
613
-     *
614
-     * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
615
-     *                              loaded.
616
-     * @return array
617
-     * @throws EE_Error
618
-     * @throws ReflectionException
619
-     */
620
-    private function _set_caffeinated($installed_refs)
621
-    {
622
-        // first let's check if there IS a caffeinated folder. If there is not then lets get out.
623
-        if ((defined('EE_DECAF') && EE_DECAF) || ! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin')) {
624
-            return $installed_refs;
625
-        }
626
-        $this->_define_caffeinated_constants();
627
-        $exclude = array('tickets');
628
-        // okay let's setup an "New" pages first (we'll return installed refs later)
629
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
630
-        if ($new_admin_screens) {
631
-            foreach ($new_admin_screens as $admin_screen) {
632
-                $admin_screen_name = basename($admin_screen);
633
-                // files and anything in the exclude array need not apply
634
-                if (is_dir($admin_screen) && ! in_array($admin_screen_name, $exclude, true)) {
635
-                    // these folders represent the different NEW EE admin pages
636
-                    $installed_refs[ $admin_screen_name ] = $admin_screen;
637
-                    // set autoloaders for our admin page classes based on included path information
638
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
639
-                }
640
-            }
641
-        }
642
-        // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
643
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
644
-        if ($extends) {
645
-            foreach ($extends as $extend) {
646
-                if (is_dir($extend)) {
647
-                    $extend_ref = basename($extend);
648
-                    // now let's make sure there is a file that matches the expected format
649
-                    $filename = str_replace(
650
-                        ' ',
651
-                        '_',
652
-                        ucwords(
653
-                            str_replace(
654
-                                '_',
655
-                                ' ',
656
-                                $extend_ref
657
-                            )
658
-                        )
659
-                    );
660
-                    $filename = 'Extend_' . $filename . '_Admin_Page';
661
-                    $this->_caffeinated_extends[ $extend_ref ]['path'] = str_replace(
662
-                        array('\\', '/'),
663
-                        '/',
664
-                        EE_CORE_CAF_ADMIN
665
-                        . 'extend/'
666
-                        . $extend_ref
667
-                        . '/'
668
-                        . $filename
669
-                        . '.core.php'
670
-                    );
671
-                    $this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename;
672
-                    // set autoloaders for our admin page classes based on included path information
673
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
674
-                }
675
-            }
676
-        }
677
-        // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
678
-        $ee_admin_hooks = array();
679
-        $hooks = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
680
-        if ($hooks) {
681
-            foreach ($hooks as $hook) {
682
-                if (is_readable($hook)) {
683
-                    require_once $hook;
684
-                    $classname = str_replace(
685
-                        [EE_CORE_CAF_ADMIN . 'hooks/', '.class.php'],
686
-                        '',
687
-                        $hook
688
-                    );
689
-                    if (class_exists($classname)) {
690
-                        $admin_page = $this->loader->getShared($classname);
691
-                        $ee_admin_hooks[] = $admin_page;
692
-                    }
693
-                }
694
-            }
695
-        }
696
-        $ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
697
-        return $installed_refs;
698
-    }
699
-
700
-
701
-    /**
702
-     * Utility method for sorting the _menu_maps (callback for usort php function)
703
-     *
704
-     * @since  4.4.0
705
-     * @param  EE_Admin_Page_Menu_Map $a menu_map object
706
-     * @param  EE_Admin_Page_Menu_Map $b being compared to
707
-     * @return int    sort order
708
-     */
709
-    private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
710
-    {
711
-        if ($a->menu_order === $b->menu_order) {
712
-            return 0;
713
-        }
714
-        return ($a->menu_order < $b->menu_order) ? -1 : 1;
715
-    }
716
-
717
-
718
-    /**
719
-     * _default_header_link
720
-     * This is just a dummy method to use with header submenu items
721
-     *
722
-     * @return bool false
723
-     */
724
-    public function _default_header_link()
725
-    {
726
-        return false;
727
-    }
19
+	/**
20
+	 * @var LoaderInterface $loader
21
+	 */
22
+	protected $loader;
23
+
24
+	/**
25
+	 * _installed_pages
26
+	 * objects for page_init objects detected and loaded
27
+	 *
28
+	 * @access private
29
+	 * @var EE_Admin_Page_Init[]
30
+	 */
31
+	private $_installed_pages = array();
32
+
33
+
34
+	/**
35
+	 * this is used to hold the registry of menu slugs for all the installed admin pages
36
+	 *
37
+	 * @var array
38
+	 */
39
+	private $_menu_slugs = array();
40
+
41
+
42
+	/**
43
+	 * _caffeinated_extends
44
+	 * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
45
+	 * pieces needed to do so).  This property is defined in the _set_caffeinated method.
46
+	 *
47
+	 * @var array
48
+	 */
49
+	private $_caffeinated_extends = array();
50
+
51
+
52
+	/**
53
+	 * _current_caf_extend_slug
54
+	 * This property is used for holding the page slug that is required for referencing the correct
55
+	 * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
56
+	 *
57
+	 * @var array
58
+	 */
59
+	private $_current_caf_extend_slug;
60
+
61
+	/**
62
+	 * _prepped_menu_maps
63
+	 * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
64
+	 *
65
+	 * @since  4.4.0
66
+	 * @var EE_Admin_Page_Menu_Map[]
67
+	 */
68
+	private $_prepped_menu_maps = array();
69
+
70
+
71
+	/**
72
+	 * _admin_menu_groups
73
+	 * array that holds the group headings and details for
74
+	 *
75
+	 * @access private
76
+	 * @var array
77
+	 */
78
+	private $_admin_menu_groups = array();
79
+
80
+
81
+	/**
82
+	 * This property will hold the hook file for setting up the filter that does all the connections between admin
83
+	 * pages.
84
+	 *
85
+	 * @var string
86
+	 */
87
+	public $hook_file;
88
+
89
+
90
+	/**
91
+	 * constructor
92
+	 *
93
+	 * @access public
94
+	 * @throws EE_Error
95
+	 * @throws InvalidArgumentException
96
+	 * @throws InvalidDataTypeException
97
+	 * @throws ReflectionException
98
+	 * @throws InvalidInterfaceException
99
+	 */
100
+	public function __construct()
101
+	{
102
+		$this->loader = LoaderFactory::getLoader();
103
+		// load menu_map classes
104
+		EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
105
+		// define the default "groups" for the admin_pages
106
+		$this->_set_menu_groups();
107
+		// let's do a scan and see what installed pages we have
108
+		$this->_get_installed_pages();
109
+		// set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
110
+		add_action('admin_menu', array($this, 'set_menus'));
111
+		add_action('network_admin_menu', array($this, 'set_network_menus'));
112
+	}
113
+
114
+
115
+	/**
116
+	 * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
117
+	 * files in the caffeinated folder.
118
+	 *
119
+	 * @access private
120
+	 * @return void
121
+	 */
122
+	private function _define_caffeinated_constants()
123
+	{
124
+		if (! defined('EE_CORE_CAF_ADMIN')) {
125
+			define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
126
+			define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
127
+			define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
128
+			define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
129
+			define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
130
+			define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
131
+		}
132
+	}
133
+
134
+
135
+	/**
136
+	 * _set_menu_groups
137
+	 * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
138
+	 *
139
+	 * @access private
140
+	 * @return void
141
+	 * @throws EE_Error
142
+	 */
143
+	private function _set_menu_groups()
144
+	{
145
+		// set array of EE_Admin_Page_Menu_Group objects
146
+		$groups = array(
147
+			'main'       => new EE_Admin_Page_Menu_Group(
148
+				array(
149
+					'menu_label'   => __('Main', 'event_espresso'),
150
+					'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
151
+					'menu_slug'    => 'main',
152
+					'capability'   => 'ee_read_ee',
153
+					'menu_order'   => 0,
154
+					'parent_slug'  => 'espresso_events',
155
+				)
156
+			),
157
+			'management' => new EE_Admin_Page_Menu_Group(
158
+				array(
159
+					'menu_label'   => __('Management', 'event_espresso'),
160
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
161
+					'menu_slug'    => 'management',
162
+					'capability'   => 'ee_read_ee',
163
+					'menu_order'   => 10,
164
+					'parent_slug'  => 'espresso_events',
165
+				)
166
+			),
167
+			'settings'   => new EE_Admin_Page_Menu_Group(
168
+				array(
169
+					'menu_label'   => __('Settings', 'event_espresso'),
170
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
171
+					'menu_slug'    => 'settings',
172
+					'capability'   => 'ee_read_ee',
173
+					'menu_order'   => 30,
174
+					'parent_slug'  => 'espresso_events',
175
+				)
176
+			),
177
+			'templates'  => new EE_Admin_Page_Menu_Group(
178
+				array(
179
+					'menu_label'   => __('Templates', 'event_espresso'),
180
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
181
+					'menu_slug'    => 'templates',
182
+					'capability'   => 'ee_read_ee',
183
+					'menu_order'   => 40,
184
+					'parent_slug'  => 'espresso_events',
185
+				)
186
+			),
187
+			'extras'     => new EE_Admin_Page_Menu_Group(
188
+				array(
189
+					'menu_label'              => __('Extras', 'event_espresso'),
190
+					'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
191
+					'menu_slug'               => 'extras',
192
+					'capability'              => 'ee_read_ee',
193
+					'menu_order'              => 50,
194
+					'parent_slug'             => 'espresso_events',
195
+					'maintenance_mode_parent' => 'espresso_maintenance_settings',
196
+				)
197
+			),
198
+			'tools'      => new EE_Admin_Page_Menu_Group(
199
+				array(
200
+					'menu_label'   => __('Tools', 'event_espresso'),
201
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
202
+					'menu_slug'    => 'tools',
203
+					'capability'   => 'ee_read_ee',
204
+					'menu_order'   => 60,
205
+					'parent_slug'  => 'espresso_events',
206
+				)
207
+			),
208
+			'addons'     => new EE_Admin_Page_Menu_Group(
209
+				array(
210
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
211
+					'menu_label'   => __('Add-ons', 'event_espresso'),
212
+					'menu_slug'    => 'addons',
213
+					'capability'   => 'ee_read_ee',
214
+					'menu_order'   => 20,
215
+					'parent_slug'  => 'espresso_events',
216
+				)
217
+			),
218
+		);
219
+		$this->_admin_menu_groups = apply_filters(
220
+			'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
221
+			$groups
222
+		);
223
+	}
224
+
225
+
226
+	/**
227
+	 * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
228
+	 * slug.  The other utility with this function is it validates that all the groups are instances of
229
+	 * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
230
+	 *
231
+	 * @return EE_Admin_Page_Menu_Group[]
232
+	 * @throws EE_Error
233
+	 * @since  4.4.0
234
+	 */
235
+	private function _rearrange_menu_groups()
236
+	{
237
+		$groups = array();
238
+		// first let's order the menu groups by their internal menu order
239
+		// (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
240
+		usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
241
+		foreach ($this->_admin_menu_groups as $group) {
242
+			if (! $group instanceof EE_Admin_Page_Menu_Group) {
243
+				throw new EE_Error(
244
+					sprintf(
245
+						__(
246
+							'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
247
+							'event_espresso'
248
+						),
249
+						print_r($group, true)
250
+					)
251
+				);
252
+			}
253
+			$groups[ $group->menu_slug ] = $group;
254
+		}
255
+		return $groups;
256
+	}
257
+
258
+
259
+	/**
260
+	 * _get_installed_pages
261
+	 * This just gets the list of installed EE_Admin_pages.
262
+	 *
263
+	 * @access private
264
+	 * @return void
265
+	 * @throws EE_Error
266
+	 * @throws InvalidArgumentException
267
+	 * @throws InvalidDataTypeException
268
+	 * @throws InvalidInterfaceException
269
+	 * @throws ReflectionException
270
+	 */
271
+	private function _get_installed_pages()
272
+	{
273
+		$installed_refs = array();
274
+		$exclude = array('assets', 'templates');
275
+		// grab everything in the  admin core directory
276
+		$admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
277
+		if ($admin_screens) {
278
+			foreach ($admin_screens as $admin_screen) {
279
+				$admin_screen_name = basename($admin_screen);
280
+				// files and anything in the exclude array need not apply
281
+				if (is_dir($admin_screen) && ! in_array($admin_screen_name, $exclude, true)) {
282
+					// these folders represent the different EE admin pages
283
+					$installed_refs[ $admin_screen_name ] = $admin_screen;
284
+				}
285
+			}
286
+		}
287
+		if (empty($installed_refs)) {
288
+			$error_msg[] = __(
289
+				'There are no EE_Admin pages detected, it looks like EE did not install properly',
290
+				'event_espresso'
291
+			);
292
+			$error_msg[] = $error_msg[0] . "\r\n"
293
+						   . sprintf(
294
+							   __(
295
+								   'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
296
+								   'event_espresso'
297
+							   ),
298
+							   EE_ADMIN_PAGES
299
+						   );
300
+			throw new EE_Error(implode('||', $error_msg));
301
+		}
302
+		// this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
303
+		$installed_refs = $this->_set_caffeinated($installed_refs);
304
+		// allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
305
+		$installed_refs = apply_filters(
306
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
307
+			$installed_refs
308
+		);
309
+		$this->_caffeinated_extends = apply_filters(
310
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
311
+			$this->_caffeinated_extends
312
+		);
313
+		// loop through admin pages and setup the $_installed_pages array.
314
+		$hooks_ref = [];
315
+		foreach ($installed_refs as $page => $path) {
316
+			// set autoloaders for our admin page classes based on included path information
317
+			EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
318
+			// build list of installed pages
319
+			$this->_installed_pages[ $page ] = $this->_load_admin_page($page, $path);
320
+			// verify returned object
321
+			if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) {
322
+				if (! $this->_installed_pages[ $page ]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
323
+					continue;
324
+				}
325
+				// skip if in full maintenance mode and maintenance_mode_parent is set
326
+				$maintenance_mode_parent = $this->_installed_pages[ $page ]->get_menu_map()->maintenance_mode_parent;
327
+				if (empty($maintenance_mode_parent)
328
+					&& EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
329
+				) {
330
+					unset($installed_refs[ $page ]);
331
+					continue;
332
+				}
333
+				$menu_slug = $this->_installed_pages[ $page ]->get_menu_map()->menu_slug;
334
+				$this->_menu_slugs[ $menu_slug ] = $page;
335
+				// flag for register hooks on extended pages b/c extended pages use the default INIT.
336
+				$extend = false;
337
+				// now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
338
+				if (isset($this->_caffeinated_extends[ $page ])) {
339
+					$this->_current_caf_extend_slug = $page;
340
+					$admin_page_name = $this->_installed_pages[ $page ]->get_admin_page_name();
341
+					$caf_path = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['path'];
342
+					$caf_admin_page = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['admin_page'];
343
+					add_filter(
344
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
345
+						static function ($path_to_file) use ($caf_path) {
346
+							return $caf_path;
347
+						}
348
+					);
349
+					add_filter(
350
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
351
+						static function ($admin_page) use ($caf_admin_page) {
352
+							return $caf_admin_page;
353
+						}
354
+					);
355
+					$extend = true;
356
+				}
357
+				// let's do the registered hooks
358
+				$extended_hooks = $this->_installed_pages[ $page ]->register_hooks($extend);
359
+				foreach ($extended_hooks as $key => $value) {
360
+					$hooks_ref[] = $value;
361
+				}
362
+			}
363
+		}
364
+		// the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
365
+		// first make sure we've got unique values
366
+		$hooks_ref = array_unique($hooks_ref);
367
+		// now let's loop and require!
368
+		foreach ($hooks_ref as $path) {
369
+			require_once($path);
370
+		}
371
+		// make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
372
+		global $ee_menu_slugs;
373
+		$ee_menu_slugs = $this->_menu_slugs;
374
+		// we need to loop again to run any early code
375
+		foreach ($installed_refs as $page => $path) {
376
+			if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) {
377
+				$this->_installed_pages[ $page ]->do_initial_loads();
378
+			}
379
+		}
380
+		do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
381
+	}
382
+
383
+
384
+	/**
385
+	 * get_admin_page_object
386
+	 *
387
+	 * @param string $page_slug
388
+	 * @return EE_Admin_Page
389
+	 */
390
+	public function get_admin_page_object($page_slug = '')
391
+	{
392
+		if (isset($this->_installed_pages[ $page_slug ])) {
393
+			return $this->_installed_pages[ $page_slug ]->loaded_page_object();
394
+		}
395
+		return null;
396
+	}
397
+
398
+
399
+	/**
400
+	 * _get_classname_for_admin_page
401
+	 * generates an "Admin Page" class based on the directory  name
402
+	 *
403
+	 * @param $dir_name
404
+	 * @return string
405
+	 */
406
+	private function _get_classname_for_admin_page($dir_name = '')
407
+	{
408
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
409
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
410
+	}
411
+
412
+
413
+	/**
414
+	 * _get_classname_for_admin_init_page
415
+	 * generates an "Admin Page Init" class based on the directory  name
416
+	 *
417
+	 * @param $dir_name
418
+	 * @return string
419
+	 */
420
+	private function _get_classname_for_admin_init_page($dir_name = '')
421
+	{
422
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
423
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
424
+	}
425
+
426
+
427
+	/**
428
+	 * _load_admin_page
429
+	 * Loads and instantiates page_init object for a single EE_admin page.
430
+	 *
431
+	 * @param string $page page_reference
432
+	 * @param string $path
433
+	 * @return object|bool  return page object if valid, bool false if not.
434
+	 * @throws EE_Error
435
+	 * @throws InvalidArgumentException
436
+	 * @throws InvalidDataTypeException
437
+	 * @throws ReflectionException
438
+	 * @throws InvalidInterfaceException
439
+	 */
440
+	private function _load_admin_page($page = '', $path = '')
441
+	{
442
+		$class_name = $this->_get_classname_for_admin_init_page($page);
443
+		EE_Registry::instance()->load_file($path, $class_name, 'core');
444
+		if (! class_exists($class_name)) {
445
+			$inner_error_msg = '<br />'
446
+							   . sprintf(
447
+								   esc_html__(
448
+									   'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
449
+									   'event_espresso'
450
+								   ),
451
+								   '<strong>' . $class_name . '</strong>'
452
+							   );
453
+			$error_msg[] = sprintf(
454
+				__('Something went wrong with loading the %s admin page.', 'event_espresso'),
455
+				$page
456
+			);
457
+			$error_msg[] = $error_msg[0]
458
+						   . "\r\n"
459
+						   . sprintf(
460
+							   esc_html__(
461
+								   'There is no Init class in place for the %s admin page.',
462
+								   'event_espresso'
463
+							   ),
464
+							   $page
465
+						   )
466
+						   . $inner_error_msg;
467
+			throw new EE_Error(implode('||', $error_msg));
468
+		}
469
+		return $this->loader->getShared($class_name);
470
+	}
471
+
472
+
473
+	/**
474
+	 * set_menus
475
+	 * This method sets up the menus for EE Admin Pages
476
+	 *
477
+	 * @access private
478
+	 * @return void
479
+	 * @throws EE_Error
480
+	 * @throws InvalidDataTypeException
481
+	 * @throws ReflectionException
482
+	 */
483
+	public function set_menus()
484
+	{
485
+		// prep the menu pages (sort, group.)
486
+		$this->_prep_pages();
487
+		foreach ($this->_prepped_menu_maps as $menu_map) {
488
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
489
+				$menu_map->add_menu_page();
490
+			}
491
+		}
492
+	}
493
+
494
+
495
+	/**
496
+	 * set_network_menus
497
+	 * This method sets up the menus for network EE Admin Pages.
498
+	 * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
499
+	 * are only added to the menu map if they are intended for the admin menu
500
+	 *
501
+	 * @return void
502
+	 * @throws EE_Error
503
+	 * @throws InvalidDataTypeException
504
+	 * @throws ReflectionException
505
+	 */
506
+	public function set_network_menus()
507
+	{
508
+		$this->_prep_pages();
509
+		foreach ($this->_prepped_menu_maps as $menu_map) {
510
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
511
+				$menu_map->add_menu_page(true);
512
+			}
513
+		}
514
+	}
515
+
516
+
517
+	/**
518
+	 * _prep_pages
519
+	 * sets the _prepped_menu_maps property
520
+	 *
521
+	 * @access private
522
+	 * @return void
523
+	 * @throws EE_Error
524
+	 * @throws InvalidDataTypeException
525
+	 */
526
+	private function _prep_pages()
527
+	{
528
+		$pages_array = array();
529
+		// rearrange _admin_menu_groups to be indexed by group slug.
530
+		$menu_groups = $this->_rearrange_menu_groups();
531
+		foreach ($this->_installed_pages as $page) {
532
+			if ($page instanceof EE_Admin_page_Init) {
533
+				$page_map = $page->get_menu_map();
534
+				// if we've got an array then the menu map is in the old format
535
+				// so let's throw a persistent notice that the admin system isn't setup correctly for this item.
536
+				if ($page_map === null || is_array($page_map)) {
537
+					new PersistentAdminNotice(
538
+						'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
539
+						sprintf(
540
+							__(
541
+								'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
542
+								'event_espresso'
543
+							),
544
+							$page->label
545
+						)
546
+					);
547
+					continue;
548
+				}
549
+				// if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
550
+				if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
551
+					throw new EE_Error(
552
+						sprintf(
553
+							__(
554
+								'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
555
+								'event_espresso'
556
+							),
557
+							$page->label,
558
+							$page_map
559
+						)
560
+					);
561
+				}
562
+				// use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
563
+				if (empty($page_map->maintenance_mode_parent)
564
+					&& EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
565
+				) {
566
+					continue;
567
+				}
568
+				// assign to group (remember $page_map has the admin page stored in it).
569
+				$pages_array[ $page_map->menu_group ][] = $page_map;
570
+			}
571
+		}
572
+		if (empty($pages_array)) {
573
+			throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
574
+		}
575
+		// let's sort the groups, make sure it's a valid group, add header (if to show).
576
+		foreach ($pages_array as $group => $menu_maps) {
577
+			// valid_group?
578
+			if (! array_key_exists($group, $menu_groups)) {
579
+				continue;
580
+			}
581
+			// sort pages.
582
+			usort($menu_maps, array($this, '_sort_menu_maps'));
583
+			// prepend header
584
+			array_unshift($menu_maps, $menu_groups[ $group ]);
585
+			// reset $pages_array with prepped data
586
+			$pages_array[ $group ] = $menu_maps;
587
+		}
588
+
589
+		// now let's setup the _prepped_menu_maps property
590
+		foreach ($menu_groups as $group => $group_objs) {
591
+			if (isset($pages_array[ $group ])) {
592
+				foreach ($pages_array[ $group ] as $key => $value) {
593
+					$this->_prepped_menu_maps[] = $value;
594
+				}
595
+			}
596
+		}
597
+	}
598
+
599
+
600
+	/**
601
+	 * This method is the "workhorse" for detecting and setting up caffeinated functionality.
602
+	 * In this method there are three checks being done:
603
+	 * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
604
+	 * array) etc.  (new page sets are found in caffeinated/new/{page})
605
+	 * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
606
+	 * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
607
+	 * Extend_Events_Admin_Page extends Events_Admin_Page.
608
+	 * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
609
+	 * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
610
+	 * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
611
+	 * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
612
+	 * admin_pages)
613
+	 *
614
+	 * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
615
+	 *                              loaded.
616
+	 * @return array
617
+	 * @throws EE_Error
618
+	 * @throws ReflectionException
619
+	 */
620
+	private function _set_caffeinated($installed_refs)
621
+	{
622
+		// first let's check if there IS a caffeinated folder. If there is not then lets get out.
623
+		if ((defined('EE_DECAF') && EE_DECAF) || ! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin')) {
624
+			return $installed_refs;
625
+		}
626
+		$this->_define_caffeinated_constants();
627
+		$exclude = array('tickets');
628
+		// okay let's setup an "New" pages first (we'll return installed refs later)
629
+		$new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
630
+		if ($new_admin_screens) {
631
+			foreach ($new_admin_screens as $admin_screen) {
632
+				$admin_screen_name = basename($admin_screen);
633
+				// files and anything in the exclude array need not apply
634
+				if (is_dir($admin_screen) && ! in_array($admin_screen_name, $exclude, true)) {
635
+					// these folders represent the different NEW EE admin pages
636
+					$installed_refs[ $admin_screen_name ] = $admin_screen;
637
+					// set autoloaders for our admin page classes based on included path information
638
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
639
+				}
640
+			}
641
+		}
642
+		// let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
643
+		$extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
644
+		if ($extends) {
645
+			foreach ($extends as $extend) {
646
+				if (is_dir($extend)) {
647
+					$extend_ref = basename($extend);
648
+					// now let's make sure there is a file that matches the expected format
649
+					$filename = str_replace(
650
+						' ',
651
+						'_',
652
+						ucwords(
653
+							str_replace(
654
+								'_',
655
+								' ',
656
+								$extend_ref
657
+							)
658
+						)
659
+					);
660
+					$filename = 'Extend_' . $filename . '_Admin_Page';
661
+					$this->_caffeinated_extends[ $extend_ref ]['path'] = str_replace(
662
+						array('\\', '/'),
663
+						'/',
664
+						EE_CORE_CAF_ADMIN
665
+						. 'extend/'
666
+						. $extend_ref
667
+						. '/'
668
+						. $filename
669
+						. '.core.php'
670
+					);
671
+					$this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename;
672
+					// set autoloaders for our admin page classes based on included path information
673
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
674
+				}
675
+			}
676
+		}
677
+		// let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
678
+		$ee_admin_hooks = array();
679
+		$hooks = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
680
+		if ($hooks) {
681
+			foreach ($hooks as $hook) {
682
+				if (is_readable($hook)) {
683
+					require_once $hook;
684
+					$classname = str_replace(
685
+						[EE_CORE_CAF_ADMIN . 'hooks/', '.class.php'],
686
+						'',
687
+						$hook
688
+					);
689
+					if (class_exists($classname)) {
690
+						$admin_page = $this->loader->getShared($classname);
691
+						$ee_admin_hooks[] = $admin_page;
692
+					}
693
+				}
694
+			}
695
+		}
696
+		$ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
697
+		return $installed_refs;
698
+	}
699
+
700
+
701
+	/**
702
+	 * Utility method for sorting the _menu_maps (callback for usort php function)
703
+	 *
704
+	 * @since  4.4.0
705
+	 * @param  EE_Admin_Page_Menu_Map $a menu_map object
706
+	 * @param  EE_Admin_Page_Menu_Map $b being compared to
707
+	 * @return int    sort order
708
+	 */
709
+	private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
710
+	{
711
+		if ($a->menu_order === $b->menu_order) {
712
+			return 0;
713
+		}
714
+		return ($a->menu_order < $b->menu_order) ? -1 : 1;
715
+	}
716
+
717
+
718
+	/**
719
+	 * _default_header_link
720
+	 * This is just a dummy method to use with header submenu items
721
+	 *
722
+	 * @return bool false
723
+	 */
724
+	public function _default_header_link()
725
+	{
726
+		return false;
727
+	}
728 728
 }
Please login to merge, or discard this patch.
Spacing   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -121,13 +121,13 @@  discard block
 block discarded – undo
121 121
      */
122 122
     private function _define_caffeinated_constants()
123 123
     {
124
-        if (! defined('EE_CORE_CAF_ADMIN')) {
125
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
126
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
127
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
128
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
129
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
130
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
124
+        if ( ! defined('EE_CORE_CAF_ADMIN')) {
125
+            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH.'caffeinated/admin/');
126
+            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL.'caffeinated/admin/');
127
+            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN.'new/');
128
+            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN.'extend/');
129
+            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL.'extend/');
130
+            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN.'hooks/');
131 131
         }
132 132
     }
133 133
 
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
         // (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
240 240
         usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
241 241
         foreach ($this->_admin_menu_groups as $group) {
242
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
242
+            if ( ! $group instanceof EE_Admin_Page_Menu_Group) {
243 243
                 throw new EE_Error(
244 244
                     sprintf(
245 245
                         __(
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
                     )
251 251
                 );
252 252
             }
253
-            $groups[ $group->menu_slug ] = $group;
253
+            $groups[$group->menu_slug] = $group;
254 254
         }
255 255
         return $groups;
256 256
     }
@@ -273,14 +273,14 @@  discard block
 block discarded – undo
273 273
         $installed_refs = array();
274 274
         $exclude = array('assets', 'templates');
275 275
         // grab everything in the  admin core directory
276
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
276
+        $admin_screens = glob(EE_ADMIN_PAGES.'*', GLOB_ONLYDIR);
277 277
         if ($admin_screens) {
278 278
             foreach ($admin_screens as $admin_screen) {
279 279
                 $admin_screen_name = basename($admin_screen);
280 280
                 // files and anything in the exclude array need not apply
281 281
                 if (is_dir($admin_screen) && ! in_array($admin_screen_name, $exclude, true)) {
282 282
                     // these folders represent the different EE admin pages
283
-                    $installed_refs[ $admin_screen_name ] = $admin_screen;
283
+                    $installed_refs[$admin_screen_name] = $admin_screen;
284 284
                 }
285 285
             }
286 286
         }
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
                 'There are no EE_Admin pages detected, it looks like EE did not install properly',
290 290
                 'event_espresso'
291 291
             );
292
-            $error_msg[] = $error_msg[0] . "\r\n"
292
+            $error_msg[] = $error_msg[0]."\r\n"
293 293
                            . sprintf(
294 294
                                __(
295 295
                                    'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
@@ -316,46 +316,46 @@  discard block
 block discarded – undo
316 316
             // set autoloaders for our admin page classes based on included path information
317 317
             EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
318 318
             // build list of installed pages
319
-            $this->_installed_pages[ $page ] = $this->_load_admin_page($page, $path);
319
+            $this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
320 320
             // verify returned object
321
-            if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) {
322
-                if (! $this->_installed_pages[ $page ]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
321
+            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
322
+                if ( ! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
323 323
                     continue;
324 324
                 }
325 325
                 // skip if in full maintenance mode and maintenance_mode_parent is set
326
-                $maintenance_mode_parent = $this->_installed_pages[ $page ]->get_menu_map()->maintenance_mode_parent;
326
+                $maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent;
327 327
                 if (empty($maintenance_mode_parent)
328 328
                     && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
329 329
                 ) {
330
-                    unset($installed_refs[ $page ]);
330
+                    unset($installed_refs[$page]);
331 331
                     continue;
332 332
                 }
333
-                $menu_slug = $this->_installed_pages[ $page ]->get_menu_map()->menu_slug;
334
-                $this->_menu_slugs[ $menu_slug ] = $page;
333
+                $menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug;
334
+                $this->_menu_slugs[$menu_slug] = $page;
335 335
                 // flag for register hooks on extended pages b/c extended pages use the default INIT.
336 336
                 $extend = false;
337 337
                 // now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
338
-                if (isset($this->_caffeinated_extends[ $page ])) {
338
+                if (isset($this->_caffeinated_extends[$page])) {
339 339
                     $this->_current_caf_extend_slug = $page;
340
-                    $admin_page_name = $this->_installed_pages[ $page ]->get_admin_page_name();
341
-                    $caf_path = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['path'];
342
-                    $caf_admin_page = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['admin_page'];
340
+                    $admin_page_name = $this->_installed_pages[$page]->get_admin_page_name();
341
+                    $caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path'];
342
+                    $caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page'];
343 343
                     add_filter(
344 344
                         "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
345
-                        static function ($path_to_file) use ($caf_path) {
345
+                        static function($path_to_file) use ($caf_path) {
346 346
                             return $caf_path;
347 347
                         }
348 348
                     );
349 349
                     add_filter(
350 350
                         "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
351
-                        static function ($admin_page) use ($caf_admin_page) {
351
+                        static function($admin_page) use ($caf_admin_page) {
352 352
                             return $caf_admin_page;
353 353
                         }
354 354
                     );
355 355
                     $extend = true;
356 356
                 }
357 357
                 // let's do the registered hooks
358
-                $extended_hooks = $this->_installed_pages[ $page ]->register_hooks($extend);
358
+                $extended_hooks = $this->_installed_pages[$page]->register_hooks($extend);
359 359
                 foreach ($extended_hooks as $key => $value) {
360 360
                     $hooks_ref[] = $value;
361 361
                 }
@@ -373,8 +373,8 @@  discard block
 block discarded – undo
373 373
         $ee_menu_slugs = $this->_menu_slugs;
374 374
         // we need to loop again to run any early code
375 375
         foreach ($installed_refs as $page => $path) {
376
-            if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) {
377
-                $this->_installed_pages[ $page ]->do_initial_loads();
376
+            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
377
+                $this->_installed_pages[$page]->do_initial_loads();
378 378
             }
379 379
         }
380 380
         do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
@@ -389,8 +389,8 @@  discard block
 block discarded – undo
389 389
      */
390 390
     public function get_admin_page_object($page_slug = '')
391 391
     {
392
-        if (isset($this->_installed_pages[ $page_slug ])) {
393
-            return $this->_installed_pages[ $page_slug ]->loaded_page_object();
392
+        if (isset($this->_installed_pages[$page_slug])) {
393
+            return $this->_installed_pages[$page_slug]->loaded_page_object();
394 394
         }
395 395
         return null;
396 396
     }
@@ -406,7 +406,7 @@  discard block
 block discarded – undo
406 406
     private function _get_classname_for_admin_page($dir_name = '')
407 407
     {
408 408
         $class_name = str_replace('_', ' ', strtolower($dir_name));
409
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
409
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page';
410 410
     }
411 411
 
412 412
 
@@ -420,7 +420,7 @@  discard block
 block discarded – undo
420 420
     private function _get_classname_for_admin_init_page($dir_name = '')
421 421
     {
422 422
         $class_name = str_replace('_', ' ', strtolower($dir_name));
423
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
423
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page_Init';
424 424
     }
425 425
 
426 426
 
@@ -441,14 +441,14 @@  discard block
 block discarded – undo
441 441
     {
442 442
         $class_name = $this->_get_classname_for_admin_init_page($page);
443 443
         EE_Registry::instance()->load_file($path, $class_name, 'core');
444
-        if (! class_exists($class_name)) {
444
+        if ( ! class_exists($class_name)) {
445 445
             $inner_error_msg = '<br />'
446 446
                                . sprintf(
447 447
                                    esc_html__(
448 448
                                        'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
449 449
                                        'event_espresso'
450 450
                                    ),
451
-                                   '<strong>' . $class_name . '</strong>'
451
+                                   '<strong>'.$class_name.'</strong>'
452 452
                                );
453 453
             $error_msg[] = sprintf(
454 454
                 __('Something went wrong with loading the %s admin page.', 'event_espresso'),
@@ -535,7 +535,7 @@  discard block
 block discarded – undo
535 535
                 // so let's throw a persistent notice that the admin system isn't setup correctly for this item.
536 536
                 if ($page_map === null || is_array($page_map)) {
537 537
                     new PersistentAdminNotice(
538
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
538
+                        'menu_map_warning_'.str_replace(' ', '_', $page->label).'_'.EVENT_ESPRESSO_VERSION,
539 539
                         sprintf(
540 540
                             __(
541 541
                                 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
@@ -547,7 +547,7 @@  discard block
 block discarded – undo
547 547
                     continue;
548 548
                 }
549 549
                 // if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
550
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
550
+                if ( ! $page_map instanceof EE_Admin_Page_Menu_Map) {
551 551
                     throw new EE_Error(
552 552
                         sprintf(
553 553
                             __(
@@ -566,7 +566,7 @@  discard block
 block discarded – undo
566 566
                     continue;
567 567
                 }
568 568
                 // assign to group (remember $page_map has the admin page stored in it).
569
-                $pages_array[ $page_map->menu_group ][] = $page_map;
569
+                $pages_array[$page_map->menu_group][] = $page_map;
570 570
             }
571 571
         }
572 572
         if (empty($pages_array)) {
@@ -575,21 +575,21 @@  discard block
 block discarded – undo
575 575
         // let's sort the groups, make sure it's a valid group, add header (if to show).
576 576
         foreach ($pages_array as $group => $menu_maps) {
577 577
             // valid_group?
578
-            if (! array_key_exists($group, $menu_groups)) {
578
+            if ( ! array_key_exists($group, $menu_groups)) {
579 579
                 continue;
580 580
             }
581 581
             // sort pages.
582 582
             usort($menu_maps, array($this, '_sort_menu_maps'));
583 583
             // prepend header
584
-            array_unshift($menu_maps, $menu_groups[ $group ]);
584
+            array_unshift($menu_maps, $menu_groups[$group]);
585 585
             // reset $pages_array with prepped data
586
-            $pages_array[ $group ] = $menu_maps;
586
+            $pages_array[$group] = $menu_maps;
587 587
         }
588 588
 
589 589
         // now let's setup the _prepped_menu_maps property
590 590
         foreach ($menu_groups as $group => $group_objs) {
591
-            if (isset($pages_array[ $group ])) {
592
-                foreach ($pages_array[ $group ] as $key => $value) {
591
+            if (isset($pages_array[$group])) {
592
+                foreach ($pages_array[$group] as $key => $value) {
593 593
                     $this->_prepped_menu_maps[] = $value;
594 594
                 }
595 595
             }
@@ -620,27 +620,27 @@  discard block
 block discarded – undo
620 620
     private function _set_caffeinated($installed_refs)
621 621
     {
622 622
         // first let's check if there IS a caffeinated folder. If there is not then lets get out.
623
-        if ((defined('EE_DECAF') && EE_DECAF) || ! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin')) {
623
+        if ((defined('EE_DECAF') && EE_DECAF) || ! is_dir(EE_PLUGIN_DIR_PATH.'caffeinated/admin')) {
624 624
             return $installed_refs;
625 625
         }
626 626
         $this->_define_caffeinated_constants();
627 627
         $exclude = array('tickets');
628 628
         // okay let's setup an "New" pages first (we'll return installed refs later)
629
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
629
+        $new_admin_screens = glob(EE_CORE_CAF_ADMIN.'new/*', GLOB_ONLYDIR);
630 630
         if ($new_admin_screens) {
631 631
             foreach ($new_admin_screens as $admin_screen) {
632 632
                 $admin_screen_name = basename($admin_screen);
633 633
                 // files and anything in the exclude array need not apply
634 634
                 if (is_dir($admin_screen) && ! in_array($admin_screen_name, $exclude, true)) {
635 635
                     // these folders represent the different NEW EE admin pages
636
-                    $installed_refs[ $admin_screen_name ] = $admin_screen;
636
+                    $installed_refs[$admin_screen_name] = $admin_screen;
637 637
                     // set autoloaders for our admin page classes based on included path information
638 638
                     EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
639 639
                 }
640 640
             }
641 641
         }
642 642
         // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
643
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
643
+        $extends = glob(EE_CORE_CAF_ADMIN.'extend/*', GLOB_ONLYDIR);
644 644
         if ($extends) {
645 645
             foreach ($extends as $extend) {
646 646
                 if (is_dir($extend)) {
@@ -657,8 +657,8 @@  discard block
 block discarded – undo
657 657
                             )
658 658
                         )
659 659
                     );
660
-                    $filename = 'Extend_' . $filename . '_Admin_Page';
661
-                    $this->_caffeinated_extends[ $extend_ref ]['path'] = str_replace(
660
+                    $filename = 'Extend_'.$filename.'_Admin_Page';
661
+                    $this->_caffeinated_extends[$extend_ref]['path'] = str_replace(
662 662
                         array('\\', '/'),
663 663
                         '/',
664 664
                         EE_CORE_CAF_ADMIN
@@ -668,7 +668,7 @@  discard block
 block discarded – undo
668 668
                         . $filename
669 669
                         . '.core.php'
670 670
                     );
671
-                    $this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename;
671
+                    $this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
672 672
                     // set autoloaders for our admin page classes based on included path information
673 673
                     EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
674 674
                 }
@@ -676,13 +676,13 @@  discard block
 block discarded – undo
676 676
         }
677 677
         // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
678 678
         $ee_admin_hooks = array();
679
-        $hooks = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
679
+        $hooks = glob(EE_CORE_CAF_ADMIN.'hooks/*.class.php');
680 680
         if ($hooks) {
681 681
             foreach ($hooks as $hook) {
682 682
                 if (is_readable($hook)) {
683 683
                     require_once $hook;
684 684
                     $classname = str_replace(
685
-                        [EE_CORE_CAF_ADMIN . 'hooks/', '.class.php'],
685
+                        [EE_CORE_CAF_ADMIN.'hooks/', '.class.php'],
686 686
                         '',
687 687
                         $hook
688 688
                     );
Please login to merge, or discard this patch.
services/admin/events/default_settings/AdvancedEditorAdminFormSection.php 1 patch
Indentation   +76 added lines, -76 removed lines patch added patch discarded remove patch
@@ -39,86 +39,86 @@
 block discarded – undo
39 39
 class AdvancedEditorAdminFormSection
40 40
 {
41 41
 
42
-    /**
43
-     * @var EE_Admin_Config
44
-     */
45
-    protected $admin_config;
42
+	/**
43
+	 * @var EE_Admin_Config
44
+	 */
45
+	protected $admin_config;
46 46
 
47 47
 
48
-    /**
49
-     * AdvancedEditorAdminForm constructor.
50
-     *
51
-     * @param EE_Admin_Config $admin_config
52
-     */
53
-    public function __construct(EE_Admin_Config $admin_config)
54
-    {
55
-        $this->admin_config = $admin_config;
56
-        add_filter(
57
-            'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
58
-            [$this, 'mergeFormSubsections']
59
-        );
60
-        add_action(
61
-            'AHEE__Events_Admin_Page___update_default_event_settings',
62
-            [$this, 'updateAdminFormSettings'],
63
-            10,
64
-            2
65
-        );
66
-    }
48
+	/**
49
+	 * AdvancedEditorAdminForm constructor.
50
+	 *
51
+	 * @param EE_Admin_Config $admin_config
52
+	 */
53
+	public function __construct(EE_Admin_Config $admin_config)
54
+	{
55
+		$this->admin_config = $admin_config;
56
+		add_filter(
57
+			'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
58
+			[$this, 'mergeFormSubsections']
59
+		);
60
+		add_action(
61
+			'AHEE__Events_Admin_Page___update_default_event_settings',
62
+			[$this, 'updateAdminFormSettings'],
63
+			10,
64
+			2
65
+		);
66
+	}
67 67
 
68 68
 
69
-    /**
70
-     * @param array $default_event_settings_form_subsections
71
-     * @return array
72
-     * @since $VID:$
73
-     */
74
-    public function mergeFormSubsections(array $default_event_settings_form_subsections)
75
-    {
76
-        return [
77
-                   'use_advanced_editor'     => new EE_Select_Input(
78
-                       apply_filters(
79
-                           'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_answer_options',
80
-                           [
81
-                               esc_html__('Legacy Editor', 'event_espresso'),
82
-                               esc_html__('Advanced Editor', 'event_espresso'),
83
-                           ]
84
-                       ),
85
-                       apply_filters(
86
-                           'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_settings',
87
-                           [
88
-                               'default'         => $this->admin_config->useAdvancedEditor(),
89
-                               'html_label_text' => esc_html__('Activate Advanced Editor?', 'event_espresso'),
90
-                               'html_help_text'  => sprintf(
91
-                                   esc_html__(
92
-                                       'Controls whether the Event Espresso Event Editor continues to use the existing legacy editor that functions like the typical older WordPress admin you are used to,%1$sor uses the new Advanced Editor with a more powerful and easier to use interface. This may be automatically turned on in order to utilize advanced features from new addons.',
93
-                                       'event_espresso'
94
-                                   ),
95
-                                   '<br />'
96
-                               ),
97
-                           ]
98
-                       )
99
-                   ),
100
-                   'defaults_section_header' => new EE_Form_Section_HTML(
101
-                       EEH_HTML::h2(
102
-                           esc_html__('Default Settings', 'event_espresso'),
103
-                           '',
104
-                           'ee-admin-settings-hdr'
105
-                       )
106
-                   ),
107
-               ] + $default_event_settings_form_subsections;
108
-    }
69
+	/**
70
+	 * @param array $default_event_settings_form_subsections
71
+	 * @return array
72
+	 * @since $VID:$
73
+	 */
74
+	public function mergeFormSubsections(array $default_event_settings_form_subsections)
75
+	{
76
+		return [
77
+				   'use_advanced_editor'     => new EE_Select_Input(
78
+					   apply_filters(
79
+						   'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_answer_options',
80
+						   [
81
+							   esc_html__('Legacy Editor', 'event_espresso'),
82
+							   esc_html__('Advanced Editor', 'event_espresso'),
83
+						   ]
84
+					   ),
85
+					   apply_filters(
86
+						   'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_settings',
87
+						   [
88
+							   'default'         => $this->admin_config->useAdvancedEditor(),
89
+							   'html_label_text' => esc_html__('Activate Advanced Editor?', 'event_espresso'),
90
+							   'html_help_text'  => sprintf(
91
+								   esc_html__(
92
+									   'Controls whether the Event Espresso Event Editor continues to use the existing legacy editor that functions like the typical older WordPress admin you are used to,%1$sor uses the new Advanced Editor with a more powerful and easier to use interface. This may be automatically turned on in order to utilize advanced features from new addons.',
93
+									   'event_espresso'
94
+								   ),
95
+								   '<br />'
96
+							   ),
97
+						   ]
98
+					   )
99
+				   ),
100
+				   'defaults_section_header' => new EE_Form_Section_HTML(
101
+					   EEH_HTML::h2(
102
+						   esc_html__('Default Settings', 'event_espresso'),
103
+						   '',
104
+						   'ee-admin-settings-hdr'
105
+					   )
106
+				   ),
107
+			   ] + $default_event_settings_form_subsections;
108
+	}
109 109
 
110 110
 
111
-    /**
112
-     * @param array     $valid_data
113
-     * @param EE_Config $config
114
-     * @since $VID:$
115
-     */
116
-    public function updateAdminFormSettings(array $valid_data, EE_Config $config)
117
-    {
118
-        $config->admin->setUseAdvancedEditor(
119
-            isset($valid_data['use_advanced_editor'])
120
-                ? $valid_data['use_advanced_editor']
121
-                : false
122
-        );
123
-    }
111
+	/**
112
+	 * @param array     $valid_data
113
+	 * @param EE_Config $config
114
+	 * @since $VID:$
115
+	 */
116
+	public function updateAdminFormSettings(array $valid_data, EE_Config $config)
117
+	{
118
+		$config->admin->setUseAdvancedEditor(
119
+			isset($valid_data['use_advanced_editor'])
120
+				? $valid_data['use_advanced_editor']
121
+				: false
122
+		);
123
+	}
124 124
 }
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 2 patches
Spacing   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -39,10 +39,10 @@  discard block
 block discarded – undo
39 39
      */
40 40
     public function __construct($routing = true)
41 41
     {
42
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
43
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
44
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
45
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
42
+        if ( ! defined('EVENTS_CAF_TEMPLATE_PATH')) {
43
+            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'events/templates/');
44
+            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'events/assets/');
45
+            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'events/assets/');
46 46
         }
47 47
         parent::__construct($routing);
48 48
         if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'default_event_settings') {
@@ -51,7 +51,7 @@  discard block
 block discarded – undo
51 51
             );
52 52
         }
53 53
         if (isset($this->_req_data['action'])
54
-            && ( $this->_req_data['action'] === 'edit' || $this->_req_data['action'] === 'create_new')
54
+            && ($this->_req_data['action'] === 'edit' || $this->_req_data['action'] === 'create_new')
55 55
         ) {
56 56
             $this->advanced_editor_data = $this->loader->getShared(
57 57
                 'EventEspresso\core\domain\services\admin\events\editor\AdvancedEditorEntityData'
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
      */
72 72
     protected function _extend_page_config()
73 73
     {
74
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
74
+        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'events';
75 75
         // is there a evt_id in the request?
76 76
         $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
77 77
             ? $this->_req_data['EVT_ID']
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
     {
286 286
         $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
287 287
         // make sure this is only when editing
288
-        if (! empty($id)) {
288
+        if ( ! empty($id)) {
289 289
             $href = EE_Admin_Page::add_query_args_and_nonce(
290 290
                 array('action' => 'duplicate_event', 'EVT_ID' => $id),
291 291
                 $this->_admin_base_url
@@ -337,7 +337,7 @@  discard block
 block discarded – undo
337 337
     {
338 338
         wp_register_script(
339 339
             'ee-event-editor-heartbeat',
340
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
340
+            EVENTS_CAF_ASSETS_URL.'event-editor-heartbeat.js',
341 341
             array('ee_admin_js', 'heartbeat'),
342 342
             EVENT_ESPRESSO_VERSION,
343 343
             true
@@ -361,7 +361,7 @@  discard block
 block discarded – undo
361 361
     public function add_additional_datetime_button($template, $template_args)
362 362
     {
363 363
         return EEH_Template::display_template(
364
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
364
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_add_additional_time.template.php',
365 365
             $template_args,
366 366
             true
367 367
         );
@@ -379,7 +379,7 @@  discard block
 block discarded – undo
379 379
     public function add_datetime_clone_button($template, $template_args)
380 380
     {
381 381
         return EEH_Template::display_template(
382
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
382
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_metabox_clone_button.template.php',
383 383
             $template_args,
384 384
             true
385 385
         );
@@ -397,7 +397,7 @@  discard block
 block discarded – undo
397 397
     public function datetime_timezones_template($template, $template_args)
398 398
     {
399 399
         return EEH_Template::display_template(
400
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
400
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_timezones.template.php',
401 401
             $template_args,
402 402
             true
403 403
         );
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
     {
525 525
         // first make sure the ID for the event is in the request.
526 526
         //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
527
-        if (! isset($this->_req_data['EVT_ID'])) {
527
+        if ( ! isset($this->_req_data['EVT_ID'])) {
528 528
             EE_Error::add_error(
529 529
                 esc_html__(
530 530
                     'In order to duplicate an event an Event ID is required.  None was given.',
@@ -539,7 +539,7 @@  discard block
 block discarded – undo
539 539
         }
540 540
         // k we've got EVT_ID so let's use that to get the event we'll duplicate
541 541
         $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
542
-        if (! $orig_event instanceof EE_Event) {
542
+        if ( ! $orig_event instanceof EE_Event) {
543 543
             throw new EE_Error(
544 544
                 sprintf(
545 545
                     esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
         $orig_ven = $orig_event->get_many_related('Venue');
556 556
         // reset the ID and modify other details to make it clear this is a dupe
557 557
         $new_event->set('EVT_ID', 0);
558
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
558
+        $new_name = $new_event->name().' '.esc_html__('**DUPLICATE**', 'event_espresso');
559 559
         $new_event->set('EVT_name', $new_name);
560 560
         $new_event->set(
561 561
             'EVT_slug',
@@ -584,7 +584,7 @@  discard block
 block discarded – undo
584 584
             'Question_Group',
585 585
             [['Event_Question_Group.EQG_primary' => true]]
586 586
         );
587
-        if (! empty($orig_primary_qgs)) {
587
+        if ( ! empty($orig_primary_qgs)) {
588 588
             foreach ($orig_primary_qgs as $id => $obj) {
589 589
                 if ($obj instanceof EE_Question_Group) {
590 590
                     $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
@@ -596,7 +596,7 @@  discard block
 block discarded – undo
596 596
             'Question_Group',
597 597
             [['Event_Question_Group.EQG_additional' => true]]
598 598
         );
599
-        if (! empty($orig_additional_qgs)) {
599
+        if ( ! empty($orig_additional_qgs)) {
600 600
             foreach ($orig_additional_qgs as $id => $obj) {
601 601
                 if ($obj instanceof EE_Question_Group) {
602 602
                     $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
@@ -609,7 +609,7 @@  discard block
 block discarded – undo
609 609
         // k now that we have the new event saved we can loop through the datetimes and start adding relations.
610 610
         $cloned_tickets = array();
611 611
         foreach ($orig_datetimes as $orig_dtt) {
612
-            if (! $orig_dtt instanceof EE_Datetime) {
612
+            if ( ! $orig_dtt instanceof EE_Datetime) {
613 613
                 continue;
614 614
             }
615 615
             $new_dtt = clone $orig_dtt;
@@ -624,7 +624,7 @@  discard block
 block discarded – undo
624 624
             // now let's get the ticket relations setup.
625 625
             foreach ((array) $orig_tkts as $orig_tkt) {
626 626
                 // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
627
-                if (! $orig_tkt instanceof EE_Ticket) {
627
+                if ( ! $orig_tkt instanceof EE_Ticket) {
628 628
                     continue;
629 629
                 }
630 630
                 // is this ticket archived?  If it is then let's skip
@@ -633,8 +633,8 @@  discard block
 block discarded – undo
633 633
                 }
634 634
                 // does this original ticket already exist in the clone_tickets cache?
635 635
                 //  If so we'll just use the new ticket from it.
636
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
637
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
636
+                if (isset($cloned_tickets[$orig_tkt->ID()])) {
637
+                    $new_tkt = $cloned_tickets[$orig_tkt->ID()];
638 638
                 } else {
639 639
                     $new_tkt = clone $orig_tkt;
640 640
                     // get relations on the $orig_tkt that we need to setup.
@@ -667,7 +667,7 @@  discard block
 block discarded – undo
667 667
                 // for use with later datetimes that have the same ticket.
668 668
                 $new_dtt->_add_relation_to($new_tkt, 'Ticket');
669 669
                 $new_dtt->save();
670
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
670
+                $cloned_tickets[$orig_tkt->ID()] = $new_tkt;
671 671
             }
672 672
         }
673 673
         // clone taxonomy information
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
             $this->_admin_base_url
755 755
         );
756 756
         $content = EEH_Template::display_template(
757
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
757
+            EVENTS_CAF_TEMPLATE_PATH.'import_page.template.php',
758 758
             $this->_template_args,
759 759
             true
760 760
         );
@@ -775,7 +775,7 @@  discard block
 block discarded – undo
775 775
      */
776 776
     protected function _import_events()
777 777
     {
778
-        require_once(EE_CLASSES . 'EE_Import.class.php');
778
+        require_once(EE_CLASSES.'EE_Import.class.php');
779 779
         $success = EE_Import::instance()->import();
780 780
         $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
781 781
     }
@@ -804,8 +804,8 @@  discard block
 block discarded – undo
804 804
             'EVT_ID' => $event_ids,
805 805
         );
806 806
         $this->_req_data = array_merge($this->_req_data, $new_request_args);
807
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
808
-            require_once(EE_CLASSES . 'EE_Export.class.php');
807
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
808
+            require_once(EE_CLASSES.'EE_Export.class.php');
809 809
             $EE_Export = EE_Export::instance($this->_req_data);
810 810
             $EE_Export->export();
811 811
         }
@@ -826,8 +826,8 @@  discard block
 block discarded – undo
826 826
             'category_ids' => $this->_req_data['EVT_CAT_ID'],
827 827
         );
828 828
         $this->_req_data = array_merge($this->_req_data, $new_request_args);
829
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
830
-            require_once(EE_CLASSES . 'EE_Export.class.php');
829
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
830
+            require_once(EE_CLASSES.'EE_Export.class.php');
831 831
             $EE_Export = EE_Export::instance($this->_req_data);
832 832
             $EE_Export->export();
833 833
         }
@@ -868,7 +868,7 @@  discard block
 block discarded – undo
868 868
         $this->_set_add_edit_form_tags('update_template_settings');
869 869
         $this->_set_publish_post_box_vars(null, false, false, null, false);
870 870
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
871
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
871
+            EVENTS_CAF_TEMPLATE_PATH.'template_settings.template.php',
872 872
             $this->_template_args,
873 873
             true
874 874
         );
@@ -1001,7 +1001,7 @@  discard block
 block discarded – undo
1001 1001
             $default_reg_status_values
1002 1002
         );
1003 1003
         EEH_Template::display_template(
1004
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
1004
+            EVENTS_CAF_TEMPLATE_PATH.'event_registration_options.template.php',
1005 1005
             $template_args
1006 1006
         );
1007 1007
     }
@@ -1110,7 +1110,7 @@  discard block
 block discarded – undo
1110 1110
         $venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1111 1111
 
1112 1112
         foreach ($venues as $venue) {
1113
-            $values[ $venue->ID() ] = $venue->name();
1113
+            $values[$venue->ID()] = $venue->name();
1114 1114
         }
1115 1115
 
1116 1116
         return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
@@ -1144,13 +1144,13 @@  discard block
 block discarded – undo
1144 1144
     {
1145 1145
         $start = EEM_Datetime::instance()->convert_datetime_for_query(
1146 1146
             'DTT_EVT_start',
1147
-            date('Y-m-d') . ' 00:00:00',
1147
+            date('Y-m-d').' 00:00:00',
1148 1148
             'Y-m-d H:i:s',
1149 1149
             'UTC'
1150 1150
         );
1151 1151
         $end = EEM_Datetime::instance()->convert_datetime_for_query(
1152 1152
             'DTT_EVT_start',
1153
-            date('Y-m-d') . ' 23:59:59',
1153
+            date('Y-m-d').' 23:59:59',
1154 1154
             'Y-m-d H:i:s',
1155 1155
             'UTC'
1156 1156
         );
@@ -1180,13 +1180,13 @@  discard block
 block discarded – undo
1180 1180
         $days_this_month = date('t');
1181 1181
         $start = EEM_Datetime::instance()->convert_datetime_for_query(
1182 1182
             'DTT_EVT_start',
1183
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1183
+            $this_year_r.'-'.$this_month_r.'-01 00:00:00',
1184 1184
             'Y-m-d H:i:s',
1185 1185
             'UTC'
1186 1186
         );
1187 1187
         $end = EEM_Datetime::instance()->convert_datetime_for_query(
1188 1188
             'DTT_EVT_start',
1189
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1189
+            $this_year_r.'-'.$this_month_r.'-'.$days_this_month.' 23:59:59',
1190 1190
             'Y-m-d H:i:s',
1191 1191
             'UTC'
1192 1192
         );
@@ -1263,7 +1263,7 @@  discard block
 block discarded – undo
1263 1263
         $offset = ($current_page - 1) * $per_page;
1264 1264
         $limit = array($offset, $per_page);
1265 1265
         if (isset($this->_req_data['s'])) {
1266
-            $sstr = '%' . $this->_req_data['s'] . '%';
1266
+            $sstr = '%'.$this->_req_data['s'].'%';
1267 1267
             $_where['OR'] = array(
1268 1268
                 'TKT_name'        => array('LIKE', $sstr),
1269 1269
                 'TKT_description' => array('LIKE', $sstr),
@@ -1295,16 +1295,16 @@  discard block
 block discarded – undo
1295 1295
         $success = 1;
1296 1296
         $TKT = EEM_Ticket::instance();
1297 1297
         // checkboxes?
1298
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1298
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1299 1299
             // if array has more than one element then success message should be plural
1300 1300
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1301 1301
             // cycle thru the boxes
1302 1302
             foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1303 1303
                 if ($trash) {
1304
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1304
+                    if ( ! $TKT->delete_by_ID($TKT_ID)) {
1305 1305
                         $success = 0;
1306 1306
                     }
1307
-                } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1307
+                } elseif ( ! $TKT->restore_by_ID($TKT_ID)) {
1308 1308
                     $success = 0;
1309 1309
                 }
1310 1310
             }
@@ -1312,10 +1312,10 @@  discard block
 block discarded – undo
1312 1312
             // grab single id and trash
1313 1313
             $TKT_ID = absint($this->_req_data['TKT_ID']);
1314 1314
             if ($trash) {
1315
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1315
+                if ( ! $TKT->delete_by_ID($TKT_ID)) {
1316 1316
                     $success = 0;
1317 1317
                 }
1318
-            } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1318
+            } elseif ( ! $TKT->restore_by_ID($TKT_ID)) {
1319 1319
                 $success = 0;
1320 1320
             }
1321 1321
         }
@@ -1341,20 +1341,20 @@  discard block
 block discarded – undo
1341 1341
     {
1342 1342
         $success = 1;
1343 1343
         // checkboxes?
1344
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1344
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1345 1345
             // if array has more than one element then success message should be plural
1346 1346
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1347 1347
             // cycle thru the boxes
1348 1348
             foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1349 1349
                 // delete
1350
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1350
+                if ( ! $this->_delete_the_ticket($TKT_ID)) {
1351 1351
                     $success = 0;
1352 1352
                 }
1353 1353
             }
1354 1354
         } else {
1355 1355
             // grab single id and trash
1356 1356
             $TKT_ID = absint($this->_req_data['TKT_ID']);
1357
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1357
+            if ( ! $this->_delete_the_ticket($TKT_ID)) {
1358 1358
                 $success = 0;
1359 1359
             }
1360 1360
         }
Please login to merge, or discard this patch.
Indentation   +1378 added lines, -1378 removed lines patch added patch discarded remove patch
@@ -17,1382 +17,1382 @@
 block discarded – undo
17 17
 class Extend_Events_Admin_Page extends Events_Admin_Page
18 18
 {
19 19
 
20
-    /**
21
-     * @var AdvancedEditorAdminFormSection
22
-     */
23
-    protected $advanced_editor_admin_form;
24
-    /**
25
-     * @var AdvancedEditorEntityData
26
-     */
27
-    protected $advanced_editor_data;
28
-
29
-
30
-    /**
31
-     * Extend_Events_Admin_Page constructor.
32
-     *
33
-     * @param bool $routing
34
-     * @throws EE_Error
35
-     * @throws InvalidArgumentException
36
-     * @throws InvalidDataTypeException
37
-     * @throws InvalidInterfaceException
38
-     * @throws ReflectionException
39
-     */
40
-    public function __construct($routing = true)
41
-    {
42
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
43
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
44
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
45
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
46
-        }
47
-        parent::__construct($routing);
48
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'default_event_settings') {
49
-            $this->advanced_editor_admin_form = $this->loader->getShared(
50
-                'EventEspresso\core\domain\services\admin\events\default_settings\AdvancedEditorAdminFormSection'
51
-            );
52
-        }
53
-        if (isset($this->_req_data['action'])
54
-            && ( $this->_req_data['action'] === 'edit' || $this->_req_data['action'] === 'create_new')
55
-        ) {
56
-            $this->advanced_editor_data = $this->loader->getShared(
57
-                'EventEspresso\core\domain\services\admin\events\editor\AdvancedEditorEntityData'
58
-            );
59
-        }
60
-    }
61
-
62
-
63
-    /**
64
-     * Sets routes.
65
-     *
66
-     * @throws EE_Error
67
-     * @throws InvalidArgumentException
68
-     * @throws InvalidDataTypeException
69
-     * @throws InvalidInterfaceException
70
-     * @since $VID:$
71
-     */
72
-    protected function _extend_page_config()
73
-    {
74
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
75
-        // is there a evt_id in the request?
76
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
77
-            ? $this->_req_data['EVT_ID']
78
-            : 0;
79
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
80
-        // tkt_id?
81
-        $tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
82
-            ? $this->_req_data['TKT_ID']
83
-            : 0;
84
-        $new_page_routes = array(
85
-            'duplicate_event'          => array(
86
-                'func'       => '_duplicate_event',
87
-                'capability' => 'ee_edit_event',
88
-                'obj_id'     => $evt_id,
89
-                'noheader'   => true,
90
-            ),
91
-            'ticket_list_table'        => array(
92
-                'func'       => '_tickets_overview_list_table',
93
-                'capability' => 'ee_read_default_tickets',
94
-            ),
95
-            'trash_ticket'             => array(
96
-                'func'       => '_trash_or_restore_ticket',
97
-                'capability' => 'ee_delete_default_ticket',
98
-                'obj_id'     => $tkt_id,
99
-                'noheader'   => true,
100
-                'args'       => array('trash' => true),
101
-            ),
102
-            'trash_tickets'            => array(
103
-                'func'       => '_trash_or_restore_ticket',
104
-                'capability' => 'ee_delete_default_tickets',
105
-                'noheader'   => true,
106
-                'args'       => array('trash' => true),
107
-            ),
108
-            'restore_ticket'           => array(
109
-                'func'       => '_trash_or_restore_ticket',
110
-                'capability' => 'ee_delete_default_ticket',
111
-                'obj_id'     => $tkt_id,
112
-                'noheader'   => true,
113
-            ),
114
-            'restore_tickets'          => array(
115
-                'func'       => '_trash_or_restore_ticket',
116
-                'capability' => 'ee_delete_default_tickets',
117
-                'noheader'   => true,
118
-            ),
119
-            'delete_ticket'            => array(
120
-                'func'       => '_delete_ticket',
121
-                'capability' => 'ee_delete_default_ticket',
122
-                'obj_id'     => $tkt_id,
123
-                'noheader'   => true,
124
-            ),
125
-            'delete_tickets'           => array(
126
-                'func'       => '_delete_ticket',
127
-                'capability' => 'ee_delete_default_tickets',
128
-                'noheader'   => true,
129
-            ),
130
-            'import_page'              => array(
131
-                'func'       => '_import_page',
132
-                'capability' => 'import',
133
-            ),
134
-            'import'                   => array(
135
-                'func'       => '_import_events',
136
-                'capability' => 'import',
137
-                'noheader'   => true,
138
-            ),
139
-            'import_events'            => array(
140
-                'func'       => '_import_events',
141
-                'capability' => 'import',
142
-                'noheader'   => true,
143
-            ),
144
-            'export_events'            => array(
145
-                'func'       => '_events_export',
146
-                'capability' => 'export',
147
-                'noheader'   => true,
148
-            ),
149
-            'export_categories'        => array(
150
-                'func'       => '_categories_export',
151
-                'capability' => 'export',
152
-                'noheader'   => true,
153
-            ),
154
-            'sample_export_file'       => array(
155
-                'func'       => '_sample_export_file',
156
-                'capability' => 'export',
157
-                'noheader'   => true,
158
-            ),
159
-            'update_template_settings' => array(
160
-                'func'       => '_update_template_settings',
161
-                'capability' => 'manage_options',
162
-                'noheader'   => true,
163
-            ),
164
-        );
165
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
166
-        // partial route/config override
167
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
168
-        $this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
169
-        $this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
170
-        $this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
171
-        $this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
172
-        $this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
173
-        // add tickets tab but only if there are more than one default ticket!
174
-        $tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
175
-            array(array('TKT_is_default' => 1)),
176
-            'TKT_ID',
177
-            true
178
-        );
179
-        if ($tkt_count > 1) {
180
-            $new_page_config = array(
181
-                'ticket_list_table' => array(
182
-                    'nav'           => array(
183
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
184
-                        'order' => 60,
185
-                    ),
186
-                    'list_table'    => 'Tickets_List_Table',
187
-                    'require_nonce' => false,
188
-                ),
189
-            );
190
-        }
191
-        // template settings
192
-        $new_page_config['template_settings'] = array(
193
-            'nav'           => array(
194
-                'label' => esc_html__('Templates', 'event_espresso'),
195
-                'order' => 30,
196
-            ),
197
-            'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
198
-            'help_tabs'     => array(
199
-                'general_settings_templates_help_tab' => array(
200
-                    'title'    => esc_html__('Templates', 'event_espresso'),
201
-                    'filename' => 'general_settings_templates',
202
-                ),
203
-            ),
204
-            'help_tour'     => array('Templates_Help_Tour'),
205
-            'require_nonce' => false,
206
-        );
207
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
208
-        // add filters and actions
209
-        // modifying _views
210
-        add_filter(
211
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
212
-            array($this, 'add_additional_datetime_button'),
213
-            10,
214
-            2
215
-        );
216
-        add_filter(
217
-            'FHEE_event_datetime_metabox_clone_button_template',
218
-            array($this, 'add_datetime_clone_button'),
219
-            10,
220
-            2
221
-        );
222
-        add_filter(
223
-            'FHEE_event_datetime_metabox_timezones_template',
224
-            array($this, 'datetime_timezones_template'),
225
-            10,
226
-            2
227
-        );
228
-        // filters for event list table
229
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
230
-        add_filter(
231
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
232
-            array($this, 'extra_list_table_actions'),
233
-            10,
234
-            2
235
-        );
236
-        // legend item
237
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
238
-        add_action('admin_init', array($this, 'admin_init'));
239
-    }
240
-
241
-
242
-    /**
243
-     * admin_init
244
-     */
245
-    public function admin_init()
246
-    {
247
-        EE_Registry::$i18n_js_strings = array_merge(
248
-            EE_Registry::$i18n_js_strings,
249
-            array(
250
-                'image_confirm'          => esc_html__(
251
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
252
-                    'event_espresso'
253
-                ),
254
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
255
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
256
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
257
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
258
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
259
-            )
260
-        );
261
-    }
262
-
263
-
264
-    /**
265
-     * Add per page screen options to the default ticket list table view.
266
-     *
267
-     * @throws InvalidArgumentException
268
-     * @throws InvalidDataTypeException
269
-     * @throws InvalidInterfaceException
270
-     */
271
-    protected function _add_screen_options_ticket_list_table()
272
-    {
273
-        $this->_per_page_screen_option();
274
-    }
275
-
276
-
277
-    /**
278
-     * @param string $return
279
-     * @param int    $id
280
-     * @param string $new_title
281
-     * @param string $new_slug
282
-     * @return string
283
-     */
284
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
285
-    {
286
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
287
-        // make sure this is only when editing
288
-        if (! empty($id)) {
289
-            $href = EE_Admin_Page::add_query_args_and_nonce(
290
-                array('action' => 'duplicate_event', 'EVT_ID' => $id),
291
-                $this->_admin_base_url
292
-            );
293
-            $title = esc_attr__('Duplicate Event', 'event_espresso');
294
-            $return .= '<a href="'
295
-                       . $href
296
-                       . '" title="'
297
-                       . $title
298
-                       . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
299
-                       . $title
300
-                       . '</a>';
301
-        }
302
-        return $return;
303
-    }
304
-
305
-
306
-    /**
307
-     * Set the list table views for the default ticket list table view.
308
-     */
309
-    public function _set_list_table_views_ticket_list_table()
310
-    {
311
-        $this->_views = array(
312
-            'all'     => array(
313
-                'slug'        => 'all',
314
-                'label'       => esc_html__('All', 'event_espresso'),
315
-                'count'       => 0,
316
-                'bulk_action' => array(
317
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
318
-                ),
319
-            ),
320
-            'trashed' => array(
321
-                'slug'        => 'trashed',
322
-                'label'       => esc_html__('Trash', 'event_espresso'),
323
-                'count'       => 0,
324
-                'bulk_action' => array(
325
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
326
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
327
-                ),
328
-            ),
329
-        );
330
-    }
331
-
332
-
333
-    /**
334
-     * Enqueue scripts and styles for the event editor.
335
-     */
336
-    public function load_scripts_styles_edit()
337
-    {
338
-        wp_register_script(
339
-            'ee-event-editor-heartbeat',
340
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
341
-            array('ee_admin_js', 'heartbeat'),
342
-            EVENT_ESPRESSO_VERSION,
343
-            true
344
-        );
345
-        wp_enqueue_script('ee-accounting');
346
-        // styles
347
-        wp_enqueue_style('espresso-ui-theme');
348
-        wp_enqueue_script('event_editor_js');
349
-        wp_enqueue_script('ee-event-editor-heartbeat');
350
-    }
351
-
352
-
353
-    /**
354
-     * Returns template for the additional datetime.
355
-     *
356
-     * @param $template
357
-     * @param $template_args
358
-     * @return mixed
359
-     * @throws DomainException
360
-     */
361
-    public function add_additional_datetime_button($template, $template_args)
362
-    {
363
-        return EEH_Template::display_template(
364
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
365
-            $template_args,
366
-            true
367
-        );
368
-    }
369
-
370
-
371
-    /**
372
-     * Returns the template for cloning a datetime.
373
-     *
374
-     * @param $template
375
-     * @param $template_args
376
-     * @return mixed
377
-     * @throws DomainException
378
-     */
379
-    public function add_datetime_clone_button($template, $template_args)
380
-    {
381
-        return EEH_Template::display_template(
382
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
383
-            $template_args,
384
-            true
385
-        );
386
-    }
387
-
388
-
389
-    /**
390
-     * Returns the template for datetime timezones.
391
-     *
392
-     * @param $template
393
-     * @param $template_args
394
-     * @return mixed
395
-     * @throws DomainException
396
-     */
397
-    public function datetime_timezones_template($template, $template_args)
398
-    {
399
-        return EEH_Template::display_template(
400
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
401
-            $template_args,
402
-            true
403
-        );
404
-    }
405
-
406
-
407
-    /**
408
-     * Sets the views for the default list table view.
409
-     */
410
-    protected function _set_list_table_views_default()
411
-    {
412
-        parent::_set_list_table_views_default();
413
-        $new_views = array(
414
-            'today' => array(
415
-                'slug'        => 'today',
416
-                'label'       => esc_html__('Today', 'event_espresso'),
417
-                'count'       => $this->total_events_today(),
418
-                'bulk_action' => array(
419
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
420
-                ),
421
-            ),
422
-            'month' => array(
423
-                'slug'        => 'month',
424
-                'label'       => esc_html__('This Month', 'event_espresso'),
425
-                'count'       => $this->total_events_this_month(),
426
-                'bulk_action' => array(
427
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
428
-                ),
429
-            ),
430
-        );
431
-        $this->_views = array_merge($this->_views, $new_views);
432
-    }
433
-
434
-
435
-    /**
436
-     * Returns the extra action links for the default list table view.
437
-     *
438
-     * @param array    $action_links
439
-     * @param EE_Event $event
440
-     * @return array
441
-     * @throws EE_Error
442
-     * @throws InvalidArgumentException
443
-     * @throws InvalidDataTypeException
444
-     * @throws InvalidInterfaceException
445
-     * @throws ReflectionException
446
-     */
447
-    public function extra_list_table_actions(array $action_links, EE_Event $event)
448
-    {
449
-        if (EE_Registry::instance()->CAP->current_user_can(
450
-            'ee_read_registrations',
451
-            'espresso_registrations_reports',
452
-            $event->ID()
453
-        )
454
-        ) {
455
-            $reports_query_args = array(
456
-                'action' => 'reports',
457
-                'EVT_ID' => $event->ID(),
458
-            );
459
-            $reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
460
-            $action_links[] = '<a href="'
461
-                              . $reports_link
462
-                              . '" title="'
463
-                              . esc_attr__('View Report', 'event_espresso')
464
-                              . '"><div class="dashicons dashicons-chart-bar"></div></a>'
465
-                              . "\n\t";
466
-        }
467
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
468
-            EE_Registry::instance()->load_helper('MSG_Template');
469
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
470
-                'see_notifications_for',
471
-                null,
472
-                array('EVT_ID' => $event->ID())
473
-            );
474
-        }
475
-        return $action_links;
476
-    }
477
-
478
-
479
-    /**
480
-     * @param $items
481
-     * @return mixed
482
-     */
483
-    public function additional_legend_items($items)
484
-    {
485
-        if (EE_Registry::instance()->CAP->current_user_can(
486
-            'ee_read_registrations',
487
-            'espresso_registrations_reports'
488
-        )
489
-        ) {
490
-            $items['reports'] = array(
491
-                'class' => 'dashicons dashicons-chart-bar',
492
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
493
-            );
494
-        }
495
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
496
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
497
-            // $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
498
-            // (can only use numeric offsets when treating strings as arrays)
499
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
500
-                $items['view_related_messages'] = array(
501
-                    'class' => $related_for_icon['css_class'],
502
-                    'desc'  => $related_for_icon['label'],
503
-                );
504
-            }
505
-        }
506
-        return $items;
507
-    }
508
-
509
-
510
-    /**
511
-     * This is the callback method for the duplicate event route
512
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
513
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
514
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
515
-     * After duplication the redirect is to the new event edit page.
516
-     *
517
-     * @return void
518
-     * @throws EE_Error If EE_Event is not available with given ID
519
-     * @throws InvalidArgumentException
520
-     * @throws InvalidDataTypeException
521
-     * @throws InvalidInterfaceException
522
-     * @throws ReflectionException
523
-     * @access protected
524
-     */
525
-    protected function _duplicate_event()
526
-    {
527
-        // first make sure the ID for the event is in the request.
528
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
529
-        if (! isset($this->_req_data['EVT_ID'])) {
530
-            EE_Error::add_error(
531
-                esc_html__(
532
-                    'In order to duplicate an event an Event ID is required.  None was given.',
533
-                    'event_espresso'
534
-                ),
535
-                __FILE__,
536
-                __FUNCTION__,
537
-                __LINE__
538
-            );
539
-            $this->_redirect_after_action(false, '', '', array(), true);
540
-            return;
541
-        }
542
-        // k we've got EVT_ID so let's use that to get the event we'll duplicate
543
-        $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
544
-        if (! $orig_event instanceof EE_Event) {
545
-            throw new EE_Error(
546
-                sprintf(
547
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
548
-                    $this->_req_data['EVT_ID']
549
-                )
550
-            );
551
-        }
552
-        // k now let's clone the $orig_event before getting relations
553
-        $new_event = clone $orig_event;
554
-        // original datetimes
555
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
556
-        // other original relations
557
-        $orig_ven = $orig_event->get_many_related('Venue');
558
-        // reset the ID and modify other details to make it clear this is a dupe
559
-        $new_event->set('EVT_ID', 0);
560
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
561
-        $new_event->set('EVT_name', $new_name);
562
-        $new_event->set(
563
-            'EVT_slug',
564
-            wp_unique_post_slug(
565
-                sanitize_title($orig_event->name()),
566
-                0,
567
-                'publish',
568
-                'espresso_events',
569
-                0
570
-            )
571
-        );
572
-        $new_event->set('status', 'draft');
573
-        // duplicate discussion settings
574
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
575
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
576
-        // save the new event
577
-        $new_event->save();
578
-        // venues
579
-        foreach ($orig_ven as $ven) {
580
-            $new_event->_add_relation_to($ven, 'Venue');
581
-        }
582
-        $new_event->save();
583
-        // now we need to get the question group relations and handle that
584
-        // first primary question groups
585
-        $orig_primary_qgs = $orig_event->get_many_related(
586
-            'Question_Group',
587
-            [['Event_Question_Group.EQG_primary' => true]]
588
-        );
589
-        if (! empty($orig_primary_qgs)) {
590
-            foreach ($orig_primary_qgs as $id => $obj) {
591
-                if ($obj instanceof EE_Question_Group) {
592
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
593
-                }
594
-            }
595
-        }
596
-        // next additional attendee question groups
597
-        $orig_additional_qgs = $orig_event->get_many_related(
598
-            'Question_Group',
599
-            [['Event_Question_Group.EQG_additional' => true]]
600
-        );
601
-        if (! empty($orig_additional_qgs)) {
602
-            foreach ($orig_additional_qgs as $id => $obj) {
603
-                if ($obj instanceof EE_Question_Group) {
604
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
605
-                }
606
-            }
607
-        }
608
-
609
-        $new_event->save();
610
-
611
-        // k now that we have the new event saved we can loop through the datetimes and start adding relations.
612
-        $cloned_tickets = array();
613
-        foreach ($orig_datetimes as $orig_dtt) {
614
-            if (! $orig_dtt instanceof EE_Datetime) {
615
-                continue;
616
-            }
617
-            $new_dtt = clone $orig_dtt;
618
-            $orig_tkts = $orig_dtt->tickets();
619
-            // save new dtt then add to event
620
-            $new_dtt->set('DTT_ID', 0);
621
-            $new_dtt->set('DTT_sold', 0);
622
-            $new_dtt->set_reserved(0);
623
-            $new_dtt->save();
624
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
625
-            $new_event->save();
626
-            // now let's get the ticket relations setup.
627
-            foreach ((array) $orig_tkts as $orig_tkt) {
628
-                // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
629
-                if (! $orig_tkt instanceof EE_Ticket) {
630
-                    continue;
631
-                }
632
-                // is this ticket archived?  If it is then let's skip
633
-                if ($orig_tkt->get('TKT_deleted')) {
634
-                    continue;
635
-                }
636
-                // does this original ticket already exist in the clone_tickets cache?
637
-                //  If so we'll just use the new ticket from it.
638
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
639
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
640
-                } else {
641
-                    $new_tkt = clone $orig_tkt;
642
-                    // get relations on the $orig_tkt that we need to setup.
643
-                    $orig_prices = $orig_tkt->prices();
644
-                    $new_tkt->set('TKT_ID', 0);
645
-                    $new_tkt->set('TKT_sold', 0);
646
-                    $new_tkt->set('TKT_reserved', 0);
647
-                    $new_tkt->save(); // make sure new ticket has ID.
648
-                    // price relations on new ticket need to be setup.
649
-                    foreach ($orig_prices as $orig_price) {
650
-                        $new_price = clone $orig_price;
651
-                        $new_price->set('PRC_ID', 0);
652
-                        $new_price->save();
653
-                        $new_tkt->_add_relation_to($new_price, 'Price');
654
-                        $new_tkt->save();
655
-                    }
656
-
657
-                    do_action(
658
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
659
-                        $orig_tkt,
660
-                        $new_tkt,
661
-                        $orig_prices,
662
-                        $orig_event,
663
-                        $orig_dtt,
664
-                        $new_dtt
665
-                    );
666
-                }
667
-                // k now we can add the new ticket as a relation to the new datetime
668
-                // and make sure its added to our cached $cloned_tickets array
669
-                // for use with later datetimes that have the same ticket.
670
-                $new_dtt->_add_relation_to($new_tkt, 'Ticket');
671
-                $new_dtt->save();
672
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
673
-            }
674
-        }
675
-        // clone taxonomy information
676
-        $taxonomies_to_clone_with = apply_filters(
677
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
678
-            array('espresso_event_categories', 'espresso_event_type', 'post_tag')
679
-        );
680
-        // get terms for original event (notice)
681
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
682
-        // loop through terms and add them to new event.
683
-        foreach ($orig_terms as $term) {
684
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
685
-        }
686
-
687
-        // duplicate other core WP_Post items for this event.
688
-        // post thumbnail (feature image).
689
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
690
-        if ($feature_image_id) {
691
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
692
-        }
693
-
694
-        // duplicate page_template setting
695
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
696
-        if ($page_template) {
697
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
698
-        }
699
-
700
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
701
-        // now let's redirect to the edit page for this duplicated event if we have a new event id.
702
-        if ($new_event->ID()) {
703
-            $redirect_args = array(
704
-                'post'   => $new_event->ID(),
705
-                'action' => 'edit',
706
-            );
707
-            EE_Error::add_success(
708
-                esc_html__(
709
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
710
-                    'event_espresso'
711
-                )
712
-            );
713
-        } else {
714
-            $redirect_args = array(
715
-                'action' => 'default',
716
-            );
717
-            EE_Error::add_error(
718
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
719
-                __FILE__,
720
-                __FUNCTION__,
721
-                __LINE__
722
-            );
723
-        }
724
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
725
-    }
726
-
727
-
728
-    /**
729
-     * Generates output for the import page.
730
-     *
731
-     * @throws DomainException
732
-     * @throws EE_Error
733
-     * @throws InvalidArgumentException
734
-     * @throws InvalidDataTypeException
735
-     * @throws InvalidInterfaceException
736
-     */
737
-    protected function _import_page()
738
-    {
739
-        $title = esc_html__('Import', 'event_espresso');
740
-        $intro = esc_html__(
741
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
742
-            'event_espresso'
743
-        );
744
-        $form_url = EVENTS_ADMIN_URL;
745
-        $action = 'import_events';
746
-        $type = 'csv';
747
-        $this->_template_args['form'] = EE_Import::instance()->upload_form(
748
-            $title,
749
-            $intro,
750
-            $form_url,
751
-            $action,
752
-            $type
753
-        );
754
-        $this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
755
-            array('action' => 'sample_export_file'),
756
-            $this->_admin_base_url
757
-        );
758
-        $content = EEH_Template::display_template(
759
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
760
-            $this->_template_args,
761
-            true
762
-        );
763
-        $this->_template_args['admin_page_content'] = $content;
764
-        $this->display_admin_page_with_sidebar();
765
-    }
766
-
767
-
768
-    /**
769
-     * _import_events
770
-     * This handles displaying the screen and running imports for importing events.
771
-     *
772
-     * @return void
773
-     * @throws EE_Error
774
-     * @throws InvalidArgumentException
775
-     * @throws InvalidDataTypeException
776
-     * @throws InvalidInterfaceException
777
-     */
778
-    protected function _import_events()
779
-    {
780
-        require_once(EE_CLASSES . 'EE_Import.class.php');
781
-        $success = EE_Import::instance()->import();
782
-        $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
783
-    }
784
-
785
-
786
-    /**
787
-     * _events_export
788
-     * Will export all (or just the given event) to a Excel compatible file.
789
-     *
790
-     * @access protected
791
-     * @return void
792
-     */
793
-    protected function _events_export()
794
-    {
795
-        if (isset($this->_req_data['EVT_ID'])) {
796
-            $event_ids = $this->_req_data['EVT_ID'];
797
-        } elseif (isset($this->_req_data['EVT_IDs'])) {
798
-            $event_ids = $this->_req_data['EVT_IDs'];
799
-        } else {
800
-            $event_ids = null;
801
-        }
802
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
803
-        $new_request_args = array(
804
-            'export' => 'report',
805
-            'action' => 'all_event_data',
806
-            'EVT_ID' => $event_ids,
807
-        );
808
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
809
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
810
-            require_once(EE_CLASSES . 'EE_Export.class.php');
811
-            $EE_Export = EE_Export::instance($this->_req_data);
812
-            $EE_Export->export();
813
-        }
814
-    }
815
-
816
-
817
-    /**
818
-     * handle category exports()
819
-     *
820
-     * @return void
821
-     */
822
-    protected function _categories_export()
823
-    {
824
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
825
-        $new_request_args = array(
826
-            'export'       => 'report',
827
-            'action'       => 'categories',
828
-            'category_ids' => $this->_req_data['EVT_CAT_ID'],
829
-        );
830
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
831
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
832
-            require_once(EE_CLASSES . 'EE_Export.class.php');
833
-            $EE_Export = EE_Export::instance($this->_req_data);
834
-            $EE_Export->export();
835
-        }
836
-    }
837
-
838
-
839
-    /**
840
-     * Creates a sample CSV file for importing
841
-     */
842
-    protected function _sample_export_file()
843
-    {
844
-        // require_once(EE_CLASSES . 'EE_Export.class.php');
845
-        EE_Export::instance()->export_sample();
846
-    }
847
-
848
-
849
-    /*************        Template Settings        *************/
850
-    /**
851
-     * Generates template settings page output
852
-     *
853
-     * @throws DomainException
854
-     * @throws EE_Error
855
-     * @throws InvalidArgumentException
856
-     * @throws InvalidDataTypeException
857
-     * @throws InvalidInterfaceException
858
-     */
859
-    protected function _template_settings()
860
-    {
861
-        $this->_template_args['values'] = $this->_yes_no_values;
862
-        /**
863
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
864
-         * from General_Settings_Admin_Page to here.
865
-         */
866
-        $this->_template_args = apply_filters(
867
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
868
-            $this->_template_args
869
-        );
870
-        $this->_set_add_edit_form_tags('update_template_settings');
871
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
872
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
873
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
874
-            $this->_template_args,
875
-            true
876
-        );
877
-        $this->display_admin_page_with_sidebar();
878
-    }
879
-
880
-
881
-    /**
882
-     * Handler for updating template settings.
883
-     *
884
-     * @throws EE_Error
885
-     * @throws InvalidArgumentException
886
-     * @throws InvalidDataTypeException
887
-     * @throws InvalidInterfaceException
888
-     */
889
-    protected function _update_template_settings()
890
-    {
891
-        /**
892
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
893
-         * from General_Settings_Admin_Page to here.
894
-         */
895
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
896
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
897
-            EE_Registry::instance()->CFG->template_settings,
898
-            $this->_req_data
899
-        );
900
-        // update custom post type slugs and detect if we need to flush rewrite rules
901
-        $old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
902
-        EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
903
-            ? EE_Registry::instance()->CFG->core->event_cpt_slug
904
-            : EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
905
-        $what = 'Template Settings';
906
-        $success = $this->_update_espresso_configuration(
907
-            $what,
908
-            EE_Registry::instance()->CFG->template_settings,
909
-            __FILE__,
910
-            __FUNCTION__,
911
-            __LINE__
912
-        );
913
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
914
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
915
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
916
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
917
-            );
918
-            $rewrite_rules->flush();
919
-        }
920
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
921
-    }
922
-
923
-
924
-    /**
925
-     * _premium_event_editor_meta_boxes
926
-     * add all metaboxes related to the event_editor
927
-     *
928
-     * @access protected
929
-     * @return void
930
-     * @throws EE_Error
931
-     * @throws InvalidArgumentException
932
-     * @throws InvalidDataTypeException
933
-     * @throws InvalidInterfaceException
934
-     * @throws ReflectionException
935
-     */
936
-    protected function _premium_event_editor_meta_boxes()
937
-    {
938
-        $this->verify_cpt_object();
939
-        add_meta_box(
940
-            'espresso_event_editor_event_options',
941
-            esc_html__('Event Registration Options', 'event_espresso'),
942
-            array($this, 'registration_options_meta_box'),
943
-            $this->page_slug,
944
-            'side',
945
-            'core'
946
-        );
947
-    }
948
-
949
-
950
-    /**
951
-     * override caf metabox
952
-     *
953
-     * @return void
954
-     * @throws DomainException
955
-     * @throws EE_Error
956
-     */
957
-    public function registration_options_meta_box()
958
-    {
959
-        $yes_no_values = array(
960
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
961
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
962
-        );
963
-        $default_reg_status_values = EEM_Registration::reg_status_array(
964
-            array(
965
-                EEM_Registration::status_id_cancelled,
966
-                EEM_Registration::status_id_declined,
967
-                EEM_Registration::status_id_incomplete,
968
-                EEM_Registration::status_id_wait_list,
969
-            ),
970
-            true
971
-        );
972
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
973
-        $template_args['_event'] = $this->_cpt_model_obj;
974
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
975
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
976
-            'default_reg_status',
977
-            $default_reg_status_values,
978
-            $this->_cpt_model_obj->default_registration_status()
979
-        );
980
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
981
-            'display_desc',
982
-            $yes_no_values,
983
-            $this->_cpt_model_obj->display_description()
984
-        );
985
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
986
-            'display_ticket_selector',
987
-            $yes_no_values,
988
-            $this->_cpt_model_obj->display_ticket_selector(),
989
-            '',
990
-            '',
991
-            false
992
-        );
993
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
994
-            'EVT_default_registration_status',
995
-            $default_reg_status_values,
996
-            $this->_cpt_model_obj->default_registration_status()
997
-        );
998
-        $template_args['additional_registration_options'] = apply_filters(
999
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1000
-            '',
1001
-            $template_args,
1002
-            $yes_no_values,
1003
-            $default_reg_status_values
1004
-        );
1005
-        EEH_Template::display_template(
1006
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
1007
-            $template_args
1008
-        );
1009
-    }
1010
-
1011
-
1012
-
1013
-    /**
1014
-     * wp_list_table_mods for caf
1015
-     * ============================
1016
-     */
1017
-    /**
1018
-     * hook into list table filters and provide filters for caffeinated list table
1019
-     *
1020
-     * @param array $old_filters    any existing filters present
1021
-     * @param array $list_table_obj the list table object
1022
-     * @return array                  new filters
1023
-     * @throws EE_Error
1024
-     * @throws InvalidArgumentException
1025
-     * @throws InvalidDataTypeException
1026
-     * @throws InvalidInterfaceException
1027
-     * @throws ReflectionException
1028
-     */
1029
-    public function list_table_filters($old_filters, $list_table_obj)
1030
-    {
1031
-        $filters = array();
1032
-        // first month/year filters
1033
-        $filters[] = $this->espresso_event_months_dropdown();
1034
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1035
-        // active status dropdown
1036
-        if ($status !== 'draft') {
1037
-            $filters[] = $this->active_status_dropdown(
1038
-                isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
1039
-            );
1040
-            $filters[] = $this->venuesDropdown(
1041
-                isset($this->_req_data['venue']) ? $this->_req_data['venue'] : ''
1042
-            );
1043
-        }
1044
-        // category filter
1045
-        $filters[] = $this->category_dropdown();
1046
-        return array_merge($old_filters, $filters);
1047
-    }
1048
-
1049
-
1050
-    /**
1051
-     * espresso_event_months_dropdown
1052
-     *
1053
-     * @access public
1054
-     * @return string                dropdown listing month/year selections for events.
1055
-     */
1056
-    public function espresso_event_months_dropdown()
1057
-    {
1058
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
1059
-        // Note we need to include any other filters that are set!
1060
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1061
-        // categories?
1062
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1063
-            ? $this->_req_data['EVT_CAT']
1064
-            : null;
1065
-        // active status?
1066
-        $active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1067
-        $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1068
-        return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1069
-    }
1070
-
1071
-
1072
-    /**
1073
-     * returns a list of "active" statuses on the event
1074
-     *
1075
-     * @param  string $current_value whatever the current active status is
1076
-     * @return string
1077
-     */
1078
-    public function active_status_dropdown($current_value = '')
1079
-    {
1080
-        $select_name = 'active_status';
1081
-        $values = array(
1082
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1083
-            'active'   => esc_html__('Active', 'event_espresso'),
1084
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1085
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1086
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1087
-        );
1088
-
1089
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1090
-    }
1091
-
1092
-
1093
-    /**
1094
-     * returns a list of "venues"
1095
-     *
1096
-     * @param string $current_value whatever the current active status is
1097
-     * @return string
1098
-     * @throws EE_Error
1099
-     * @throws InvalidArgumentException
1100
-     * @throws InvalidDataTypeException
1101
-     * @throws InvalidInterfaceException
1102
-     * @throws ReflectionException
1103
-     */
1104
-    protected function venuesDropdown($current_value = '')
1105
-    {
1106
-        $select_name = 'venue';
1107
-        $values = array(
1108
-            '' => esc_html__('All Venues', 'event_espresso'),
1109
-        );
1110
-        // populate the list of venues.
1111
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1112
-        $venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1113
-
1114
-        foreach ($venues as $venue) {
1115
-            $values[ $venue->ID() ] = $venue->name();
1116
-        }
1117
-
1118
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1119
-    }
1120
-
1121
-
1122
-    /**
1123
-     * output a dropdown of the categories for the category filter on the event admin list table
1124
-     *
1125
-     * @access  public
1126
-     * @return string html
1127
-     */
1128
-    public function category_dropdown()
1129
-    {
1130
-        $cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1131
-        return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1132
-    }
1133
-
1134
-
1135
-    /**
1136
-     * get total number of events today
1137
-     *
1138
-     * @access public
1139
-     * @return int
1140
-     * @throws EE_Error
1141
-     * @throws InvalidArgumentException
1142
-     * @throws InvalidDataTypeException
1143
-     * @throws InvalidInterfaceException
1144
-     */
1145
-    public function total_events_today()
1146
-    {
1147
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1148
-            'DTT_EVT_start',
1149
-            date('Y-m-d') . ' 00:00:00',
1150
-            'Y-m-d H:i:s',
1151
-            'UTC'
1152
-        );
1153
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1154
-            'DTT_EVT_start',
1155
-            date('Y-m-d') . ' 23:59:59',
1156
-            'Y-m-d H:i:s',
1157
-            'UTC'
1158
-        );
1159
-        $where = array(
1160
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1161
-        );
1162
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1163
-        return $count;
1164
-    }
1165
-
1166
-
1167
-    /**
1168
-     * get total number of events this month
1169
-     *
1170
-     * @access public
1171
-     * @return int
1172
-     * @throws EE_Error
1173
-     * @throws InvalidArgumentException
1174
-     * @throws InvalidDataTypeException
1175
-     * @throws InvalidInterfaceException
1176
-     */
1177
-    public function total_events_this_month()
1178
-    {
1179
-        // Dates
1180
-        $this_year_r = date('Y');
1181
-        $this_month_r = date('m');
1182
-        $days_this_month = date('t');
1183
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1184
-            'DTT_EVT_start',
1185
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1186
-            'Y-m-d H:i:s',
1187
-            'UTC'
1188
-        );
1189
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1190
-            'DTT_EVT_start',
1191
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1192
-            'Y-m-d H:i:s',
1193
-            'UTC'
1194
-        );
1195
-        $where = array(
1196
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1197
-        );
1198
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1199
-        return $count;
1200
-    }
1201
-
1202
-
1203
-    /** DEFAULT TICKETS STUFF **/
1204
-
1205
-    /**
1206
-     * Output default tickets list table view.
1207
-     *
1208
-     * @throws DomainException
1209
-     * @throws EE_Error
1210
-     * @throws InvalidArgumentException
1211
-     * @throws InvalidDataTypeException
1212
-     * @throws InvalidInterfaceException
1213
-     */
1214
-    public function _tickets_overview_list_table()
1215
-    {
1216
-        $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1217
-        $this->display_admin_list_table_page_with_no_sidebar();
1218
-    }
1219
-
1220
-
1221
-    /**
1222
-     * @param int  $per_page
1223
-     * @param bool $count
1224
-     * @param bool $trashed
1225
-     * @return EE_Soft_Delete_Base_Class[]|int
1226
-     * @throws EE_Error
1227
-     * @throws InvalidArgumentException
1228
-     * @throws InvalidDataTypeException
1229
-     * @throws InvalidInterfaceException
1230
-     */
1231
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1232
-    {
1233
-        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1234
-        $order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1235
-        switch ($orderby) {
1236
-            case 'TKT_name':
1237
-                $orderby = array('TKT_name' => $order);
1238
-                break;
1239
-            case 'TKT_price':
1240
-                $orderby = array('TKT_price' => $order);
1241
-                break;
1242
-            case 'TKT_uses':
1243
-                $orderby = array('TKT_uses' => $order);
1244
-                break;
1245
-            case 'TKT_min':
1246
-                $orderby = array('TKT_min' => $order);
1247
-                break;
1248
-            case 'TKT_max':
1249
-                $orderby = array('TKT_max' => $order);
1250
-                break;
1251
-            case 'TKT_qty':
1252
-                $orderby = array('TKT_qty' => $order);
1253
-                break;
1254
-        }
1255
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1256
-            ? $this->_req_data['paged']
1257
-            : 1;
1258
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1259
-            ? $this->_req_data['perpage']
1260
-            : $per_page;
1261
-        $_where = array(
1262
-            'TKT_is_default' => 1,
1263
-            'TKT_deleted'    => $trashed,
1264
-        );
1265
-        $offset = ($current_page - 1) * $per_page;
1266
-        $limit = array($offset, $per_page);
1267
-        if (isset($this->_req_data['s'])) {
1268
-            $sstr = '%' . $this->_req_data['s'] . '%';
1269
-            $_where['OR'] = array(
1270
-                'TKT_name'        => array('LIKE', $sstr),
1271
-                'TKT_description' => array('LIKE', $sstr),
1272
-            );
1273
-        }
1274
-        $query_params = array(
1275
-            $_where,
1276
-            'order_by' => $orderby,
1277
-            'limit'    => $limit,
1278
-            'group_by' => 'TKT_ID',
1279
-        );
1280
-        if ($count) {
1281
-            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1282
-        } else {
1283
-            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1284
-        }
1285
-    }
1286
-
1287
-
1288
-    /**
1289
-     * @param bool $trash
1290
-     * @throws EE_Error
1291
-     * @throws InvalidArgumentException
1292
-     * @throws InvalidDataTypeException
1293
-     * @throws InvalidInterfaceException
1294
-     */
1295
-    protected function _trash_or_restore_ticket($trash = false)
1296
-    {
1297
-        $success = 1;
1298
-        $TKT = EEM_Ticket::instance();
1299
-        // checkboxes?
1300
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1301
-            // if array has more than one element then success message should be plural
1302
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1303
-            // cycle thru the boxes
1304
-            foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1305
-                if ($trash) {
1306
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1307
-                        $success = 0;
1308
-                    }
1309
-                } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1310
-                    $success = 0;
1311
-                }
1312
-            }
1313
-        } else {
1314
-            // grab single id and trash
1315
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1316
-            if ($trash) {
1317
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1318
-                    $success = 0;
1319
-                }
1320
-            } elseif (! $TKT->restore_by_ID($TKT_ID)) {
1321
-                $success = 0;
1322
-            }
1323
-        }
1324
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1325
-        $query_args = array(
1326
-            'action' => 'ticket_list_table',
1327
-            'status' => $trash ? '' : 'trashed',
1328
-        );
1329
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1330
-    }
1331
-
1332
-
1333
-    /**
1334
-     * Handles trashing default ticket.
1335
-     *
1336
-     * @throws EE_Error
1337
-     * @throws InvalidArgumentException
1338
-     * @throws InvalidDataTypeException
1339
-     * @throws InvalidInterfaceException
1340
-     * @throws ReflectionException
1341
-     */
1342
-    protected function _delete_ticket()
1343
-    {
1344
-        $success = 1;
1345
-        // checkboxes?
1346
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1347
-            // if array has more than one element then success message should be plural
1348
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1349
-            // cycle thru the boxes
1350
-            foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1351
-                // delete
1352
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1353
-                    $success = 0;
1354
-                }
1355
-            }
1356
-        } else {
1357
-            // grab single id and trash
1358
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1359
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1360
-                $success = 0;
1361
-            }
1362
-        }
1363
-        $action_desc = 'deleted';
1364
-        $query_args = array(
1365
-            'action' => 'ticket_list_table',
1366
-            'status' => 'trashed',
1367
-        );
1368
-        // fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1369
-        if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1370
-            array(array('TKT_is_default' => 1)),
1371
-            'TKT_ID',
1372
-            true
1373
-        )
1374
-        ) {
1375
-            $query_args = array();
1376
-        }
1377
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1378
-    }
1379
-
1380
-
1381
-    /**
1382
-     * @param int $TKT_ID
1383
-     * @return bool|int
1384
-     * @throws EE_Error
1385
-     * @throws InvalidArgumentException
1386
-     * @throws InvalidDataTypeException
1387
-     * @throws InvalidInterfaceException
1388
-     * @throws ReflectionException
1389
-     */
1390
-    protected function _delete_the_ticket($TKT_ID)
1391
-    {
1392
-        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1393
-        $tkt->_remove_relations('Datetime');
1394
-        // delete all related prices first
1395
-        $tkt->delete_related_permanently('Price');
1396
-        return $tkt->delete_permanently();
1397
-    }
20
+	/**
21
+	 * @var AdvancedEditorAdminFormSection
22
+	 */
23
+	protected $advanced_editor_admin_form;
24
+	/**
25
+	 * @var AdvancedEditorEntityData
26
+	 */
27
+	protected $advanced_editor_data;
28
+
29
+
30
+	/**
31
+	 * Extend_Events_Admin_Page constructor.
32
+	 *
33
+	 * @param bool $routing
34
+	 * @throws EE_Error
35
+	 * @throws InvalidArgumentException
36
+	 * @throws InvalidDataTypeException
37
+	 * @throws InvalidInterfaceException
38
+	 * @throws ReflectionException
39
+	 */
40
+	public function __construct($routing = true)
41
+	{
42
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
43
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
44
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
45
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
46
+		}
47
+		parent::__construct($routing);
48
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'default_event_settings') {
49
+			$this->advanced_editor_admin_form = $this->loader->getShared(
50
+				'EventEspresso\core\domain\services\admin\events\default_settings\AdvancedEditorAdminFormSection'
51
+			);
52
+		}
53
+		if (isset($this->_req_data['action'])
54
+			&& ( $this->_req_data['action'] === 'edit' || $this->_req_data['action'] === 'create_new')
55
+		) {
56
+			$this->advanced_editor_data = $this->loader->getShared(
57
+				'EventEspresso\core\domain\services\admin\events\editor\AdvancedEditorEntityData'
58
+			);
59
+		}
60
+	}
61
+
62
+
63
+	/**
64
+	 * Sets routes.
65
+	 *
66
+	 * @throws EE_Error
67
+	 * @throws InvalidArgumentException
68
+	 * @throws InvalidDataTypeException
69
+	 * @throws InvalidInterfaceException
70
+	 * @since $VID:$
71
+	 */
72
+	protected function _extend_page_config()
73
+	{
74
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
75
+		// is there a evt_id in the request?
76
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
77
+			? $this->_req_data['EVT_ID']
78
+			: 0;
79
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
80
+		// tkt_id?
81
+		$tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
82
+			? $this->_req_data['TKT_ID']
83
+			: 0;
84
+		$new_page_routes = array(
85
+			'duplicate_event'          => array(
86
+				'func'       => '_duplicate_event',
87
+				'capability' => 'ee_edit_event',
88
+				'obj_id'     => $evt_id,
89
+				'noheader'   => true,
90
+			),
91
+			'ticket_list_table'        => array(
92
+				'func'       => '_tickets_overview_list_table',
93
+				'capability' => 'ee_read_default_tickets',
94
+			),
95
+			'trash_ticket'             => array(
96
+				'func'       => '_trash_or_restore_ticket',
97
+				'capability' => 'ee_delete_default_ticket',
98
+				'obj_id'     => $tkt_id,
99
+				'noheader'   => true,
100
+				'args'       => array('trash' => true),
101
+			),
102
+			'trash_tickets'            => array(
103
+				'func'       => '_trash_or_restore_ticket',
104
+				'capability' => 'ee_delete_default_tickets',
105
+				'noheader'   => true,
106
+				'args'       => array('trash' => true),
107
+			),
108
+			'restore_ticket'           => array(
109
+				'func'       => '_trash_or_restore_ticket',
110
+				'capability' => 'ee_delete_default_ticket',
111
+				'obj_id'     => $tkt_id,
112
+				'noheader'   => true,
113
+			),
114
+			'restore_tickets'          => array(
115
+				'func'       => '_trash_or_restore_ticket',
116
+				'capability' => 'ee_delete_default_tickets',
117
+				'noheader'   => true,
118
+			),
119
+			'delete_ticket'            => array(
120
+				'func'       => '_delete_ticket',
121
+				'capability' => 'ee_delete_default_ticket',
122
+				'obj_id'     => $tkt_id,
123
+				'noheader'   => true,
124
+			),
125
+			'delete_tickets'           => array(
126
+				'func'       => '_delete_ticket',
127
+				'capability' => 'ee_delete_default_tickets',
128
+				'noheader'   => true,
129
+			),
130
+			'import_page'              => array(
131
+				'func'       => '_import_page',
132
+				'capability' => 'import',
133
+			),
134
+			'import'                   => array(
135
+				'func'       => '_import_events',
136
+				'capability' => 'import',
137
+				'noheader'   => true,
138
+			),
139
+			'import_events'            => array(
140
+				'func'       => '_import_events',
141
+				'capability' => 'import',
142
+				'noheader'   => true,
143
+			),
144
+			'export_events'            => array(
145
+				'func'       => '_events_export',
146
+				'capability' => 'export',
147
+				'noheader'   => true,
148
+			),
149
+			'export_categories'        => array(
150
+				'func'       => '_categories_export',
151
+				'capability' => 'export',
152
+				'noheader'   => true,
153
+			),
154
+			'sample_export_file'       => array(
155
+				'func'       => '_sample_export_file',
156
+				'capability' => 'export',
157
+				'noheader'   => true,
158
+			),
159
+			'update_template_settings' => array(
160
+				'func'       => '_update_template_settings',
161
+				'capability' => 'manage_options',
162
+				'noheader'   => true,
163
+			),
164
+		);
165
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
166
+		// partial route/config override
167
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
168
+		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
169
+		$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
170
+		$this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
171
+		$this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
172
+		$this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
173
+		// add tickets tab but only if there are more than one default ticket!
174
+		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
175
+			array(array('TKT_is_default' => 1)),
176
+			'TKT_ID',
177
+			true
178
+		);
179
+		if ($tkt_count > 1) {
180
+			$new_page_config = array(
181
+				'ticket_list_table' => array(
182
+					'nav'           => array(
183
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
184
+						'order' => 60,
185
+					),
186
+					'list_table'    => 'Tickets_List_Table',
187
+					'require_nonce' => false,
188
+				),
189
+			);
190
+		}
191
+		// template settings
192
+		$new_page_config['template_settings'] = array(
193
+			'nav'           => array(
194
+				'label' => esc_html__('Templates', 'event_espresso'),
195
+				'order' => 30,
196
+			),
197
+			'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
198
+			'help_tabs'     => array(
199
+				'general_settings_templates_help_tab' => array(
200
+					'title'    => esc_html__('Templates', 'event_espresso'),
201
+					'filename' => 'general_settings_templates',
202
+				),
203
+			),
204
+			'help_tour'     => array('Templates_Help_Tour'),
205
+			'require_nonce' => false,
206
+		);
207
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
208
+		// add filters and actions
209
+		// modifying _views
210
+		add_filter(
211
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
212
+			array($this, 'add_additional_datetime_button'),
213
+			10,
214
+			2
215
+		);
216
+		add_filter(
217
+			'FHEE_event_datetime_metabox_clone_button_template',
218
+			array($this, 'add_datetime_clone_button'),
219
+			10,
220
+			2
221
+		);
222
+		add_filter(
223
+			'FHEE_event_datetime_metabox_timezones_template',
224
+			array($this, 'datetime_timezones_template'),
225
+			10,
226
+			2
227
+		);
228
+		// filters for event list table
229
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
230
+		add_filter(
231
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
232
+			array($this, 'extra_list_table_actions'),
233
+			10,
234
+			2
235
+		);
236
+		// legend item
237
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
238
+		add_action('admin_init', array($this, 'admin_init'));
239
+	}
240
+
241
+
242
+	/**
243
+	 * admin_init
244
+	 */
245
+	public function admin_init()
246
+	{
247
+		EE_Registry::$i18n_js_strings = array_merge(
248
+			EE_Registry::$i18n_js_strings,
249
+			array(
250
+				'image_confirm'          => esc_html__(
251
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
252
+					'event_espresso'
253
+				),
254
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
255
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
256
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
257
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
258
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
259
+			)
260
+		);
261
+	}
262
+
263
+
264
+	/**
265
+	 * Add per page screen options to the default ticket list table view.
266
+	 *
267
+	 * @throws InvalidArgumentException
268
+	 * @throws InvalidDataTypeException
269
+	 * @throws InvalidInterfaceException
270
+	 */
271
+	protected function _add_screen_options_ticket_list_table()
272
+	{
273
+		$this->_per_page_screen_option();
274
+	}
275
+
276
+
277
+	/**
278
+	 * @param string $return
279
+	 * @param int    $id
280
+	 * @param string $new_title
281
+	 * @param string $new_slug
282
+	 * @return string
283
+	 */
284
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
285
+	{
286
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
287
+		// make sure this is only when editing
288
+		if (! empty($id)) {
289
+			$href = EE_Admin_Page::add_query_args_and_nonce(
290
+				array('action' => 'duplicate_event', 'EVT_ID' => $id),
291
+				$this->_admin_base_url
292
+			);
293
+			$title = esc_attr__('Duplicate Event', 'event_espresso');
294
+			$return .= '<a href="'
295
+					   . $href
296
+					   . '" title="'
297
+					   . $title
298
+					   . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
299
+					   . $title
300
+					   . '</a>';
301
+		}
302
+		return $return;
303
+	}
304
+
305
+
306
+	/**
307
+	 * Set the list table views for the default ticket list table view.
308
+	 */
309
+	public function _set_list_table_views_ticket_list_table()
310
+	{
311
+		$this->_views = array(
312
+			'all'     => array(
313
+				'slug'        => 'all',
314
+				'label'       => esc_html__('All', 'event_espresso'),
315
+				'count'       => 0,
316
+				'bulk_action' => array(
317
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
318
+				),
319
+			),
320
+			'trashed' => array(
321
+				'slug'        => 'trashed',
322
+				'label'       => esc_html__('Trash', 'event_espresso'),
323
+				'count'       => 0,
324
+				'bulk_action' => array(
325
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
326
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
327
+				),
328
+			),
329
+		);
330
+	}
331
+
332
+
333
+	/**
334
+	 * Enqueue scripts and styles for the event editor.
335
+	 */
336
+	public function load_scripts_styles_edit()
337
+	{
338
+		wp_register_script(
339
+			'ee-event-editor-heartbeat',
340
+			EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
341
+			array('ee_admin_js', 'heartbeat'),
342
+			EVENT_ESPRESSO_VERSION,
343
+			true
344
+		);
345
+		wp_enqueue_script('ee-accounting');
346
+		// styles
347
+		wp_enqueue_style('espresso-ui-theme');
348
+		wp_enqueue_script('event_editor_js');
349
+		wp_enqueue_script('ee-event-editor-heartbeat');
350
+	}
351
+
352
+
353
+	/**
354
+	 * Returns template for the additional datetime.
355
+	 *
356
+	 * @param $template
357
+	 * @param $template_args
358
+	 * @return mixed
359
+	 * @throws DomainException
360
+	 */
361
+	public function add_additional_datetime_button($template, $template_args)
362
+	{
363
+		return EEH_Template::display_template(
364
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
365
+			$template_args,
366
+			true
367
+		);
368
+	}
369
+
370
+
371
+	/**
372
+	 * Returns the template for cloning a datetime.
373
+	 *
374
+	 * @param $template
375
+	 * @param $template_args
376
+	 * @return mixed
377
+	 * @throws DomainException
378
+	 */
379
+	public function add_datetime_clone_button($template, $template_args)
380
+	{
381
+		return EEH_Template::display_template(
382
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
383
+			$template_args,
384
+			true
385
+		);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Returns the template for datetime timezones.
391
+	 *
392
+	 * @param $template
393
+	 * @param $template_args
394
+	 * @return mixed
395
+	 * @throws DomainException
396
+	 */
397
+	public function datetime_timezones_template($template, $template_args)
398
+	{
399
+		return EEH_Template::display_template(
400
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
401
+			$template_args,
402
+			true
403
+		);
404
+	}
405
+
406
+
407
+	/**
408
+	 * Sets the views for the default list table view.
409
+	 */
410
+	protected function _set_list_table_views_default()
411
+	{
412
+		parent::_set_list_table_views_default();
413
+		$new_views = array(
414
+			'today' => array(
415
+				'slug'        => 'today',
416
+				'label'       => esc_html__('Today', 'event_espresso'),
417
+				'count'       => $this->total_events_today(),
418
+				'bulk_action' => array(
419
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
420
+				),
421
+			),
422
+			'month' => array(
423
+				'slug'        => 'month',
424
+				'label'       => esc_html__('This Month', 'event_espresso'),
425
+				'count'       => $this->total_events_this_month(),
426
+				'bulk_action' => array(
427
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
428
+				),
429
+			),
430
+		);
431
+		$this->_views = array_merge($this->_views, $new_views);
432
+	}
433
+
434
+
435
+	/**
436
+	 * Returns the extra action links for the default list table view.
437
+	 *
438
+	 * @param array    $action_links
439
+	 * @param EE_Event $event
440
+	 * @return array
441
+	 * @throws EE_Error
442
+	 * @throws InvalidArgumentException
443
+	 * @throws InvalidDataTypeException
444
+	 * @throws InvalidInterfaceException
445
+	 * @throws ReflectionException
446
+	 */
447
+	public function extra_list_table_actions(array $action_links, EE_Event $event)
448
+	{
449
+		if (EE_Registry::instance()->CAP->current_user_can(
450
+			'ee_read_registrations',
451
+			'espresso_registrations_reports',
452
+			$event->ID()
453
+		)
454
+		) {
455
+			$reports_query_args = array(
456
+				'action' => 'reports',
457
+				'EVT_ID' => $event->ID(),
458
+			);
459
+			$reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
460
+			$action_links[] = '<a href="'
461
+							  . $reports_link
462
+							  . '" title="'
463
+							  . esc_attr__('View Report', 'event_espresso')
464
+							  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
465
+							  . "\n\t";
466
+		}
467
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
468
+			EE_Registry::instance()->load_helper('MSG_Template');
469
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
470
+				'see_notifications_for',
471
+				null,
472
+				array('EVT_ID' => $event->ID())
473
+			);
474
+		}
475
+		return $action_links;
476
+	}
477
+
478
+
479
+	/**
480
+	 * @param $items
481
+	 * @return mixed
482
+	 */
483
+	public function additional_legend_items($items)
484
+	{
485
+		if (EE_Registry::instance()->CAP->current_user_can(
486
+			'ee_read_registrations',
487
+			'espresso_registrations_reports'
488
+		)
489
+		) {
490
+			$items['reports'] = array(
491
+				'class' => 'dashicons dashicons-chart-bar',
492
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
493
+			);
494
+		}
495
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
496
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
497
+			// $related_for_icon can sometimes be a string so 'css_class' would be an illegal offset
498
+			// (can only use numeric offsets when treating strings as arrays)
499
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
500
+				$items['view_related_messages'] = array(
501
+					'class' => $related_for_icon['css_class'],
502
+					'desc'  => $related_for_icon['label'],
503
+				);
504
+			}
505
+		}
506
+		return $items;
507
+	}
508
+
509
+
510
+	/**
511
+	 * This is the callback method for the duplicate event route
512
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
513
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
514
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
515
+	 * After duplication the redirect is to the new event edit page.
516
+	 *
517
+	 * @return void
518
+	 * @throws EE_Error If EE_Event is not available with given ID
519
+	 * @throws InvalidArgumentException
520
+	 * @throws InvalidDataTypeException
521
+	 * @throws InvalidInterfaceException
522
+	 * @throws ReflectionException
523
+	 * @access protected
524
+	 */
525
+	protected function _duplicate_event()
526
+	{
527
+		// first make sure the ID for the event is in the request.
528
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
529
+		if (! isset($this->_req_data['EVT_ID'])) {
530
+			EE_Error::add_error(
531
+				esc_html__(
532
+					'In order to duplicate an event an Event ID is required.  None was given.',
533
+					'event_espresso'
534
+				),
535
+				__FILE__,
536
+				__FUNCTION__,
537
+				__LINE__
538
+			);
539
+			$this->_redirect_after_action(false, '', '', array(), true);
540
+			return;
541
+		}
542
+		// k we've got EVT_ID so let's use that to get the event we'll duplicate
543
+		$orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
544
+		if (! $orig_event instanceof EE_Event) {
545
+			throw new EE_Error(
546
+				sprintf(
547
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
548
+					$this->_req_data['EVT_ID']
549
+				)
550
+			);
551
+		}
552
+		// k now let's clone the $orig_event before getting relations
553
+		$new_event = clone $orig_event;
554
+		// original datetimes
555
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
556
+		// other original relations
557
+		$orig_ven = $orig_event->get_many_related('Venue');
558
+		// reset the ID and modify other details to make it clear this is a dupe
559
+		$new_event->set('EVT_ID', 0);
560
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
561
+		$new_event->set('EVT_name', $new_name);
562
+		$new_event->set(
563
+			'EVT_slug',
564
+			wp_unique_post_slug(
565
+				sanitize_title($orig_event->name()),
566
+				0,
567
+				'publish',
568
+				'espresso_events',
569
+				0
570
+			)
571
+		);
572
+		$new_event->set('status', 'draft');
573
+		// duplicate discussion settings
574
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
575
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
576
+		// save the new event
577
+		$new_event->save();
578
+		// venues
579
+		foreach ($orig_ven as $ven) {
580
+			$new_event->_add_relation_to($ven, 'Venue');
581
+		}
582
+		$new_event->save();
583
+		// now we need to get the question group relations and handle that
584
+		// first primary question groups
585
+		$orig_primary_qgs = $orig_event->get_many_related(
586
+			'Question_Group',
587
+			[['Event_Question_Group.EQG_primary' => true]]
588
+		);
589
+		if (! empty($orig_primary_qgs)) {
590
+			foreach ($orig_primary_qgs as $id => $obj) {
591
+				if ($obj instanceof EE_Question_Group) {
592
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
593
+				}
594
+			}
595
+		}
596
+		// next additional attendee question groups
597
+		$orig_additional_qgs = $orig_event->get_many_related(
598
+			'Question_Group',
599
+			[['Event_Question_Group.EQG_additional' => true]]
600
+		);
601
+		if (! empty($orig_additional_qgs)) {
602
+			foreach ($orig_additional_qgs as $id => $obj) {
603
+				if ($obj instanceof EE_Question_Group) {
604
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
605
+				}
606
+			}
607
+		}
608
+
609
+		$new_event->save();
610
+
611
+		// k now that we have the new event saved we can loop through the datetimes and start adding relations.
612
+		$cloned_tickets = array();
613
+		foreach ($orig_datetimes as $orig_dtt) {
614
+			if (! $orig_dtt instanceof EE_Datetime) {
615
+				continue;
616
+			}
617
+			$new_dtt = clone $orig_dtt;
618
+			$orig_tkts = $orig_dtt->tickets();
619
+			// save new dtt then add to event
620
+			$new_dtt->set('DTT_ID', 0);
621
+			$new_dtt->set('DTT_sold', 0);
622
+			$new_dtt->set_reserved(0);
623
+			$new_dtt->save();
624
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
625
+			$new_event->save();
626
+			// now let's get the ticket relations setup.
627
+			foreach ((array) $orig_tkts as $orig_tkt) {
628
+				// it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
629
+				if (! $orig_tkt instanceof EE_Ticket) {
630
+					continue;
631
+				}
632
+				// is this ticket archived?  If it is then let's skip
633
+				if ($orig_tkt->get('TKT_deleted')) {
634
+					continue;
635
+				}
636
+				// does this original ticket already exist in the clone_tickets cache?
637
+				//  If so we'll just use the new ticket from it.
638
+				if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
639
+					$new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
640
+				} else {
641
+					$new_tkt = clone $orig_tkt;
642
+					// get relations on the $orig_tkt that we need to setup.
643
+					$orig_prices = $orig_tkt->prices();
644
+					$new_tkt->set('TKT_ID', 0);
645
+					$new_tkt->set('TKT_sold', 0);
646
+					$new_tkt->set('TKT_reserved', 0);
647
+					$new_tkt->save(); // make sure new ticket has ID.
648
+					// price relations on new ticket need to be setup.
649
+					foreach ($orig_prices as $orig_price) {
650
+						$new_price = clone $orig_price;
651
+						$new_price->set('PRC_ID', 0);
652
+						$new_price->save();
653
+						$new_tkt->_add_relation_to($new_price, 'Price');
654
+						$new_tkt->save();
655
+					}
656
+
657
+					do_action(
658
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
659
+						$orig_tkt,
660
+						$new_tkt,
661
+						$orig_prices,
662
+						$orig_event,
663
+						$orig_dtt,
664
+						$new_dtt
665
+					);
666
+				}
667
+				// k now we can add the new ticket as a relation to the new datetime
668
+				// and make sure its added to our cached $cloned_tickets array
669
+				// for use with later datetimes that have the same ticket.
670
+				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
671
+				$new_dtt->save();
672
+				$cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
673
+			}
674
+		}
675
+		// clone taxonomy information
676
+		$taxonomies_to_clone_with = apply_filters(
677
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
678
+			array('espresso_event_categories', 'espresso_event_type', 'post_tag')
679
+		);
680
+		// get terms for original event (notice)
681
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
682
+		// loop through terms and add them to new event.
683
+		foreach ($orig_terms as $term) {
684
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
685
+		}
686
+
687
+		// duplicate other core WP_Post items for this event.
688
+		// post thumbnail (feature image).
689
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
690
+		if ($feature_image_id) {
691
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
692
+		}
693
+
694
+		// duplicate page_template setting
695
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
696
+		if ($page_template) {
697
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
698
+		}
699
+
700
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
701
+		// now let's redirect to the edit page for this duplicated event if we have a new event id.
702
+		if ($new_event->ID()) {
703
+			$redirect_args = array(
704
+				'post'   => $new_event->ID(),
705
+				'action' => 'edit',
706
+			);
707
+			EE_Error::add_success(
708
+				esc_html__(
709
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
710
+					'event_espresso'
711
+				)
712
+			);
713
+		} else {
714
+			$redirect_args = array(
715
+				'action' => 'default',
716
+			);
717
+			EE_Error::add_error(
718
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
719
+				__FILE__,
720
+				__FUNCTION__,
721
+				__LINE__
722
+			);
723
+		}
724
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
725
+	}
726
+
727
+
728
+	/**
729
+	 * Generates output for the import page.
730
+	 *
731
+	 * @throws DomainException
732
+	 * @throws EE_Error
733
+	 * @throws InvalidArgumentException
734
+	 * @throws InvalidDataTypeException
735
+	 * @throws InvalidInterfaceException
736
+	 */
737
+	protected function _import_page()
738
+	{
739
+		$title = esc_html__('Import', 'event_espresso');
740
+		$intro = esc_html__(
741
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
742
+			'event_espresso'
743
+		);
744
+		$form_url = EVENTS_ADMIN_URL;
745
+		$action = 'import_events';
746
+		$type = 'csv';
747
+		$this->_template_args['form'] = EE_Import::instance()->upload_form(
748
+			$title,
749
+			$intro,
750
+			$form_url,
751
+			$action,
752
+			$type
753
+		);
754
+		$this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
755
+			array('action' => 'sample_export_file'),
756
+			$this->_admin_base_url
757
+		);
758
+		$content = EEH_Template::display_template(
759
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
760
+			$this->_template_args,
761
+			true
762
+		);
763
+		$this->_template_args['admin_page_content'] = $content;
764
+		$this->display_admin_page_with_sidebar();
765
+	}
766
+
767
+
768
+	/**
769
+	 * _import_events
770
+	 * This handles displaying the screen and running imports for importing events.
771
+	 *
772
+	 * @return void
773
+	 * @throws EE_Error
774
+	 * @throws InvalidArgumentException
775
+	 * @throws InvalidDataTypeException
776
+	 * @throws InvalidInterfaceException
777
+	 */
778
+	protected function _import_events()
779
+	{
780
+		require_once(EE_CLASSES . 'EE_Import.class.php');
781
+		$success = EE_Import::instance()->import();
782
+		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
783
+	}
784
+
785
+
786
+	/**
787
+	 * _events_export
788
+	 * Will export all (or just the given event) to a Excel compatible file.
789
+	 *
790
+	 * @access protected
791
+	 * @return void
792
+	 */
793
+	protected function _events_export()
794
+	{
795
+		if (isset($this->_req_data['EVT_ID'])) {
796
+			$event_ids = $this->_req_data['EVT_ID'];
797
+		} elseif (isset($this->_req_data['EVT_IDs'])) {
798
+			$event_ids = $this->_req_data['EVT_IDs'];
799
+		} else {
800
+			$event_ids = null;
801
+		}
802
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
803
+		$new_request_args = array(
804
+			'export' => 'report',
805
+			'action' => 'all_event_data',
806
+			'EVT_ID' => $event_ids,
807
+		);
808
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
809
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
810
+			require_once(EE_CLASSES . 'EE_Export.class.php');
811
+			$EE_Export = EE_Export::instance($this->_req_data);
812
+			$EE_Export->export();
813
+		}
814
+	}
815
+
816
+
817
+	/**
818
+	 * handle category exports()
819
+	 *
820
+	 * @return void
821
+	 */
822
+	protected function _categories_export()
823
+	{
824
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
825
+		$new_request_args = array(
826
+			'export'       => 'report',
827
+			'action'       => 'categories',
828
+			'category_ids' => $this->_req_data['EVT_CAT_ID'],
829
+		);
830
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
831
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
832
+			require_once(EE_CLASSES . 'EE_Export.class.php');
833
+			$EE_Export = EE_Export::instance($this->_req_data);
834
+			$EE_Export->export();
835
+		}
836
+	}
837
+
838
+
839
+	/**
840
+	 * Creates a sample CSV file for importing
841
+	 */
842
+	protected function _sample_export_file()
843
+	{
844
+		// require_once(EE_CLASSES . 'EE_Export.class.php');
845
+		EE_Export::instance()->export_sample();
846
+	}
847
+
848
+
849
+	/*************        Template Settings        *************/
850
+	/**
851
+	 * Generates template settings page output
852
+	 *
853
+	 * @throws DomainException
854
+	 * @throws EE_Error
855
+	 * @throws InvalidArgumentException
856
+	 * @throws InvalidDataTypeException
857
+	 * @throws InvalidInterfaceException
858
+	 */
859
+	protected function _template_settings()
860
+	{
861
+		$this->_template_args['values'] = $this->_yes_no_values;
862
+		/**
863
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
864
+		 * from General_Settings_Admin_Page to here.
865
+		 */
866
+		$this->_template_args = apply_filters(
867
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
868
+			$this->_template_args
869
+		);
870
+		$this->_set_add_edit_form_tags('update_template_settings');
871
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
872
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
873
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
874
+			$this->_template_args,
875
+			true
876
+		);
877
+		$this->display_admin_page_with_sidebar();
878
+	}
879
+
880
+
881
+	/**
882
+	 * Handler for updating template settings.
883
+	 *
884
+	 * @throws EE_Error
885
+	 * @throws InvalidArgumentException
886
+	 * @throws InvalidDataTypeException
887
+	 * @throws InvalidInterfaceException
888
+	 */
889
+	protected function _update_template_settings()
890
+	{
891
+		/**
892
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
893
+		 * from General_Settings_Admin_Page to here.
894
+		 */
895
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
896
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
897
+			EE_Registry::instance()->CFG->template_settings,
898
+			$this->_req_data
899
+		);
900
+		// update custom post type slugs and detect if we need to flush rewrite rules
901
+		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
902
+		EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
903
+			? EE_Registry::instance()->CFG->core->event_cpt_slug
904
+			: EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
905
+		$what = 'Template Settings';
906
+		$success = $this->_update_espresso_configuration(
907
+			$what,
908
+			EE_Registry::instance()->CFG->template_settings,
909
+			__FILE__,
910
+			__FUNCTION__,
911
+			__LINE__
912
+		);
913
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug !== $old_slug) {
914
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
915
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
916
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
917
+			);
918
+			$rewrite_rules->flush();
919
+		}
920
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
921
+	}
922
+
923
+
924
+	/**
925
+	 * _premium_event_editor_meta_boxes
926
+	 * add all metaboxes related to the event_editor
927
+	 *
928
+	 * @access protected
929
+	 * @return void
930
+	 * @throws EE_Error
931
+	 * @throws InvalidArgumentException
932
+	 * @throws InvalidDataTypeException
933
+	 * @throws InvalidInterfaceException
934
+	 * @throws ReflectionException
935
+	 */
936
+	protected function _premium_event_editor_meta_boxes()
937
+	{
938
+		$this->verify_cpt_object();
939
+		add_meta_box(
940
+			'espresso_event_editor_event_options',
941
+			esc_html__('Event Registration Options', 'event_espresso'),
942
+			array($this, 'registration_options_meta_box'),
943
+			$this->page_slug,
944
+			'side',
945
+			'core'
946
+		);
947
+	}
948
+
949
+
950
+	/**
951
+	 * override caf metabox
952
+	 *
953
+	 * @return void
954
+	 * @throws DomainException
955
+	 * @throws EE_Error
956
+	 */
957
+	public function registration_options_meta_box()
958
+	{
959
+		$yes_no_values = array(
960
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
961
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
962
+		);
963
+		$default_reg_status_values = EEM_Registration::reg_status_array(
964
+			array(
965
+				EEM_Registration::status_id_cancelled,
966
+				EEM_Registration::status_id_declined,
967
+				EEM_Registration::status_id_incomplete,
968
+				EEM_Registration::status_id_wait_list,
969
+			),
970
+			true
971
+		);
972
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
973
+		$template_args['_event'] = $this->_cpt_model_obj;
974
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
975
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
976
+			'default_reg_status',
977
+			$default_reg_status_values,
978
+			$this->_cpt_model_obj->default_registration_status()
979
+		);
980
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
981
+			'display_desc',
982
+			$yes_no_values,
983
+			$this->_cpt_model_obj->display_description()
984
+		);
985
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
986
+			'display_ticket_selector',
987
+			$yes_no_values,
988
+			$this->_cpt_model_obj->display_ticket_selector(),
989
+			'',
990
+			'',
991
+			false
992
+		);
993
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
994
+			'EVT_default_registration_status',
995
+			$default_reg_status_values,
996
+			$this->_cpt_model_obj->default_registration_status()
997
+		);
998
+		$template_args['additional_registration_options'] = apply_filters(
999
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1000
+			'',
1001
+			$template_args,
1002
+			$yes_no_values,
1003
+			$default_reg_status_values
1004
+		);
1005
+		EEH_Template::display_template(
1006
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
1007
+			$template_args
1008
+		);
1009
+	}
1010
+
1011
+
1012
+
1013
+	/**
1014
+	 * wp_list_table_mods for caf
1015
+	 * ============================
1016
+	 */
1017
+	/**
1018
+	 * hook into list table filters and provide filters for caffeinated list table
1019
+	 *
1020
+	 * @param array $old_filters    any existing filters present
1021
+	 * @param array $list_table_obj the list table object
1022
+	 * @return array                  new filters
1023
+	 * @throws EE_Error
1024
+	 * @throws InvalidArgumentException
1025
+	 * @throws InvalidDataTypeException
1026
+	 * @throws InvalidInterfaceException
1027
+	 * @throws ReflectionException
1028
+	 */
1029
+	public function list_table_filters($old_filters, $list_table_obj)
1030
+	{
1031
+		$filters = array();
1032
+		// first month/year filters
1033
+		$filters[] = $this->espresso_event_months_dropdown();
1034
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1035
+		// active status dropdown
1036
+		if ($status !== 'draft') {
1037
+			$filters[] = $this->active_status_dropdown(
1038
+				isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
1039
+			);
1040
+			$filters[] = $this->venuesDropdown(
1041
+				isset($this->_req_data['venue']) ? $this->_req_data['venue'] : ''
1042
+			);
1043
+		}
1044
+		// category filter
1045
+		$filters[] = $this->category_dropdown();
1046
+		return array_merge($old_filters, $filters);
1047
+	}
1048
+
1049
+
1050
+	/**
1051
+	 * espresso_event_months_dropdown
1052
+	 *
1053
+	 * @access public
1054
+	 * @return string                dropdown listing month/year selections for events.
1055
+	 */
1056
+	public function espresso_event_months_dropdown()
1057
+	{
1058
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
1059
+		// Note we need to include any other filters that are set!
1060
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1061
+		// categories?
1062
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1063
+			? $this->_req_data['EVT_CAT']
1064
+			: null;
1065
+		// active status?
1066
+		$active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1067
+		$cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1068
+		return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1069
+	}
1070
+
1071
+
1072
+	/**
1073
+	 * returns a list of "active" statuses on the event
1074
+	 *
1075
+	 * @param  string $current_value whatever the current active status is
1076
+	 * @return string
1077
+	 */
1078
+	public function active_status_dropdown($current_value = '')
1079
+	{
1080
+		$select_name = 'active_status';
1081
+		$values = array(
1082
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1083
+			'active'   => esc_html__('Active', 'event_espresso'),
1084
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1085
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1086
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1087
+		);
1088
+
1089
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1090
+	}
1091
+
1092
+
1093
+	/**
1094
+	 * returns a list of "venues"
1095
+	 *
1096
+	 * @param string $current_value whatever the current active status is
1097
+	 * @return string
1098
+	 * @throws EE_Error
1099
+	 * @throws InvalidArgumentException
1100
+	 * @throws InvalidDataTypeException
1101
+	 * @throws InvalidInterfaceException
1102
+	 * @throws ReflectionException
1103
+	 */
1104
+	protected function venuesDropdown($current_value = '')
1105
+	{
1106
+		$select_name = 'venue';
1107
+		$values = array(
1108
+			'' => esc_html__('All Venues', 'event_espresso'),
1109
+		);
1110
+		// populate the list of venues.
1111
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1112
+		$venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1113
+
1114
+		foreach ($venues as $venue) {
1115
+			$values[ $venue->ID() ] = $venue->name();
1116
+		}
1117
+
1118
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1119
+	}
1120
+
1121
+
1122
+	/**
1123
+	 * output a dropdown of the categories for the category filter on the event admin list table
1124
+	 *
1125
+	 * @access  public
1126
+	 * @return string html
1127
+	 */
1128
+	public function category_dropdown()
1129
+	{
1130
+		$cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1131
+		return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1132
+	}
1133
+
1134
+
1135
+	/**
1136
+	 * get total number of events today
1137
+	 *
1138
+	 * @access public
1139
+	 * @return int
1140
+	 * @throws EE_Error
1141
+	 * @throws InvalidArgumentException
1142
+	 * @throws InvalidDataTypeException
1143
+	 * @throws InvalidInterfaceException
1144
+	 */
1145
+	public function total_events_today()
1146
+	{
1147
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1148
+			'DTT_EVT_start',
1149
+			date('Y-m-d') . ' 00:00:00',
1150
+			'Y-m-d H:i:s',
1151
+			'UTC'
1152
+		);
1153
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1154
+			'DTT_EVT_start',
1155
+			date('Y-m-d') . ' 23:59:59',
1156
+			'Y-m-d H:i:s',
1157
+			'UTC'
1158
+		);
1159
+		$where = array(
1160
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1161
+		);
1162
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1163
+		return $count;
1164
+	}
1165
+
1166
+
1167
+	/**
1168
+	 * get total number of events this month
1169
+	 *
1170
+	 * @access public
1171
+	 * @return int
1172
+	 * @throws EE_Error
1173
+	 * @throws InvalidArgumentException
1174
+	 * @throws InvalidDataTypeException
1175
+	 * @throws InvalidInterfaceException
1176
+	 */
1177
+	public function total_events_this_month()
1178
+	{
1179
+		// Dates
1180
+		$this_year_r = date('Y');
1181
+		$this_month_r = date('m');
1182
+		$days_this_month = date('t');
1183
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1184
+			'DTT_EVT_start',
1185
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1186
+			'Y-m-d H:i:s',
1187
+			'UTC'
1188
+		);
1189
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1190
+			'DTT_EVT_start',
1191
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1192
+			'Y-m-d H:i:s',
1193
+			'UTC'
1194
+		);
1195
+		$where = array(
1196
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1197
+		);
1198
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1199
+		return $count;
1200
+	}
1201
+
1202
+
1203
+	/** DEFAULT TICKETS STUFF **/
1204
+
1205
+	/**
1206
+	 * Output default tickets list table view.
1207
+	 *
1208
+	 * @throws DomainException
1209
+	 * @throws EE_Error
1210
+	 * @throws InvalidArgumentException
1211
+	 * @throws InvalidDataTypeException
1212
+	 * @throws InvalidInterfaceException
1213
+	 */
1214
+	public function _tickets_overview_list_table()
1215
+	{
1216
+		$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1217
+		$this->display_admin_list_table_page_with_no_sidebar();
1218
+	}
1219
+
1220
+
1221
+	/**
1222
+	 * @param int  $per_page
1223
+	 * @param bool $count
1224
+	 * @param bool $trashed
1225
+	 * @return EE_Soft_Delete_Base_Class[]|int
1226
+	 * @throws EE_Error
1227
+	 * @throws InvalidArgumentException
1228
+	 * @throws InvalidDataTypeException
1229
+	 * @throws InvalidInterfaceException
1230
+	 */
1231
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1232
+	{
1233
+		$orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1234
+		$order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1235
+		switch ($orderby) {
1236
+			case 'TKT_name':
1237
+				$orderby = array('TKT_name' => $order);
1238
+				break;
1239
+			case 'TKT_price':
1240
+				$orderby = array('TKT_price' => $order);
1241
+				break;
1242
+			case 'TKT_uses':
1243
+				$orderby = array('TKT_uses' => $order);
1244
+				break;
1245
+			case 'TKT_min':
1246
+				$orderby = array('TKT_min' => $order);
1247
+				break;
1248
+			case 'TKT_max':
1249
+				$orderby = array('TKT_max' => $order);
1250
+				break;
1251
+			case 'TKT_qty':
1252
+				$orderby = array('TKT_qty' => $order);
1253
+				break;
1254
+		}
1255
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1256
+			? $this->_req_data['paged']
1257
+			: 1;
1258
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1259
+			? $this->_req_data['perpage']
1260
+			: $per_page;
1261
+		$_where = array(
1262
+			'TKT_is_default' => 1,
1263
+			'TKT_deleted'    => $trashed,
1264
+		);
1265
+		$offset = ($current_page - 1) * $per_page;
1266
+		$limit = array($offset, $per_page);
1267
+		if (isset($this->_req_data['s'])) {
1268
+			$sstr = '%' . $this->_req_data['s'] . '%';
1269
+			$_where['OR'] = array(
1270
+				'TKT_name'        => array('LIKE', $sstr),
1271
+				'TKT_description' => array('LIKE', $sstr),
1272
+			);
1273
+		}
1274
+		$query_params = array(
1275
+			$_where,
1276
+			'order_by' => $orderby,
1277
+			'limit'    => $limit,
1278
+			'group_by' => 'TKT_ID',
1279
+		);
1280
+		if ($count) {
1281
+			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1282
+		} else {
1283
+			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1284
+		}
1285
+	}
1286
+
1287
+
1288
+	/**
1289
+	 * @param bool $trash
1290
+	 * @throws EE_Error
1291
+	 * @throws InvalidArgumentException
1292
+	 * @throws InvalidDataTypeException
1293
+	 * @throws InvalidInterfaceException
1294
+	 */
1295
+	protected function _trash_or_restore_ticket($trash = false)
1296
+	{
1297
+		$success = 1;
1298
+		$TKT = EEM_Ticket::instance();
1299
+		// checkboxes?
1300
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1301
+			// if array has more than one element then success message should be plural
1302
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1303
+			// cycle thru the boxes
1304
+			foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1305
+				if ($trash) {
1306
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1307
+						$success = 0;
1308
+					}
1309
+				} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1310
+					$success = 0;
1311
+				}
1312
+			}
1313
+		} else {
1314
+			// grab single id and trash
1315
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1316
+			if ($trash) {
1317
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1318
+					$success = 0;
1319
+				}
1320
+			} elseif (! $TKT->restore_by_ID($TKT_ID)) {
1321
+				$success = 0;
1322
+			}
1323
+		}
1324
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1325
+		$query_args = array(
1326
+			'action' => 'ticket_list_table',
1327
+			'status' => $trash ? '' : 'trashed',
1328
+		);
1329
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1330
+	}
1331
+
1332
+
1333
+	/**
1334
+	 * Handles trashing default ticket.
1335
+	 *
1336
+	 * @throws EE_Error
1337
+	 * @throws InvalidArgumentException
1338
+	 * @throws InvalidDataTypeException
1339
+	 * @throws InvalidInterfaceException
1340
+	 * @throws ReflectionException
1341
+	 */
1342
+	protected function _delete_ticket()
1343
+	{
1344
+		$success = 1;
1345
+		// checkboxes?
1346
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1347
+			// if array has more than one element then success message should be plural
1348
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1349
+			// cycle thru the boxes
1350
+			foreach ($this->_req_data['checkbox'] as $TKT_ID) {
1351
+				// delete
1352
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1353
+					$success = 0;
1354
+				}
1355
+			}
1356
+		} else {
1357
+			// grab single id and trash
1358
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1359
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1360
+				$success = 0;
1361
+			}
1362
+		}
1363
+		$action_desc = 'deleted';
1364
+		$query_args = array(
1365
+			'action' => 'ticket_list_table',
1366
+			'status' => 'trashed',
1367
+		);
1368
+		// fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1369
+		if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1370
+			array(array('TKT_is_default' => 1)),
1371
+			'TKT_ID',
1372
+			true
1373
+		)
1374
+		) {
1375
+			$query_args = array();
1376
+		}
1377
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1378
+	}
1379
+
1380
+
1381
+	/**
1382
+	 * @param int $TKT_ID
1383
+	 * @return bool|int
1384
+	 * @throws EE_Error
1385
+	 * @throws InvalidArgumentException
1386
+	 * @throws InvalidDataTypeException
1387
+	 * @throws InvalidInterfaceException
1388
+	 * @throws ReflectionException
1389
+	 */
1390
+	protected function _delete_the_ticket($TKT_ID)
1391
+	{
1392
+		$tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1393
+		$tkt->_remove_relations('Datetime');
1394
+		// delete all related prices first
1395
+		$tkt->delete_related_permanently('Price');
1396
+		return $tkt->delete_permanently();
1397
+	}
1398 1398
 }
Please login to merge, or discard this patch.
caffeinated/admin/new/pricing/Pricing_Admin_Page_Init.core.php 1 patch
Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -14,53 +14,53 @@
 block discarded – undo
14 14
 {
15 15
 
16 16
 
17
-    /**
18
-     * @Constructor
19
-     */
20
-    public function __construct()
21
-    {
17
+	/**
18
+	 * @Constructor
19
+	 */
20
+	public function __construct()
21
+	{
22 22
 
23
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
23
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
24 24
 
25
-        define('PRICING_PG_SLUG', 'pricing');
26
-        define('PRICING_LABEL', __('Pricing', 'event_espresso'));
27
-        define('PRICING_PG_NAME', ucwords(str_replace('_', '', PRICING_PG_SLUG)));
28
-        define('PRICING_ADMIN', EE_CORE_CAF_ADMIN . 'new/' . PRICING_PG_SLUG . '/');
29
-        define('PRICING_ADMIN_URL', admin_url('admin.php?page=' . PRICING_PG_SLUG));
30
-        define('PRICING_ASSETS_PATH', PRICING_ADMIN . 'assets/');
31
-        define('PRICING_ASSETS_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/assets/');
32
-        define('PRICING_TEMPLATE_PATH', PRICING_ADMIN . 'templates/');
33
-        define('PRICING_TEMPLATE_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/templates/');
25
+		define('PRICING_PG_SLUG', 'pricing');
26
+		define('PRICING_LABEL', __('Pricing', 'event_espresso'));
27
+		define('PRICING_PG_NAME', ucwords(str_replace('_', '', PRICING_PG_SLUG)));
28
+		define('PRICING_ADMIN', EE_CORE_CAF_ADMIN . 'new/' . PRICING_PG_SLUG . '/');
29
+		define('PRICING_ADMIN_URL', admin_url('admin.php?page=' . PRICING_PG_SLUG));
30
+		define('PRICING_ASSETS_PATH', PRICING_ADMIN . 'assets/');
31
+		define('PRICING_ASSETS_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/assets/');
32
+		define('PRICING_TEMPLATE_PATH', PRICING_ADMIN . 'templates/');
33
+		define('PRICING_TEMPLATE_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/templates/');
34 34
 
35
-        parent::__construct();
36
-        $this->_folder_path = EE_CORE_CAF_ADMIN . 'new/' . $this->_folder_name . '/';
37
-    }
35
+		parent::__construct();
36
+		$this->_folder_path = EE_CORE_CAF_ADMIN . 'new/' . $this->_folder_name . '/';
37
+	}
38 38
 
39 39
 
40
-    protected function _set_init_properties()
41
-    {
42
-        $this->label = PRICING_LABEL;
43
-    }
40
+	protected function _set_init_properties()
41
+	{
42
+		$this->label = PRICING_LABEL;
43
+	}
44 44
 
45 45
 
46
-    /**
47
-     * @return array|void
48
-     * @throws EE_Error
49
-     * @since $VID:$
50
-     */
51
-    protected function _set_menu_map()
52
-    {
53
-        $this->_menu_map = new EE_Admin_Page_Sub_Menu(
54
-            array(
55
-                'menu_group'      => 'management',
56
-                'menu_order'      => 20,
57
-                'show_on_menu'    => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
58
-                'parent_slug'     => 'espresso_events',
59
-                'menu_slug'       => PRICING_PG_SLUG,
60
-                'menu_label'      => PRICING_LABEL,
61
-                'capability'      => 'ee_read_default_prices',
62
-                'admin_init_page' => $this,
63
-            )
64
-        );
65
-    }
46
+	/**
47
+	 * @return array|void
48
+	 * @throws EE_Error
49
+	 * @since $VID:$
50
+	 */
51
+	protected function _set_menu_map()
52
+	{
53
+		$this->_menu_map = new EE_Admin_Page_Sub_Menu(
54
+			array(
55
+				'menu_group'      => 'management',
56
+				'menu_order'      => 20,
57
+				'show_on_menu'    => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
58
+				'parent_slug'     => 'espresso_events',
59
+				'menu_slug'       => PRICING_PG_SLUG,
60
+				'menu_label'      => PRICING_LABEL,
61
+				'capability'      => 'ee_read_default_prices',
62
+				'admin_init_page' => $this,
63
+			)
64
+		);
65
+	}
66 66
 }
Please login to merge, or discard this patch.