Completed
Branch FET-10766-extract-activation-d... (99f7dd)
by
unknown
134:15 queued 121:56
created
maintenance/templates/ee_upgrade_addons_before_migrating.template.php 1 patch
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 ?>
4
-<h1><?php esc_html_e("You must upgrade your Event Espresso Add-ons before Migrating", "event_espresso");?></h1>
5
-<p><?php printf(esc_html__("Please %s visit the plugins page%s and update all Event Espresso addon plugins before updating your database.", "event_espresso"), "<a href='".admin_url('/plugins.php')."'>","</a>");?></p>
6
-<p><?php esc_html_e("You can also deactivate the addons, but all of their data will be lost when your database is migrated", "event_espresso");?></p>
7 4
\ No newline at end of file
5
+<h1><?php esc_html_e("You must upgrade your Event Espresso Add-ons before Migrating", "event_espresso"); ?></h1>
6
+<p><?php printf(esc_html__("Please %s visit the plugins page%s and update all Event Espresso addon plugins before updating your database.", "event_espresso"), "<a href='".admin_url('/plugins.php')."'>", "</a>"); ?></p>
7
+<p><?php esc_html_e("You can also deactivate the addons, but all of their data will be lost when your database is migrated", "event_espresso"); ?></p>
8 8
\ No newline at end of file
Please login to merge, or discard this patch.
admin_pages/maintenance/templates/ee_migration_page.template.php 1 patch
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -28,29 +28,29 @@  discard block
 block discarded – undo
28 28
             <h3 class="espresso-header">
29 29
                 <span class="dashicons dashicons-flag ee-icon-size-22"></span>
30 30
                 <?php
31
-                echo apply_filters(
32
-                        'FHEE__ee_migration_page__header',
33
-                        sprintf(
34
-                                esc_html__("Your Event Espresso data needs to be updated.", "event_espresso"),
35
-                                $current_db_state,
36
-                                $next_db_state
37
-                        ),
38
-                        $current_db_state,
39
-                        $next_db_state
40
-                );
41
-                ?>
31
+				echo apply_filters(
32
+						'FHEE__ee_migration_page__header',
33
+						sprintf(
34
+								esc_html__("Your Event Espresso data needs to be updated.", "event_espresso"),
35
+								$current_db_state,
36
+								$next_db_state
37
+						),
38
+						$current_db_state,
39
+						$next_db_state
40
+				);
41
+				?>
42 42
             </h3>
43 43
         <?php } elseif ($show_most_recent_migration) { ?>
44 44
             <h3 class="espresso-header">
45 45
                 <span class="dashicons dashicons-awards ee-icon-size-22"></span>
46 46
                 <?php echo apply_filters('FHEE__ee_migration_page__done_migration_header',
47
-                        sprintf(esc_html__('Congratulations! Your database is "up-to-date" and you are ready to begin using %s',
48
-                                "event_espresso"), $ultimate_db_state)); ?>
47
+						sprintf(esc_html__('Congratulations! Your database is "up-to-date" and you are ready to begin using %s',
48
+								"event_espresso"), $ultimate_db_state)); ?>
49 49
             </h3>
50 50
             <p>
51 51
                 <?php echo apply_filters('FHEE__ee_migration_page__p_after_done_migration_header',
52
-                        sprintf(esc_html__("Time to find out about all the great new features %s has to offer.",
53
-                                "event_espresso"), $ultimate_db_state)); ?> &nbsp;
52
+						sprintf(esc_html__("Time to find out about all the great new features %s has to offer.",
53
+								"event_espresso"), $ultimate_db_state)); ?> &nbsp;
54 54
                 <b><a id="get-started-after-migrate" class="button-primary"
55 55
                       href="<?php echo add_query_arg(array('page' => 'espresso_about'), admin_url('admin.php')); ?>">
56 56
                         <?php esc_html_e("Let's Get Started", "event_espresso"); ?>&nbsp;<span
@@ -61,34 +61,34 @@  discard block
 block discarded – undo
61 61
 
62 62
 
63 63
         <?php if ($show_backup_db_text) {
64
-            echo $migration_options_html;
65
-        } ?>
64
+			echo $migration_options_html;
65
+		} ?>
66 66
 
67 67
         <?php
68
-        if ($show_most_recent_migration) {
69
-            if ($most_recent_migration && $most_recent_migration instanceof EE_Data_Migration_Script_Base) {
70
-                if ($most_recent_migration->can_continue()) {
71
-                    //tell the user they should continue their migration because it appears to be unfinished... well, assuming there were no errors ?>
68
+		if ($show_most_recent_migration) {
69
+			if ($most_recent_migration && $most_recent_migration instanceof EE_Data_Migration_Script_Base) {
70
+				if ($most_recent_migration->can_continue()) {
71
+					//tell the user they should continue their migration because it appears to be unfinished... well, assuming there were no errors ?>
72 72
                     <h3 class="espresso-header">
73 73
                         <span class="dashicons dashicons-star-half ee-icon-size-22"></span>
74 74
                         <?php printf(esc_html__("It appears that your previous Database Update (%s) is incomplete, and should be resumed",
75
-                                "event_espresso"), $most_recent_migration->pretty_name()); ?>
75
+								"event_espresso"), $most_recent_migration->pretty_name()); ?>
76 76
                     </h3>
77 77
                 <?php } elseif ($most_recent_migration->is_broken()) {
78
-                    //tell the user the migration failed and they should notify EE?>
78
+					//tell the user the migration failed and they should notify EE?>
79 79
                     <h3 class="espresso-header">
80 80
                         <span class="dashicons dashicons-no ee-icon-size-22"></span>
81 81
                         <?php echo $most_recent_migration->get_feedback_message() ?>
82 82
                     </h3>
83 83
                 <?php }
84
-                //display errors or not of the most recent migration ran
85
-                if ($most_recent_migration->get_errors()) { ?>
84
+				//display errors or not of the most recent migration ran
85
+				if ($most_recent_migration->get_errors()) { ?>
86 86
                     <div class="ee-attention">
87 87
                         <strong><?php printf(esc_html__("Warnings occurred during your last Database Update (%s):",
88
-                                    'event_espresso'),
89
-                                    $most_recent_migration->pretty_name()) ?></strong>
88
+									'event_espresso'),
89
+									$most_recent_migration->pretty_name()) ?></strong>
90 90
                         <a id="show-hide-migration-warnings" class="display-the-hidden"><?php esc_html_e("Show Warnings",
91
-                                    'event_espresso'); ?></a>
91
+									'event_espresso'); ?></a>
92 92
                         <ul class="migration-warnings" style="display:none">
93 93
                             <?php foreach ($most_recent_migration->get_errors() as $error) { ?>
94 94
                                 <li><?php echo htmlentities($error) ?></li>
@@ -96,15 +96,15 @@  discard block
 block discarded – undo
96 96
                         </ul>
97 97
                     </div>
98 98
                 <?php } else {
99
-                    //there were no errors during the last migration, just say so?>
99
+					//there were no errors during the last migration, just say so?>
100 100
                     <h2><?php printf(esc_html__("The last Database Update (%s) ran successfully without errors.",
101
-                                "event_espresso"), $most_recent_migration->pretty_name()) ?></h2>
101
+								"event_espresso"), $most_recent_migration->pretty_name()) ?></h2>
102 102
                 <?php }
103
-            } else {
104
-            }
105
-        }
106
-        // end of: if ( $show_most_recent_migration )
107
-        ?>
103
+			} else {
104
+			}
105
+		}
106
+		// end of: if ( $show_most_recent_migration )
107
+		?>
108 108
 
109 109
     </div>
110 110
     <!--end of #migration-prep-->
@@ -124,12 +124,12 @@  discard block
 block discarded – undo
124 124
             <div id='progress-area'>
125 125
                 <h3 class="espresso-header">
126 126
                     <?php
127
-                    echo sprintf(_n(
128
-                            "The following task needs to be performed:",
129
-                            "The following %s tasks need to be performed:",
130
-                            count($script_names),
131
-                            "event_espresso"
132
-                    ), count($script_names)); ?>
127
+					echo sprintf(_n(
128
+							"The following task needs to be performed:",
129
+							"The following %s tasks need to be performed:",
130
+							count($script_names),
131
+							"event_espresso"
132
+					), count($script_names)); ?>
133 133
                 </h3>
134 134
                 <ul style="list-style: inside;">
135 135
                     <?php foreach ($script_names as $script_name) { ?>
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
                 <br/>
140 140
                 <?php if (count($script_names) > 1) { ?>
141 141
                     <p><?php esc_html_e("Please note: after each task is completed you will need to continue the Database Update, or report an error to Event Espresso.",
142
-                                "event_espresso"); ?></p>
142
+								"event_espresso"); ?></p>
143 143
                 <?php } ?>
144 144
 
145 145
                 <div class="ee-attention">
@@ -149,11 +149,11 @@  discard block
 block discarded – undo
149 149
 					</span>
150 150
                         <br/>
151 151
                         <?php esc_html_e("Depending on the number of events and the complexity of the information in your database, this could take a few minutes.",
152
-                                "event_espresso"); ?>
152
+								"event_espresso"); ?>
153 153
                     </p>
154 154
                     <p>
155 155
                         <?php printf(esc_html__("%sPlease be patient and do NOT navigate away from this page once the migration has begun%s. If any issues arise due to existing malformed data, an itemized report will be made available to you after the migration has completed.",
156
-                                "event_espresso"), '<strong>', '</strong>'); ?>
156
+								"event_espresso"), '<strong>', '</strong>'); ?>
157 157
                     </p>
158 158
                     <p>
159 159
                         <?php esc_html_e("Click the button below to begin the migration process.", "event_espresso") ?>
@@ -169,8 +169,8 @@  discard block
 block discarded – undo
169 169
 
170 170
                 <button id='start-migration' class='button-primary'>
171 171
                     <?php echo $show_continue_current_migration_script ? esc_html__("Continue Database Update",
172
-                            "event_espresso")
173
-                            : esc_html__("Begin Database Update", "event_espresso"); ?>
172
+							"event_espresso")
173
+							: esc_html__("Begin Database Update", "event_espresso"); ?>
174 174
                 </button>
175 175
                 <br class="clear"/>
176 176
 
@@ -186,10 +186,10 @@  discard block
 block discarded – undo
186 186
         </div>
187 187
 
188 188
     <?php }
189
-    if ($show_maintenance_switch) {
190
-        ?>
189
+	if ($show_maintenance_switch) {
190
+		?>
191 191
         <h2><span class="dashicons dashicons-admin-tools"></span><?php esc_html_e('Set Event Espresso Maintenance Mode',
192
-                    'event_espresso'); ?></h2>
192
+					'event_espresso'); ?></h2>
193 193
         <form method='post' action='<?php echo $update_migration_script_page_link ?>'>
194 194
             <div class="ee-table-wrap">
195 195
                 <table>
@@ -197,15 +197,15 @@  discard block
 block discarded – undo
197 197
                         <td width="40px" align="center">
198 198
                             <input type="radio" id="maintenance_mode_level_off" name="maintenance_mode_level"
199 199
                                    value="0" <?php echo EE_Maintenance_Mode::instance()->level()
200
-                                                        == EE_Maintenance_Mode::level_0_not_in_maintenance
201
-                                    ? 'checked="checked"' : '' ?>>
200
+														== EE_Maintenance_Mode::level_0_not_in_maintenance
201
+									? 'checked="checked"' : '' ?>>
202 202
                         </td>
203 203
                         <th align="left">
204 204
                             <label for="maintenance_mode_level_off"><?php esc_html_e('Maintenance Mode OFF',
205
-                                        'event_espresso'); ?></label>
205
+										'event_espresso'); ?></label>
206 206
                             <p class='description' style="font-weight: normal;">
207 207
                                 <?php esc_html_e("This is the normal operating mode for Event Espresso and allows all functionality to be viewed by all site visitors.",
208
-                                        "event_espresso"); ?>
208
+										"event_espresso"); ?>
209 209
                             </p>
210 210
                         </th>
211 211
                     </tr>
@@ -213,8 +213,8 @@  discard block
 block discarded – undo
213 213
                         <td width="40px" align="center">
214 214
                             <input type="radio" id="maintenance_mode_level_on" name="maintenance_mode_level"
215 215
                                    value="1" <?php echo EE_Maintenance_Mode::instance()->level()
216
-                                                        == EE_Maintenance_Mode::level_1_frontend_only_maintenance
217
-                                    ? 'checked="checked"' : '' ?>>
216
+														== EE_Maintenance_Mode::level_1_frontend_only_maintenance
217
+									? 'checked="checked"' : '' ?>>
218 218
                         </td>
219 219
                         <th align="left">
220 220
                             <label for="maintenance_mode_level_on">
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
                             </label>
223 223
                             <p class='description' style="font-weight: normal;">
224 224
                                 <?php esc_html_e("This disables Event Espresso frontend functionality for all site visitors that are not administrators, and allows you to configure and/or test things on the frontend of your website before others can see.",
225
-                                        "event_espresso"); ?>
225
+										"event_espresso"); ?>
226 226
                             </p>
227 227
                         </th>
228 228
                     </tr>
@@ -234,6 +234,6 @@  discard block
 block discarded – undo
234 234
             </p>
235 235
         </form>
236 236
         <?php
237
-    } ?>
237
+	} ?>
238 238
 
239 239
 </div>
Please login to merge, or discard this patch.
admin_pages/maintenance/templates/ee_migration_was_borked_page.template.php 1 patch
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -1,26 +1,26 @@
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 ?>
4
-<h1><?php esc_html_e("Data Migration Error", "event_espresso");?></h1>
5
-<p class='error'><?php printf(esc_html__("Your last Database Update had a %s FATAL ERROR, and CANNOT be continued%s.", "event_espresso"),"<b>","</b>");?></p>
6
-<a id="show-hide-migration-warnings" class="display-the-hidden"><?php esc_html_e("Show Errors", 'event_espresso');?></a>
4
+<h1><?php esc_html_e("Data Migration Error", "event_espresso"); ?></h1>
5
+<p class='error'><?php printf(esc_html__("Your last Database Update had a %s FATAL ERROR, and CANNOT be continued%s.", "event_espresso"), "<b>", "</b>"); ?></p>
6
+<a id="show-hide-migration-warnings" class="display-the-hidden"><?php esc_html_e("Show Errors", 'event_espresso'); ?></a>
7 7
 <ul class="migration-warnings" style="display:none">
8
-<?php foreach($most_recent_migration->get_errors() as $error){ ?>
8
+<?php foreach ($most_recent_migration->get_errors() as $error) { ?>
9 9
 	<li style="overflow-y:auto;max-height:100px"><?php echo esc_html($error)?></li>
10 10
 <?php }?>
11 11
 </ul>
12
-<h2><?php esc_html_e("Fill out the below form to automatically Send Event Espresso a Crash Report", "event_espresso");?></h2>
13
-<form action='<?php echo EE_Admin_Page::add_query_args_and_nonce(array('action'=>'send_migration_crash_report'), EE_MAINTENANCE_ADMIN_URL);?>' method='post'>
12
+<h2><?php esc_html_e("Fill out the below form to automatically Send Event Espresso a Crash Report", "event_espresso"); ?></h2>
13
+<form action='<?php echo EE_Admin_Page::add_query_args_and_nonce(array('action'=>'send_migration_crash_report'), EE_MAINTENANCE_ADMIN_URL); ?>' method='post'>
14 14
 	<table class='widefat'>
15
-		<tr><td><label for='from'><?php esc_html_e("From/Reply-To:", "event_espresso");?></label></td><td><input name='from' id='from' type='text' style="width:200px"value='<?php echo get_bloginfo('admin_email','display'); ?>'></td></tr>
16
-		<tr><td><label for='from_name'><?php esc_html_e("Your Name", "event_espresso");?></label></td><td><input name='from_name' id='from_name' type='text' style="width:200px"value='<?php printf(esc_html__("Admin of %s", "event_espresso"),get_bloginfo('name','display'));?>'></td></tr>
17
-		<tr><td><label for='body'><?php esc_html_e("Comments", "event_espresso");?></label></td><td><textarea name="body" id="body" class='system_status_info'><?php esc_html_e("Enter any comments about why you think the error may have occurred", "event_espresso");?></textarea>
18
-			<p class='description'><?php esc_html_e("Note: the System Information report will also be added to the email's body, which contains information about your Event Espresso, Wordpress, and PHP settings which can be helpful in debugging the problem.", "event_espresso");?></p></td></tr>
19
-		<tr><td colspan="2"><input type="submit" value="<?php esc_html_e("Mail Crash Report to Event Espresso", "event_espresso");?>"/></td></tr>
15
+		<tr><td><label for='from'><?php esc_html_e("From/Reply-To:", "event_espresso"); ?></label></td><td><input name='from' id='from' type='text' style="width:200px"value='<?php echo get_bloginfo('admin_email', 'display'); ?>'></td></tr>
16
+		<tr><td><label for='from_name'><?php esc_html_e("Your Name", "event_espresso"); ?></label></td><td><input name='from_name' id='from_name' type='text' style="width:200px"value='<?php printf(esc_html__("Admin of %s", "event_espresso"), get_bloginfo('name', 'display')); ?>'></td></tr>
17
+		<tr><td><label for='body'><?php esc_html_e("Comments", "event_espresso"); ?></label></td><td><textarea name="body" id="body" class='system_status_info'><?php esc_html_e("Enter any comments about why you think the error may have occurred", "event_espresso"); ?></textarea>
18
+			<p class='description'><?php esc_html_e("Note: the System Information report will also be added to the email's body, which contains information about your Event Espresso, Wordpress, and PHP settings which can be helpful in debugging the problem.", "event_espresso"); ?></p></td></tr>
19
+		<tr><td colspan="2"><input type="submit" value="<?php esc_html_e("Mail Crash Report to Event Espresso", "event_espresso"); ?>"/></td></tr>
20 20
 	</table>
21 21
 </form>
22 22
 <br>
23
-<p><?php printf(esc_html__('...or copy-and-paste the below information to %1$s %2$s %3$s', "event_espresso"),'<a href="mailto:'.EE_SUPPORT_EMAIL.'">',EE_SUPPORT_EMAIL,"</a>");?></p>
24
-<textarea class="system_status_info"><?php print_r( EEM_System_Status::instance()->get_system_stati())?></textarea>
25
-<p><?php printf( esc_html__( '%1$sNext Step%2$s', 'event_espresso' ), "<a href='$next_url'>","</a>");?></p>
26
-<p><?php printf( esc_html__( '...or %1$sDON\'T send crash report%2$s.', 'event_espresso' ), "<a href='$next_url'>","</a>");?></p>
23
+<p><?php printf(esc_html__('...or copy-and-paste the below information to %1$s %2$s %3$s', "event_espresso"), '<a href="mailto:'.EE_SUPPORT_EMAIL.'">', EE_SUPPORT_EMAIL, "</a>"); ?></p>
24
+<textarea class="system_status_info"><?php print_r(EEM_System_Status::instance()->get_system_stati())?></textarea>
25
+<p><?php printf(esc_html__('%1$sNext Step%2$s', 'event_espresso'), "<a href='$next_url'>", "</a>"); ?></p>
26
+<p><?php printf(esc_html__('...or %1$sDON\'T send crash report%2$s.', 'event_espresso'), "<a href='$next_url'>", "</a>"); ?></p>
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -1430,7 +1430,7 @@  discard block
 block discarded – undo
1430 1430
      * This just returns whatever is set as the _event object property
1431 1431
      * //todo this will become obsolete once the models are in place
1432 1432
      *
1433
-     * @return object
1433
+     * @return EE_Event
1434 1434
      */
1435 1435
     public function get_event_object()
1436 1436
     {
@@ -2375,7 +2375,7 @@  discard block
 block discarded – undo
2375 2375
     
2376 2376
     
2377 2377
     /**
2378
-     * @return mixed
2378
+     * @return string
2379 2379
      */
2380 2380
     protected function _category_details_content()
2381 2381
     {
Please login to merge, or discard this patch.
Indentation   +2628 added lines, -2628 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 
@@ -17,2634 +17,2634 @@  discard block
 block discarded – undo
17 17
 class Events_Admin_Page extends EE_Admin_Page_CPT
18 18
 {
19 19
 
20
-    /**
21
-     * This will hold the event object for event_details screen.
22
-     *
23
-     * @access protected
24
-     * @var EE_Event $_event
25
-     */
26
-    protected $_event;
27
-
28
-
29
-    /**
30
-     * This will hold the category object for category_details screen.
31
-     *
32
-     * @var stdClass $_category
33
-     */
34
-    protected $_category;
35
-
36
-
37
-    /**
38
-     * This will hold the event model instance
39
-     *
40
-     * @var EEM_Event $_event_model
41
-     */
42
-    protected $_event_model;
43
-
44
-
45
-
46
-    /**
47
-     * @var EE_Event
48
-     */
49
-    protected $_cpt_model_obj = false;
50
-
51
-
52
-
53
-    protected function _init_page_props()
54
-    {
55
-        $this->page_slug = EVENTS_PG_SLUG;
56
-        $this->page_label = EVENTS_LABEL;
57
-        $this->_admin_base_url = EVENTS_ADMIN_URL;
58
-        $this->_admin_base_path = EVENTS_ADMIN;
59
-        $this->_cpt_model_names = array(
60
-            'create_new' => 'EEM_Event',
61
-            'edit'       => 'EEM_Event',
62
-        );
63
-        $this->_cpt_edit_routes = array(
64
-            'espresso_events' => 'edit',
65
-        );
66
-        add_action(
67
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
68
-            array($this, 'verify_event_edit')
69
-        );
70
-    }
71
-
72
-
73
-
74
-    protected function _ajax_hooks()
75
-    {
76
-        //todo: all hooks for events ajax goes in here.
77
-    }
78
-
79
-
80
-
81
-    protected function _define_page_props()
82
-    {
83
-        $this->_admin_page_title = EVENTS_LABEL;
84
-        $this->_labels = array(
85
-            'buttons'      => array(
86
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
87
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
88
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
89
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
90
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
91
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
92
-            ),
93
-            'editor_title' => array(
94
-                'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
95
-            ),
96
-            'publishbox'   => array(
97
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
98
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
99
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
100
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
101
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
102
-            ),
103
-        );
104
-    }
105
-
106
-
107
-
108
-    protected function _set_page_routes()
109
-    {
110
-        //load formatter helper
111
-        //load field generator helper
112
-        //is there a evt_id in the request?
113
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
114
-            ? $this->_req_data['EVT_ID'] : 0;
115
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
116
-        $this->_page_routes = array(
117
-            'default'                       => array(
118
-                'func'       => '_events_overview_list_table',
119
-                'capability' => 'ee_read_events',
120
-            ),
121
-            'create_new'                    => array(
122
-                'func'       => '_create_new_cpt_item',
123
-                'capability' => 'ee_edit_events',
124
-            ),
125
-            'edit'                          => array(
126
-                'func'       => '_edit_cpt_item',
127
-                'capability' => 'ee_edit_event',
128
-                'obj_id'     => $evt_id,
129
-            ),
130
-            'copy_event'                    => array(
131
-                'func'       => '_copy_events',
132
-                'capability' => 'ee_edit_event',
133
-                'obj_id'     => $evt_id,
134
-                'noheader'   => true,
135
-            ),
136
-            'trash_event'                   => array(
137
-                'func'       => '_trash_or_restore_event',
138
-                'args'       => array('event_status' => 'trash'),
139
-                'capability' => 'ee_delete_event',
140
-                'obj_id'     => $evt_id,
141
-                'noheader'   => true,
142
-            ),
143
-            'trash_events'                  => array(
144
-                'func'       => '_trash_or_restore_events',
145
-                'args'       => array('event_status' => 'trash'),
146
-                'capability' => 'ee_delete_events',
147
-                'noheader'   => true,
148
-            ),
149
-            'restore_event'                 => array(
150
-                'func'       => '_trash_or_restore_event',
151
-                'args'       => array('event_status' => 'draft'),
152
-                'capability' => 'ee_delete_event',
153
-                'obj_id'     => $evt_id,
154
-                'noheader'   => true,
155
-            ),
156
-            'restore_events'                => array(
157
-                'func'       => '_trash_or_restore_events',
158
-                'args'       => array('event_status' => 'draft'),
159
-                'capability' => 'ee_delete_events',
160
-                'noheader'   => true,
161
-            ),
162
-            'delete_event'                  => array(
163
-                'func'       => '_delete_event',
164
-                'capability' => 'ee_delete_event',
165
-                'obj_id'     => $evt_id,
166
-                'noheader'   => true,
167
-            ),
168
-            'delete_events'                 => array(
169
-                'func'       => '_delete_events',
170
-                'capability' => 'ee_delete_events',
171
-                'noheader'   => true,
172
-            ),
173
-            'view_report'                   => array(
174
-                'func'      => '_view_report',
175
-                'capablity' => 'ee_edit_events',
176
-            ),
177
-            'default_event_settings'        => array(
178
-                'func'       => '_default_event_settings',
179
-                'capability' => 'manage_options',
180
-            ),
181
-            'update_default_event_settings' => array(
182
-                'func'       => '_update_default_event_settings',
183
-                'capability' => 'manage_options',
184
-                'noheader'   => true,
185
-            ),
186
-            'template_settings'             => array(
187
-                'func'       => '_template_settings',
188
-                'capability' => 'manage_options',
189
-            ),
190
-            //event category tab related
191
-            'add_category'                  => array(
192
-                'func'       => '_category_details',
193
-                'capability' => 'ee_edit_event_category',
194
-                'args'       => array('add'),
195
-            ),
196
-            'edit_category'                 => array(
197
-                'func'       => '_category_details',
198
-                'capability' => 'ee_edit_event_category',
199
-                'args'       => array('edit'),
200
-            ),
201
-            'delete_categories'             => array(
202
-                'func'       => '_delete_categories',
203
-                'capability' => 'ee_delete_event_category',
204
-                'noheader'   => true,
205
-            ),
206
-            'delete_category'               => array(
207
-                'func'       => '_delete_categories',
208
-                'capability' => 'ee_delete_event_category',
209
-                'noheader'   => true,
210
-            ),
211
-            'insert_category'               => array(
212
-                'func'       => '_insert_or_update_category',
213
-                'args'       => array('new_category' => true),
214
-                'capability' => 'ee_edit_event_category',
215
-                'noheader'   => true,
216
-            ),
217
-            'update_category'               => array(
218
-                'func'       => '_insert_or_update_category',
219
-                'args'       => array('new_category' => false),
220
-                'capability' => 'ee_edit_event_category',
221
-                'noheader'   => true,
222
-            ),
223
-            'category_list'                 => array(
224
-                'func'       => '_category_list_table',
225
-                'capability' => 'ee_manage_event_categories',
226
-            ),
227
-        );
228
-    }
229
-
230
-
231
-
232
-    protected function _set_page_config()
233
-    {
234
-        $this->_page_config = array(
235
-            'default'                => array(
236
-                'nav'           => array(
237
-                    'label' => esc_html__('Overview', 'event_espresso'),
238
-                    'order' => 10,
239
-                ),
240
-                'list_table'    => 'Events_Admin_List_Table',
241
-                'help_tabs'     => array(
242
-                    'events_overview_help_tab'                       => array(
243
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
244
-                        'filename' => 'events_overview',
245
-                    ),
246
-                    'events_overview_table_column_headings_help_tab' => array(
247
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
248
-                        'filename' => 'events_overview_table_column_headings',
249
-                    ),
250
-                    'events_overview_filters_help_tab'               => array(
251
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
252
-                        'filename' => 'events_overview_filters',
253
-                    ),
254
-                    'events_overview_view_help_tab'                  => array(
255
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
256
-                        'filename' => 'events_overview_views',
257
-                    ),
258
-                    'events_overview_other_help_tab'                 => array(
259
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
260
-                        'filename' => 'events_overview_other',
261
-                    ),
262
-                ),
263
-                'help_tour'     => array(
264
-                    'Event_Overview_Help_Tour',
265
-                    //'New_Features_Test_Help_Tour' for testing multiple help tour
266
-                ),
267
-                'qtips'         => array(
268
-                    'EE_Event_List_Table_Tips',
269
-                ),
270
-                'require_nonce' => false,
271
-            ),
272
-            'create_new'             => array(
273
-                'nav'           => array(
274
-                    'label'      => esc_html__('Add Event', 'event_espresso'),
275
-                    'order'      => 5,
276
-                    'persistent' => false,
277
-                ),
278
-                'metaboxes'     => array('_register_event_editor_meta_boxes'),
279
-                'help_tabs'     => array(
280
-                    'event_editor_help_tab'                            => array(
281
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
282
-                        'filename' => 'event_editor',
283
-                    ),
284
-                    'event_editor_title_richtexteditor_help_tab'       => array(
285
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
286
-                        'filename' => 'event_editor_title_richtexteditor',
287
-                    ),
288
-                    'event_editor_venue_details_help_tab'              => array(
289
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
290
-                        'filename' => 'event_editor_venue_details',
291
-                    ),
292
-                    'event_editor_event_datetimes_help_tab'            => array(
293
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
294
-                        'filename' => 'event_editor_event_datetimes',
295
-                    ),
296
-                    'event_editor_event_tickets_help_tab'              => array(
297
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
298
-                        'filename' => 'event_editor_event_tickets',
299
-                    ),
300
-                    'event_editor_event_registration_options_help_tab' => array(
301
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
302
-                        'filename' => 'event_editor_event_registration_options',
303
-                    ),
304
-                    'event_editor_tags_categories_help_tab'            => array(
305
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
306
-                        'filename' => 'event_editor_tags_categories',
307
-                    ),
308
-                    'event_editor_questions_registrants_help_tab'      => array(
309
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
310
-                        'filename' => 'event_editor_questions_registrants',
311
-                    ),
312
-                    'event_editor_save_new_event_help_tab'             => array(
313
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
314
-                        'filename' => 'event_editor_save_new_event',
315
-                    ),
316
-                    'event_editor_other_help_tab'                      => array(
317
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
318
-                        'filename' => 'event_editor_other',
319
-                    ),
320
-                ),
321
-                'help_tour'     => array(
322
-                    'Event_Editor_Help_Tour',
323
-                ),
324
-                'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
325
-                'require_nonce' => false,
326
-            ),
327
-            'edit'                   => array(
328
-                'nav'           => array(
329
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
330
-                    'order'      => 5,
331
-                    'persistent' => false,
332
-                    'url'        => isset($this->_req_data['post'])
333
-                        ? EE_Admin_Page::add_query_args_and_nonce(
334
-                            array('post' => $this->_req_data['post'], 'action' => 'edit'),
335
-                            $this->_current_page_view_url
336
-                        )
337
-                        : $this->_admin_base_url,
338
-                ),
339
-                'metaboxes'     => array('_register_event_editor_meta_boxes'),
340
-                'help_tabs'     => array(
341
-                    'event_editor_help_tab'                            => array(
342
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
343
-                        'filename' => 'event_editor',
344
-                    ),
345
-                    'event_editor_title_richtexteditor_help_tab'       => array(
346
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
347
-                        'filename' => 'event_editor_title_richtexteditor',
348
-                    ),
349
-                    'event_editor_venue_details_help_tab'              => array(
350
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
351
-                        'filename' => 'event_editor_venue_details',
352
-                    ),
353
-                    'event_editor_event_datetimes_help_tab'            => array(
354
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
355
-                        'filename' => 'event_editor_event_datetimes',
356
-                    ),
357
-                    'event_editor_event_tickets_help_tab'              => array(
358
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
359
-                        'filename' => 'event_editor_event_tickets',
360
-                    ),
361
-                    'event_editor_event_registration_options_help_tab' => array(
362
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
363
-                        'filename' => 'event_editor_event_registration_options',
364
-                    ),
365
-                    'event_editor_tags_categories_help_tab'            => array(
366
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
367
-                        'filename' => 'event_editor_tags_categories',
368
-                    ),
369
-                    'event_editor_questions_registrants_help_tab'      => array(
370
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
371
-                        'filename' => 'event_editor_questions_registrants',
372
-                    ),
373
-                    'event_editor_save_new_event_help_tab'             => array(
374
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
375
-                        'filename' => 'event_editor_save_new_event',
376
-                    ),
377
-                    'event_editor_other_help_tab'                      => array(
378
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
379
-                        'filename' => 'event_editor_other',
380
-                    ),
381
-                ),
382
-                /*'help_tour' => array(
20
+	/**
21
+	 * This will hold the event object for event_details screen.
22
+	 *
23
+	 * @access protected
24
+	 * @var EE_Event $_event
25
+	 */
26
+	protected $_event;
27
+
28
+
29
+	/**
30
+	 * This will hold the category object for category_details screen.
31
+	 *
32
+	 * @var stdClass $_category
33
+	 */
34
+	protected $_category;
35
+
36
+
37
+	/**
38
+	 * This will hold the event model instance
39
+	 *
40
+	 * @var EEM_Event $_event_model
41
+	 */
42
+	protected $_event_model;
43
+
44
+
45
+
46
+	/**
47
+	 * @var EE_Event
48
+	 */
49
+	protected $_cpt_model_obj = false;
50
+
51
+
52
+
53
+	protected function _init_page_props()
54
+	{
55
+		$this->page_slug = EVENTS_PG_SLUG;
56
+		$this->page_label = EVENTS_LABEL;
57
+		$this->_admin_base_url = EVENTS_ADMIN_URL;
58
+		$this->_admin_base_path = EVENTS_ADMIN;
59
+		$this->_cpt_model_names = array(
60
+			'create_new' => 'EEM_Event',
61
+			'edit'       => 'EEM_Event',
62
+		);
63
+		$this->_cpt_edit_routes = array(
64
+			'espresso_events' => 'edit',
65
+		);
66
+		add_action(
67
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
68
+			array($this, 'verify_event_edit')
69
+		);
70
+	}
71
+
72
+
73
+
74
+	protected function _ajax_hooks()
75
+	{
76
+		//todo: all hooks for events ajax goes in here.
77
+	}
78
+
79
+
80
+
81
+	protected function _define_page_props()
82
+	{
83
+		$this->_admin_page_title = EVENTS_LABEL;
84
+		$this->_labels = array(
85
+			'buttons'      => array(
86
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
87
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
88
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
89
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
90
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
91
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
92
+			),
93
+			'editor_title' => array(
94
+				'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
95
+			),
96
+			'publishbox'   => array(
97
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
98
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
99
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
100
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
101
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
102
+			),
103
+		);
104
+	}
105
+
106
+
107
+
108
+	protected function _set_page_routes()
109
+	{
110
+		//load formatter helper
111
+		//load field generator helper
112
+		//is there a evt_id in the request?
113
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
114
+			? $this->_req_data['EVT_ID'] : 0;
115
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
116
+		$this->_page_routes = array(
117
+			'default'                       => array(
118
+				'func'       => '_events_overview_list_table',
119
+				'capability' => 'ee_read_events',
120
+			),
121
+			'create_new'                    => array(
122
+				'func'       => '_create_new_cpt_item',
123
+				'capability' => 'ee_edit_events',
124
+			),
125
+			'edit'                          => array(
126
+				'func'       => '_edit_cpt_item',
127
+				'capability' => 'ee_edit_event',
128
+				'obj_id'     => $evt_id,
129
+			),
130
+			'copy_event'                    => array(
131
+				'func'       => '_copy_events',
132
+				'capability' => 'ee_edit_event',
133
+				'obj_id'     => $evt_id,
134
+				'noheader'   => true,
135
+			),
136
+			'trash_event'                   => array(
137
+				'func'       => '_trash_or_restore_event',
138
+				'args'       => array('event_status' => 'trash'),
139
+				'capability' => 'ee_delete_event',
140
+				'obj_id'     => $evt_id,
141
+				'noheader'   => true,
142
+			),
143
+			'trash_events'                  => array(
144
+				'func'       => '_trash_or_restore_events',
145
+				'args'       => array('event_status' => 'trash'),
146
+				'capability' => 'ee_delete_events',
147
+				'noheader'   => true,
148
+			),
149
+			'restore_event'                 => array(
150
+				'func'       => '_trash_or_restore_event',
151
+				'args'       => array('event_status' => 'draft'),
152
+				'capability' => 'ee_delete_event',
153
+				'obj_id'     => $evt_id,
154
+				'noheader'   => true,
155
+			),
156
+			'restore_events'                => array(
157
+				'func'       => '_trash_or_restore_events',
158
+				'args'       => array('event_status' => 'draft'),
159
+				'capability' => 'ee_delete_events',
160
+				'noheader'   => true,
161
+			),
162
+			'delete_event'                  => array(
163
+				'func'       => '_delete_event',
164
+				'capability' => 'ee_delete_event',
165
+				'obj_id'     => $evt_id,
166
+				'noheader'   => true,
167
+			),
168
+			'delete_events'                 => array(
169
+				'func'       => '_delete_events',
170
+				'capability' => 'ee_delete_events',
171
+				'noheader'   => true,
172
+			),
173
+			'view_report'                   => array(
174
+				'func'      => '_view_report',
175
+				'capablity' => 'ee_edit_events',
176
+			),
177
+			'default_event_settings'        => array(
178
+				'func'       => '_default_event_settings',
179
+				'capability' => 'manage_options',
180
+			),
181
+			'update_default_event_settings' => array(
182
+				'func'       => '_update_default_event_settings',
183
+				'capability' => 'manage_options',
184
+				'noheader'   => true,
185
+			),
186
+			'template_settings'             => array(
187
+				'func'       => '_template_settings',
188
+				'capability' => 'manage_options',
189
+			),
190
+			//event category tab related
191
+			'add_category'                  => array(
192
+				'func'       => '_category_details',
193
+				'capability' => 'ee_edit_event_category',
194
+				'args'       => array('add'),
195
+			),
196
+			'edit_category'                 => array(
197
+				'func'       => '_category_details',
198
+				'capability' => 'ee_edit_event_category',
199
+				'args'       => array('edit'),
200
+			),
201
+			'delete_categories'             => array(
202
+				'func'       => '_delete_categories',
203
+				'capability' => 'ee_delete_event_category',
204
+				'noheader'   => true,
205
+			),
206
+			'delete_category'               => array(
207
+				'func'       => '_delete_categories',
208
+				'capability' => 'ee_delete_event_category',
209
+				'noheader'   => true,
210
+			),
211
+			'insert_category'               => array(
212
+				'func'       => '_insert_or_update_category',
213
+				'args'       => array('new_category' => true),
214
+				'capability' => 'ee_edit_event_category',
215
+				'noheader'   => true,
216
+			),
217
+			'update_category'               => array(
218
+				'func'       => '_insert_or_update_category',
219
+				'args'       => array('new_category' => false),
220
+				'capability' => 'ee_edit_event_category',
221
+				'noheader'   => true,
222
+			),
223
+			'category_list'                 => array(
224
+				'func'       => '_category_list_table',
225
+				'capability' => 'ee_manage_event_categories',
226
+			),
227
+		);
228
+	}
229
+
230
+
231
+
232
+	protected function _set_page_config()
233
+	{
234
+		$this->_page_config = array(
235
+			'default'                => array(
236
+				'nav'           => array(
237
+					'label' => esc_html__('Overview', 'event_espresso'),
238
+					'order' => 10,
239
+				),
240
+				'list_table'    => 'Events_Admin_List_Table',
241
+				'help_tabs'     => array(
242
+					'events_overview_help_tab'                       => array(
243
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
244
+						'filename' => 'events_overview',
245
+					),
246
+					'events_overview_table_column_headings_help_tab' => array(
247
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
248
+						'filename' => 'events_overview_table_column_headings',
249
+					),
250
+					'events_overview_filters_help_tab'               => array(
251
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
252
+						'filename' => 'events_overview_filters',
253
+					),
254
+					'events_overview_view_help_tab'                  => array(
255
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
256
+						'filename' => 'events_overview_views',
257
+					),
258
+					'events_overview_other_help_tab'                 => array(
259
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
260
+						'filename' => 'events_overview_other',
261
+					),
262
+				),
263
+				'help_tour'     => array(
264
+					'Event_Overview_Help_Tour',
265
+					//'New_Features_Test_Help_Tour' for testing multiple help tour
266
+				),
267
+				'qtips'         => array(
268
+					'EE_Event_List_Table_Tips',
269
+				),
270
+				'require_nonce' => false,
271
+			),
272
+			'create_new'             => array(
273
+				'nav'           => array(
274
+					'label'      => esc_html__('Add Event', 'event_espresso'),
275
+					'order'      => 5,
276
+					'persistent' => false,
277
+				),
278
+				'metaboxes'     => array('_register_event_editor_meta_boxes'),
279
+				'help_tabs'     => array(
280
+					'event_editor_help_tab'                            => array(
281
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
282
+						'filename' => 'event_editor',
283
+					),
284
+					'event_editor_title_richtexteditor_help_tab'       => array(
285
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
286
+						'filename' => 'event_editor_title_richtexteditor',
287
+					),
288
+					'event_editor_venue_details_help_tab'              => array(
289
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
290
+						'filename' => 'event_editor_venue_details',
291
+					),
292
+					'event_editor_event_datetimes_help_tab'            => array(
293
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
294
+						'filename' => 'event_editor_event_datetimes',
295
+					),
296
+					'event_editor_event_tickets_help_tab'              => array(
297
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
298
+						'filename' => 'event_editor_event_tickets',
299
+					),
300
+					'event_editor_event_registration_options_help_tab' => array(
301
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
302
+						'filename' => 'event_editor_event_registration_options',
303
+					),
304
+					'event_editor_tags_categories_help_tab'            => array(
305
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
306
+						'filename' => 'event_editor_tags_categories',
307
+					),
308
+					'event_editor_questions_registrants_help_tab'      => array(
309
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
310
+						'filename' => 'event_editor_questions_registrants',
311
+					),
312
+					'event_editor_save_new_event_help_tab'             => array(
313
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
314
+						'filename' => 'event_editor_save_new_event',
315
+					),
316
+					'event_editor_other_help_tab'                      => array(
317
+						'title'    => esc_html__('Event Other', 'event_espresso'),
318
+						'filename' => 'event_editor_other',
319
+					),
320
+				),
321
+				'help_tour'     => array(
322
+					'Event_Editor_Help_Tour',
323
+				),
324
+				'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
325
+				'require_nonce' => false,
326
+			),
327
+			'edit'                   => array(
328
+				'nav'           => array(
329
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
330
+					'order'      => 5,
331
+					'persistent' => false,
332
+					'url'        => isset($this->_req_data['post'])
333
+						? EE_Admin_Page::add_query_args_and_nonce(
334
+							array('post' => $this->_req_data['post'], 'action' => 'edit'),
335
+							$this->_current_page_view_url
336
+						)
337
+						: $this->_admin_base_url,
338
+				),
339
+				'metaboxes'     => array('_register_event_editor_meta_boxes'),
340
+				'help_tabs'     => array(
341
+					'event_editor_help_tab'                            => array(
342
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
343
+						'filename' => 'event_editor',
344
+					),
345
+					'event_editor_title_richtexteditor_help_tab'       => array(
346
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
347
+						'filename' => 'event_editor_title_richtexteditor',
348
+					),
349
+					'event_editor_venue_details_help_tab'              => array(
350
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
351
+						'filename' => 'event_editor_venue_details',
352
+					),
353
+					'event_editor_event_datetimes_help_tab'            => array(
354
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
355
+						'filename' => 'event_editor_event_datetimes',
356
+					),
357
+					'event_editor_event_tickets_help_tab'              => array(
358
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
359
+						'filename' => 'event_editor_event_tickets',
360
+					),
361
+					'event_editor_event_registration_options_help_tab' => array(
362
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
363
+						'filename' => 'event_editor_event_registration_options',
364
+					),
365
+					'event_editor_tags_categories_help_tab'            => array(
366
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
367
+						'filename' => 'event_editor_tags_categories',
368
+					),
369
+					'event_editor_questions_registrants_help_tab'      => array(
370
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
371
+						'filename' => 'event_editor_questions_registrants',
372
+					),
373
+					'event_editor_save_new_event_help_tab'             => array(
374
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
375
+						'filename' => 'event_editor_save_new_event',
376
+					),
377
+					'event_editor_other_help_tab'                      => array(
378
+						'title'    => esc_html__('Event Other', 'event_espresso'),
379
+						'filename' => 'event_editor_other',
380
+					),
381
+				),
382
+				/*'help_tour' => array(
383 383
 					'Event_Edit_Help_Tour'
384 384
 				),*/
385
-                'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
386
-                'require_nonce' => false,
387
-            ),
388
-            'default_event_settings' => array(
389
-                'nav'           => array(
390
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
391
-                    'order' => 40,
392
-                ),
393
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
394
-                'labels'        => array(
395
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
396
-                ),
397
-                'help_tabs'     => array(
398
-                    'default_settings_help_tab'        => array(
399
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
400
-                        'filename' => 'events_default_settings',
401
-                    ),
402
-                    'default_settings_status_help_tab' => array(
403
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
404
-                        'filename' => 'events_default_settings_status',
405
-                    ),
406
-                    'default_maximum_tickets_help_tab' => array(
407
-                        'title' => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
408
-                        'filename' => 'events_default_settings_max_tickets',
409
-                    )
410
-                ),
411
-                'help_tour'     => array('Event_Default_Settings_Help_Tour'),
412
-                'require_nonce' => false,
413
-            ),
414
-            //template settings
415
-            'template_settings'      => array(
416
-                'nav'           => array(
417
-                    'label' => esc_html__('Templates', 'event_espresso'),
418
-                    'order' => 30,
419
-                ),
420
-                'metaboxes'     => $this->_default_espresso_metaboxes,
421
-                'help_tabs'     => array(
422
-                    'general_settings_templates_help_tab' => array(
423
-                        'title'    => esc_html__('Templates', 'event_espresso'),
424
-                        'filename' => 'general_settings_templates',
425
-                    ),
426
-                ),
427
-                'help_tour'     => array('Templates_Help_Tour'),
428
-                'require_nonce' => false,
429
-            ),
430
-            //event category stuff
431
-            'add_category'           => array(
432
-                'nav'           => array(
433
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
434
-                    'order'      => 15,
435
-                    'persistent' => false,
436
-                ),
437
-                'help_tabs'     => array(
438
-                    'add_category_help_tab' => array(
439
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
440
-                        'filename' => 'events_add_category',
441
-                    ),
442
-                ),
443
-                'help_tour'     => array('Event_Add_Category_Help_Tour'),
444
-                'metaboxes'     => array('_publish_post_box'),
445
-                'require_nonce' => false,
446
-            ),
447
-            'edit_category'          => array(
448
-                'nav'           => array(
449
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
450
-                    'order'      => 15,
451
-                    'persistent' => false,
452
-                    'url'        => isset($this->_req_data['EVT_CAT_ID'])
453
-                        ? add_query_arg(
454
-                            array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']),
455
-                            $this->_current_page_view_url
456
-                        )
457
-                        : $this->_admin_base_url,
458
-                ),
459
-                'help_tabs'     => array(
460
-                    'edit_category_help_tab' => array(
461
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
462
-                        'filename' => 'events_edit_category',
463
-                    ),
464
-                ),
465
-                /*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
466
-                'metaboxes'     => array('_publish_post_box'),
467
-                'require_nonce' => false,
468
-            ),
469
-            'category_list'          => array(
470
-                'nav'           => array(
471
-                    'label' => esc_html__('Categories', 'event_espresso'),
472
-                    'order' => 20,
473
-                ),
474
-                'list_table'    => 'Event_Categories_Admin_List_Table',
475
-                'help_tabs'     => array(
476
-                    'events_categories_help_tab'                       => array(
477
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
478
-                        'filename' => 'events_categories',
479
-                    ),
480
-                    'events_categories_table_column_headings_help_tab' => array(
481
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
482
-                        'filename' => 'events_categories_table_column_headings',
483
-                    ),
484
-                    'events_categories_view_help_tab'                  => array(
485
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
486
-                        'filename' => 'events_categories_views',
487
-                    ),
488
-                    'events_categories_other_help_tab'                 => array(
489
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
490
-                        'filename' => 'events_categories_other',
491
-                    ),
492
-                ),
493
-                'help_tour'     => array(
494
-                    'Event_Categories_Help_Tour',
495
-                ),
496
-                'metaboxes'     => $this->_default_espresso_metaboxes,
497
-                'require_nonce' => false,
498
-            ),
499
-        );
500
-    }
501
-
502
-
503
-
504
-    protected function _add_screen_options()
505
-    {
506
-        //todo
507
-    }
508
-
509
-
510
-
511
-    protected function _add_screen_options_default()
512
-    {
513
-        $this->_per_page_screen_option();
514
-    }
515
-
516
-
517
-
518
-    protected function _add_screen_options_category_list()
519
-    {
520
-        $page_title = $this->_admin_page_title;
521
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
522
-        $this->_per_page_screen_option();
523
-        $this->_admin_page_title = $page_title;
524
-    }
525
-
526
-
527
-
528
-    protected function _add_feature_pointers()
529
-    {
530
-        //todo
531
-    }
532
-
533
-
534
-
535
-    public function load_scripts_styles()
536
-    {
537
-        wp_register_style(
538
-            'events-admin-css',
539
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
540
-            array(),
541
-            EVENT_ESPRESSO_VERSION
542
-        );
543
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
544
-        wp_enqueue_style('events-admin-css');
545
-        wp_enqueue_style('ee-cat-admin');
546
-        //todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
547
-        //registers for all views
548
-        //scripts
549
-        wp_register_script(
550
-            'event_editor_js',
551
-            EVENTS_ASSETS_URL . 'event_editor.js',
552
-            array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
553
-            EVENT_ESPRESSO_VERSION,
554
-            true
555
-        );
556
-    }
557
-
558
-
559
-
560
-    /**
561
-     * enqueuing scripts and styles specific to this view
562
-     *
563
-     * @return void
564
-     */
565
-    public function load_scripts_styles_create_new()
566
-    {
567
-        $this->load_scripts_styles_edit();
568
-    }
569
-
570
-
571
-
572
-    /**
573
-     * enqueuing scripts and styles specific to this view
574
-     *
575
-     * @return void
576
-     */
577
-    public function load_scripts_styles_edit()
578
-    {
579
-        //styles
580
-        wp_enqueue_style('espresso-ui-theme');
581
-        wp_register_style(
582
-            'event-editor-css',
583
-            EVENTS_ASSETS_URL . 'event-editor.css',
584
-            array('ee-admin-css'),
585
-            EVENT_ESPRESSO_VERSION
586
-        );
587
-        wp_enqueue_style('event-editor-css');
588
-        //scripts
589
-        wp_register_script(
590
-            'event-datetime-metabox',
591
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
592
-            array('event_editor_js', 'ee-datepicker'),
593
-            EVENT_ESPRESSO_VERSION
594
-        );
595
-        wp_enqueue_script('event-datetime-metabox');
596
-    }
597
-
598
-
599
-
600
-    public function load_scripts_styles_add_category()
601
-    {
602
-        $this->load_scripts_styles_edit_category();
603
-    }
604
-
605
-
606
-
607
-    public function load_scripts_styles_edit_category()
608
-    {
609
-    }
610
-
611
-
612
-
613
-    protected function _set_list_table_views_category_list()
614
-    {
615
-        $this->_views = array(
616
-            'all' => array(
617
-                'slug'        => 'all',
618
-                'label'       => esc_html__('All', 'event_espresso'),
619
-                'count'       => 0,
620
-                'bulk_action' => array(
621
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
622
-                ),
623
-            ),
624
-        );
625
-    }
626
-
627
-
628
-
629
-    public function admin_init()
630
-    {
631
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
632
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
633
-            'event_espresso'
634
-        );
635
-    }
636
-
637
-
638
-
639
-    //nothing needed for events with these methods.
640
-    public function admin_notices()
641
-    {
642
-    }
643
-
644
-
645
-
646
-    public function admin_footer_scripts()
647
-    {
648
-    }
649
-
650
-
651
-
652
-    /**
653
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
654
-     * warning (via EE_Error::add_error());
655
-     *
656
-     * @param  EE_Event $event Event object
657
-     * @access public
658
-     * @return void
659
-     */
660
-    public function verify_event_edit($event = null)
661
-    {
662
-        // no event?
663
-        if (empty($event)) {
664
-            // set event
665
-            $event = $this->_cpt_model_obj;
666
-        }
667
-        // STILL no event?
668
-        if (! $event instanceof EE_Event) {
669
-            return;
670
-        }
671
-        $orig_status = $event->status();
672
-        // first check if event is active.
673
-        if (
674
-            $orig_status === EEM_Event::cancelled
675
-            || $orig_status === EEM_Event::postponed
676
-            || $event->is_expired()
677
-            || $event->is_inactive()
678
-        ) {
679
-            return;
680
-        }
681
-        //made it here so it IS active... next check that any of the tickets are sold.
682
-        if ($event->is_sold_out(true)) {
683
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
684
-                EE_Error::add_attention(
685
-                    sprintf(
686
-                        esc_html__(
687
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
688
-                            'event_espresso'
689
-                        ),
690
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
691
-                    )
692
-                );
693
-            }
694
-            return;
695
-        } else if ($orig_status === EEM_Event::sold_out) {
696
-            EE_Error::add_attention(
697
-                sprintf(
698
-                    esc_html__(
699
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
700
-                        'event_espresso'
701
-                    ),
702
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
703
-                )
704
-            );
705
-        }
706
-        //now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
707
-        if ( ! $event->tickets_on_sale()) {
708
-            return;
709
-        }
710
-        //made it here so show warning
711
-        $this->_edit_event_warning();
712
-    }
713
-
714
-
715
-
716
-    /**
717
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
718
-     * When needed, hook this into a EE_Error::add_error() notice.
719
-     *
720
-     * @access protected
721
-     * @return void
722
-     */
723
-    protected function _edit_event_warning()
724
-    {
725
-        // we don't want to add warnings during these requests
726
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
727
-            return;
728
-        }
729
-        EE_Error::add_attention(
730
-            esc_html__(
731
-                'Please be advised that this event has been published and is open for registrations on your website. If you update any registration-related details (i.e. custom questions, messages, tickets, datetimes, etc.) while a registration is in process, the registration process could be interrupted and result in errors for the person registering and potentially incorrect registration or transaction data inside Event Espresso. We recommend editing events during a period of slow traffic, or even temporarily changing the status of an event to "Draft" until your edits are complete.',
732
-                'event_espresso'
733
-            )
734
-        );
735
-    }
736
-
737
-
738
-
739
-    /**
740
-     * When a user is creating a new event, notify them if they haven't set their timezone.
741
-     * Otherwise, do the normal logic
742
-     *
743
-     * @return string
744
-     * @throws \EE_Error
745
-     */
746
-    protected function _create_new_cpt_item()
747
-    {
748
-        $gmt_offset = get_option('gmt_offset');
749
-        //only nag them about setting their timezone if it's their first event, and they haven't already done it
750
-        if ($gmt_offset === '0' && ! EEM_Event::instance()->exists(array())) {
751
-            EE_Error::add_attention(
752
-                sprintf(
753
-                    __(
754
-                        'Your website\'s timezone is currently set to UTC + 0. We recommend updating your timezone to a city or region near you before you create an event. Your timezone can be updated through the %1$sGeneral Settings%2$s page.',
755
-                        'event_espresso'
756
-                    ),
757
-                    '<a href="' . admin_url('options-general.php') . '">',
758
-                    '</a>'
759
-                ),
760
-                __FILE__,
761
-                __FUNCTION__,
762
-                __LINE__
763
-            );
764
-        }
765
-        return parent::_create_new_cpt_item();
766
-    }
767
-
768
-
769
-
770
-    protected function _set_list_table_views_default()
771
-    {
772
-        $this->_views = array(
773
-            'all'   => array(
774
-                'slug'        => 'all',
775
-                'label'       => esc_html__('View All Events', 'event_espresso'),
776
-                'count'       => 0,
777
-                'bulk_action' => array(
778
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
779
-                ),
780
-            ),
781
-            'draft' => array(
782
-                'slug'        => 'draft',
783
-                'label'       => esc_html__('Draft', 'event_espresso'),
784
-                'count'       => 0,
785
-                'bulk_action' => array(
786
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
787
-                ),
788
-            ),
789
-        );
790
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
791
-            $this->_views['trash'] = array(
792
-                'slug'        => 'trash',
793
-                'label'       => esc_html__('Trash', 'event_espresso'),
794
-                'count'       => 0,
795
-                'bulk_action' => array(
796
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
797
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
798
-                ),
799
-            );
800
-        }
801
-    }
802
-
803
-
804
-
805
-    /**
806
-     * @return array
807
-     */
808
-    protected function _event_legend_items()
809
-    {
810
-        $items = array(
811
-            'view_details'   => array(
812
-                'class' => 'dashicons dashicons-search',
813
-                'desc'  => esc_html__('View Event', 'event_espresso'),
814
-            ),
815
-            'edit_event'     => array(
816
-                'class' => 'ee-icon ee-icon-calendar-edit',
817
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
818
-            ),
819
-            'view_attendees' => array(
820
-                'class' => 'dashicons dashicons-groups',
821
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
822
-            ),
823
-        );
824
-        $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
825
-        $statuses = array(
826
-            'sold_out_status'  => array(
827
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
828
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
829
-            ),
830
-            'active_status'    => array(
831
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
832
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
833
-            ),
834
-            'upcoming_status'  => array(
835
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
836
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
837
-            ),
838
-            'postponed_status' => array(
839
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
840
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
841
-            ),
842
-            'cancelled_status' => array(
843
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
844
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
845
-            ),
846
-            'expired_status'   => array(
847
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
848
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
849
-            ),
850
-            'inactive_status'  => array(
851
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
852
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
853
-            ),
854
-        );
855
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
856
-        return array_merge($items, $statuses);
857
-    }
858
-
859
-
860
-
861
-    /**
862
-     * _event_model
863
-     *
864
-     * @return EEM_Event
865
-     */
866
-    private function _event_model()
867
-    {
868
-        if ( ! $this->_event_model instanceof EEM_Event) {
869
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
870
-        }
871
-        return $this->_event_model;
872
-    }
873
-
874
-
875
-
876
-    /**
877
-     * Adds extra buttons to the WP CPT permalink field row.
878
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
879
-     *
880
-     * @param  string $return    the current html
881
-     * @param  int    $id        the post id for the page
882
-     * @param  string $new_title What the title is
883
-     * @param  string $new_slug  what the slug is
884
-     * @return string            The new html string for the permalink area
885
-     */
886
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
887
-    {
888
-        //make sure this is only when editing
889
-        if ( ! empty($id)) {
890
-            $post = get_post($id);
891
-            $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
892
-                       . esc_html__('Shortcode', 'event_espresso')
893
-                       . '</a> ';
894
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
895
-                       . $post->ID
896
-                       . ']">';
897
-        }
898
-        return $return;
899
-    }
900
-
901
-
902
-
903
-    /**
904
-     * _events_overview_list_table
905
-     * This contains the logic for showing the events_overview list
906
-     *
907
-     * @access protected
908
-     * @return void
909
-     * @throws \EE_Error
910
-     */
911
-    protected function _events_overview_list_table()
912
-    {
913
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
914
-        $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
915
-            ? (array)$this->_template_args['after_list_table']
916
-            : array();
917
-        $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
918
-                                                                              . EEH_Template::get_button_or_link(
919
-                get_post_type_archive_link('espresso_events'),
920
-                esc_html__("View Event Archive Page", "event_espresso"),
921
-                'button'
922
-            );
923
-        $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
924
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
925
-                'create_new',
926
-                'add',
927
-                array(),
928
-                'add-new-h2'
929
-            );
930
-        $this->display_admin_list_table_page_with_no_sidebar();
931
-    }
932
-
933
-
934
-
935
-    /**
936
-     * this allows for extra misc actions in the default WP publish box
937
-     *
938
-     * @return void
939
-     */
940
-    public function extra_misc_actions_publish_box()
941
-    {
942
-        $this->_generate_publish_box_extra_content();
943
-    }
944
-
945
-
946
-
947
-    /**
948
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
949
-     * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
950
-     * data.
951
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
952
-     * ALSO very important.  When a post transitions from scheduled to published, the save_post action is fired but you
953
-     * will NOT have any _POST data containing any extra info you may have from other meta saves.  So MAKE sure that
954
-     * you handle this accordingly.
955
-     *
956
-     * @access protected
957
-     * @abstract
958
-     * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
959
-     * @param  object $post    The post object of the cpt that was saved.
960
-     * @return void
961
-     */
962
-    protected function _insert_update_cpt_item($post_id, $post)
963
-    {
964
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
965
-            //get out we're not processing an event save.
966
-            return;
967
-        }
968
-        $event_values = array(
969
-            'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
970
-            'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
971
-            'EVT_additional_limit'            => min(
972
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
973
-                ! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
974
-            ),
975
-            'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
976
-                ? $this->_req_data['EVT_default_registration_status']
977
-                : EE_Registry::instance()->CFG->registration->default_STS_ID,
978
-            'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
979
-            'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
980
-            'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
981
-                ? $this->_req_data['timezone_string'] : null,
982
-            'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
983
-                ? $this->_req_data['externalURL'] : null,
984
-            'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
985
-                ? $this->_req_data['event_phone'] : null,
986
-        );
987
-        //update event
988
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
989
-        //get event_object for other metaboxes... though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id!
990
-        $get_one_where = array($this->_event_model()->primary_key_name() => $post_id, 'status' => $post->post_status);
991
-        $event = $this->_event_model()->get_one(array($get_one_where));
992
-        //the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
993
-        $event_update_callbacks = apply_filters(
994
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
995
-            array(array($this, '_default_venue_update'), array($this, '_default_tickets_update'))
996
-        );
997
-        $att_success = true;
998
-        foreach ($event_update_callbacks as $e_callback) {
999
-            $_succ = call_user_func_array($e_callback, array($event, $this->_req_data));
1000
-            $att_success = ! $att_success ? $att_success
1001
-                : $_succ; //if ANY of these updates fail then we want the appropriate global error message
1002
-        }
1003
-        //any errors?
1004
-        if ($success && false === $att_success) {
1005
-            EE_Error::add_error(
1006
-                esc_html__(
1007
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1008
-                    'event_espresso'
1009
-                ),
1010
-                __FILE__,
1011
-                __FUNCTION__,
1012
-                __LINE__
1013
-            );
1014
-        } else if ($success === false) {
1015
-            EE_Error::add_error(
1016
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1017
-                __FILE__,
1018
-                __FUNCTION__,
1019
-                __LINE__
1020
-            );
1021
-        }
1022
-    }
1023
-
1024
-
1025
-
1026
-    /**
1027
-     * @see parent::restore_item()
1028
-     * @param int $post_id
1029
-     * @param int $revision_id
1030
-     */
1031
-    protected function _restore_cpt_item($post_id, $revision_id)
1032
-    {
1033
-        //copy existing event meta to new post
1034
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1035
-        if ($post_evt instanceof EE_Event) {
1036
-            //meta revision restore
1037
-            $post_evt->restore_revision($revision_id);
1038
-            //related objs restore
1039
-            $post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1040
-        }
1041
-    }
1042
-
1043
-
1044
-
1045
-    /**
1046
-     * Attach the venue to the Event
1047
-     *
1048
-     * @param  \EE_Event $evtobj Event Object to add the venue to
1049
-     * @param  array     $data   The request data from the form
1050
-     * @return bool           Success or fail.
1051
-     */
1052
-    protected function _default_venue_update(\EE_Event $evtobj, $data)
1053
-    {
1054
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1055
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1056
-        $rows_affected = null;
1057
-        $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1058
-        // very important.  If we don't have a venue name...
1059
-        // then we'll get out because not necessary to create empty venue
1060
-        if (empty($data['venue_title'])) {
1061
-            return false;
1062
-        }
1063
-        $venue_array = array(
1064
-            'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1065
-            'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1066
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1067
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1068
-            'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1069
-                : null,
1070
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1071
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1072
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1073
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1074
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1075
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1076
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1077
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1078
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1079
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1080
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1081
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1082
-            'status'              => 'publish',
1083
-        );
1084
-        //if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1085
-        if ( ! empty($venue_id)) {
1086
-            $update_where = array($venue_model->primary_key_name() => $venue_id);
1087
-            $rows_affected = $venue_model->update($venue_array, array($update_where));
1088
-            //we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1089
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1090
-            return $rows_affected > 0 ? true : false;
1091
-        } else {
1092
-            //we insert the venue
1093
-            $venue_id = $venue_model->insert($venue_array);
1094
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1095
-            return ! empty($venue_id) ? true : false;
1096
-        }
1097
-        //when we have the ancestor come in it's already been handled by the revision save.
1098
-    }
1099
-
1100
-
1101
-
1102
-    /**
1103
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1104
-     *
1105
-     * @param  EE_Event $evtobj The Event object we're attaching data to
1106
-     * @param  array    $data   The request data from the form
1107
-     * @return array
1108
-     */
1109
-    protected function _default_tickets_update(EE_Event $evtobj, $data)
1110
-    {
1111
-        $success = true;
1112
-        $saved_dtt = null;
1113
-        $saved_tickets = array();
1114
-        $incoming_date_formats = array('Y-m-d', 'h:i a');
1115
-        foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1116
-            //trim all values to ensure any excess whitespace is removed.
1117
-            $dtt = array_map('trim', $dtt);
1118
-            $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1119
-                : $dtt['DTT_EVT_start'];
1120
-            $datetime_values = array(
1121
-                'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1122
-                'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1123
-                'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1124
-                'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1125
-                'DTT_order'     => $row,
1126
-            );
1127
-            //if we have an id then let's get existing object first and then set the new values.  Otherwise we instantiate a new object for save.
1128
-            if ( ! empty($dtt['DTT_ID'])) {
1129
-                $DTM = EE_Registry::instance()
1130
-                                  ->load_model('Datetime', array($evtobj->get_timezone()))
1131
-                                  ->get_one_by_ID($dtt['DTT_ID']);
1132
-                $DTM->set_date_format($incoming_date_formats[0]);
1133
-                $DTM->set_time_format($incoming_date_formats[1]);
1134
-                foreach ($datetime_values as $field => $value) {
1135
-                    $DTM->set($field, $value);
1136
-                }
1137
-                //make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it.  We need to do this so we dont' TRASH the parent DTT.
1138
-                $saved_dtts[$DTM->ID()] = $DTM;
1139
-            } else {
1140
-                $DTM = EE_Registry::instance()->load_class(
1141
-                    'Datetime',
1142
-                    array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1143
-                    false,
1144
-                    false
1145
-                );
1146
-                foreach ($datetime_values as $field => $value) {
1147
-                    $DTM->set($field, $value);
1148
-                }
1149
-            }
1150
-            $DTM->save();
1151
-            $DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1152
-            //load DTT helper
1153
-            //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1154
-            if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1155
-                $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1156
-                $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1157
-                $DTT->save();
1158
-            }
1159
-            //now we got to make sure we add the new DTT_ID to the $saved_dtts array  because it is possible there was a new one created for the autosave.
1160
-            $saved_dtt = $DTT;
1161
-            $success = ! $success ? $success : $DTT;
1162
-            //if ANY of these updates fail then we want the appropriate global error message.
1163
-            // //todo this is actually sucky we need a better error message but this is what it is for now.
1164
-        }
1165
-        //no dtts get deleted so we don't do any of that logic here.
1166
-        //update tickets next
1167
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1168
-        foreach ($data['edit_tickets'] as $row => $tkt) {
1169
-            $incoming_date_formats = array('Y-m-d', 'h:i a');
1170
-            $update_prices = false;
1171
-            $ticket_price = isset($data['edit_prices'][$row][1]['PRC_amount'])
1172
-                ? $data['edit_prices'][$row][1]['PRC_amount'] : 0;
1173
-            // trim inputs to ensure any excess whitespace is removed.
1174
-            $tkt = array_map('trim', $tkt);
1175
-            if (empty($tkt['TKT_start_date'])) {
1176
-                //let's use now in the set timezone.
1177
-                $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1178
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1179
-            }
1180
-            if (empty($tkt['TKT_end_date'])) {
1181
-                //use the start date of the first datetime
1182
-                $dtt = $evtobj->first_datetime();
1183
-                $tkt['TKT_end_date'] = $dtt->start_date_and_time(
1184
-                    $incoming_date_formats[0],
1185
-                    $incoming_date_formats[1]
1186
-                );
1187
-            }
1188
-            $TKT_values = array(
1189
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1190
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1191
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1192
-                'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1193
-                'TKT_start_date'  => $tkt['TKT_start_date'],
1194
-                'TKT_end_date'    => $tkt['TKT_end_date'],
1195
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1196
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1197
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1198
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1199
-                'TKT_row'         => $row,
1200
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1201
-                'TKT_price'       => $ticket_price,
1202
-            );
1203
-            //if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
1204
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1205
-                $TKT_values['TKT_ID'] = 0;
1206
-                $TKT_values['TKT_is_default'] = 0;
1207
-                $TKT_values['TKT_price'] = $ticket_price;
1208
-                $update_prices = true;
1209
-            }
1210
-            //if we have a TKT_ID then we need to get that existing TKT_obj and update it
1211
-            //we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
1212
-            //keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1213
-            if ( ! empty($tkt['TKT_ID'])) {
1214
-                $TKT = EE_Registry::instance()
1215
-                                  ->load_model('Ticket', array($evtobj->get_timezone()))
1216
-                                  ->get_one_by_ID($tkt['TKT_ID']);
1217
-                if ($TKT instanceof EE_Ticket) {
1218
-                    $ticket_sold = $TKT->count_related(
1219
-                        'Registration',
1220
-                        array(
1221
-                            array(
1222
-                                'STS_ID' => array(
1223
-                                    'NOT IN',
1224
-                                    array(EEM_Registration::status_id_incomplete),
1225
-                                ),
1226
-                            ),
1227
-                        )
1228
-                    ) > 0 ? true : false;
1229
-                    //let's just check the total price for the existing ticket and determine if it matches the new total price.  if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket.
1230
-                    $create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price')
1231
-                                      && ! $TKT->get(
1232
-                        'TKT_deleted'
1233
-                    ) ? true : false;
1234
-                    $TKT->set_date_format($incoming_date_formats[0]);
1235
-                    $TKT->set_time_format($incoming_date_formats[1]);
1236
-                    //set new values
1237
-                    foreach ($TKT_values as $field => $value) {
1238
-                        if ($field == 'TKT_qty') {
1239
-                            $TKT->set_qty($value);
1240
-                        } else {
1241
-                            $TKT->set($field, $value);
1242
-                        }
1243
-                    }
1244
-                    //if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1245
-                    if ($create_new_TKT) {
1246
-                        //archive the old ticket first
1247
-                        $TKT->set('TKT_deleted', 1);
1248
-                        $TKT->save();
1249
-                        //make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1250
-                        $saved_tickets[$TKT->ID()] = $TKT;
1251
-                        //create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it.
1252
-                        $TKT = clone $TKT;
1253
-                        $TKT->set('TKT_ID', 0);
1254
-                        $TKT->set('TKT_deleted', 0);
1255
-                        $TKT->set('TKT_price', $ticket_price);
1256
-                        $TKT->set('TKT_sold', 0);
1257
-                        //now we need to make sure that $new prices are created as well and attached to new ticket.
1258
-                        $update_prices = true;
1259
-                    }
1260
-                    //make sure price is set if it hasn't been already
1261
-                    $TKT->set('TKT_price', $ticket_price);
1262
-                }
1263
-            } else {
1264
-                //no TKT_id so a new TKT
1265
-                $TKT_values['TKT_price'] = $ticket_price;
1266
-                $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1267
-                if ($TKT instanceof EE_Ticket) {
1268
-                    //need to reset values to properly account for the date formats
1269
-                    $TKT->set_date_format($incoming_date_formats[0]);
1270
-                    $TKT->set_time_format($incoming_date_formats[1]);
1271
-                    $TKT->set_timezone($evtobj->get_timezone());
1272
-                    //set new values
1273
-                    foreach ($TKT_values as $field => $value) {
1274
-                        if ($field == 'TKT_qty') {
1275
-                            $TKT->set_qty($value);
1276
-                        } else {
1277
-                            $TKT->set($field, $value);
1278
-                        }
1279
-                    }
1280
-                    $update_prices = true;
1281
-                }
1282
-            }
1283
-            // cap ticket qty by datetime reg limits
1284
-            $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1285
-            //update ticket.
1286
-            $TKT->save();
1287
-            //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1288
-            if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1289
-                $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1290
-                $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1291
-                $TKT->save();
1292
-            }
1293
-            //initially let's add the ticket to the dtt
1294
-            $saved_dtt->_add_relation_to($TKT, 'Ticket');
1295
-            $saved_tickets[$TKT->ID()] = $TKT;
1296
-            //add prices to ticket
1297
-            $this->_add_prices_to_ticket($data['edit_prices'][$row], $TKT, $update_prices);
1298
-        }
1299
-        //however now we need to handle permanently deleting tickets via the ui.  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.  However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db.
1300
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
1301
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1302
-        foreach ($tickets_removed as $id) {
1303
-            $id = absint($id);
1304
-            //get the ticket for this id
1305
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1306
-            //need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold)
1307
-            $dtts = $tkt_to_remove->get_many_related('Datetime');
1308
-            foreach ($dtts as $dtt) {
1309
-                $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1310
-            }
1311
-            //need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1312
-            $tkt_to_remove->delete_related_permanently('Price');
1313
-            //finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1314
-            $tkt_to_remove->delete_permanently();
1315
-        }
1316
-        return array($saved_dtt, $saved_tickets);
1317
-    }
1318
-
1319
-
1320
-
1321
-    /**
1322
-     * This attaches a list of given prices to a ticket.
1323
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1324
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1325
-     * price info and prices are automatically "archived" via the ticket.
1326
-     *
1327
-     * @access  private
1328
-     * @param array     $prices     Array of prices from the form.
1329
-     * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1330
-     * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1331
-     * @return  void
1332
-     */
1333
-    private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1334
-    {
1335
-        foreach ($prices as $row => $prc) {
1336
-            $PRC_values = array(
1337
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1338
-                'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1339
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1340
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1341
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1342
-                'PRC_is_default' => 0, //make sure prices are NOT set as default from this context
1343
-                'PRC_order'      => $row,
1344
-            );
1345
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
1346
-                $PRC_values['PRC_ID'] = 0;
1347
-                $PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1348
-            } else {
1349
-                $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1350
-                //update this price with new values
1351
-                foreach ($PRC_values as $field => $newprc) {
1352
-                    $PRC->set($field, $newprc);
1353
-                }
1354
-                $PRC->save();
1355
-            }
1356
-            $ticket->_add_relation_to($PRC, 'Price');
1357
-        }
1358
-    }
1359
-
1360
-
1361
-
1362
-    /**
1363
-     * Add in our autosave ajax handlers
1364
-     *
1365
-     * @return void
1366
-     */
1367
-    protected function _ee_autosave_create_new()
1368
-    {
1369
-        // $this->_ee_autosave_edit();
1370
-    }
1371
-
1372
-
1373
-
1374
-    protected function _ee_autosave_edit()
1375
-    {
1376
-        return; //TEMPORARILY EXITING CAUSE THIS IS A TODO
1377
-    }
1378
-
1379
-
1380
-
1381
-    /**
1382
-     *    _generate_publish_box_extra_content
1383
-     *
1384
-     * @access private
1385
-     * @return void
1386
-     */
1387
-    private function _generate_publish_box_extra_content()
1388
-    {
1389
-        //load formatter helper
1390
-        //args for getting related registrations
1391
-        $approved_query_args = array(
1392
-            array(
1393
-                'REG_deleted' => 0,
1394
-                'STS_ID'      => EEM_Registration::status_id_approved,
1395
-            ),
1396
-        );
1397
-        $not_approved_query_args = array(
1398
-            array(
1399
-                'REG_deleted' => 0,
1400
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1401
-            ),
1402
-        );
1403
-        $pending_payment_query_args = array(
1404
-            array(
1405
-                'REG_deleted' => 0,
1406
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1407
-            ),
1408
-        );
1409
-        // publish box
1410
-        $publish_box_extra_args = array(
1411
-            'view_approved_reg_url'        => add_query_arg(
1412
-                array(
1413
-                    'action'      => 'default',
1414
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1415
-                    '_reg_status' => EEM_Registration::status_id_approved,
1416
-                ),
1417
-                REG_ADMIN_URL
1418
-            ),
1419
-            'view_not_approved_reg_url'    => add_query_arg(
1420
-                array(
1421
-                    'action'      => 'default',
1422
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1423
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1424
-                ),
1425
-                REG_ADMIN_URL
1426
-            ),
1427
-            'view_pending_payment_reg_url' => add_query_arg(
1428
-                array(
1429
-                    'action'      => 'default',
1430
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1431
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1432
-                ),
1433
-                REG_ADMIN_URL
1434
-            ),
1435
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1436
-                'Registration',
1437
-                $approved_query_args
1438
-            ),
1439
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1440
-                'Registration',
1441
-                $not_approved_query_args
1442
-            ),
1443
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1444
-                'Registration',
1445
-                $pending_payment_query_args
1446
-            ),
1447
-            'misc_pub_section_class'       => apply_filters(
1448
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1449
-                'misc-pub-section'
1450
-            ),
1451
-            //'email_attendees_url' => add_query_arg(
1452
-            //	array(
1453
-            //		'event_admin_reports' => 'event_newsletter',
1454
-            //		'event_id' => $this->_cpt_model_obj->id
1455
-            //	),
1456
-            //	'admin.php?page=espresso_registrations'
1457
-            //),
1458
-        );
1459
-        ob_start();
1460
-        do_action(
1461
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1462
-            $this->_cpt_model_obj
1463
-        );
1464
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1465
-        // load template
1466
-        EEH_Template::display_template(
1467
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1468
-            $publish_box_extra_args
1469
-        );
1470
-    }
1471
-
1472
-
1473
-
1474
-    /**
1475
-     * This just returns whatever is set as the _event object property
1476
-     * //todo this will become obsolete once the models are in place
1477
-     *
1478
-     * @return object
1479
-     */
1480
-    public function get_event_object()
1481
-    {
1482
-        return $this->_cpt_model_obj;
1483
-    }
1484
-
1485
-
1486
-
1487
-
1488
-    /** METABOXES * */
1489
-    /**
1490
-     * _register_event_editor_meta_boxes
1491
-     * add all metaboxes related to the event_editor
1492
-     *
1493
-     * @return void
1494
-     */
1495
-    protected function _register_event_editor_meta_boxes()
1496
-    {
1497
-        $this->verify_cpt_object();
1498
-        add_meta_box(
1499
-            'espresso_event_editor_tickets',
1500
-            esc_html__('Event Datetime & Ticket', 'event_espresso'),
1501
-            array($this, 'ticket_metabox'),
1502
-            $this->page_slug,
1503
-            'normal',
1504
-            'high'
1505
-        );
1506
-        add_meta_box(
1507
-            'espresso_event_editor_event_options',
1508
-            esc_html__('Event Registration Options', 'event_espresso'),
1509
-            array($this, 'registration_options_meta_box'),
1510
-            $this->page_slug,
1511
-            'side',
1512
-            'default'
1513
-        );
1514
-        // NOTE: if you're looking for other metaboxes in here,
1515
-        // where a metabox has a related management page in the admin
1516
-        // you will find it setup in the related management page's "_Hooks" file.
1517
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1518
-    }
1519
-
1520
-
1521
-
1522
-    public function ticket_metabox()
1523
-    {
1524
-        $existing_datetime_ids = $existing_ticket_ids = array();
1525
-        //defaults for template args
1526
-        $template_args = array(
1527
-            'existing_datetime_ids'    => '',
1528
-            'event_datetime_help_link' => '',
1529
-            'ticket_options_help_link' => '',
1530
-            'time'                     => null,
1531
-            'ticket_rows'              => '',
1532
-            'existing_ticket_ids'      => '',
1533
-            'total_ticket_rows'        => 1,
1534
-            'ticket_js_structure'      => '',
1535
-            'trash_icon'               => 'ee-lock-icon',
1536
-            'disabled'                 => '',
1537
-        );
1538
-        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1539
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1540
-        /**
1541
-         * 1. Start with retrieving Datetimes
1542
-         * 2. Fore each datetime get related tickets
1543
-         * 3. For each ticket get related prices
1544
-         */
1545
-        $times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1546
-        /** @type EE_Datetime $first_datetime */
1547
-        $first_datetime = reset($times);
1548
-        //do we get related tickets?
1549
-        if ($first_datetime instanceof EE_Datetime
1550
-            && $first_datetime->ID() !== 0
1551
-        ) {
1552
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1553
-            $template_args['time'] = $first_datetime;
1554
-            $related_tickets = $first_datetime->tickets(
1555
-                array(
1556
-                    array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1557
-                    'default_where_conditions' => 'none',
1558
-                )
1559
-            );
1560
-            if ( ! empty($related_tickets)) {
1561
-                $template_args['total_ticket_rows'] = count($related_tickets);
1562
-                $row = 0;
1563
-                foreach ($related_tickets as $ticket) {
1564
-                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1565
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1566
-                    $row++;
1567
-                }
1568
-            } else {
1569
-                $template_args['total_ticket_rows'] = 1;
1570
-                /** @type EE_Ticket $ticket */
1571
-                $ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1572
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1573
-            }
1574
-        } else {
1575
-            $template_args['time'] = $times[0];
1576
-            /** @type EE_Ticket $ticket */
1577
-            $ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1578
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1579
-            // NOTE: we're just sending the first default row
1580
-            // (decaf can't manage default tickets so this should be sufficient);
1581
-        }
1582
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1583
-            'event_editor_event_datetimes_help_tab'
1584
-        );
1585
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1586
-        $template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1587
-        $template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1588
-        $template_args['ticket_js_structure'] = $this->_get_ticket_row(
1589
-            EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1590
-            true
1591
-        );
1592
-        $template = apply_filters(
1593
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1594
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1595
-        );
1596
-        EEH_Template::display_template($template, $template_args);
1597
-    }
1598
-
1599
-
1600
-
1601
-    /**
1602
-     * Setup an individual ticket form for the decaf event editor page
1603
-     *
1604
-     * @access private
1605
-     * @param  EE_Ticket $ticket   the ticket object
1606
-     * @param  boolean   $skeleton whether we're generating a skeleton for js manipulation
1607
-     * @param int        $row
1608
-     * @return string generated html for the ticket row.
1609
-     */
1610
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1611
-    {
1612
-        $template_args = array(
1613
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1614
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1615
-                : '',
1616
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1617
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1618
-            'TKT_name'            => $ticket->get('TKT_name'),
1619
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1620
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1621
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1622
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1623
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1624
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1625
-            'trash_icon'          => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')))
1626
-                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1627
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1628
-            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1629
-                : ' disabled=disabled',
1630
-        );
1631
-        $price = $ticket->ID() !== 0
1632
-            ? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1633
-            : EE_Registry::instance()->load_model('Price')->create_default_object();
1634
-        $price_args = array(
1635
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1636
-            'PRC_amount'            => $price->get('PRC_amount'),
1637
-            'PRT_ID'                => $price->get('PRT_ID'),
1638
-            'PRC_ID'                => $price->get('PRC_ID'),
1639
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1640
-        );
1641
-        //make sure we have default start and end dates if skeleton
1642
-        //handle rows that should NOT be empty
1643
-        if (empty($template_args['TKT_start_date'])) {
1644
-            //if empty then the start date will be now.
1645
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1646
-        }
1647
-        if (empty($template_args['TKT_end_date'])) {
1648
-            //get the earliest datetime (if present);
1649
-            $earliest_dtt = $this->_cpt_model_obj->ID() > 0
1650
-                ? $this->_cpt_model_obj->get_first_related(
1651
-                    'Datetime',
1652
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1653
-                )
1654
-                : null;
1655
-            if ( ! empty($earliest_dtt)) {
1656
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1657
-            } else {
1658
-                $template_args['TKT_end_date'] = date(
1659
-                    'Y-m-d h:i a',
1660
-                    mktime(0, 0, 0, date("m"), date("d") + 7, date("Y"))
1661
-                );
1662
-            }
1663
-        }
1664
-        $template_args = array_merge($template_args, $price_args);
1665
-        $template = apply_filters(
1666
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1667
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1668
-            $ticket
1669
-        );
1670
-        return EEH_Template::display_template($template, $template_args, true);
1671
-    }
1672
-
1673
-
1674
-
1675
-    public function registration_options_meta_box()
1676
-    {
1677
-        $yes_no_values = array(
1678
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1679
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1680
-        );
1681
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1682
-            array(
1683
-                EEM_Registration::status_id_cancelled,
1684
-                EEM_Registration::status_id_declined,
1685
-                EEM_Registration::status_id_incomplete,
1686
-            ),
1687
-            true
1688
-        );
1689
-        //$template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1690
-        $template_args['_event'] = $this->_cpt_model_obj;
1691
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1692
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1693
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1694
-            'default_reg_status',
1695
-            $default_reg_status_values,
1696
-            $this->_cpt_model_obj->default_registration_status()
1697
-        );
1698
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
1699
-            'display_desc',
1700
-            $yes_no_values,
1701
-            $this->_cpt_model_obj->display_description()
1702
-        );
1703
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1704
-            'display_ticket_selector',
1705
-            $yes_no_values,
1706
-            $this->_cpt_model_obj->display_ticket_selector(),
1707
-            '',
1708
-            '',
1709
-            false
1710
-        );
1711
-        $template_args['additional_registration_options'] = apply_filters(
1712
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1713
-            '',
1714
-            $template_args,
1715
-            $yes_no_values,
1716
-            $default_reg_status_values
1717
-        );
1718
-        EEH_Template::display_template(
1719
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1720
-            $template_args
1721
-        );
1722
-    }
1723
-
1724
-
1725
-
1726
-    /**
1727
-     * _get_events()
1728
-     * This method simply returns all the events (for the given _view and paging)
1729
-     *
1730
-     * @access public
1731
-     * @param int  $per_page     count of items per page (20 default);
1732
-     * @param int  $current_page what is the current page being viewed.
1733
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1734
-     *                           If FALSE then we return an array of event objects
1735
-     *                           that match the given _view and paging parameters.
1736
-     * @return array an array of event objects.
1737
-     */
1738
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1739
-    {
1740
-        $EEME = $this->_event_model();
1741
-        $offset = ($current_page - 1) * $per_page;
1742
-        $limit = $count ? null : $offset . ',' . $per_page;
1743
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1744
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1745
-        if (isset($this->_req_data['month_range'])) {
1746
-            $pieces = explode(' ', $this->_req_data['month_range'], 3);
1747
-            //simulate the FIRST day of the month, that fixes issues for months like February
1748
-            //where PHP doesn't know what to assume for date.
1749
-            //@see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1750
-            $month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1751
-            $year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1752
-        }
1753
-        $where = array();
1754
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1755
-        //determine what post_status our condition will have for the query.
1756
-        switch ($status) {
1757
-            case 'month' :
1758
-            case 'today' :
1759
-            case null :
1760
-            case 'all' :
1761
-                break;
1762
-            case 'draft' :
1763
-                $where['status'] = array('IN', array('draft', 'auto-draft'));
1764
-                break;
1765
-            default :
1766
-                $where['status'] = $status;
1767
-        }
1768
-        //categories?
1769
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1770
-            ? $this->_req_data['EVT_CAT'] : null;
1771
-        if ( ! empty ($category)) {
1772
-            $where['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1773
-            $where['Term_Taxonomy.term_id'] = $category;
1774
-        }
1775
-        //date where conditions
1776
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1777
-        if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1778
-            $DateTime = new DateTime(
1779
-                $year_r . '-' . $month_r . '-01 00:00:00',
1780
-                new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1781
-            );
1782
-            $start = $DateTime->format(implode(' ', $start_formats));
1783
-            $end = $DateTime->setDate($year_r, $month_r, $DateTime
1784
-                ->format('t'))->setTime(23, 59, 59)
1785
-                            ->format(implode(' ', $start_formats));
1786
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1787
-        } else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') {
1788
-            $DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1789
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1790
-            $end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1791
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1792
-        } else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') {
1793
-            $now = date('Y-m-01');
1794
-            $DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1795
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1796
-            $end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1797
-                            ->setTime(23, 59, 59)
1798
-                            ->format(implode(' ', $start_formats));
1799
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1800
-        }
1801
-        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1802
-            $where['EVT_wp_user'] = get_current_user_id();
1803
-        } else {
1804
-            if ( ! isset($where['status'])) {
1805
-                if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1806
-                    $where['OR'] = array(
1807
-                        'status*restrict_private' => array('!=', 'private'),
1808
-                        'AND'                     => array(
1809
-                            'status*inclusive' => array('=', 'private'),
1810
-                            'EVT_wp_user'      => get_current_user_id(),
1811
-                        ),
1812
-                    );
1813
-                }
1814
-            }
1815
-        }
1816
-        if (isset($this->_req_data['EVT_wp_user'])) {
1817
-            if ($this->_req_data['EVT_wp_user'] != get_current_user_id()
1818
-                && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1819
-            ) {
1820
-                $where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1821
-            }
1822
-        }
1823
-        //search query handling
1824
-        if (isset($this->_req_data['s'])) {
1825
-            $search_string = '%' . $this->_req_data['s'] . '%';
1826
-            $where['OR'] = array(
1827
-                'EVT_name'       => array('LIKE', $search_string),
1828
-                'EVT_desc'       => array('LIKE', $search_string),
1829
-                'EVT_short_desc' => array('LIKE', $search_string),
1830
-            );
1831
-        }
1832
-        $where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1833
-        $query_params = apply_filters(
1834
-            'FHEE__Events_Admin_Page__get_events__query_params',
1835
-            array(
1836
-                $where,
1837
-                'limit'    => $limit,
1838
-                'order_by' => $orderby,
1839
-                'order'    => $order,
1840
-                'group_by' => 'EVT_ID',
1841
-            ),
1842
-            $this->_req_data
1843
-        );
1844
-        //let's first check if we have special requests coming in.
1845
-        if (isset($this->_req_data['active_status'])) {
1846
-            switch ($this->_req_data['active_status']) {
1847
-                case 'upcoming' :
1848
-                    return $EEME->get_upcoming_events($query_params, $count);
1849
-                    break;
1850
-                case 'expired' :
1851
-                    return $EEME->get_expired_events($query_params, $count);
1852
-                    break;
1853
-                case 'active' :
1854
-                    return $EEME->get_active_events($query_params, $count);
1855
-                    break;
1856
-                case 'inactive' :
1857
-                    return $EEME->get_inactive_events($query_params, $count);
1858
-                    break;
1859
-            }
1860
-        }
1861
-        $events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1862
-        return $events;
1863
-    }
1864
-
1865
-
1866
-
1867
-    /**
1868
-     * handling for WordPress CPT actions (trash, restore, delete)
1869
-     *
1870
-     * @param string $post_id
1871
-     */
1872
-    public function trash_cpt_item($post_id)
1873
-    {
1874
-        $this->_req_data['EVT_ID'] = $post_id;
1875
-        $this->_trash_or_restore_event('trash', false);
1876
-    }
1877
-
1878
-
1879
-
1880
-    /**
1881
-     * @param string $post_id
1882
-     */
1883
-    public function restore_cpt_item($post_id)
1884
-    {
1885
-        $this->_req_data['EVT_ID'] = $post_id;
1886
-        $this->_trash_or_restore_event('draft', false);
1887
-    }
1888
-
1889
-
1890
-
1891
-    /**
1892
-     * @param string $post_id
1893
-     */
1894
-    public function delete_cpt_item($post_id)
1895
-    {
1896
-        $this->_req_data['EVT_ID'] = $post_id;
1897
-        $this->_delete_event(false);
1898
-    }
1899
-
1900
-
1901
-
1902
-    /**
1903
-     * _trash_or_restore_event
1904
-     *
1905
-     * @access protected
1906
-     * @param  string $event_status
1907
-     * @param bool    $redirect_after
1908
-     */
1909
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
1910
-    {
1911
-        //determine the event id and set to array.
1912
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
1913
-        // loop thru events
1914
-        if ($EVT_ID) {
1915
-            // clean status
1916
-            $event_status = sanitize_key($event_status);
1917
-            // grab status
1918
-            if ( ! empty($event_status)) {
1919
-                $success = $this->_change_event_status($EVT_ID, $event_status);
1920
-            } else {
1921
-                $success = false;
1922
-                $msg = esc_html__(
1923
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1924
-                    'event_espresso'
1925
-                );
1926
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1927
-            }
1928
-        } else {
1929
-            $success = false;
1930
-            $msg = esc_html__(
1931
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
1932
-                'event_espresso'
1933
-            );
1934
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1935
-        }
1936
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1937
-        if ($redirect_after) {
1938
-            $this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
1939
-        }
1940
-    }
1941
-
1942
-
1943
-
1944
-    /**
1945
-     * _trash_or_restore_events
1946
-     *
1947
-     * @access protected
1948
-     * @param  string $event_status
1949
-     * @return void
1950
-     */
1951
-    protected function _trash_or_restore_events($event_status = 'trash')
1952
-    {
1953
-        // clean status
1954
-        $event_status = sanitize_key($event_status);
1955
-        // grab status
1956
-        if ( ! empty($event_status)) {
1957
-            $success = true;
1958
-            //determine the event id and set to array.
1959
-            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
1960
-            // loop thru events
1961
-            foreach ($EVT_IDs as $EVT_ID) {
1962
-                if ($EVT_ID = absint($EVT_ID)) {
1963
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
1964
-                    $success = $results !== false ? $success : false;
1965
-                } else {
1966
-                    $msg = sprintf(
1967
-                        esc_html__(
1968
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
1969
-                            'event_espresso'
1970
-                        ),
1971
-                        $EVT_ID
1972
-                    );
1973
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1974
-                    $success = false;
1975
-                }
1976
-            }
1977
-        } else {
1978
-            $success = false;
1979
-            $msg = esc_html__(
1980
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1981
-                'event_espresso'
1982
-            );
1983
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1984
-        }
1985
-        // in order to force a pluralized result message we need to send back a success status greater than 1
1986
-        $success = $success ? 2 : false;
1987
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1988
-        $this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
1989
-    }
1990
-
1991
-
1992
-
1993
-    /**
1994
-     * _trash_or_restore_events
1995
-     *
1996
-     * @access  private
1997
-     * @param  int    $EVT_ID
1998
-     * @param  string $event_status
1999
-     * @return bool
2000
-     */
2001
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2002
-    {
2003
-        // grab event id
2004
-        if ( ! $EVT_ID) {
2005
-            $msg = esc_html__(
2006
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2007
-                'event_espresso'
2008
-            );
2009
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2010
-            return false;
2011
-        }
2012
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2013
-        // clean status
2014
-        $event_status = sanitize_key($event_status);
2015
-        // grab status
2016
-        if (empty($event_status)) {
2017
-            $msg = esc_html__(
2018
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2019
-                'event_espresso'
2020
-            );
2021
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2022
-            return false;
2023
-        }
2024
-        // was event trashed or restored ?
2025
-        switch ($event_status) {
2026
-            case 'draft' :
2027
-                $action = 'restored from the trash';
2028
-                $hook = 'AHEE_event_restored_from_trash';
2029
-                break;
2030
-            case 'trash' :
2031
-                $action = 'moved to the trash';
2032
-                $hook = 'AHEE_event_moved_to_trash';
2033
-                break;
2034
-            default :
2035
-                $action = 'updated';
2036
-                $hook = false;
2037
-        }
2038
-        //use class to change status
2039
-        $this->_cpt_model_obj->set_status($event_status);
2040
-        $success = $this->_cpt_model_obj->save();
2041
-        if ($success === false) {
2042
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2043
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2044
-            return false;
2045
-        }
2046
-        if ($hook) {
2047
-            do_action($hook);
2048
-        }
2049
-        return true;
2050
-    }
2051
-
2052
-
2053
-
2054
-    /**
2055
-     * _delete_event
2056
-     *
2057
-     * @access protected
2058
-     * @param bool $redirect_after
2059
-     */
2060
-    protected function _delete_event($redirect_after = true)
2061
-    {
2062
-        //determine the event id and set to array.
2063
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2064
-        $EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2065
-        // loop thru events
2066
-        if ($EVT_ID) {
2067
-            $success = $this->_permanently_delete_event($EVT_ID);
2068
-            // get list of events with no prices
2069
-            $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2070
-            // remove this event from the list of events with no prices
2071
-            if (isset($espresso_no_ticket_prices[$EVT_ID])) {
2072
-                unset($espresso_no_ticket_prices[$EVT_ID]);
2073
-            }
2074
-            update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2075
-        } else {
2076
-            $success = false;
2077
-            $msg = esc_html__(
2078
-                'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2079
-                'event_espresso'
2080
-            );
2081
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2082
-        }
2083
-        if ($redirect_after) {
2084
-            $this->_redirect_after_action(
2085
-                $success,
2086
-                'Event',
2087
-                'deleted',
2088
-                array('action' => 'default', 'status' => 'trash')
2089
-            );
2090
-        }
2091
-    }
2092
-
2093
-
2094
-
2095
-    /**
2096
-     * _delete_events
2097
-     *
2098
-     * @access protected
2099
-     * @return void
2100
-     */
2101
-    protected function _delete_events()
2102
-    {
2103
-        $success = true;
2104
-        // get list of events with no prices
2105
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2106
-        //determine the event id and set to array.
2107
-        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
2108
-        // loop thru events
2109
-        foreach ($EVT_IDs as $EVT_ID) {
2110
-            $EVT_ID = absint($EVT_ID);
2111
-            if ($EVT_ID) {
2112
-                $results = $this->_permanently_delete_event($EVT_ID);
2113
-                $success = $results !== false ? $success : false;
2114
-                // remove this event from the list of events with no prices
2115
-                unset($espresso_no_ticket_prices[$EVT_ID]);
2116
-            } else {
2117
-                $success = false;
2118
-                $msg = esc_html__(
2119
-                    'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2120
-                    'event_espresso'
2121
-                );
2122
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2123
-            }
2124
-        }
2125
-        update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2126
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2127
-        $success = $success ? 2 : false;
2128
-        $this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2129
-    }
2130
-
2131
-
2132
-
2133
-    /**
2134
-     * _permanently_delete_event
2135
-     *
2136
-     * @access  private
2137
-     * @param  int $EVT_ID
2138
-     * @return bool
2139
-     */
2140
-    private function _permanently_delete_event($EVT_ID = 0)
2141
-    {
2142
-        // grab event id
2143
-        if ( ! $EVT_ID) {
2144
-            $msg = esc_html__(
2145
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2146
-                'event_espresso'
2147
-            );
2148
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2149
-            return false;
2150
-        }
2151
-        if (
2152
-            ! $this->_cpt_model_obj instanceof EE_Event
2153
-            || $this->_cpt_model_obj->ID() !== $EVT_ID
2154
-        ) {
2155
-            $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2156
-        }
2157
-        if ( ! $this->_cpt_model_obj instanceof EE_Event) {
2158
-            return false;
2159
-        }
2160
-        //need to delete related tickets and prices first.
2161
-        $datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2162
-        foreach ($datetimes as $datetime) {
2163
-            $this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2164
-            $tickets = $datetime->get_many_related('Ticket');
2165
-            foreach ($tickets as $ticket) {
2166
-                $ticket->_remove_relation_to($datetime, 'Datetime');
2167
-                $ticket->delete_related_permanently('Price');
2168
-                $ticket->delete_permanently();
2169
-            }
2170
-            $datetime->delete();
2171
-        }
2172
-        //what about related venues or terms?
2173
-        $venues = $this->_cpt_model_obj->get_many_related('Venue');
2174
-        foreach ($venues as $venue) {
2175
-            $this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2176
-        }
2177
-        //any attached question groups?
2178
-        $question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2179
-        if ( ! empty($question_groups)) {
2180
-            foreach ($question_groups as $question_group) {
2181
-                $this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2182
-            }
2183
-        }
2184
-        //Message Template Groups
2185
-        $this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2186
-        /** @type EE_Term_Taxonomy[] $term_taxonomies */
2187
-        $term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2188
-        foreach ($term_taxonomies as $term_taxonomy) {
2189
-            $this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2190
-        }
2191
-        $success = $this->_cpt_model_obj->delete_permanently();
2192
-        // did it all go as planned ?
2193
-        if ($success) {
2194
-            $msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2195
-            EE_Error::add_success($msg);
2196
-        } else {
2197
-            $msg = sprintf(
2198
-                esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2199
-                $EVT_ID
2200
-            );
2201
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2202
-            return false;
2203
-        }
2204
-        do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2205
-        return true;
2206
-    }
2207
-
2208
-
2209
-
2210
-    /**
2211
-     * get total number of events
2212
-     *
2213
-     * @access public
2214
-     * @return int
2215
-     */
2216
-    public function total_events()
2217
-    {
2218
-        $count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2219
-        return $count;
2220
-    }
2221
-
2222
-
2223
-
2224
-    /**
2225
-     * get total number of draft events
2226
-     *
2227
-     * @access public
2228
-     * @return int
2229
-     */
2230
-    public function total_events_draft()
2231
-    {
2232
-        $where = array(
2233
-            'status' => array('IN', array('draft', 'auto-draft')),
2234
-        );
2235
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2236
-        return $count;
2237
-    }
2238
-
2239
-
2240
-
2241
-    /**
2242
-     * get total number of trashed events
2243
-     *
2244
-     * @access public
2245
-     * @return int
2246
-     */
2247
-    public function total_trashed_events()
2248
-    {
2249
-        $where = array(
2250
-            'status' => 'trash',
2251
-        );
2252
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2253
-        return $count;
2254
-    }
2255
-
2256
-
2257
-    /**
2258
-     *    _default_event_settings
2259
-     *    This generates the Default Settings Tab
2260
-     *
2261
-     * @return void
2262
-     * @throws \EE_Error
2263
-     */
2264
-    protected function _default_event_settings()
2265
-    {
2266
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2267
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2268
-        $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2269
-        $this->display_admin_page_with_sidebar();
2270
-    }
2271
-
2272
-
2273
-    /**
2274
-     * Return the form for event settings.
2275
-     * @return \EE_Form_Section_Proper
2276
-     */
2277
-    protected function _default_event_settings_form()
2278
-    {
2279
-        $registration_config = EE_Registry::instance()->CFG->registration;
2280
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2281
-        //exclude
2282
-            array(
2283
-                EEM_Registration::status_id_cancelled,
2284
-                EEM_Registration::status_id_declined,
2285
-                EEM_Registration::status_id_incomplete,
2286
-                EEM_Registration::status_id_wait_list,
2287
-            ),
2288
-            true
2289
-        );
2290
-        return new EE_Form_Section_Proper(
2291
-            array(
2292
-                'name' => 'update_default_event_settings',
2293
-                'html_id' => 'update_default_event_settings',
2294
-                'html_class' => 'form-table',
2295
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2296
-                'subsections' => apply_filters(
2297
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2298
-                    array(
2299
-                        'default_reg_status' => new EE_Select_Input(
2300
-                            $registration_stati_for_selection,
2301
-                            array(
2302
-                                'default' => isset($registration_config->default_STS_ID)
2303
-                                             && array_key_exists(
2304
-                                                $registration_config->default_STS_ID,
2305
-                                                $registration_stati_for_selection
2306
-                                             )
2307
-                                            ? sanitize_text_field($registration_config->default_STS_ID)
2308
-                                            : EEM_Registration::status_id_pending_payment,
2309
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2310
-                                                    . EEH_Template::get_help_tab_link(
2311
-                                                        'default_settings_status_help_tab'
2312
-                                                    ),
2313
-                                'html_help_text' => esc_html__(
2314
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2315
-                                    'event_espresso'
2316
-                                )
2317
-                            )
2318
-                        ),
2319
-                        'default_max_tickets' => new EE_Integer_Input(
2320
-                            array(
2321
-                                'default' => isset($registration_config->default_maximum_number_of_tickets)
2322
-                                    ? $registration_config->default_maximum_number_of_tickets
2323
-                                    : EEM_Event::get_default_additional_limit(),
2324
-                                'html_label_text' => esc_html__(
2325
-                                    'Default Maximum Tickets Allowed Per Order:',
2326
-                                    'event_espresso'
2327
-                                ) . EEH_Template::get_help_tab_link(
2328
-                                    'default_maximum_tickets_help_tab"'
2329
-                                    ),
2330
-                                'html_help_text' => esc_html__(
2331
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2332
-                                    'event_espresso'
2333
-                                )
2334
-                            )
2335
-                        )
2336
-                    )
2337
-                )
2338
-            )
2339
-        );
2340
-    }
2341
-
2342
-
2343
-    /**
2344
-     * _update_default_event_settings
2345
-     *
2346
-     * @access protected
2347
-     * @return void
2348
-     * @throws \EE_Error
2349
-     */
2350
-    protected function _update_default_event_settings()
2351
-    {
2352
-        $registration_config = EE_Registry::instance()->CFG->registration;
2353
-        $form = $this->_default_event_settings_form();
2354
-        if ($form->was_submitted()) {
2355
-            $form->receive_form_submission();
2356
-            if ($form->is_valid()) {
2357
-                $valid_data = $form->valid_data();
2358
-                if (isset($valid_data['default_reg_status'])) {
2359
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2360
-                }
2361
-                if (isset($valid_data['default_max_tickets'])) {
2362
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2363
-                }
2364
-                //update because data was valid!
2365
-                EE_Registry::instance()->CFG->update_espresso_config();
2366
-                EE_Error::overwrite_success();
2367
-                EE_Error::add_success(
2368
-                    __('Default Event Settings were updated', 'event_espresso')
2369
-                );
2370
-            }
2371
-        }
2372
-        $this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true);
2373
-    }
2374
-
2375
-
2376
-
2377
-    /*************        Templates        *************/
2378
-    protected function _template_settings()
2379
-    {
2380
-        $this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2381
-        $this->_template_args['preview_img'] = '<img src="'
2382
-                                               . EVENTS_ASSETS_URL
2383
-                                               . DS
2384
-                                               . 'images'
2385
-                                               . DS
2386
-                                               . 'caffeinated_template_features.jpg" alt="'
2387
-                                               . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2388
-                                               . '" />';
2389
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__(
2390
-                'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2391
-                'event_espresso'
2392
-            ) . '</strong>';
2393
-        $this->display_admin_caf_preview_page('template_settings_tab');
2394
-    }
2395
-
2396
-
2397
-    /** Event Category Stuff **/
2398
-    /**
2399
-     * set the _category property with the category object for the loaded page.
2400
-     *
2401
-     * @access private
2402
-     * @return void
2403
-     */
2404
-    private function _set_category_object()
2405
-    {
2406
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2407
-            return;
2408
-        } //already have the category object so get out.
2409
-        //set default category object
2410
-        $this->_set_empty_category_object();
2411
-        //only set if we've got an id
2412
-        if ( ! isset($this->_req_data['EVT_CAT_ID'])) {
2413
-            return;
2414
-        }
2415
-        $category_id = absint($this->_req_data['EVT_CAT_ID']);
2416
-        $term = get_term($category_id, 'espresso_event_categories');
2417
-        if ( ! empty($term)) {
2418
-            $this->_category->category_name = $term->name;
2419
-            $this->_category->category_identifier = $term->slug;
2420
-            $this->_category->category_desc = $term->description;
2421
-            $this->_category->id = $term->term_id;
2422
-            $this->_category->parent = $term->parent;
2423
-        }
2424
-    }
2425
-
2426
-
2427
-
2428
-    private function _set_empty_category_object()
2429
-    {
2430
-        $this->_category = new stdClass();
2431
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2432
-        $this->_category->id = $this->_category->parent = 0;
2433
-    }
2434
-
2435
-
2436
-
2437
-    protected function _category_list_table()
2438
-    {
2439
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2440
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2441
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2442
-                'add_category',
2443
-                'add_category',
2444
-                array(),
2445
-                'add-new-h2'
2446
-            );
2447
-        $this->display_admin_list_table_page_with_sidebar();
2448
-    }
2449
-
2450
-
2451
-
2452
-    /**
2453
-     * @param $view
2454
-     */
2455
-    protected function _category_details($view)
2456
-    {
2457
-        //load formatter helper
2458
-        //load field generator helper
2459
-        $route = $view == 'edit' ? 'update_category' : 'insert_category';
2460
-        $this->_set_add_edit_form_tags($route);
2461
-        $this->_set_category_object();
2462
-        $id = ! empty($this->_category->id) ? $this->_category->id : '';
2463
-        $delete_action = 'delete_category';
2464
-        //custom redirect
2465
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2466
-            array('action' => 'category_list'),
2467
-            $this->_admin_base_url
2468
-        );
2469
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2470
-        //take care of contents
2471
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2472
-        $this->display_admin_page_with_sidebar();
2473
-    }
2474
-
2475
-
2476
-
2477
-    /**
2478
-     * @return mixed
2479
-     */
2480
-    protected function _category_details_content()
2481
-    {
2482
-        $editor_args['category_desc'] = array(
2483
-            'type'          => 'wp_editor',
2484
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2485
-            'class'         => 'my_editor_custom',
2486
-            'wpeditor_args' => array('media_buttons' => false),
2487
-        );
2488
-        $_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2489
-        $all_terms = get_terms(
2490
-            array('espresso_event_categories'),
2491
-            array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2492
-        );
2493
-        //setup category select for term parents.
2494
-        $category_select_values[] = array(
2495
-            'text' => esc_html__('No Parent', 'event_espresso'),
2496
-            'id'   => 0,
2497
-        );
2498
-        foreach ($all_terms as $term) {
2499
-            $category_select_values[] = array(
2500
-                'text' => $term->name,
2501
-                'id'   => $term->term_id,
2502
-            );
2503
-        }
2504
-        $category_select = EEH_Form_Fields::select_input(
2505
-            'category_parent',
2506
-            $category_select_values,
2507
-            $this->_category->parent
2508
-        );
2509
-        $template_args = array(
2510
-            'category'                 => $this->_category,
2511
-            'category_select'          => $category_select,
2512
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2513
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2514
-            'disable'                  => '',
2515
-            'disabled_message'         => false,
2516
-        );
2517
-        $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2518
-        return EEH_Template::display_template($template, $template_args, true);
2519
-    }
2520
-
2521
-
2522
-
2523
-    protected function _delete_categories()
2524
-    {
2525
-        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array)$this->_req_data['EVT_CAT_ID']
2526
-            : (array)$this->_req_data['category_id'];
2527
-        foreach ($cat_ids as $cat_id) {
2528
-            $this->_delete_category($cat_id);
2529
-        }
2530
-        //doesn't matter what page we're coming from... we're going to the same place after delete.
2531
-        $query_args = array(
2532
-            'action' => 'category_list',
2533
-        );
2534
-        $this->_redirect_after_action(0, '', '', $query_args);
2535
-    }
2536
-
2537
-
2538
-
2539
-    /**
2540
-     * @param $cat_id
2541
-     */
2542
-    protected function _delete_category($cat_id)
2543
-    {
2544
-        $cat_id = absint($cat_id);
2545
-        wp_delete_term($cat_id, 'espresso_event_categories');
2546
-    }
2547
-
2548
-
2549
-
2550
-    /**
2551
-     * @param $new_category
2552
-     */
2553
-    protected function _insert_or_update_category($new_category)
2554
-    {
2555
-        $cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2556
-        $success = 0; //we already have a success message so lets not send another.
2557
-        if ($cat_id) {
2558
-            $query_args = array(
2559
-                'action'     => 'edit_category',
2560
-                'EVT_CAT_ID' => $cat_id,
2561
-            );
2562
-        } else {
2563
-            $query_args = array('action' => 'add_category');
2564
-        }
2565
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2566
-    }
2567
-
2568
-
2569
-
2570
-    /**
2571
-     * @param bool $update
2572
-     * @return bool|mixed|string
2573
-     */
2574
-    private function _insert_category($update = false)
2575
-    {
2576
-        $cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2577
-        $category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2578
-        $category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2579
-        $category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2580
-        if (empty($category_name)) {
2581
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2582
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2583
-            return false;
2584
-        }
2585
-        $term_args = array(
2586
-            'name'        => $category_name,
2587
-            'description' => $category_desc,
2588
-            'parent'      => $category_parent,
2589
-        );
2590
-        //was the category_identifier input disabled?
2591
-        if (isset($this->_req_data['category_identifier'])) {
2592
-            $term_args['slug'] = $this->_req_data['category_identifier'];
2593
-        }
2594
-        $insert_ids = $update
2595
-            ? wp_update_term($cat_id, 'espresso_event_categories', $term_args)
2596
-            : wp_insert_term($category_name, 'espresso_event_categories', $term_args);
2597
-        if ( ! is_array($insert_ids)) {
2598
-            $msg = esc_html__(
2599
-                'An error occurred and the category has not been saved to the database.',
2600
-                'event_espresso'
2601
-            );
2602
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2603
-        } else {
2604
-            $cat_id = $insert_ids['term_id'];
2605
-            $msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2606
-            EE_Error::add_success($msg);
2607
-        }
2608
-        return $cat_id;
2609
-    }
2610
-
2611
-
2612
-
2613
-    /**
2614
-     * @param int  $per_page
2615
-     * @param int  $current_page
2616
-     * @param bool $count
2617
-     * @return \EE_Base_Class[]|int
2618
-     */
2619
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2620
-    {
2621
-        //testing term stuff
2622
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2623
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2624
-        $limit = ($current_page - 1) * $per_page;
2625
-        $where = array('taxonomy' => 'espresso_event_categories');
2626
-        if (isset($this->_req_data['s'])) {
2627
-            $sstr = '%' . $this->_req_data['s'] . '%';
2628
-            $where['OR'] = array(
2629
-                'Term.name'   => array('LIKE', $sstr),
2630
-                'description' => array('LIKE', $sstr),
2631
-            );
2632
-        }
2633
-        $query_params = array(
2634
-            $where,
2635
-            'order_by'   => array($orderby => $order),
2636
-            'limit'      => $limit . ',' . $per_page,
2637
-            'force_join' => array('Term'),
2638
-        );
2639
-        $categories = $count
2640
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2641
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2642
-        return $categories;
2643
-    }
2644
-
2645
-
2646
-
2647
-    /* end category stuff */
2648
-    /**************/
385
+				'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
386
+				'require_nonce' => false,
387
+			),
388
+			'default_event_settings' => array(
389
+				'nav'           => array(
390
+					'label' => esc_html__('Default Settings', 'event_espresso'),
391
+					'order' => 40,
392
+				),
393
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
394
+				'labels'        => array(
395
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
396
+				),
397
+				'help_tabs'     => array(
398
+					'default_settings_help_tab'        => array(
399
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
400
+						'filename' => 'events_default_settings',
401
+					),
402
+					'default_settings_status_help_tab' => array(
403
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
404
+						'filename' => 'events_default_settings_status',
405
+					),
406
+					'default_maximum_tickets_help_tab' => array(
407
+						'title' => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
408
+						'filename' => 'events_default_settings_max_tickets',
409
+					)
410
+				),
411
+				'help_tour'     => array('Event_Default_Settings_Help_Tour'),
412
+				'require_nonce' => false,
413
+			),
414
+			//template settings
415
+			'template_settings'      => array(
416
+				'nav'           => array(
417
+					'label' => esc_html__('Templates', 'event_espresso'),
418
+					'order' => 30,
419
+				),
420
+				'metaboxes'     => $this->_default_espresso_metaboxes,
421
+				'help_tabs'     => array(
422
+					'general_settings_templates_help_tab' => array(
423
+						'title'    => esc_html__('Templates', 'event_espresso'),
424
+						'filename' => 'general_settings_templates',
425
+					),
426
+				),
427
+				'help_tour'     => array('Templates_Help_Tour'),
428
+				'require_nonce' => false,
429
+			),
430
+			//event category stuff
431
+			'add_category'           => array(
432
+				'nav'           => array(
433
+					'label'      => esc_html__('Add Category', 'event_espresso'),
434
+					'order'      => 15,
435
+					'persistent' => false,
436
+				),
437
+				'help_tabs'     => array(
438
+					'add_category_help_tab' => array(
439
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
440
+						'filename' => 'events_add_category',
441
+					),
442
+				),
443
+				'help_tour'     => array('Event_Add_Category_Help_Tour'),
444
+				'metaboxes'     => array('_publish_post_box'),
445
+				'require_nonce' => false,
446
+			),
447
+			'edit_category'          => array(
448
+				'nav'           => array(
449
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
450
+					'order'      => 15,
451
+					'persistent' => false,
452
+					'url'        => isset($this->_req_data['EVT_CAT_ID'])
453
+						? add_query_arg(
454
+							array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']),
455
+							$this->_current_page_view_url
456
+						)
457
+						: $this->_admin_base_url,
458
+				),
459
+				'help_tabs'     => array(
460
+					'edit_category_help_tab' => array(
461
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
462
+						'filename' => 'events_edit_category',
463
+					),
464
+				),
465
+				/*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
466
+				'metaboxes'     => array('_publish_post_box'),
467
+				'require_nonce' => false,
468
+			),
469
+			'category_list'          => array(
470
+				'nav'           => array(
471
+					'label' => esc_html__('Categories', 'event_espresso'),
472
+					'order' => 20,
473
+				),
474
+				'list_table'    => 'Event_Categories_Admin_List_Table',
475
+				'help_tabs'     => array(
476
+					'events_categories_help_tab'                       => array(
477
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
478
+						'filename' => 'events_categories',
479
+					),
480
+					'events_categories_table_column_headings_help_tab' => array(
481
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
482
+						'filename' => 'events_categories_table_column_headings',
483
+					),
484
+					'events_categories_view_help_tab'                  => array(
485
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
486
+						'filename' => 'events_categories_views',
487
+					),
488
+					'events_categories_other_help_tab'                 => array(
489
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
490
+						'filename' => 'events_categories_other',
491
+					),
492
+				),
493
+				'help_tour'     => array(
494
+					'Event_Categories_Help_Tour',
495
+				),
496
+				'metaboxes'     => $this->_default_espresso_metaboxes,
497
+				'require_nonce' => false,
498
+			),
499
+		);
500
+	}
501
+
502
+
503
+
504
+	protected function _add_screen_options()
505
+	{
506
+		//todo
507
+	}
508
+
509
+
510
+
511
+	protected function _add_screen_options_default()
512
+	{
513
+		$this->_per_page_screen_option();
514
+	}
515
+
516
+
517
+
518
+	protected function _add_screen_options_category_list()
519
+	{
520
+		$page_title = $this->_admin_page_title;
521
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
522
+		$this->_per_page_screen_option();
523
+		$this->_admin_page_title = $page_title;
524
+	}
525
+
526
+
527
+
528
+	protected function _add_feature_pointers()
529
+	{
530
+		//todo
531
+	}
532
+
533
+
534
+
535
+	public function load_scripts_styles()
536
+	{
537
+		wp_register_style(
538
+			'events-admin-css',
539
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
540
+			array(),
541
+			EVENT_ESPRESSO_VERSION
542
+		);
543
+		wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
544
+		wp_enqueue_style('events-admin-css');
545
+		wp_enqueue_style('ee-cat-admin');
546
+		//todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
547
+		//registers for all views
548
+		//scripts
549
+		wp_register_script(
550
+			'event_editor_js',
551
+			EVENTS_ASSETS_URL . 'event_editor.js',
552
+			array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
553
+			EVENT_ESPRESSO_VERSION,
554
+			true
555
+		);
556
+	}
557
+
558
+
559
+
560
+	/**
561
+	 * enqueuing scripts and styles specific to this view
562
+	 *
563
+	 * @return void
564
+	 */
565
+	public function load_scripts_styles_create_new()
566
+	{
567
+		$this->load_scripts_styles_edit();
568
+	}
569
+
570
+
571
+
572
+	/**
573
+	 * enqueuing scripts and styles specific to this view
574
+	 *
575
+	 * @return void
576
+	 */
577
+	public function load_scripts_styles_edit()
578
+	{
579
+		//styles
580
+		wp_enqueue_style('espresso-ui-theme');
581
+		wp_register_style(
582
+			'event-editor-css',
583
+			EVENTS_ASSETS_URL . 'event-editor.css',
584
+			array('ee-admin-css'),
585
+			EVENT_ESPRESSO_VERSION
586
+		);
587
+		wp_enqueue_style('event-editor-css');
588
+		//scripts
589
+		wp_register_script(
590
+			'event-datetime-metabox',
591
+			EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
592
+			array('event_editor_js', 'ee-datepicker'),
593
+			EVENT_ESPRESSO_VERSION
594
+		);
595
+		wp_enqueue_script('event-datetime-metabox');
596
+	}
597
+
598
+
599
+
600
+	public function load_scripts_styles_add_category()
601
+	{
602
+		$this->load_scripts_styles_edit_category();
603
+	}
604
+
605
+
606
+
607
+	public function load_scripts_styles_edit_category()
608
+	{
609
+	}
610
+
611
+
612
+
613
+	protected function _set_list_table_views_category_list()
614
+	{
615
+		$this->_views = array(
616
+			'all' => array(
617
+				'slug'        => 'all',
618
+				'label'       => esc_html__('All', 'event_espresso'),
619
+				'count'       => 0,
620
+				'bulk_action' => array(
621
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
622
+				),
623
+			),
624
+		);
625
+	}
626
+
627
+
628
+
629
+	public function admin_init()
630
+	{
631
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
632
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
633
+			'event_espresso'
634
+		);
635
+	}
636
+
637
+
638
+
639
+	//nothing needed for events with these methods.
640
+	public function admin_notices()
641
+	{
642
+	}
643
+
644
+
645
+
646
+	public function admin_footer_scripts()
647
+	{
648
+	}
649
+
650
+
651
+
652
+	/**
653
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
654
+	 * warning (via EE_Error::add_error());
655
+	 *
656
+	 * @param  EE_Event $event Event object
657
+	 * @access public
658
+	 * @return void
659
+	 */
660
+	public function verify_event_edit($event = null)
661
+	{
662
+		// no event?
663
+		if (empty($event)) {
664
+			// set event
665
+			$event = $this->_cpt_model_obj;
666
+		}
667
+		// STILL no event?
668
+		if (! $event instanceof EE_Event) {
669
+			return;
670
+		}
671
+		$orig_status = $event->status();
672
+		// first check if event is active.
673
+		if (
674
+			$orig_status === EEM_Event::cancelled
675
+			|| $orig_status === EEM_Event::postponed
676
+			|| $event->is_expired()
677
+			|| $event->is_inactive()
678
+		) {
679
+			return;
680
+		}
681
+		//made it here so it IS active... next check that any of the tickets are sold.
682
+		if ($event->is_sold_out(true)) {
683
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
684
+				EE_Error::add_attention(
685
+					sprintf(
686
+						esc_html__(
687
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
688
+							'event_espresso'
689
+						),
690
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
691
+					)
692
+				);
693
+			}
694
+			return;
695
+		} else if ($orig_status === EEM_Event::sold_out) {
696
+			EE_Error::add_attention(
697
+				sprintf(
698
+					esc_html__(
699
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
700
+						'event_espresso'
701
+					),
702
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
703
+				)
704
+			);
705
+		}
706
+		//now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
707
+		if ( ! $event->tickets_on_sale()) {
708
+			return;
709
+		}
710
+		//made it here so show warning
711
+		$this->_edit_event_warning();
712
+	}
713
+
714
+
715
+
716
+	/**
717
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
718
+	 * When needed, hook this into a EE_Error::add_error() notice.
719
+	 *
720
+	 * @access protected
721
+	 * @return void
722
+	 */
723
+	protected function _edit_event_warning()
724
+	{
725
+		// we don't want to add warnings during these requests
726
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
727
+			return;
728
+		}
729
+		EE_Error::add_attention(
730
+			esc_html__(
731
+				'Please be advised that this event has been published and is open for registrations on your website. If you update any registration-related details (i.e. custom questions, messages, tickets, datetimes, etc.) while a registration is in process, the registration process could be interrupted and result in errors for the person registering and potentially incorrect registration or transaction data inside Event Espresso. We recommend editing events during a period of slow traffic, or even temporarily changing the status of an event to "Draft" until your edits are complete.',
732
+				'event_espresso'
733
+			)
734
+		);
735
+	}
736
+
737
+
738
+
739
+	/**
740
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
741
+	 * Otherwise, do the normal logic
742
+	 *
743
+	 * @return string
744
+	 * @throws \EE_Error
745
+	 */
746
+	protected function _create_new_cpt_item()
747
+	{
748
+		$gmt_offset = get_option('gmt_offset');
749
+		//only nag them about setting their timezone if it's their first event, and they haven't already done it
750
+		if ($gmt_offset === '0' && ! EEM_Event::instance()->exists(array())) {
751
+			EE_Error::add_attention(
752
+				sprintf(
753
+					__(
754
+						'Your website\'s timezone is currently set to UTC + 0. We recommend updating your timezone to a city or region near you before you create an event. Your timezone can be updated through the %1$sGeneral Settings%2$s page.',
755
+						'event_espresso'
756
+					),
757
+					'<a href="' . admin_url('options-general.php') . '">',
758
+					'</a>'
759
+				),
760
+				__FILE__,
761
+				__FUNCTION__,
762
+				__LINE__
763
+			);
764
+		}
765
+		return parent::_create_new_cpt_item();
766
+	}
767
+
768
+
769
+
770
+	protected function _set_list_table_views_default()
771
+	{
772
+		$this->_views = array(
773
+			'all'   => array(
774
+				'slug'        => 'all',
775
+				'label'       => esc_html__('View All Events', 'event_espresso'),
776
+				'count'       => 0,
777
+				'bulk_action' => array(
778
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
779
+				),
780
+			),
781
+			'draft' => array(
782
+				'slug'        => 'draft',
783
+				'label'       => esc_html__('Draft', 'event_espresso'),
784
+				'count'       => 0,
785
+				'bulk_action' => array(
786
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
787
+				),
788
+			),
789
+		);
790
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
791
+			$this->_views['trash'] = array(
792
+				'slug'        => 'trash',
793
+				'label'       => esc_html__('Trash', 'event_espresso'),
794
+				'count'       => 0,
795
+				'bulk_action' => array(
796
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
797
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
798
+				),
799
+			);
800
+		}
801
+	}
802
+
803
+
804
+
805
+	/**
806
+	 * @return array
807
+	 */
808
+	protected function _event_legend_items()
809
+	{
810
+		$items = array(
811
+			'view_details'   => array(
812
+				'class' => 'dashicons dashicons-search',
813
+				'desc'  => esc_html__('View Event', 'event_espresso'),
814
+			),
815
+			'edit_event'     => array(
816
+				'class' => 'ee-icon ee-icon-calendar-edit',
817
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
818
+			),
819
+			'view_attendees' => array(
820
+				'class' => 'dashicons dashicons-groups',
821
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
822
+			),
823
+		);
824
+		$items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
825
+		$statuses = array(
826
+			'sold_out_status'  => array(
827
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
828
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
829
+			),
830
+			'active_status'    => array(
831
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
832
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
833
+			),
834
+			'upcoming_status'  => array(
835
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
836
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
837
+			),
838
+			'postponed_status' => array(
839
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
840
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
841
+			),
842
+			'cancelled_status' => array(
843
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
844
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
845
+			),
846
+			'expired_status'   => array(
847
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
848
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
849
+			),
850
+			'inactive_status'  => array(
851
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
852
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
853
+			),
854
+		);
855
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
856
+		return array_merge($items, $statuses);
857
+	}
858
+
859
+
860
+
861
+	/**
862
+	 * _event_model
863
+	 *
864
+	 * @return EEM_Event
865
+	 */
866
+	private function _event_model()
867
+	{
868
+		if ( ! $this->_event_model instanceof EEM_Event) {
869
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
870
+		}
871
+		return $this->_event_model;
872
+	}
873
+
874
+
875
+
876
+	/**
877
+	 * Adds extra buttons to the WP CPT permalink field row.
878
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
879
+	 *
880
+	 * @param  string $return    the current html
881
+	 * @param  int    $id        the post id for the page
882
+	 * @param  string $new_title What the title is
883
+	 * @param  string $new_slug  what the slug is
884
+	 * @return string            The new html string for the permalink area
885
+	 */
886
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
887
+	{
888
+		//make sure this is only when editing
889
+		if ( ! empty($id)) {
890
+			$post = get_post($id);
891
+			$return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
892
+					   . esc_html__('Shortcode', 'event_espresso')
893
+					   . '</a> ';
894
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
895
+					   . $post->ID
896
+					   . ']">';
897
+		}
898
+		return $return;
899
+	}
900
+
901
+
902
+
903
+	/**
904
+	 * _events_overview_list_table
905
+	 * This contains the logic for showing the events_overview list
906
+	 *
907
+	 * @access protected
908
+	 * @return void
909
+	 * @throws \EE_Error
910
+	 */
911
+	protected function _events_overview_list_table()
912
+	{
913
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
914
+		$this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
915
+			? (array)$this->_template_args['after_list_table']
916
+			: array();
917
+		$this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
918
+																			  . EEH_Template::get_button_or_link(
919
+				get_post_type_archive_link('espresso_events'),
920
+				esc_html__("View Event Archive Page", "event_espresso"),
921
+				'button'
922
+			);
923
+		$this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
924
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
925
+				'create_new',
926
+				'add',
927
+				array(),
928
+				'add-new-h2'
929
+			);
930
+		$this->display_admin_list_table_page_with_no_sidebar();
931
+	}
932
+
933
+
934
+
935
+	/**
936
+	 * this allows for extra misc actions in the default WP publish box
937
+	 *
938
+	 * @return void
939
+	 */
940
+	public function extra_misc_actions_publish_box()
941
+	{
942
+		$this->_generate_publish_box_extra_content();
943
+	}
944
+
945
+
946
+
947
+	/**
948
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
949
+	 * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
950
+	 * data.
951
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
952
+	 * ALSO very important.  When a post transitions from scheduled to published, the save_post action is fired but you
953
+	 * will NOT have any _POST data containing any extra info you may have from other meta saves.  So MAKE sure that
954
+	 * you handle this accordingly.
955
+	 *
956
+	 * @access protected
957
+	 * @abstract
958
+	 * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
959
+	 * @param  object $post    The post object of the cpt that was saved.
960
+	 * @return void
961
+	 */
962
+	protected function _insert_update_cpt_item($post_id, $post)
963
+	{
964
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
965
+			//get out we're not processing an event save.
966
+			return;
967
+		}
968
+		$event_values = array(
969
+			'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
970
+			'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
971
+			'EVT_additional_limit'            => min(
972
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
973
+				! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
974
+			),
975
+			'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
976
+				? $this->_req_data['EVT_default_registration_status']
977
+				: EE_Registry::instance()->CFG->registration->default_STS_ID,
978
+			'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
979
+			'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
980
+			'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
981
+				? $this->_req_data['timezone_string'] : null,
982
+			'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
983
+				? $this->_req_data['externalURL'] : null,
984
+			'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
985
+				? $this->_req_data['event_phone'] : null,
986
+		);
987
+		//update event
988
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
989
+		//get event_object for other metaboxes... though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id!
990
+		$get_one_where = array($this->_event_model()->primary_key_name() => $post_id, 'status' => $post->post_status);
991
+		$event = $this->_event_model()->get_one(array($get_one_where));
992
+		//the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
993
+		$event_update_callbacks = apply_filters(
994
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
995
+			array(array($this, '_default_venue_update'), array($this, '_default_tickets_update'))
996
+		);
997
+		$att_success = true;
998
+		foreach ($event_update_callbacks as $e_callback) {
999
+			$_succ = call_user_func_array($e_callback, array($event, $this->_req_data));
1000
+			$att_success = ! $att_success ? $att_success
1001
+				: $_succ; //if ANY of these updates fail then we want the appropriate global error message
1002
+		}
1003
+		//any errors?
1004
+		if ($success && false === $att_success) {
1005
+			EE_Error::add_error(
1006
+				esc_html__(
1007
+					'Event Details saved successfully but something went wrong with saving attachments.',
1008
+					'event_espresso'
1009
+				),
1010
+				__FILE__,
1011
+				__FUNCTION__,
1012
+				__LINE__
1013
+			);
1014
+		} else if ($success === false) {
1015
+			EE_Error::add_error(
1016
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1017
+				__FILE__,
1018
+				__FUNCTION__,
1019
+				__LINE__
1020
+			);
1021
+		}
1022
+	}
1023
+
1024
+
1025
+
1026
+	/**
1027
+	 * @see parent::restore_item()
1028
+	 * @param int $post_id
1029
+	 * @param int $revision_id
1030
+	 */
1031
+	protected function _restore_cpt_item($post_id, $revision_id)
1032
+	{
1033
+		//copy existing event meta to new post
1034
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1035
+		if ($post_evt instanceof EE_Event) {
1036
+			//meta revision restore
1037
+			$post_evt->restore_revision($revision_id);
1038
+			//related objs restore
1039
+			$post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1040
+		}
1041
+	}
1042
+
1043
+
1044
+
1045
+	/**
1046
+	 * Attach the venue to the Event
1047
+	 *
1048
+	 * @param  \EE_Event $evtobj Event Object to add the venue to
1049
+	 * @param  array     $data   The request data from the form
1050
+	 * @return bool           Success or fail.
1051
+	 */
1052
+	protected function _default_venue_update(\EE_Event $evtobj, $data)
1053
+	{
1054
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1055
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1056
+		$rows_affected = null;
1057
+		$venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1058
+		// very important.  If we don't have a venue name...
1059
+		// then we'll get out because not necessary to create empty venue
1060
+		if (empty($data['venue_title'])) {
1061
+			return false;
1062
+		}
1063
+		$venue_array = array(
1064
+			'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1065
+			'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1066
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1067
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1068
+			'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1069
+				: null,
1070
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1071
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1072
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1073
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1074
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1075
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1076
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1077
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1078
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1079
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1080
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1081
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1082
+			'status'              => 'publish',
1083
+		);
1084
+		//if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1085
+		if ( ! empty($venue_id)) {
1086
+			$update_where = array($venue_model->primary_key_name() => $venue_id);
1087
+			$rows_affected = $venue_model->update($venue_array, array($update_where));
1088
+			//we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1089
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1090
+			return $rows_affected > 0 ? true : false;
1091
+		} else {
1092
+			//we insert the venue
1093
+			$venue_id = $venue_model->insert($venue_array);
1094
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1095
+			return ! empty($venue_id) ? true : false;
1096
+		}
1097
+		//when we have the ancestor come in it's already been handled by the revision save.
1098
+	}
1099
+
1100
+
1101
+
1102
+	/**
1103
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1104
+	 *
1105
+	 * @param  EE_Event $evtobj The Event object we're attaching data to
1106
+	 * @param  array    $data   The request data from the form
1107
+	 * @return array
1108
+	 */
1109
+	protected function _default_tickets_update(EE_Event $evtobj, $data)
1110
+	{
1111
+		$success = true;
1112
+		$saved_dtt = null;
1113
+		$saved_tickets = array();
1114
+		$incoming_date_formats = array('Y-m-d', 'h:i a');
1115
+		foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1116
+			//trim all values to ensure any excess whitespace is removed.
1117
+			$dtt = array_map('trim', $dtt);
1118
+			$dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1119
+				: $dtt['DTT_EVT_start'];
1120
+			$datetime_values = array(
1121
+				'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1122
+				'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1123
+				'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1124
+				'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1125
+				'DTT_order'     => $row,
1126
+			);
1127
+			//if we have an id then let's get existing object first and then set the new values.  Otherwise we instantiate a new object for save.
1128
+			if ( ! empty($dtt['DTT_ID'])) {
1129
+				$DTM = EE_Registry::instance()
1130
+								  ->load_model('Datetime', array($evtobj->get_timezone()))
1131
+								  ->get_one_by_ID($dtt['DTT_ID']);
1132
+				$DTM->set_date_format($incoming_date_formats[0]);
1133
+				$DTM->set_time_format($incoming_date_formats[1]);
1134
+				foreach ($datetime_values as $field => $value) {
1135
+					$DTM->set($field, $value);
1136
+				}
1137
+				//make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it.  We need to do this so we dont' TRASH the parent DTT.
1138
+				$saved_dtts[$DTM->ID()] = $DTM;
1139
+			} else {
1140
+				$DTM = EE_Registry::instance()->load_class(
1141
+					'Datetime',
1142
+					array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1143
+					false,
1144
+					false
1145
+				);
1146
+				foreach ($datetime_values as $field => $value) {
1147
+					$DTM->set($field, $value);
1148
+				}
1149
+			}
1150
+			$DTM->save();
1151
+			$DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1152
+			//load DTT helper
1153
+			//before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1154
+			if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1155
+				$DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1156
+				$DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1157
+				$DTT->save();
1158
+			}
1159
+			//now we got to make sure we add the new DTT_ID to the $saved_dtts array  because it is possible there was a new one created for the autosave.
1160
+			$saved_dtt = $DTT;
1161
+			$success = ! $success ? $success : $DTT;
1162
+			//if ANY of these updates fail then we want the appropriate global error message.
1163
+			// //todo this is actually sucky we need a better error message but this is what it is for now.
1164
+		}
1165
+		//no dtts get deleted so we don't do any of that logic here.
1166
+		//update tickets next
1167
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1168
+		foreach ($data['edit_tickets'] as $row => $tkt) {
1169
+			$incoming_date_formats = array('Y-m-d', 'h:i a');
1170
+			$update_prices = false;
1171
+			$ticket_price = isset($data['edit_prices'][$row][1]['PRC_amount'])
1172
+				? $data['edit_prices'][$row][1]['PRC_amount'] : 0;
1173
+			// trim inputs to ensure any excess whitespace is removed.
1174
+			$tkt = array_map('trim', $tkt);
1175
+			if (empty($tkt['TKT_start_date'])) {
1176
+				//let's use now in the set timezone.
1177
+				$now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1178
+				$tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1179
+			}
1180
+			if (empty($tkt['TKT_end_date'])) {
1181
+				//use the start date of the first datetime
1182
+				$dtt = $evtobj->first_datetime();
1183
+				$tkt['TKT_end_date'] = $dtt->start_date_and_time(
1184
+					$incoming_date_formats[0],
1185
+					$incoming_date_formats[1]
1186
+				);
1187
+			}
1188
+			$TKT_values = array(
1189
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1190
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1191
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1192
+				'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1193
+				'TKT_start_date'  => $tkt['TKT_start_date'],
1194
+				'TKT_end_date'    => $tkt['TKT_end_date'],
1195
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1196
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1197
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1198
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1199
+				'TKT_row'         => $row,
1200
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1201
+				'TKT_price'       => $ticket_price,
1202
+			);
1203
+			//if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
1204
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1205
+				$TKT_values['TKT_ID'] = 0;
1206
+				$TKT_values['TKT_is_default'] = 0;
1207
+				$TKT_values['TKT_price'] = $ticket_price;
1208
+				$update_prices = true;
1209
+			}
1210
+			//if we have a TKT_ID then we need to get that existing TKT_obj and update it
1211
+			//we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
1212
+			//keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1213
+			if ( ! empty($tkt['TKT_ID'])) {
1214
+				$TKT = EE_Registry::instance()
1215
+								  ->load_model('Ticket', array($evtobj->get_timezone()))
1216
+								  ->get_one_by_ID($tkt['TKT_ID']);
1217
+				if ($TKT instanceof EE_Ticket) {
1218
+					$ticket_sold = $TKT->count_related(
1219
+						'Registration',
1220
+						array(
1221
+							array(
1222
+								'STS_ID' => array(
1223
+									'NOT IN',
1224
+									array(EEM_Registration::status_id_incomplete),
1225
+								),
1226
+							),
1227
+						)
1228
+					) > 0 ? true : false;
1229
+					//let's just check the total price for the existing ticket and determine if it matches the new total price.  if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket.
1230
+					$create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price')
1231
+									  && ! $TKT->get(
1232
+						'TKT_deleted'
1233
+					) ? true : false;
1234
+					$TKT->set_date_format($incoming_date_formats[0]);
1235
+					$TKT->set_time_format($incoming_date_formats[1]);
1236
+					//set new values
1237
+					foreach ($TKT_values as $field => $value) {
1238
+						if ($field == 'TKT_qty') {
1239
+							$TKT->set_qty($value);
1240
+						} else {
1241
+							$TKT->set($field, $value);
1242
+						}
1243
+					}
1244
+					//if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1245
+					if ($create_new_TKT) {
1246
+						//archive the old ticket first
1247
+						$TKT->set('TKT_deleted', 1);
1248
+						$TKT->save();
1249
+						//make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1250
+						$saved_tickets[$TKT->ID()] = $TKT;
1251
+						//create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it.
1252
+						$TKT = clone $TKT;
1253
+						$TKT->set('TKT_ID', 0);
1254
+						$TKT->set('TKT_deleted', 0);
1255
+						$TKT->set('TKT_price', $ticket_price);
1256
+						$TKT->set('TKT_sold', 0);
1257
+						//now we need to make sure that $new prices are created as well and attached to new ticket.
1258
+						$update_prices = true;
1259
+					}
1260
+					//make sure price is set if it hasn't been already
1261
+					$TKT->set('TKT_price', $ticket_price);
1262
+				}
1263
+			} else {
1264
+				//no TKT_id so a new TKT
1265
+				$TKT_values['TKT_price'] = $ticket_price;
1266
+				$TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1267
+				if ($TKT instanceof EE_Ticket) {
1268
+					//need to reset values to properly account for the date formats
1269
+					$TKT->set_date_format($incoming_date_formats[0]);
1270
+					$TKT->set_time_format($incoming_date_formats[1]);
1271
+					$TKT->set_timezone($evtobj->get_timezone());
1272
+					//set new values
1273
+					foreach ($TKT_values as $field => $value) {
1274
+						if ($field == 'TKT_qty') {
1275
+							$TKT->set_qty($value);
1276
+						} else {
1277
+							$TKT->set($field, $value);
1278
+						}
1279
+					}
1280
+					$update_prices = true;
1281
+				}
1282
+			}
1283
+			// cap ticket qty by datetime reg limits
1284
+			$TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1285
+			//update ticket.
1286
+			$TKT->save();
1287
+			//before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1288
+			if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1289
+				$TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1290
+				$TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1291
+				$TKT->save();
1292
+			}
1293
+			//initially let's add the ticket to the dtt
1294
+			$saved_dtt->_add_relation_to($TKT, 'Ticket');
1295
+			$saved_tickets[$TKT->ID()] = $TKT;
1296
+			//add prices to ticket
1297
+			$this->_add_prices_to_ticket($data['edit_prices'][$row], $TKT, $update_prices);
1298
+		}
1299
+		//however now we need to handle permanently deleting tickets via the ui.  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.  However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db.
1300
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
1301
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1302
+		foreach ($tickets_removed as $id) {
1303
+			$id = absint($id);
1304
+			//get the ticket for this id
1305
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1306
+			//need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold)
1307
+			$dtts = $tkt_to_remove->get_many_related('Datetime');
1308
+			foreach ($dtts as $dtt) {
1309
+				$tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1310
+			}
1311
+			//need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1312
+			$tkt_to_remove->delete_related_permanently('Price');
1313
+			//finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1314
+			$tkt_to_remove->delete_permanently();
1315
+		}
1316
+		return array($saved_dtt, $saved_tickets);
1317
+	}
1318
+
1319
+
1320
+
1321
+	/**
1322
+	 * This attaches a list of given prices to a ticket.
1323
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1324
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1325
+	 * price info and prices are automatically "archived" via the ticket.
1326
+	 *
1327
+	 * @access  private
1328
+	 * @param array     $prices     Array of prices from the form.
1329
+	 * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1330
+	 * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1331
+	 * @return  void
1332
+	 */
1333
+	private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1334
+	{
1335
+		foreach ($prices as $row => $prc) {
1336
+			$PRC_values = array(
1337
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1338
+				'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1339
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1340
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1341
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1342
+				'PRC_is_default' => 0, //make sure prices are NOT set as default from this context
1343
+				'PRC_order'      => $row,
1344
+			);
1345
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
1346
+				$PRC_values['PRC_ID'] = 0;
1347
+				$PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1348
+			} else {
1349
+				$PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1350
+				//update this price with new values
1351
+				foreach ($PRC_values as $field => $newprc) {
1352
+					$PRC->set($field, $newprc);
1353
+				}
1354
+				$PRC->save();
1355
+			}
1356
+			$ticket->_add_relation_to($PRC, 'Price');
1357
+		}
1358
+	}
1359
+
1360
+
1361
+
1362
+	/**
1363
+	 * Add in our autosave ajax handlers
1364
+	 *
1365
+	 * @return void
1366
+	 */
1367
+	protected function _ee_autosave_create_new()
1368
+	{
1369
+		// $this->_ee_autosave_edit();
1370
+	}
1371
+
1372
+
1373
+
1374
+	protected function _ee_autosave_edit()
1375
+	{
1376
+		return; //TEMPORARILY EXITING CAUSE THIS IS A TODO
1377
+	}
1378
+
1379
+
1380
+
1381
+	/**
1382
+	 *    _generate_publish_box_extra_content
1383
+	 *
1384
+	 * @access private
1385
+	 * @return void
1386
+	 */
1387
+	private function _generate_publish_box_extra_content()
1388
+	{
1389
+		//load formatter helper
1390
+		//args for getting related registrations
1391
+		$approved_query_args = array(
1392
+			array(
1393
+				'REG_deleted' => 0,
1394
+				'STS_ID'      => EEM_Registration::status_id_approved,
1395
+			),
1396
+		);
1397
+		$not_approved_query_args = array(
1398
+			array(
1399
+				'REG_deleted' => 0,
1400
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1401
+			),
1402
+		);
1403
+		$pending_payment_query_args = array(
1404
+			array(
1405
+				'REG_deleted' => 0,
1406
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1407
+			),
1408
+		);
1409
+		// publish box
1410
+		$publish_box_extra_args = array(
1411
+			'view_approved_reg_url'        => add_query_arg(
1412
+				array(
1413
+					'action'      => 'default',
1414
+					'event_id'    => $this->_cpt_model_obj->ID(),
1415
+					'_reg_status' => EEM_Registration::status_id_approved,
1416
+				),
1417
+				REG_ADMIN_URL
1418
+			),
1419
+			'view_not_approved_reg_url'    => add_query_arg(
1420
+				array(
1421
+					'action'      => 'default',
1422
+					'event_id'    => $this->_cpt_model_obj->ID(),
1423
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1424
+				),
1425
+				REG_ADMIN_URL
1426
+			),
1427
+			'view_pending_payment_reg_url' => add_query_arg(
1428
+				array(
1429
+					'action'      => 'default',
1430
+					'event_id'    => $this->_cpt_model_obj->ID(),
1431
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1432
+				),
1433
+				REG_ADMIN_URL
1434
+			),
1435
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1436
+				'Registration',
1437
+				$approved_query_args
1438
+			),
1439
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1440
+				'Registration',
1441
+				$not_approved_query_args
1442
+			),
1443
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1444
+				'Registration',
1445
+				$pending_payment_query_args
1446
+			),
1447
+			'misc_pub_section_class'       => apply_filters(
1448
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1449
+				'misc-pub-section'
1450
+			),
1451
+			//'email_attendees_url' => add_query_arg(
1452
+			//	array(
1453
+			//		'event_admin_reports' => 'event_newsletter',
1454
+			//		'event_id' => $this->_cpt_model_obj->id
1455
+			//	),
1456
+			//	'admin.php?page=espresso_registrations'
1457
+			//),
1458
+		);
1459
+		ob_start();
1460
+		do_action(
1461
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1462
+			$this->_cpt_model_obj
1463
+		);
1464
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1465
+		// load template
1466
+		EEH_Template::display_template(
1467
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1468
+			$publish_box_extra_args
1469
+		);
1470
+	}
1471
+
1472
+
1473
+
1474
+	/**
1475
+	 * This just returns whatever is set as the _event object property
1476
+	 * //todo this will become obsolete once the models are in place
1477
+	 *
1478
+	 * @return object
1479
+	 */
1480
+	public function get_event_object()
1481
+	{
1482
+		return $this->_cpt_model_obj;
1483
+	}
1484
+
1485
+
1486
+
1487
+
1488
+	/** METABOXES * */
1489
+	/**
1490
+	 * _register_event_editor_meta_boxes
1491
+	 * add all metaboxes related to the event_editor
1492
+	 *
1493
+	 * @return void
1494
+	 */
1495
+	protected function _register_event_editor_meta_boxes()
1496
+	{
1497
+		$this->verify_cpt_object();
1498
+		add_meta_box(
1499
+			'espresso_event_editor_tickets',
1500
+			esc_html__('Event Datetime & Ticket', 'event_espresso'),
1501
+			array($this, 'ticket_metabox'),
1502
+			$this->page_slug,
1503
+			'normal',
1504
+			'high'
1505
+		);
1506
+		add_meta_box(
1507
+			'espresso_event_editor_event_options',
1508
+			esc_html__('Event Registration Options', 'event_espresso'),
1509
+			array($this, 'registration_options_meta_box'),
1510
+			$this->page_slug,
1511
+			'side',
1512
+			'default'
1513
+		);
1514
+		// NOTE: if you're looking for other metaboxes in here,
1515
+		// where a metabox has a related management page in the admin
1516
+		// you will find it setup in the related management page's "_Hooks" file.
1517
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1518
+	}
1519
+
1520
+
1521
+
1522
+	public function ticket_metabox()
1523
+	{
1524
+		$existing_datetime_ids = $existing_ticket_ids = array();
1525
+		//defaults for template args
1526
+		$template_args = array(
1527
+			'existing_datetime_ids'    => '',
1528
+			'event_datetime_help_link' => '',
1529
+			'ticket_options_help_link' => '',
1530
+			'time'                     => null,
1531
+			'ticket_rows'              => '',
1532
+			'existing_ticket_ids'      => '',
1533
+			'total_ticket_rows'        => 1,
1534
+			'ticket_js_structure'      => '',
1535
+			'trash_icon'               => 'ee-lock-icon',
1536
+			'disabled'                 => '',
1537
+		);
1538
+		$event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1539
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1540
+		/**
1541
+		 * 1. Start with retrieving Datetimes
1542
+		 * 2. Fore each datetime get related tickets
1543
+		 * 3. For each ticket get related prices
1544
+		 */
1545
+		$times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1546
+		/** @type EE_Datetime $first_datetime */
1547
+		$first_datetime = reset($times);
1548
+		//do we get related tickets?
1549
+		if ($first_datetime instanceof EE_Datetime
1550
+			&& $first_datetime->ID() !== 0
1551
+		) {
1552
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1553
+			$template_args['time'] = $first_datetime;
1554
+			$related_tickets = $first_datetime->tickets(
1555
+				array(
1556
+					array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1557
+					'default_where_conditions' => 'none',
1558
+				)
1559
+			);
1560
+			if ( ! empty($related_tickets)) {
1561
+				$template_args['total_ticket_rows'] = count($related_tickets);
1562
+				$row = 0;
1563
+				foreach ($related_tickets as $ticket) {
1564
+					$existing_ticket_ids[] = $ticket->get('TKT_ID');
1565
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1566
+					$row++;
1567
+				}
1568
+			} else {
1569
+				$template_args['total_ticket_rows'] = 1;
1570
+				/** @type EE_Ticket $ticket */
1571
+				$ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1572
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1573
+			}
1574
+		} else {
1575
+			$template_args['time'] = $times[0];
1576
+			/** @type EE_Ticket $ticket */
1577
+			$ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1578
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1579
+			// NOTE: we're just sending the first default row
1580
+			// (decaf can't manage default tickets so this should be sufficient);
1581
+		}
1582
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1583
+			'event_editor_event_datetimes_help_tab'
1584
+		);
1585
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1586
+		$template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1587
+		$template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1588
+		$template_args['ticket_js_structure'] = $this->_get_ticket_row(
1589
+			EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1590
+			true
1591
+		);
1592
+		$template = apply_filters(
1593
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1594
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1595
+		);
1596
+		EEH_Template::display_template($template, $template_args);
1597
+	}
1598
+
1599
+
1600
+
1601
+	/**
1602
+	 * Setup an individual ticket form for the decaf event editor page
1603
+	 *
1604
+	 * @access private
1605
+	 * @param  EE_Ticket $ticket   the ticket object
1606
+	 * @param  boolean   $skeleton whether we're generating a skeleton for js manipulation
1607
+	 * @param int        $row
1608
+	 * @return string generated html for the ticket row.
1609
+	 */
1610
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1611
+	{
1612
+		$template_args = array(
1613
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1614
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1615
+				: '',
1616
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1617
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1618
+			'TKT_name'            => $ticket->get('TKT_name'),
1619
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1620
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1621
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1622
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1623
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1624
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1625
+			'trash_icon'          => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')))
1626
+									 && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1627
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1628
+			'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1629
+				: ' disabled=disabled',
1630
+		);
1631
+		$price = $ticket->ID() !== 0
1632
+			? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1633
+			: EE_Registry::instance()->load_model('Price')->create_default_object();
1634
+		$price_args = array(
1635
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1636
+			'PRC_amount'            => $price->get('PRC_amount'),
1637
+			'PRT_ID'                => $price->get('PRT_ID'),
1638
+			'PRC_ID'                => $price->get('PRC_ID'),
1639
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1640
+		);
1641
+		//make sure we have default start and end dates if skeleton
1642
+		//handle rows that should NOT be empty
1643
+		if (empty($template_args['TKT_start_date'])) {
1644
+			//if empty then the start date will be now.
1645
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1646
+		}
1647
+		if (empty($template_args['TKT_end_date'])) {
1648
+			//get the earliest datetime (if present);
1649
+			$earliest_dtt = $this->_cpt_model_obj->ID() > 0
1650
+				? $this->_cpt_model_obj->get_first_related(
1651
+					'Datetime',
1652
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1653
+				)
1654
+				: null;
1655
+			if ( ! empty($earliest_dtt)) {
1656
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1657
+			} else {
1658
+				$template_args['TKT_end_date'] = date(
1659
+					'Y-m-d h:i a',
1660
+					mktime(0, 0, 0, date("m"), date("d") + 7, date("Y"))
1661
+				);
1662
+			}
1663
+		}
1664
+		$template_args = array_merge($template_args, $price_args);
1665
+		$template = apply_filters(
1666
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1667
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1668
+			$ticket
1669
+		);
1670
+		return EEH_Template::display_template($template, $template_args, true);
1671
+	}
1672
+
1673
+
1674
+
1675
+	public function registration_options_meta_box()
1676
+	{
1677
+		$yes_no_values = array(
1678
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1679
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1680
+		);
1681
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1682
+			array(
1683
+				EEM_Registration::status_id_cancelled,
1684
+				EEM_Registration::status_id_declined,
1685
+				EEM_Registration::status_id_incomplete,
1686
+			),
1687
+			true
1688
+		);
1689
+		//$template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1690
+		$template_args['_event'] = $this->_cpt_model_obj;
1691
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1692
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1693
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1694
+			'default_reg_status',
1695
+			$default_reg_status_values,
1696
+			$this->_cpt_model_obj->default_registration_status()
1697
+		);
1698
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
1699
+			'display_desc',
1700
+			$yes_no_values,
1701
+			$this->_cpt_model_obj->display_description()
1702
+		);
1703
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1704
+			'display_ticket_selector',
1705
+			$yes_no_values,
1706
+			$this->_cpt_model_obj->display_ticket_selector(),
1707
+			'',
1708
+			'',
1709
+			false
1710
+		);
1711
+		$template_args['additional_registration_options'] = apply_filters(
1712
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1713
+			'',
1714
+			$template_args,
1715
+			$yes_no_values,
1716
+			$default_reg_status_values
1717
+		);
1718
+		EEH_Template::display_template(
1719
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1720
+			$template_args
1721
+		);
1722
+	}
1723
+
1724
+
1725
+
1726
+	/**
1727
+	 * _get_events()
1728
+	 * This method simply returns all the events (for the given _view and paging)
1729
+	 *
1730
+	 * @access public
1731
+	 * @param int  $per_page     count of items per page (20 default);
1732
+	 * @param int  $current_page what is the current page being viewed.
1733
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1734
+	 *                           If FALSE then we return an array of event objects
1735
+	 *                           that match the given _view and paging parameters.
1736
+	 * @return array an array of event objects.
1737
+	 */
1738
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1739
+	{
1740
+		$EEME = $this->_event_model();
1741
+		$offset = ($current_page - 1) * $per_page;
1742
+		$limit = $count ? null : $offset . ',' . $per_page;
1743
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1744
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1745
+		if (isset($this->_req_data['month_range'])) {
1746
+			$pieces = explode(' ', $this->_req_data['month_range'], 3);
1747
+			//simulate the FIRST day of the month, that fixes issues for months like February
1748
+			//where PHP doesn't know what to assume for date.
1749
+			//@see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1750
+			$month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1751
+			$year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1752
+		}
1753
+		$where = array();
1754
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1755
+		//determine what post_status our condition will have for the query.
1756
+		switch ($status) {
1757
+			case 'month' :
1758
+			case 'today' :
1759
+			case null :
1760
+			case 'all' :
1761
+				break;
1762
+			case 'draft' :
1763
+				$where['status'] = array('IN', array('draft', 'auto-draft'));
1764
+				break;
1765
+			default :
1766
+				$where['status'] = $status;
1767
+		}
1768
+		//categories?
1769
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1770
+			? $this->_req_data['EVT_CAT'] : null;
1771
+		if ( ! empty ($category)) {
1772
+			$where['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1773
+			$where['Term_Taxonomy.term_id'] = $category;
1774
+		}
1775
+		//date where conditions
1776
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1777
+		if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1778
+			$DateTime = new DateTime(
1779
+				$year_r . '-' . $month_r . '-01 00:00:00',
1780
+				new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1781
+			);
1782
+			$start = $DateTime->format(implode(' ', $start_formats));
1783
+			$end = $DateTime->setDate($year_r, $month_r, $DateTime
1784
+				->format('t'))->setTime(23, 59, 59)
1785
+							->format(implode(' ', $start_formats));
1786
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1787
+		} else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') {
1788
+			$DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1789
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1790
+			$end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1791
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1792
+		} else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') {
1793
+			$now = date('Y-m-01');
1794
+			$DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1795
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1796
+			$end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1797
+							->setTime(23, 59, 59)
1798
+							->format(implode(' ', $start_formats));
1799
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1800
+		}
1801
+		if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1802
+			$where['EVT_wp_user'] = get_current_user_id();
1803
+		} else {
1804
+			if ( ! isset($where['status'])) {
1805
+				if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1806
+					$where['OR'] = array(
1807
+						'status*restrict_private' => array('!=', 'private'),
1808
+						'AND'                     => array(
1809
+							'status*inclusive' => array('=', 'private'),
1810
+							'EVT_wp_user'      => get_current_user_id(),
1811
+						),
1812
+					);
1813
+				}
1814
+			}
1815
+		}
1816
+		if (isset($this->_req_data['EVT_wp_user'])) {
1817
+			if ($this->_req_data['EVT_wp_user'] != get_current_user_id()
1818
+				&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1819
+			) {
1820
+				$where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1821
+			}
1822
+		}
1823
+		//search query handling
1824
+		if (isset($this->_req_data['s'])) {
1825
+			$search_string = '%' . $this->_req_data['s'] . '%';
1826
+			$where['OR'] = array(
1827
+				'EVT_name'       => array('LIKE', $search_string),
1828
+				'EVT_desc'       => array('LIKE', $search_string),
1829
+				'EVT_short_desc' => array('LIKE', $search_string),
1830
+			);
1831
+		}
1832
+		$where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1833
+		$query_params = apply_filters(
1834
+			'FHEE__Events_Admin_Page__get_events__query_params',
1835
+			array(
1836
+				$where,
1837
+				'limit'    => $limit,
1838
+				'order_by' => $orderby,
1839
+				'order'    => $order,
1840
+				'group_by' => 'EVT_ID',
1841
+			),
1842
+			$this->_req_data
1843
+		);
1844
+		//let's first check if we have special requests coming in.
1845
+		if (isset($this->_req_data['active_status'])) {
1846
+			switch ($this->_req_data['active_status']) {
1847
+				case 'upcoming' :
1848
+					return $EEME->get_upcoming_events($query_params, $count);
1849
+					break;
1850
+				case 'expired' :
1851
+					return $EEME->get_expired_events($query_params, $count);
1852
+					break;
1853
+				case 'active' :
1854
+					return $EEME->get_active_events($query_params, $count);
1855
+					break;
1856
+				case 'inactive' :
1857
+					return $EEME->get_inactive_events($query_params, $count);
1858
+					break;
1859
+			}
1860
+		}
1861
+		$events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1862
+		return $events;
1863
+	}
1864
+
1865
+
1866
+
1867
+	/**
1868
+	 * handling for WordPress CPT actions (trash, restore, delete)
1869
+	 *
1870
+	 * @param string $post_id
1871
+	 */
1872
+	public function trash_cpt_item($post_id)
1873
+	{
1874
+		$this->_req_data['EVT_ID'] = $post_id;
1875
+		$this->_trash_or_restore_event('trash', false);
1876
+	}
1877
+
1878
+
1879
+
1880
+	/**
1881
+	 * @param string $post_id
1882
+	 */
1883
+	public function restore_cpt_item($post_id)
1884
+	{
1885
+		$this->_req_data['EVT_ID'] = $post_id;
1886
+		$this->_trash_or_restore_event('draft', false);
1887
+	}
1888
+
1889
+
1890
+
1891
+	/**
1892
+	 * @param string $post_id
1893
+	 */
1894
+	public function delete_cpt_item($post_id)
1895
+	{
1896
+		$this->_req_data['EVT_ID'] = $post_id;
1897
+		$this->_delete_event(false);
1898
+	}
1899
+
1900
+
1901
+
1902
+	/**
1903
+	 * _trash_or_restore_event
1904
+	 *
1905
+	 * @access protected
1906
+	 * @param  string $event_status
1907
+	 * @param bool    $redirect_after
1908
+	 */
1909
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
1910
+	{
1911
+		//determine the event id and set to array.
1912
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
1913
+		// loop thru events
1914
+		if ($EVT_ID) {
1915
+			// clean status
1916
+			$event_status = sanitize_key($event_status);
1917
+			// grab status
1918
+			if ( ! empty($event_status)) {
1919
+				$success = $this->_change_event_status($EVT_ID, $event_status);
1920
+			} else {
1921
+				$success = false;
1922
+				$msg = esc_html__(
1923
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1924
+					'event_espresso'
1925
+				);
1926
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1927
+			}
1928
+		} else {
1929
+			$success = false;
1930
+			$msg = esc_html__(
1931
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
1932
+				'event_espresso'
1933
+			);
1934
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1935
+		}
1936
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1937
+		if ($redirect_after) {
1938
+			$this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
1939
+		}
1940
+	}
1941
+
1942
+
1943
+
1944
+	/**
1945
+	 * _trash_or_restore_events
1946
+	 *
1947
+	 * @access protected
1948
+	 * @param  string $event_status
1949
+	 * @return void
1950
+	 */
1951
+	protected function _trash_or_restore_events($event_status = 'trash')
1952
+	{
1953
+		// clean status
1954
+		$event_status = sanitize_key($event_status);
1955
+		// grab status
1956
+		if ( ! empty($event_status)) {
1957
+			$success = true;
1958
+			//determine the event id and set to array.
1959
+			$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
1960
+			// loop thru events
1961
+			foreach ($EVT_IDs as $EVT_ID) {
1962
+				if ($EVT_ID = absint($EVT_ID)) {
1963
+					$results = $this->_change_event_status($EVT_ID, $event_status);
1964
+					$success = $results !== false ? $success : false;
1965
+				} else {
1966
+					$msg = sprintf(
1967
+						esc_html__(
1968
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
1969
+							'event_espresso'
1970
+						),
1971
+						$EVT_ID
1972
+					);
1973
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1974
+					$success = false;
1975
+				}
1976
+			}
1977
+		} else {
1978
+			$success = false;
1979
+			$msg = esc_html__(
1980
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1981
+				'event_espresso'
1982
+			);
1983
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1984
+		}
1985
+		// in order to force a pluralized result message we need to send back a success status greater than 1
1986
+		$success = $success ? 2 : false;
1987
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1988
+		$this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
1989
+	}
1990
+
1991
+
1992
+
1993
+	/**
1994
+	 * _trash_or_restore_events
1995
+	 *
1996
+	 * @access  private
1997
+	 * @param  int    $EVT_ID
1998
+	 * @param  string $event_status
1999
+	 * @return bool
2000
+	 */
2001
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2002
+	{
2003
+		// grab event id
2004
+		if ( ! $EVT_ID) {
2005
+			$msg = esc_html__(
2006
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2007
+				'event_espresso'
2008
+			);
2009
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2010
+			return false;
2011
+		}
2012
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2013
+		// clean status
2014
+		$event_status = sanitize_key($event_status);
2015
+		// grab status
2016
+		if (empty($event_status)) {
2017
+			$msg = esc_html__(
2018
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2019
+				'event_espresso'
2020
+			);
2021
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2022
+			return false;
2023
+		}
2024
+		// was event trashed or restored ?
2025
+		switch ($event_status) {
2026
+			case 'draft' :
2027
+				$action = 'restored from the trash';
2028
+				$hook = 'AHEE_event_restored_from_trash';
2029
+				break;
2030
+			case 'trash' :
2031
+				$action = 'moved to the trash';
2032
+				$hook = 'AHEE_event_moved_to_trash';
2033
+				break;
2034
+			default :
2035
+				$action = 'updated';
2036
+				$hook = false;
2037
+		}
2038
+		//use class to change status
2039
+		$this->_cpt_model_obj->set_status($event_status);
2040
+		$success = $this->_cpt_model_obj->save();
2041
+		if ($success === false) {
2042
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2043
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2044
+			return false;
2045
+		}
2046
+		if ($hook) {
2047
+			do_action($hook);
2048
+		}
2049
+		return true;
2050
+	}
2051
+
2052
+
2053
+
2054
+	/**
2055
+	 * _delete_event
2056
+	 *
2057
+	 * @access protected
2058
+	 * @param bool $redirect_after
2059
+	 */
2060
+	protected function _delete_event($redirect_after = true)
2061
+	{
2062
+		//determine the event id and set to array.
2063
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2064
+		$EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2065
+		// loop thru events
2066
+		if ($EVT_ID) {
2067
+			$success = $this->_permanently_delete_event($EVT_ID);
2068
+			// get list of events with no prices
2069
+			$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2070
+			// remove this event from the list of events with no prices
2071
+			if (isset($espresso_no_ticket_prices[$EVT_ID])) {
2072
+				unset($espresso_no_ticket_prices[$EVT_ID]);
2073
+			}
2074
+			update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2075
+		} else {
2076
+			$success = false;
2077
+			$msg = esc_html__(
2078
+				'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2079
+				'event_espresso'
2080
+			);
2081
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2082
+		}
2083
+		if ($redirect_after) {
2084
+			$this->_redirect_after_action(
2085
+				$success,
2086
+				'Event',
2087
+				'deleted',
2088
+				array('action' => 'default', 'status' => 'trash')
2089
+			);
2090
+		}
2091
+	}
2092
+
2093
+
2094
+
2095
+	/**
2096
+	 * _delete_events
2097
+	 *
2098
+	 * @access protected
2099
+	 * @return void
2100
+	 */
2101
+	protected function _delete_events()
2102
+	{
2103
+		$success = true;
2104
+		// get list of events with no prices
2105
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2106
+		//determine the event id and set to array.
2107
+		$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
2108
+		// loop thru events
2109
+		foreach ($EVT_IDs as $EVT_ID) {
2110
+			$EVT_ID = absint($EVT_ID);
2111
+			if ($EVT_ID) {
2112
+				$results = $this->_permanently_delete_event($EVT_ID);
2113
+				$success = $results !== false ? $success : false;
2114
+				// remove this event from the list of events with no prices
2115
+				unset($espresso_no_ticket_prices[$EVT_ID]);
2116
+			} else {
2117
+				$success = false;
2118
+				$msg = esc_html__(
2119
+					'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2120
+					'event_espresso'
2121
+				);
2122
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2123
+			}
2124
+		}
2125
+		update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2126
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2127
+		$success = $success ? 2 : false;
2128
+		$this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2129
+	}
2130
+
2131
+
2132
+
2133
+	/**
2134
+	 * _permanently_delete_event
2135
+	 *
2136
+	 * @access  private
2137
+	 * @param  int $EVT_ID
2138
+	 * @return bool
2139
+	 */
2140
+	private function _permanently_delete_event($EVT_ID = 0)
2141
+	{
2142
+		// grab event id
2143
+		if ( ! $EVT_ID) {
2144
+			$msg = esc_html__(
2145
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2146
+				'event_espresso'
2147
+			);
2148
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2149
+			return false;
2150
+		}
2151
+		if (
2152
+			! $this->_cpt_model_obj instanceof EE_Event
2153
+			|| $this->_cpt_model_obj->ID() !== $EVT_ID
2154
+		) {
2155
+			$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2156
+		}
2157
+		if ( ! $this->_cpt_model_obj instanceof EE_Event) {
2158
+			return false;
2159
+		}
2160
+		//need to delete related tickets and prices first.
2161
+		$datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2162
+		foreach ($datetimes as $datetime) {
2163
+			$this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2164
+			$tickets = $datetime->get_many_related('Ticket');
2165
+			foreach ($tickets as $ticket) {
2166
+				$ticket->_remove_relation_to($datetime, 'Datetime');
2167
+				$ticket->delete_related_permanently('Price');
2168
+				$ticket->delete_permanently();
2169
+			}
2170
+			$datetime->delete();
2171
+		}
2172
+		//what about related venues or terms?
2173
+		$venues = $this->_cpt_model_obj->get_many_related('Venue');
2174
+		foreach ($venues as $venue) {
2175
+			$this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2176
+		}
2177
+		//any attached question groups?
2178
+		$question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2179
+		if ( ! empty($question_groups)) {
2180
+			foreach ($question_groups as $question_group) {
2181
+				$this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2182
+			}
2183
+		}
2184
+		//Message Template Groups
2185
+		$this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2186
+		/** @type EE_Term_Taxonomy[] $term_taxonomies */
2187
+		$term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2188
+		foreach ($term_taxonomies as $term_taxonomy) {
2189
+			$this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2190
+		}
2191
+		$success = $this->_cpt_model_obj->delete_permanently();
2192
+		// did it all go as planned ?
2193
+		if ($success) {
2194
+			$msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2195
+			EE_Error::add_success($msg);
2196
+		} else {
2197
+			$msg = sprintf(
2198
+				esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2199
+				$EVT_ID
2200
+			);
2201
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2202
+			return false;
2203
+		}
2204
+		do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2205
+		return true;
2206
+	}
2207
+
2208
+
2209
+
2210
+	/**
2211
+	 * get total number of events
2212
+	 *
2213
+	 * @access public
2214
+	 * @return int
2215
+	 */
2216
+	public function total_events()
2217
+	{
2218
+		$count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2219
+		return $count;
2220
+	}
2221
+
2222
+
2223
+
2224
+	/**
2225
+	 * get total number of draft events
2226
+	 *
2227
+	 * @access public
2228
+	 * @return int
2229
+	 */
2230
+	public function total_events_draft()
2231
+	{
2232
+		$where = array(
2233
+			'status' => array('IN', array('draft', 'auto-draft')),
2234
+		);
2235
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2236
+		return $count;
2237
+	}
2238
+
2239
+
2240
+
2241
+	/**
2242
+	 * get total number of trashed events
2243
+	 *
2244
+	 * @access public
2245
+	 * @return int
2246
+	 */
2247
+	public function total_trashed_events()
2248
+	{
2249
+		$where = array(
2250
+			'status' => 'trash',
2251
+		);
2252
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2253
+		return $count;
2254
+	}
2255
+
2256
+
2257
+	/**
2258
+	 *    _default_event_settings
2259
+	 *    This generates the Default Settings Tab
2260
+	 *
2261
+	 * @return void
2262
+	 * @throws \EE_Error
2263
+	 */
2264
+	protected function _default_event_settings()
2265
+	{
2266
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2267
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2268
+		$this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2269
+		$this->display_admin_page_with_sidebar();
2270
+	}
2271
+
2272
+
2273
+	/**
2274
+	 * Return the form for event settings.
2275
+	 * @return \EE_Form_Section_Proper
2276
+	 */
2277
+	protected function _default_event_settings_form()
2278
+	{
2279
+		$registration_config = EE_Registry::instance()->CFG->registration;
2280
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2281
+		//exclude
2282
+			array(
2283
+				EEM_Registration::status_id_cancelled,
2284
+				EEM_Registration::status_id_declined,
2285
+				EEM_Registration::status_id_incomplete,
2286
+				EEM_Registration::status_id_wait_list,
2287
+			),
2288
+			true
2289
+		);
2290
+		return new EE_Form_Section_Proper(
2291
+			array(
2292
+				'name' => 'update_default_event_settings',
2293
+				'html_id' => 'update_default_event_settings',
2294
+				'html_class' => 'form-table',
2295
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2296
+				'subsections' => apply_filters(
2297
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2298
+					array(
2299
+						'default_reg_status' => new EE_Select_Input(
2300
+							$registration_stati_for_selection,
2301
+							array(
2302
+								'default' => isset($registration_config->default_STS_ID)
2303
+											 && array_key_exists(
2304
+												$registration_config->default_STS_ID,
2305
+												$registration_stati_for_selection
2306
+											 )
2307
+											? sanitize_text_field($registration_config->default_STS_ID)
2308
+											: EEM_Registration::status_id_pending_payment,
2309
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2310
+													. EEH_Template::get_help_tab_link(
2311
+														'default_settings_status_help_tab'
2312
+													),
2313
+								'html_help_text' => esc_html__(
2314
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2315
+									'event_espresso'
2316
+								)
2317
+							)
2318
+						),
2319
+						'default_max_tickets' => new EE_Integer_Input(
2320
+							array(
2321
+								'default' => isset($registration_config->default_maximum_number_of_tickets)
2322
+									? $registration_config->default_maximum_number_of_tickets
2323
+									: EEM_Event::get_default_additional_limit(),
2324
+								'html_label_text' => esc_html__(
2325
+									'Default Maximum Tickets Allowed Per Order:',
2326
+									'event_espresso'
2327
+								) . EEH_Template::get_help_tab_link(
2328
+									'default_maximum_tickets_help_tab"'
2329
+									),
2330
+								'html_help_text' => esc_html__(
2331
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2332
+									'event_espresso'
2333
+								)
2334
+							)
2335
+						)
2336
+					)
2337
+				)
2338
+			)
2339
+		);
2340
+	}
2341
+
2342
+
2343
+	/**
2344
+	 * _update_default_event_settings
2345
+	 *
2346
+	 * @access protected
2347
+	 * @return void
2348
+	 * @throws \EE_Error
2349
+	 */
2350
+	protected function _update_default_event_settings()
2351
+	{
2352
+		$registration_config = EE_Registry::instance()->CFG->registration;
2353
+		$form = $this->_default_event_settings_form();
2354
+		if ($form->was_submitted()) {
2355
+			$form->receive_form_submission();
2356
+			if ($form->is_valid()) {
2357
+				$valid_data = $form->valid_data();
2358
+				if (isset($valid_data['default_reg_status'])) {
2359
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2360
+				}
2361
+				if (isset($valid_data['default_max_tickets'])) {
2362
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2363
+				}
2364
+				//update because data was valid!
2365
+				EE_Registry::instance()->CFG->update_espresso_config();
2366
+				EE_Error::overwrite_success();
2367
+				EE_Error::add_success(
2368
+					__('Default Event Settings were updated', 'event_espresso')
2369
+				);
2370
+			}
2371
+		}
2372
+		$this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true);
2373
+	}
2374
+
2375
+
2376
+
2377
+	/*************        Templates        *************/
2378
+	protected function _template_settings()
2379
+	{
2380
+		$this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2381
+		$this->_template_args['preview_img'] = '<img src="'
2382
+											   . EVENTS_ASSETS_URL
2383
+											   . DS
2384
+											   . 'images'
2385
+											   . DS
2386
+											   . 'caffeinated_template_features.jpg" alt="'
2387
+											   . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2388
+											   . '" />';
2389
+		$this->_template_args['preview_text'] = '<strong>' . esc_html__(
2390
+				'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2391
+				'event_espresso'
2392
+			) . '</strong>';
2393
+		$this->display_admin_caf_preview_page('template_settings_tab');
2394
+	}
2395
+
2396
+
2397
+	/** Event Category Stuff **/
2398
+	/**
2399
+	 * set the _category property with the category object for the loaded page.
2400
+	 *
2401
+	 * @access private
2402
+	 * @return void
2403
+	 */
2404
+	private function _set_category_object()
2405
+	{
2406
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2407
+			return;
2408
+		} //already have the category object so get out.
2409
+		//set default category object
2410
+		$this->_set_empty_category_object();
2411
+		//only set if we've got an id
2412
+		if ( ! isset($this->_req_data['EVT_CAT_ID'])) {
2413
+			return;
2414
+		}
2415
+		$category_id = absint($this->_req_data['EVT_CAT_ID']);
2416
+		$term = get_term($category_id, 'espresso_event_categories');
2417
+		if ( ! empty($term)) {
2418
+			$this->_category->category_name = $term->name;
2419
+			$this->_category->category_identifier = $term->slug;
2420
+			$this->_category->category_desc = $term->description;
2421
+			$this->_category->id = $term->term_id;
2422
+			$this->_category->parent = $term->parent;
2423
+		}
2424
+	}
2425
+
2426
+
2427
+
2428
+	private function _set_empty_category_object()
2429
+	{
2430
+		$this->_category = new stdClass();
2431
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2432
+		$this->_category->id = $this->_category->parent = 0;
2433
+	}
2434
+
2435
+
2436
+
2437
+	protected function _category_list_table()
2438
+	{
2439
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2440
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2441
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2442
+				'add_category',
2443
+				'add_category',
2444
+				array(),
2445
+				'add-new-h2'
2446
+			);
2447
+		$this->display_admin_list_table_page_with_sidebar();
2448
+	}
2449
+
2450
+
2451
+
2452
+	/**
2453
+	 * @param $view
2454
+	 */
2455
+	protected function _category_details($view)
2456
+	{
2457
+		//load formatter helper
2458
+		//load field generator helper
2459
+		$route = $view == 'edit' ? 'update_category' : 'insert_category';
2460
+		$this->_set_add_edit_form_tags($route);
2461
+		$this->_set_category_object();
2462
+		$id = ! empty($this->_category->id) ? $this->_category->id : '';
2463
+		$delete_action = 'delete_category';
2464
+		//custom redirect
2465
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2466
+			array('action' => 'category_list'),
2467
+			$this->_admin_base_url
2468
+		);
2469
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2470
+		//take care of contents
2471
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2472
+		$this->display_admin_page_with_sidebar();
2473
+	}
2474
+
2475
+
2476
+
2477
+	/**
2478
+	 * @return mixed
2479
+	 */
2480
+	protected function _category_details_content()
2481
+	{
2482
+		$editor_args['category_desc'] = array(
2483
+			'type'          => 'wp_editor',
2484
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2485
+			'class'         => 'my_editor_custom',
2486
+			'wpeditor_args' => array('media_buttons' => false),
2487
+		);
2488
+		$_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2489
+		$all_terms = get_terms(
2490
+			array('espresso_event_categories'),
2491
+			array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2492
+		);
2493
+		//setup category select for term parents.
2494
+		$category_select_values[] = array(
2495
+			'text' => esc_html__('No Parent', 'event_espresso'),
2496
+			'id'   => 0,
2497
+		);
2498
+		foreach ($all_terms as $term) {
2499
+			$category_select_values[] = array(
2500
+				'text' => $term->name,
2501
+				'id'   => $term->term_id,
2502
+			);
2503
+		}
2504
+		$category_select = EEH_Form_Fields::select_input(
2505
+			'category_parent',
2506
+			$category_select_values,
2507
+			$this->_category->parent
2508
+		);
2509
+		$template_args = array(
2510
+			'category'                 => $this->_category,
2511
+			'category_select'          => $category_select,
2512
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2513
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2514
+			'disable'                  => '',
2515
+			'disabled_message'         => false,
2516
+		);
2517
+		$template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2518
+		return EEH_Template::display_template($template, $template_args, true);
2519
+	}
2520
+
2521
+
2522
+
2523
+	protected function _delete_categories()
2524
+	{
2525
+		$cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array)$this->_req_data['EVT_CAT_ID']
2526
+			: (array)$this->_req_data['category_id'];
2527
+		foreach ($cat_ids as $cat_id) {
2528
+			$this->_delete_category($cat_id);
2529
+		}
2530
+		//doesn't matter what page we're coming from... we're going to the same place after delete.
2531
+		$query_args = array(
2532
+			'action' => 'category_list',
2533
+		);
2534
+		$this->_redirect_after_action(0, '', '', $query_args);
2535
+	}
2536
+
2537
+
2538
+
2539
+	/**
2540
+	 * @param $cat_id
2541
+	 */
2542
+	protected function _delete_category($cat_id)
2543
+	{
2544
+		$cat_id = absint($cat_id);
2545
+		wp_delete_term($cat_id, 'espresso_event_categories');
2546
+	}
2547
+
2548
+
2549
+
2550
+	/**
2551
+	 * @param $new_category
2552
+	 */
2553
+	protected function _insert_or_update_category($new_category)
2554
+	{
2555
+		$cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2556
+		$success = 0; //we already have a success message so lets not send another.
2557
+		if ($cat_id) {
2558
+			$query_args = array(
2559
+				'action'     => 'edit_category',
2560
+				'EVT_CAT_ID' => $cat_id,
2561
+			);
2562
+		} else {
2563
+			$query_args = array('action' => 'add_category');
2564
+		}
2565
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2566
+	}
2567
+
2568
+
2569
+
2570
+	/**
2571
+	 * @param bool $update
2572
+	 * @return bool|mixed|string
2573
+	 */
2574
+	private function _insert_category($update = false)
2575
+	{
2576
+		$cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2577
+		$category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2578
+		$category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2579
+		$category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2580
+		if (empty($category_name)) {
2581
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2582
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2583
+			return false;
2584
+		}
2585
+		$term_args = array(
2586
+			'name'        => $category_name,
2587
+			'description' => $category_desc,
2588
+			'parent'      => $category_parent,
2589
+		);
2590
+		//was the category_identifier input disabled?
2591
+		if (isset($this->_req_data['category_identifier'])) {
2592
+			$term_args['slug'] = $this->_req_data['category_identifier'];
2593
+		}
2594
+		$insert_ids = $update
2595
+			? wp_update_term($cat_id, 'espresso_event_categories', $term_args)
2596
+			: wp_insert_term($category_name, 'espresso_event_categories', $term_args);
2597
+		if ( ! is_array($insert_ids)) {
2598
+			$msg = esc_html__(
2599
+				'An error occurred and the category has not been saved to the database.',
2600
+				'event_espresso'
2601
+			);
2602
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2603
+		} else {
2604
+			$cat_id = $insert_ids['term_id'];
2605
+			$msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2606
+			EE_Error::add_success($msg);
2607
+		}
2608
+		return $cat_id;
2609
+	}
2610
+
2611
+
2612
+
2613
+	/**
2614
+	 * @param int  $per_page
2615
+	 * @param int  $current_page
2616
+	 * @param bool $count
2617
+	 * @return \EE_Base_Class[]|int
2618
+	 */
2619
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2620
+	{
2621
+		//testing term stuff
2622
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2623
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2624
+		$limit = ($current_page - 1) * $per_page;
2625
+		$where = array('taxonomy' => 'espresso_event_categories');
2626
+		if (isset($this->_req_data['s'])) {
2627
+			$sstr = '%' . $this->_req_data['s'] . '%';
2628
+			$where['OR'] = array(
2629
+				'Term.name'   => array('LIKE', $sstr),
2630
+				'description' => array('LIKE', $sstr),
2631
+			);
2632
+		}
2633
+		$query_params = array(
2634
+			$where,
2635
+			'order_by'   => array($orderby => $order),
2636
+			'limit'      => $limit . ',' . $per_page,
2637
+			'force_join' => array('Term'),
2638
+		);
2639
+		$categories = $count
2640
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2641
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2642
+		return $categories;
2643
+	}
2644
+
2645
+
2646
+
2647
+	/* end category stuff */
2648
+	/**************/
2649 2649
 }
2650 2650
 //end class Events_Admin_Page
Please login to merge, or discard this patch.
Spacing   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -536,11 +536,11 @@  discard block
 block discarded – undo
536 536
     {
537 537
         wp_register_style(
538 538
             'events-admin-css',
539
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
539
+            EVENTS_ASSETS_URL.'events-admin-page.css',
540 540
             array(),
541 541
             EVENT_ESPRESSO_VERSION
542 542
         );
543
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
543
+        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL.'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
544 544
         wp_enqueue_style('events-admin-css');
545 545
         wp_enqueue_style('ee-cat-admin');
546 546
         //todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
@@ -548,7 +548,7 @@  discard block
 block discarded – undo
548 548
         //scripts
549 549
         wp_register_script(
550 550
             'event_editor_js',
551
-            EVENTS_ASSETS_URL . 'event_editor.js',
551
+            EVENTS_ASSETS_URL.'event_editor.js',
552 552
             array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
553 553
             EVENT_ESPRESSO_VERSION,
554 554
             true
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
         wp_enqueue_style('espresso-ui-theme');
581 581
         wp_register_style(
582 582
             'event-editor-css',
583
-            EVENTS_ASSETS_URL . 'event-editor.css',
583
+            EVENTS_ASSETS_URL.'event-editor.css',
584 584
             array('ee-admin-css'),
585 585
             EVENT_ESPRESSO_VERSION
586 586
         );
@@ -588,7 +588,7 @@  discard block
 block discarded – undo
588 588
         //scripts
589 589
         wp_register_script(
590 590
             'event-datetime-metabox',
591
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
591
+            EVENTS_ASSETS_URL.'event-datetime-metabox.js',
592 592
             array('event_editor_js', 'ee-datepicker'),
593 593
             EVENT_ESPRESSO_VERSION
594 594
         );
@@ -665,7 +665,7 @@  discard block
 block discarded – undo
665 665
             $event = $this->_cpt_model_obj;
666 666
         }
667 667
         // STILL no event?
668
-        if (! $event instanceof EE_Event) {
668
+        if ( ! $event instanceof EE_Event) {
669 669
             return;
670 670
         }
671 671
         $orig_status = $event->status();
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
                         'Your website\'s timezone is currently set to UTC + 0. We recommend updating your timezone to a city or region near you before you create an event. Your timezone can be updated through the %1$sGeneral Settings%2$s page.',
755 755
                         'event_espresso'
756 756
                     ),
757
-                    '<a href="' . admin_url('options-general.php') . '">',
757
+                    '<a href="'.admin_url('options-general.php').'">',
758 758
                     '</a>'
759 759
                 ),
760 760
                 __FILE__,
@@ -824,31 +824,31 @@  discard block
 block discarded – undo
824 824
         $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
825 825
         $statuses = array(
826 826
             'sold_out_status'  => array(
827
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
827
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::sold_out,
828 828
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
829 829
             ),
830 830
             'active_status'    => array(
831
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
831
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::active,
832 832
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
833 833
             ),
834 834
             'upcoming_status'  => array(
835
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
835
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::upcoming,
836 836
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
837 837
             ),
838 838
             'postponed_status' => array(
839
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
839
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::postponed,
840 840
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
841 841
             ),
842 842
             'cancelled_status' => array(
843
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
843
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::cancelled,
844 844
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
845 845
             ),
846 846
             'expired_status'   => array(
847
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
847
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::expired,
848 848
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
849 849
             ),
850 850
             'inactive_status'  => array(
851
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
851
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::inactive,
852 852
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
853 853
             ),
854 854
         );
@@ -912,7 +912,7 @@  discard block
 block discarded – undo
912 912
     {
913 913
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
914 914
         $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
915
-            ? (array)$this->_template_args['after_list_table']
915
+            ? (array) $this->_template_args['after_list_table']
916 916
             : array();
917 917
         $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
918 918
                                                                               . EEH_Template::get_button_or_link(
@@ -921,7 +921,7 @@  discard block
 block discarded – undo
921 921
                 'button'
922 922
             );
923 923
         $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
924
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
924
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
925 925
                 'create_new',
926 926
                 'add',
927 927
                 array(),
@@ -1051,7 +1051,7 @@  discard block
 block discarded – undo
1051 1051
      */
1052 1052
     protected function _default_venue_update(\EE_Event $evtobj, $data)
1053 1053
     {
1054
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1054
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1055 1055
         $venue_model = EE_Registry::instance()->load_model('Venue');
1056 1056
         $rows_affected = null;
1057 1057
         $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
@@ -1175,7 +1175,7 @@  discard block
 block discarded – undo
1175 1175
             if (empty($tkt['TKT_start_date'])) {
1176 1176
                 //let's use now in the set timezone.
1177 1177
                 $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1178
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1178
+                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0].' '.$incoming_date_formats[1]);
1179 1179
             }
1180 1180
             if (empty($tkt['TKT_end_date'])) {
1181 1181
                 //use the start date of the first datetime
@@ -1464,7 +1464,7 @@  discard block
 block discarded – undo
1464 1464
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1465 1465
         // load template
1466 1466
         EEH_Template::display_template(
1467
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1467
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1468 1468
             $publish_box_extra_args
1469 1469
         );
1470 1470
     }
@@ -1591,7 +1591,7 @@  discard block
 block discarded – undo
1591 1591
         );
1592 1592
         $template = apply_filters(
1593 1593
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1594
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1594
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1595 1595
         );
1596 1596
         EEH_Template::display_template($template, $template_args);
1597 1597
     }
@@ -1610,7 +1610,7 @@  discard block
 block discarded – undo
1610 1610
     private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1611 1611
     {
1612 1612
         $template_args = array(
1613
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1613
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1614 1614
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1615 1615
                 : '',
1616 1616
             'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
@@ -1664,7 +1664,7 @@  discard block
 block discarded – undo
1664 1664
         $template_args = array_merge($template_args, $price_args);
1665 1665
         $template = apply_filters(
1666 1666
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1667
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1667
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1668 1668
             $ticket
1669 1669
         );
1670 1670
         return EEH_Template::display_template($template, $template_args, true);
@@ -1716,7 +1716,7 @@  discard block
 block discarded – undo
1716 1716
             $default_reg_status_values
1717 1717
         );
1718 1718
         EEH_Template::display_template(
1719
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1719
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1720 1720
             $template_args
1721 1721
         );
1722 1722
     }
@@ -1739,7 +1739,7 @@  discard block
 block discarded – undo
1739 1739
     {
1740 1740
         $EEME = $this->_event_model();
1741 1741
         $offset = ($current_page - 1) * $per_page;
1742
-        $limit = $count ? null : $offset . ',' . $per_page;
1742
+        $limit = $count ? null : $offset.','.$per_page;
1743 1743
         $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1744 1744
         $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1745 1745
         if (isset($this->_req_data['month_range'])) {
@@ -1776,7 +1776,7 @@  discard block
 block discarded – undo
1776 1776
         $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1777 1777
         if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1778 1778
             $DateTime = new DateTime(
1779
-                $year_r . '-' . $month_r . '-01 00:00:00',
1779
+                $year_r.'-'.$month_r.'-01 00:00:00',
1780 1780
                 new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1781 1781
             );
1782 1782
             $start = $DateTime->format(implode(' ', $start_formats));
@@ -1822,7 +1822,7 @@  discard block
 block discarded – undo
1822 1822
         }
1823 1823
         //search query handling
1824 1824
         if (isset($this->_req_data['s'])) {
1825
-            $search_string = '%' . $this->_req_data['s'] . '%';
1825
+            $search_string = '%'.$this->_req_data['s'].'%';
1826 1826
             $where['OR'] = array(
1827 1827
                 'EVT_name'       => array('LIKE', $search_string),
1828 1828
                 'EVT_desc'       => array('LIKE', $search_string),
@@ -1956,7 +1956,7 @@  discard block
 block discarded – undo
1956 1956
         if ( ! empty($event_status)) {
1957 1957
             $success = true;
1958 1958
             //determine the event id and set to array.
1959
-            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
1959
+            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
1960 1960
             // loop thru events
1961 1961
             foreach ($EVT_IDs as $EVT_ID) {
1962 1962
                 if ($EVT_ID = absint($EVT_ID)) {
@@ -2104,7 +2104,7 @@  discard block
 block discarded – undo
2104 2104
         // get list of events with no prices
2105 2105
         $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2106 2106
         //determine the event id and set to array.
2107
-        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
2107
+        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2108 2108
         // loop thru events
2109 2109
         foreach ($EVT_IDs as $EVT_ID) {
2110 2110
             $EVT_ID = absint($EVT_ID);
@@ -2324,7 +2324,7 @@  discard block
 block discarded – undo
2324 2324
                                 'html_label_text' => esc_html__(
2325 2325
                                     'Default Maximum Tickets Allowed Per Order:',
2326 2326
                                     'event_espresso'
2327
-                                ) . EEH_Template::get_help_tab_link(
2327
+                                ).EEH_Template::get_help_tab_link(
2328 2328
                                     'default_maximum_tickets_help_tab"'
2329 2329
                                     ),
2330 2330
                                 'html_help_text' => esc_html__(
@@ -2386,10 +2386,10 @@  discard block
 block discarded – undo
2386 2386
                                                . 'caffeinated_template_features.jpg" alt="'
2387 2387
                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2388 2388
                                                . '" />';
2389
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__(
2389
+        $this->_template_args['preview_text'] = '<strong>'.esc_html__(
2390 2390
                 'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2391 2391
                 'event_espresso'
2392
-            ) . '</strong>';
2392
+            ).'</strong>';
2393 2393
         $this->display_admin_caf_preview_page('template_settings_tab');
2394 2394
     }
2395 2395
 
@@ -2438,7 +2438,7 @@  discard block
 block discarded – undo
2438 2438
     {
2439 2439
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2440 2440
         $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2441
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2441
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
2442 2442
                 'add_category',
2443 2443
                 'add_category',
2444 2444
                 array(),
@@ -2514,7 +2514,7 @@  discard block
 block discarded – undo
2514 2514
             'disable'                  => '',
2515 2515
             'disabled_message'         => false,
2516 2516
         );
2517
-        $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2517
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2518 2518
         return EEH_Template::display_template($template, $template_args, true);
2519 2519
     }
2520 2520
 
@@ -2522,8 +2522,8 @@  discard block
 block discarded – undo
2522 2522
 
2523 2523
     protected function _delete_categories()
2524 2524
     {
2525
-        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array)$this->_req_data['EVT_CAT_ID']
2526
-            : (array)$this->_req_data['category_id'];
2525
+        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2526
+            : (array) $this->_req_data['category_id'];
2527 2527
         foreach ($cat_ids as $cat_id) {
2528 2528
             $this->_delete_category($cat_id);
2529 2529
         }
@@ -2624,7 +2624,7 @@  discard block
 block discarded – undo
2624 2624
         $limit = ($current_page - 1) * $per_page;
2625 2625
         $where = array('taxonomy' => 'espresso_event_categories');
2626 2626
         if (isset($this->_req_data['s'])) {
2627
-            $sstr = '%' . $this->_req_data['s'] . '%';
2627
+            $sstr = '%'.$this->_req_data['s'].'%';
2628 2628
             $where['OR'] = array(
2629 2629
                 'Term.name'   => array('LIKE', $sstr),
2630 2630
                 'description' => array('LIKE', $sstr),
@@ -2633,7 +2633,7 @@  discard block
 block discarded – undo
2633 2633
         $query_params = array(
2634 2634
             $where,
2635 2635
             'order_by'   => array($orderby => $order),
2636
-            'limit'      => $limit . ',' . $per_page,
2636
+            'limit'      => $limit.','.$per_page,
2637 2637
             'force_join' => array('Term'),
2638 2638
         );
2639 2639
         $categories = $count
Please login to merge, or discard this patch.
modules/single_page_checkout/EED_Single_Page_Checkout.module.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -781,7 +781,7 @@  discard block
 block discarded – undo
781 781
      * _get_transaction_and_cart_for_previous_visit
782 782
      *
783 783
      * @access private
784
-     * @return mixed EE_Transaction|NULL
784
+     * @return EE_Transaction|null EE_Transaction|NULL
785 785
      */
786 786
     private function _get_transaction_and_cart_for_previous_visit()
787 787
     {
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
      *    generates a new EE_Transaction object and adds it to the $_transaction property.
864 864
      *
865 865
      * @access private
866
-     * @return mixed EE_Transaction|NULL
866
+     * @return EE_Transaction|null EE_Transaction|NULL
867 867
      */
868 868
     private function _initialize_transaction()
869 869
     {
Please login to merge, or discard this patch.
Indentation   +1849 added lines, -1849 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use EventEspresso\core\exceptions\InvalidEntityException;
6 6
 
7 7
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
8
-    exit('No direct script access allowed');
8
+	exit('No direct script access allowed');
9 9
 }
10 10
 
11 11
 
@@ -20,1854 +20,1854 @@  discard block
 block discarded – undo
20 20
 class EED_Single_Page_Checkout extends EED_Module
21 21
 {
22 22
 
23
-    /**
24
-     * $_initialized - has the SPCO controller already been initialized ?
25
-     *
26
-     * @access private
27
-     * @var bool $_initialized
28
-     */
29
-    private static $_initialized = false;
30
-
31
-
32
-    /**
33
-     * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
34
-     *
35
-     * @access private
36
-     * @var bool $_valid_checkout
37
-     */
38
-    private static $_checkout_verified = true;
39
-
40
-    /**
41
-     *    $_reg_steps_array - holds initial array of reg steps
42
-     *
43
-     * @access private
44
-     * @var array $_reg_steps_array
45
-     */
46
-    private static $_reg_steps_array = array();
47
-
48
-    /**
49
-     *    $checkout - EE_Checkout object for handling the properties of the current checkout process
50
-     *
51
-     * @access public
52
-     * @var EE_Checkout $checkout
53
-     */
54
-    public $checkout;
55
-
56
-
57
-
58
-    /**
59
-     * @return EED_Module|EED_Single_Page_Checkout
60
-     */
61
-    public static function instance()
62
-    {
63
-        add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
64
-        return parent::get_instance(__CLASS__);
65
-    }
66
-
67
-
68
-
69
-    /**
70
-     * @return EE_CART
71
-     */
72
-    public function cart()
73
-    {
74
-        return $this->checkout->cart;
75
-    }
76
-
77
-
78
-
79
-    /**
80
-     * @return EE_Transaction
81
-     */
82
-    public function transaction()
83
-    {
84
-        return $this->checkout->transaction;
85
-    }
86
-
87
-
88
-
89
-    /**
90
-     *    set_hooks - for hooking into EE Core, other modules, etc
91
-     *
92
-     * @access    public
93
-     * @return    void
94
-     * @throws EE_Error
95
-     */
96
-    public static function set_hooks()
97
-    {
98
-        EED_Single_Page_Checkout::set_definitions();
99
-    }
100
-
101
-
102
-
103
-    /**
104
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
-     *
106
-     * @access    public
107
-     * @return    void
108
-     * @throws EE_Error
109
-     */
110
-    public static function set_hooks_admin()
111
-    {
112
-        EED_Single_Page_Checkout::set_definitions();
113
-        if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
114
-            return;
115
-        }
116
-        // going to start an output buffer in case anything gets accidentally output
117
-        // that might disrupt our JSON response
118
-        ob_start();
119
-        EED_Single_Page_Checkout::load_request_handler();
120
-        EED_Single_Page_Checkout::load_reg_steps();
121
-        // set ajax hooks
122
-        add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
123
-        add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
124
-        add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
125
-        add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
126
-        add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
127
-        add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
128
-    }
129
-
130
-
131
-
132
-    /**
133
-     *    process ajax request
134
-     *
135
-     * @param string $ajax_action
136
-     * @throws EE_Error
137
-     */
138
-    public static function process_ajax_request($ajax_action)
139
-    {
140
-        EE_Registry::instance()->REQ->set('action', $ajax_action);
141
-        EED_Single_Page_Checkout::instance()->_initialize();
142
-    }
143
-
144
-
145
-
146
-    /**
147
-     *    ajax display registration step
148
-     *
149
-     * @throws EE_Error
150
-     */
151
-    public static function display_reg_step()
152
-    {
153
-        EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
154
-    }
155
-
156
-
157
-
158
-    /**
159
-     *    ajax process registration step
160
-     *
161
-     * @throws EE_Error
162
-     */
163
-    public static function process_reg_step()
164
-    {
165
-        EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
166
-    }
167
-
168
-
169
-
170
-    /**
171
-     *    ajax process registration step
172
-     *
173
-     * @throws EE_Error
174
-     */
175
-    public static function update_reg_step()
176
-    {
177
-        EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
178
-    }
179
-
180
-
181
-
182
-    /**
183
-     *   update_checkout
184
-     *
185
-     * @access public
186
-     * @return void
187
-     * @throws EE_Error
188
-     */
189
-    public static function update_checkout()
190
-    {
191
-        EED_Single_Page_Checkout::process_ajax_request('update_checkout');
192
-    }
193
-
194
-
195
-
196
-    /**
197
-     *    load_request_handler
198
-     *
199
-     * @access    public
200
-     * @return    void
201
-     */
202
-    public static function load_request_handler()
203
-    {
204
-        // load core Request_Handler class
205
-        if (EE_Registry::instance()->REQ !== null) {
206
-            EE_Registry::instance()->load_core('Request_Handler');
207
-        }
208
-    }
209
-
210
-
211
-
212
-    /**
213
-     *    set_definitions
214
-     *
215
-     * @access    public
216
-     * @return    void
217
-     * @throws EE_Error
218
-     */
219
-    public static function set_definitions()
220
-    {
221
-        if(defined('SPCO_BASE_PATH')) {
222
-            return;
223
-        }
224
-        define(
225
-            'SPCO_BASE_PATH',
226
-            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
227
-        );
228
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
234
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236
-            __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
237
-                'event_espresso'),
238
-            '<h4 class="important-notice">',
239
-            '</h4>',
240
-            '<br />',
241
-            '<p>',
242
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
243
-            '">',
244
-            '</a>',
245
-            '</p>'
246
-        );
247
-    }
248
-
249
-
250
-
251
-    /**
252
-     * load_reg_steps
253
-     * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
254
-     *
255
-     * @access    private
256
-     * @throws EE_Error
257
-     */
258
-    public static function load_reg_steps()
259
-    {
260
-        static $reg_steps_loaded = false;
261
-        if ($reg_steps_loaded) {
262
-            return;
263
-        }
264
-        // filter list of reg_steps
265
-        $reg_steps_to_load = (array)apply_filters(
266
-            'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267
-            EED_Single_Page_Checkout::get_reg_steps()
268
-        );
269
-        // sort by key (order)
270
-        ksort($reg_steps_to_load);
271
-        // loop through folders
272
-        foreach ($reg_steps_to_load as $order => $reg_step) {
273
-            // we need a
274
-            if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
275
-                // copy over to the reg_steps_array
276
-                EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
277
-                // register custom key route for each reg step
278
-                // ie: step=>"slug" - this is the entire reason we load the reg steps array now
279
-                EE_Config::register_route(
280
-                    $reg_step['slug'],
281
-                    'EED_Single_Page_Checkout',
282
-                    'run',
283
-                    'step'
284
-                );
285
-                // add AJAX or other hooks
286
-                if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
287
-                    // setup autoloaders if necessary
288
-                    if ( ! class_exists($reg_step['class_name'])) {
289
-                        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
290
-                            $reg_step['file_path'],
291
-                            true
292
-                        );
293
-                    }
294
-                    if (is_callable($reg_step['class_name'], 'set_hooks')) {
295
-                        call_user_func(array($reg_step['class_name'], 'set_hooks'));
296
-                    }
297
-                }
298
-            }
299
-        }
300
-        $reg_steps_loaded = true;
301
-    }
302
-
303
-
304
-
305
-    /**
306
-     *    get_reg_steps
307
-     *
308
-     * @access    public
309
-     * @return    array
310
-     */
311
-    public static function get_reg_steps()
312
-    {
313
-        $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
314
-        if (empty($reg_steps)) {
315
-            $reg_steps = array(
316
-                10  => array(
317
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
318
-                    'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319
-                    'slug'       => 'attendee_information',
320
-                    'has_hooks'  => false,
321
-                ),
322
-                20  => array(
323
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
324
-                    'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325
-                    'slug'       => 'registration_confirmation',
326
-                    'has_hooks'  => false,
327
-                ),
328
-                30  => array(
329
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
330
-                    'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331
-                    'slug'       => 'payment_options',
332
-                    'has_hooks'  => true,
333
-                ),
334
-                999 => array(
335
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
336
-                    'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337
-                    'slug'       => 'finalize_registration',
338
-                    'has_hooks'  => false,
339
-                ),
340
-            );
341
-        }
342
-        return $reg_steps;
343
-    }
344
-
345
-
346
-
347
-    /**
348
-     *    registration_checkout_for_admin
349
-     *
350
-     * @access    public
351
-     * @return    string
352
-     * @throws EE_Error
353
-     */
354
-    public static function registration_checkout_for_admin()
355
-    {
356
-        EED_Single_Page_Checkout::load_request_handler();
357
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
358
-        EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
359
-        EE_Registry::instance()->REQ->set('process_form_submission', false);
360
-        EED_Single_Page_Checkout::instance()->_initialize();
361
-        EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
362
-        return EE_Registry::instance()->REQ->get_output();
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     * process_registration_from_admin
369
-     *
370
-     * @access public
371
-     * @return \EE_Transaction
372
-     * @throws EE_Error
373
-     */
374
-    public static function process_registration_from_admin()
375
-    {
376
-        EED_Single_Page_Checkout::load_request_handler();
377
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
378
-        EE_Registry::instance()->REQ->set('action', 'process_reg_step');
379
-        EE_Registry::instance()->REQ->set('process_form_submission', true);
380
-        EED_Single_Page_Checkout::instance()->_initialize();
381
-        if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
382
-            $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
383
-            if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
384
-                EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
385
-                if ($final_reg_step->process_reg_step()) {
386
-                    $final_reg_step->set_completed();
387
-                    EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
388
-                    return EED_Single_Page_Checkout::instance()->checkout->transaction;
389
-                }
390
-            }
391
-        }
392
-        return null;
393
-    }
394
-
395
-
396
-
397
-    /**
398
-     *    run
399
-     *
400
-     * @access    public
401
-     * @param WP_Query $WP_Query
402
-     * @return    void
403
-     * @throws EE_Error
404
-     */
405
-    public function run($WP_Query)
406
-    {
407
-        if (
408
-            $WP_Query instanceof WP_Query
409
-            && $WP_Query->is_main_query()
410
-            && apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
411
-            && $this->_is_reg_checkout()
412
-        ) {
413
-            $this->_initialize();
414
-        }
415
-    }
416
-
417
-
418
-
419
-    /**
420
-     * determines whether current url matches reg page url
421
-     *
422
-     * @return bool
423
-     */
424
-    protected function _is_reg_checkout()
425
-    {
426
-        // get current permalink for reg page without any extra query args
427
-        $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
428
-        // get request URI for current request, but without the scheme or host
429
-        $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
430
-        $current_request_uri = html_entity_decode($current_request_uri);
431
-        // get array of query args from the current request URI
432
-        $query_args = \EEH_URL::get_query_string($current_request_uri);
433
-        // grab page id if it is set
434
-        $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
435
-        // and remove the page id from the query args (we will re-add it later)
436
-        unset($query_args['page_id']);
437
-        // now strip all query args from current request URI
438
-        $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
439
-        // and re-add the page id if it was set
440
-        if ($page_id) {
441
-            $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
442
-        }
443
-        // remove slashes and ?
444
-        $current_request_uri = trim($current_request_uri, '?/');
445
-        // is current request URI part of the known full reg page URL ?
446
-        return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
447
-    }
448
-
449
-
450
-
451
-    /**
452
-     * @param WP_Query $wp_query
453
-     * @return    void
454
-     * @throws EE_Error
455
-     */
456
-    public static function init($wp_query)
457
-    {
458
-        EED_Single_Page_Checkout::instance()->run($wp_query);
459
-    }
460
-
461
-
462
-
463
-    /**
464
-     *    _initialize - initial module setup
465
-     *
466
-     * @access    private
467
-     * @throws EE_Error
468
-     * @return    void
469
-     */
470
-    private function _initialize()
471
-    {
472
-        // ensure SPCO doesn't run twice
473
-        if (EED_Single_Page_Checkout::$_initialized) {
474
-            return;
475
-        }
476
-        try {
477
-            EED_Single_Page_Checkout::load_reg_steps();
478
-            $this->_verify_session();
479
-            // setup the EE_Checkout object
480
-            $this->checkout = $this->_initialize_checkout();
481
-            // filter checkout
482
-            $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
483
-            // get the $_GET
484
-            $this->_get_request_vars();
485
-            if ($this->_block_bots()) {
486
-                return;
487
-            }
488
-            // filter continue_reg
489
-            $this->checkout->continue_reg = apply_filters(
490
-                'FHEE__EED_Single_Page_Checkout__init___continue_reg',
491
-                true,
492
-                $this->checkout
493
-            );
494
-            // load the reg steps array
495
-            if ( ! $this->_load_and_instantiate_reg_steps()) {
496
-                EED_Single_Page_Checkout::$_initialized = true;
497
-                return;
498
-            }
499
-            // set the current step
500
-            $this->checkout->set_current_step($this->checkout->step);
501
-            // and the next step
502
-            $this->checkout->set_next_step();
503
-            // verify that everything has been setup correctly
504
-            if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
505
-                EED_Single_Page_Checkout::$_initialized = true;
506
-                return;
507
-            }
508
-            // lock the transaction
509
-            $this->checkout->transaction->lock();
510
-            // make sure all of our cached objects are added to their respective model entity mappers
511
-            $this->checkout->refresh_all_entities();
512
-            // set amount owing
513
-            $this->checkout->amount_owing = $this->checkout->transaction->remaining();
514
-            // initialize each reg step, which gives them the chance to potentially alter the process
515
-            $this->_initialize_reg_steps();
516
-            // DEBUG LOG
517
-            //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518
-            // get reg form
519
-            if( ! $this->_check_form_submission()) {
520
-                EED_Single_Page_Checkout::$_initialized = true;
521
-                return;
522
-            }
523
-            // checkout the action!!!
524
-            $this->_process_form_action();
525
-            // add some style and make it dance
526
-            $this->add_styles_and_scripts();
527
-            // kk... SPCO has successfully run
528
-            EED_Single_Page_Checkout::$_initialized = true;
529
-            // set no cache headers and constants
530
-            EE_System::do_not_cache();
531
-            // add anchor
532
-            add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
533
-            // remove transaction lock
534
-            add_action('shutdown', array($this, 'unlock_transaction'), 1);
535
-        } catch (Exception $e) {
536
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
537
-        }
538
-    }
539
-
540
-
541
-
542
-    /**
543
-     *    _verify_session
544
-     * checks that the session is valid and not expired
545
-     *
546
-     * @access    private
547
-     * @throws EE_Error
548
-     */
549
-    private function _verify_session()
550
-    {
551
-        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
552
-            throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
553
-        }
554
-        // is session still valid ?
555
-        if (
556
-            EE_Registry::instance()->SSN->expired()
557
-            && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
558
-        ) {
559
-            $this->checkout = new EE_Checkout();
560
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
561
-            // EE_Registry::instance()->SSN->reset_cart();
562
-            // EE_Registry::instance()->SSN->reset_checkout();
563
-            // EE_Registry::instance()->SSN->reset_transaction();
564
-            EE_Error::add_attention(
565
-                EE_Registry::$i18n_js_strings['registration_expiration_notice'],
566
-                __FILE__, __FUNCTION__, __LINE__
567
-            );
568
-            // EE_Registry::instance()->SSN->reset_expired();
569
-        }
570
-    }
571
-
572
-
573
-
574
-    /**
575
-     *    _initialize_checkout
576
-     * loads and instantiates EE_Checkout
577
-     *
578
-     * @access    private
579
-     * @throws EE_Error
580
-     * @return EE_Checkout
581
-     */
582
-    private function _initialize_checkout()
583
-    {
584
-        // look in session for existing checkout
585
-        /** @type EE_Checkout $checkout */
586
-        $checkout = EE_Registry::instance()->SSN->checkout();
587
-        // verify
588
-        if ( ! $checkout instanceof EE_Checkout) {
589
-            // instantiate EE_Checkout object for handling the properties of the current checkout process
590
-            $checkout = EE_Registry::instance()->load_file(
591
-                SPCO_INC_PATH,
592
-                'EE_Checkout',
593
-                'class', array(),
594
-                false
595
-            );
596
-        } else {
597
-            if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
598
-                $this->unlock_transaction();
599
-                wp_safe_redirect($checkout->redirect_url);
600
-                exit();
601
-            }
602
-        }
603
-        $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
604
-        // verify again
605
-        if ( ! $checkout instanceof EE_Checkout) {
606
-            throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
607
-        }
608
-        // reset anything that needs a clean slate for each request
609
-        $checkout->reset_for_current_request();
610
-        return $checkout;
611
-    }
612
-
613
-
614
-
615
-    /**
616
-     *    _get_request_vars
617
-     *
618
-     * @access    private
619
-     * @return    void
620
-     * @throws EE_Error
621
-     */
622
-    private function _get_request_vars()
623
-    {
624
-        // load classes
625
-        EED_Single_Page_Checkout::load_request_handler();
626
-        //make sure this request is marked as belonging to EE
627
-        EE_Registry::instance()->REQ->set_espresso_page(true);
628
-        // which step is being requested ?
629
-        $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
630
-        // which step is being edited ?
631
-        $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
632
-        // and what we're doing on the current step
633
-        $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
634
-        // timestamp
635
-        $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
636
-        // returning to edit ?
637
-        $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
638
-        // or some other kind of revisit ?
639
-        $this->checkout->revisit = filter_var(
640
-            EE_Registry::instance()->REQ->get('revisit', false),
641
-            FILTER_VALIDATE_BOOLEAN
642
-        );
643
-        // and whether or not to generate a reg form for this request
644
-        $this->checkout->generate_reg_form = filter_var(
645
-            EE_Registry::instance()->REQ->get('generate_reg_form', true),
646
-            FILTER_VALIDATE_BOOLEAN
647
-        );
648
-        // and whether or not to process a reg form submission for this request
649
-        $this->checkout->process_form_submission = filter_var(
650
-            EE_Registry::instance()->REQ->get(
651
-                'process_form_submission',
652
-                $this->checkout->action === 'process_reg_step'
653
-            ),
654
-            FILTER_VALIDATE_BOOLEAN
655
-        );
656
-        $this->checkout->process_form_submission = filter_var(
657
-            $this->checkout->action !== 'display_spco_reg_step'
658
-                ? $this->checkout->process_form_submission
659
-                : false,
660
-            FILTER_VALIDATE_BOOLEAN
661
-        );
662
-        // $this->_display_request_vars();
663
-    }
664
-
665
-
666
-
667
-    /**
668
-     *  _display_request_vars
669
-     *
670
-     * @access    protected
671
-     * @return    void
672
-     */
673
-    protected function _display_request_vars()
674
-    {
675
-        if ( ! WP_DEBUG) {
676
-            return;
677
-        }
678
-        EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
679
-        EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
680
-        EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
681
-        EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
682
-        EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
683
-        EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
684
-        EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
685
-        EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
686
-    }
687
-
688
-
689
-
690
-    /**
691
-     * _block_bots
692
-     * checks that the incoming request has either of the following set:
693
-     *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
694
-     *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
695
-     * so if you're not coming from the Ticket Selector nor returning for a valid IP...
696
-     * then where you coming from man?
697
-     *
698
-     * @return boolean
699
-     */
700
-    private function _block_bots()
701
-    {
702
-        $invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
703
-        if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
704
-            return true;
705
-        }
706
-        return false;
707
-    }
708
-
709
-
710
-
711
-    /**
712
-     *    _get_first_step
713
-     *  gets slug for first step in $_reg_steps_array
714
-     *
715
-     * @access    private
716
-     * @throws EE_Error
717
-     * @return    string
718
-     */
719
-    private function _get_first_step()
720
-    {
721
-        $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
722
-        return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
723
-    }
724
-
725
-
726
-
727
-    /**
728
-     *    _load_and_instantiate_reg_steps
729
-     *  instantiates each reg step based on the loaded reg_steps array
730
-     *
731
-     * @access    private
732
-     * @throws EE_Error
733
-     * @return    bool
734
-     */
735
-    private function _load_and_instantiate_reg_steps()
736
-    {
737
-        do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
738
-        // have reg_steps already been instantiated ?
739
-        if (
740
-            empty($this->checkout->reg_steps)
741
-            || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
742
-        ) {
743
-            // if not, then loop through raw reg steps array
744
-            foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
745
-                if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
746
-                    return false;
747
-                }
748
-            }
749
-            EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
750
-            EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
751
-            // skip the registration_confirmation page ?
752
-            if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
753
-                // just remove it from the reg steps array
754
-                $this->checkout->remove_reg_step('registration_confirmation', false);
755
-            } else if (
756
-                isset($this->checkout->reg_steps['registration_confirmation'])
757
-                && EE_Registry::instance()->CFG->registration->reg_confirmation_last
758
-            ) {
759
-                // set the order to something big like 100
760
-                $this->checkout->set_reg_step_order('registration_confirmation', 100);
761
-            }
762
-            // filter the array for good luck
763
-            $this->checkout->reg_steps = apply_filters(
764
-                'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
765
-                $this->checkout->reg_steps
766
-            );
767
-            // finally re-sort based on the reg step class order properties
768
-            $this->checkout->sort_reg_steps();
769
-        } else {
770
-            foreach ($this->checkout->reg_steps as $reg_step) {
771
-                // set all current step stati to FALSE
772
-                $reg_step->set_is_current_step(false);
773
-            }
774
-        }
775
-        if (empty($this->checkout->reg_steps)) {
776
-            EE_Error::add_error(
777
-                __('No Reg Steps were loaded..', 'event_espresso'),
778
-                __FILE__, __FUNCTION__, __LINE__
779
-            );
780
-            return false;
781
-        }
782
-        // make reg step details available to JS
783
-        $this->checkout->set_reg_step_JSON_info();
784
-        return true;
785
-    }
786
-
787
-
788
-
789
-    /**
790
-     *     _load_and_instantiate_reg_step
791
-     *
792
-     * @access    private
793
-     * @param array $reg_step
794
-     * @param int   $order
795
-     * @return bool
796
-     */
797
-    private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
798
-    {
799
-        // we need a file_path, class_name, and slug to add a reg step
800
-        if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
801
-            // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
802
-            if (
803
-                $this->checkout->reg_url_link
804
-                && $this->checkout->step !== $reg_step['slug']
805
-                && $reg_step['slug'] !== 'finalize_registration'
806
-                // normally at this point we would NOT load the reg step, but this filter can change that
807
-                && apply_filters(
808
-                    'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
809
-                    true,
810
-                    $reg_step,
811
-                    $this->checkout
812
-                )
813
-            ) {
814
-                return true;
815
-            }
816
-            // instantiate step class using file path and class name
817
-            $reg_step_obj = EE_Registry::instance()->load_file(
818
-                $reg_step['file_path'],
819
-                $reg_step['class_name'],
820
-                'class',
821
-                $this->checkout,
822
-                false
823
-            );
824
-            // did we gets the goods ?
825
-            if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
826
-                // set reg step order based on config
827
-                $reg_step_obj->set_order($order);
828
-                // add instantiated reg step object to the master reg steps array
829
-                $this->checkout->add_reg_step($reg_step_obj);
830
-            } else {
831
-                EE_Error::add_error(
832
-                    __('The current step could not be set.', 'event_espresso'),
833
-                    __FILE__, __FUNCTION__, __LINE__
834
-                );
835
-                return false;
836
-            }
837
-        } else {
838
-            if (WP_DEBUG) {
839
-                EE_Error::add_error(
840
-                    sprintf(
841
-                        __(
842
-                            'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
843
-                            'event_espresso'
844
-                        ),
845
-                        isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
846
-                        isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
847
-                        isset($reg_step['slug']) ? $reg_step['slug'] : '',
848
-                        '<ul>',
849
-                        '<li>',
850
-                        '</li>',
851
-                        '</ul>'
852
-                    ),
853
-                    __FILE__, __FUNCTION__, __LINE__
854
-                );
855
-            }
856
-            return false;
857
-        }
858
-        return true;
859
-    }
860
-
861
-
862
-    /**
863
-     * _verify_transaction_and_get_registrations
864
-     *
865
-     * @access private
866
-     * @return bool
867
-     * @throws InvalidDataTypeException
868
-     * @throws InvalidEntityException
869
-     * @throws EE_Error
870
-     */
871
-    private function _verify_transaction_and_get_registrations()
872
-    {
873
-        // was there already a valid transaction in the checkout from the session ?
874
-        if ( ! $this->checkout->transaction instanceof EE_Transaction) {
875
-            // get transaction from db or session
876
-            $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
877
-                ? $this->_get_transaction_and_cart_for_previous_visit()
878
-                : $this->_get_cart_for_current_session_and_setup_new_transaction();
879
-            if ( ! $this->checkout->transaction instanceof EE_Transaction) {
880
-                EE_Error::add_error(
881
-                    __('Your Registration and Transaction information could not be retrieved from the db.',
882
-                        'event_espresso'),
883
-                    __FILE__, __FUNCTION__, __LINE__
884
-                );
885
-                $this->checkout->transaction = EE_Transaction::new_instance();
886
-                // add some style and make it dance
887
-                $this->add_styles_and_scripts();
888
-                EED_Single_Page_Checkout::$_initialized = true;
889
-                return false;
890
-            }
891
-            // and the registrations for the transaction
892
-            $this->_get_registrations($this->checkout->transaction);
893
-        }
894
-        return true;
895
-    }
896
-
897
-
898
-
899
-    /**
900
-     * _get_transaction_and_cart_for_previous_visit
901
-     *
902
-     * @access private
903
-     * @return mixed EE_Transaction|NULL
904
-     */
905
-    private function _get_transaction_and_cart_for_previous_visit()
906
-    {
907
-        /** @var $TXN_model EEM_Transaction */
908
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
909
-        // because the reg_url_link is present in the request,
910
-        // this is a return visit to SPCO, so we'll get the transaction data from the db
911
-        $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
912
-        // verify transaction
913
-        if ($transaction instanceof EE_Transaction) {
914
-            // and get the cart that was used for that transaction
915
-            $this->checkout->cart = $this->_get_cart_for_transaction($transaction);
916
-            return $transaction;
917
-        }
918
-        EE_Error::add_error(
919
-            __('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'),
920
-            __FILE__, __FUNCTION__, __LINE__
921
-        );
922
-        return null;
923
-
924
-    }
925
-
926
-
927
-
928
-    /**
929
-     * _get_cart_for_transaction
930
-     *
931
-     * @access private
932
-     * @param EE_Transaction $transaction
933
-     * @return EE_Cart
934
-     */
935
-    private function _get_cart_for_transaction($transaction)
936
-    {
937
-        return $this->checkout->get_cart_for_transaction($transaction);
938
-    }
939
-
940
-
941
-
942
-    /**
943
-     * get_cart_for_transaction
944
-     *
945
-     * @access public
946
-     * @param EE_Transaction $transaction
947
-     * @return EE_Cart
948
-     */
949
-    public function get_cart_for_transaction(EE_Transaction $transaction)
950
-    {
951
-        return $this->checkout->get_cart_for_transaction($transaction);
952
-    }
953
-
954
-
955
-
956
-    /**
957
-     * _get_transaction_and_cart_for_current_session
958
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
959
-     *
960
-     * @access private
961
-     * @return EE_Transaction
962
-     * @throws EE_Error
963
-     */
964
-    private function _get_cart_for_current_session_and_setup_new_transaction()
965
-    {
966
-        //  if there's no transaction, then this is the FIRST visit to SPCO
967
-        // so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
968
-        $this->checkout->cart = $this->_get_cart_for_transaction(null);
969
-        // and then create a new transaction
970
-        $transaction = $this->_initialize_transaction();
971
-        // verify transaction
972
-        if ($transaction instanceof EE_Transaction) {
973
-            // save it so that we have an ID for other objects to use
974
-            $transaction->save();
975
-            // and save TXN data to the cart
976
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
977
-        } else {
978
-            EE_Error::add_error(
979
-                __('A Valid Transaction could not be initialized.', 'event_espresso'),
980
-                __FILE__, __FUNCTION__, __LINE__
981
-            );
982
-        }
983
-        return $transaction;
984
-    }
985
-
986
-
987
-
988
-    /**
989
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
990
-     *
991
-     * @access private
992
-     * @return mixed EE_Transaction|NULL
993
-     */
994
-    private function _initialize_transaction()
995
-    {
996
-        try {
997
-            // ensure cart totals have been calculated
998
-            $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
999
-            // grab the cart grand total
1000
-            $cart_total = $this->checkout->cart->get_cart_grand_total();
1001
-            // create new TXN
1002
-            $transaction = EE_Transaction::new_instance(
1003
-                array(
1004
-                    'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
1005
-                    'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
1006
-                    'TXN_paid'      => 0,
1007
-                    'STS_ID'        => EEM_Transaction::failed_status_code,
1008
-                )
1009
-            );
1010
-            // save it so that we have an ID for other objects to use
1011
-            $transaction->save();
1012
-            // set cron job for following up on TXNs after their session has expired
1013
-            EE_Cron_Tasks::schedule_expired_transaction_check(
1014
-                EE_Registry::instance()->SSN->expiration() + 1,
1015
-                $transaction->ID()
1016
-            );
1017
-            return $transaction;
1018
-        } catch (Exception $e) {
1019
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1020
-        }
1021
-        return null;
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * _get_registrations
1027
-     *
1028
-     * @access private
1029
-     * @param EE_Transaction $transaction
1030
-     * @return void
1031
-     * @throws InvalidDataTypeException
1032
-     * @throws InvalidEntityException
1033
-     * @throws EE_Error
1034
-     */
1035
-    private function _get_registrations(EE_Transaction $transaction)
1036
-    {
1037
-        // first step: grab the registrants  { : o
1038
-        $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
1039
-        // verify registrations have been set
1040
-        if (empty($registrations)) {
1041
-            // if no cached registrations, then check the db
1042
-            $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1043
-            // still nothing ? well as long as this isn't a revisit
1044
-            if (empty($registrations) && ! $this->checkout->revisit) {
1045
-                // generate new registrations from scratch
1046
-                $registrations = $this->_initialize_registrations($transaction);
1047
-            }
1048
-        }
1049
-        // sort by their original registration order
1050
-        usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1051
-        // then loop thru the array
1052
-        foreach ($registrations as $registration) {
1053
-            // verify each registration
1054
-            if ($registration instanceof EE_Registration) {
1055
-                // we display all attendee info for the primary registrant
1056
-                if ($this->checkout->reg_url_link === $registration->reg_url_link()
1057
-                    && $registration->is_primary_registrant()
1058
-                ) {
1059
-                    $this->checkout->primary_revisit = true;
1060
-                    break;
1061
-                }
1062
-                if ($this->checkout->revisit
1063
-                           && $this->checkout->reg_url_link !== $registration->reg_url_link()
1064
-                ) {
1065
-                    // but hide info if it doesn't belong to you
1066
-                    $transaction->clear_cache('Registration', $registration->ID());
1067
-                }
1068
-                $this->checkout->set_reg_status_updated($registration->ID(), false);
1069
-            }
1070
-        }
1071
-    }
1072
-
1073
-
1074
-    /**
1075
-     *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1076
-     *
1077
-     * @access private
1078
-     * @param EE_Transaction $transaction
1079
-     * @return    array
1080
-     * @throws InvalidDataTypeException
1081
-     * @throws InvalidEntityException
1082
-     * @throws EE_Error
1083
-     */
1084
-    private function _initialize_registrations(EE_Transaction $transaction)
1085
-    {
1086
-        $att_nmbr = 0;
1087
-        $registrations = array();
1088
-        if ($transaction instanceof EE_Transaction) {
1089
-            /** @type EE_Registration_Processor $registration_processor */
1090
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1091
-            $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1092
-            // now let's add the cart items to the $transaction
1093
-            foreach ($this->checkout->cart->get_tickets() as $line_item) {
1094
-                //do the following for each ticket of this type they selected
1095
-                for ($x = 1; $x <= $line_item->quantity(); $x++) {
1096
-                    $att_nmbr++;
1097
-                    /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1098
-                    $CreateRegistrationCommand = EE_Registry::instance()->create(
1099
-                        'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1100
-                        array(
1101
-                            $transaction,
1102
-                            $line_item,
1103
-                            $att_nmbr,
1104
-                            $this->checkout->total_ticket_count,
1105
-                        )
1106
-                    );
1107
-                    // override capabilities for frontend registrations
1108
-                    if ( ! is_admin()) {
1109
-                        $CreateRegistrationCommand->setCapCheck(
1110
-                            new PublicCapabilities('', 'create_new_registration')
1111
-                        );
1112
-                    }
1113
-                    $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1114
-                    if ( ! $registration instanceof EE_Registration) {
1115
-                        throw new InvalidEntityException($registration, 'EE_Registration');
1116
-                    }
1117
-                    $registrations[ $registration->ID() ] = $registration;
1118
-                }
1119
-            }
1120
-            $registration_processor->fix_reg_final_price_rounding_issue($transaction);
1121
-        }
1122
-        return $registrations;
1123
-    }
1124
-
1125
-
1126
-
1127
-    /**
1128
-     * sorts registrations by REG_count
1129
-     *
1130
-     * @access public
1131
-     * @param EE_Registration $reg_A
1132
-     * @param EE_Registration $reg_B
1133
-     * @return int
1134
-     */
1135
-    public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1136
-    {
1137
-        // this shouldn't ever happen within the same TXN, but oh well
1138
-        if ($reg_A->count() === $reg_B->count()) {
1139
-            return 0;
1140
-        }
1141
-        return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1142
-    }
1143
-
1144
-
1145
-
1146
-    /**
1147
-     *    _final_verifications
1148
-     * just makes sure that everything is set up correctly before proceeding
1149
-     *
1150
-     * @access    private
1151
-     * @return    bool
1152
-     * @throws EE_Error
1153
-     */
1154
-    private function _final_verifications()
1155
-    {
1156
-        // filter checkout
1157
-        $this->checkout = apply_filters(
1158
-            'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1159
-            $this->checkout
1160
-        );
1161
-        //verify that current step is still set correctly
1162
-        if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1163
-            EE_Error::add_error(
1164
-                __('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'),
1165
-                __FILE__,
1166
-                __FUNCTION__,
1167
-                __LINE__
1168
-            );
1169
-            return false;
1170
-        }
1171
-        // if returning to SPCO, then verify that primary registrant is set
1172
-        if ( ! empty($this->checkout->reg_url_link)) {
1173
-            $valid_registrant = $this->checkout->transaction->primary_registration();
1174
-            if ( ! $valid_registrant instanceof EE_Registration) {
1175
-                EE_Error::add_error(
1176
-                    __('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'),
1177
-                    __FILE__,
1178
-                    __FUNCTION__,
1179
-                    __LINE__
1180
-                );
1181
-                return false;
1182
-            }
1183
-            $valid_registrant = null;
1184
-            foreach (
1185
-                $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration
1186
-            ) {
1187
-                if (
1188
-                    $registration instanceof EE_Registration
1189
-                    && $registration->reg_url_link() === $this->checkout->reg_url_link
1190
-                ) {
1191
-                    $valid_registrant = $registration;
1192
-                }
1193
-            }
1194
-            if ( ! $valid_registrant instanceof EE_Registration) {
1195
-                // hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1196
-                if (EED_Single_Page_Checkout::$_checkout_verified) {
1197
-                    // clear the session, mark the checkout as unverified, and try again
1198
-                    EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1199
-                    EED_Single_Page_Checkout::$_initialized = false;
1200
-                    EED_Single_Page_Checkout::$_checkout_verified = false;
1201
-                    $this->_initialize();
1202
-                    EE_Error::reset_notices();
1203
-                    return false;
1204
-                }
1205
-                EE_Error::add_error(
1206
-                    __(
1207
-                        'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1208
-                        'event_espresso'
1209
-                    ),
1210
-                    __FILE__,
1211
-                    __FUNCTION__,
1212
-                    __LINE__
1213
-                );
1214
-                return false;
1215
-            }
1216
-        }
1217
-        // now that things have been kinda sufficiently verified,
1218
-        // let's add the checkout to the session so that it's available to other systems
1219
-        EE_Registry::instance()->SSN->set_checkout($this->checkout);
1220
-        return true;
1221
-    }
1222
-
1223
-
1224
-
1225
-    /**
1226
-     *    _initialize_reg_steps
1227
-     * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1228
-     * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1229
-     *
1230
-     * @access    private
1231
-     * @param bool $reinitializing
1232
-     * @throws EE_Error
1233
-     */
1234
-    private function _initialize_reg_steps($reinitializing = false)
1235
-    {
1236
-        $this->checkout->set_reg_step_initiated($this->checkout->current_step);
1237
-        // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1238
-        foreach ($this->checkout->reg_steps as $reg_step) {
1239
-            if ( ! $reg_step->initialize_reg_step()) {
1240
-                // if not initialized then maybe this step is being removed...
1241
-                if ( ! $reinitializing && $reg_step->is_current_step()) {
1242
-                    // if it was the current step, then we need to start over here
1243
-                    $this->_initialize_reg_steps(true);
1244
-                    return;
1245
-                }
1246
-                continue;
1247
-            }
1248
-            // add css and JS for current step
1249
-            $reg_step->enqueue_styles_and_scripts();
1250
-            // i18n
1251
-            $reg_step->translate_js_strings();
1252
-            if ($reg_step->is_current_step()) {
1253
-                // the text that appears on the reg step form submit button
1254
-                $reg_step->set_submit_button_text();
1255
-            }
1256
-        }
1257
-        // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1258
-        do_action(
1259
-            "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1260
-            $this->checkout->current_step
1261
-        );
1262
-    }
1263
-
1264
-
1265
-
1266
-    /**
1267
-     * _check_form_submission
1268
-     *
1269
-     * @access private
1270
-     * @return boolean
1271
-     */
1272
-    private function _check_form_submission()
1273
-    {
1274
-        //does this request require the reg form to be generated ?
1275
-        if ($this->checkout->generate_reg_form) {
1276
-            // ever heard that song by Blue Rodeo ?
1277
-            try {
1278
-                $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1279
-                // if not displaying a form, then check for form submission
1280
-                if (
1281
-                    $this->checkout->process_form_submission
1282
-                    && $this->checkout->current_step->reg_form->was_submitted()
1283
-                ) {
1284
-                    // clear out any old data in case this step is being run again
1285
-                    $this->checkout->current_step->set_valid_data(array());
1286
-                    // capture submitted form data
1287
-                    $this->checkout->current_step->reg_form->receive_form_submission(
1288
-                        apply_filters(
1289
-                            'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1290
-                            EE_Registry::instance()->REQ->params(),
1291
-                            $this->checkout
1292
-                        )
1293
-                    );
1294
-                    // validate submitted form data
1295
-                    if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1296
-                        // thou shall not pass !!!
1297
-                        $this->checkout->continue_reg = false;
1298
-                        // any form validation errors?
1299
-                        if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1300
-                            $submission_error_messages = array();
1301
-                            // bad, bad, bad registrant
1302
-                            foreach (
1303
-                                $this->checkout->current_step->reg_form->get_validation_errors_accumulated()
1304
-                                as $validation_error
1305
-                            ) {
1306
-                                if ($validation_error instanceof EE_Validation_Error) {
1307
-                                    $submission_error_messages[] = sprintf(
1308
-                                        __('%s : %s', 'event_espresso'),
1309
-                                        $validation_error->get_form_section()->html_label_text(),
1310
-                                        $validation_error->getMessage()
1311
-                                    );
1312
-                                }
1313
-                            }
1314
-                            EE_Error::add_error(
1315
-                                implode('<br />', $submission_error_messages),
1316
-                                __FILE__, __FUNCTION__, __LINE__
1317
-                            );
1318
-                        }
1319
-                        // well not really... what will happen is
1320
-                        // we'll just get redirected back to redo the current step
1321
-                        $this->go_to_next_step();
1322
-                        return false;
1323
-                    }
1324
-                }
1325
-            } catch (EE_Error $e) {
1326
-                $e->get_error();
1327
-            }
1328
-        }
1329
-        return true;
1330
-    }
1331
-
1332
-
1333
-
1334
-    /**
1335
-     * _process_action
1336
-     *
1337
-     * @access private
1338
-     * @return void
1339
-     * @throws EE_Error
1340
-     */
1341
-    private function _process_form_action()
1342
-    {
1343
-        // what cha wanna do?
1344
-        switch ($this->checkout->action) {
1345
-            // AJAX next step reg form
1346
-            case 'display_spco_reg_step' :
1347
-                $this->checkout->redirect = false;
1348
-                if (EE_Registry::instance()->REQ->ajax) {
1349
-                    $this->checkout->json_response->set_reg_step_html(
1350
-                        $this->checkout->current_step->display_reg_form()
1351
-                    );
1352
-                }
1353
-                break;
1354
-            default :
1355
-                // meh... do one of those other steps first
1356
-                if (
1357
-                    ! empty($this->checkout->action)
1358
-                    && is_callable(array($this->checkout->current_step, $this->checkout->action))
1359
-                ) {
1360
-                    // dynamically creates hook point like:
1361
-                    //   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1362
-                    do_action(
1363
-                        "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1364
-                        $this->checkout->current_step
1365
-                    );
1366
-                    // call action on current step
1367
-                    if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1368
-                        // good registrant, you get to proceed
1369
-                        if (
1370
-                            $this->checkout->current_step->success_message() !== ''
1371
-                            && apply_filters(
1372
-                                'FHEE__Single_Page_Checkout___process_form_action__display_success',
1373
-                                false
1374
-                            )
1375
-                        ) {
1376
-                            EE_Error::add_success(
1377
-                                $this->checkout->current_step->success_message()
1378
-                                . '<br />' . $this->checkout->next_step->_instructions()
1379
-                            );
1380
-                        }
1381
-                        // pack it up, pack it in...
1382
-                        $this->_setup_redirect();
1383
-                    }
1384
-                    // dynamically creates hook point like:
1385
-                    //  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1386
-                    do_action(
1387
-                        "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1388
-                        $this->checkout->current_step
1389
-                    );
1390
-                } else {
1391
-                    EE_Error::add_error(
1392
-                        sprintf(
1393
-                            __(
1394
-                                'The requested form action "%s" does not exist for the current "%s" registration step.',
1395
-                                'event_espresso'
1396
-                            ),
1397
-                            $this->checkout->action,
1398
-                            $this->checkout->current_step->name()
1399
-                        ),
1400
-                        __FILE__,
1401
-                        __FUNCTION__,
1402
-                        __LINE__
1403
-                    );
1404
-                }
1405
-            // end default
1406
-        }
1407
-        // store our progress so far
1408
-        $this->checkout->stash_transaction_and_checkout();
1409
-        // advance to the next step! If you pass GO, collect $200
1410
-        $this->go_to_next_step();
1411
-    }
1412
-
1413
-
1414
-
1415
-    /**
1416
-     *        add_styles_and_scripts
1417
-     *
1418
-     * @access        public
1419
-     * @return        void
1420
-     */
1421
-    public function add_styles_and_scripts()
1422
-    {
1423
-        // i18n
1424
-        $this->translate_js_strings();
1425
-        if ($this->checkout->admin_request) {
1426
-            add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1427
-        } else {
1428
-            add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1429
-        }
1430
-    }
1431
-
1432
-
1433
-
1434
-    /**
1435
-     *        translate_js_strings
1436
-     *
1437
-     * @access        public
1438
-     * @return        void
1439
-     */
1440
-    public function translate_js_strings()
1441
-    {
1442
-        EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1443
-        EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1444
-        EE_Registry::$i18n_js_strings['server_error'] = __(
1445
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1446
-            'event_espresso'
1447
-        );
1448
-        EE_Registry::$i18n_js_strings['invalid_json_response'] = __(
1449
-            'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1450
-            'event_espresso'
1451
-        );
1452
-        EE_Registry::$i18n_js_strings['validation_error'] = __(
1453
-            'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1454
-            'event_espresso'
1455
-        );
1456
-        EE_Registry::$i18n_js_strings['invalid_payment_method'] = __(
1457
-            'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1458
-            'event_espresso'
1459
-        );
1460
-        EE_Registry::$i18n_js_strings['reg_step_error'] = __(
1461
-            'This registration step could not be completed. Please refresh the page and try again.',
1462
-            'event_espresso'
1463
-        );
1464
-        EE_Registry::$i18n_js_strings['invalid_coupon'] = __(
1465
-            'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1466
-            'event_espresso'
1467
-        );
1468
-        EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1469
-            __(
1470
-                'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1471
-                'event_espresso'
1472
-            ),
1473
-            '<br/>',
1474
-            '<br/>'
1475
-        );
1476
-        EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1477
-        EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1478
-        EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1479
-        EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1480
-        EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1481
-        EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1482
-        EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1483
-        EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1484
-        EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1485
-        EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1486
-        EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1487
-        EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1488
-        EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1489
-        EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1490
-        EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1491
-        EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1492
-        EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1493
-        EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1494
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1495
-            __(
1496
-                '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
1497
-                'event_espresso'
1498
-            ),
1499
-            '<h4 class="important-notice">',
1500
-            '</h4>',
1501
-            '<br />',
1502
-            '<p>',
1503
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1504
-            '">',
1505
-            '</a>',
1506
-            '</p>'
1507
-        );
1508
-        EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters(
1509
-            'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1510
-            true
1511
-        );
1512
-        EE_Registry::$i18n_js_strings['session_extension'] = absint(
1513
-            apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1514
-        );
1515
-        EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1516
-            'M d, Y H:i:s',
1517
-            EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1518
-        );
1519
-    }
1520
-
1521
-
1522
-
1523
-    /**
1524
-     *    enqueue_styles_and_scripts
1525
-     *
1526
-     * @access        public
1527
-     * @return        void
1528
-     * @throws EE_Error
1529
-     */
1530
-    public function enqueue_styles_and_scripts()
1531
-    {
1532
-        // load css
1533
-        wp_register_style(
1534
-            'single_page_checkout',
1535
-            SPCO_CSS_URL . 'single_page_checkout.css',
1536
-            array('espresso_default'),
1537
-            EVENT_ESPRESSO_VERSION
1538
-        );
1539
-        wp_enqueue_style('single_page_checkout');
1540
-        // load JS
1541
-        wp_register_script(
1542
-            'jquery_plugin',
1543
-            EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1544
-            array('jquery'),
1545
-            '1.0.1',
1546
-            true
1547
-        );
1548
-        wp_register_script(
1549
-            'jquery_countdown',
1550
-            EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1551
-            array('jquery_plugin'),
1552
-            '2.0.2',
1553
-            true
1554
-        );
1555
-        wp_register_script(
1556
-            'single_page_checkout',
1557
-            SPCO_JS_URL . 'single_page_checkout.js',
1558
-            array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1559
-            EVENT_ESPRESSO_VERSION,
1560
-            true
1561
-        );
1562
-        if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1563
-            $this->checkout->registration_form->enqueue_js();
1564
-        }
1565
-        if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1566
-            $this->checkout->current_step->reg_form->enqueue_js();
1567
-        }
1568
-        wp_enqueue_script('single_page_checkout');
1569
-        /**
1570
-         * global action hook for enqueueing styles and scripts with
1571
-         * spco calls.
1572
-         */
1573
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1574
-        /**
1575
-         * dynamic action hook for enqueueing styles and scripts with spco calls.
1576
-         * The hook will end up being something like:
1577
-         *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1578
-         */
1579
-        do_action(
1580
-            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1581
-            $this
1582
-        );
1583
-    }
1584
-
1585
-
1586
-
1587
-    /**
1588
-     *    display the Registration Single Page Checkout Form
1589
-     *
1590
-     * @access    private
1591
-     * @return    void
1592
-     * @throws EE_Error
1593
-     */
1594
-    private function _display_spco_reg_form()
1595
-    {
1596
-        // if registering via the admin, just display the reg form for the current step
1597
-        if ($this->checkout->admin_request) {
1598
-            EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1599
-        } else {
1600
-            // add powered by EE msg
1601
-            add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1602
-            $empty_cart = count(
1603
-                $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1604
-            ) < 1;
1605
-            EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1606
-            $cookies_not_set_msg = '';
1607
-            if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1608
-                $cookies_not_set_msg = apply_filters(
1609
-                    'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1610
-                    sprintf(
1611
-                        __(
1612
-                            '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1613
-                            'event_espresso'
1614
-                        ),
1615
-                        '<div class="ee-attention">',
1616
-                        '</div>',
1617
-                        '<h6 class="important-notice">',
1618
-                        '</h6>',
1619
-                        '<p>',
1620
-                        '</p>',
1621
-                        '<br />',
1622
-                        '<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1623
-                        '</a>'
1624
-                    )
1625
-                );
1626
-            }
1627
-            $this->checkout->registration_form = new EE_Form_Section_Proper(
1628
-                array(
1629
-                    'name'            => 'single-page-checkout',
1630
-                    'html_id'         => 'ee-single-page-checkout-dv',
1631
-                    'layout_strategy' =>
1632
-                        new EE_Template_Layout(
1633
-                            array(
1634
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1635
-                                'template_args'        => array(
1636
-                                    'empty_cart'              => $empty_cart,
1637
-                                    'revisit'                 => $this->checkout->revisit,
1638
-                                    'reg_steps'               => $this->checkout->reg_steps,
1639
-                                    'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1640
-                                        ? $this->checkout->next_step->slug()
1641
-                                        : '',
1642
-                                    'cancel_page_url'         => $this->checkout->cancel_page_url,
1643
-                                    'empty_msg'               => apply_filters(
1644
-                                        'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1645
-                                        sprintf(
1646
-                                            __(
1647
-                                                'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1648
-                                                'event_espresso'
1649
-                                            ),
1650
-                                            '<a href="'
1651
-                                            . get_post_type_archive_link('espresso_events')
1652
-                                            . '" title="',
1653
-                                            '">',
1654
-                                            '</a>'
1655
-                                        )
1656
-                                    ),
1657
-                                    'cookies_not_set_msg'     => $cookies_not_set_msg,
1658
-                                    'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1659
-                                    'session_expiration'      => gmdate(
1660
-                                        'M d, Y H:i:s',
1661
-                                        EE_Registry::instance()->SSN->expiration()
1662
-                                        + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1663
-                                    ),
1664
-                                ),
1665
-                            )
1666
-                        ),
1667
-                )
1668
-            );
1669
-            // load template and add to output sent that gets filtered into the_content()
1670
-            EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1671
-        }
1672
-    }
1673
-
1674
-
1675
-
1676
-    /**
1677
-     *    add_extra_finalize_registration_inputs
1678
-     *
1679
-     * @access    public
1680
-     * @param $next_step
1681
-     * @internal  param string $label
1682
-     * @return void
1683
-     */
1684
-    public function add_extra_finalize_registration_inputs($next_step)
1685
-    {
1686
-        if ($next_step === 'finalize_registration') {
1687
-            echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1688
-        }
1689
-    }
1690
-
1691
-
1692
-
1693
-    /**
1694
-     *    display_registration_footer
1695
-     *
1696
-     * @access    public
1697
-     * @return    string
1698
-     */
1699
-    public static function display_registration_footer()
1700
-    {
1701
-        if (
1702
-        apply_filters(
1703
-            'FHEE__EE_Front__Controller__show_reg_footer',
1704
-            EE_Registry::instance()->CFG->admin->show_reg_footer
1705
-        )
1706
-        ) {
1707
-            add_filter(
1708
-                'FHEE__EEH_Template__powered_by_event_espresso__url',
1709
-                function ($url) {
1710
-                    return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1711
-                }
1712
-            );
1713
-            echo apply_filters(
1714
-                'FHEE__EE_Front_Controller__display_registration_footer',
1715
-                \EEH_Template::powered_by_event_espresso(
1716
-                    '',
1717
-                    'espresso-registration-footer-dv',
1718
-                    array('utm_content' => 'registration_checkout')
1719
-                )
1720
-            );
1721
-        }
1722
-        return '';
1723
-    }
1724
-
1725
-
1726
-
1727
-    /**
1728
-     *    unlock_transaction
1729
-     *
1730
-     * @access    public
1731
-     * @return    void
1732
-     * @throws EE_Error
1733
-     */
1734
-    public function unlock_transaction()
1735
-    {
1736
-        if ($this->checkout->transaction instanceof EE_Transaction) {
1737
-            $this->checkout->transaction->unlock();
1738
-        }
1739
-    }
1740
-
1741
-
1742
-
1743
-    /**
1744
-     *        _setup_redirect
1745
-     *
1746
-     * @access    private
1747
-     * @return void
1748
-     */
1749
-    private function _setup_redirect()
1750
-    {
1751
-        if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1752
-            $this->checkout->redirect = true;
1753
-            if (empty($this->checkout->redirect_url)) {
1754
-                $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1755
-            }
1756
-            $this->checkout->redirect_url = apply_filters(
1757
-                'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1758
-                $this->checkout->redirect_url,
1759
-                $this->checkout
1760
-            );
1761
-        }
1762
-    }
1763
-
1764
-
1765
-
1766
-    /**
1767
-     *   handle ajax message responses and redirects
1768
-     *
1769
-     * @access public
1770
-     * @return void
1771
-     * @throws EE_Error
1772
-     */
1773
-    public function go_to_next_step()
1774
-    {
1775
-        if (EE_Registry::instance()->REQ->ajax) {
1776
-            // capture contents of output buffer we started earlier in the request, and insert into JSON response
1777
-            $this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1778
-        }
1779
-        $this->unlock_transaction();
1780
-        // just return for these conditions
1781
-        if (
1782
-            $this->checkout->admin_request
1783
-            || $this->checkout->action === 'redirect_form'
1784
-            || $this->checkout->action === 'update_checkout'
1785
-        ) {
1786
-            return;
1787
-        }
1788
-        // AJAX response
1789
-        $this->_handle_json_response();
1790
-        // redirect to next step or the Thank You page
1791
-        $this->_handle_html_redirects();
1792
-        // hmmm... must be something wrong, so let's just display the form again !
1793
-        $this->_display_spco_reg_form();
1794
-    }
1795
-
1796
-
1797
-
1798
-    /**
1799
-     *   _handle_json_response
1800
-     *
1801
-     * @access protected
1802
-     * @return void
1803
-     */
1804
-    protected function _handle_json_response()
1805
-    {
1806
-        // if this is an ajax request
1807
-        if (EE_Registry::instance()->REQ->ajax) {
1808
-            // DEBUG LOG
1809
-            //$this->checkout->log(
1810
-            //	__CLASS__, __FUNCTION__, __LINE__,
1811
-            //	array(
1812
-            //		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1813
-            //		'redirect'                   => $this->checkout->redirect,
1814
-            //		'continue_reg'               => $this->checkout->continue_reg,
1815
-            //	)
1816
-            //);
1817
-            $this->checkout->json_response->set_registration_time_limit(
1818
-                $this->checkout->get_registration_time_limit()
1819
-            );
1820
-            $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1821
-            // just send the ajax (
1822
-            $json_response = apply_filters(
1823
-                'FHEE__EE_Single_Page_Checkout__JSON_response',
1824
-                $this->checkout->json_response
1825
-            );
1826
-            echo $json_response;
1827
-            exit();
1828
-        }
1829
-    }
1830
-
1831
-
1832
-
1833
-    /**
1834
-     *   _handle_redirects
1835
-     *
1836
-     * @access protected
1837
-     * @return void
1838
-     */
1839
-    protected function _handle_html_redirects()
1840
-    {
1841
-        // going somewhere ?
1842
-        if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1843
-            // store notices in a transient
1844
-            EE_Error::get_notices(false, true, true);
1845
-            // DEBUG LOG
1846
-            //$this->checkout->log(
1847
-            //	__CLASS__, __FUNCTION__, __LINE__,
1848
-            //	array(
1849
-            //		'headers_sent' => headers_sent(),
1850
-            //		'redirect_url'     => $this->checkout->redirect_url,
1851
-            //		'headers_list'    => headers_list(),
1852
-            //	)
1853
-            //);
1854
-            wp_safe_redirect($this->checkout->redirect_url);
1855
-            exit();
1856
-        }
1857
-    }
1858
-
1859
-
1860
-
1861
-    /**
1862
-     *   set_checkout_anchor
1863
-     *
1864
-     * @access public
1865
-     * @return void
1866
-     */
1867
-    public function set_checkout_anchor()
1868
-    {
1869
-        echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1870
-    }
23
+	/**
24
+	 * $_initialized - has the SPCO controller already been initialized ?
25
+	 *
26
+	 * @access private
27
+	 * @var bool $_initialized
28
+	 */
29
+	private static $_initialized = false;
30
+
31
+
32
+	/**
33
+	 * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
34
+	 *
35
+	 * @access private
36
+	 * @var bool $_valid_checkout
37
+	 */
38
+	private static $_checkout_verified = true;
39
+
40
+	/**
41
+	 *    $_reg_steps_array - holds initial array of reg steps
42
+	 *
43
+	 * @access private
44
+	 * @var array $_reg_steps_array
45
+	 */
46
+	private static $_reg_steps_array = array();
47
+
48
+	/**
49
+	 *    $checkout - EE_Checkout object for handling the properties of the current checkout process
50
+	 *
51
+	 * @access public
52
+	 * @var EE_Checkout $checkout
53
+	 */
54
+	public $checkout;
55
+
56
+
57
+
58
+	/**
59
+	 * @return EED_Module|EED_Single_Page_Checkout
60
+	 */
61
+	public static function instance()
62
+	{
63
+		add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
64
+		return parent::get_instance(__CLASS__);
65
+	}
66
+
67
+
68
+
69
+	/**
70
+	 * @return EE_CART
71
+	 */
72
+	public function cart()
73
+	{
74
+		return $this->checkout->cart;
75
+	}
76
+
77
+
78
+
79
+	/**
80
+	 * @return EE_Transaction
81
+	 */
82
+	public function transaction()
83
+	{
84
+		return $this->checkout->transaction;
85
+	}
86
+
87
+
88
+
89
+	/**
90
+	 *    set_hooks - for hooking into EE Core, other modules, etc
91
+	 *
92
+	 * @access    public
93
+	 * @return    void
94
+	 * @throws EE_Error
95
+	 */
96
+	public static function set_hooks()
97
+	{
98
+		EED_Single_Page_Checkout::set_definitions();
99
+	}
100
+
101
+
102
+
103
+	/**
104
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
+	 *
106
+	 * @access    public
107
+	 * @return    void
108
+	 * @throws EE_Error
109
+	 */
110
+	public static function set_hooks_admin()
111
+	{
112
+		EED_Single_Page_Checkout::set_definitions();
113
+		if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
114
+			return;
115
+		}
116
+		// going to start an output buffer in case anything gets accidentally output
117
+		// that might disrupt our JSON response
118
+		ob_start();
119
+		EED_Single_Page_Checkout::load_request_handler();
120
+		EED_Single_Page_Checkout::load_reg_steps();
121
+		// set ajax hooks
122
+		add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
123
+		add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
124
+		add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
125
+		add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
126
+		add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
127
+		add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
128
+	}
129
+
130
+
131
+
132
+	/**
133
+	 *    process ajax request
134
+	 *
135
+	 * @param string $ajax_action
136
+	 * @throws EE_Error
137
+	 */
138
+	public static function process_ajax_request($ajax_action)
139
+	{
140
+		EE_Registry::instance()->REQ->set('action', $ajax_action);
141
+		EED_Single_Page_Checkout::instance()->_initialize();
142
+	}
143
+
144
+
145
+
146
+	/**
147
+	 *    ajax display registration step
148
+	 *
149
+	 * @throws EE_Error
150
+	 */
151
+	public static function display_reg_step()
152
+	{
153
+		EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
154
+	}
155
+
156
+
157
+
158
+	/**
159
+	 *    ajax process registration step
160
+	 *
161
+	 * @throws EE_Error
162
+	 */
163
+	public static function process_reg_step()
164
+	{
165
+		EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
166
+	}
167
+
168
+
169
+
170
+	/**
171
+	 *    ajax process registration step
172
+	 *
173
+	 * @throws EE_Error
174
+	 */
175
+	public static function update_reg_step()
176
+	{
177
+		EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
178
+	}
179
+
180
+
181
+
182
+	/**
183
+	 *   update_checkout
184
+	 *
185
+	 * @access public
186
+	 * @return void
187
+	 * @throws EE_Error
188
+	 */
189
+	public static function update_checkout()
190
+	{
191
+		EED_Single_Page_Checkout::process_ajax_request('update_checkout');
192
+	}
193
+
194
+
195
+
196
+	/**
197
+	 *    load_request_handler
198
+	 *
199
+	 * @access    public
200
+	 * @return    void
201
+	 */
202
+	public static function load_request_handler()
203
+	{
204
+		// load core Request_Handler class
205
+		if (EE_Registry::instance()->REQ !== null) {
206
+			EE_Registry::instance()->load_core('Request_Handler');
207
+		}
208
+	}
209
+
210
+
211
+
212
+	/**
213
+	 *    set_definitions
214
+	 *
215
+	 * @access    public
216
+	 * @return    void
217
+	 * @throws EE_Error
218
+	 */
219
+	public static function set_definitions()
220
+	{
221
+		if(defined('SPCO_BASE_PATH')) {
222
+			return;
223
+		}
224
+		define(
225
+			'SPCO_BASE_PATH',
226
+			rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
227
+		);
228
+		define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
+		define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
+		define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
+		define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
+		define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
+		define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
234
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236
+			__('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
237
+				'event_espresso'),
238
+			'<h4 class="important-notice">',
239
+			'</h4>',
240
+			'<br />',
241
+			'<p>',
242
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
243
+			'">',
244
+			'</a>',
245
+			'</p>'
246
+		);
247
+	}
248
+
249
+
250
+
251
+	/**
252
+	 * load_reg_steps
253
+	 * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
254
+	 *
255
+	 * @access    private
256
+	 * @throws EE_Error
257
+	 */
258
+	public static function load_reg_steps()
259
+	{
260
+		static $reg_steps_loaded = false;
261
+		if ($reg_steps_loaded) {
262
+			return;
263
+		}
264
+		// filter list of reg_steps
265
+		$reg_steps_to_load = (array)apply_filters(
266
+			'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267
+			EED_Single_Page_Checkout::get_reg_steps()
268
+		);
269
+		// sort by key (order)
270
+		ksort($reg_steps_to_load);
271
+		// loop through folders
272
+		foreach ($reg_steps_to_load as $order => $reg_step) {
273
+			// we need a
274
+			if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
275
+				// copy over to the reg_steps_array
276
+				EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
277
+				// register custom key route for each reg step
278
+				// ie: step=>"slug" - this is the entire reason we load the reg steps array now
279
+				EE_Config::register_route(
280
+					$reg_step['slug'],
281
+					'EED_Single_Page_Checkout',
282
+					'run',
283
+					'step'
284
+				);
285
+				// add AJAX or other hooks
286
+				if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
287
+					// setup autoloaders if necessary
288
+					if ( ! class_exists($reg_step['class_name'])) {
289
+						EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
290
+							$reg_step['file_path'],
291
+							true
292
+						);
293
+					}
294
+					if (is_callable($reg_step['class_name'], 'set_hooks')) {
295
+						call_user_func(array($reg_step['class_name'], 'set_hooks'));
296
+					}
297
+				}
298
+			}
299
+		}
300
+		$reg_steps_loaded = true;
301
+	}
302
+
303
+
304
+
305
+	/**
306
+	 *    get_reg_steps
307
+	 *
308
+	 * @access    public
309
+	 * @return    array
310
+	 */
311
+	public static function get_reg_steps()
312
+	{
313
+		$reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
314
+		if (empty($reg_steps)) {
315
+			$reg_steps = array(
316
+				10  => array(
317
+					'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
318
+					'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319
+					'slug'       => 'attendee_information',
320
+					'has_hooks'  => false,
321
+				),
322
+				20  => array(
323
+					'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
324
+					'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325
+					'slug'       => 'registration_confirmation',
326
+					'has_hooks'  => false,
327
+				),
328
+				30  => array(
329
+					'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
330
+					'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331
+					'slug'       => 'payment_options',
332
+					'has_hooks'  => true,
333
+				),
334
+				999 => array(
335
+					'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
336
+					'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337
+					'slug'       => 'finalize_registration',
338
+					'has_hooks'  => false,
339
+				),
340
+			);
341
+		}
342
+		return $reg_steps;
343
+	}
344
+
345
+
346
+
347
+	/**
348
+	 *    registration_checkout_for_admin
349
+	 *
350
+	 * @access    public
351
+	 * @return    string
352
+	 * @throws EE_Error
353
+	 */
354
+	public static function registration_checkout_for_admin()
355
+	{
356
+		EED_Single_Page_Checkout::load_request_handler();
357
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
358
+		EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
359
+		EE_Registry::instance()->REQ->set('process_form_submission', false);
360
+		EED_Single_Page_Checkout::instance()->_initialize();
361
+		EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
362
+		return EE_Registry::instance()->REQ->get_output();
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 * process_registration_from_admin
369
+	 *
370
+	 * @access public
371
+	 * @return \EE_Transaction
372
+	 * @throws EE_Error
373
+	 */
374
+	public static function process_registration_from_admin()
375
+	{
376
+		EED_Single_Page_Checkout::load_request_handler();
377
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
378
+		EE_Registry::instance()->REQ->set('action', 'process_reg_step');
379
+		EE_Registry::instance()->REQ->set('process_form_submission', true);
380
+		EED_Single_Page_Checkout::instance()->_initialize();
381
+		if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
382
+			$final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
383
+			if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
384
+				EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
385
+				if ($final_reg_step->process_reg_step()) {
386
+					$final_reg_step->set_completed();
387
+					EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
388
+					return EED_Single_Page_Checkout::instance()->checkout->transaction;
389
+				}
390
+			}
391
+		}
392
+		return null;
393
+	}
394
+
395
+
396
+
397
+	/**
398
+	 *    run
399
+	 *
400
+	 * @access    public
401
+	 * @param WP_Query $WP_Query
402
+	 * @return    void
403
+	 * @throws EE_Error
404
+	 */
405
+	public function run($WP_Query)
406
+	{
407
+		if (
408
+			$WP_Query instanceof WP_Query
409
+			&& $WP_Query->is_main_query()
410
+			&& apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
411
+			&& $this->_is_reg_checkout()
412
+		) {
413
+			$this->_initialize();
414
+		}
415
+	}
416
+
417
+
418
+
419
+	/**
420
+	 * determines whether current url matches reg page url
421
+	 *
422
+	 * @return bool
423
+	 */
424
+	protected function _is_reg_checkout()
425
+	{
426
+		// get current permalink for reg page without any extra query args
427
+		$reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
428
+		// get request URI for current request, but without the scheme or host
429
+		$current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
430
+		$current_request_uri = html_entity_decode($current_request_uri);
431
+		// get array of query args from the current request URI
432
+		$query_args = \EEH_URL::get_query_string($current_request_uri);
433
+		// grab page id if it is set
434
+		$page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
435
+		// and remove the page id from the query args (we will re-add it later)
436
+		unset($query_args['page_id']);
437
+		// now strip all query args from current request URI
438
+		$current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
439
+		// and re-add the page id if it was set
440
+		if ($page_id) {
441
+			$current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
442
+		}
443
+		// remove slashes and ?
444
+		$current_request_uri = trim($current_request_uri, '?/');
445
+		// is current request URI part of the known full reg page URL ?
446
+		return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
447
+	}
448
+
449
+
450
+
451
+	/**
452
+	 * @param WP_Query $wp_query
453
+	 * @return    void
454
+	 * @throws EE_Error
455
+	 */
456
+	public static function init($wp_query)
457
+	{
458
+		EED_Single_Page_Checkout::instance()->run($wp_query);
459
+	}
460
+
461
+
462
+
463
+	/**
464
+	 *    _initialize - initial module setup
465
+	 *
466
+	 * @access    private
467
+	 * @throws EE_Error
468
+	 * @return    void
469
+	 */
470
+	private function _initialize()
471
+	{
472
+		// ensure SPCO doesn't run twice
473
+		if (EED_Single_Page_Checkout::$_initialized) {
474
+			return;
475
+		}
476
+		try {
477
+			EED_Single_Page_Checkout::load_reg_steps();
478
+			$this->_verify_session();
479
+			// setup the EE_Checkout object
480
+			$this->checkout = $this->_initialize_checkout();
481
+			// filter checkout
482
+			$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
483
+			// get the $_GET
484
+			$this->_get_request_vars();
485
+			if ($this->_block_bots()) {
486
+				return;
487
+			}
488
+			// filter continue_reg
489
+			$this->checkout->continue_reg = apply_filters(
490
+				'FHEE__EED_Single_Page_Checkout__init___continue_reg',
491
+				true,
492
+				$this->checkout
493
+			);
494
+			// load the reg steps array
495
+			if ( ! $this->_load_and_instantiate_reg_steps()) {
496
+				EED_Single_Page_Checkout::$_initialized = true;
497
+				return;
498
+			}
499
+			// set the current step
500
+			$this->checkout->set_current_step($this->checkout->step);
501
+			// and the next step
502
+			$this->checkout->set_next_step();
503
+			// verify that everything has been setup correctly
504
+			if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
505
+				EED_Single_Page_Checkout::$_initialized = true;
506
+				return;
507
+			}
508
+			// lock the transaction
509
+			$this->checkout->transaction->lock();
510
+			// make sure all of our cached objects are added to their respective model entity mappers
511
+			$this->checkout->refresh_all_entities();
512
+			// set amount owing
513
+			$this->checkout->amount_owing = $this->checkout->transaction->remaining();
514
+			// initialize each reg step, which gives them the chance to potentially alter the process
515
+			$this->_initialize_reg_steps();
516
+			// DEBUG LOG
517
+			//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518
+			// get reg form
519
+			if( ! $this->_check_form_submission()) {
520
+				EED_Single_Page_Checkout::$_initialized = true;
521
+				return;
522
+			}
523
+			// checkout the action!!!
524
+			$this->_process_form_action();
525
+			// add some style and make it dance
526
+			$this->add_styles_and_scripts();
527
+			// kk... SPCO has successfully run
528
+			EED_Single_Page_Checkout::$_initialized = true;
529
+			// set no cache headers and constants
530
+			EE_System::do_not_cache();
531
+			// add anchor
532
+			add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
533
+			// remove transaction lock
534
+			add_action('shutdown', array($this, 'unlock_transaction'), 1);
535
+		} catch (Exception $e) {
536
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
537
+		}
538
+	}
539
+
540
+
541
+
542
+	/**
543
+	 *    _verify_session
544
+	 * checks that the session is valid and not expired
545
+	 *
546
+	 * @access    private
547
+	 * @throws EE_Error
548
+	 */
549
+	private function _verify_session()
550
+	{
551
+		if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
552
+			throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
553
+		}
554
+		// is session still valid ?
555
+		if (
556
+			EE_Registry::instance()->SSN->expired()
557
+			&& EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
558
+		) {
559
+			$this->checkout = new EE_Checkout();
560
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
561
+			// EE_Registry::instance()->SSN->reset_cart();
562
+			// EE_Registry::instance()->SSN->reset_checkout();
563
+			// EE_Registry::instance()->SSN->reset_transaction();
564
+			EE_Error::add_attention(
565
+				EE_Registry::$i18n_js_strings['registration_expiration_notice'],
566
+				__FILE__, __FUNCTION__, __LINE__
567
+			);
568
+			// EE_Registry::instance()->SSN->reset_expired();
569
+		}
570
+	}
571
+
572
+
573
+
574
+	/**
575
+	 *    _initialize_checkout
576
+	 * loads and instantiates EE_Checkout
577
+	 *
578
+	 * @access    private
579
+	 * @throws EE_Error
580
+	 * @return EE_Checkout
581
+	 */
582
+	private function _initialize_checkout()
583
+	{
584
+		// look in session for existing checkout
585
+		/** @type EE_Checkout $checkout */
586
+		$checkout = EE_Registry::instance()->SSN->checkout();
587
+		// verify
588
+		if ( ! $checkout instanceof EE_Checkout) {
589
+			// instantiate EE_Checkout object for handling the properties of the current checkout process
590
+			$checkout = EE_Registry::instance()->load_file(
591
+				SPCO_INC_PATH,
592
+				'EE_Checkout',
593
+				'class', array(),
594
+				false
595
+			);
596
+		} else {
597
+			if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
598
+				$this->unlock_transaction();
599
+				wp_safe_redirect($checkout->redirect_url);
600
+				exit();
601
+			}
602
+		}
603
+		$checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
604
+		// verify again
605
+		if ( ! $checkout instanceof EE_Checkout) {
606
+			throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
607
+		}
608
+		// reset anything that needs a clean slate for each request
609
+		$checkout->reset_for_current_request();
610
+		return $checkout;
611
+	}
612
+
613
+
614
+
615
+	/**
616
+	 *    _get_request_vars
617
+	 *
618
+	 * @access    private
619
+	 * @return    void
620
+	 * @throws EE_Error
621
+	 */
622
+	private function _get_request_vars()
623
+	{
624
+		// load classes
625
+		EED_Single_Page_Checkout::load_request_handler();
626
+		//make sure this request is marked as belonging to EE
627
+		EE_Registry::instance()->REQ->set_espresso_page(true);
628
+		// which step is being requested ?
629
+		$this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
630
+		// which step is being edited ?
631
+		$this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
632
+		// and what we're doing on the current step
633
+		$this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
634
+		// timestamp
635
+		$this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
636
+		// returning to edit ?
637
+		$this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
638
+		// or some other kind of revisit ?
639
+		$this->checkout->revisit = filter_var(
640
+			EE_Registry::instance()->REQ->get('revisit', false),
641
+			FILTER_VALIDATE_BOOLEAN
642
+		);
643
+		// and whether or not to generate a reg form for this request
644
+		$this->checkout->generate_reg_form = filter_var(
645
+			EE_Registry::instance()->REQ->get('generate_reg_form', true),
646
+			FILTER_VALIDATE_BOOLEAN
647
+		);
648
+		// and whether or not to process a reg form submission for this request
649
+		$this->checkout->process_form_submission = filter_var(
650
+			EE_Registry::instance()->REQ->get(
651
+				'process_form_submission',
652
+				$this->checkout->action === 'process_reg_step'
653
+			),
654
+			FILTER_VALIDATE_BOOLEAN
655
+		);
656
+		$this->checkout->process_form_submission = filter_var(
657
+			$this->checkout->action !== 'display_spco_reg_step'
658
+				? $this->checkout->process_form_submission
659
+				: false,
660
+			FILTER_VALIDATE_BOOLEAN
661
+		);
662
+		// $this->_display_request_vars();
663
+	}
664
+
665
+
666
+
667
+	/**
668
+	 *  _display_request_vars
669
+	 *
670
+	 * @access    protected
671
+	 * @return    void
672
+	 */
673
+	protected function _display_request_vars()
674
+	{
675
+		if ( ! WP_DEBUG) {
676
+			return;
677
+		}
678
+		EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
679
+		EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
680
+		EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
681
+		EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
682
+		EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
683
+		EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
684
+		EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
685
+		EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
686
+	}
687
+
688
+
689
+
690
+	/**
691
+	 * _block_bots
692
+	 * checks that the incoming request has either of the following set:
693
+	 *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
694
+	 *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
695
+	 * so if you're not coming from the Ticket Selector nor returning for a valid IP...
696
+	 * then where you coming from man?
697
+	 *
698
+	 * @return boolean
699
+	 */
700
+	private function _block_bots()
701
+	{
702
+		$invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
703
+		if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
704
+			return true;
705
+		}
706
+		return false;
707
+	}
708
+
709
+
710
+
711
+	/**
712
+	 *    _get_first_step
713
+	 *  gets slug for first step in $_reg_steps_array
714
+	 *
715
+	 * @access    private
716
+	 * @throws EE_Error
717
+	 * @return    string
718
+	 */
719
+	private function _get_first_step()
720
+	{
721
+		$first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
722
+		return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
723
+	}
724
+
725
+
726
+
727
+	/**
728
+	 *    _load_and_instantiate_reg_steps
729
+	 *  instantiates each reg step based on the loaded reg_steps array
730
+	 *
731
+	 * @access    private
732
+	 * @throws EE_Error
733
+	 * @return    bool
734
+	 */
735
+	private function _load_and_instantiate_reg_steps()
736
+	{
737
+		do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
738
+		// have reg_steps already been instantiated ?
739
+		if (
740
+			empty($this->checkout->reg_steps)
741
+			|| apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
742
+		) {
743
+			// if not, then loop through raw reg steps array
744
+			foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
745
+				if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
746
+					return false;
747
+				}
748
+			}
749
+			EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
750
+			EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
751
+			// skip the registration_confirmation page ?
752
+			if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
753
+				// just remove it from the reg steps array
754
+				$this->checkout->remove_reg_step('registration_confirmation', false);
755
+			} else if (
756
+				isset($this->checkout->reg_steps['registration_confirmation'])
757
+				&& EE_Registry::instance()->CFG->registration->reg_confirmation_last
758
+			) {
759
+				// set the order to something big like 100
760
+				$this->checkout->set_reg_step_order('registration_confirmation', 100);
761
+			}
762
+			// filter the array for good luck
763
+			$this->checkout->reg_steps = apply_filters(
764
+				'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
765
+				$this->checkout->reg_steps
766
+			);
767
+			// finally re-sort based on the reg step class order properties
768
+			$this->checkout->sort_reg_steps();
769
+		} else {
770
+			foreach ($this->checkout->reg_steps as $reg_step) {
771
+				// set all current step stati to FALSE
772
+				$reg_step->set_is_current_step(false);
773
+			}
774
+		}
775
+		if (empty($this->checkout->reg_steps)) {
776
+			EE_Error::add_error(
777
+				__('No Reg Steps were loaded..', 'event_espresso'),
778
+				__FILE__, __FUNCTION__, __LINE__
779
+			);
780
+			return false;
781
+		}
782
+		// make reg step details available to JS
783
+		$this->checkout->set_reg_step_JSON_info();
784
+		return true;
785
+	}
786
+
787
+
788
+
789
+	/**
790
+	 *     _load_and_instantiate_reg_step
791
+	 *
792
+	 * @access    private
793
+	 * @param array $reg_step
794
+	 * @param int   $order
795
+	 * @return bool
796
+	 */
797
+	private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
798
+	{
799
+		// we need a file_path, class_name, and slug to add a reg step
800
+		if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
801
+			// if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
802
+			if (
803
+				$this->checkout->reg_url_link
804
+				&& $this->checkout->step !== $reg_step['slug']
805
+				&& $reg_step['slug'] !== 'finalize_registration'
806
+				// normally at this point we would NOT load the reg step, but this filter can change that
807
+				&& apply_filters(
808
+					'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
809
+					true,
810
+					$reg_step,
811
+					$this->checkout
812
+				)
813
+			) {
814
+				return true;
815
+			}
816
+			// instantiate step class using file path and class name
817
+			$reg_step_obj = EE_Registry::instance()->load_file(
818
+				$reg_step['file_path'],
819
+				$reg_step['class_name'],
820
+				'class',
821
+				$this->checkout,
822
+				false
823
+			);
824
+			// did we gets the goods ?
825
+			if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
826
+				// set reg step order based on config
827
+				$reg_step_obj->set_order($order);
828
+				// add instantiated reg step object to the master reg steps array
829
+				$this->checkout->add_reg_step($reg_step_obj);
830
+			} else {
831
+				EE_Error::add_error(
832
+					__('The current step could not be set.', 'event_espresso'),
833
+					__FILE__, __FUNCTION__, __LINE__
834
+				);
835
+				return false;
836
+			}
837
+		} else {
838
+			if (WP_DEBUG) {
839
+				EE_Error::add_error(
840
+					sprintf(
841
+						__(
842
+							'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
843
+							'event_espresso'
844
+						),
845
+						isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
846
+						isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
847
+						isset($reg_step['slug']) ? $reg_step['slug'] : '',
848
+						'<ul>',
849
+						'<li>',
850
+						'</li>',
851
+						'</ul>'
852
+					),
853
+					__FILE__, __FUNCTION__, __LINE__
854
+				);
855
+			}
856
+			return false;
857
+		}
858
+		return true;
859
+	}
860
+
861
+
862
+	/**
863
+	 * _verify_transaction_and_get_registrations
864
+	 *
865
+	 * @access private
866
+	 * @return bool
867
+	 * @throws InvalidDataTypeException
868
+	 * @throws InvalidEntityException
869
+	 * @throws EE_Error
870
+	 */
871
+	private function _verify_transaction_and_get_registrations()
872
+	{
873
+		// was there already a valid transaction in the checkout from the session ?
874
+		if ( ! $this->checkout->transaction instanceof EE_Transaction) {
875
+			// get transaction from db or session
876
+			$this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
877
+				? $this->_get_transaction_and_cart_for_previous_visit()
878
+				: $this->_get_cart_for_current_session_and_setup_new_transaction();
879
+			if ( ! $this->checkout->transaction instanceof EE_Transaction) {
880
+				EE_Error::add_error(
881
+					__('Your Registration and Transaction information could not be retrieved from the db.',
882
+						'event_espresso'),
883
+					__FILE__, __FUNCTION__, __LINE__
884
+				);
885
+				$this->checkout->transaction = EE_Transaction::new_instance();
886
+				// add some style and make it dance
887
+				$this->add_styles_and_scripts();
888
+				EED_Single_Page_Checkout::$_initialized = true;
889
+				return false;
890
+			}
891
+			// and the registrations for the transaction
892
+			$this->_get_registrations($this->checkout->transaction);
893
+		}
894
+		return true;
895
+	}
896
+
897
+
898
+
899
+	/**
900
+	 * _get_transaction_and_cart_for_previous_visit
901
+	 *
902
+	 * @access private
903
+	 * @return mixed EE_Transaction|NULL
904
+	 */
905
+	private function _get_transaction_and_cart_for_previous_visit()
906
+	{
907
+		/** @var $TXN_model EEM_Transaction */
908
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
909
+		// because the reg_url_link is present in the request,
910
+		// this is a return visit to SPCO, so we'll get the transaction data from the db
911
+		$transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
912
+		// verify transaction
913
+		if ($transaction instanceof EE_Transaction) {
914
+			// and get the cart that was used for that transaction
915
+			$this->checkout->cart = $this->_get_cart_for_transaction($transaction);
916
+			return $transaction;
917
+		}
918
+		EE_Error::add_error(
919
+			__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'),
920
+			__FILE__, __FUNCTION__, __LINE__
921
+		);
922
+		return null;
923
+
924
+	}
925
+
926
+
927
+
928
+	/**
929
+	 * _get_cart_for_transaction
930
+	 *
931
+	 * @access private
932
+	 * @param EE_Transaction $transaction
933
+	 * @return EE_Cart
934
+	 */
935
+	private function _get_cart_for_transaction($transaction)
936
+	{
937
+		return $this->checkout->get_cart_for_transaction($transaction);
938
+	}
939
+
940
+
941
+
942
+	/**
943
+	 * get_cart_for_transaction
944
+	 *
945
+	 * @access public
946
+	 * @param EE_Transaction $transaction
947
+	 * @return EE_Cart
948
+	 */
949
+	public function get_cart_for_transaction(EE_Transaction $transaction)
950
+	{
951
+		return $this->checkout->get_cart_for_transaction($transaction);
952
+	}
953
+
954
+
955
+
956
+	/**
957
+	 * _get_transaction_and_cart_for_current_session
958
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
959
+	 *
960
+	 * @access private
961
+	 * @return EE_Transaction
962
+	 * @throws EE_Error
963
+	 */
964
+	private function _get_cart_for_current_session_and_setup_new_transaction()
965
+	{
966
+		//  if there's no transaction, then this is the FIRST visit to SPCO
967
+		// so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
968
+		$this->checkout->cart = $this->_get_cart_for_transaction(null);
969
+		// and then create a new transaction
970
+		$transaction = $this->_initialize_transaction();
971
+		// verify transaction
972
+		if ($transaction instanceof EE_Transaction) {
973
+			// save it so that we have an ID for other objects to use
974
+			$transaction->save();
975
+			// and save TXN data to the cart
976
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
977
+		} else {
978
+			EE_Error::add_error(
979
+				__('A Valid Transaction could not be initialized.', 'event_espresso'),
980
+				__FILE__, __FUNCTION__, __LINE__
981
+			);
982
+		}
983
+		return $transaction;
984
+	}
985
+
986
+
987
+
988
+	/**
989
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
990
+	 *
991
+	 * @access private
992
+	 * @return mixed EE_Transaction|NULL
993
+	 */
994
+	private function _initialize_transaction()
995
+	{
996
+		try {
997
+			// ensure cart totals have been calculated
998
+			$this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
999
+			// grab the cart grand total
1000
+			$cart_total = $this->checkout->cart->get_cart_grand_total();
1001
+			// create new TXN
1002
+			$transaction = EE_Transaction::new_instance(
1003
+				array(
1004
+					'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
1005
+					'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
1006
+					'TXN_paid'      => 0,
1007
+					'STS_ID'        => EEM_Transaction::failed_status_code,
1008
+				)
1009
+			);
1010
+			// save it so that we have an ID for other objects to use
1011
+			$transaction->save();
1012
+			// set cron job for following up on TXNs after their session has expired
1013
+			EE_Cron_Tasks::schedule_expired_transaction_check(
1014
+				EE_Registry::instance()->SSN->expiration() + 1,
1015
+				$transaction->ID()
1016
+			);
1017
+			return $transaction;
1018
+		} catch (Exception $e) {
1019
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1020
+		}
1021
+		return null;
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * _get_registrations
1027
+	 *
1028
+	 * @access private
1029
+	 * @param EE_Transaction $transaction
1030
+	 * @return void
1031
+	 * @throws InvalidDataTypeException
1032
+	 * @throws InvalidEntityException
1033
+	 * @throws EE_Error
1034
+	 */
1035
+	private function _get_registrations(EE_Transaction $transaction)
1036
+	{
1037
+		// first step: grab the registrants  { : o
1038
+		$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
1039
+		// verify registrations have been set
1040
+		if (empty($registrations)) {
1041
+			// if no cached registrations, then check the db
1042
+			$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1043
+			// still nothing ? well as long as this isn't a revisit
1044
+			if (empty($registrations) && ! $this->checkout->revisit) {
1045
+				// generate new registrations from scratch
1046
+				$registrations = $this->_initialize_registrations($transaction);
1047
+			}
1048
+		}
1049
+		// sort by their original registration order
1050
+		usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1051
+		// then loop thru the array
1052
+		foreach ($registrations as $registration) {
1053
+			// verify each registration
1054
+			if ($registration instanceof EE_Registration) {
1055
+				// we display all attendee info for the primary registrant
1056
+				if ($this->checkout->reg_url_link === $registration->reg_url_link()
1057
+					&& $registration->is_primary_registrant()
1058
+				) {
1059
+					$this->checkout->primary_revisit = true;
1060
+					break;
1061
+				}
1062
+				if ($this->checkout->revisit
1063
+						   && $this->checkout->reg_url_link !== $registration->reg_url_link()
1064
+				) {
1065
+					// but hide info if it doesn't belong to you
1066
+					$transaction->clear_cache('Registration', $registration->ID());
1067
+				}
1068
+				$this->checkout->set_reg_status_updated($registration->ID(), false);
1069
+			}
1070
+		}
1071
+	}
1072
+
1073
+
1074
+	/**
1075
+	 *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1076
+	 *
1077
+	 * @access private
1078
+	 * @param EE_Transaction $transaction
1079
+	 * @return    array
1080
+	 * @throws InvalidDataTypeException
1081
+	 * @throws InvalidEntityException
1082
+	 * @throws EE_Error
1083
+	 */
1084
+	private function _initialize_registrations(EE_Transaction $transaction)
1085
+	{
1086
+		$att_nmbr = 0;
1087
+		$registrations = array();
1088
+		if ($transaction instanceof EE_Transaction) {
1089
+			/** @type EE_Registration_Processor $registration_processor */
1090
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1091
+			$this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1092
+			// now let's add the cart items to the $transaction
1093
+			foreach ($this->checkout->cart->get_tickets() as $line_item) {
1094
+				//do the following for each ticket of this type they selected
1095
+				for ($x = 1; $x <= $line_item->quantity(); $x++) {
1096
+					$att_nmbr++;
1097
+					/** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1098
+					$CreateRegistrationCommand = EE_Registry::instance()->create(
1099
+						'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1100
+						array(
1101
+							$transaction,
1102
+							$line_item,
1103
+							$att_nmbr,
1104
+							$this->checkout->total_ticket_count,
1105
+						)
1106
+					);
1107
+					// override capabilities for frontend registrations
1108
+					if ( ! is_admin()) {
1109
+						$CreateRegistrationCommand->setCapCheck(
1110
+							new PublicCapabilities('', 'create_new_registration')
1111
+						);
1112
+					}
1113
+					$registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1114
+					if ( ! $registration instanceof EE_Registration) {
1115
+						throw new InvalidEntityException($registration, 'EE_Registration');
1116
+					}
1117
+					$registrations[ $registration->ID() ] = $registration;
1118
+				}
1119
+			}
1120
+			$registration_processor->fix_reg_final_price_rounding_issue($transaction);
1121
+		}
1122
+		return $registrations;
1123
+	}
1124
+
1125
+
1126
+
1127
+	/**
1128
+	 * sorts registrations by REG_count
1129
+	 *
1130
+	 * @access public
1131
+	 * @param EE_Registration $reg_A
1132
+	 * @param EE_Registration $reg_B
1133
+	 * @return int
1134
+	 */
1135
+	public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1136
+	{
1137
+		// this shouldn't ever happen within the same TXN, but oh well
1138
+		if ($reg_A->count() === $reg_B->count()) {
1139
+			return 0;
1140
+		}
1141
+		return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1142
+	}
1143
+
1144
+
1145
+
1146
+	/**
1147
+	 *    _final_verifications
1148
+	 * just makes sure that everything is set up correctly before proceeding
1149
+	 *
1150
+	 * @access    private
1151
+	 * @return    bool
1152
+	 * @throws EE_Error
1153
+	 */
1154
+	private function _final_verifications()
1155
+	{
1156
+		// filter checkout
1157
+		$this->checkout = apply_filters(
1158
+			'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1159
+			$this->checkout
1160
+		);
1161
+		//verify that current step is still set correctly
1162
+		if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1163
+			EE_Error::add_error(
1164
+				__('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'),
1165
+				__FILE__,
1166
+				__FUNCTION__,
1167
+				__LINE__
1168
+			);
1169
+			return false;
1170
+		}
1171
+		// if returning to SPCO, then verify that primary registrant is set
1172
+		if ( ! empty($this->checkout->reg_url_link)) {
1173
+			$valid_registrant = $this->checkout->transaction->primary_registration();
1174
+			if ( ! $valid_registrant instanceof EE_Registration) {
1175
+				EE_Error::add_error(
1176
+					__('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'),
1177
+					__FILE__,
1178
+					__FUNCTION__,
1179
+					__LINE__
1180
+				);
1181
+				return false;
1182
+			}
1183
+			$valid_registrant = null;
1184
+			foreach (
1185
+				$this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration
1186
+			) {
1187
+				if (
1188
+					$registration instanceof EE_Registration
1189
+					&& $registration->reg_url_link() === $this->checkout->reg_url_link
1190
+				) {
1191
+					$valid_registrant = $registration;
1192
+				}
1193
+			}
1194
+			if ( ! $valid_registrant instanceof EE_Registration) {
1195
+				// hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1196
+				if (EED_Single_Page_Checkout::$_checkout_verified) {
1197
+					// clear the session, mark the checkout as unverified, and try again
1198
+					EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1199
+					EED_Single_Page_Checkout::$_initialized = false;
1200
+					EED_Single_Page_Checkout::$_checkout_verified = false;
1201
+					$this->_initialize();
1202
+					EE_Error::reset_notices();
1203
+					return false;
1204
+				}
1205
+				EE_Error::add_error(
1206
+					__(
1207
+						'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1208
+						'event_espresso'
1209
+					),
1210
+					__FILE__,
1211
+					__FUNCTION__,
1212
+					__LINE__
1213
+				);
1214
+				return false;
1215
+			}
1216
+		}
1217
+		// now that things have been kinda sufficiently verified,
1218
+		// let's add the checkout to the session so that it's available to other systems
1219
+		EE_Registry::instance()->SSN->set_checkout($this->checkout);
1220
+		return true;
1221
+	}
1222
+
1223
+
1224
+
1225
+	/**
1226
+	 *    _initialize_reg_steps
1227
+	 * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1228
+	 * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1229
+	 *
1230
+	 * @access    private
1231
+	 * @param bool $reinitializing
1232
+	 * @throws EE_Error
1233
+	 */
1234
+	private function _initialize_reg_steps($reinitializing = false)
1235
+	{
1236
+		$this->checkout->set_reg_step_initiated($this->checkout->current_step);
1237
+		// loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1238
+		foreach ($this->checkout->reg_steps as $reg_step) {
1239
+			if ( ! $reg_step->initialize_reg_step()) {
1240
+				// if not initialized then maybe this step is being removed...
1241
+				if ( ! $reinitializing && $reg_step->is_current_step()) {
1242
+					// if it was the current step, then we need to start over here
1243
+					$this->_initialize_reg_steps(true);
1244
+					return;
1245
+				}
1246
+				continue;
1247
+			}
1248
+			// add css and JS for current step
1249
+			$reg_step->enqueue_styles_and_scripts();
1250
+			// i18n
1251
+			$reg_step->translate_js_strings();
1252
+			if ($reg_step->is_current_step()) {
1253
+				// the text that appears on the reg step form submit button
1254
+				$reg_step->set_submit_button_text();
1255
+			}
1256
+		}
1257
+		// dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1258
+		do_action(
1259
+			"AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1260
+			$this->checkout->current_step
1261
+		);
1262
+	}
1263
+
1264
+
1265
+
1266
+	/**
1267
+	 * _check_form_submission
1268
+	 *
1269
+	 * @access private
1270
+	 * @return boolean
1271
+	 */
1272
+	private function _check_form_submission()
1273
+	{
1274
+		//does this request require the reg form to be generated ?
1275
+		if ($this->checkout->generate_reg_form) {
1276
+			// ever heard that song by Blue Rodeo ?
1277
+			try {
1278
+				$this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1279
+				// if not displaying a form, then check for form submission
1280
+				if (
1281
+					$this->checkout->process_form_submission
1282
+					&& $this->checkout->current_step->reg_form->was_submitted()
1283
+				) {
1284
+					// clear out any old data in case this step is being run again
1285
+					$this->checkout->current_step->set_valid_data(array());
1286
+					// capture submitted form data
1287
+					$this->checkout->current_step->reg_form->receive_form_submission(
1288
+						apply_filters(
1289
+							'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1290
+							EE_Registry::instance()->REQ->params(),
1291
+							$this->checkout
1292
+						)
1293
+					);
1294
+					// validate submitted form data
1295
+					if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1296
+						// thou shall not pass !!!
1297
+						$this->checkout->continue_reg = false;
1298
+						// any form validation errors?
1299
+						if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1300
+							$submission_error_messages = array();
1301
+							// bad, bad, bad registrant
1302
+							foreach (
1303
+								$this->checkout->current_step->reg_form->get_validation_errors_accumulated()
1304
+								as $validation_error
1305
+							) {
1306
+								if ($validation_error instanceof EE_Validation_Error) {
1307
+									$submission_error_messages[] = sprintf(
1308
+										__('%s : %s', 'event_espresso'),
1309
+										$validation_error->get_form_section()->html_label_text(),
1310
+										$validation_error->getMessage()
1311
+									);
1312
+								}
1313
+							}
1314
+							EE_Error::add_error(
1315
+								implode('<br />', $submission_error_messages),
1316
+								__FILE__, __FUNCTION__, __LINE__
1317
+							);
1318
+						}
1319
+						// well not really... what will happen is
1320
+						// we'll just get redirected back to redo the current step
1321
+						$this->go_to_next_step();
1322
+						return false;
1323
+					}
1324
+				}
1325
+			} catch (EE_Error $e) {
1326
+				$e->get_error();
1327
+			}
1328
+		}
1329
+		return true;
1330
+	}
1331
+
1332
+
1333
+
1334
+	/**
1335
+	 * _process_action
1336
+	 *
1337
+	 * @access private
1338
+	 * @return void
1339
+	 * @throws EE_Error
1340
+	 */
1341
+	private function _process_form_action()
1342
+	{
1343
+		// what cha wanna do?
1344
+		switch ($this->checkout->action) {
1345
+			// AJAX next step reg form
1346
+			case 'display_spco_reg_step' :
1347
+				$this->checkout->redirect = false;
1348
+				if (EE_Registry::instance()->REQ->ajax) {
1349
+					$this->checkout->json_response->set_reg_step_html(
1350
+						$this->checkout->current_step->display_reg_form()
1351
+					);
1352
+				}
1353
+				break;
1354
+			default :
1355
+				// meh... do one of those other steps first
1356
+				if (
1357
+					! empty($this->checkout->action)
1358
+					&& is_callable(array($this->checkout->current_step, $this->checkout->action))
1359
+				) {
1360
+					// dynamically creates hook point like:
1361
+					//   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1362
+					do_action(
1363
+						"AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1364
+						$this->checkout->current_step
1365
+					);
1366
+					// call action on current step
1367
+					if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1368
+						// good registrant, you get to proceed
1369
+						if (
1370
+							$this->checkout->current_step->success_message() !== ''
1371
+							&& apply_filters(
1372
+								'FHEE__Single_Page_Checkout___process_form_action__display_success',
1373
+								false
1374
+							)
1375
+						) {
1376
+							EE_Error::add_success(
1377
+								$this->checkout->current_step->success_message()
1378
+								. '<br />' . $this->checkout->next_step->_instructions()
1379
+							);
1380
+						}
1381
+						// pack it up, pack it in...
1382
+						$this->_setup_redirect();
1383
+					}
1384
+					// dynamically creates hook point like:
1385
+					//  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1386
+					do_action(
1387
+						"AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1388
+						$this->checkout->current_step
1389
+					);
1390
+				} else {
1391
+					EE_Error::add_error(
1392
+						sprintf(
1393
+							__(
1394
+								'The requested form action "%s" does not exist for the current "%s" registration step.',
1395
+								'event_espresso'
1396
+							),
1397
+							$this->checkout->action,
1398
+							$this->checkout->current_step->name()
1399
+						),
1400
+						__FILE__,
1401
+						__FUNCTION__,
1402
+						__LINE__
1403
+					);
1404
+				}
1405
+			// end default
1406
+		}
1407
+		// store our progress so far
1408
+		$this->checkout->stash_transaction_and_checkout();
1409
+		// advance to the next step! If you pass GO, collect $200
1410
+		$this->go_to_next_step();
1411
+	}
1412
+
1413
+
1414
+
1415
+	/**
1416
+	 *        add_styles_and_scripts
1417
+	 *
1418
+	 * @access        public
1419
+	 * @return        void
1420
+	 */
1421
+	public function add_styles_and_scripts()
1422
+	{
1423
+		// i18n
1424
+		$this->translate_js_strings();
1425
+		if ($this->checkout->admin_request) {
1426
+			add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1427
+		} else {
1428
+			add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1429
+		}
1430
+	}
1431
+
1432
+
1433
+
1434
+	/**
1435
+	 *        translate_js_strings
1436
+	 *
1437
+	 * @access        public
1438
+	 * @return        void
1439
+	 */
1440
+	public function translate_js_strings()
1441
+	{
1442
+		EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1443
+		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1444
+		EE_Registry::$i18n_js_strings['server_error'] = __(
1445
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1446
+			'event_espresso'
1447
+		);
1448
+		EE_Registry::$i18n_js_strings['invalid_json_response'] = __(
1449
+			'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1450
+			'event_espresso'
1451
+		);
1452
+		EE_Registry::$i18n_js_strings['validation_error'] = __(
1453
+			'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1454
+			'event_espresso'
1455
+		);
1456
+		EE_Registry::$i18n_js_strings['invalid_payment_method'] = __(
1457
+			'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1458
+			'event_espresso'
1459
+		);
1460
+		EE_Registry::$i18n_js_strings['reg_step_error'] = __(
1461
+			'This registration step could not be completed. Please refresh the page and try again.',
1462
+			'event_espresso'
1463
+		);
1464
+		EE_Registry::$i18n_js_strings['invalid_coupon'] = __(
1465
+			'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1466
+			'event_espresso'
1467
+		);
1468
+		EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1469
+			__(
1470
+				'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1471
+				'event_espresso'
1472
+			),
1473
+			'<br/>',
1474
+			'<br/>'
1475
+		);
1476
+		EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1477
+		EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1478
+		EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1479
+		EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1480
+		EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1481
+		EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1482
+		EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1483
+		EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1484
+		EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1485
+		EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1486
+		EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1487
+		EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1488
+		EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1489
+		EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1490
+		EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1491
+		EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1492
+		EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1493
+		EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1494
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1495
+			__(
1496
+				'%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
1497
+				'event_espresso'
1498
+			),
1499
+			'<h4 class="important-notice">',
1500
+			'</h4>',
1501
+			'<br />',
1502
+			'<p>',
1503
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1504
+			'">',
1505
+			'</a>',
1506
+			'</p>'
1507
+		);
1508
+		EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters(
1509
+			'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1510
+			true
1511
+		);
1512
+		EE_Registry::$i18n_js_strings['session_extension'] = absint(
1513
+			apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1514
+		);
1515
+		EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1516
+			'M d, Y H:i:s',
1517
+			EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1518
+		);
1519
+	}
1520
+
1521
+
1522
+
1523
+	/**
1524
+	 *    enqueue_styles_and_scripts
1525
+	 *
1526
+	 * @access        public
1527
+	 * @return        void
1528
+	 * @throws EE_Error
1529
+	 */
1530
+	public function enqueue_styles_and_scripts()
1531
+	{
1532
+		// load css
1533
+		wp_register_style(
1534
+			'single_page_checkout',
1535
+			SPCO_CSS_URL . 'single_page_checkout.css',
1536
+			array('espresso_default'),
1537
+			EVENT_ESPRESSO_VERSION
1538
+		);
1539
+		wp_enqueue_style('single_page_checkout');
1540
+		// load JS
1541
+		wp_register_script(
1542
+			'jquery_plugin',
1543
+			EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1544
+			array('jquery'),
1545
+			'1.0.1',
1546
+			true
1547
+		);
1548
+		wp_register_script(
1549
+			'jquery_countdown',
1550
+			EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1551
+			array('jquery_plugin'),
1552
+			'2.0.2',
1553
+			true
1554
+		);
1555
+		wp_register_script(
1556
+			'single_page_checkout',
1557
+			SPCO_JS_URL . 'single_page_checkout.js',
1558
+			array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1559
+			EVENT_ESPRESSO_VERSION,
1560
+			true
1561
+		);
1562
+		if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1563
+			$this->checkout->registration_form->enqueue_js();
1564
+		}
1565
+		if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1566
+			$this->checkout->current_step->reg_form->enqueue_js();
1567
+		}
1568
+		wp_enqueue_script('single_page_checkout');
1569
+		/**
1570
+		 * global action hook for enqueueing styles and scripts with
1571
+		 * spco calls.
1572
+		 */
1573
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1574
+		/**
1575
+		 * dynamic action hook for enqueueing styles and scripts with spco calls.
1576
+		 * The hook will end up being something like:
1577
+		 *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1578
+		 */
1579
+		do_action(
1580
+			'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1581
+			$this
1582
+		);
1583
+	}
1584
+
1585
+
1586
+
1587
+	/**
1588
+	 *    display the Registration Single Page Checkout Form
1589
+	 *
1590
+	 * @access    private
1591
+	 * @return    void
1592
+	 * @throws EE_Error
1593
+	 */
1594
+	private function _display_spco_reg_form()
1595
+	{
1596
+		// if registering via the admin, just display the reg form for the current step
1597
+		if ($this->checkout->admin_request) {
1598
+			EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1599
+		} else {
1600
+			// add powered by EE msg
1601
+			add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1602
+			$empty_cart = count(
1603
+				$this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1604
+			) < 1;
1605
+			EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1606
+			$cookies_not_set_msg = '';
1607
+			if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1608
+				$cookies_not_set_msg = apply_filters(
1609
+					'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1610
+					sprintf(
1611
+						__(
1612
+							'%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1613
+							'event_espresso'
1614
+						),
1615
+						'<div class="ee-attention">',
1616
+						'</div>',
1617
+						'<h6 class="important-notice">',
1618
+						'</h6>',
1619
+						'<p>',
1620
+						'</p>',
1621
+						'<br />',
1622
+						'<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1623
+						'</a>'
1624
+					)
1625
+				);
1626
+			}
1627
+			$this->checkout->registration_form = new EE_Form_Section_Proper(
1628
+				array(
1629
+					'name'            => 'single-page-checkout',
1630
+					'html_id'         => 'ee-single-page-checkout-dv',
1631
+					'layout_strategy' =>
1632
+						new EE_Template_Layout(
1633
+							array(
1634
+								'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1635
+								'template_args'        => array(
1636
+									'empty_cart'              => $empty_cart,
1637
+									'revisit'                 => $this->checkout->revisit,
1638
+									'reg_steps'               => $this->checkout->reg_steps,
1639
+									'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1640
+										? $this->checkout->next_step->slug()
1641
+										: '',
1642
+									'cancel_page_url'         => $this->checkout->cancel_page_url,
1643
+									'empty_msg'               => apply_filters(
1644
+										'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1645
+										sprintf(
1646
+											__(
1647
+												'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1648
+												'event_espresso'
1649
+											),
1650
+											'<a href="'
1651
+											. get_post_type_archive_link('espresso_events')
1652
+											. '" title="',
1653
+											'">',
1654
+											'</a>'
1655
+										)
1656
+									),
1657
+									'cookies_not_set_msg'     => $cookies_not_set_msg,
1658
+									'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1659
+									'session_expiration'      => gmdate(
1660
+										'M d, Y H:i:s',
1661
+										EE_Registry::instance()->SSN->expiration()
1662
+										+ (get_option('gmt_offset') * HOUR_IN_SECONDS)
1663
+									),
1664
+								),
1665
+							)
1666
+						),
1667
+				)
1668
+			);
1669
+			// load template and add to output sent that gets filtered into the_content()
1670
+			EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1671
+		}
1672
+	}
1673
+
1674
+
1675
+
1676
+	/**
1677
+	 *    add_extra_finalize_registration_inputs
1678
+	 *
1679
+	 * @access    public
1680
+	 * @param $next_step
1681
+	 * @internal  param string $label
1682
+	 * @return void
1683
+	 */
1684
+	public function add_extra_finalize_registration_inputs($next_step)
1685
+	{
1686
+		if ($next_step === 'finalize_registration') {
1687
+			echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1688
+		}
1689
+	}
1690
+
1691
+
1692
+
1693
+	/**
1694
+	 *    display_registration_footer
1695
+	 *
1696
+	 * @access    public
1697
+	 * @return    string
1698
+	 */
1699
+	public static function display_registration_footer()
1700
+	{
1701
+		if (
1702
+		apply_filters(
1703
+			'FHEE__EE_Front__Controller__show_reg_footer',
1704
+			EE_Registry::instance()->CFG->admin->show_reg_footer
1705
+		)
1706
+		) {
1707
+			add_filter(
1708
+				'FHEE__EEH_Template__powered_by_event_espresso__url',
1709
+				function ($url) {
1710
+					return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1711
+				}
1712
+			);
1713
+			echo apply_filters(
1714
+				'FHEE__EE_Front_Controller__display_registration_footer',
1715
+				\EEH_Template::powered_by_event_espresso(
1716
+					'',
1717
+					'espresso-registration-footer-dv',
1718
+					array('utm_content' => 'registration_checkout')
1719
+				)
1720
+			);
1721
+		}
1722
+		return '';
1723
+	}
1724
+
1725
+
1726
+
1727
+	/**
1728
+	 *    unlock_transaction
1729
+	 *
1730
+	 * @access    public
1731
+	 * @return    void
1732
+	 * @throws EE_Error
1733
+	 */
1734
+	public function unlock_transaction()
1735
+	{
1736
+		if ($this->checkout->transaction instanceof EE_Transaction) {
1737
+			$this->checkout->transaction->unlock();
1738
+		}
1739
+	}
1740
+
1741
+
1742
+
1743
+	/**
1744
+	 *        _setup_redirect
1745
+	 *
1746
+	 * @access    private
1747
+	 * @return void
1748
+	 */
1749
+	private function _setup_redirect()
1750
+	{
1751
+		if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1752
+			$this->checkout->redirect = true;
1753
+			if (empty($this->checkout->redirect_url)) {
1754
+				$this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1755
+			}
1756
+			$this->checkout->redirect_url = apply_filters(
1757
+				'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1758
+				$this->checkout->redirect_url,
1759
+				$this->checkout
1760
+			);
1761
+		}
1762
+	}
1763
+
1764
+
1765
+
1766
+	/**
1767
+	 *   handle ajax message responses and redirects
1768
+	 *
1769
+	 * @access public
1770
+	 * @return void
1771
+	 * @throws EE_Error
1772
+	 */
1773
+	public function go_to_next_step()
1774
+	{
1775
+		if (EE_Registry::instance()->REQ->ajax) {
1776
+			// capture contents of output buffer we started earlier in the request, and insert into JSON response
1777
+			$this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1778
+		}
1779
+		$this->unlock_transaction();
1780
+		// just return for these conditions
1781
+		if (
1782
+			$this->checkout->admin_request
1783
+			|| $this->checkout->action === 'redirect_form'
1784
+			|| $this->checkout->action === 'update_checkout'
1785
+		) {
1786
+			return;
1787
+		}
1788
+		// AJAX response
1789
+		$this->_handle_json_response();
1790
+		// redirect to next step or the Thank You page
1791
+		$this->_handle_html_redirects();
1792
+		// hmmm... must be something wrong, so let's just display the form again !
1793
+		$this->_display_spco_reg_form();
1794
+	}
1795
+
1796
+
1797
+
1798
+	/**
1799
+	 *   _handle_json_response
1800
+	 *
1801
+	 * @access protected
1802
+	 * @return void
1803
+	 */
1804
+	protected function _handle_json_response()
1805
+	{
1806
+		// if this is an ajax request
1807
+		if (EE_Registry::instance()->REQ->ajax) {
1808
+			// DEBUG LOG
1809
+			//$this->checkout->log(
1810
+			//	__CLASS__, __FUNCTION__, __LINE__,
1811
+			//	array(
1812
+			//		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1813
+			//		'redirect'                   => $this->checkout->redirect,
1814
+			//		'continue_reg'               => $this->checkout->continue_reg,
1815
+			//	)
1816
+			//);
1817
+			$this->checkout->json_response->set_registration_time_limit(
1818
+				$this->checkout->get_registration_time_limit()
1819
+			);
1820
+			$this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1821
+			// just send the ajax (
1822
+			$json_response = apply_filters(
1823
+				'FHEE__EE_Single_Page_Checkout__JSON_response',
1824
+				$this->checkout->json_response
1825
+			);
1826
+			echo $json_response;
1827
+			exit();
1828
+		}
1829
+	}
1830
+
1831
+
1832
+
1833
+	/**
1834
+	 *   _handle_redirects
1835
+	 *
1836
+	 * @access protected
1837
+	 * @return void
1838
+	 */
1839
+	protected function _handle_html_redirects()
1840
+	{
1841
+		// going somewhere ?
1842
+		if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1843
+			// store notices in a transient
1844
+			EE_Error::get_notices(false, true, true);
1845
+			// DEBUG LOG
1846
+			//$this->checkout->log(
1847
+			//	__CLASS__, __FUNCTION__, __LINE__,
1848
+			//	array(
1849
+			//		'headers_sent' => headers_sent(),
1850
+			//		'redirect_url'     => $this->checkout->redirect_url,
1851
+			//		'headers_list'    => headers_list(),
1852
+			//	)
1853
+			//);
1854
+			wp_safe_redirect($this->checkout->redirect_url);
1855
+			exit();
1856
+		}
1857
+	}
1858
+
1859
+
1860
+
1861
+	/**
1862
+	 *   set_checkout_anchor
1863
+	 *
1864
+	 * @access public
1865
+	 * @return void
1866
+	 */
1867
+	public function set_checkout_anchor()
1868
+	{
1869
+		echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1870
+	}
1871 1871
 
1872 1872
 
1873 1873
 
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -218,19 +218,19 @@  discard block
 block discarded – undo
218 218
      */
219 219
     public static function set_definitions()
220 220
     {
221
-        if(defined('SPCO_BASE_PATH')) {
221
+        if (defined('SPCO_BASE_PATH')) {
222 222
             return;
223 223
         }
224 224
         define(
225 225
             'SPCO_BASE_PATH',
226
-            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
226
+            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS).DS
227 227
         );
228
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
228
+        define('SPCO_CSS_URL', plugin_dir_url(__FILE__).'css'.DS);
229
+        define('SPCO_IMG_URL', plugin_dir_url(__FILE__).'img'.DS);
230
+        define('SPCO_JS_URL', plugin_dir_url(__FILE__).'js'.DS);
231
+        define('SPCO_INC_PATH', SPCO_BASE_PATH.'inc'.DS);
232
+        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH.'reg_steps'.DS);
233
+        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH.'templates'.DS);
234 234
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235 235
         EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236 236
             __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
             '</h4>',
240 240
             '<br />',
241 241
             '<p>',
242
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
242
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
243 243
             '">',
244 244
             '</a>',
245 245
             '</p>'
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
             return;
263 263
         }
264 264
         // filter list of reg_steps
265
-        $reg_steps_to_load = (array)apply_filters(
265
+        $reg_steps_to_load = (array) apply_filters(
266 266
             'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267 267
             EED_Single_Page_Checkout::get_reg_steps()
268 268
         );
@@ -314,25 +314,25 @@  discard block
 block discarded – undo
314 314
         if (empty($reg_steps)) {
315 315
             $reg_steps = array(
316 316
                 10  => array(
317
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
317
+                    'file_path'  => SPCO_REG_STEPS_PATH.'attendee_information',
318 318
                     'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319 319
                     'slug'       => 'attendee_information',
320 320
                     'has_hooks'  => false,
321 321
                 ),
322 322
                 20  => array(
323
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
323
+                    'file_path'  => SPCO_REG_STEPS_PATH.'registration_confirmation',
324 324
                     'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325 325
                     'slug'       => 'registration_confirmation',
326 326
                     'has_hooks'  => false,
327 327
                 ),
328 328
                 30  => array(
329
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
329
+                    'file_path'  => SPCO_REG_STEPS_PATH.'payment_options',
330 330
                     'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331 331
                     'slug'       => 'payment_options',
332 332
                     'has_hooks'  => true,
333 333
                 ),
334 334
                 999 => array(
335
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
335
+                    'file_path'  => SPCO_REG_STEPS_PATH.'finalize_registration',
336 336
                     'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337 337
                     'slug'       => 'finalize_registration',
338 338
                     'has_hooks'  => false,
@@ -516,7 +516,7 @@  discard block
 block discarded – undo
516 516
             // DEBUG LOG
517 517
             //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518 518
             // get reg form
519
-            if( ! $this->_check_form_submission()) {
519
+            if ( ! $this->_check_form_submission()) {
520 520
                 EED_Single_Page_Checkout::$_initialized = true;
521 521
                 return;
522 522
             }
@@ -1114,7 +1114,7 @@  discard block
 block discarded – undo
1114 1114
                     if ( ! $registration instanceof EE_Registration) {
1115 1115
                         throw new InvalidEntityException($registration, 'EE_Registration');
1116 1116
                     }
1117
-                    $registrations[ $registration->ID() ] = $registration;
1117
+                    $registrations[$registration->ID()] = $registration;
1118 1118
                 }
1119 1119
             }
1120 1120
             $registration_processor->fix_reg_final_price_rounding_issue($transaction);
@@ -1375,7 +1375,7 @@  discard block
 block discarded – undo
1375 1375
                         ) {
1376 1376
                             EE_Error::add_success(
1377 1377
                                 $this->checkout->current_step->success_message()
1378
-                                . '<br />' . $this->checkout->next_step->_instructions()
1378
+                                . '<br />'.$this->checkout->next_step->_instructions()
1379 1379
                             );
1380 1380
                         }
1381 1381
                         // pack it up, pack it in...
@@ -1500,7 +1500,7 @@  discard block
 block discarded – undo
1500 1500
             '</h4>',
1501 1501
             '<br />',
1502 1502
             '<p>',
1503
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1503
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
1504 1504
             '">',
1505 1505
             '</a>',
1506 1506
             '</p>'
@@ -1532,7 +1532,7 @@  discard block
 block discarded – undo
1532 1532
         // load css
1533 1533
         wp_register_style(
1534 1534
             'single_page_checkout',
1535
-            SPCO_CSS_URL . 'single_page_checkout.css',
1535
+            SPCO_CSS_URL.'single_page_checkout.css',
1536 1536
             array('espresso_default'),
1537 1537
             EVENT_ESPRESSO_VERSION
1538 1538
         );
@@ -1540,21 +1540,21 @@  discard block
 block discarded – undo
1540 1540
         // load JS
1541 1541
         wp_register_script(
1542 1542
             'jquery_plugin',
1543
-            EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1543
+            EE_THIRD_PARTY_URL.'jquery	.plugin.min.js',
1544 1544
             array('jquery'),
1545 1545
             '1.0.1',
1546 1546
             true
1547 1547
         );
1548 1548
         wp_register_script(
1549 1549
             'jquery_countdown',
1550
-            EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1550
+            EE_THIRD_PARTY_URL.'jquery	.countdown.min.js',
1551 1551
             array('jquery_plugin'),
1552 1552
             '2.0.2',
1553 1553
             true
1554 1554
         );
1555 1555
         wp_register_script(
1556 1556
             'single_page_checkout',
1557
-            SPCO_JS_URL . 'single_page_checkout.js',
1557
+            SPCO_JS_URL.'single_page_checkout.js',
1558 1558
             array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1559 1559
             EVENT_ESPRESSO_VERSION,
1560 1560
             true
@@ -1577,7 +1577,7 @@  discard block
 block discarded – undo
1577 1577
          *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1578 1578
          */
1579 1579
         do_action(
1580
-            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1580
+            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__'.$this->checkout->current_step->slug(),
1581 1581
             $this
1582 1582
         );
1583 1583
     }
@@ -1631,7 +1631,7 @@  discard block
 block discarded – undo
1631 1631
                     'layout_strategy' =>
1632 1632
                         new EE_Template_Layout(
1633 1633
                             array(
1634
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1634
+                                'layout_template_file' => SPCO_TEMPLATES_PATH.'registration_page_wrapper.template.php',
1635 1635
                                 'template_args'        => array(
1636 1636
                                     'empty_cart'              => $empty_cart,
1637 1637
                                     'revisit'                 => $this->checkout->revisit,
@@ -1706,7 +1706,7 @@  discard block
 block discarded – undo
1706 1706
         ) {
1707 1707
             add_filter(
1708 1708
                 'FHEE__EEH_Template__powered_by_event_espresso__url',
1709
-                function ($url) {
1709
+                function($url) {
1710 1710
                     return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1711 1711
                 }
1712 1712
             );
Please login to merge, or discard this patch.
admin_pages/maintenance/templates/migration_options_from_ee4.template.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -68,7 +68,7 @@
 block discarded – undo
68 68
     </div>
69 69
     <p><?php esc_html_e('Don\'t want to keep your old Event Espresso data? Alternatively, you can delete it all and start fresh.',
70 70
                 'event_espresso'); ?> <a
71
-                href="<?php echo $data_reset_page;?>"><?php esc_html_e('Visit the Maintenance Page and Reset Your Event Espresso Data',
71
+                href="<?php echo $data_reset_page; ?>"><?php esc_html_e('Visit the Maintenance Page and Reset Your Event Espresso Data',
72 72
                     'event_espresso'); ?></a></p>
73 73
     <?php do_action('AHEE__ee_migration_page__after_migration_options_table'); ?>
74 74
 </div>
75 75
\ No newline at end of file
Please login to merge, or discard this patch.
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -25,14 +25,14 @@  discard block
 block discarded – undo
25 25
             <tr>
26 26
                 <td>
27 27
                     <?php
28
-                    echo apply_filters(
29
-                            'FHEE__ee_migration_page__option_1_main',
30
-                            esc_html__('Before updating your database, you should first create a database backup',
31
-                                    "event_espresso"),
32
-                            $current_db_state,
33
-                            $next_db_state
34
-                    );
35
-                    ?>
28
+					echo apply_filters(
29
+							'FHEE__ee_migration_page__option_1_main',
30
+							esc_html__('Before updating your database, you should first create a database backup',
31
+									"event_espresso"),
32
+							$current_db_state,
33
+							$next_db_state
34
+					);
35
+					?>
36 36
                     <a id="display-migration-details"
37 37
                        class="display-the-hidden lt-grey-text smaller-text hide-if-no-js"
38 38
                        rel="migration-details"><?php esc_html_e('How Do I Make a Database Backup?', "event_espresso"); ?>
@@ -41,8 +41,8 @@  discard block
 block discarded – undo
41 41
                 <td>
42 42
                     <a id="db-backed-up"
43 43
                        class="toggle-migration-monitor button-primary"><?php echo apply_filters('FHEE__ee_migration_page__option_1_button_text',
44
-                                sprintf(esc_html__("My Database Is Backed Up, Continue", "event_espresso"), $current_db_state,
45
-                                        $next_db_state), $current_db_state, $next_db_state); ?></a>
44
+								sprintf(esc_html__("My Database Is Backed Up, Continue", "event_espresso"), $current_db_state,
45
+										$next_db_state), $current_db_state, $next_db_state); ?></a>
46 46
                 </td>
47 47
             </tr>
48 48
             <tr>
@@ -50,14 +50,14 @@  discard block
 block discarded – undo
50 50
                     <div id="migration-details-dv" style="display: none; padding: 1em;">
51 51
                         <p>
52 52
                             <?php
53
-                            printf(
54
-                                    esc_html__('%1$sClick Here to Learn How To Backup your Database Yourself%2$s. Or have one of our dedicated support technicians help you by %3$spurchasing a Priority Support Token.%2$s',
55
-                                            "event_espresso"),
56
-                                    '<a target="_blank" href="http://eventespresso.com/wiki/how-to-back-up-your-site/">',
57
-                                    "</a>",
58
-                                    "<a target=\"_blank\" href='http://eventespresso.com/product/priority-support-tokens/'>"
59
-                            );
60
-                            ?>
53
+							printf(
54
+									esc_html__('%1$sClick Here to Learn How To Backup your Database Yourself%2$s. Or have one of our dedicated support technicians help you by %3$spurchasing a Priority Support Token.%2$s',
55
+											"event_espresso"),
56
+									'<a target="_blank" href="http://eventespresso.com/wiki/how-to-back-up-your-site/">',
57
+									"</a>",
58
+									"<a target=\"_blank\" href='http://eventespresso.com/product/priority-support-tokens/'>"
59
+							);
60
+							?>
61 61
                         </p>
62 62
                         <?php do_action('AHEE__ee_migration_page__option_1_extra_details'); ?>
63 63
                     </div>
@@ -67,8 +67,8 @@  discard block
 block discarded – undo
67 67
         </table>
68 68
     </div>
69 69
     <p><?php esc_html_e('Don\'t want to keep your old Event Espresso data? Alternatively, you can delete it all and start fresh.',
70
-                'event_espresso'); ?> <a
70
+				'event_espresso'); ?> <a
71 71
                 href="<?php echo $data_reset_page;?>"><?php esc_html_e('Visit the Maintenance Page and Reset Your Event Espresso Data',
72
-                    'event_espresso'); ?></a></p>
72
+					'event_espresso'); ?></a></p>
73 73
     <?php do_action('AHEE__ee_migration_page__after_migration_options_table'); ?>
74 74
 </div>
75 75
\ No newline at end of file
Please login to merge, or discard this patch.
core/EE_Cart.core.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -260,7 +260,7 @@  discard block
 block discarded – undo
260 260
      * @access  public
261 261
      * @param EE_Ticket $ticket
262 262
      * @param int       $qty
263
-     * @return TRUE on success, FALSE on fail
263
+     * @return boolean on success, FALSE on fail
264 264
      * @throws \EE_Error
265 265
      */
266 266
     public function add_ticket_to_cart(EE_Ticket $ticket, $qty = 1)
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
      * @save   cart to session
386 386
      * @access public
387 387
      * @param bool $apply_taxes
388
-     * @return TRUE on success, FALSE on fail
388
+     * @return boolean on success, FALSE on fail
389 389
      * @throws \EE_Error
390 390
      */
391 391
     public function save_cart($apply_taxes = true)
@@ -419,7 +419,7 @@  discard block
 block discarded – undo
419 419
 
420 420
 
421 421
     /**
422
-     * @return array
422
+     * @return string[]
423 423
      */
424 424
     public function __sleep()
425 425
     {
Please login to merge, or discard this patch.
Indentation   +413 added lines, -413 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 do_action('AHEE_log', __FILE__, __FUNCTION__, '');
5 5
 
@@ -20,418 +20,418 @@  discard block
 block discarded – undo
20 20
 class EE_Cart
21 21
 {
22 22
 
23
-    /**
24
-     * instance of the EE_Cart object
25
-     *
26
-     * @access    private
27
-     * @var EE_Cart $_instance
28
-     */
29
-    private static $_instance;
30
-
31
-    /**
32
-     * instance of the EE_Session object
33
-     *
34
-     * @access    protected
35
-     * @var EE_Session $_session
36
-     */
37
-    protected $_session;
38
-
39
-    /**
40
-     * The total Line item which comprises all the children line-item subtotals,
41
-     * which in turn each have their line items.
42
-     * Typically, the line item structure will look like:
43
-     * grand total
44
-     * -tickets-sub-total
45
-     * --ticket1
46
-     * --ticket2
47
-     * --...
48
-     * -taxes-sub-total
49
-     * --tax1
50
-     * --tax2
51
-     *
52
-     * @var EE_Line_Item
53
-     */
54
-    private $_grand_total;
55
-
56
-
57
-
58
-    /**
59
-     * @singleton method used to instantiate class object
60
-     * @access    public
61
-     * @param EE_Line_Item $grand_total
62
-     * @param EE_Session   $session
63
-     * @return \EE_Cart
64
-     * @throws \EE_Error
65
-     */
66
-    public static function instance(EE_Line_Item $grand_total = null, EE_Session $session = null)
67
-    {
68
-        if ( ! empty($grand_total)) {
69
-            self::$_instance = new self($grand_total, $session);
70
-        }
71
-        // or maybe retrieve an existing one ?
72
-        if ( ! self::$_instance instanceof EE_Cart) {
73
-            // try getting the cart out of the session
74
-            $saved_cart = $session instanceof EE_Session ? $session->cart() : null;
75
-            self::$_instance = $saved_cart instanceof EE_Cart ? $saved_cart : new self($grand_total, $session);
76
-            unset($saved_cart);
77
-        }
78
-        // verify that cart is ok and grand total line item exists
79
-        if ( ! self::$_instance instanceof EE_Cart || ! self::$_instance->_grand_total instanceof EE_Line_Item) {
80
-            self::$_instance = new self($grand_total, $session);
81
-        }
82
-        self::$_instance->get_grand_total();
83
-        // once everything is all said and done, save the cart to the EE_Session
84
-        add_action('shutdown', array(self::$_instance, 'save_cart'), 90);
85
-        return self::$_instance;
86
-    }
87
-
88
-
89
-
90
-    /**
91
-     * private constructor to prevent direct creation
92
-     *
93
-     * @Constructor
94
-     * @access private
95
-     * @param EE_Line_Item $grand_total
96
-     * @param EE_Session   $session
97
-     */
98
-    private function __construct(EE_Line_Item $grand_total = null, EE_Session $session = null)
99
-    {
100
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
101
-        $this->set_session($session);
102
-        if ($grand_total instanceof EE_Line_Item) {
103
-            $this->set_grand_total_line_item($grand_total);
104
-        }
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * Resets the cart completely (whereas empty_cart
111
-     *
112
-     * @param EE_Line_Item $grand_total
113
-     * @param EE_Session   $session
114
-     * @return EE_Cart
115
-     * @throws \EE_Error
116
-     */
117
-    public static function reset(EE_Line_Item $grand_total = null, EE_Session $session = null)
118
-    {
119
-        remove_action('shutdown', array(self::$_instance, 'save_cart'), 90);
120
-        if ($session instanceof EE_Session) {
121
-            $session->reset_cart();
122
-        }
123
-        self::$_instance = null;
124
-        return self::instance($grand_total, $session);
125
-    }
126
-
127
-
128
-
129
-    /**
130
-     * @return \EE_Session
131
-     */
132
-    public function session()
133
-    {
134
-        if ( ! $this->_session instanceof EE_Session) {
135
-            $this->set_session();
136
-        }
137
-        return $this->_session;
138
-    }
139
-
140
-
141
-
142
-    /**
143
-     * @param EE_Session $session
144
-     */
145
-    public function set_session(EE_Session $session = null)
146
-    {
147
-        $this->_session = $session instanceof EE_Session ? $session : EE_Registry::instance()->load_core('Session');
148
-    }
149
-
150
-
151
-
152
-    /**
153
-     * Sets the cart to match the line item. Especially handy for loading an old cart where you
154
-     *  know the grand total line item on it
155
-     *
156
-     * @param EE_Line_Item $line_item
157
-     */
158
-    public function set_grand_total_line_item(EE_Line_Item $line_item)
159
-    {
160
-        $this->_grand_total = $line_item;
161
-    }
162
-
163
-
164
-
165
-    /**
166
-     * get_cart_from_reg_url_link
167
-     *
168
-     * @access public
169
-     * @param EE_Transaction $transaction
170
-     * @param EE_Session     $session
171
-     * @return \EE_Cart
172
-     * @throws \EE_Error
173
-     */
174
-    public static function get_cart_from_txn(EE_Transaction $transaction, EE_Session $session = null)
175
-    {
176
-        $grand_total = $transaction->total_line_item();
177
-        $grand_total->get_items();
178
-        $grand_total->tax_descendants();
179
-        return EE_Cart::instance($grand_total, $session);
180
-    }
181
-
182
-
183
-
184
-    /**
185
-     * Creates the total line item, and ensures it has its 'tickets' and 'taxes' sub-items
186
-     *
187
-     * @return EE_Line_Item
188
-     * @throws \EE_Error
189
-     */
190
-    private function _create_grand_total()
191
-    {
192
-        $this->_grand_total = EEH_Line_Item::create_total_line_item();
193
-        return $this->_grand_total;
194
-    }
195
-
196
-
197
-
198
-    /**
199
-     * Gets all the line items of object type Ticket
200
-     *
201
-     * @access public
202
-     * @return \EE_Line_Item[]
203
-     */
204
-    public function get_tickets()
205
-    {
206
-        if ($this->_grand_total === null ) {
207
-            return array();
208
-        }
209
-        return EEH_Line_Item::get_ticket_line_items($this->_grand_total);
210
-    }
211
-
212
-
213
-
214
-    /**
215
-     * returns the total quantity of tickets in the cart
216
-     *
217
-     * @access public
218
-     * @return int
219
-     * @throws \EE_Error
220
-     */
221
-    public function all_ticket_quantity_count()
222
-    {
223
-        $tickets = $this->get_tickets();
224
-        if (empty($tickets)) {
225
-            return 0;
226
-        }
227
-        $count = 0;
228
-        foreach ($tickets as $ticket) {
229
-            $count += $ticket->get('LIN_quantity');
230
-        }
231
-        return $count;
232
-    }
233
-
234
-
235
-
236
-    /**
237
-     * Gets all the tax line items
238
-     *
239
-     * @return \EE_Line_Item[]
240
-     * @throws \EE_Error
241
-     */
242
-    public function get_taxes()
243
-    {
244
-        return EEH_Line_Item::get_taxes_subtotal($this->_grand_total)->children();
245
-    }
246
-
247
-
248
-
249
-    /**
250
-     * Gets the total line item (which is a parent of all other line items) on this cart
251
-     *
252
-     * @return EE_Line_Item
253
-     * @throws \EE_Error
254
-     */
255
-    public function get_grand_total()
256
-    {
257
-        return $this->_grand_total instanceof EE_Line_Item ? $this->_grand_total : $this->_create_grand_total();
258
-    }
259
-
260
-
261
-
262
-    /**
263
-     * @process items for adding to cart
264
-     * @access  public
265
-     * @param EE_Ticket $ticket
266
-     * @param int       $qty
267
-     * @return TRUE on success, FALSE on fail
268
-     * @throws \EE_Error
269
-     */
270
-    public function add_ticket_to_cart(EE_Ticket $ticket, $qty = 1)
271
-    {
272
-        EEH_Line_Item::add_ticket_purchase($this->get_grand_total(), $ticket, $qty);
273
-        return $this->save_cart() ? true : false;
274
-    }
275
-
276
-
277
-
278
-    /**
279
-     * get_cart_total_before_tax
280
-     *
281
-     * @access public
282
-     * @return float
283
-     * @throws \EE_Error
284
-     */
285
-    public function get_cart_total_before_tax()
286
-    {
287
-        return $this->get_grand_total()->recalculate_pre_tax_total();
288
-    }
289
-
290
-
291
-
292
-    /**
293
-     * gets the total amount of tax paid for items in this cart
294
-     *
295
-     * @access public
296
-     * @return float
297
-     * @throws \EE_Error
298
-     */
299
-    public function get_applied_taxes()
300
-    {
301
-        return EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
302
-    }
303
-
304
-
305
-
306
-    /**
307
-     * Gets the total amount to be paid for the items in the cart, including taxes and other modifiers
308
-     *
309
-     * @access public
310
-     * @return float
311
-     * @throws \EE_Error
312
-     */
313
-    public function get_cart_grand_total()
314
-    {
315
-        EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
316
-        return $this->get_grand_total()->total();
317
-    }
318
-
319
-
320
-
321
-    /**
322
-     * Gets the total amount to be paid for the items in the cart, including taxes and other modifiers
323
-     *
324
-     * @access public
325
-     * @return float
326
-     * @throws \EE_Error
327
-     */
328
-    public function recalculate_all_cart_totals()
329
-    {
330
-        $pre_tax_total = $this->get_cart_total_before_tax();
331
-        $taxes_total = EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
332
-        $this->_grand_total->set_total($pre_tax_total + $taxes_total);
333
-        $this->_grand_total->save_this_and_descendants_to_txn();
334
-        return $this->get_grand_total()->total();
335
-    }
336
-
337
-
338
-
339
-    /**
340
-     * deletes an item from the cart
341
-     *
342
-     * @access public
343
-     * @param array|bool|string $line_item_codes
344
-     * @return int on success, FALSE on fail
345
-     * @throws \EE_Error
346
-     */
347
-    public function delete_items($line_item_codes = false)
348
-    {
349
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
350
-        return EEH_Line_Item::delete_items($this->get_grand_total(), $line_item_codes);
351
-    }
352
-
353
-
354
-
355
-    /**
356
-     * @remove ALL items from cart and zero ALL totals
357
-     * @access public
358
-     * @return bool
359
-     * @throws \EE_Error
360
-     */
361
-    public function empty_cart()
362
-    {
363
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
364
-        $this->_grand_total = $this->_create_grand_total();
365
-        return $this->save_cart(true);
366
-    }
367
-
368
-
369
-
370
-    /**
371
-     * @remove ALL items from cart and delete total as well
372
-     * @access public
373
-     * @return bool
374
-     * @throws \EE_Error
375
-     */
376
-    public function delete_cart()
377
-    {
378
-        $deleted = EEH_Line_Item::delete_all_child_items($this->_grand_total);
379
-        if ($deleted) {
380
-            $deleted += $this->_grand_total->delete();
381
-            $this->_grand_total = null;
382
-        }
383
-        return $deleted;
384
-    }
385
-
386
-
387
-
388
-    /**
389
-     * @save   cart to session
390
-     * @access public
391
-     * @param bool $apply_taxes
392
-     * @return TRUE on success, FALSE on fail
393
-     * @throws \EE_Error
394
-     */
395
-    public function save_cart($apply_taxes = true)
396
-    {
397
-        if ($apply_taxes && $this->_grand_total instanceof EE_Line_Item) {
398
-            EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
399
-            //make sure we don't cache the transaction because it can get stale
400
-            if ($this->_grand_total->get_one_from_cache('Transaction') instanceof EE_Transaction
401
-                && $this->_grand_total->get_one_from_cache('Transaction')->ID()
402
-            ) {
403
-                $this->_grand_total->clear_cache('Transaction', null, true);
404
-            }
405
-        }
406
-        if ($this->session() instanceof EE_Session) {
407
-            return $this->session()->set_cart($this);
408
-        } else {
409
-            return false;
410
-        }
411
-    }
412
-
413
-
414
-
415
-    public function __wakeup()
416
-    {
417
-        if ( ! $this->_grand_total instanceof EE_Line_Item && absint($this->_grand_total) !== 0) {
418
-            // $this->_grand_total is actually just an ID, so use it to get the object from the db
419
-            $this->_grand_total = EEM_Line_Item::instance()->get_one_by_ID($this->_grand_total);
420
-        }
421
-    }
422
-
423
-
424
-
425
-    /**
426
-     * @return array
427
-     */
428
-    public function __sleep()
429
-    {
430
-        if ($this->_grand_total instanceof EE_Line_Item && $this->_grand_total->ID()) {
431
-            $this->_grand_total = $this->_grand_total->ID();
432
-        }
433
-        return array('_grand_total');
434
-    }
23
+	/**
24
+	 * instance of the EE_Cart object
25
+	 *
26
+	 * @access    private
27
+	 * @var EE_Cart $_instance
28
+	 */
29
+	private static $_instance;
30
+
31
+	/**
32
+	 * instance of the EE_Session object
33
+	 *
34
+	 * @access    protected
35
+	 * @var EE_Session $_session
36
+	 */
37
+	protected $_session;
38
+
39
+	/**
40
+	 * The total Line item which comprises all the children line-item subtotals,
41
+	 * which in turn each have their line items.
42
+	 * Typically, the line item structure will look like:
43
+	 * grand total
44
+	 * -tickets-sub-total
45
+	 * --ticket1
46
+	 * --ticket2
47
+	 * --...
48
+	 * -taxes-sub-total
49
+	 * --tax1
50
+	 * --tax2
51
+	 *
52
+	 * @var EE_Line_Item
53
+	 */
54
+	private $_grand_total;
55
+
56
+
57
+
58
+	/**
59
+	 * @singleton method used to instantiate class object
60
+	 * @access    public
61
+	 * @param EE_Line_Item $grand_total
62
+	 * @param EE_Session   $session
63
+	 * @return \EE_Cart
64
+	 * @throws \EE_Error
65
+	 */
66
+	public static function instance(EE_Line_Item $grand_total = null, EE_Session $session = null)
67
+	{
68
+		if ( ! empty($grand_total)) {
69
+			self::$_instance = new self($grand_total, $session);
70
+		}
71
+		// or maybe retrieve an existing one ?
72
+		if ( ! self::$_instance instanceof EE_Cart) {
73
+			// try getting the cart out of the session
74
+			$saved_cart = $session instanceof EE_Session ? $session->cart() : null;
75
+			self::$_instance = $saved_cart instanceof EE_Cart ? $saved_cart : new self($grand_total, $session);
76
+			unset($saved_cart);
77
+		}
78
+		// verify that cart is ok and grand total line item exists
79
+		if ( ! self::$_instance instanceof EE_Cart || ! self::$_instance->_grand_total instanceof EE_Line_Item) {
80
+			self::$_instance = new self($grand_total, $session);
81
+		}
82
+		self::$_instance->get_grand_total();
83
+		// once everything is all said and done, save the cart to the EE_Session
84
+		add_action('shutdown', array(self::$_instance, 'save_cart'), 90);
85
+		return self::$_instance;
86
+	}
87
+
88
+
89
+
90
+	/**
91
+	 * private constructor to prevent direct creation
92
+	 *
93
+	 * @Constructor
94
+	 * @access private
95
+	 * @param EE_Line_Item $grand_total
96
+	 * @param EE_Session   $session
97
+	 */
98
+	private function __construct(EE_Line_Item $grand_total = null, EE_Session $session = null)
99
+	{
100
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
101
+		$this->set_session($session);
102
+		if ($grand_total instanceof EE_Line_Item) {
103
+			$this->set_grand_total_line_item($grand_total);
104
+		}
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * Resets the cart completely (whereas empty_cart
111
+	 *
112
+	 * @param EE_Line_Item $grand_total
113
+	 * @param EE_Session   $session
114
+	 * @return EE_Cart
115
+	 * @throws \EE_Error
116
+	 */
117
+	public static function reset(EE_Line_Item $grand_total = null, EE_Session $session = null)
118
+	{
119
+		remove_action('shutdown', array(self::$_instance, 'save_cart'), 90);
120
+		if ($session instanceof EE_Session) {
121
+			$session->reset_cart();
122
+		}
123
+		self::$_instance = null;
124
+		return self::instance($grand_total, $session);
125
+	}
126
+
127
+
128
+
129
+	/**
130
+	 * @return \EE_Session
131
+	 */
132
+	public function session()
133
+	{
134
+		if ( ! $this->_session instanceof EE_Session) {
135
+			$this->set_session();
136
+		}
137
+		return $this->_session;
138
+	}
139
+
140
+
141
+
142
+	/**
143
+	 * @param EE_Session $session
144
+	 */
145
+	public function set_session(EE_Session $session = null)
146
+	{
147
+		$this->_session = $session instanceof EE_Session ? $session : EE_Registry::instance()->load_core('Session');
148
+	}
149
+
150
+
151
+
152
+	/**
153
+	 * Sets the cart to match the line item. Especially handy for loading an old cart where you
154
+	 *  know the grand total line item on it
155
+	 *
156
+	 * @param EE_Line_Item $line_item
157
+	 */
158
+	public function set_grand_total_line_item(EE_Line_Item $line_item)
159
+	{
160
+		$this->_grand_total = $line_item;
161
+	}
162
+
163
+
164
+
165
+	/**
166
+	 * get_cart_from_reg_url_link
167
+	 *
168
+	 * @access public
169
+	 * @param EE_Transaction $transaction
170
+	 * @param EE_Session     $session
171
+	 * @return \EE_Cart
172
+	 * @throws \EE_Error
173
+	 */
174
+	public static function get_cart_from_txn(EE_Transaction $transaction, EE_Session $session = null)
175
+	{
176
+		$grand_total = $transaction->total_line_item();
177
+		$grand_total->get_items();
178
+		$grand_total->tax_descendants();
179
+		return EE_Cart::instance($grand_total, $session);
180
+	}
181
+
182
+
183
+
184
+	/**
185
+	 * Creates the total line item, and ensures it has its 'tickets' and 'taxes' sub-items
186
+	 *
187
+	 * @return EE_Line_Item
188
+	 * @throws \EE_Error
189
+	 */
190
+	private function _create_grand_total()
191
+	{
192
+		$this->_grand_total = EEH_Line_Item::create_total_line_item();
193
+		return $this->_grand_total;
194
+	}
195
+
196
+
197
+
198
+	/**
199
+	 * Gets all the line items of object type Ticket
200
+	 *
201
+	 * @access public
202
+	 * @return \EE_Line_Item[]
203
+	 */
204
+	public function get_tickets()
205
+	{
206
+		if ($this->_grand_total === null ) {
207
+			return array();
208
+		}
209
+		return EEH_Line_Item::get_ticket_line_items($this->_grand_total);
210
+	}
211
+
212
+
213
+
214
+	/**
215
+	 * returns the total quantity of tickets in the cart
216
+	 *
217
+	 * @access public
218
+	 * @return int
219
+	 * @throws \EE_Error
220
+	 */
221
+	public function all_ticket_quantity_count()
222
+	{
223
+		$tickets = $this->get_tickets();
224
+		if (empty($tickets)) {
225
+			return 0;
226
+		}
227
+		$count = 0;
228
+		foreach ($tickets as $ticket) {
229
+			$count += $ticket->get('LIN_quantity');
230
+		}
231
+		return $count;
232
+	}
233
+
234
+
235
+
236
+	/**
237
+	 * Gets all the tax line items
238
+	 *
239
+	 * @return \EE_Line_Item[]
240
+	 * @throws \EE_Error
241
+	 */
242
+	public function get_taxes()
243
+	{
244
+		return EEH_Line_Item::get_taxes_subtotal($this->_grand_total)->children();
245
+	}
246
+
247
+
248
+
249
+	/**
250
+	 * Gets the total line item (which is a parent of all other line items) on this cart
251
+	 *
252
+	 * @return EE_Line_Item
253
+	 * @throws \EE_Error
254
+	 */
255
+	public function get_grand_total()
256
+	{
257
+		return $this->_grand_total instanceof EE_Line_Item ? $this->_grand_total : $this->_create_grand_total();
258
+	}
259
+
260
+
261
+
262
+	/**
263
+	 * @process items for adding to cart
264
+	 * @access  public
265
+	 * @param EE_Ticket $ticket
266
+	 * @param int       $qty
267
+	 * @return TRUE on success, FALSE on fail
268
+	 * @throws \EE_Error
269
+	 */
270
+	public function add_ticket_to_cart(EE_Ticket $ticket, $qty = 1)
271
+	{
272
+		EEH_Line_Item::add_ticket_purchase($this->get_grand_total(), $ticket, $qty);
273
+		return $this->save_cart() ? true : false;
274
+	}
275
+
276
+
277
+
278
+	/**
279
+	 * get_cart_total_before_tax
280
+	 *
281
+	 * @access public
282
+	 * @return float
283
+	 * @throws \EE_Error
284
+	 */
285
+	public function get_cart_total_before_tax()
286
+	{
287
+		return $this->get_grand_total()->recalculate_pre_tax_total();
288
+	}
289
+
290
+
291
+
292
+	/**
293
+	 * gets the total amount of tax paid for items in this cart
294
+	 *
295
+	 * @access public
296
+	 * @return float
297
+	 * @throws \EE_Error
298
+	 */
299
+	public function get_applied_taxes()
300
+	{
301
+		return EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
302
+	}
303
+
304
+
305
+
306
+	/**
307
+	 * Gets the total amount to be paid for the items in the cart, including taxes and other modifiers
308
+	 *
309
+	 * @access public
310
+	 * @return float
311
+	 * @throws \EE_Error
312
+	 */
313
+	public function get_cart_grand_total()
314
+	{
315
+		EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
316
+		return $this->get_grand_total()->total();
317
+	}
318
+
319
+
320
+
321
+	/**
322
+	 * Gets the total amount to be paid for the items in the cart, including taxes and other modifiers
323
+	 *
324
+	 * @access public
325
+	 * @return float
326
+	 * @throws \EE_Error
327
+	 */
328
+	public function recalculate_all_cart_totals()
329
+	{
330
+		$pre_tax_total = $this->get_cart_total_before_tax();
331
+		$taxes_total = EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
332
+		$this->_grand_total->set_total($pre_tax_total + $taxes_total);
333
+		$this->_grand_total->save_this_and_descendants_to_txn();
334
+		return $this->get_grand_total()->total();
335
+	}
336
+
337
+
338
+
339
+	/**
340
+	 * deletes an item from the cart
341
+	 *
342
+	 * @access public
343
+	 * @param array|bool|string $line_item_codes
344
+	 * @return int on success, FALSE on fail
345
+	 * @throws \EE_Error
346
+	 */
347
+	public function delete_items($line_item_codes = false)
348
+	{
349
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
350
+		return EEH_Line_Item::delete_items($this->get_grand_total(), $line_item_codes);
351
+	}
352
+
353
+
354
+
355
+	/**
356
+	 * @remove ALL items from cart and zero ALL totals
357
+	 * @access public
358
+	 * @return bool
359
+	 * @throws \EE_Error
360
+	 */
361
+	public function empty_cart()
362
+	{
363
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
364
+		$this->_grand_total = $this->_create_grand_total();
365
+		return $this->save_cart(true);
366
+	}
367
+
368
+
369
+
370
+	/**
371
+	 * @remove ALL items from cart and delete total as well
372
+	 * @access public
373
+	 * @return bool
374
+	 * @throws \EE_Error
375
+	 */
376
+	public function delete_cart()
377
+	{
378
+		$deleted = EEH_Line_Item::delete_all_child_items($this->_grand_total);
379
+		if ($deleted) {
380
+			$deleted += $this->_grand_total->delete();
381
+			$this->_grand_total = null;
382
+		}
383
+		return $deleted;
384
+	}
385
+
386
+
387
+
388
+	/**
389
+	 * @save   cart to session
390
+	 * @access public
391
+	 * @param bool $apply_taxes
392
+	 * @return TRUE on success, FALSE on fail
393
+	 * @throws \EE_Error
394
+	 */
395
+	public function save_cart($apply_taxes = true)
396
+	{
397
+		if ($apply_taxes && $this->_grand_total instanceof EE_Line_Item) {
398
+			EEH_Line_Item::ensure_taxes_applied($this->_grand_total);
399
+			//make sure we don't cache the transaction because it can get stale
400
+			if ($this->_grand_total->get_one_from_cache('Transaction') instanceof EE_Transaction
401
+				&& $this->_grand_total->get_one_from_cache('Transaction')->ID()
402
+			) {
403
+				$this->_grand_total->clear_cache('Transaction', null, true);
404
+			}
405
+		}
406
+		if ($this->session() instanceof EE_Session) {
407
+			return $this->session()->set_cart($this);
408
+		} else {
409
+			return false;
410
+		}
411
+	}
412
+
413
+
414
+
415
+	public function __wakeup()
416
+	{
417
+		if ( ! $this->_grand_total instanceof EE_Line_Item && absint($this->_grand_total) !== 0) {
418
+			// $this->_grand_total is actually just an ID, so use it to get the object from the db
419
+			$this->_grand_total = EEM_Line_Item::instance()->get_one_by_ID($this->_grand_total);
420
+		}
421
+	}
422
+
423
+
424
+
425
+	/**
426
+	 * @return array
427
+	 */
428
+	public function __sleep()
429
+	{
430
+		if ($this->_grand_total instanceof EE_Line_Item && $this->_grand_total->ID()) {
431
+			$this->_grand_total = $this->_grand_total->ID();
432
+		}
433
+		return array('_grand_total');
434
+	}
435 435
 
436 436
 
437 437
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -203,7 +203,7 @@
 block discarded – undo
203 203
      */
204 204
     public function get_tickets()
205 205
     {
206
-        if ($this->_grand_total === null ) {
206
+        if ($this->_grand_total === null) {
207 207
             return array();
208 208
         }
209 209
         return EEH_Line_Item::get_ticket_line_items($this->_grand_total);
Please login to merge, or discard this patch.
core/EE_Registry.core.php 3 patches
Doc Comments   +1 added lines patch added patch discarded remove patch
@@ -298,6 +298,7 @@
 block discarded – undo
298 298
 
299 299
     /**
300 300
      * @param mixed string | EED_Module $module
301
+     * @param string $module
301 302
      */
302 303
     public function add_module($module)
303 304
     {
Please login to merge, or discard this patch.
Indentation   +1428 added lines, -1428 removed lines patch added patch discarded remove patch
@@ -16,1464 +16,1464 @@
 block discarded – undo
16 16
 class EE_Registry
17 17
 {
18 18
 
19
-    /**
20
-     *    EE_Registry Object
21
-     *
22
-     * @var EE_Registry $_instance
23
-     * @access    private
24
-     */
25
-    private static $_instance = null;
26
-
27
-    /**
28
-     * @var EE_Dependency_Map $_dependency_map
29
-     * @access    protected
30
-     */
31
-    protected $_dependency_map = null;
32
-
33
-    /**
34
-     * @var array $_class_abbreviations
35
-     * @access    protected
36
-     */
37
-    protected $_class_abbreviations = array();
38
-
39
-    /**
40
-     * @access public
41
-     * @var \EventEspresso\core\services\commands\CommandBusInterface $BUS
42
-     */
43
-    public $BUS;
44
-
45
-    /**
46
-     *    EE_Cart Object
47
-     *
48
-     * @access    public
49
-     * @var    EE_Cart $CART
50
-     */
51
-    public $CART = null;
52
-
53
-    /**
54
-     *    EE_Config Object
55
-     *
56
-     * @access    public
57
-     * @var    EE_Config $CFG
58
-     */
59
-    public $CFG = null;
60
-
61
-    /**
62
-     * EE_Network_Config Object
63
-     *
64
-     * @access public
65
-     * @var EE_Network_Config $NET_CFG
66
-     */
67
-    public $NET_CFG = null;
68
-
69
-    /**
70
-     *    StdClass object for storing library classes in
71
-     *
72
-     * @public LIB
73
-     * @var StdClass $LIB
74
-     */
75
-    public $LIB = null;
76
-
77
-    /**
78
-     *    EE_Request_Handler Object
79
-     *
80
-     * @access    public
81
-     * @var    EE_Request_Handler $REQ
82
-     */
83
-    public $REQ = null;
84
-
85
-    /**
86
-     *    EE_Session Object
87
-     *
88
-     * @access    public
89
-     * @var    EE_Session $SSN
90
-     */
91
-    public $SSN = null;
92
-
93
-    /**
94
-     * holds the ee capabilities object.
95
-     *
96
-     * @since 4.5.0
97
-     * @var EE_Capabilities
98
-     */
99
-    public $CAP = null;
100
-
101
-    /**
102
-     * holds the EE_Message_Resource_Manager object.
103
-     *
104
-     * @since 4.9.0
105
-     * @var EE_Message_Resource_Manager
106
-     */
107
-    public $MRM = null;
108
-
109
-
110
-    /**
111
-     * Holds the Assets Registry instance
112
-     * @var Registry
113
-     */
114
-    public $AssetsRegistry = null;
115
-
116
-    /**
117
-     * StdClass object for holding addons which have registered themselves to work with EE core
118
-     *
119
-     * @var StdClass
120
-     */
121
-    public $addons = null;
122
-
123
-    /**
124
-     *    $models
125
-     * @access    public
126
-     * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
127
-     */
128
-    public $models = array();
129
-
130
-    /**
131
-     *    $modules
132
-     * @access    public
133
-     * @var    EED_Module[] $modules
134
-     */
135
-    public $modules = null;
136
-
137
-    /**
138
-     *    $shortcodes
139
-     * @access    public
140
-     * @var    EES_Shortcode[] $shortcodes
141
-     */
142
-    public $shortcodes = null;
143
-
144
-    /**
145
-     *    $widgets
146
-     * @access    public
147
-     * @var    WP_Widget[] $widgets
148
-     */
149
-    public $widgets = null;
150
-
151
-    /**
152
-     * $non_abstract_db_models
153
-     * @access public
154
-     * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
155
-     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
156
-     * Keys are model "short names" (eg "Event") as used in model relations, and values are
157
-     * classnames (eg "EEM_Event")
158
-     */
159
-    public $non_abstract_db_models = array();
160
-
161
-
162
-    /**
163
-     *    $i18n_js_strings - internationalization for JS strings
164
-     *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
165
-     *    in js file:  var translatedString = eei18n.string_key;
166
-     *
167
-     * @access    public
168
-     * @var    array
169
-     */
170
-    public static $i18n_js_strings = array();
171
-
172
-
173
-    /**
174
-     *    $main_file - path to espresso.php
175
-     *
176
-     * @access    public
177
-     * @var    array
178
-     */
179
-    public $main_file;
180
-
181
-    /**
182
-     * array of ReflectionClass objects where the key is the class name
183
-     *
184
-     * @access    public
185
-     * @var ReflectionClass[]
186
-     */
187
-    public $_reflectors;
188
-
189
-    /**
190
-     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
191
-     *
192
-     * @access    protected
193
-     * @var boolean $_cache_on
194
-     */
195
-    protected $_cache_on = true;
196
-
197
-
198
-
199
-    /**
200
-     * @singleton method used to instantiate class object
201
-     * @access    public
202
-     * @param  \EE_Dependency_Map $dependency_map
203
-     * @return \EE_Registry instance
204
-     */
205
-    public static function instance(\EE_Dependency_Map $dependency_map = null)
206
-    {
207
-        // check if class object is instantiated
208
-        if ( ! self::$_instance instanceof EE_Registry) {
209
-            self::$_instance = new EE_Registry($dependency_map);
210
-        }
211
-        return self::$_instance;
212
-    }
213
-
214
-
215
-
216
-    /**
217
-     *protected constructor to prevent direct creation
218
-     *
219
-     * @Constructor
220
-     * @access protected
221
-     * @param  \EE_Dependency_Map $dependency_map
222
-     */
223
-    protected function __construct(\EE_Dependency_Map $dependency_map)
224
-    {
225
-        $this->_dependency_map = $dependency_map;
226
-        $this->LIB = new stdClass();
227
-        $this->addons = new stdClass();
228
-        $this->modules = new stdClass();
229
-        $this->shortcodes = new stdClass();
230
-        $this->widgets = new stdClass();
231
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
232
-    }
233
-
234
-
235
-
236
-    /**
237
-     * initialize
238
-     */
239
-    public function initialize()
240
-    {
241
-        $this->_class_abbreviations = apply_filters(
242
-            'FHEE__EE_Registry____construct___class_abbreviations',
243
-            array(
244
-                'EE_Config'                                       => 'CFG',
245
-                'EE_Session'                                      => 'SSN',
246
-                'EE_Capabilities'                                 => 'CAP',
247
-                'EE_Cart'                                         => 'CART',
248
-                'EE_Network_Config'                               => 'NET_CFG',
249
-                'EE_Request_Handler'                              => 'REQ',
250
-                'EE_Message_Resource_Manager'                     => 'MRM',
251
-                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
252
-                'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
253
-            )
254
-        );
255
-        $this->load_core('Base', array(), true);
256
-        // add our request and response objects to the cache
257
-        $request_loader = $this->_dependency_map->class_loader('EE_Request');
258
-        $this->_set_cached_class(
259
-            $request_loader(),
260
-            'EE_Request'
261
-        );
262
-        $response_loader = $this->_dependency_map->class_loader('EE_Response');
263
-        $this->_set_cached_class(
264
-            $response_loader(),
265
-            'EE_Response'
266
-        );
267
-        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
268
-    }
269
-
270
-
271
-
272
-    /**
273
-     *    init
274
-     *
275
-     * @access    public
276
-     * @return    void
277
-     */
278
-    public function init()
279
-    {
280
-        // Get current page protocol
281
-        $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
282
-        // Output admin-ajax.php URL with same protocol as current page
283
-        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
284
-        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
285
-    }
286
-
287
-
288
-
289
-    /**
290
-     * localize_i18n_js_strings
291
-     *
292
-     * @return string
293
-     */
294
-    public static function localize_i18n_js_strings()
295
-    {
296
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
297
-        foreach ($i18n_js_strings as $key => $value) {
298
-            if (is_scalar($value)) {
299
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
300
-            }
301
-        }
302
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
303
-    }
304
-
305
-
306
-
307
-    /**
308
-     * @param mixed string | EED_Module $module
309
-     */
310
-    public function add_module($module)
311
-    {
312
-        if ($module instanceof EED_Module) {
313
-            $module_class = get_class($module);
314
-            $this->modules->{$module_class} = $module;
315
-        } else {
316
-            if ( ! class_exists('EE_Module_Request_Router')) {
317
-                $this->load_core('Module_Request_Router');
318
-            }
319
-            $this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
320
-        }
321
-    }
322
-
323
-
324
-
325
-    /**
326
-     * @param string $module_name
327
-     * @return mixed EED_Module | NULL
328
-     */
329
-    public function get_module($module_name = '')
330
-    {
331
-        return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
332
-    }
333
-
334
-
335
-
336
-    /**
337
-     *    loads core classes - must be singletons
338
-     *
339
-     * @access    public
340
-     * @param string $class_name - simple class name ie: session
341
-     * @param mixed  $arguments
342
-     * @param bool   $load_only
343
-     * @return mixed
344
-     */
345
-    public function load_core($class_name, $arguments = array(), $load_only = false)
346
-    {
347
-        $core_paths = apply_filters(
348
-            'FHEE__EE_Registry__load_core__core_paths',
349
-            array(
350
-                EE_CORE,
351
-                EE_ADMIN,
352
-                EE_CPTS,
353
-                EE_CORE . 'data_migration_scripts' . DS,
354
-                EE_CORE . 'request_stack' . DS,
355
-                EE_CORE . 'middleware' . DS,
356
-            )
357
-        );
358
-        // retrieve instantiated class
359
-        return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
360
-    }
361
-
362
-
363
-
364
-    /**
365
-     *    loads service classes
366
-     *
367
-     * @access    public
368
-     * @param string $class_name - simple class name ie: session
369
-     * @param mixed  $arguments
370
-     * @param bool   $load_only
371
-     * @return mixed
372
-     */
373
-    public function load_service($class_name, $arguments = array(), $load_only = false)
374
-    {
375
-        $service_paths = apply_filters(
376
-            'FHEE__EE_Registry__load_service__service_paths',
377
-            array(
378
-                EE_CORE . 'services' . DS,
379
-            )
380
-        );
381
-        // retrieve instantiated class
382
-        return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
383
-    }
384
-
385
-
386
-
387
-    /**
388
-     *    loads data_migration_scripts
389
-     *
390
-     * @access    public
391
-     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
392
-     * @param mixed  $arguments
393
-     * @return EE_Data_Migration_Script_Base|mixed
394
-     */
395
-    public function load_dms($class_name, $arguments = array())
396
-    {
397
-        // retrieve instantiated class
398
-        return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
399
-    }
400
-
401
-
402
-
403
-    /**
404
-     *    loads object creating classes - must be singletons
405
-     *
406
-     * @param string $class_name - simple class name ie: attendee
407
-     * @param mixed  $arguments  - an array of arguments to pass to the class
408
-     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
409
-     * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then set this to FALSE (ie. when instantiating model objects from client in a loop)
410
-     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
411
-     * @return EE_Base_Class | bool
412
-     */
413
-    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
414
-    {
415
-        $paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
416
-            EE_CORE,
417
-            EE_CLASSES,
418
-            EE_BUSINESS,
419
-        ));
420
-        // retrieve instantiated class
421
-        return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
422
-    }
423
-
424
-
425
-
426
-    /**
427
-     *    loads helper classes - must be singletons
428
-     *
429
-     * @param string $class_name - simple class name ie: price
430
-     * @param mixed  $arguments
431
-     * @param bool   $load_only
432
-     * @return EEH_Base | bool
433
-     */
434
-    public function load_helper($class_name, $arguments = array(), $load_only = true)
435
-    {
436
-        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
437
-        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
438
-        // retrieve instantiated class
439
-        return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
440
-    }
441
-
442
-
443
-
444
-    /**
445
-     *    loads core classes - must be singletons
446
-     *
447
-     * @access    public
448
-     * @param string $class_name - simple class name ie: session
449
-     * @param mixed  $arguments
450
-     * @param bool   $load_only
451
-     * @param bool   $cache      whether to cache the object or not.
452
-     * @return mixed
453
-     */
454
-    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
455
-    {
456
-        $paths = array(
457
-            EE_LIBRARIES,
458
-            EE_LIBRARIES . 'messages' . DS,
459
-            EE_LIBRARIES . 'shortcodes' . DS,
460
-            EE_LIBRARIES . 'qtips' . DS,
461
-            EE_LIBRARIES . 'payment_methods' . DS,
462
-        );
463
-        // retrieve instantiated class
464
-        return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
465
-    }
466
-
467
-
468
-
469
-    /**
470
-     *    loads model classes - must be singletons
471
-     *
472
-     * @param string $class_name - simple class name ie: price
473
-     * @param mixed  $arguments
474
-     * @param bool   $load_only
475
-     * @return EEM_Base | bool
476
-     */
477
-    public function load_model($class_name, $arguments = array(), $load_only = false)
478
-    {
479
-        $paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
480
-            EE_MODELS,
481
-            EE_CORE,
482
-        ));
483
-        // retrieve instantiated class
484
-        return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
485
-    }
486
-
487
-
488
-
489
-    /**
490
-     *    loads model classes - must be singletons
491
-     *
492
-     * @param string $class_name - simple class name ie: price
493
-     * @param mixed  $arguments
494
-     * @param bool   $load_only
495
-     * @return mixed | bool
496
-     */
497
-    public function load_model_class($class_name, $arguments = array(), $load_only = true)
498
-    {
499
-        $paths = array(
500
-            EE_MODELS . 'fields' . DS,
501
-            EE_MODELS . 'helpers' . DS,
502
-            EE_MODELS . 'relations' . DS,
503
-            EE_MODELS . 'strategies' . DS,
504
-        );
505
-        // retrieve instantiated class
506
-        return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
507
-    }
508
-
509
-
510
-
511
-    /**
512
-     * Determines if $model_name is the name of an actual EE model.
513
-     *
514
-     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
515
-     * @return boolean
516
-     */
517
-    public function is_model_name($model_name)
518
-    {
519
-        return isset($this->models[$model_name]) ? true : false;
520
-    }
521
-
522
-
523
-
524
-    /**
525
-     *    generic class loader
526
-     *
527
-     * @param string $path_to_file - directory path to file location, not including filename
528
-     * @param string $file_name    - file name  ie:  my_file.php, including extension
529
-     * @param string $type         - file type - core? class? helper? model?
530
-     * @param mixed  $arguments
531
-     * @param bool   $load_only
532
-     * @return mixed
533
-     */
534
-    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
535
-    {
536
-        // retrieve instantiated class
537
-        return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
538
-    }
539
-
540
-
541
-
542
-    /**
543
-     *    load_addon
544
-     *
545
-     * @param string $path_to_file - directory path to file location, not including filename
546
-     * @param string $class_name   - full class name  ie:  My_Class
547
-     * @param string $type         - file type - core? class? helper? model?
548
-     * @param mixed  $arguments
549
-     * @param bool   $load_only
550
-     * @return EE_Addon
551
-     */
552
-    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
553
-    {
554
-        // retrieve instantiated class
555
-        return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
556
-    }
557
-
558
-
559
-
560
-    /**
561
-     * instantiates, caches, and automatically resolves dependencies
562
-     * for classes that use a Fully Qualified Class Name.
563
-     * if the class is not capable of being loaded using PSR-4 autoloading,
564
-     * then you need to use one of the existing load_*() methods
565
-     * which can resolve the classname and filepath from the passed arguments
566
-     *
567
-     * @param bool|string $class_name   Fully Qualified Class Name
568
-     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
569
-     * @param bool        $cache        whether to cache the instantiated object for reuse
570
-     * @param bool        $from_db      some classes are instantiated from the db
571
-     *                                  and thus call a different method to instantiate
572
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
573
-     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
574
-     * @return mixed null = failure to load or instantiate class object.
575
-     *                                  object = class loaded and instantiated successfully.
576
-     *                                  bool = fail or success when $load_only is true
577
-     * @throws EE_Error
578
-     */
579
-    public function create(
580
-        $class_name = false,
581
-        $arguments = array(),
582
-        $cache = false,
583
-        $from_db = false,
584
-        $load_only = false,
585
-        $addon = false
586
-    ) {
587
-        $class_name = ltrim($class_name, '\\');
588
-        $class_name = $this->_dependency_map->get_alias($class_name);
589
-        $class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
590
-        // if a non-FQCN was passed, then verifyClassExists() might return an object
591
-        // or it could return null if the class just could not be found anywhere
592
-        if ($class_exists instanceof $class_name || $class_exists === null){
593
-            // either way, return the results
594
-            return $class_exists;
595
-        }
596
-        $class_name = $class_exists;
597
-        // if we're only loading the class and it already exists, then let's just return true immediately
598
-        if ($load_only) {
599
-            return true;
600
-        }
601
-        $addon = $addon ? 'addon' : '';
602
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
603
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
604
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
605
-        if ($this->_cache_on && $cache && ! $load_only) {
606
-            // return object if it's already cached
607
-            $cached_class = $this->_get_cached_class($class_name, $addon);
608
-            if ($cached_class !== null) {
609
-                return $cached_class;
610
-            }
611
-        }
612
-        // instantiate the requested object
613
-        $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
614
-        // if caching is turned on OR this class is cached in a class property
615
-        if (($this->_cache_on && $cache) || isset($this->_class_abbreviations[ $class_name ])) {
616
-            // save it for later... kinda like gum  { : $
617
-            $this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
618
-        }
619
-        $this->_cache_on = true;
620
-        return $class_obj;
621
-    }
622
-
623
-
624
-
625
-    /**
626
-     * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
627
-     *
628
-     * @param string $class_name
629
-     * @param array  $arguments
630
-     * @param int    $attempt
631
-     * @return mixed
632
-     */
633
-    private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1) {
634
-        if (is_object($class_name) || class_exists($class_name)) {
635
-            return $class_name;
636
-        }
637
-        switch ($attempt) {
638
-            case 1:
639
-                // if it's a FQCN then maybe the class is registered with a preceding \
640
-                $class_name = strpos($class_name, '\\') !== false
641
-                    ? '\\' . ltrim($class_name, '\\')
642
-                    : $class_name;
643
-                break;
644
-            case 2:
645
-                //
646
-                $loader = $this->_dependency_map->class_loader($class_name);
647
-                if ($loader && method_exists($this, $loader)) {
648
-                    return $this->{$loader}($class_name, $arguments);
649
-                }
650
-                break;
651
-            case 3:
652
-            default;
653
-                return null;
654
-        }
655
-        $attempt++;
656
-        return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
657
-    }
658
-
659
-
660
-
661
-    /**
662
-     * instantiates, caches, and injects dependencies for classes
663
-     *
664
-     * @param array       $file_paths   an array of paths to folders to look in
665
-     * @param string      $class_prefix EE  or EEM or... ???
666
-     * @param bool|string $class_name   $class name
667
-     * @param string      $type         file type - core? class? helper? model?
668
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
669
-     * @param bool        $from_db      some classes are instantiated from the db
670
-     *                                  and thus call a different method to instantiate
671
-     * @param bool        $cache        whether to cache the instantiated object for reuse
672
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
673
-     * @return bool|null|object null = failure to load or instantiate class object.
674
-     *                                  object = class loaded and instantiated successfully.
675
-     *                                  bool = fail or success when $load_only is true
676
-     * @throws EE_Error
677
-     */
678
-    protected function _load(
679
-        $file_paths = array(),
680
-        $class_prefix = 'EE_',
681
-        $class_name = false,
682
-        $type = 'class',
683
-        $arguments = array(),
684
-        $from_db = false,
685
-        $cache = true,
686
-        $load_only = false
687
-    ) {
688
-        $class_name = ltrim($class_name, '\\');
689
-        // strip php file extension
690
-        $class_name = str_replace('.php', '', trim($class_name));
691
-        // does the class have a prefix ?
692
-        if ( ! empty($class_prefix) && $class_prefix != 'addon') {
693
-            // make sure $class_prefix is uppercase
694
-            $class_prefix = strtoupper(trim($class_prefix));
695
-            // add class prefix ONCE!!!
696
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
697
-        }
698
-        $class_name = $this->_dependency_map->get_alias($class_name);
699
-        $class_exists = class_exists($class_name);
700
-        // if we're only loading the class and it already exists, then let's just return true immediately
701
-        if ($load_only && $class_exists) {
702
-            return true;
703
-        }
704
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
705
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
706
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
707
-        if ($this->_cache_on && $cache && ! $load_only) {
708
-            // return object if it's already cached
709
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix);
710
-            if ($cached_class !== null) {
711
-                return $cached_class;
712
-            }
713
-        }
714
-        // if the class doesn't already exist.. then we need to try and find the file and load it
715
-        if ( ! $class_exists) {
716
-            // get full path to file
717
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
718
-            // load the file
719
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
720
-            // if loading failed, or we are only loading a file but NOT instantiating an object
721
-            if ( ! $loaded || $load_only) {
722
-                // return boolean if only loading, or null if an object was expected
723
-                return $load_only ? $loaded : null;
724
-            }
725
-        }
726
-        // instantiate the requested object
727
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
728
-        if ($this->_cache_on && $cache) {
729
-            // save it for later... kinda like gum  { : $
730
-            $this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
731
-        }
732
-        $this->_cache_on = true;
733
-        return $class_obj;
734
-    }
735
-
736
-
737
-
738
-
739
-    /**
740
-     * _get_cached_class
741
-     * attempts to find a cached version of the requested class
742
-     * by looking in the following places:
743
-     *        $this->{$class_abbreviation}            ie:    $this->CART
744
-     *        $this->{$class_name}                        ie:    $this->Some_Class
745
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
746
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
747
-     *
748
-     * @access protected
749
-     * @param string $class_name
750
-     * @param string $class_prefix
751
-     * @return mixed
752
-     */
753
-    protected function _get_cached_class($class_name, $class_prefix = '')
754
-    {
755
-        // have to specify something, but not anything that will conflict
756
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
757
-            ? $this->_class_abbreviations[ $class_name ]
758
-            : 'FANCY_BATMAN_PANTS';
759
-        $class_name = str_replace('\\', '_', $class_name);
760
-        // check if class has already been loaded, and return it if it has been
761
-        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
762
-            return $this->{$class_abbreviation};
763
-        }
764
-        if (isset ($this->{$class_name})) {
765
-            return $this->{$class_name};
766
-        }
767
-        if (isset ($this->LIB->{$class_name})) {
768
-            return $this->LIB->{$class_name};
769
-        }
770
-        if ($class_prefix === 'addon' && isset ($this->addons->{$class_name})) {
771
-            return $this->addons->{$class_name};
772
-        }
773
-        return null;
774
-    }
775
-
776
-
777
-
778
-    /**
779
-     * removes a cached version of the requested class
780
-     *
781
-     * @param string $class_name
782
-     * @param boolean $addon
783
-     * @return boolean
784
-     */
785
-    public function clear_cached_class($class_name, $addon = false)
786
-    {
787
-        // have to specify something, but not anything that will conflict
788
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
789
-            ? $this->_class_abbreviations[ $class_name ]
790
-            : 'FANCY_BATMAN_PANTS';
791
-        $class_name = str_replace('\\', '_', $class_name);
792
-        // check if class has already been loaded, and return it if it has been
793
-        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
794
-            $this->{$class_abbreviation} = null;
795
-            return true;
796
-        }
797
-        if (isset($this->{$class_name})) {
798
-            $this->{$class_name} = null;
799
-            return true;
800
-        }
801
-        if (isset($this->LIB->{$class_name})) {
802
-            unset($this->LIB->{$class_name});
803
-            return true;
804
-        }
805
-        if ($addon && isset($this->addons->{$class_name})) {
806
-            unset($this->addons->{$class_name});
807
-            return true;
808
-        }
809
-        return false;
810
-    }
811
-
812
-
813
-    /**
814
-     * _resolve_path
815
-     * attempts to find a full valid filepath for the requested class.
816
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
817
-     * then returns that path if the target file has been found and is readable
818
-     *
819
-     * @access protected
820
-     * @param string $class_name
821
-     * @param string $type
822
-     * @param array  $file_paths
823
-     * @return string | bool
824
-     */
825
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
826
-    {
827
-        // make sure $file_paths is an array
828
-        $file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
829
-        // cycle thru paths
830
-        foreach ($file_paths as $key => $file_path) {
831
-            // convert all separators to proper DS, if no filepath, then use EE_CLASSES
832
-            $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
833
-            // prep file type
834
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
835
-            // build full file path
836
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
837
-            //does the file exist and can be read ?
838
-            if (is_readable($file_paths[$key])) {
839
-                return $file_paths[$key];
840
-            }
841
-        }
842
-        return false;
843
-    }
844
-
845
-
846
-
847
-    /**
848
-     * _require_file
849
-     * basically just performs a require_once()
850
-     * but with some error handling
851
-     *
852
-     * @access protected
853
-     * @param  string $path
854
-     * @param  string $class_name
855
-     * @param  string $type
856
-     * @param  array  $file_paths
857
-     * @return boolean
858
-     * @throws \EE_Error
859
-     */
860
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
861
-    {
862
-        // don't give up! you gotta...
863
-        try {
864
-            //does the file exist and can it be read ?
865
-            if ( ! $path) {
866
-                // so sorry, can't find the file
867
-                throw new EE_Error (
868
-                    sprintf(
869
-                        __('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
870
-                        trim($type, '.'),
871
-                        $class_name,
872
-                        '<br />' . implode(',<br />', $file_paths)
873
-                    )
874
-                );
875
-            }
876
-            // get the file
877
-            require_once($path);
878
-            // if the class isn't already declared somewhere
879
-            if (class_exists($class_name, false) === false) {
880
-                // so sorry, not a class
881
-                throw new EE_Error(
882
-                    sprintf(
883
-                        __('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
884
-                        $type,
885
-                        $path,
886
-                        $class_name
887
-                    )
888
-                );
889
-            }
890
-        } catch (EE_Error $e) {
891
-            $e->get_error();
892
-            return false;
893
-        }
894
-        return true;
895
-    }
896
-
897
-
898
-
899
-    /**
900
-     * _create_object
901
-     * Attempts to instantiate the requested class via any of the
902
-     * commonly used instantiation methods employed throughout EE.
903
-     * The priority for instantiation is as follows:
904
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
905
-     *        - model objects via their 'new_instance_from_db' method
906
-     *        - model objects via their 'new_instance' method
907
-     *        - "singleton" classes" via their 'instance' method
908
-     *    - standard instantiable classes via their __constructor
909
-     * Prior to instantiation, if the classname exists in the dependency_map,
910
-     * then the constructor for the requested class will be examined to determine
911
-     * if any dependencies exist, and if they can be injected.
912
-     * If so, then those classes will be added to the array of arguments passed to the constructor
913
-     *
914
-     * @access protected
915
-     * @param string $class_name
916
-     * @param array  $arguments
917
-     * @param string $type
918
-     * @param bool   $from_db
919
-     * @return null | object
920
-     * @throws \EE_Error
921
-     */
922
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
923
-    {
924
-        $class_obj = null;
925
-        $instantiation_mode = '0) none';
926
-        // don't give up! you gotta...
927
-        try {
928
-            // create reflection
929
-            $reflector = $this->get_ReflectionClass($class_name);
930
-            // make sure arguments are an array
931
-            $arguments = is_array($arguments) ? $arguments : array($arguments);
932
-            // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
933
-            // else wrap it in an additional array so that it doesn't get split into multiple parameters
934
-            $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
935
-                ? $arguments
936
-                : array($arguments);
937
-            // attempt to inject dependencies ?
938
-            if ($this->_dependency_map->has($class_name)) {
939
-                $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
940
-            }
941
-            // instantiate the class if possible
942
-            if ($reflector->isAbstract()) {
943
-                // nothing to instantiate, loading file was enough
944
-                // does not throw an exception so $instantiation_mode is unused
945
-                // $instantiation_mode = "1) no constructor abstract class";
946
-                $class_obj = true;
947
-            } else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
948
-                // no constructor = static methods only... nothing to instantiate, loading file was enough
949
-                $instantiation_mode = "2) no constructor but instantiable";
950
-                $class_obj = $reflector->newInstance();
951
-            } else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
952
-                $instantiation_mode = "3) new_instance_from_db()";
953
-                $class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
954
-            } else if (method_exists($class_name, 'new_instance')) {
955
-                $instantiation_mode = "4) new_instance()";
956
-                $class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
957
-            } else if (method_exists($class_name, 'instance')) {
958
-                $instantiation_mode = "5) instance()";
959
-                $class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
960
-            } else if ($reflector->isInstantiable()) {
961
-                $instantiation_mode = "6) constructor";
962
-                $class_obj = $reflector->newInstanceArgs($arguments);
963
-            } else {
964
-                // heh ? something's not right !
965
-                throw new EE_Error(
966
-                    sprintf(
967
-                        __('The %s file %s could not be instantiated.', 'event_espresso'),
968
-                        $type,
969
-                        $class_name
970
-                    )
971
-                );
972
-            }
973
-        } catch (Exception $e) {
974
-            if ( ! $e instanceof EE_Error) {
975
-                $e = new EE_Error(
976
-                    sprintf(
977
-                        __('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
978
-                        $class_name,
979
-                        '<br />',
980
-                        $e->getMessage(),
981
-                        $instantiation_mode
982
-                    )
983
-                );
984
-            }
985
-            $e->get_error();
986
-        }
987
-        return $class_obj;
988
-    }
989
-
990
-
991
-
992
-    /**
993
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
994
-     * @param array $array
995
-     * @return bool
996
-     */
997
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
998
-    {
999
-        return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
1000
-    }
1001
-
1002
-
1003
-
1004
-    /**
1005
-     * getReflectionClass
1006
-     * checks if a ReflectionClass object has already been generated for a class
1007
-     * and returns that instead of creating a new one
1008
-     *
1009
-     * @access public
1010
-     * @param string $class_name
1011
-     * @return ReflectionClass
1012
-     */
1013
-    public function get_ReflectionClass($class_name)
1014
-    {
1015
-        if (
1016
-            ! isset($this->_reflectors[$class_name])
1017
-            || ! $this->_reflectors[$class_name] instanceof ReflectionClass
1018
-        ) {
1019
-            $this->_reflectors[$class_name] = new ReflectionClass($class_name);
1020
-        }
1021
-        return $this->_reflectors[$class_name];
1022
-    }
1023
-
1024
-
1025
-
1026
-    /**
1027
-     * _resolve_dependencies
1028
-     * examines the constructor for the requested class to determine
1029
-     * if any dependencies exist, and if they can be injected.
1030
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1031
-     * PLZ NOTE: this is achieved by type hinting the constructor params
1032
-     * For example:
1033
-     *        if attempting to load a class "Foo" with the following constructor:
1034
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
1035
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
1036
-     *        but only IF they are NOT already present in the incoming arguments array,
1037
-     *        and the correct classes can be loaded
1038
-     *
1039
-     * @access protected
1040
-     * @param ReflectionClass $reflector
1041
-     * @param string          $class_name
1042
-     * @param array           $arguments
1043
-     * @return array
1044
-     * @throws \ReflectionException
1045
-     */
1046
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
1047
-    {
1048
-        // let's examine the constructor
1049
-        $constructor = $reflector->getConstructor();
1050
-        // whu? huh? nothing?
1051
-        if ( ! $constructor) {
1052
-            return $arguments;
1053
-        }
1054
-        // get constructor parameters
1055
-        $params = $constructor->getParameters();
1056
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1057
-        $argument_keys = array_keys($arguments);
1058
-        // now loop thru all of the constructors expected parameters
1059
-        foreach ($params as $index => $param) {
1060
-            // is this a dependency for a specific class ?
1061
-            $param_class = $param->getClass() ? $param->getClass()->name : null;
1062
-            // BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1063
-            $param_class = $this->_dependency_map->has_alias($param_class, $class_name)
1064
-                ? $this->_dependency_map->get_alias($param_class, $class_name)
1065
-                : $param_class;
1066
-            if (
1067
-                // param is not even a class
1068
-                empty($param_class)
1069
-                // and something already exists in the incoming arguments for this param
1070
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1071
-            ) {
1072
-                // so let's skip this argument and move on to the next
1073
-                continue;
1074
-            }
1075
-            if (
1076
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1077
-                ! empty($param_class)
1078
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1079
-                && $arguments[$argument_keys[$index]] instanceof $param_class
1080
-            ) {
1081
-                // skip this argument and move on to the next
1082
-                continue;
1083
-            }
1084
-            if (
1085
-                // parameter is type hinted as a class, and should be injected
1086
-                ! empty($param_class)
1087
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1088
-            ) {
1089
-                $arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1090
-            } else {
1091
-                try {
1092
-                    $arguments[$index] = $param->getDefaultValue();
1093
-                } catch (ReflectionException $e) {
1094
-                    throw new ReflectionException(
1095
-                        sprintf(
1096
-                            __('%1$s for parameter "$%2$s"', 'event_espresso'),
1097
-                            $e->getMessage(),
1098
-                            $param->getName()
1099
-                        )
1100
-                    );
1101
-                }
1102
-            }
1103
-        }
1104
-        return $arguments;
1105
-    }
1106
-
1107
-
1108
-
1109
-    /**
1110
-     * @access protected
1111
-     * @param string $class_name
1112
-     * @param string $param_class
1113
-     * @param array  $arguments
1114
-     * @param mixed  $index
1115
-     * @return array
1116
-     */
1117
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1118
-    {
1119
-        $dependency = null;
1120
-        // should dependency be loaded from cache ?
1121
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1122
-                    !== EE_Dependency_Map::load_new_object
1123
-            ? true
1124
-            : false;
1125
-        // we might have a dependency...
1126
-        // let's MAYBE try and find it in our cache if that's what's been requested
1127
-        $cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1128
-        // and grab it if it exists
1129
-        if ($cached_class instanceof $param_class) {
1130
-            $dependency = $cached_class;
1131
-        } else if ($param_class !== $class_name) {
1132
-            // obtain the loader method from the dependency map
1133
-            $loader = $this->_dependency_map->class_loader($param_class);
1134
-            // is loader a custom closure ?
1135
-            if ($loader instanceof Closure) {
1136
-                $dependency = $loader();
1137
-            } else {
1138
-                // set the cache on property for the recursive loading call
1139
-                $this->_cache_on = $cache_on;
1140
-                // if not, then let's try and load it via the registry
1141
-                if ($loader && method_exists($this, $loader)) {
1142
-                    $dependency = $this->{$loader}($param_class);
1143
-                } else {
1144
-                    $dependency = $this->create($param_class, array(), $cache_on);
1145
-                }
1146
-            }
1147
-        }
1148
-        // did we successfully find the correct dependency ?
1149
-        if ($dependency instanceof $param_class) {
1150
-            // then let's inject it into the incoming array of arguments at the correct location
1151
-            if (isset($argument_keys[$index])) {
1152
-                $arguments[$argument_keys[$index]] = $dependency;
1153
-            } else {
1154
-                $arguments[$index] = $dependency;
1155
-            }
1156
-        }
1157
-        return $arguments;
1158
-    }
1159
-
1160
-
1161
-
1162
-    /**
1163
-     * _set_cached_class
1164
-     * attempts to cache the instantiated class locally
1165
-     * in one of the following places, in the following order:
1166
-     *        $this->{class_abbreviation}   ie:    $this->CART
1167
-     *        $this->{$class_name}          ie:    $this->Some_Class
1168
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1169
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1170
-     *
1171
-     * @access protected
1172
-     * @param object $class_obj
1173
-     * @param string $class_name
1174
-     * @param string $class_prefix
1175
-     * @param bool   $from_db
1176
-     * @return void
1177
-     */
1178
-    protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1179
-    {
1180
-        if (empty($class_obj)) {
1181
-            return;
1182
-        }
1183
-        // return newly instantiated class
1184
-        if (isset($this->_class_abbreviations[$class_name])) {
1185
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
1186
-            $this->{$class_abbreviation} = $class_obj;
1187
-            return;
1188
-        }
1189
-        $class_name = str_replace('\\', '_', $class_name);
1190
-        if (property_exists($this, $class_name)) {
1191
-            $this->{$class_name} = $class_obj;
1192
-            return;
1193
-        }
1194
-        if ($class_prefix === 'addon') {
1195
-            $this->addons->{$class_name} = $class_obj;
1196
-            return;
1197
-        }
1198
-        if ( ! $from_db) {
1199
-            $this->LIB->{$class_name} = $class_obj;
1200
-        }
1201
-    }
1202
-
1203
-
1204
-
1205
-    /**
1206
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1207
-     *
1208
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1209
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1210
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1211
-     * @param array  $arguments
1212
-     * @return object
1213
-     */
1214
-    public static function factory($classname, $arguments = array())
1215
-    {
1216
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1217
-        if ($loader instanceof Closure) {
1218
-            return $loader($arguments);
1219
-        }
1220
-        if (method_exists(EE_Registry::instance(), $loader)) {
1221
-            return EE_Registry::instance()->{$loader}($classname, $arguments);
1222
-        }
1223
-        return null;
1224
-    }
1225
-
1226
-
1227
-
1228
-    /**
1229
-     * Gets the addon by its name/slug (not classname. For that, just
1230
-     * use the classname as the property name on EE_Config::instance()->addons)
1231
-     *
1232
-     * @param string $name
1233
-     * @return EE_Addon
1234
-     */
1235
-    public function get_addon_by_name($name)
1236
-    {
1237
-        foreach ($this->addons as $addon) {
1238
-            if ($addon->name() == $name) {
1239
-                return $addon;
1240
-            }
1241
-        }
1242
-        return null;
1243
-    }
1244
-
1245
-
1246
-
1247
-    /**
1248
-     * Gets an array of all the registered addons, where the keys are their names. (ie, what each returns for their name() function) They're already available on EE_Config::instance()->addons as properties, where each property's name is
1249
-     * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1250
-     *
1251
-     * @return EE_Addon[] where the KEYS are the addon's name()
1252
-     */
1253
-    public function get_addons_by_name()
1254
-    {
1255
-        $addons = array();
1256
-        foreach ($this->addons as $addon) {
1257
-            $addons[$addon->name()] = $addon;
1258
-        }
1259
-        return $addons;
1260
-    }
1261
-
1262
-
1263
-
1264
-    /**
1265
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1266
-     * a stale copy of it around
1267
-     *
1268
-     * @param string $model_name
1269
-     * @return \EEM_Base
1270
-     * @throws \EE_Error
1271
-     */
1272
-    public function reset_model($model_name)
1273
-    {
1274
-        $model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1275
-        if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1276
-            return null;
1277
-        }
1278
-        //get that model reset it and make sure we nuke the old reference to it
1279
-        if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1280
-            $this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1281
-        } else {
1282
-            throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1283
-        }
1284
-        return $this->LIB->{$model_class_name};
1285
-    }
1286
-
1287
-
1288
-
1289
-    /**
1290
-     * Resets the registry.
1291
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1292
-     * is used in a multisite install.  Here is a list of things that are NOT reset.
1293
-     * - $_dependency_map
1294
-     * - $_class_abbreviations
1295
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1296
-     * - $REQ:  Still on the same request so no need to change.
1297
-     * - $CAP: There is no site specific state in the EE_Capability class.
1298
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1299
-     *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1300
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1301
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1302
-     *             switch or on the restore.
1303
-     * - $modules
1304
-     * - $shortcodes
1305
-     * - $widgets
1306
-     *
1307
-     * @param boolean $hard             whether to reset data in the database too, or just refresh
1308
-     *                                  the Registry to its state at the beginning of the request
1309
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1310
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1311
-     *                                  currently reinstantiate the singletons at the moment)
1312
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1313
-     *                                  code instead can just change the model context to a different blog id if necessary
1314
-     * @return EE_Registry
1315
-     */
1316
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1317
-    {
1318
-        $instance = self::instance();
1319
-        EEH_Activation::reset();
1320
-        //properties that get reset
1321
-        $instance->_cache_on = true;
1322
-        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1323
-        $instance->CART = null;
1324
-        $instance->MRM = null;
1325
-        $instance->AssetsRegistry = null;
1326
-        $instance->AssetsRegistry = $instance->create('EventEspresso\core\services\assets\Registry');
1327
-        //messages reset
1328
-        EED_Messages::reset();
1329
-        if ($reset_models) {
1330
-            foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1331
-                $instance->reset_model($model_name);
1332
-            }
1333
-        }
1334
-        $instance->LIB = new stdClass();
1335
-        return $instance;
1336
-    }
1337
-
1338
-
1339
-
1340
-    /**
1341
-     * @override magic methods
1342
-     * @return void
1343
-     */
1344
-    public final function __destruct()
1345
-    {
1346
-    }
1347
-
1348
-
1349
-
1350
-    /**
1351
-     * @param $a
1352
-     * @param $b
1353
-     */
1354
-    public final function __call($a, $b)
1355
-    {
1356
-    }
1357
-
1358
-
1359
-
1360
-    /**
1361
-     * @param $a
1362
-     */
1363
-    public final function __get($a)
1364
-    {
1365
-    }
1366
-
1367
-
1368
-
1369
-    /**
1370
-     * @param $a
1371
-     * @param $b
1372
-     */
1373
-    public final function __set($a, $b)
1374
-    {
1375
-    }
1376
-
1377
-
1378
-
1379
-    /**
1380
-     * @param $a
1381
-     */
1382
-    public final function __isset($a)
1383
-    {
1384
-    }
19
+	/**
20
+	 *    EE_Registry Object
21
+	 *
22
+	 * @var EE_Registry $_instance
23
+	 * @access    private
24
+	 */
25
+	private static $_instance = null;
26
+
27
+	/**
28
+	 * @var EE_Dependency_Map $_dependency_map
29
+	 * @access    protected
30
+	 */
31
+	protected $_dependency_map = null;
32
+
33
+	/**
34
+	 * @var array $_class_abbreviations
35
+	 * @access    protected
36
+	 */
37
+	protected $_class_abbreviations = array();
38
+
39
+	/**
40
+	 * @access public
41
+	 * @var \EventEspresso\core\services\commands\CommandBusInterface $BUS
42
+	 */
43
+	public $BUS;
44
+
45
+	/**
46
+	 *    EE_Cart Object
47
+	 *
48
+	 * @access    public
49
+	 * @var    EE_Cart $CART
50
+	 */
51
+	public $CART = null;
52
+
53
+	/**
54
+	 *    EE_Config Object
55
+	 *
56
+	 * @access    public
57
+	 * @var    EE_Config $CFG
58
+	 */
59
+	public $CFG = null;
60
+
61
+	/**
62
+	 * EE_Network_Config Object
63
+	 *
64
+	 * @access public
65
+	 * @var EE_Network_Config $NET_CFG
66
+	 */
67
+	public $NET_CFG = null;
68
+
69
+	/**
70
+	 *    StdClass object for storing library classes in
71
+	 *
72
+	 * @public LIB
73
+	 * @var StdClass $LIB
74
+	 */
75
+	public $LIB = null;
76
+
77
+	/**
78
+	 *    EE_Request_Handler Object
79
+	 *
80
+	 * @access    public
81
+	 * @var    EE_Request_Handler $REQ
82
+	 */
83
+	public $REQ = null;
84
+
85
+	/**
86
+	 *    EE_Session Object
87
+	 *
88
+	 * @access    public
89
+	 * @var    EE_Session $SSN
90
+	 */
91
+	public $SSN = null;
92
+
93
+	/**
94
+	 * holds the ee capabilities object.
95
+	 *
96
+	 * @since 4.5.0
97
+	 * @var EE_Capabilities
98
+	 */
99
+	public $CAP = null;
100
+
101
+	/**
102
+	 * holds the EE_Message_Resource_Manager object.
103
+	 *
104
+	 * @since 4.9.0
105
+	 * @var EE_Message_Resource_Manager
106
+	 */
107
+	public $MRM = null;
108
+
109
+
110
+	/**
111
+	 * Holds the Assets Registry instance
112
+	 * @var Registry
113
+	 */
114
+	public $AssetsRegistry = null;
115
+
116
+	/**
117
+	 * StdClass object for holding addons which have registered themselves to work with EE core
118
+	 *
119
+	 * @var StdClass
120
+	 */
121
+	public $addons = null;
122
+
123
+	/**
124
+	 *    $models
125
+	 * @access    public
126
+	 * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
127
+	 */
128
+	public $models = array();
129
+
130
+	/**
131
+	 *    $modules
132
+	 * @access    public
133
+	 * @var    EED_Module[] $modules
134
+	 */
135
+	public $modules = null;
136
+
137
+	/**
138
+	 *    $shortcodes
139
+	 * @access    public
140
+	 * @var    EES_Shortcode[] $shortcodes
141
+	 */
142
+	public $shortcodes = null;
143
+
144
+	/**
145
+	 *    $widgets
146
+	 * @access    public
147
+	 * @var    WP_Widget[] $widgets
148
+	 */
149
+	public $widgets = null;
150
+
151
+	/**
152
+	 * $non_abstract_db_models
153
+	 * @access public
154
+	 * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
155
+	 * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
156
+	 * Keys are model "short names" (eg "Event") as used in model relations, and values are
157
+	 * classnames (eg "EEM_Event")
158
+	 */
159
+	public $non_abstract_db_models = array();
160
+
161
+
162
+	/**
163
+	 *    $i18n_js_strings - internationalization for JS strings
164
+	 *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
165
+	 *    in js file:  var translatedString = eei18n.string_key;
166
+	 *
167
+	 * @access    public
168
+	 * @var    array
169
+	 */
170
+	public static $i18n_js_strings = array();
171
+
172
+
173
+	/**
174
+	 *    $main_file - path to espresso.php
175
+	 *
176
+	 * @access    public
177
+	 * @var    array
178
+	 */
179
+	public $main_file;
180
+
181
+	/**
182
+	 * array of ReflectionClass objects where the key is the class name
183
+	 *
184
+	 * @access    public
185
+	 * @var ReflectionClass[]
186
+	 */
187
+	public $_reflectors;
188
+
189
+	/**
190
+	 * boolean flag to indicate whether or not to load/save dependencies from/to the cache
191
+	 *
192
+	 * @access    protected
193
+	 * @var boolean $_cache_on
194
+	 */
195
+	protected $_cache_on = true;
196
+
197
+
198
+
199
+	/**
200
+	 * @singleton method used to instantiate class object
201
+	 * @access    public
202
+	 * @param  \EE_Dependency_Map $dependency_map
203
+	 * @return \EE_Registry instance
204
+	 */
205
+	public static function instance(\EE_Dependency_Map $dependency_map = null)
206
+	{
207
+		// check if class object is instantiated
208
+		if ( ! self::$_instance instanceof EE_Registry) {
209
+			self::$_instance = new EE_Registry($dependency_map);
210
+		}
211
+		return self::$_instance;
212
+	}
213
+
214
+
215
+
216
+	/**
217
+	 *protected constructor to prevent direct creation
218
+	 *
219
+	 * @Constructor
220
+	 * @access protected
221
+	 * @param  \EE_Dependency_Map $dependency_map
222
+	 */
223
+	protected function __construct(\EE_Dependency_Map $dependency_map)
224
+	{
225
+		$this->_dependency_map = $dependency_map;
226
+		$this->LIB = new stdClass();
227
+		$this->addons = new stdClass();
228
+		$this->modules = new stdClass();
229
+		$this->shortcodes = new stdClass();
230
+		$this->widgets = new stdClass();
231
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
232
+	}
233
+
234
+
235
+
236
+	/**
237
+	 * initialize
238
+	 */
239
+	public function initialize()
240
+	{
241
+		$this->_class_abbreviations = apply_filters(
242
+			'FHEE__EE_Registry____construct___class_abbreviations',
243
+			array(
244
+				'EE_Config'                                       => 'CFG',
245
+				'EE_Session'                                      => 'SSN',
246
+				'EE_Capabilities'                                 => 'CAP',
247
+				'EE_Cart'                                         => 'CART',
248
+				'EE_Network_Config'                               => 'NET_CFG',
249
+				'EE_Request_Handler'                              => 'REQ',
250
+				'EE_Message_Resource_Manager'                     => 'MRM',
251
+				'EventEspresso\core\services\commands\CommandBus' => 'BUS',
252
+				'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
253
+			)
254
+		);
255
+		$this->load_core('Base', array(), true);
256
+		// add our request and response objects to the cache
257
+		$request_loader = $this->_dependency_map->class_loader('EE_Request');
258
+		$this->_set_cached_class(
259
+			$request_loader(),
260
+			'EE_Request'
261
+		);
262
+		$response_loader = $this->_dependency_map->class_loader('EE_Response');
263
+		$this->_set_cached_class(
264
+			$response_loader(),
265
+			'EE_Response'
266
+		);
267
+		add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
268
+	}
269
+
270
+
271
+
272
+	/**
273
+	 *    init
274
+	 *
275
+	 * @access    public
276
+	 * @return    void
277
+	 */
278
+	public function init()
279
+	{
280
+		// Get current page protocol
281
+		$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
282
+		// Output admin-ajax.php URL with same protocol as current page
283
+		self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
284
+		self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
285
+	}
286
+
287
+
288
+
289
+	/**
290
+	 * localize_i18n_js_strings
291
+	 *
292
+	 * @return string
293
+	 */
294
+	public static function localize_i18n_js_strings()
295
+	{
296
+		$i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
297
+		foreach ($i18n_js_strings as $key => $value) {
298
+			if (is_scalar($value)) {
299
+				$i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
300
+			}
301
+		}
302
+		return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
303
+	}
304
+
305
+
306
+
307
+	/**
308
+	 * @param mixed string | EED_Module $module
309
+	 */
310
+	public function add_module($module)
311
+	{
312
+		if ($module instanceof EED_Module) {
313
+			$module_class = get_class($module);
314
+			$this->modules->{$module_class} = $module;
315
+		} else {
316
+			if ( ! class_exists('EE_Module_Request_Router')) {
317
+				$this->load_core('Module_Request_Router');
318
+			}
319
+			$this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
320
+		}
321
+	}
322
+
323
+
324
+
325
+	/**
326
+	 * @param string $module_name
327
+	 * @return mixed EED_Module | NULL
328
+	 */
329
+	public function get_module($module_name = '')
330
+	{
331
+		return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
332
+	}
333
+
334
+
335
+
336
+	/**
337
+	 *    loads core classes - must be singletons
338
+	 *
339
+	 * @access    public
340
+	 * @param string $class_name - simple class name ie: session
341
+	 * @param mixed  $arguments
342
+	 * @param bool   $load_only
343
+	 * @return mixed
344
+	 */
345
+	public function load_core($class_name, $arguments = array(), $load_only = false)
346
+	{
347
+		$core_paths = apply_filters(
348
+			'FHEE__EE_Registry__load_core__core_paths',
349
+			array(
350
+				EE_CORE,
351
+				EE_ADMIN,
352
+				EE_CPTS,
353
+				EE_CORE . 'data_migration_scripts' . DS,
354
+				EE_CORE . 'request_stack' . DS,
355
+				EE_CORE . 'middleware' . DS,
356
+			)
357
+		);
358
+		// retrieve instantiated class
359
+		return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
360
+	}
361
+
362
+
363
+
364
+	/**
365
+	 *    loads service classes
366
+	 *
367
+	 * @access    public
368
+	 * @param string $class_name - simple class name ie: session
369
+	 * @param mixed  $arguments
370
+	 * @param bool   $load_only
371
+	 * @return mixed
372
+	 */
373
+	public function load_service($class_name, $arguments = array(), $load_only = false)
374
+	{
375
+		$service_paths = apply_filters(
376
+			'FHEE__EE_Registry__load_service__service_paths',
377
+			array(
378
+				EE_CORE . 'services' . DS,
379
+			)
380
+		);
381
+		// retrieve instantiated class
382
+		return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
383
+	}
384
+
385
+
386
+
387
+	/**
388
+	 *    loads data_migration_scripts
389
+	 *
390
+	 * @access    public
391
+	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
392
+	 * @param mixed  $arguments
393
+	 * @return EE_Data_Migration_Script_Base|mixed
394
+	 */
395
+	public function load_dms($class_name, $arguments = array())
396
+	{
397
+		// retrieve instantiated class
398
+		return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
399
+	}
400
+
401
+
402
+
403
+	/**
404
+	 *    loads object creating classes - must be singletons
405
+	 *
406
+	 * @param string $class_name - simple class name ie: attendee
407
+	 * @param mixed  $arguments  - an array of arguments to pass to the class
408
+	 * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
409
+	 * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then set this to FALSE (ie. when instantiating model objects from client in a loop)
410
+	 * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
411
+	 * @return EE_Base_Class | bool
412
+	 */
413
+	public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
414
+	{
415
+		$paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
416
+			EE_CORE,
417
+			EE_CLASSES,
418
+			EE_BUSINESS,
419
+		));
420
+		// retrieve instantiated class
421
+		return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
422
+	}
423
+
424
+
425
+
426
+	/**
427
+	 *    loads helper classes - must be singletons
428
+	 *
429
+	 * @param string $class_name - simple class name ie: price
430
+	 * @param mixed  $arguments
431
+	 * @param bool   $load_only
432
+	 * @return EEH_Base | bool
433
+	 */
434
+	public function load_helper($class_name, $arguments = array(), $load_only = true)
435
+	{
436
+		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
437
+		$helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
438
+		// retrieve instantiated class
439
+		return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
440
+	}
441
+
442
+
443
+
444
+	/**
445
+	 *    loads core classes - must be singletons
446
+	 *
447
+	 * @access    public
448
+	 * @param string $class_name - simple class name ie: session
449
+	 * @param mixed  $arguments
450
+	 * @param bool   $load_only
451
+	 * @param bool   $cache      whether to cache the object or not.
452
+	 * @return mixed
453
+	 */
454
+	public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
455
+	{
456
+		$paths = array(
457
+			EE_LIBRARIES,
458
+			EE_LIBRARIES . 'messages' . DS,
459
+			EE_LIBRARIES . 'shortcodes' . DS,
460
+			EE_LIBRARIES . 'qtips' . DS,
461
+			EE_LIBRARIES . 'payment_methods' . DS,
462
+		);
463
+		// retrieve instantiated class
464
+		return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
465
+	}
466
+
467
+
468
+
469
+	/**
470
+	 *    loads model classes - must be singletons
471
+	 *
472
+	 * @param string $class_name - simple class name ie: price
473
+	 * @param mixed  $arguments
474
+	 * @param bool   $load_only
475
+	 * @return EEM_Base | bool
476
+	 */
477
+	public function load_model($class_name, $arguments = array(), $load_only = false)
478
+	{
479
+		$paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
480
+			EE_MODELS,
481
+			EE_CORE,
482
+		));
483
+		// retrieve instantiated class
484
+		return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
485
+	}
486
+
487
+
488
+
489
+	/**
490
+	 *    loads model classes - must be singletons
491
+	 *
492
+	 * @param string $class_name - simple class name ie: price
493
+	 * @param mixed  $arguments
494
+	 * @param bool   $load_only
495
+	 * @return mixed | bool
496
+	 */
497
+	public function load_model_class($class_name, $arguments = array(), $load_only = true)
498
+	{
499
+		$paths = array(
500
+			EE_MODELS . 'fields' . DS,
501
+			EE_MODELS . 'helpers' . DS,
502
+			EE_MODELS . 'relations' . DS,
503
+			EE_MODELS . 'strategies' . DS,
504
+		);
505
+		// retrieve instantiated class
506
+		return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
507
+	}
508
+
509
+
510
+
511
+	/**
512
+	 * Determines if $model_name is the name of an actual EE model.
513
+	 *
514
+	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
515
+	 * @return boolean
516
+	 */
517
+	public function is_model_name($model_name)
518
+	{
519
+		return isset($this->models[$model_name]) ? true : false;
520
+	}
521
+
522
+
523
+
524
+	/**
525
+	 *    generic class loader
526
+	 *
527
+	 * @param string $path_to_file - directory path to file location, not including filename
528
+	 * @param string $file_name    - file name  ie:  my_file.php, including extension
529
+	 * @param string $type         - file type - core? class? helper? model?
530
+	 * @param mixed  $arguments
531
+	 * @param bool   $load_only
532
+	 * @return mixed
533
+	 */
534
+	public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
535
+	{
536
+		// retrieve instantiated class
537
+		return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
538
+	}
539
+
540
+
541
+
542
+	/**
543
+	 *    load_addon
544
+	 *
545
+	 * @param string $path_to_file - directory path to file location, not including filename
546
+	 * @param string $class_name   - full class name  ie:  My_Class
547
+	 * @param string $type         - file type - core? class? helper? model?
548
+	 * @param mixed  $arguments
549
+	 * @param bool   $load_only
550
+	 * @return EE_Addon
551
+	 */
552
+	public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
553
+	{
554
+		// retrieve instantiated class
555
+		return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
556
+	}
557
+
558
+
559
+
560
+	/**
561
+	 * instantiates, caches, and automatically resolves dependencies
562
+	 * for classes that use a Fully Qualified Class Name.
563
+	 * if the class is not capable of being loaded using PSR-4 autoloading,
564
+	 * then you need to use one of the existing load_*() methods
565
+	 * which can resolve the classname and filepath from the passed arguments
566
+	 *
567
+	 * @param bool|string $class_name   Fully Qualified Class Name
568
+	 * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
569
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
570
+	 * @param bool        $from_db      some classes are instantiated from the db
571
+	 *                                  and thus call a different method to instantiate
572
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
573
+	 * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
574
+	 * @return mixed null = failure to load or instantiate class object.
575
+	 *                                  object = class loaded and instantiated successfully.
576
+	 *                                  bool = fail or success when $load_only is true
577
+	 * @throws EE_Error
578
+	 */
579
+	public function create(
580
+		$class_name = false,
581
+		$arguments = array(),
582
+		$cache = false,
583
+		$from_db = false,
584
+		$load_only = false,
585
+		$addon = false
586
+	) {
587
+		$class_name = ltrim($class_name, '\\');
588
+		$class_name = $this->_dependency_map->get_alias($class_name);
589
+		$class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
590
+		// if a non-FQCN was passed, then verifyClassExists() might return an object
591
+		// or it could return null if the class just could not be found anywhere
592
+		if ($class_exists instanceof $class_name || $class_exists === null){
593
+			// either way, return the results
594
+			return $class_exists;
595
+		}
596
+		$class_name = $class_exists;
597
+		// if we're only loading the class and it already exists, then let's just return true immediately
598
+		if ($load_only) {
599
+			return true;
600
+		}
601
+		$addon = $addon ? 'addon' : '';
602
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
603
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
604
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
605
+		if ($this->_cache_on && $cache && ! $load_only) {
606
+			// return object if it's already cached
607
+			$cached_class = $this->_get_cached_class($class_name, $addon);
608
+			if ($cached_class !== null) {
609
+				return $cached_class;
610
+			}
611
+		}
612
+		// instantiate the requested object
613
+		$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
614
+		// if caching is turned on OR this class is cached in a class property
615
+		if (($this->_cache_on && $cache) || isset($this->_class_abbreviations[ $class_name ])) {
616
+			// save it for later... kinda like gum  { : $
617
+			$this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
618
+		}
619
+		$this->_cache_on = true;
620
+		return $class_obj;
621
+	}
622
+
623
+
624
+
625
+	/**
626
+	 * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
627
+	 *
628
+	 * @param string $class_name
629
+	 * @param array  $arguments
630
+	 * @param int    $attempt
631
+	 * @return mixed
632
+	 */
633
+	private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1) {
634
+		if (is_object($class_name) || class_exists($class_name)) {
635
+			return $class_name;
636
+		}
637
+		switch ($attempt) {
638
+			case 1:
639
+				// if it's a FQCN then maybe the class is registered with a preceding \
640
+				$class_name = strpos($class_name, '\\') !== false
641
+					? '\\' . ltrim($class_name, '\\')
642
+					: $class_name;
643
+				break;
644
+			case 2:
645
+				//
646
+				$loader = $this->_dependency_map->class_loader($class_name);
647
+				if ($loader && method_exists($this, $loader)) {
648
+					return $this->{$loader}($class_name, $arguments);
649
+				}
650
+				break;
651
+			case 3:
652
+			default;
653
+				return null;
654
+		}
655
+		$attempt++;
656
+		return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
657
+	}
658
+
659
+
660
+
661
+	/**
662
+	 * instantiates, caches, and injects dependencies for classes
663
+	 *
664
+	 * @param array       $file_paths   an array of paths to folders to look in
665
+	 * @param string      $class_prefix EE  or EEM or... ???
666
+	 * @param bool|string $class_name   $class name
667
+	 * @param string      $type         file type - core? class? helper? model?
668
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
669
+	 * @param bool        $from_db      some classes are instantiated from the db
670
+	 *                                  and thus call a different method to instantiate
671
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
672
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
673
+	 * @return bool|null|object null = failure to load or instantiate class object.
674
+	 *                                  object = class loaded and instantiated successfully.
675
+	 *                                  bool = fail or success when $load_only is true
676
+	 * @throws EE_Error
677
+	 */
678
+	protected function _load(
679
+		$file_paths = array(),
680
+		$class_prefix = 'EE_',
681
+		$class_name = false,
682
+		$type = 'class',
683
+		$arguments = array(),
684
+		$from_db = false,
685
+		$cache = true,
686
+		$load_only = false
687
+	) {
688
+		$class_name = ltrim($class_name, '\\');
689
+		// strip php file extension
690
+		$class_name = str_replace('.php', '', trim($class_name));
691
+		// does the class have a prefix ?
692
+		if ( ! empty($class_prefix) && $class_prefix != 'addon') {
693
+			// make sure $class_prefix is uppercase
694
+			$class_prefix = strtoupper(trim($class_prefix));
695
+			// add class prefix ONCE!!!
696
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
697
+		}
698
+		$class_name = $this->_dependency_map->get_alias($class_name);
699
+		$class_exists = class_exists($class_name);
700
+		// if we're only loading the class and it already exists, then let's just return true immediately
701
+		if ($load_only && $class_exists) {
702
+			return true;
703
+		}
704
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
705
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
706
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
707
+		if ($this->_cache_on && $cache && ! $load_only) {
708
+			// return object if it's already cached
709
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix);
710
+			if ($cached_class !== null) {
711
+				return $cached_class;
712
+			}
713
+		}
714
+		// if the class doesn't already exist.. then we need to try and find the file and load it
715
+		if ( ! $class_exists) {
716
+			// get full path to file
717
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
718
+			// load the file
719
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
720
+			// if loading failed, or we are only loading a file but NOT instantiating an object
721
+			if ( ! $loaded || $load_only) {
722
+				// return boolean if only loading, or null if an object was expected
723
+				return $load_only ? $loaded : null;
724
+			}
725
+		}
726
+		// instantiate the requested object
727
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
728
+		if ($this->_cache_on && $cache) {
729
+			// save it for later... kinda like gum  { : $
730
+			$this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
731
+		}
732
+		$this->_cache_on = true;
733
+		return $class_obj;
734
+	}
735
+
736
+
737
+
738
+
739
+	/**
740
+	 * _get_cached_class
741
+	 * attempts to find a cached version of the requested class
742
+	 * by looking in the following places:
743
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
744
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
745
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
746
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
747
+	 *
748
+	 * @access protected
749
+	 * @param string $class_name
750
+	 * @param string $class_prefix
751
+	 * @return mixed
752
+	 */
753
+	protected function _get_cached_class($class_name, $class_prefix = '')
754
+	{
755
+		// have to specify something, but not anything that will conflict
756
+		$class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
757
+			? $this->_class_abbreviations[ $class_name ]
758
+			: 'FANCY_BATMAN_PANTS';
759
+		$class_name = str_replace('\\', '_', $class_name);
760
+		// check if class has already been loaded, and return it if it has been
761
+		if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
762
+			return $this->{$class_abbreviation};
763
+		}
764
+		if (isset ($this->{$class_name})) {
765
+			return $this->{$class_name};
766
+		}
767
+		if (isset ($this->LIB->{$class_name})) {
768
+			return $this->LIB->{$class_name};
769
+		}
770
+		if ($class_prefix === 'addon' && isset ($this->addons->{$class_name})) {
771
+			return $this->addons->{$class_name};
772
+		}
773
+		return null;
774
+	}
775
+
776
+
777
+
778
+	/**
779
+	 * removes a cached version of the requested class
780
+	 *
781
+	 * @param string $class_name
782
+	 * @param boolean $addon
783
+	 * @return boolean
784
+	 */
785
+	public function clear_cached_class($class_name, $addon = false)
786
+	{
787
+		// have to specify something, but not anything that will conflict
788
+		$class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
789
+			? $this->_class_abbreviations[ $class_name ]
790
+			: 'FANCY_BATMAN_PANTS';
791
+		$class_name = str_replace('\\', '_', $class_name);
792
+		// check if class has already been loaded, and return it if it has been
793
+		if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
794
+			$this->{$class_abbreviation} = null;
795
+			return true;
796
+		}
797
+		if (isset($this->{$class_name})) {
798
+			$this->{$class_name} = null;
799
+			return true;
800
+		}
801
+		if (isset($this->LIB->{$class_name})) {
802
+			unset($this->LIB->{$class_name});
803
+			return true;
804
+		}
805
+		if ($addon && isset($this->addons->{$class_name})) {
806
+			unset($this->addons->{$class_name});
807
+			return true;
808
+		}
809
+		return false;
810
+	}
811
+
812
+
813
+	/**
814
+	 * _resolve_path
815
+	 * attempts to find a full valid filepath for the requested class.
816
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
817
+	 * then returns that path if the target file has been found and is readable
818
+	 *
819
+	 * @access protected
820
+	 * @param string $class_name
821
+	 * @param string $type
822
+	 * @param array  $file_paths
823
+	 * @return string | bool
824
+	 */
825
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
826
+	{
827
+		// make sure $file_paths is an array
828
+		$file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
829
+		// cycle thru paths
830
+		foreach ($file_paths as $key => $file_path) {
831
+			// convert all separators to proper DS, if no filepath, then use EE_CLASSES
832
+			$file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
833
+			// prep file type
834
+			$type = ! empty($type) ? trim($type, '.') . '.' : '';
835
+			// build full file path
836
+			$file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
837
+			//does the file exist and can be read ?
838
+			if (is_readable($file_paths[$key])) {
839
+				return $file_paths[$key];
840
+			}
841
+		}
842
+		return false;
843
+	}
844
+
845
+
846
+
847
+	/**
848
+	 * _require_file
849
+	 * basically just performs a require_once()
850
+	 * but with some error handling
851
+	 *
852
+	 * @access protected
853
+	 * @param  string $path
854
+	 * @param  string $class_name
855
+	 * @param  string $type
856
+	 * @param  array  $file_paths
857
+	 * @return boolean
858
+	 * @throws \EE_Error
859
+	 */
860
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
861
+	{
862
+		// don't give up! you gotta...
863
+		try {
864
+			//does the file exist and can it be read ?
865
+			if ( ! $path) {
866
+				// so sorry, can't find the file
867
+				throw new EE_Error (
868
+					sprintf(
869
+						__('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
870
+						trim($type, '.'),
871
+						$class_name,
872
+						'<br />' . implode(',<br />', $file_paths)
873
+					)
874
+				);
875
+			}
876
+			// get the file
877
+			require_once($path);
878
+			// if the class isn't already declared somewhere
879
+			if (class_exists($class_name, false) === false) {
880
+				// so sorry, not a class
881
+				throw new EE_Error(
882
+					sprintf(
883
+						__('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
884
+						$type,
885
+						$path,
886
+						$class_name
887
+					)
888
+				);
889
+			}
890
+		} catch (EE_Error $e) {
891
+			$e->get_error();
892
+			return false;
893
+		}
894
+		return true;
895
+	}
896
+
897
+
898
+
899
+	/**
900
+	 * _create_object
901
+	 * Attempts to instantiate the requested class via any of the
902
+	 * commonly used instantiation methods employed throughout EE.
903
+	 * The priority for instantiation is as follows:
904
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
905
+	 *        - model objects via their 'new_instance_from_db' method
906
+	 *        - model objects via their 'new_instance' method
907
+	 *        - "singleton" classes" via their 'instance' method
908
+	 *    - standard instantiable classes via their __constructor
909
+	 * Prior to instantiation, if the classname exists in the dependency_map,
910
+	 * then the constructor for the requested class will be examined to determine
911
+	 * if any dependencies exist, and if they can be injected.
912
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
913
+	 *
914
+	 * @access protected
915
+	 * @param string $class_name
916
+	 * @param array  $arguments
917
+	 * @param string $type
918
+	 * @param bool   $from_db
919
+	 * @return null | object
920
+	 * @throws \EE_Error
921
+	 */
922
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
923
+	{
924
+		$class_obj = null;
925
+		$instantiation_mode = '0) none';
926
+		// don't give up! you gotta...
927
+		try {
928
+			// create reflection
929
+			$reflector = $this->get_ReflectionClass($class_name);
930
+			// make sure arguments are an array
931
+			$arguments = is_array($arguments) ? $arguments : array($arguments);
932
+			// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
933
+			// else wrap it in an additional array so that it doesn't get split into multiple parameters
934
+			$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
935
+				? $arguments
936
+				: array($arguments);
937
+			// attempt to inject dependencies ?
938
+			if ($this->_dependency_map->has($class_name)) {
939
+				$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
940
+			}
941
+			// instantiate the class if possible
942
+			if ($reflector->isAbstract()) {
943
+				// nothing to instantiate, loading file was enough
944
+				// does not throw an exception so $instantiation_mode is unused
945
+				// $instantiation_mode = "1) no constructor abstract class";
946
+				$class_obj = true;
947
+			} else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
948
+				// no constructor = static methods only... nothing to instantiate, loading file was enough
949
+				$instantiation_mode = "2) no constructor but instantiable";
950
+				$class_obj = $reflector->newInstance();
951
+			} else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
952
+				$instantiation_mode = "3) new_instance_from_db()";
953
+				$class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
954
+			} else if (method_exists($class_name, 'new_instance')) {
955
+				$instantiation_mode = "4) new_instance()";
956
+				$class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
957
+			} else if (method_exists($class_name, 'instance')) {
958
+				$instantiation_mode = "5) instance()";
959
+				$class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
960
+			} else if ($reflector->isInstantiable()) {
961
+				$instantiation_mode = "6) constructor";
962
+				$class_obj = $reflector->newInstanceArgs($arguments);
963
+			} else {
964
+				// heh ? something's not right !
965
+				throw new EE_Error(
966
+					sprintf(
967
+						__('The %s file %s could not be instantiated.', 'event_espresso'),
968
+						$type,
969
+						$class_name
970
+					)
971
+				);
972
+			}
973
+		} catch (Exception $e) {
974
+			if ( ! $e instanceof EE_Error) {
975
+				$e = new EE_Error(
976
+					sprintf(
977
+						__('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
978
+						$class_name,
979
+						'<br />',
980
+						$e->getMessage(),
981
+						$instantiation_mode
982
+					)
983
+				);
984
+			}
985
+			$e->get_error();
986
+		}
987
+		return $class_obj;
988
+	}
989
+
990
+
991
+
992
+	/**
993
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
994
+	 * @param array $array
995
+	 * @return bool
996
+	 */
997
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
998
+	{
999
+		return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
1000
+	}
1001
+
1002
+
1003
+
1004
+	/**
1005
+	 * getReflectionClass
1006
+	 * checks if a ReflectionClass object has already been generated for a class
1007
+	 * and returns that instead of creating a new one
1008
+	 *
1009
+	 * @access public
1010
+	 * @param string $class_name
1011
+	 * @return ReflectionClass
1012
+	 */
1013
+	public function get_ReflectionClass($class_name)
1014
+	{
1015
+		if (
1016
+			! isset($this->_reflectors[$class_name])
1017
+			|| ! $this->_reflectors[$class_name] instanceof ReflectionClass
1018
+		) {
1019
+			$this->_reflectors[$class_name] = new ReflectionClass($class_name);
1020
+		}
1021
+		return $this->_reflectors[$class_name];
1022
+	}
1023
+
1024
+
1025
+
1026
+	/**
1027
+	 * _resolve_dependencies
1028
+	 * examines the constructor for the requested class to determine
1029
+	 * if any dependencies exist, and if they can be injected.
1030
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1031
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
1032
+	 * For example:
1033
+	 *        if attempting to load a class "Foo" with the following constructor:
1034
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
1035
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
1036
+	 *        but only IF they are NOT already present in the incoming arguments array,
1037
+	 *        and the correct classes can be loaded
1038
+	 *
1039
+	 * @access protected
1040
+	 * @param ReflectionClass $reflector
1041
+	 * @param string          $class_name
1042
+	 * @param array           $arguments
1043
+	 * @return array
1044
+	 * @throws \ReflectionException
1045
+	 */
1046
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
1047
+	{
1048
+		// let's examine the constructor
1049
+		$constructor = $reflector->getConstructor();
1050
+		// whu? huh? nothing?
1051
+		if ( ! $constructor) {
1052
+			return $arguments;
1053
+		}
1054
+		// get constructor parameters
1055
+		$params = $constructor->getParameters();
1056
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1057
+		$argument_keys = array_keys($arguments);
1058
+		// now loop thru all of the constructors expected parameters
1059
+		foreach ($params as $index => $param) {
1060
+			// is this a dependency for a specific class ?
1061
+			$param_class = $param->getClass() ? $param->getClass()->name : null;
1062
+			// BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1063
+			$param_class = $this->_dependency_map->has_alias($param_class, $class_name)
1064
+				? $this->_dependency_map->get_alias($param_class, $class_name)
1065
+				: $param_class;
1066
+			if (
1067
+				// param is not even a class
1068
+				empty($param_class)
1069
+				// and something already exists in the incoming arguments for this param
1070
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1071
+			) {
1072
+				// so let's skip this argument and move on to the next
1073
+				continue;
1074
+			}
1075
+			if (
1076
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1077
+				! empty($param_class)
1078
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1079
+				&& $arguments[$argument_keys[$index]] instanceof $param_class
1080
+			) {
1081
+				// skip this argument and move on to the next
1082
+				continue;
1083
+			}
1084
+			if (
1085
+				// parameter is type hinted as a class, and should be injected
1086
+				! empty($param_class)
1087
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1088
+			) {
1089
+				$arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1090
+			} else {
1091
+				try {
1092
+					$arguments[$index] = $param->getDefaultValue();
1093
+				} catch (ReflectionException $e) {
1094
+					throw new ReflectionException(
1095
+						sprintf(
1096
+							__('%1$s for parameter "$%2$s"', 'event_espresso'),
1097
+							$e->getMessage(),
1098
+							$param->getName()
1099
+						)
1100
+					);
1101
+				}
1102
+			}
1103
+		}
1104
+		return $arguments;
1105
+	}
1106
+
1107
+
1108
+
1109
+	/**
1110
+	 * @access protected
1111
+	 * @param string $class_name
1112
+	 * @param string $param_class
1113
+	 * @param array  $arguments
1114
+	 * @param mixed  $index
1115
+	 * @return array
1116
+	 */
1117
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1118
+	{
1119
+		$dependency = null;
1120
+		// should dependency be loaded from cache ?
1121
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1122
+					!== EE_Dependency_Map::load_new_object
1123
+			? true
1124
+			: false;
1125
+		// we might have a dependency...
1126
+		// let's MAYBE try and find it in our cache if that's what's been requested
1127
+		$cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1128
+		// and grab it if it exists
1129
+		if ($cached_class instanceof $param_class) {
1130
+			$dependency = $cached_class;
1131
+		} else if ($param_class !== $class_name) {
1132
+			// obtain the loader method from the dependency map
1133
+			$loader = $this->_dependency_map->class_loader($param_class);
1134
+			// is loader a custom closure ?
1135
+			if ($loader instanceof Closure) {
1136
+				$dependency = $loader();
1137
+			} else {
1138
+				// set the cache on property for the recursive loading call
1139
+				$this->_cache_on = $cache_on;
1140
+				// if not, then let's try and load it via the registry
1141
+				if ($loader && method_exists($this, $loader)) {
1142
+					$dependency = $this->{$loader}($param_class);
1143
+				} else {
1144
+					$dependency = $this->create($param_class, array(), $cache_on);
1145
+				}
1146
+			}
1147
+		}
1148
+		// did we successfully find the correct dependency ?
1149
+		if ($dependency instanceof $param_class) {
1150
+			// then let's inject it into the incoming array of arguments at the correct location
1151
+			if (isset($argument_keys[$index])) {
1152
+				$arguments[$argument_keys[$index]] = $dependency;
1153
+			} else {
1154
+				$arguments[$index] = $dependency;
1155
+			}
1156
+		}
1157
+		return $arguments;
1158
+	}
1159
+
1160
+
1161
+
1162
+	/**
1163
+	 * _set_cached_class
1164
+	 * attempts to cache the instantiated class locally
1165
+	 * in one of the following places, in the following order:
1166
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1167
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1168
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1169
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1170
+	 *
1171
+	 * @access protected
1172
+	 * @param object $class_obj
1173
+	 * @param string $class_name
1174
+	 * @param string $class_prefix
1175
+	 * @param bool   $from_db
1176
+	 * @return void
1177
+	 */
1178
+	protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1179
+	{
1180
+		if (empty($class_obj)) {
1181
+			return;
1182
+		}
1183
+		// return newly instantiated class
1184
+		if (isset($this->_class_abbreviations[$class_name])) {
1185
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
1186
+			$this->{$class_abbreviation} = $class_obj;
1187
+			return;
1188
+		}
1189
+		$class_name = str_replace('\\', '_', $class_name);
1190
+		if (property_exists($this, $class_name)) {
1191
+			$this->{$class_name} = $class_obj;
1192
+			return;
1193
+		}
1194
+		if ($class_prefix === 'addon') {
1195
+			$this->addons->{$class_name} = $class_obj;
1196
+			return;
1197
+		}
1198
+		if ( ! $from_db) {
1199
+			$this->LIB->{$class_name} = $class_obj;
1200
+		}
1201
+	}
1202
+
1203
+
1204
+
1205
+	/**
1206
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1207
+	 *
1208
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1209
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1210
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1211
+	 * @param array  $arguments
1212
+	 * @return object
1213
+	 */
1214
+	public static function factory($classname, $arguments = array())
1215
+	{
1216
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1217
+		if ($loader instanceof Closure) {
1218
+			return $loader($arguments);
1219
+		}
1220
+		if (method_exists(EE_Registry::instance(), $loader)) {
1221
+			return EE_Registry::instance()->{$loader}($classname, $arguments);
1222
+		}
1223
+		return null;
1224
+	}
1225
+
1226
+
1227
+
1228
+	/**
1229
+	 * Gets the addon by its name/slug (not classname. For that, just
1230
+	 * use the classname as the property name on EE_Config::instance()->addons)
1231
+	 *
1232
+	 * @param string $name
1233
+	 * @return EE_Addon
1234
+	 */
1235
+	public function get_addon_by_name($name)
1236
+	{
1237
+		foreach ($this->addons as $addon) {
1238
+			if ($addon->name() == $name) {
1239
+				return $addon;
1240
+			}
1241
+		}
1242
+		return null;
1243
+	}
1244
+
1245
+
1246
+
1247
+	/**
1248
+	 * Gets an array of all the registered addons, where the keys are their names. (ie, what each returns for their name() function) They're already available on EE_Config::instance()->addons as properties, where each property's name is
1249
+	 * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1250
+	 *
1251
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1252
+	 */
1253
+	public function get_addons_by_name()
1254
+	{
1255
+		$addons = array();
1256
+		foreach ($this->addons as $addon) {
1257
+			$addons[$addon->name()] = $addon;
1258
+		}
1259
+		return $addons;
1260
+	}
1261
+
1262
+
1263
+
1264
+	/**
1265
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1266
+	 * a stale copy of it around
1267
+	 *
1268
+	 * @param string $model_name
1269
+	 * @return \EEM_Base
1270
+	 * @throws \EE_Error
1271
+	 */
1272
+	public function reset_model($model_name)
1273
+	{
1274
+		$model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1275
+		if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1276
+			return null;
1277
+		}
1278
+		//get that model reset it and make sure we nuke the old reference to it
1279
+		if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1280
+			$this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1281
+		} else {
1282
+			throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1283
+		}
1284
+		return $this->LIB->{$model_class_name};
1285
+	}
1286
+
1287
+
1288
+
1289
+	/**
1290
+	 * Resets the registry.
1291
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1292
+	 * is used in a multisite install.  Here is a list of things that are NOT reset.
1293
+	 * - $_dependency_map
1294
+	 * - $_class_abbreviations
1295
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1296
+	 * - $REQ:  Still on the same request so no need to change.
1297
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1298
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1299
+	 *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1300
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1301
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1302
+	 *             switch or on the restore.
1303
+	 * - $modules
1304
+	 * - $shortcodes
1305
+	 * - $widgets
1306
+	 *
1307
+	 * @param boolean $hard             whether to reset data in the database too, or just refresh
1308
+	 *                                  the Registry to its state at the beginning of the request
1309
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1310
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1311
+	 *                                  currently reinstantiate the singletons at the moment)
1312
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1313
+	 *                                  code instead can just change the model context to a different blog id if necessary
1314
+	 * @return EE_Registry
1315
+	 */
1316
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1317
+	{
1318
+		$instance = self::instance();
1319
+		EEH_Activation::reset();
1320
+		//properties that get reset
1321
+		$instance->_cache_on = true;
1322
+		$instance->CFG = EE_Config::reset($hard, $reinstantiate);
1323
+		$instance->CART = null;
1324
+		$instance->MRM = null;
1325
+		$instance->AssetsRegistry = null;
1326
+		$instance->AssetsRegistry = $instance->create('EventEspresso\core\services\assets\Registry');
1327
+		//messages reset
1328
+		EED_Messages::reset();
1329
+		if ($reset_models) {
1330
+			foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1331
+				$instance->reset_model($model_name);
1332
+			}
1333
+		}
1334
+		$instance->LIB = new stdClass();
1335
+		return $instance;
1336
+	}
1337
+
1338
+
1339
+
1340
+	/**
1341
+	 * @override magic methods
1342
+	 * @return void
1343
+	 */
1344
+	public final function __destruct()
1345
+	{
1346
+	}
1347
+
1348
+
1349
+
1350
+	/**
1351
+	 * @param $a
1352
+	 * @param $b
1353
+	 */
1354
+	public final function __call($a, $b)
1355
+	{
1356
+	}
1357
+
1358
+
1359
+
1360
+	/**
1361
+	 * @param $a
1362
+	 */
1363
+	public final function __get($a)
1364
+	{
1365
+	}
1366
+
1367
+
1368
+
1369
+	/**
1370
+	 * @param $a
1371
+	 * @param $b
1372
+	 */
1373
+	public final function __set($a, $b)
1374
+	{
1375
+	}
1376
+
1377
+
1378
+
1379
+	/**
1380
+	 * @param $a
1381
+	 */
1382
+	public final function __isset($a)
1383
+	{
1384
+	}
1385 1385
 
1386 1386
 
1387 1387
 
1388
-    /**
1389
-     * @param $a
1390
-     */
1391
-    public final function __unset($a)
1392
-    {
1393
-    }
1388
+	/**
1389
+	 * @param $a
1390
+	 */
1391
+	public final function __unset($a)
1392
+	{
1393
+	}
1394 1394
 
1395 1395
 
1396 1396
 
1397
-    /**
1398
-     * @return array
1399
-     */
1400
-    public final function __sleep()
1401
-    {
1402
-        return array();
1403
-    }
1397
+	/**
1398
+	 * @return array
1399
+	 */
1400
+	public final function __sleep()
1401
+	{
1402
+		return array();
1403
+	}
1404 1404
 
1405 1405
 
1406 1406
 
1407
-    public final function __wakeup()
1408
-    {
1409
-    }
1407
+	public final function __wakeup()
1408
+	{
1409
+	}
1410 1410
 
1411 1411
 
1412 1412
 
1413
-    /**
1414
-     * @return string
1415
-     */
1416
-    public final function __toString()
1417
-    {
1418
-        return '';
1419
-    }
1413
+	/**
1414
+	 * @return string
1415
+	 */
1416
+	public final function __toString()
1417
+	{
1418
+		return '';
1419
+	}
1420 1420
 
1421 1421
 
1422 1422
 
1423
-    public final function __invoke()
1424
-    {
1425
-    }
1423
+	public final function __invoke()
1424
+	{
1425
+	}
1426 1426
 
1427 1427
 
1428 1428
 
1429
-    public final static function __set_state($array = array())
1430
-    {
1431
-        return EE_Registry::instance();
1432
-    }
1429
+	public final static function __set_state($array = array())
1430
+	{
1431
+		return EE_Registry::instance();
1432
+	}
1433 1433
 
1434 1434
 
1435 1435
 
1436
-    public final function __clone()
1437
-    {
1438
-    }
1436
+	public final function __clone()
1437
+	{
1438
+	}
1439 1439
 
1440 1440
 
1441 1441
 
1442
-    /**
1443
-     * @param $a
1444
-     * @param $b
1445
-     */
1446
-    public final static function __callStatic($a, $b)
1447
-    {
1448
-    }
1442
+	/**
1443
+	 * @param $a
1444
+	 * @param $b
1445
+	 */
1446
+	public final static function __callStatic($a, $b)
1447
+	{
1448
+	}
1449 1449
 
1450 1450
 
1451 1451
 
1452
-    /**
1453
-     * Gets all the custom post type models defined
1454
-     *
1455
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1456
-     */
1457
-    public function cpt_models()
1458
-    {
1459
-        $cpt_models = array();
1460
-        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1461
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1462
-                $cpt_models[$short_name] = $classname;
1463
-            }
1464
-        }
1465
-        return $cpt_models;
1466
-    }
1452
+	/**
1453
+	 * Gets all the custom post type models defined
1454
+	 *
1455
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1456
+	 */
1457
+	public function cpt_models()
1458
+	{
1459
+		$cpt_models = array();
1460
+		foreach ($this->non_abstract_db_models as $short_name => $classname) {
1461
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1462
+				$cpt_models[$short_name] = $classname;
1463
+			}
1464
+		}
1465
+		return $cpt_models;
1466
+	}
1467 1467
 
1468 1468
 
1469 1469
 
1470
-    /**
1471
-     * @return \EE_Config
1472
-     */
1473
-    public static function CFG()
1474
-    {
1475
-        return self::instance()->CFG;
1476
-    }
1470
+	/**
1471
+	 * @return \EE_Config
1472
+	 */
1473
+	public static function CFG()
1474
+	{
1475
+		return self::instance()->CFG;
1476
+	}
1477 1477
 
1478 1478
 
1479 1479
 }
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -293,13 +293,13 @@  discard block
 block discarded – undo
293 293
      */
294 294
     public static function localize_i18n_js_strings()
295 295
     {
296
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
296
+        $i18n_js_strings = (array) EE_Registry::$i18n_js_strings;
297 297
         foreach ($i18n_js_strings as $key => $value) {
298 298
             if (is_scalar($value)) {
299
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
299
+                $i18n_js_strings[$key] = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
300 300
             }
301 301
         }
302
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
302
+        return "/* <![CDATA[ */ var eei18n = ".wp_json_encode($i18n_js_strings).'; /* ]]> */';
303 303
     }
304 304
 
305 305
 
@@ -350,9 +350,9 @@  discard block
 block discarded – undo
350 350
                 EE_CORE,
351 351
                 EE_ADMIN,
352 352
                 EE_CPTS,
353
-                EE_CORE . 'data_migration_scripts' . DS,
354
-                EE_CORE . 'request_stack' . DS,
355
-                EE_CORE . 'middleware' . DS,
353
+                EE_CORE.'data_migration_scripts'.DS,
354
+                EE_CORE.'request_stack'.DS,
355
+                EE_CORE.'middleware'.DS,
356 356
             )
357 357
         );
358 358
         // retrieve instantiated class
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
         $service_paths = apply_filters(
376 376
             'FHEE__EE_Registry__load_service__service_paths',
377 377
             array(
378
-                EE_CORE . 'services' . DS,
378
+                EE_CORE.'services'.DS,
379 379
             )
380 380
         );
381 381
         // retrieve instantiated class
@@ -455,10 +455,10 @@  discard block
 block discarded – undo
455 455
     {
456 456
         $paths = array(
457 457
             EE_LIBRARIES,
458
-            EE_LIBRARIES . 'messages' . DS,
459
-            EE_LIBRARIES . 'shortcodes' . DS,
460
-            EE_LIBRARIES . 'qtips' . DS,
461
-            EE_LIBRARIES . 'payment_methods' . DS,
458
+            EE_LIBRARIES.'messages'.DS,
459
+            EE_LIBRARIES.'shortcodes'.DS,
460
+            EE_LIBRARIES.'qtips'.DS,
461
+            EE_LIBRARIES.'payment_methods'.DS,
462 462
         );
463 463
         // retrieve instantiated class
464 464
         return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
@@ -497,10 +497,10 @@  discard block
 block discarded – undo
497 497
     public function load_model_class($class_name, $arguments = array(), $load_only = true)
498 498
     {
499 499
         $paths = array(
500
-            EE_MODELS . 'fields' . DS,
501
-            EE_MODELS . 'helpers' . DS,
502
-            EE_MODELS . 'relations' . DS,
503
-            EE_MODELS . 'strategies' . DS,
500
+            EE_MODELS.'fields'.DS,
501
+            EE_MODELS.'helpers'.DS,
502
+            EE_MODELS.'relations'.DS,
503
+            EE_MODELS.'strategies'.DS,
504 504
         );
505 505
         // retrieve instantiated class
506 506
         return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
@@ -589,7 +589,7 @@  discard block
 block discarded – undo
589 589
         $class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
590 590
         // if a non-FQCN was passed, then verifyClassExists() might return an object
591 591
         // or it could return null if the class just could not be found anywhere
592
-        if ($class_exists instanceof $class_name || $class_exists === null){
592
+        if ($class_exists instanceof $class_name || $class_exists === null) {
593 593
             // either way, return the results
594 594
             return $class_exists;
595 595
         }
@@ -612,7 +612,7 @@  discard block
 block discarded – undo
612 612
         // instantiate the requested object
613 613
         $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
614 614
         // if caching is turned on OR this class is cached in a class property
615
-        if (($this->_cache_on && $cache) || isset($this->_class_abbreviations[ $class_name ])) {
615
+        if (($this->_cache_on && $cache) || isset($this->_class_abbreviations[$class_name])) {
616 616
             // save it for later... kinda like gum  { : $
617 617
             $this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
618 618
         }
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
             case 1:
639 639
                 // if it's a FQCN then maybe the class is registered with a preceding \
640 640
                 $class_name = strpos($class_name, '\\') !== false
641
-                    ? '\\' . ltrim($class_name, '\\')
641
+                    ? '\\'.ltrim($class_name, '\\')
642 642
                     : $class_name;
643 643
                 break;
644 644
             case 2:
@@ -693,7 +693,7 @@  discard block
 block discarded – undo
693 693
             // make sure $class_prefix is uppercase
694 694
             $class_prefix = strtoupper(trim($class_prefix));
695 695
             // add class prefix ONCE!!!
696
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
696
+            $class_name = $class_prefix.str_replace($class_prefix, '', $class_name);
697 697
         }
698 698
         $class_name = $this->_dependency_map->get_alias($class_name);
699 699
         $class_exists = class_exists($class_name);
@@ -753,8 +753,8 @@  discard block
 block discarded – undo
753 753
     protected function _get_cached_class($class_name, $class_prefix = '')
754 754
     {
755 755
         // have to specify something, but not anything that will conflict
756
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
757
-            ? $this->_class_abbreviations[ $class_name ]
756
+        $class_abbreviation = isset($this->_class_abbreviations[$class_name])
757
+            ? $this->_class_abbreviations[$class_name]
758 758
             : 'FANCY_BATMAN_PANTS';
759 759
         $class_name = str_replace('\\', '_', $class_name);
760 760
         // check if class has already been loaded, and return it if it has been
@@ -785,8 +785,8 @@  discard block
 block discarded – undo
785 785
     public function clear_cached_class($class_name, $addon = false)
786 786
     {
787 787
         // have to specify something, but not anything that will conflict
788
-        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
789
-            ? $this->_class_abbreviations[ $class_name ]
788
+        $class_abbreviation = isset($this->_class_abbreviations[$class_name])
789
+            ? $this->_class_abbreviations[$class_name]
790 790
             : 'FANCY_BATMAN_PANTS';
791 791
         $class_name = str_replace('\\', '_', $class_name);
792 792
         // check if class has already been loaded, and return it if it has been
@@ -831,9 +831,9 @@  discard block
 block discarded – undo
831 831
             // convert all separators to proper DS, if no filepath, then use EE_CLASSES
832 832
             $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
833 833
             // prep file type
834
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
834
+            $type = ! empty($type) ? trim($type, '.').'.' : '';
835 835
             // build full file path
836
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
836
+            $file_paths[$key] = rtrim($file_path, DS).DS.$class_name.'.'.$type.'php';
837 837
             //does the file exist and can be read ?
838 838
             if (is_readable($file_paths[$key])) {
839 839
                 return $file_paths[$key];
@@ -864,12 +864,12 @@  discard block
 block discarded – undo
864 864
             //does the file exist and can it be read ?
865 865
             if ( ! $path) {
866 866
                 // so sorry, can't find the file
867
-                throw new EE_Error (
867
+                throw new EE_Error(
868 868
                     sprintf(
869 869
                         __('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
870 870
                         trim($type, '.'),
871 871
                         $class_name,
872
-                        '<br />' . implode(',<br />', $file_paths)
872
+                        '<br />'.implode(',<br />', $file_paths)
873 873
                     )
874 874
                 );
875 875
             }
Please login to merge, or discard this patch.
core/helpers/EEH_Activation.helper.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -613,7 +613,7 @@  discard block
 block discarded – undo
613 613
      *
614 614
      * @since  4.6.0
615 615
      * @global WPDB $wpdb
616
-     * @return mixed null|int WP_user ID or NULL
616
+     * @return integer|null null|int WP_user ID or NULL
617 617
      */
618 618
     public static function get_default_creator_id()
619 619
     {
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
      * @static
775 775
      * @deprecated instead use TableManager::dropTable()
776 776
      * @param string $table_name
777
-     * @return bool | int
777
+     * @return integer | int
778 778
      */
779 779
     public static function delete_unused_db_table($table_name)
780 780
     {
@@ -791,7 +791,7 @@  discard block
 block discarded – undo
791 791
      * @deprecated instead use TableManager::dropIndex()
792 792
      * @param string $table_name
793 793
      * @param string $index_name
794
-     * @return bool | int
794
+     * @return integer | int
795 795
      */
796 796
     public static function drop_index($table_name, $index_name)
797 797
     {
Please login to merge, or discard this patch.
Spacing   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -61,7 +61,7 @@  discard block
 block discarded – undo
61 61
      */
62 62
     public static function getTableAnalysis()
63 63
     {
64
-        if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
64
+        if ( ! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
65 65
             self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
66 66
         }
67 67
         return self::$table_analysis;
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
      */
74 74
     public static function getTableManager()
75 75
     {
76
-        if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
76
+        if ( ! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
77 77
             self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
78 78
         }
79 79
         return self::$table_manager;
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
         if ($which_to_include === 'old') {
190 190
             $cron_tasks = array_filter(
191 191
                 $cron_tasks,
192
-                function ($value) {
192
+                function($value) {
193 193
                     return $value === EEH_Activation::cron_task_no_longer_in_use;
194 194
                 }
195 195
             );
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
     {
220 220
 
221 221
         foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
222
-            if (! wp_next_scheduled($hook_name)) {
222
+            if ( ! wp_next_scheduled($hook_name)) {
223 223
                 /**
224 224
                  * This allows client code to define the initial start timestamp for this schedule.
225 225
                  */
@@ -324,7 +324,7 @@  discard block
 block discarded – undo
324 324
             3
325 325
         );
326 326
         //EE_Config::reset();
327
-        if (! EE_Config::logging_enabled()) {
327
+        if ( ! EE_Config::logging_enabled()) {
328 328
             delete_option(EE_Config::LOG_NAME);
329 329
         }
330 330
     }
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
     public static function load_calendar_config()
340 340
     {
341 341
         // grab array of all plugin folders and loop thru it
342
-        $plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
342
+        $plugins = glob(WP_PLUGIN_DIR.DS.'*', GLOB_ONLYDIR);
343 343
         if (empty($plugins)) {
344 344
             return;
345 345
         }
@@ -356,7 +356,7 @@  discard block
 block discarded – undo
356 356
                 || strpos($plugin, 'calendar') !== false
357 357
             ) {
358 358
                 // this is what we are looking for
359
-                $calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
359
+                $calendar_config = $plugin_path.DS.'EE_Calendar_Config.php';
360 360
                 // does it exist in this folder ?
361 361
                 if (is_readable($calendar_config)) {
362 362
                     // YEAH! let's load it
@@ -489,7 +489,7 @@  discard block
 block discarded – undo
489 489
             ) {
490 490
                 //update Config with post ID
491 491
                 $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
492
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
492
+                if ( ! EE_Config::instance()->update_espresso_config(false, false)) {
493 493
                     $msg = __(
494 494
                         'The Event Espresso critical page configuration settings could not be updated.',
495 495
                         'event_espresso'
@@ -538,7 +538,7 @@  discard block
 block discarded – undo
538 538
     public static function get_page_by_ee_shortcode($ee_shortcode)
539 539
     {
540 540
         global $wpdb;
541
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
541
+        $shortcode_and_opening_bracket = '['.$ee_shortcode;
542 542
         $post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
543 543
         if ($post_id) {
544 544
             return get_post($post_id);
@@ -564,11 +564,11 @@  discard block
 block discarded – undo
564 564
             'post_status'    => 'publish',
565 565
             'post_type'      => 'page',
566 566
             'comment_status' => 'closed',
567
-            'post_content'   => '[' . $critical_page['code'] . ']',
567
+            'post_content'   => '['.$critical_page['code'].']',
568 568
         );
569 569
 
570 570
         $post_id = wp_insert_post($post_args);
571
-        if (! $post_id) {
571
+        if ( ! $post_id) {
572 572
             $msg = sprintf(
573 573
                 __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
574 574
                 $critical_page['name']
@@ -577,7 +577,7 @@  discard block
 block discarded – undo
577 577
             return $critical_page;
578 578
         }
579 579
         // get newly created post's details
580
-        if (! $critical_page['post'] = get_post($post_id)) {
580
+        if ( ! $critical_page['post'] = get_post($post_id)) {
581 581
             $msg = sprintf(
582 582
                 __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
583 583
                 $critical_page['name']
@@ -664,17 +664,17 @@  discard block
 block discarded – undo
664 664
             $role_to_check
665 665
         );
666 666
         if ($pre_filtered_id !== false) {
667
-            return (int)$pre_filtered_id;
667
+            return (int) $pre_filtered_id;
668 668
         }
669 669
         $capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
670 670
         $query = $wpdb->prepare(
671 671
             "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
672
-            '%' . $role_to_check . '%'
672
+            '%'.$role_to_check.'%'
673 673
         );
674 674
         $user_id = $wpdb->get_var($query);
675 675
         $user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
676
-        if ($user_id && (int)$user_id) {
677
-            self::$_default_creator_id = (int)$user_id;
676
+        if ($user_id && (int) $user_id) {
677
+            self::$_default_creator_id = (int) $user_id;
678 678
             return self::$_default_creator_id;
679 679
         } else {
680 680
             return null;
@@ -709,7 +709,7 @@  discard block
 block discarded – undo
709 709
         }
710 710
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
711 711
         if ( ! function_exists('dbDelta')) {
712
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
712
+            require_once(ABSPATH.'wp-admin/includes/upgrade.php');
713 713
         }
714 714
         $tableAnalysis = \EEH_Activation::getTableAnalysis();
715 715
         $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
@@ -920,13 +920,13 @@  discard block
 block discarded – undo
920 920
             // reset values array
921 921
             $QSG_values = array();
922 922
             // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
923
-            if (! in_array("$QSG_system", $question_groups)) {
923
+            if ( ! in_array("$QSG_system", $question_groups)) {
924 924
                 // add it
925 925
                 switch ($QSG_system) {
926 926
                     case 1:
927 927
                         $QSG_values = array(
928 928
                             'QSG_name'            => __('Personal Information', 'event_espresso'),
929
-                            'QSG_identifier'      => 'personal-information-' . time(),
929
+                            'QSG_identifier'      => 'personal-information-'.time(),
930 930
                             'QSG_desc'            => '',
931 931
                             'QSG_order'           => 1,
932 932
                             'QSG_show_group_name' => 1,
@@ -938,7 +938,7 @@  discard block
 block discarded – undo
938 938
                     case 2:
939 939
                         $QSG_values = array(
940 940
                             'QSG_name'            => __('Address Information', 'event_espresso'),
941
-                            'QSG_identifier'      => 'address-information-' . time(),
941
+                            'QSG_identifier'      => 'address-information-'.time(),
942 942
                             'QSG_desc'            => '',
943 943
                             'QSG_order'           => 2,
944 944
                             'QSG_show_group_name' => 1,
@@ -949,7 +949,7 @@  discard block
 block discarded – undo
949 949
                         break;
950 950
                 }
951 951
                 // make sure we have some values before inserting them
952
-                if (! empty($QSG_values)) {
952
+                if ( ! empty($QSG_values)) {
953 953
                     // insert system question
954 954
                     $wpdb->insert(
955 955
                         $table_name,
@@ -986,7 +986,7 @@  discard block
 block discarded – undo
986 986
             // reset values array
987 987
             $QST_values = array();
988 988
             // if we don't have what we should have
989
-            if (! in_array($QST_system, $questions)) {
989
+            if ( ! in_array($QST_system, $questions)) {
990 990
                 // add it
991 991
                 switch ($QST_system) {
992 992
                     case 'fname':
@@ -1138,7 +1138,7 @@  discard block
 block discarded – undo
1138 1138
                         );
1139 1139
                         break;
1140 1140
                 }
1141
-                if (! empty($QST_values)) {
1141
+                if ( ! empty($QST_values)) {
1142 1142
                     // insert system question
1143 1143
                     $wpdb->insert(
1144 1144
                         $table_name,
@@ -1199,7 +1199,7 @@  discard block
 block discarded – undo
1199 1199
      */
1200 1200
     public static function insert_default_payment_methods()
1201 1201
     {
1202
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1202
+        if ( ! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1203 1203
             EE_Registry::instance()->load_lib('Payment_Method_Manager');
1204 1204
             EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1205 1205
         } else {
@@ -1287,9 +1287,9 @@  discard block
 block discarded – undo
1287 1287
         $folders = array(
1288 1288
             EVENT_ESPRESSO_TEMPLATE_DIR,
1289 1289
             EVENT_ESPRESSO_GATEWAY_DIR,
1290
-            EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1291
-            EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1292
-            EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1290
+            EVENT_ESPRESSO_UPLOAD_DIR.'logs/',
1291
+            EVENT_ESPRESSO_UPLOAD_DIR.'css/',
1292
+            EVENT_ESPRESSO_UPLOAD_DIR.'tickets/',
1293 1293
         );
1294 1294
         foreach ($folders as $folder) {
1295 1295
             try {
@@ -1300,7 +1300,7 @@  discard block
 block discarded – undo
1300 1300
                     sprintf(
1301 1301
                         __('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1302 1302
                         $folder,
1303
-                        '<br />' . $e->getMessage()
1303
+                        '<br />'.$e->getMessage()
1304 1304
                     ),
1305 1305
                     __FILE__, __FUNCTION__, __LINE__
1306 1306
                 );
@@ -1311,7 +1311,7 @@  discard block
 block discarded – undo
1311 1311
         }
1312 1312
         //just add the .htaccess file to the logs directory to begin with. Even if logging
1313 1313
         //is disabled, there might be activation errors recorded in there
1314
-        EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1314
+        EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR.'logs/');
1315 1315
         //remember EE's folders are all good
1316 1316
         delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1317 1317
         return true;
@@ -1547,7 +1547,7 @@  discard block
 block discarded – undo
1547 1547
         // this creates an array for tracking events that have no active ticket prices created
1548 1548
         // this allows us to warn admins of the situation so that it can be corrected
1549 1549
         $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1550
-        if (! $espresso_no_ticket_prices) {
1550
+        if ( ! $espresso_no_ticket_prices) {
1551 1551
             add_option('ee_no_ticket_prices', array(), '', false);
1552 1552
         }
1553 1553
     }
@@ -1586,7 +1586,7 @@  discard block
 block discarded – undo
1586 1586
             }
1587 1587
         }
1588 1588
         //get all our CPTs
1589
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1589
+        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (".implode(",", $ee_post_types).")";
1590 1590
         $cpt_ids = $wpdb->get_col($query);
1591 1591
         //delete each post meta and term relations too
1592 1592
         foreach ($cpt_ids as $post_id) {
@@ -1726,7 +1726,7 @@  discard block
 block discarded – undo
1726 1726
         if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1727 1727
             $db_update_sans_ee4 = array();
1728 1728
             foreach ($espresso_db_update as $version => $times_activated) {
1729
-                if ((string)$version[0] === '3') {//if its NON EE4
1729
+                if ((string) $version[0] === '3') {//if its NON EE4
1730 1730
                     $db_update_sans_ee4[$version] = $times_activated;
1731 1731
                 }
1732 1732
             }
Please login to merge, or discard this patch.
Indentation   +1653 added lines, -1653 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -14,244 +14,244 @@  discard block
 block discarded – undo
14 14
 class EEH_Activation
15 15
 {
16 16
 
17
-    /**
18
-     * constant used to indicate a cron task is no longer in use
19
-     */
20
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
21
-
22
-    /**
23
-     * option name that will indicate whether or not we still
24
-     * need to create EE's folders in the uploads directory
25
-     * (because if EE was installed without file system access,
26
-     * we need to request credentials before we can create them)
27
-     */
28
-    const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
29
-
30
-    /**
31
-     * WP_User->ID
32
-     *
33
-     * @var int
34
-     */
35
-    private static $_default_creator_id;
36
-
37
-    /**
38
-     * indicates whether or not we've already verified core's default data during this request,
39
-     * because after migrations are done, any addons activated while in maintenance mode
40
-     * will want to setup their own default data, and they might hook into core's default data
41
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
42
-     * This prevents doing that for EVERY single addon.
43
-     *
44
-     * @var boolean
45
-     */
46
-    protected static $_initialized_db_content_already_in_this_request = false;
47
-
48
-    /**
49
-     * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
50
-     */
51
-    private static $table_analysis;
52
-
53
-    /**
54
-     * @var \EventEspresso\core\services\database\TableManager $table_manager
55
-     */
56
-    private static $table_manager;
57
-
58
-
59
-    /**
60
-     * @return \EventEspresso\core\services\database\TableAnalysis
61
-     */
62
-    public static function getTableAnalysis()
63
-    {
64
-        if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
65
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
66
-        }
67
-        return self::$table_analysis;
68
-    }
69
-
70
-
71
-    /**
72
-     * @return \EventEspresso\core\services\database\TableManager
73
-     */
74
-    public static function getTableManager()
75
-    {
76
-        if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
77
-            self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
78
-        }
79
-        return self::$table_manager;
80
-    }
81
-
82
-
83
-    /**
84
-     *    _ensure_table_name_has_prefix
85
-     *
86
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
-     * @access     public
88
-     * @static
89
-     * @param $table_name
90
-     * @return string
91
-     */
92
-    public static function ensure_table_name_has_prefix($table_name)
93
-    {
94
-        return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
95
-    }
96
-
97
-
98
-    /**
99
-     *    system_initialization
100
-     *    ensures the EE configuration settings are loaded with at least default options set
101
-     *    and that all critical EE pages have been generated with the appropriate shortcodes in place
102
-     *
103
-     * @access public
104
-     * @static
105
-     * @return void
106
-     */
107
-    public static function system_initialization()
108
-    {
109
-        EEH_Activation::reset_and_update_config();
110
-        //which is fired BEFORE activation of plugin anyways
111
-        EEH_Activation::verify_default_pages_exist();
112
-    }
113
-
114
-
115
-    /**
116
-     * Sets the database schema and creates folders. This should
117
-     * be called on plugin activation and reactivation
118
-     *
119
-     * @return boolean success, whether the database and folders are setup properly
120
-     * @throws \EE_Error
121
-     */
122
-    public static function initialize_db_and_folders()
123
-    {
124
-        $good_filesystem = EEH_Activation::create_upload_directories();
125
-        $good_db         = EEH_Activation::create_database_tables();
126
-        return $good_filesystem && $good_db;
127
-    }
128
-
129
-
130
-    /**
131
-     * assuming we have an up-to-date database schema, this will populate it
132
-     * with default and initial data. This should be called
133
-     * upon activation of a new plugin, reactivation, and at the end
134
-     * of running migration scripts
135
-     *
136
-     * @throws \EE_Error
137
-     */
138
-    public static function initialize_db_content()
139
-    {
140
-        //let's avoid doing all this logic repeatedly, especially when addons are requesting it
141
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
142
-            return;
143
-        }
144
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
145
-
146
-        EEH_Activation::initialize_system_questions();
147
-        EEH_Activation::insert_default_status_codes();
148
-        EEH_Activation::generate_default_message_templates();
149
-        EEH_Activation::create_no_ticket_prices_array();
150
-        EE_Registry::instance()->CAP->init_caps();
151
-
152
-        EEH_Activation::validate_messages_system();
153
-        EEH_Activation::insert_default_payment_methods();
154
-        //in case we've
155
-        EEH_Activation::remove_cron_tasks();
156
-        EEH_Activation::create_cron_tasks();
157
-        // remove all TXN locks since that is being done via extra meta now
158
-        delete_option('ee_locked_transactions');
159
-        //also, check for CAF default db content
160
-        do_action('AHEE__EEH_Activation__initialize_db_content');
161
-        //also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
162
-        //which users really won't care about on initial activation
163
-        EE_Error::overwrite_success();
164
-    }
165
-
166
-
167
-    /**
168
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
169
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
170
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
171
-     * (null)
172
-     *
173
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
174
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
175
-     * @return array
176
-     * @throws \EE_Error
177
-     */
178
-    public static function get_cron_tasks($which_to_include)
179
-    {
180
-        $cron_tasks = apply_filters(
181
-            'FHEE__EEH_Activation__get_cron_tasks',
182
-            array(
183
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
17
+	/**
18
+	 * constant used to indicate a cron task is no longer in use
19
+	 */
20
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
21
+
22
+	/**
23
+	 * option name that will indicate whether or not we still
24
+	 * need to create EE's folders in the uploads directory
25
+	 * (because if EE was installed without file system access,
26
+	 * we need to request credentials before we can create them)
27
+	 */
28
+	const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
29
+
30
+	/**
31
+	 * WP_User->ID
32
+	 *
33
+	 * @var int
34
+	 */
35
+	private static $_default_creator_id;
36
+
37
+	/**
38
+	 * indicates whether or not we've already verified core's default data during this request,
39
+	 * because after migrations are done, any addons activated while in maintenance mode
40
+	 * will want to setup their own default data, and they might hook into core's default data
41
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
42
+	 * This prevents doing that for EVERY single addon.
43
+	 *
44
+	 * @var boolean
45
+	 */
46
+	protected static $_initialized_db_content_already_in_this_request = false;
47
+
48
+	/**
49
+	 * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
50
+	 */
51
+	private static $table_analysis;
52
+
53
+	/**
54
+	 * @var \EventEspresso\core\services\database\TableManager $table_manager
55
+	 */
56
+	private static $table_manager;
57
+
58
+
59
+	/**
60
+	 * @return \EventEspresso\core\services\database\TableAnalysis
61
+	 */
62
+	public static function getTableAnalysis()
63
+	{
64
+		if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
65
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
66
+		}
67
+		return self::$table_analysis;
68
+	}
69
+
70
+
71
+	/**
72
+	 * @return \EventEspresso\core\services\database\TableManager
73
+	 */
74
+	public static function getTableManager()
75
+	{
76
+		if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
77
+			self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
78
+		}
79
+		return self::$table_manager;
80
+	}
81
+
82
+
83
+	/**
84
+	 *    _ensure_table_name_has_prefix
85
+	 *
86
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
+	 * @access     public
88
+	 * @static
89
+	 * @param $table_name
90
+	 * @return string
91
+	 */
92
+	public static function ensure_table_name_has_prefix($table_name)
93
+	{
94
+		return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
95
+	}
96
+
97
+
98
+	/**
99
+	 *    system_initialization
100
+	 *    ensures the EE configuration settings are loaded with at least default options set
101
+	 *    and that all critical EE pages have been generated with the appropriate shortcodes in place
102
+	 *
103
+	 * @access public
104
+	 * @static
105
+	 * @return void
106
+	 */
107
+	public static function system_initialization()
108
+	{
109
+		EEH_Activation::reset_and_update_config();
110
+		//which is fired BEFORE activation of plugin anyways
111
+		EEH_Activation::verify_default_pages_exist();
112
+	}
113
+
114
+
115
+	/**
116
+	 * Sets the database schema and creates folders. This should
117
+	 * be called on plugin activation and reactivation
118
+	 *
119
+	 * @return boolean success, whether the database and folders are setup properly
120
+	 * @throws \EE_Error
121
+	 */
122
+	public static function initialize_db_and_folders()
123
+	{
124
+		$good_filesystem = EEH_Activation::create_upload_directories();
125
+		$good_db         = EEH_Activation::create_database_tables();
126
+		return $good_filesystem && $good_db;
127
+	}
128
+
129
+
130
+	/**
131
+	 * assuming we have an up-to-date database schema, this will populate it
132
+	 * with default and initial data. This should be called
133
+	 * upon activation of a new plugin, reactivation, and at the end
134
+	 * of running migration scripts
135
+	 *
136
+	 * @throws \EE_Error
137
+	 */
138
+	public static function initialize_db_content()
139
+	{
140
+		//let's avoid doing all this logic repeatedly, especially when addons are requesting it
141
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
142
+			return;
143
+		}
144
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
145
+
146
+		EEH_Activation::initialize_system_questions();
147
+		EEH_Activation::insert_default_status_codes();
148
+		EEH_Activation::generate_default_message_templates();
149
+		EEH_Activation::create_no_ticket_prices_array();
150
+		EE_Registry::instance()->CAP->init_caps();
151
+
152
+		EEH_Activation::validate_messages_system();
153
+		EEH_Activation::insert_default_payment_methods();
154
+		//in case we've
155
+		EEH_Activation::remove_cron_tasks();
156
+		EEH_Activation::create_cron_tasks();
157
+		// remove all TXN locks since that is being done via extra meta now
158
+		delete_option('ee_locked_transactions');
159
+		//also, check for CAF default db content
160
+		do_action('AHEE__EEH_Activation__initialize_db_content');
161
+		//also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
162
+		//which users really won't care about on initial activation
163
+		EE_Error::overwrite_success();
164
+	}
165
+
166
+
167
+	/**
168
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
169
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
170
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
171
+	 * (null)
172
+	 *
173
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
174
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
175
+	 * @return array
176
+	 * @throws \EE_Error
177
+	 */
178
+	public static function get_cron_tasks($which_to_include)
179
+	{
180
+		$cron_tasks = apply_filters(
181
+			'FHEE__EEH_Activation__get_cron_tasks',
182
+			array(
183
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
184 184
 //				'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
185
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
186
-                //there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
187
-                'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
188
-            )
189
-        );
190
-        if ($which_to_include === 'old') {
191
-            $cron_tasks = array_filter(
192
-                $cron_tasks,
193
-                function ($value) {
194
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
195
-                }
196
-            );
197
-        } elseif ($which_to_include === 'current') {
198
-            $cron_tasks = array_filter($cron_tasks);
199
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
200
-            throw new EE_Error(
201
-                sprintf(
202
-                    __(
203
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
204
-                        'event_espresso'
205
-                    ),
206
-                    $which_to_include
207
-                )
208
-            );
209
-        }
210
-        return $cron_tasks;
211
-    }
212
-
213
-
214
-    /**
215
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
216
-     *
217
-     * @throws \EE_Error
218
-     */
219
-    public static function create_cron_tasks()
220
-    {
221
-
222
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
223
-            if (! wp_next_scheduled($hook_name)) {
224
-                /**
225
-                 * This allows client code to define the initial start timestamp for this schedule.
226
-                 */
227
-                if (is_array($frequency)
228
-                    && count($frequency) === 2
229
-                    && isset($frequency[0], $frequency[1])
230
-                ) {
231
-                    $start_timestamp = $frequency[0];
232
-                    $frequency = $frequency[1];
233
-                } else {
234
-                    $start_timestamp = time();
235
-                }
236
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
237
-            }
238
-        }
239
-
240
-    }
241
-
242
-
243
-    /**
244
-     * Remove the currently-existing and now-removed cron tasks.
245
-     *
246
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
247
-     * @throws \EE_Error
248
-     */
249
-    public static function remove_cron_tasks($remove_all = true)
250
-    {
251
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
252
-        $crons                = _get_cron_array();
253
-        $crons                = is_array($crons) ? $crons : array();
254
-        /* reminder of what $crons look like:
185
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
186
+				//there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
187
+				'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
188
+			)
189
+		);
190
+		if ($which_to_include === 'old') {
191
+			$cron_tasks = array_filter(
192
+				$cron_tasks,
193
+				function ($value) {
194
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
195
+				}
196
+			);
197
+		} elseif ($which_to_include === 'current') {
198
+			$cron_tasks = array_filter($cron_tasks);
199
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
200
+			throw new EE_Error(
201
+				sprintf(
202
+					__(
203
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
204
+						'event_espresso'
205
+					),
206
+					$which_to_include
207
+				)
208
+			);
209
+		}
210
+		return $cron_tasks;
211
+	}
212
+
213
+
214
+	/**
215
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
216
+	 *
217
+	 * @throws \EE_Error
218
+	 */
219
+	public static function create_cron_tasks()
220
+	{
221
+
222
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
223
+			if (! wp_next_scheduled($hook_name)) {
224
+				/**
225
+				 * This allows client code to define the initial start timestamp for this schedule.
226
+				 */
227
+				if (is_array($frequency)
228
+					&& count($frequency) === 2
229
+					&& isset($frequency[0], $frequency[1])
230
+				) {
231
+					$start_timestamp = $frequency[0];
232
+					$frequency = $frequency[1];
233
+				} else {
234
+					$start_timestamp = time();
235
+				}
236
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
237
+			}
238
+		}
239
+
240
+	}
241
+
242
+
243
+	/**
244
+	 * Remove the currently-existing and now-removed cron tasks.
245
+	 *
246
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
247
+	 * @throws \EE_Error
248
+	 */
249
+	public static function remove_cron_tasks($remove_all = true)
250
+	{
251
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
252
+		$crons                = _get_cron_array();
253
+		$crons                = is_array($crons) ? $crons : array();
254
+		/* reminder of what $crons look like:
255 255
          * Top-level keys are timestamps, and their values are arrays.
256 256
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
257 257
          * and their values are arrays.
@@ -268,912 +268,912 @@  discard block
 block discarded – undo
268 268
          *					...
269 269
          *      ...
270 270
          */
271
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
272
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
273
-            if (is_array($hooks_to_fire_at_time)) {
274
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
275
-                    if (isset($ee_cron_tasks_to_remove[$hook_name])
276
-                        && is_array($ee_cron_tasks_to_remove[$hook_name])
277
-                    ) {
278
-                        unset($crons[$timestamp][$hook_name]);
279
-                    }
280
-                }
281
-                //also take care of any empty cron timestamps.
282
-                if (empty($hooks_to_fire_at_time)) {
283
-                    unset($crons[$timestamp]);
284
-                }
285
-            }
286
-        }
287
-        _set_cron_array($crons);
288
-    }
289
-
290
-
291
-    /**
292
-     *    CPT_initialization
293
-     *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
294
-     *
295
-     * @access public
296
-     * @static
297
-     * @return void
298
-     */
299
-    public static function CPT_initialization()
300
-    {
301
-        // register Custom Post Types
302
-        EE_Registry::instance()->load_core('Register_CPTs');
303
-        flush_rewrite_rules();
304
-    }
305
-
306
-
307
-
308
-    /**
309
-     *    reset_and_update_config
310
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
311
-     * If there is old calendar config data saved, then it will get converted on activation.
312
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
313
-     *
314
-     * @access public
315
-     * @static
316
-     * @return void
317
-     */
318
-    public static function reset_and_update_config()
319
-    {
320
-        do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
321
-        add_filter(
322
-            'FHEE__EE_Config___load_core_config__config_settings',
323
-            array('EEH_Activation', 'migrate_old_config_data'),
324
-            10,
325
-            3
326
-        );
327
-        //EE_Config::reset();
328
-        if (! EE_Config::logging_enabled()) {
329
-            delete_option(EE_Config::LOG_NAME);
330
-        }
331
-    }
332
-
333
-
334
-    /**
335
-     *    load_calendar_config
336
-     *
337
-     * @access    public
338
-     * @return    void
339
-     */
340
-    public static function load_calendar_config()
341
-    {
342
-        // grab array of all plugin folders and loop thru it
343
-        $plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
344
-        if (empty($plugins)) {
345
-            return;
346
-        }
347
-        foreach ($plugins as $plugin_path) {
348
-            // grab plugin folder name from path
349
-            $plugin = basename($plugin_path);
350
-            // drill down to Espresso plugins
351
-            // then to calendar related plugins
352
-            if (
353
-                strpos($plugin, 'espresso') !== false
354
-                || strpos($plugin, 'Espresso') !== false
355
-                || strpos($plugin, 'ee4') !== false
356
-                || strpos($plugin, 'EE4') !== false
357
-                || strpos($plugin, 'calendar') !== false
358
-            ) {
359
-                // this is what we are looking for
360
-                $calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
361
-                // does it exist in this folder ?
362
-                if (is_readable($calendar_config)) {
363
-                    // YEAH! let's load it
364
-                    require_once($calendar_config);
365
-                }
366
-            }
367
-        }
368
-    }
369
-
370
-
371
-
372
-    /**
373
-     *    _migrate_old_config_data
374
-     *
375
-     * @access    public
376
-     * @param array|stdClass $settings
377
-     * @param string         $config
378
-     * @param \EE_Config     $EE_Config
379
-     * @return \stdClass
380
-     */
381
-    public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
382
-    {
383
-        $convert_from_array = array('addons');
384
-        // in case old settings were saved as an array
385
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
386
-            // convert existing settings to an object
387
-            $config_array = $settings;
388
-            $settings = new stdClass();
389
-            foreach ($config_array as $key => $value) {
390
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
391
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
392
-                } else {
393
-                    $settings->{$key} = $value;
394
-                }
395
-            }
396
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
397
-        }
398
-        return $settings;
399
-    }
400
-
401
-
402
-    /**
403
-     * deactivate_event_espresso
404
-     *
405
-     * @access public
406
-     * @static
407
-     * @return void
408
-     */
409
-    public static function deactivate_event_espresso()
410
-    {
411
-        // check permissions
412
-        if (current_user_can('activate_plugins')) {
413
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
414
-        }
415
-    }
416
-
417
-
418
-
419
-
420
-
421
-    /**
422
-     * verify_default_pages_exist
423
-     *
424
-     * @access public
425
-     * @static
426
-     * @return void
427
-     */
428
-    public static function verify_default_pages_exist()
429
-    {
430
-        $critical_page_problem = false;
431
-        $critical_pages = array(
432
-            array(
433
-                'id'   => 'reg_page_id',
434
-                'name' => __('Registration Checkout', 'event_espresso'),
435
-                'post' => null,
436
-                'code' => 'ESPRESSO_CHECKOUT',
437
-            ),
438
-            array(
439
-                'id'   => 'txn_page_id',
440
-                'name' => __('Transactions', 'event_espresso'),
441
-                'post' => null,
442
-                'code' => 'ESPRESSO_TXN_PAGE',
443
-            ),
444
-            array(
445
-                'id'   => 'thank_you_page_id',
446
-                'name' => __('Thank You', 'event_espresso'),
447
-                'post' => null,
448
-                'code' => 'ESPRESSO_THANK_YOU',
449
-            ),
450
-            array(
451
-                'id'   => 'cancel_page_id',
452
-                'name' => __('Registration Cancelled', 'event_espresso'),
453
-                'post' => null,
454
-                'code' => 'ESPRESSO_CANCELLED',
455
-            ),
456
-        );
457
-        $EE_Core_Config = EE_Registry::instance()->CFG->core;
458
-        foreach ($critical_pages as $critical_page) {
459
-            // is critical page ID set in config ?
460
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
461
-                // attempt to find post by ID
462
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
463
-            }
464
-            // no dice?
465
-            if ($critical_page['post'] === null) {
466
-                // attempt to find post by title
467
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
468
-                // still nothing?
469
-                if ($critical_page['post'] === null) {
470
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
471
-                    // REALLY? Still nothing ??!?!?
472
-                    if ($critical_page['post'] === null) {
473
-                        $msg = __(
474
-                            'The Event Espresso critical page configuration settings could not be updated.',
475
-                            'event_espresso'
476
-                        );
477
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
478
-                        break;
479
-                    }
480
-                }
481
-            }
482
-            // check that Post ID matches critical page ID in config
483
-            if (
484
-                isset($critical_page['post']->ID)
485
-                && $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
486
-            ) {
487
-                //update Config with post ID
488
-                $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
489
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
490
-                    $msg = __(
491
-                        'The Event Espresso critical page configuration settings could not be updated.',
492
-                        'event_espresso'
493
-                    );
494
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
495
-                }
496
-            }
497
-            $critical_page_problem =
498
-                ! isset($critical_page['post']->post_status)
499
-                || $critical_page['post']->post_status !== 'publish'
500
-                || strpos($critical_page['post']->post_content, $critical_page['code']) === false
501
-                    ? true
502
-                    : $critical_page_problem;
503
-        }
504
-        if ($critical_page_problem) {
505
-            $msg = sprintf(
506
-                __(
507
-                    'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
508
-                    'event_espresso'
509
-                ),
510
-                '<a href="'
511
-                . admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
512
-                . '">'
513
-                . __('Event Espresso Critical Pages Settings', 'event_espresso')
514
-                . '</a>'
515
-            );
516
-            EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
517
-        }
518
-        if (EE_Error::has_notices()) {
519
-            EE_Error::get_notices(false, true, true);
520
-        }
521
-    }
522
-
523
-
524
-
525
-    /**
526
-     * Returns the first post which uses the specified shortcode
527
-     *
528
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
529
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
530
-     *                             "[ESPRESSO_THANK_YOU"
531
-     *                             (we don't search for the closing shortcode bracket because they might have added
532
-     *                             parameter to the shortcode
533
-     * @return WP_Post or NULl
534
-     */
535
-    public static function get_page_by_ee_shortcode($ee_shortcode)
536
-    {
537
-        global $wpdb;
538
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
539
-        $post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
540
-        if ($post_id) {
541
-            return get_post($post_id);
542
-        } else {
543
-            return null;
544
-        }
545
-    }
546
-
547
-
548
-    /**
549
-     *    This function generates a post for critical espresso pages
550
-     *
551
-     * @access public
552
-     * @static
553
-     * @param array $critical_page
554
-     * @return array
555
-     */
556
-    public static function create_critical_page($critical_page)
557
-    {
558
-
559
-        $post_args = array(
560
-            'post_title'     => $critical_page['name'],
561
-            'post_status'    => 'publish',
562
-            'post_type'      => 'page',
563
-            'comment_status' => 'closed',
564
-            'post_content'   => '[' . $critical_page['code'] . ']',
565
-        );
566
-
567
-        $post_id = wp_insert_post($post_args);
568
-        if (! $post_id) {
569
-            $msg = sprintf(
570
-                __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
571
-                $critical_page['name']
572
-            );
573
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
574
-            return $critical_page;
575
-        }
576
-        // get newly created post's details
577
-        if (! $critical_page['post'] = get_post($post_id)) {
578
-            $msg = sprintf(
579
-                __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
580
-                $critical_page['name']
581
-            );
582
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
583
-        }
584
-
585
-        return $critical_page;
586
-
587
-    }
588
-
589
-
590
-
591
-
592
-    /**
593
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
594
-     * The role being used to check is filterable.
595
-     *
596
-     * @since  4.6.0
597
-     * @global WPDB $wpdb
598
-     * @return mixed null|int WP_user ID or NULL
599
-     */
600
-    public static function get_default_creator_id()
601
-    {
602
-        global $wpdb;
603
-        if ( ! empty(self::$_default_creator_id)) {
604
-            return self::$_default_creator_id;
605
-        }/**/
606
-        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
607
-        //let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
608
-        $pre_filtered_id = apply_filters(
609
-            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
610
-            false,
611
-            $role_to_check
612
-        );
613
-        if ($pre_filtered_id !== false) {
614
-            return (int)$pre_filtered_id;
615
-        }
616
-        $capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
617
-        $query = $wpdb->prepare(
618
-            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
619
-            '%' . $role_to_check . '%'
620
-        );
621
-        $user_id = $wpdb->get_var($query);
622
-        $user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
623
-        if ($user_id && (int)$user_id) {
624
-            self::$_default_creator_id = (int)$user_id;
625
-            return self::$_default_creator_id;
626
-        } else {
627
-            return null;
628
-        }
629
-    }
630
-
631
-
632
-
633
-    /**
634
-     * used by EE and EE addons during plugin activation to create tables.
635
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
636
-     * but includes extra logic regarding activations.
637
-     *
638
-     * @access public
639
-     * @static
640
-     * @param string  $table_name              without the $wpdb->prefix
641
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
642
-     *                                         table query)
643
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
644
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
645
-     *                                         and new once this function is done (ie, you really do want to CREATE a
646
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
647
-     *                                         you just want to verify the table exists and matches this definition
648
-     *                                         (and if it HAS data in it you want to leave it be)
649
-     * @return void
650
-     * @throws EE_Error if there are database errors
651
-     */
652
-    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
653
-    {
654
-        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
655
-            return;
656
-        }
657
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
658
-        if ( ! function_exists('dbDelta')) {
659
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
660
-        }
661
-        $tableAnalysis = \EEH_Activation::getTableAnalysis();
662
-        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
663
-        // do we need to first delete an existing version of this table ?
664
-        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
665
-            // ok, delete the table... but ONLY if it's empty
666
-            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
667
-            // table is NOT empty, are you SURE you want to delete this table ???
668
-            if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
669
-                \EEH_Activation::getTableManager()->dropTable($wp_table_name);
670
-            } else if ( ! $deleted_safely) {
671
-                // so we should be more cautious rather than just dropping tables so easily
672
-                error_log(
673
-                    sprintf(
674
-                        __(
675
-                            'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
676
-                            'event_espresso'
677
-                        ),
678
-                        $wp_table_name,
679
-                        '<br/>',
680
-                        'espresso_db_update'
681
-                    )
682
-                );
683
-            }
684
-        }
685
-        $engine = str_replace('ENGINE=', '', $engine);
686
-        \EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
687
-    }
688
-
689
-
690
-
691
-    /**
692
-     *    add_column_if_it_doesn't_exist
693
-     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
694
-     *
695
-     * @access     public
696
-     * @static
697
-     * @deprecated instead use TableManager::addColumn()
698
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
699
-     * @param string $column_name
700
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
701
-     *                            'VARCHAR(10)'
702
-     * @return bool|int
703
-     */
704
-    public static function add_column_if_it_doesnt_exist(
705
-        $table_name,
706
-        $column_name,
707
-        $column_info = 'INT UNSIGNED NOT NULL'
708
-    ) {
709
-        return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
710
-    }
711
-
712
-
713
-    /**
714
-     * get_fields_on_table
715
-     * Gets all the fields on the database table.
716
-     *
717
-     * @access     public
718
-     * @deprecated instead use TableManager::getTableColumns()
719
-     * @static
720
-     * @param string $table_name , without prefixed $wpdb->prefix
721
-     * @return array of database column names
722
-     */
723
-    public static function get_fields_on_table($table_name = null)
724
-    {
725
-        return \EEH_Activation::getTableManager()->getTableColumns($table_name);
726
-    }
727
-
728
-
729
-    /**
730
-     * db_table_is_empty
731
-     *
732
-     * @access     public\
733
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
734
-     * @static
735
-     * @param string $table_name
736
-     * @return bool
737
-     */
738
-    public static function db_table_is_empty($table_name)
739
-    {
740
-        return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
741
-    }
742
-
743
-
744
-    /**
745
-     * delete_db_table_if_empty
746
-     *
747
-     * @access public
748
-     * @static
749
-     * @param string $table_name
750
-     * @return bool | int
751
-     */
752
-    public static function delete_db_table_if_empty($table_name)
753
-    {
754
-        if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
755
-            return \EEH_Activation::getTableManager()->dropTable($table_name);
756
-        }
757
-        return false;
758
-    }
759
-
760
-
761
-    /**
762
-     * delete_unused_db_table
763
-     *
764
-     * @access     public
765
-     * @static
766
-     * @deprecated instead use TableManager::dropTable()
767
-     * @param string $table_name
768
-     * @return bool | int
769
-     */
770
-    public static function delete_unused_db_table($table_name)
771
-    {
772
-        return \EEH_Activation::getTableManager()->dropTable($table_name);
773
-    }
774
-
775
-
776
-    /**
777
-     * drop_index
778
-     *
779
-     * @access     public
780
-     * @static
781
-     * @deprecated instead use TableManager::dropIndex()
782
-     * @param string $table_name
783
-     * @param string $index_name
784
-     * @return bool | int
785
-     */
786
-    public static function drop_index($table_name, $index_name)
787
-    {
788
-        return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
789
-    }
790
-
791
-
792
-
793
-    /**
794
-     * create_database_tables
795
-     *
796
-     * @access public
797
-     * @static
798
-     * @throws EE_Error
799
-     * @return boolean success (whether database is setup properly or not)
800
-     */
801
-    public static function create_database_tables()
802
-    {
803
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
804
-        //find the migration script that sets the database to be compatible with the code
805
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
806
-        if ($dms_name) {
807
-            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
808
-            $current_data_migration_script->set_migrating(false);
809
-            $current_data_migration_script->schema_changes_before_migration();
810
-            $current_data_migration_script->schema_changes_after_migration();
811
-            if ($current_data_migration_script->get_errors()) {
812
-                if (WP_DEBUG) {
813
-                    foreach ($current_data_migration_script->get_errors() as $error) {
814
-                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
815
-                    }
816
-                } else {
817
-                    EE_Error::add_error(
818
-                        __(
819
-                            'There were errors creating the Event Espresso database tables and Event Espresso has been 
271
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
272
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
273
+			if (is_array($hooks_to_fire_at_time)) {
274
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
275
+					if (isset($ee_cron_tasks_to_remove[$hook_name])
276
+						&& is_array($ee_cron_tasks_to_remove[$hook_name])
277
+					) {
278
+						unset($crons[$timestamp][$hook_name]);
279
+					}
280
+				}
281
+				//also take care of any empty cron timestamps.
282
+				if (empty($hooks_to_fire_at_time)) {
283
+					unset($crons[$timestamp]);
284
+				}
285
+			}
286
+		}
287
+		_set_cron_array($crons);
288
+	}
289
+
290
+
291
+	/**
292
+	 *    CPT_initialization
293
+	 *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
294
+	 *
295
+	 * @access public
296
+	 * @static
297
+	 * @return void
298
+	 */
299
+	public static function CPT_initialization()
300
+	{
301
+		// register Custom Post Types
302
+		EE_Registry::instance()->load_core('Register_CPTs');
303
+		flush_rewrite_rules();
304
+	}
305
+
306
+
307
+
308
+	/**
309
+	 *    reset_and_update_config
310
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
311
+	 * If there is old calendar config data saved, then it will get converted on activation.
312
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
313
+	 *
314
+	 * @access public
315
+	 * @static
316
+	 * @return void
317
+	 */
318
+	public static function reset_and_update_config()
319
+	{
320
+		do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
321
+		add_filter(
322
+			'FHEE__EE_Config___load_core_config__config_settings',
323
+			array('EEH_Activation', 'migrate_old_config_data'),
324
+			10,
325
+			3
326
+		);
327
+		//EE_Config::reset();
328
+		if (! EE_Config::logging_enabled()) {
329
+			delete_option(EE_Config::LOG_NAME);
330
+		}
331
+	}
332
+
333
+
334
+	/**
335
+	 *    load_calendar_config
336
+	 *
337
+	 * @access    public
338
+	 * @return    void
339
+	 */
340
+	public static function load_calendar_config()
341
+	{
342
+		// grab array of all plugin folders and loop thru it
343
+		$plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
344
+		if (empty($plugins)) {
345
+			return;
346
+		}
347
+		foreach ($plugins as $plugin_path) {
348
+			// grab plugin folder name from path
349
+			$plugin = basename($plugin_path);
350
+			// drill down to Espresso plugins
351
+			// then to calendar related plugins
352
+			if (
353
+				strpos($plugin, 'espresso') !== false
354
+				|| strpos($plugin, 'Espresso') !== false
355
+				|| strpos($plugin, 'ee4') !== false
356
+				|| strpos($plugin, 'EE4') !== false
357
+				|| strpos($plugin, 'calendar') !== false
358
+			) {
359
+				// this is what we are looking for
360
+				$calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
361
+				// does it exist in this folder ?
362
+				if (is_readable($calendar_config)) {
363
+					// YEAH! let's load it
364
+					require_once($calendar_config);
365
+				}
366
+			}
367
+		}
368
+	}
369
+
370
+
371
+
372
+	/**
373
+	 *    _migrate_old_config_data
374
+	 *
375
+	 * @access    public
376
+	 * @param array|stdClass $settings
377
+	 * @param string         $config
378
+	 * @param \EE_Config     $EE_Config
379
+	 * @return \stdClass
380
+	 */
381
+	public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
382
+	{
383
+		$convert_from_array = array('addons');
384
+		// in case old settings were saved as an array
385
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
386
+			// convert existing settings to an object
387
+			$config_array = $settings;
388
+			$settings = new stdClass();
389
+			foreach ($config_array as $key => $value) {
390
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
391
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
392
+				} else {
393
+					$settings->{$key} = $value;
394
+				}
395
+			}
396
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
397
+		}
398
+		return $settings;
399
+	}
400
+
401
+
402
+	/**
403
+	 * deactivate_event_espresso
404
+	 *
405
+	 * @access public
406
+	 * @static
407
+	 * @return void
408
+	 */
409
+	public static function deactivate_event_espresso()
410
+	{
411
+		// check permissions
412
+		if (current_user_can('activate_plugins')) {
413
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
414
+		}
415
+	}
416
+
417
+
418
+
419
+
420
+
421
+	/**
422
+	 * verify_default_pages_exist
423
+	 *
424
+	 * @access public
425
+	 * @static
426
+	 * @return void
427
+	 */
428
+	public static function verify_default_pages_exist()
429
+	{
430
+		$critical_page_problem = false;
431
+		$critical_pages = array(
432
+			array(
433
+				'id'   => 'reg_page_id',
434
+				'name' => __('Registration Checkout', 'event_espresso'),
435
+				'post' => null,
436
+				'code' => 'ESPRESSO_CHECKOUT',
437
+			),
438
+			array(
439
+				'id'   => 'txn_page_id',
440
+				'name' => __('Transactions', 'event_espresso'),
441
+				'post' => null,
442
+				'code' => 'ESPRESSO_TXN_PAGE',
443
+			),
444
+			array(
445
+				'id'   => 'thank_you_page_id',
446
+				'name' => __('Thank You', 'event_espresso'),
447
+				'post' => null,
448
+				'code' => 'ESPRESSO_THANK_YOU',
449
+			),
450
+			array(
451
+				'id'   => 'cancel_page_id',
452
+				'name' => __('Registration Cancelled', 'event_espresso'),
453
+				'post' => null,
454
+				'code' => 'ESPRESSO_CANCELLED',
455
+			),
456
+		);
457
+		$EE_Core_Config = EE_Registry::instance()->CFG->core;
458
+		foreach ($critical_pages as $critical_page) {
459
+			// is critical page ID set in config ?
460
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
461
+				// attempt to find post by ID
462
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
463
+			}
464
+			// no dice?
465
+			if ($critical_page['post'] === null) {
466
+				// attempt to find post by title
467
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
468
+				// still nothing?
469
+				if ($critical_page['post'] === null) {
470
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
471
+					// REALLY? Still nothing ??!?!?
472
+					if ($critical_page['post'] === null) {
473
+						$msg = __(
474
+							'The Event Espresso critical page configuration settings could not be updated.',
475
+							'event_espresso'
476
+						);
477
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
478
+						break;
479
+					}
480
+				}
481
+			}
482
+			// check that Post ID matches critical page ID in config
483
+			if (
484
+				isset($critical_page['post']->ID)
485
+				&& $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
486
+			) {
487
+				//update Config with post ID
488
+				$EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
489
+				if (! EE_Config::instance()->update_espresso_config(false, false)) {
490
+					$msg = __(
491
+						'The Event Espresso critical page configuration settings could not be updated.',
492
+						'event_espresso'
493
+					);
494
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
495
+				}
496
+			}
497
+			$critical_page_problem =
498
+				! isset($critical_page['post']->post_status)
499
+				|| $critical_page['post']->post_status !== 'publish'
500
+				|| strpos($critical_page['post']->post_content, $critical_page['code']) === false
501
+					? true
502
+					: $critical_page_problem;
503
+		}
504
+		if ($critical_page_problem) {
505
+			$msg = sprintf(
506
+				__(
507
+					'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
508
+					'event_espresso'
509
+				),
510
+				'<a href="'
511
+				. admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
512
+				. '">'
513
+				. __('Event Espresso Critical Pages Settings', 'event_espresso')
514
+				. '</a>'
515
+			);
516
+			EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
517
+		}
518
+		if (EE_Error::has_notices()) {
519
+			EE_Error::get_notices(false, true, true);
520
+		}
521
+	}
522
+
523
+
524
+
525
+	/**
526
+	 * Returns the first post which uses the specified shortcode
527
+	 *
528
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
529
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
530
+	 *                             "[ESPRESSO_THANK_YOU"
531
+	 *                             (we don't search for the closing shortcode bracket because they might have added
532
+	 *                             parameter to the shortcode
533
+	 * @return WP_Post or NULl
534
+	 */
535
+	public static function get_page_by_ee_shortcode($ee_shortcode)
536
+	{
537
+		global $wpdb;
538
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
539
+		$post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
540
+		if ($post_id) {
541
+			return get_post($post_id);
542
+		} else {
543
+			return null;
544
+		}
545
+	}
546
+
547
+
548
+	/**
549
+	 *    This function generates a post for critical espresso pages
550
+	 *
551
+	 * @access public
552
+	 * @static
553
+	 * @param array $critical_page
554
+	 * @return array
555
+	 */
556
+	public static function create_critical_page($critical_page)
557
+	{
558
+
559
+		$post_args = array(
560
+			'post_title'     => $critical_page['name'],
561
+			'post_status'    => 'publish',
562
+			'post_type'      => 'page',
563
+			'comment_status' => 'closed',
564
+			'post_content'   => '[' . $critical_page['code'] . ']',
565
+		);
566
+
567
+		$post_id = wp_insert_post($post_args);
568
+		if (! $post_id) {
569
+			$msg = sprintf(
570
+				__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
571
+				$critical_page['name']
572
+			);
573
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
574
+			return $critical_page;
575
+		}
576
+		// get newly created post's details
577
+		if (! $critical_page['post'] = get_post($post_id)) {
578
+			$msg = sprintf(
579
+				__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
580
+				$critical_page['name']
581
+			);
582
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
583
+		}
584
+
585
+		return $critical_page;
586
+
587
+	}
588
+
589
+
590
+
591
+
592
+	/**
593
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
594
+	 * The role being used to check is filterable.
595
+	 *
596
+	 * @since  4.6.0
597
+	 * @global WPDB $wpdb
598
+	 * @return mixed null|int WP_user ID or NULL
599
+	 */
600
+	public static function get_default_creator_id()
601
+	{
602
+		global $wpdb;
603
+		if ( ! empty(self::$_default_creator_id)) {
604
+			return self::$_default_creator_id;
605
+		}/**/
606
+		$role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
607
+		//let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
608
+		$pre_filtered_id = apply_filters(
609
+			'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
610
+			false,
611
+			$role_to_check
612
+		);
613
+		if ($pre_filtered_id !== false) {
614
+			return (int)$pre_filtered_id;
615
+		}
616
+		$capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
617
+		$query = $wpdb->prepare(
618
+			"SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
619
+			'%' . $role_to_check . '%'
620
+		);
621
+		$user_id = $wpdb->get_var($query);
622
+		$user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
623
+		if ($user_id && (int)$user_id) {
624
+			self::$_default_creator_id = (int)$user_id;
625
+			return self::$_default_creator_id;
626
+		} else {
627
+			return null;
628
+		}
629
+	}
630
+
631
+
632
+
633
+	/**
634
+	 * used by EE and EE addons during plugin activation to create tables.
635
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
636
+	 * but includes extra logic regarding activations.
637
+	 *
638
+	 * @access public
639
+	 * @static
640
+	 * @param string  $table_name              without the $wpdb->prefix
641
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
642
+	 *                                         table query)
643
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
644
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
645
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
646
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
647
+	 *                                         you just want to verify the table exists and matches this definition
648
+	 *                                         (and if it HAS data in it you want to leave it be)
649
+	 * @return void
650
+	 * @throws EE_Error if there are database errors
651
+	 */
652
+	public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
653
+	{
654
+		if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
655
+			return;
656
+		}
657
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
658
+		if ( ! function_exists('dbDelta')) {
659
+			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
660
+		}
661
+		$tableAnalysis = \EEH_Activation::getTableAnalysis();
662
+		$wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
663
+		// do we need to first delete an existing version of this table ?
664
+		if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
665
+			// ok, delete the table... but ONLY if it's empty
666
+			$deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
667
+			// table is NOT empty, are you SURE you want to delete this table ???
668
+			if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
669
+				\EEH_Activation::getTableManager()->dropTable($wp_table_name);
670
+			} else if ( ! $deleted_safely) {
671
+				// so we should be more cautious rather than just dropping tables so easily
672
+				error_log(
673
+					sprintf(
674
+						__(
675
+							'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
676
+							'event_espresso'
677
+						),
678
+						$wp_table_name,
679
+						'<br/>',
680
+						'espresso_db_update'
681
+					)
682
+				);
683
+			}
684
+		}
685
+		$engine = str_replace('ENGINE=', '', $engine);
686
+		\EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
687
+	}
688
+
689
+
690
+
691
+	/**
692
+	 *    add_column_if_it_doesn't_exist
693
+	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
694
+	 *
695
+	 * @access     public
696
+	 * @static
697
+	 * @deprecated instead use TableManager::addColumn()
698
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
699
+	 * @param string $column_name
700
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
701
+	 *                            'VARCHAR(10)'
702
+	 * @return bool|int
703
+	 */
704
+	public static function add_column_if_it_doesnt_exist(
705
+		$table_name,
706
+		$column_name,
707
+		$column_info = 'INT UNSIGNED NOT NULL'
708
+	) {
709
+		return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
710
+	}
711
+
712
+
713
+	/**
714
+	 * get_fields_on_table
715
+	 * Gets all the fields on the database table.
716
+	 *
717
+	 * @access     public
718
+	 * @deprecated instead use TableManager::getTableColumns()
719
+	 * @static
720
+	 * @param string $table_name , without prefixed $wpdb->prefix
721
+	 * @return array of database column names
722
+	 */
723
+	public static function get_fields_on_table($table_name = null)
724
+	{
725
+		return \EEH_Activation::getTableManager()->getTableColumns($table_name);
726
+	}
727
+
728
+
729
+	/**
730
+	 * db_table_is_empty
731
+	 *
732
+	 * @access     public\
733
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
734
+	 * @static
735
+	 * @param string $table_name
736
+	 * @return bool
737
+	 */
738
+	public static function db_table_is_empty($table_name)
739
+	{
740
+		return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
741
+	}
742
+
743
+
744
+	/**
745
+	 * delete_db_table_if_empty
746
+	 *
747
+	 * @access public
748
+	 * @static
749
+	 * @param string $table_name
750
+	 * @return bool | int
751
+	 */
752
+	public static function delete_db_table_if_empty($table_name)
753
+	{
754
+		if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
755
+			return \EEH_Activation::getTableManager()->dropTable($table_name);
756
+		}
757
+		return false;
758
+	}
759
+
760
+
761
+	/**
762
+	 * delete_unused_db_table
763
+	 *
764
+	 * @access     public
765
+	 * @static
766
+	 * @deprecated instead use TableManager::dropTable()
767
+	 * @param string $table_name
768
+	 * @return bool | int
769
+	 */
770
+	public static function delete_unused_db_table($table_name)
771
+	{
772
+		return \EEH_Activation::getTableManager()->dropTable($table_name);
773
+	}
774
+
775
+
776
+	/**
777
+	 * drop_index
778
+	 *
779
+	 * @access     public
780
+	 * @static
781
+	 * @deprecated instead use TableManager::dropIndex()
782
+	 * @param string $table_name
783
+	 * @param string $index_name
784
+	 * @return bool | int
785
+	 */
786
+	public static function drop_index($table_name, $index_name)
787
+	{
788
+		return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
789
+	}
790
+
791
+
792
+
793
+	/**
794
+	 * create_database_tables
795
+	 *
796
+	 * @access public
797
+	 * @static
798
+	 * @throws EE_Error
799
+	 * @return boolean success (whether database is setup properly or not)
800
+	 */
801
+	public static function create_database_tables()
802
+	{
803
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
804
+		//find the migration script that sets the database to be compatible with the code
805
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
806
+		if ($dms_name) {
807
+			$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
808
+			$current_data_migration_script->set_migrating(false);
809
+			$current_data_migration_script->schema_changes_before_migration();
810
+			$current_data_migration_script->schema_changes_after_migration();
811
+			if ($current_data_migration_script->get_errors()) {
812
+				if (WP_DEBUG) {
813
+					foreach ($current_data_migration_script->get_errors() as $error) {
814
+						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
815
+					}
816
+				} else {
817
+					EE_Error::add_error(
818
+						__(
819
+							'There were errors creating the Event Espresso database tables and Event Espresso has been 
820 820
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
821
-                            'event_espresso'
822
-                        )
823
-                    );
824
-                }
825
-                return false;
826
-            }
827
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
828
-        } else {
829
-            EE_Error::add_error(
830
-                __(
831
-                    'Could not determine most up-to-date data migration script from which to pull database schema
821
+							'event_espresso'
822
+						)
823
+					);
824
+				}
825
+				return false;
826
+			}
827
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
828
+		} else {
829
+			EE_Error::add_error(
830
+				__(
831
+					'Could not determine most up-to-date data migration script from which to pull database schema
832 832
                      structure. So database is probably not setup properly',
833
-                    'event_espresso'
834
-                ),
835
-                __FILE__,
836
-                __FUNCTION__,
837
-                __LINE__
838
-            );
839
-            return false;
840
-        }
841
-        return true;
842
-    }
843
-
844
-
845
-
846
-    /**
847
-     * initialize_system_questions
848
-     *
849
-     * @access public
850
-     * @static
851
-     * @return void
852
-     */
853
-    public static function initialize_system_questions()
854
-    {
855
-        // QUESTION GROUPS
856
-        global $wpdb;
857
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
858
-        $SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
859
-        // what we have
860
-        $question_groups = $wpdb->get_col($SQL);
861
-        // check the response
862
-        $question_groups = is_array($question_groups) ? $question_groups : array();
863
-        // what we should have
864
-        $QSG_systems = array(1, 2);
865
-        // loop thru what we should have and compare to what we have
866
-        foreach ($QSG_systems as $QSG_system) {
867
-            // reset values array
868
-            $QSG_values = array();
869
-            // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
870
-            if (! in_array("$QSG_system", $question_groups)) {
871
-                // add it
872
-                switch ($QSG_system) {
873
-                    case 1:
874
-                        $QSG_values = array(
875
-                            'QSG_name'            => __('Personal Information', 'event_espresso'),
876
-                            'QSG_identifier'      => 'personal-information-' . time(),
877
-                            'QSG_desc'            => '',
878
-                            'QSG_order'           => 1,
879
-                            'QSG_show_group_name' => 1,
880
-                            'QSG_show_group_desc' => 1,
881
-                            'QSG_system'          => EEM_Question_Group::system_personal,
882
-                            'QSG_deleted'         => 0,
883
-                        );
884
-                        break;
885
-                    case 2:
886
-                        $QSG_values = array(
887
-                            'QSG_name'            => __('Address Information', 'event_espresso'),
888
-                            'QSG_identifier'      => 'address-information-' . time(),
889
-                            'QSG_desc'            => '',
890
-                            'QSG_order'           => 2,
891
-                            'QSG_show_group_name' => 1,
892
-                            'QSG_show_group_desc' => 1,
893
-                            'QSG_system'          => EEM_Question_Group::system_address,
894
-                            'QSG_deleted'         => 0,
895
-                        );
896
-                        break;
897
-                }
898
-                // make sure we have some values before inserting them
899
-                if (! empty($QSG_values)) {
900
-                    // insert system question
901
-                    $wpdb->insert(
902
-                        $table_name,
903
-                        $QSG_values,
904
-                        array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
905
-                    );
906
-                    $QSG_IDs[$QSG_system] = $wpdb->insert_id;
907
-                }
908
-            }
909
-        }
910
-        // QUESTIONS
911
-        global $wpdb;
912
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
913
-        $SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
914
-        // what we have
915
-        $questions = $wpdb->get_col($SQL);
916
-        // what we should have
917
-        $QST_systems = array(
918
-            'fname',
919
-            'lname',
920
-            'email',
921
-            'address',
922
-            'address2',
923
-            'city',
924
-            'country',
925
-            'state',
926
-            'zip',
927
-            'phone',
928
-        );
929
-        $order_for_group_1 = 1;
930
-        $order_for_group_2 = 1;
931
-        // loop thru what we should have and compare to what we have
932
-        foreach ($QST_systems as $QST_system) {
933
-            // reset values array
934
-            $QST_values = array();
935
-            // if we don't have what we should have
936
-            if (! in_array($QST_system, $questions)) {
937
-                // add it
938
-                switch ($QST_system) {
939
-                    case 'fname':
940
-                        $QST_values = array(
941
-                            'QST_display_text'  => __('First Name', 'event_espresso'),
942
-                            'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
943
-                            'QST_system'        => 'fname',
944
-                            'QST_type'          => 'TEXT',
945
-                            'QST_required'      => 1,
946
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
947
-                            'QST_order'         => 1,
948
-                            'QST_admin_only'    => 0,
949
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
950
-                            'QST_wp_user'       => self::get_default_creator_id(),
951
-                            'QST_deleted'       => 0,
952
-                        );
953
-                        break;
954
-                    case 'lname':
955
-                        $QST_values = array(
956
-                            'QST_display_text'  => __('Last Name', 'event_espresso'),
957
-                            'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
958
-                            'QST_system'        => 'lname',
959
-                            'QST_type'          => 'TEXT',
960
-                            'QST_required'      => 1,
961
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
962
-                            'QST_order'         => 2,
963
-                            'QST_admin_only'    => 0,
964
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
965
-                            'QST_wp_user'       => self::get_default_creator_id(),
966
-                            'QST_deleted'       => 0,
967
-                        );
968
-                        break;
969
-                    case 'email':
970
-                        $QST_values = array(
971
-                            'QST_display_text'  => __('Email Address', 'event_espresso'),
972
-                            'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
973
-                            'QST_system'        => 'email',
974
-                            'QST_type'          => 'EMAIL',
975
-                            'QST_required'      => 1,
976
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
977
-                            'QST_order'         => 3,
978
-                            'QST_admin_only'    => 0,
979
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
980
-                            'QST_wp_user'       => self::get_default_creator_id(),
981
-                            'QST_deleted'       => 0,
982
-                        );
983
-                        break;
984
-                    case 'address':
985
-                        $QST_values = array(
986
-                            'QST_display_text'  => __('Address', 'event_espresso'),
987
-                            'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
988
-                            'QST_system'        => 'address',
989
-                            'QST_type'          => 'TEXT',
990
-                            'QST_required'      => 0,
991
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
992
-                            'QST_order'         => 4,
993
-                            'QST_admin_only'    => 0,
994
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
995
-                            'QST_wp_user'       => self::get_default_creator_id(),
996
-                            'QST_deleted'       => 0,
997
-                        );
998
-                        break;
999
-                    case 'address2':
1000
-                        $QST_values = array(
1001
-                            'QST_display_text'  => __('Address2', 'event_espresso'),
1002
-                            'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1003
-                            'QST_system'        => 'address2',
1004
-                            'QST_type'          => 'TEXT',
1005
-                            'QST_required'      => 0,
1006
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1007
-                            'QST_order'         => 5,
1008
-                            'QST_admin_only'    => 0,
1009
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1010
-                            'QST_wp_user'       => self::get_default_creator_id(),
1011
-                            'QST_deleted'       => 0,
1012
-                        );
1013
-                        break;
1014
-                    case 'city':
1015
-                        $QST_values = array(
1016
-                            'QST_display_text'  => __('City', 'event_espresso'),
1017
-                            'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1018
-                            'QST_system'        => 'city',
1019
-                            'QST_type'          => 'TEXT',
1020
-                            'QST_required'      => 0,
1021
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1022
-                            'QST_order'         => 6,
1023
-                            'QST_admin_only'    => 0,
1024
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1025
-                            'QST_wp_user'       => self::get_default_creator_id(),
1026
-                            'QST_deleted'       => 0,
1027
-                        );
1028
-                        break;
1029
-                    case 'country':
1030
-                        $QST_values = array(
1031
-                            'QST_display_text'  => __('Country', 'event_espresso'),
1032
-                            'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1033
-                            'QST_system'        => 'country',
1034
-                            'QST_type'          => 'COUNTRY',
1035
-                            'QST_required'      => 0,
1036
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1037
-                            'QST_order'         => 7,
1038
-                            'QST_admin_only'    => 0,
1039
-                            'QST_wp_user'       => self::get_default_creator_id(),
1040
-                            'QST_deleted'       => 0,
1041
-                        );
1042
-                        break;
1043
-                    case 'state':
1044
-                        $QST_values = array(
1045
-                            'QST_display_text'  => __('State/Province', 'event_espresso'),
1046
-                            'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1047
-                            'QST_system'        => 'state',
1048
-                            'QST_type'          => 'STATE',
1049
-                            'QST_required'      => 0,
1050
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1051
-                            'QST_order'         => 8,
1052
-                            'QST_admin_only'    => 0,
1053
-                            'QST_wp_user'       => self::get_default_creator_id(),
1054
-                            'QST_deleted'       => 0,
1055
-                        );
1056
-                        break;
1057
-                    case 'zip':
1058
-                        $QST_values = array(
1059
-                            'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1060
-                            'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1061
-                            'QST_system'        => 'zip',
1062
-                            'QST_type'          => 'TEXT',
1063
-                            'QST_required'      => 0,
1064
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1065
-                            'QST_order'         => 9,
1066
-                            'QST_admin_only'    => 0,
1067
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1068
-                            'QST_wp_user'       => self::get_default_creator_id(),
1069
-                            'QST_deleted'       => 0,
1070
-                        );
1071
-                        break;
1072
-                    case 'phone':
1073
-                        $QST_values = array(
1074
-                            'QST_display_text'  => __('Phone Number', 'event_espresso'),
1075
-                            'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1076
-                            'QST_system'        => 'phone',
1077
-                            'QST_type'          => 'TEXT',
1078
-                            'QST_required'      => 0,
1079
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1080
-                            'QST_order'         => 10,
1081
-                            'QST_admin_only'    => 0,
1082
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1083
-                            'QST_wp_user'       => self::get_default_creator_id(),
1084
-                            'QST_deleted'       => 0,
1085
-                        );
1086
-                        break;
1087
-                }
1088
-                if (! empty($QST_values)) {
1089
-                    // insert system question
1090
-                    $wpdb->insert(
1091
-                        $table_name,
1092
-                        $QST_values,
1093
-                        array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1094
-                    );
1095
-                    $QST_ID = $wpdb->insert_id;
1096
-                    // QUESTION GROUP QUESTIONS
1097
-                    if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1098
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1099
-                    } else {
1100
-                        $system_question_we_want = EEM_Question_Group::system_address;
1101
-                    }
1102
-                    if (isset($QSG_IDs[$system_question_we_want])) {
1103
-                        $QSG_ID = $QSG_IDs[$system_question_we_want];
1104
-                    } else {
1105
-                        $id_col = EEM_Question_Group::instance()
1106
-                                                    ->get_col(array(array('QSG_system' => $system_question_we_want)));
1107
-                        if (is_array($id_col)) {
1108
-                            $QSG_ID = reset($id_col);
1109
-                        } else {
1110
-                            //ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1111
-                            EE_Log::instance()->log(
1112
-                                __FILE__,
1113
-                                __FUNCTION__,
1114
-                                sprintf(
1115
-                                    __(
1116
-                                        'Could not associate question %1$s to a question group because no system question
833
+					'event_espresso'
834
+				),
835
+				__FILE__,
836
+				__FUNCTION__,
837
+				__LINE__
838
+			);
839
+			return false;
840
+		}
841
+		return true;
842
+	}
843
+
844
+
845
+
846
+	/**
847
+	 * initialize_system_questions
848
+	 *
849
+	 * @access public
850
+	 * @static
851
+	 * @return void
852
+	 */
853
+	public static function initialize_system_questions()
854
+	{
855
+		// QUESTION GROUPS
856
+		global $wpdb;
857
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
858
+		$SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
859
+		// what we have
860
+		$question_groups = $wpdb->get_col($SQL);
861
+		// check the response
862
+		$question_groups = is_array($question_groups) ? $question_groups : array();
863
+		// what we should have
864
+		$QSG_systems = array(1, 2);
865
+		// loop thru what we should have and compare to what we have
866
+		foreach ($QSG_systems as $QSG_system) {
867
+			// reset values array
868
+			$QSG_values = array();
869
+			// if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
870
+			if (! in_array("$QSG_system", $question_groups)) {
871
+				// add it
872
+				switch ($QSG_system) {
873
+					case 1:
874
+						$QSG_values = array(
875
+							'QSG_name'            => __('Personal Information', 'event_espresso'),
876
+							'QSG_identifier'      => 'personal-information-' . time(),
877
+							'QSG_desc'            => '',
878
+							'QSG_order'           => 1,
879
+							'QSG_show_group_name' => 1,
880
+							'QSG_show_group_desc' => 1,
881
+							'QSG_system'          => EEM_Question_Group::system_personal,
882
+							'QSG_deleted'         => 0,
883
+						);
884
+						break;
885
+					case 2:
886
+						$QSG_values = array(
887
+							'QSG_name'            => __('Address Information', 'event_espresso'),
888
+							'QSG_identifier'      => 'address-information-' . time(),
889
+							'QSG_desc'            => '',
890
+							'QSG_order'           => 2,
891
+							'QSG_show_group_name' => 1,
892
+							'QSG_show_group_desc' => 1,
893
+							'QSG_system'          => EEM_Question_Group::system_address,
894
+							'QSG_deleted'         => 0,
895
+						);
896
+						break;
897
+				}
898
+				// make sure we have some values before inserting them
899
+				if (! empty($QSG_values)) {
900
+					// insert system question
901
+					$wpdb->insert(
902
+						$table_name,
903
+						$QSG_values,
904
+						array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
905
+					);
906
+					$QSG_IDs[$QSG_system] = $wpdb->insert_id;
907
+				}
908
+			}
909
+		}
910
+		// QUESTIONS
911
+		global $wpdb;
912
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
913
+		$SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
914
+		// what we have
915
+		$questions = $wpdb->get_col($SQL);
916
+		// what we should have
917
+		$QST_systems = array(
918
+			'fname',
919
+			'lname',
920
+			'email',
921
+			'address',
922
+			'address2',
923
+			'city',
924
+			'country',
925
+			'state',
926
+			'zip',
927
+			'phone',
928
+		);
929
+		$order_for_group_1 = 1;
930
+		$order_for_group_2 = 1;
931
+		// loop thru what we should have and compare to what we have
932
+		foreach ($QST_systems as $QST_system) {
933
+			// reset values array
934
+			$QST_values = array();
935
+			// if we don't have what we should have
936
+			if (! in_array($QST_system, $questions)) {
937
+				// add it
938
+				switch ($QST_system) {
939
+					case 'fname':
940
+						$QST_values = array(
941
+							'QST_display_text'  => __('First Name', 'event_espresso'),
942
+							'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
943
+							'QST_system'        => 'fname',
944
+							'QST_type'          => 'TEXT',
945
+							'QST_required'      => 1,
946
+							'QST_required_text' => __('This field is required', 'event_espresso'),
947
+							'QST_order'         => 1,
948
+							'QST_admin_only'    => 0,
949
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
950
+							'QST_wp_user'       => self::get_default_creator_id(),
951
+							'QST_deleted'       => 0,
952
+						);
953
+						break;
954
+					case 'lname':
955
+						$QST_values = array(
956
+							'QST_display_text'  => __('Last Name', 'event_espresso'),
957
+							'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
958
+							'QST_system'        => 'lname',
959
+							'QST_type'          => 'TEXT',
960
+							'QST_required'      => 1,
961
+							'QST_required_text' => __('This field is required', 'event_espresso'),
962
+							'QST_order'         => 2,
963
+							'QST_admin_only'    => 0,
964
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
965
+							'QST_wp_user'       => self::get_default_creator_id(),
966
+							'QST_deleted'       => 0,
967
+						);
968
+						break;
969
+					case 'email':
970
+						$QST_values = array(
971
+							'QST_display_text'  => __('Email Address', 'event_espresso'),
972
+							'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
973
+							'QST_system'        => 'email',
974
+							'QST_type'          => 'EMAIL',
975
+							'QST_required'      => 1,
976
+							'QST_required_text' => __('This field is required', 'event_espresso'),
977
+							'QST_order'         => 3,
978
+							'QST_admin_only'    => 0,
979
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
980
+							'QST_wp_user'       => self::get_default_creator_id(),
981
+							'QST_deleted'       => 0,
982
+						);
983
+						break;
984
+					case 'address':
985
+						$QST_values = array(
986
+							'QST_display_text'  => __('Address', 'event_espresso'),
987
+							'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
988
+							'QST_system'        => 'address',
989
+							'QST_type'          => 'TEXT',
990
+							'QST_required'      => 0,
991
+							'QST_required_text' => __('This field is required', 'event_espresso'),
992
+							'QST_order'         => 4,
993
+							'QST_admin_only'    => 0,
994
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
995
+							'QST_wp_user'       => self::get_default_creator_id(),
996
+							'QST_deleted'       => 0,
997
+						);
998
+						break;
999
+					case 'address2':
1000
+						$QST_values = array(
1001
+							'QST_display_text'  => __('Address2', 'event_espresso'),
1002
+							'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1003
+							'QST_system'        => 'address2',
1004
+							'QST_type'          => 'TEXT',
1005
+							'QST_required'      => 0,
1006
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1007
+							'QST_order'         => 5,
1008
+							'QST_admin_only'    => 0,
1009
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1010
+							'QST_wp_user'       => self::get_default_creator_id(),
1011
+							'QST_deleted'       => 0,
1012
+						);
1013
+						break;
1014
+					case 'city':
1015
+						$QST_values = array(
1016
+							'QST_display_text'  => __('City', 'event_espresso'),
1017
+							'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1018
+							'QST_system'        => 'city',
1019
+							'QST_type'          => 'TEXT',
1020
+							'QST_required'      => 0,
1021
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1022
+							'QST_order'         => 6,
1023
+							'QST_admin_only'    => 0,
1024
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1025
+							'QST_wp_user'       => self::get_default_creator_id(),
1026
+							'QST_deleted'       => 0,
1027
+						);
1028
+						break;
1029
+					case 'country':
1030
+						$QST_values = array(
1031
+							'QST_display_text'  => __('Country', 'event_espresso'),
1032
+							'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1033
+							'QST_system'        => 'country',
1034
+							'QST_type'          => 'COUNTRY',
1035
+							'QST_required'      => 0,
1036
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1037
+							'QST_order'         => 7,
1038
+							'QST_admin_only'    => 0,
1039
+							'QST_wp_user'       => self::get_default_creator_id(),
1040
+							'QST_deleted'       => 0,
1041
+						);
1042
+						break;
1043
+					case 'state':
1044
+						$QST_values = array(
1045
+							'QST_display_text'  => __('State/Province', 'event_espresso'),
1046
+							'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1047
+							'QST_system'        => 'state',
1048
+							'QST_type'          => 'STATE',
1049
+							'QST_required'      => 0,
1050
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1051
+							'QST_order'         => 8,
1052
+							'QST_admin_only'    => 0,
1053
+							'QST_wp_user'       => self::get_default_creator_id(),
1054
+							'QST_deleted'       => 0,
1055
+						);
1056
+						break;
1057
+					case 'zip':
1058
+						$QST_values = array(
1059
+							'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1060
+							'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1061
+							'QST_system'        => 'zip',
1062
+							'QST_type'          => 'TEXT',
1063
+							'QST_required'      => 0,
1064
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1065
+							'QST_order'         => 9,
1066
+							'QST_admin_only'    => 0,
1067
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1068
+							'QST_wp_user'       => self::get_default_creator_id(),
1069
+							'QST_deleted'       => 0,
1070
+						);
1071
+						break;
1072
+					case 'phone':
1073
+						$QST_values = array(
1074
+							'QST_display_text'  => __('Phone Number', 'event_espresso'),
1075
+							'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1076
+							'QST_system'        => 'phone',
1077
+							'QST_type'          => 'TEXT',
1078
+							'QST_required'      => 0,
1079
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1080
+							'QST_order'         => 10,
1081
+							'QST_admin_only'    => 0,
1082
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1083
+							'QST_wp_user'       => self::get_default_creator_id(),
1084
+							'QST_deleted'       => 0,
1085
+						);
1086
+						break;
1087
+				}
1088
+				if (! empty($QST_values)) {
1089
+					// insert system question
1090
+					$wpdb->insert(
1091
+						$table_name,
1092
+						$QST_values,
1093
+						array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1094
+					);
1095
+					$QST_ID = $wpdb->insert_id;
1096
+					// QUESTION GROUP QUESTIONS
1097
+					if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1098
+						$system_question_we_want = EEM_Question_Group::system_personal;
1099
+					} else {
1100
+						$system_question_we_want = EEM_Question_Group::system_address;
1101
+					}
1102
+					if (isset($QSG_IDs[$system_question_we_want])) {
1103
+						$QSG_ID = $QSG_IDs[$system_question_we_want];
1104
+					} else {
1105
+						$id_col = EEM_Question_Group::instance()
1106
+													->get_col(array(array('QSG_system' => $system_question_we_want)));
1107
+						if (is_array($id_col)) {
1108
+							$QSG_ID = reset($id_col);
1109
+						} else {
1110
+							//ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1111
+							EE_Log::instance()->log(
1112
+								__FILE__,
1113
+								__FUNCTION__,
1114
+								sprintf(
1115
+									__(
1116
+										'Could not associate question %1$s to a question group because no system question
1117 1117
                                          group existed',
1118
-                                        'event_espresso'
1119
-                                    ),
1120
-                                    $QST_ID),
1121
-                                'error');
1122
-                            continue;
1123
-                        }
1124
-                    }
1125
-                    // add system questions to groups
1126
-                    $wpdb->insert(
1127
-                        \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1128
-                        array(
1129
-                            'QSG_ID'    => $QSG_ID,
1130
-                            'QST_ID'    => $QST_ID,
1131
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1132
-                        ),
1133
-                        array('%d', '%d', '%d')
1134
-                    );
1135
-                }
1136
-            }
1137
-        }
1138
-    }
1139
-
1140
-
1141
-    /**
1142
-     * Makes sure the default payment method (Invoice) is active.
1143
-     * This used to be done automatically as part of constructing the old gateways config
1144
-     *
1145
-     * @throws \EE_Error
1146
-     */
1147
-    public static function insert_default_payment_methods()
1148
-    {
1149
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1150
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1151
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1152
-        } else {
1153
-            EEM_Payment_Method::instance()->verify_button_urls();
1154
-        }
1155
-    }
1156
-
1157
-    /**
1158
-     * insert_default_status_codes
1159
-     *
1160
-     * @access public
1161
-     * @static
1162
-     * @return void
1163
-     */
1164
-    public static function insert_default_status_codes()
1165
-    {
1166
-
1167
-        global $wpdb;
1168
-
1169
-        if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1170
-
1171
-            $table_name = EEM_Status::instance()->table();
1172
-
1173
-            $SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1174
-            $wpdb->query($SQL);
1175
-
1176
-            $SQL = "INSERT INTO $table_name
1118
+										'event_espresso'
1119
+									),
1120
+									$QST_ID),
1121
+								'error');
1122
+							continue;
1123
+						}
1124
+					}
1125
+					// add system questions to groups
1126
+					$wpdb->insert(
1127
+						\EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1128
+						array(
1129
+							'QSG_ID'    => $QSG_ID,
1130
+							'QST_ID'    => $QST_ID,
1131
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1132
+						),
1133
+						array('%d', '%d', '%d')
1134
+					);
1135
+				}
1136
+			}
1137
+		}
1138
+	}
1139
+
1140
+
1141
+	/**
1142
+	 * Makes sure the default payment method (Invoice) is active.
1143
+	 * This used to be done automatically as part of constructing the old gateways config
1144
+	 *
1145
+	 * @throws \EE_Error
1146
+	 */
1147
+	public static function insert_default_payment_methods()
1148
+	{
1149
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1150
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1151
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1152
+		} else {
1153
+			EEM_Payment_Method::instance()->verify_button_urls();
1154
+		}
1155
+	}
1156
+
1157
+	/**
1158
+	 * insert_default_status_codes
1159
+	 *
1160
+	 * @access public
1161
+	 * @static
1162
+	 * @return void
1163
+	 */
1164
+	public static function insert_default_status_codes()
1165
+	{
1166
+
1167
+		global $wpdb;
1168
+
1169
+		if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1170
+
1171
+			$table_name = EEM_Status::instance()->table();
1172
+
1173
+			$SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1174
+			$wpdb->query($SQL);
1175
+
1176
+			$SQL = "INSERT INTO $table_name
1177 1177
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1178 1178
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1179 1179
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1213,521 +1213,521 @@  discard block
 block discarded – undo
1213 1213
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1214 1214
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1215 1215
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1216
-            $wpdb->query($SQL);
1217
-
1218
-        }
1219
-
1220
-    }
1221
-
1222
-
1223
-    /**
1224
-     * create_upload_directories
1225
-     * Creates folders in the uploads directory to facilitate addons and templates
1226
-     *
1227
-     * @access public
1228
-     * @static
1229
-     * @return boolean success of verifying upload directories exist
1230
-     */
1231
-    public static function create_upload_directories()
1232
-    {
1233
-        // Create the required folders
1234
-        $folders = array(
1235
-            EVENT_ESPRESSO_TEMPLATE_DIR,
1236
-            EVENT_ESPRESSO_GATEWAY_DIR,
1237
-            EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1238
-            EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1239
-            EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1240
-        );
1241
-        foreach ($folders as $folder) {
1242
-            try {
1243
-                EEH_File::ensure_folder_exists_and_is_writable($folder);
1244
-                @ chmod($folder, 0755);
1245
-            } catch (EE_Error $e) {
1246
-                EE_Error::add_error(
1247
-                    sprintf(
1248
-                        __('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1249
-                        $folder,
1250
-                        '<br />' . $e->getMessage()
1251
-                    ),
1252
-                    __FILE__, __FUNCTION__, __LINE__
1253
-                );
1254
-                //indicate we'll need to fix this later
1255
-                update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1256
-                return false;
1257
-            }
1258
-        }
1259
-        //just add the .htaccess file to the logs directory to begin with. Even if logging
1260
-        //is disabled, there might be activation errors recorded in there
1261
-        EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1262
-        //remember EE's folders are all good
1263
-        delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1264
-        return true;
1265
-    }
1266
-
1267
-    /**
1268
-     * Whether the upload directories need to be fixed or not.
1269
-     * If EE is installed but filesystem access isn't initially available,
1270
-     * we need to get the user's filesystem credentials and THEN create them,
1271
-     * so there might be period of time when EE is installed but its
1272
-     * upload directories aren't available. This indicates such a state
1273
-     *
1274
-     * @return boolean
1275
-     */
1276
-    public static function upload_directories_incomplete()
1277
-    {
1278
-        return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1279
-    }
1280
-
1281
-
1282
-    /**
1283
-     * generate_default_message_templates
1284
-     *
1285
-     * @static
1286
-     * @throws EE_Error
1287
-     * @return bool     true means new templates were created.
1288
-     *                  false means no templates were created.
1289
-     *                  This is NOT an error flag. To check for errors you will want
1290
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1291
-     */
1292
-    public static function generate_default_message_templates()
1293
-    {
1294
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1295
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1296
-        /*
1216
+			$wpdb->query($SQL);
1217
+
1218
+		}
1219
+
1220
+	}
1221
+
1222
+
1223
+	/**
1224
+	 * create_upload_directories
1225
+	 * Creates folders in the uploads directory to facilitate addons and templates
1226
+	 *
1227
+	 * @access public
1228
+	 * @static
1229
+	 * @return boolean success of verifying upload directories exist
1230
+	 */
1231
+	public static function create_upload_directories()
1232
+	{
1233
+		// Create the required folders
1234
+		$folders = array(
1235
+			EVENT_ESPRESSO_TEMPLATE_DIR,
1236
+			EVENT_ESPRESSO_GATEWAY_DIR,
1237
+			EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1238
+			EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1239
+			EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1240
+		);
1241
+		foreach ($folders as $folder) {
1242
+			try {
1243
+				EEH_File::ensure_folder_exists_and_is_writable($folder);
1244
+				@ chmod($folder, 0755);
1245
+			} catch (EE_Error $e) {
1246
+				EE_Error::add_error(
1247
+					sprintf(
1248
+						__('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1249
+						$folder,
1250
+						'<br />' . $e->getMessage()
1251
+					),
1252
+					__FILE__, __FUNCTION__, __LINE__
1253
+				);
1254
+				//indicate we'll need to fix this later
1255
+				update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1256
+				return false;
1257
+			}
1258
+		}
1259
+		//just add the .htaccess file to the logs directory to begin with. Even if logging
1260
+		//is disabled, there might be activation errors recorded in there
1261
+		EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1262
+		//remember EE's folders are all good
1263
+		delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1264
+		return true;
1265
+	}
1266
+
1267
+	/**
1268
+	 * Whether the upload directories need to be fixed or not.
1269
+	 * If EE is installed but filesystem access isn't initially available,
1270
+	 * we need to get the user's filesystem credentials and THEN create them,
1271
+	 * so there might be period of time when EE is installed but its
1272
+	 * upload directories aren't available. This indicates such a state
1273
+	 *
1274
+	 * @return boolean
1275
+	 */
1276
+	public static function upload_directories_incomplete()
1277
+	{
1278
+		return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1279
+	}
1280
+
1281
+
1282
+	/**
1283
+	 * generate_default_message_templates
1284
+	 *
1285
+	 * @static
1286
+	 * @throws EE_Error
1287
+	 * @return bool     true means new templates were created.
1288
+	 *                  false means no templates were created.
1289
+	 *                  This is NOT an error flag. To check for errors you will want
1290
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1291
+	 */
1292
+	public static function generate_default_message_templates()
1293
+	{
1294
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1295
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1296
+		/*
1297 1297
          * This first method is taking care of ensuring any default messengers
1298 1298
          * that should be made active and have templates generated are done.
1299 1299
          */
1300
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1301
-            $message_resource_manager
1302
-        );
1303
-        /**
1304
-         * This method is verifying there are no NEW default message types
1305
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1306
-         */
1307
-        $new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1308
-            $message_resource_manager
1309
-        );
1310
-        //after all is done, let's persist these changes to the db.
1311
-        $message_resource_manager->update_has_activated_messengers_option();
1312
-        $message_resource_manager->update_active_messengers_option();
1313
-        // will return true if either of these are true.  Otherwise will return false.
1314
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1315
-    }
1316
-
1317
-
1318
-
1319
-    /**
1320
-     * @param \EE_Message_Resource_Manager $message_resource_manager
1321
-     * @return array|bool
1322
-     * @throws \EE_Error
1323
-     */
1324
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1325
-        EE_Message_Resource_Manager $message_resource_manager
1326
-    ) {
1327
-        /** @type EE_messenger[] $active_messengers */
1328
-        $active_messengers = $message_resource_manager->active_messengers();
1329
-        $installed_message_types = $message_resource_manager->installed_message_types();
1330
-        $templates_created = false;
1331
-        foreach ($active_messengers as $active_messenger) {
1332
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1333
-            $default_message_type_names_to_activate = array();
1334
-            // looping through each default message type reported by the messenger
1335
-            // and setup the actual message types to activate.
1336
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1337
-                // if already active or has already been activated before we skip
1338
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1339
-                // we also skip if the message type is not installed.
1340
-                if (
1341
-                    $message_resource_manager->has_message_type_been_activated_for_messenger(
1342
-                        $default_message_type_name_for_messenger,
1343
-                        $active_messenger->name
1344
-                    )
1345
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1346
-                        $active_messenger->name,
1347
-                        $default_message_type_name_for_messenger
1348
-                    )
1349
-                    || ! isset($installed_message_types[$default_message_type_name_for_messenger])
1350
-                ) {
1351
-                    continue;
1352
-                }
1353
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1354
-            }
1355
-            //let's activate!
1356
-            $message_resource_manager->ensure_message_types_are_active(
1357
-                $default_message_type_names_to_activate,
1358
-                $active_messenger->name,
1359
-                false
1360
-            );
1361
-            //activate the templates for these message types
1362
-            if ( ! empty($default_message_type_names_to_activate)) {
1363
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1364
-                    $active_messenger->name,
1365
-                    $default_message_type_names_for_messenger,
1366
-                    '',
1367
-                    true
1368
-                );
1369
-            }
1370
-        }
1371
-        return $templates_created;
1372
-    }
1373
-
1374
-
1375
-
1376
-    /**
1377
-     * This will activate and generate default messengers and default message types for those messengers.
1378
-     *
1379
-     * @param EE_message_Resource_Manager $message_resource_manager
1380
-     * @return array|bool  True means there were default messengers and message type templates generated.
1381
-     *                     False means that there were no templates generated
1382
-     *                     (which could simply mean there are no default message types for a messenger).
1383
-     * @throws EE_Error
1384
-     */
1385
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1386
-        EE_Message_Resource_Manager $message_resource_manager
1387
-    ) {
1388
-        /** @type EE_messenger[] $messengers_to_generate */
1389
-        $messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1390
-        $installed_message_types = $message_resource_manager->installed_message_types();
1391
-        $templates_generated = false;
1392
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1393
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1394
-            //verify the default message types match an installed message type.
1395
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1396
-                if (
1397
-                    ! isset($installed_message_types[$name])
1398
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1399
-                        $name,
1400
-                        $messenger_to_generate->name
1401
-                    )
1402
-                ) {
1403
-                    unset($default_message_type_names_for_messenger[$key]);
1404
-                }
1405
-            }
1406
-            // in previous iterations, the active_messengers option in the db
1407
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1408
-            // This comment is left here just in case we discover that we _do_ need to update before
1409
-            // passing off to create templates (after the refactor is done).
1410
-            // @todo remove this comment when determined not necessary.
1411
-            $message_resource_manager->activate_messenger(
1412
-                $messenger_to_generate->name,
1413
-                $default_message_type_names_for_messenger,
1414
-                false
1415
-            );
1416
-            //create any templates needing created (or will reactivate templates already generated as necessary).
1417
-            if ( ! empty($default_message_type_names_for_messenger)) {
1418
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1419
-                    $messenger_to_generate->name,
1420
-                    $default_message_type_names_for_messenger,
1421
-                    '',
1422
-                    true
1423
-                );
1424
-            }
1425
-        }
1426
-        return $templates_generated;
1427
-    }
1428
-
1429
-
1430
-    /**
1431
-     * This returns the default messengers to generate templates for on activation of EE.
1432
-     * It considers:
1433
-     * - whether a messenger is already active in the db.
1434
-     * - whether a messenger has been made active at any time in the past.
1435
-     *
1436
-     * @static
1437
-     * @param  EE_Message_Resource_Manager $message_resource_manager
1438
-     * @return EE_messenger[]
1439
-     */
1440
-    protected static function _get_default_messengers_to_generate_on_activation(
1441
-        EE_Message_Resource_Manager $message_resource_manager
1442
-    ) {
1443
-        $active_messengers    = $message_resource_manager->active_messengers();
1444
-        $installed_messengers = $message_resource_manager->installed_messengers();
1445
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1446
-
1447
-        $messengers_to_generate = array();
1448
-        foreach ($installed_messengers as $installed_messenger) {
1449
-            //if installed messenger is a messenger that should be activated on install
1450
-            //and is not already active
1451
-            //and has never been activated
1452
-            if (
1453
-                ! $installed_messenger->activate_on_install
1454
-                || isset($active_messengers[$installed_messenger->name])
1455
-                || isset($has_activated[$installed_messenger->name])
1456
-            ) {
1457
-                continue;
1458
-            }
1459
-            $messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1460
-        }
1461
-        return $messengers_to_generate;
1462
-    }
1463
-
1464
-
1465
-    /**
1466
-     * This simply validates active message types to ensure they actually match installed
1467
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1468
-     * rows are set inactive.
1469
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1470
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1471
-     * are still handled in here.
1472
-     *
1473
-     * @since 4.3.1
1474
-     * @return void
1475
-     */
1476
-    public static function validate_messages_system()
1477
-    {
1478
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1479
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1480
-        $message_resource_manager->validate_active_message_types_are_installed();
1481
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1482
-    }
1483
-
1484
-
1485
-    /**
1486
-     * create_no_ticket_prices_array
1487
-     *
1488
-     * @access public
1489
-     * @static
1490
-     * @return void
1491
-     */
1492
-    public static function create_no_ticket_prices_array()
1493
-    {
1494
-        // this creates an array for tracking events that have no active ticket prices created
1495
-        // this allows us to warn admins of the situation so that it can be corrected
1496
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1497
-        if (! $espresso_no_ticket_prices) {
1498
-            add_option('ee_no_ticket_prices', array(), '', false);
1499
-        }
1500
-    }
1501
-
1502
-
1503
-    /**
1504
-     * plugin_deactivation
1505
-     *
1506
-     * @access public
1507
-     * @static
1508
-     * @return void
1509
-     */
1510
-    public static function plugin_deactivation()
1511
-    {
1512
-    }
1513
-
1514
-
1515
-    /**
1516
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1517
-     * (like post meta or term relations)
1518
-     *
1519
-     * @global wpdb $wpdb
1520
-     * @throws \EE_Error
1521
-     */
1522
-    public static function delete_all_espresso_cpt_data()
1523
-    {
1524
-        global $wpdb;
1525
-        //get all the CPT post_types
1526
-        $ee_post_types = array();
1527
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1528
-            if (method_exists($model_name, 'instance')) {
1529
-                $model_obj = call_user_func(array($model_name, 'instance'));
1530
-                if ($model_obj instanceof EEM_CPT_Base) {
1531
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1532
-                }
1533
-            }
1534
-        }
1535
-        //get all our CPTs
1536
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1537
-        $cpt_ids = $wpdb->get_col($query);
1538
-        //delete each post meta and term relations too
1539
-        foreach ($cpt_ids as $post_id) {
1540
-            wp_delete_post($post_id, true);
1541
-        }
1542
-    }
1543
-
1544
-    /**
1545
-     * Deletes all EE custom tables
1546
-     *
1547
-     * @return array
1548
-     */
1549
-    public static function drop_espresso_tables()
1550
-    {
1551
-        $tables = array();
1552
-        // load registry
1553
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1554
-            if (method_exists($model_name, 'instance')) {
1555
-                $model_obj = call_user_func(array($model_name, 'instance'));
1556
-                if ($model_obj instanceof EEM_Base) {
1557
-                    foreach ($model_obj->get_tables() as $table) {
1558
-                        if (strpos($table->get_table_name(), 'esp_')
1559
-                            &&
1560
-                            (
1561
-                                is_main_site()//main site? nuke them all
1562
-                                || ! $table->is_global()//not main site,but not global either. nuke it
1563
-                            )
1564
-                        ) {
1565
-                            $tables[$table->get_table_name()] = $table->get_table_name();
1566
-                        }
1567
-                    }
1568
-                }
1569
-            }
1570
-        }
1571
-
1572
-        //there are some tables whose models were removed.
1573
-        //they should be removed when removing all EE core's data
1574
-        $tables_without_models = array(
1575
-            'esp_promotion',
1576
-            'esp_promotion_applied',
1577
-            'esp_promotion_object',
1578
-            'esp_promotion_rule',
1579
-            'esp_rule',
1580
-        );
1581
-        foreach ($tables_without_models as $table) {
1582
-            $tables[$table] = $table;
1583
-        }
1584
-        return \EEH_Activation::getTableManager()->dropTables($tables);
1585
-    }
1586
-
1587
-
1588
-
1589
-    /**
1590
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1591
-     * each table name provided has a wpdb prefix attached, and that it exists.
1592
-     * Returns the list actually deleted
1593
-     *
1594
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1595
-     * @global WPDB $wpdb
1596
-     * @param array $table_names
1597
-     * @return array of table names which we deleted
1598
-     */
1599
-    public static function drop_tables($table_names)
1600
-    {
1601
-        return \EEH_Activation::getTableManager()->dropTables($table_names);
1602
-    }
1603
-
1604
-
1605
-
1606
-    /**
1607
-     * plugin_uninstall
1608
-     *
1609
-     * @access public
1610
-     * @static
1611
-     * @param bool $remove_all
1612
-     * @return void
1613
-     */
1614
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1615
-    {
1616
-        global $wpdb;
1617
-        self::drop_espresso_tables();
1618
-        $wp_options_to_delete = array(
1619
-            'ee_no_ticket_prices'                => true,
1620
-            'ee_active_messengers'               => true,
1621
-            'ee_has_activated_messenger'         => true,
1622
-            'ee_flush_rewrite_rules'             => true,
1623
-            'ee_config'                          => false,
1624
-            'ee_data_migration_current_db_state' => true,
1625
-            'ee_data_migration_mapping_'         => false,
1626
-            'ee_data_migration_script_'          => false,
1627
-            'ee_data_migrations'                 => true,
1628
-            'ee_dms_map'                         => false,
1629
-            'ee_notices'                         => true,
1630
-            'lang_file_check_'                   => false,
1631
-            'ee_maintenance_mode'                => true,
1632
-            'ee_ueip_optin'                      => true,
1633
-            'ee_ueip_has_notified'               => true,
1634
-            'ee_plugin_activation_errors'        => true,
1635
-            'ee_id_mapping_from'                 => false,
1636
-            'espresso_persistent_admin_notices'  => true,
1637
-            'ee_encryption_key'                  => true,
1638
-            'pue_force_upgrade_'                 => false,
1639
-            'pue_json_error_'                    => false,
1640
-            'pue_install_key_'                   => false,
1641
-            'pue_verification_error_'            => false,
1642
-            'pu_dismissed_upgrade_'              => false,
1643
-            'external_updates-'                  => false,
1644
-            'ee_extra_data'                      => true,
1645
-            'ee_ssn_'                            => false,
1646
-            'ee_rss_'                            => false,
1647
-            'ee_rte_n_tx_'                       => false,
1648
-            'ee_pers_admin_notices'              => true,
1649
-            'ee_job_parameters_'                 => false,
1650
-            'ee_upload_directories_incomplete'   => true,
1651
-            'ee_verified_db_collations'          => true,
1652
-        );
1653
-        if (is_main_site()) {
1654
-            $wp_options_to_delete['ee_network_config'] = true;
1655
-        }
1656
-        $undeleted_options = array();
1657
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1658
-            if ($no_wildcard) {
1659
-                if ( ! delete_option($option_name)) {
1660
-                    $undeleted_options[] = $option_name;
1661
-                }
1662
-            } else {
1663
-                $option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1664
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1665
-                    if ( ! delete_option($option_name_from_wildcard)) {
1666
-                        $undeleted_options[] = $option_name_from_wildcard;
1667
-                    }
1668
-                }
1669
-            }
1670
-        }
1671
-        //also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1672
-        remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1673
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1674
-            $db_update_sans_ee4 = array();
1675
-            foreach ($espresso_db_update as $version => $times_activated) {
1676
-                if ((string)$version[0] === '3') {//if its NON EE4
1677
-                    $db_update_sans_ee4[$version] = $times_activated;
1678
-                }
1679
-            }
1680
-            update_option('espresso_db_update', $db_update_sans_ee4);
1681
-        }
1682
-        $errors = '';
1683
-        if ( ! empty($undeleted_options)) {
1684
-            $errors .= sprintf(
1685
-                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1686
-                '<br/>',
1687
-                implode(',<br/>', $undeleted_options)
1688
-            );
1689
-        }
1690
-        if ( ! empty($errors)) {
1691
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1692
-        }
1693
-    }
1694
-
1695
-    /**
1696
-     * Gets the mysql error code from the last used query by wpdb
1697
-     *
1698
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1699
-     */
1700
-    public static function last_wpdb_error_code()
1701
-    {
1702
-        global $wpdb;
1703
-        if ($wpdb->use_mysqli) {
1704
-            return mysqli_errno($wpdb->dbh);
1705
-        } else {
1706
-            return mysql_errno($wpdb->dbh);
1707
-        }
1708
-    }
1709
-
1710
-    /**
1711
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1712
-     *
1713
-     * @global wpdb  $wpdb
1714
-     * @deprecated instead use TableAnalysis::tableExists()
1715
-     * @param string $table_name with or without $wpdb->prefix
1716
-     * @return boolean
1717
-     */
1718
-    public static function table_exists($table_name)
1719
-    {
1720
-        return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1721
-    }
1722
-
1723
-    /**
1724
-     * Resets the cache on EEH_Activation
1725
-     */
1726
-    public static function reset()
1727
-    {
1728
-        self::$_default_creator_id                             = null;
1729
-        self::$_initialized_db_content_already_in_this_request = false;
1730
-    }
1300
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1301
+			$message_resource_manager
1302
+		);
1303
+		/**
1304
+		 * This method is verifying there are no NEW default message types
1305
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1306
+		 */
1307
+		$new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1308
+			$message_resource_manager
1309
+		);
1310
+		//after all is done, let's persist these changes to the db.
1311
+		$message_resource_manager->update_has_activated_messengers_option();
1312
+		$message_resource_manager->update_active_messengers_option();
1313
+		// will return true if either of these are true.  Otherwise will return false.
1314
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1315
+	}
1316
+
1317
+
1318
+
1319
+	/**
1320
+	 * @param \EE_Message_Resource_Manager $message_resource_manager
1321
+	 * @return array|bool
1322
+	 * @throws \EE_Error
1323
+	 */
1324
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1325
+		EE_Message_Resource_Manager $message_resource_manager
1326
+	) {
1327
+		/** @type EE_messenger[] $active_messengers */
1328
+		$active_messengers = $message_resource_manager->active_messengers();
1329
+		$installed_message_types = $message_resource_manager->installed_message_types();
1330
+		$templates_created = false;
1331
+		foreach ($active_messengers as $active_messenger) {
1332
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1333
+			$default_message_type_names_to_activate = array();
1334
+			// looping through each default message type reported by the messenger
1335
+			// and setup the actual message types to activate.
1336
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1337
+				// if already active or has already been activated before we skip
1338
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1339
+				// we also skip if the message type is not installed.
1340
+				if (
1341
+					$message_resource_manager->has_message_type_been_activated_for_messenger(
1342
+						$default_message_type_name_for_messenger,
1343
+						$active_messenger->name
1344
+					)
1345
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1346
+						$active_messenger->name,
1347
+						$default_message_type_name_for_messenger
1348
+					)
1349
+					|| ! isset($installed_message_types[$default_message_type_name_for_messenger])
1350
+				) {
1351
+					continue;
1352
+				}
1353
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1354
+			}
1355
+			//let's activate!
1356
+			$message_resource_manager->ensure_message_types_are_active(
1357
+				$default_message_type_names_to_activate,
1358
+				$active_messenger->name,
1359
+				false
1360
+			);
1361
+			//activate the templates for these message types
1362
+			if ( ! empty($default_message_type_names_to_activate)) {
1363
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1364
+					$active_messenger->name,
1365
+					$default_message_type_names_for_messenger,
1366
+					'',
1367
+					true
1368
+				);
1369
+			}
1370
+		}
1371
+		return $templates_created;
1372
+	}
1373
+
1374
+
1375
+
1376
+	/**
1377
+	 * This will activate and generate default messengers and default message types for those messengers.
1378
+	 *
1379
+	 * @param EE_message_Resource_Manager $message_resource_manager
1380
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1381
+	 *                     False means that there were no templates generated
1382
+	 *                     (which could simply mean there are no default message types for a messenger).
1383
+	 * @throws EE_Error
1384
+	 */
1385
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1386
+		EE_Message_Resource_Manager $message_resource_manager
1387
+	) {
1388
+		/** @type EE_messenger[] $messengers_to_generate */
1389
+		$messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1390
+		$installed_message_types = $message_resource_manager->installed_message_types();
1391
+		$templates_generated = false;
1392
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1393
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1394
+			//verify the default message types match an installed message type.
1395
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1396
+				if (
1397
+					! isset($installed_message_types[$name])
1398
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1399
+						$name,
1400
+						$messenger_to_generate->name
1401
+					)
1402
+				) {
1403
+					unset($default_message_type_names_for_messenger[$key]);
1404
+				}
1405
+			}
1406
+			// in previous iterations, the active_messengers option in the db
1407
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1408
+			// This comment is left here just in case we discover that we _do_ need to update before
1409
+			// passing off to create templates (after the refactor is done).
1410
+			// @todo remove this comment when determined not necessary.
1411
+			$message_resource_manager->activate_messenger(
1412
+				$messenger_to_generate->name,
1413
+				$default_message_type_names_for_messenger,
1414
+				false
1415
+			);
1416
+			//create any templates needing created (or will reactivate templates already generated as necessary).
1417
+			if ( ! empty($default_message_type_names_for_messenger)) {
1418
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1419
+					$messenger_to_generate->name,
1420
+					$default_message_type_names_for_messenger,
1421
+					'',
1422
+					true
1423
+				);
1424
+			}
1425
+		}
1426
+		return $templates_generated;
1427
+	}
1428
+
1429
+
1430
+	/**
1431
+	 * This returns the default messengers to generate templates for on activation of EE.
1432
+	 * It considers:
1433
+	 * - whether a messenger is already active in the db.
1434
+	 * - whether a messenger has been made active at any time in the past.
1435
+	 *
1436
+	 * @static
1437
+	 * @param  EE_Message_Resource_Manager $message_resource_manager
1438
+	 * @return EE_messenger[]
1439
+	 */
1440
+	protected static function _get_default_messengers_to_generate_on_activation(
1441
+		EE_Message_Resource_Manager $message_resource_manager
1442
+	) {
1443
+		$active_messengers    = $message_resource_manager->active_messengers();
1444
+		$installed_messengers = $message_resource_manager->installed_messengers();
1445
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1446
+
1447
+		$messengers_to_generate = array();
1448
+		foreach ($installed_messengers as $installed_messenger) {
1449
+			//if installed messenger is a messenger that should be activated on install
1450
+			//and is not already active
1451
+			//and has never been activated
1452
+			if (
1453
+				! $installed_messenger->activate_on_install
1454
+				|| isset($active_messengers[$installed_messenger->name])
1455
+				|| isset($has_activated[$installed_messenger->name])
1456
+			) {
1457
+				continue;
1458
+			}
1459
+			$messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1460
+		}
1461
+		return $messengers_to_generate;
1462
+	}
1463
+
1464
+
1465
+	/**
1466
+	 * This simply validates active message types to ensure they actually match installed
1467
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1468
+	 * rows are set inactive.
1469
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1470
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1471
+	 * are still handled in here.
1472
+	 *
1473
+	 * @since 4.3.1
1474
+	 * @return void
1475
+	 */
1476
+	public static function validate_messages_system()
1477
+	{
1478
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1479
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1480
+		$message_resource_manager->validate_active_message_types_are_installed();
1481
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1482
+	}
1483
+
1484
+
1485
+	/**
1486
+	 * create_no_ticket_prices_array
1487
+	 *
1488
+	 * @access public
1489
+	 * @static
1490
+	 * @return void
1491
+	 */
1492
+	public static function create_no_ticket_prices_array()
1493
+	{
1494
+		// this creates an array for tracking events that have no active ticket prices created
1495
+		// this allows us to warn admins of the situation so that it can be corrected
1496
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1497
+		if (! $espresso_no_ticket_prices) {
1498
+			add_option('ee_no_ticket_prices', array(), '', false);
1499
+		}
1500
+	}
1501
+
1502
+
1503
+	/**
1504
+	 * plugin_deactivation
1505
+	 *
1506
+	 * @access public
1507
+	 * @static
1508
+	 * @return void
1509
+	 */
1510
+	public static function plugin_deactivation()
1511
+	{
1512
+	}
1513
+
1514
+
1515
+	/**
1516
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1517
+	 * (like post meta or term relations)
1518
+	 *
1519
+	 * @global wpdb $wpdb
1520
+	 * @throws \EE_Error
1521
+	 */
1522
+	public static function delete_all_espresso_cpt_data()
1523
+	{
1524
+		global $wpdb;
1525
+		//get all the CPT post_types
1526
+		$ee_post_types = array();
1527
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1528
+			if (method_exists($model_name, 'instance')) {
1529
+				$model_obj = call_user_func(array($model_name, 'instance'));
1530
+				if ($model_obj instanceof EEM_CPT_Base) {
1531
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1532
+				}
1533
+			}
1534
+		}
1535
+		//get all our CPTs
1536
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1537
+		$cpt_ids = $wpdb->get_col($query);
1538
+		//delete each post meta and term relations too
1539
+		foreach ($cpt_ids as $post_id) {
1540
+			wp_delete_post($post_id, true);
1541
+		}
1542
+	}
1543
+
1544
+	/**
1545
+	 * Deletes all EE custom tables
1546
+	 *
1547
+	 * @return array
1548
+	 */
1549
+	public static function drop_espresso_tables()
1550
+	{
1551
+		$tables = array();
1552
+		// load registry
1553
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1554
+			if (method_exists($model_name, 'instance')) {
1555
+				$model_obj = call_user_func(array($model_name, 'instance'));
1556
+				if ($model_obj instanceof EEM_Base) {
1557
+					foreach ($model_obj->get_tables() as $table) {
1558
+						if (strpos($table->get_table_name(), 'esp_')
1559
+							&&
1560
+							(
1561
+								is_main_site()//main site? nuke them all
1562
+								|| ! $table->is_global()//not main site,but not global either. nuke it
1563
+							)
1564
+						) {
1565
+							$tables[$table->get_table_name()] = $table->get_table_name();
1566
+						}
1567
+					}
1568
+				}
1569
+			}
1570
+		}
1571
+
1572
+		//there are some tables whose models were removed.
1573
+		//they should be removed when removing all EE core's data
1574
+		$tables_without_models = array(
1575
+			'esp_promotion',
1576
+			'esp_promotion_applied',
1577
+			'esp_promotion_object',
1578
+			'esp_promotion_rule',
1579
+			'esp_rule',
1580
+		);
1581
+		foreach ($tables_without_models as $table) {
1582
+			$tables[$table] = $table;
1583
+		}
1584
+		return \EEH_Activation::getTableManager()->dropTables($tables);
1585
+	}
1586
+
1587
+
1588
+
1589
+	/**
1590
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1591
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1592
+	 * Returns the list actually deleted
1593
+	 *
1594
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1595
+	 * @global WPDB $wpdb
1596
+	 * @param array $table_names
1597
+	 * @return array of table names which we deleted
1598
+	 */
1599
+	public static function drop_tables($table_names)
1600
+	{
1601
+		return \EEH_Activation::getTableManager()->dropTables($table_names);
1602
+	}
1603
+
1604
+
1605
+
1606
+	/**
1607
+	 * plugin_uninstall
1608
+	 *
1609
+	 * @access public
1610
+	 * @static
1611
+	 * @param bool $remove_all
1612
+	 * @return void
1613
+	 */
1614
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1615
+	{
1616
+		global $wpdb;
1617
+		self::drop_espresso_tables();
1618
+		$wp_options_to_delete = array(
1619
+			'ee_no_ticket_prices'                => true,
1620
+			'ee_active_messengers'               => true,
1621
+			'ee_has_activated_messenger'         => true,
1622
+			'ee_flush_rewrite_rules'             => true,
1623
+			'ee_config'                          => false,
1624
+			'ee_data_migration_current_db_state' => true,
1625
+			'ee_data_migration_mapping_'         => false,
1626
+			'ee_data_migration_script_'          => false,
1627
+			'ee_data_migrations'                 => true,
1628
+			'ee_dms_map'                         => false,
1629
+			'ee_notices'                         => true,
1630
+			'lang_file_check_'                   => false,
1631
+			'ee_maintenance_mode'                => true,
1632
+			'ee_ueip_optin'                      => true,
1633
+			'ee_ueip_has_notified'               => true,
1634
+			'ee_plugin_activation_errors'        => true,
1635
+			'ee_id_mapping_from'                 => false,
1636
+			'espresso_persistent_admin_notices'  => true,
1637
+			'ee_encryption_key'                  => true,
1638
+			'pue_force_upgrade_'                 => false,
1639
+			'pue_json_error_'                    => false,
1640
+			'pue_install_key_'                   => false,
1641
+			'pue_verification_error_'            => false,
1642
+			'pu_dismissed_upgrade_'              => false,
1643
+			'external_updates-'                  => false,
1644
+			'ee_extra_data'                      => true,
1645
+			'ee_ssn_'                            => false,
1646
+			'ee_rss_'                            => false,
1647
+			'ee_rte_n_tx_'                       => false,
1648
+			'ee_pers_admin_notices'              => true,
1649
+			'ee_job_parameters_'                 => false,
1650
+			'ee_upload_directories_incomplete'   => true,
1651
+			'ee_verified_db_collations'          => true,
1652
+		);
1653
+		if (is_main_site()) {
1654
+			$wp_options_to_delete['ee_network_config'] = true;
1655
+		}
1656
+		$undeleted_options = array();
1657
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1658
+			if ($no_wildcard) {
1659
+				if ( ! delete_option($option_name)) {
1660
+					$undeleted_options[] = $option_name;
1661
+				}
1662
+			} else {
1663
+				$option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1664
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1665
+					if ( ! delete_option($option_name_from_wildcard)) {
1666
+						$undeleted_options[] = $option_name_from_wildcard;
1667
+					}
1668
+				}
1669
+			}
1670
+		}
1671
+		//also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1672
+		remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1673
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1674
+			$db_update_sans_ee4 = array();
1675
+			foreach ($espresso_db_update as $version => $times_activated) {
1676
+				if ((string)$version[0] === '3') {//if its NON EE4
1677
+					$db_update_sans_ee4[$version] = $times_activated;
1678
+				}
1679
+			}
1680
+			update_option('espresso_db_update', $db_update_sans_ee4);
1681
+		}
1682
+		$errors = '';
1683
+		if ( ! empty($undeleted_options)) {
1684
+			$errors .= sprintf(
1685
+				__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1686
+				'<br/>',
1687
+				implode(',<br/>', $undeleted_options)
1688
+			);
1689
+		}
1690
+		if ( ! empty($errors)) {
1691
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1692
+		}
1693
+	}
1694
+
1695
+	/**
1696
+	 * Gets the mysql error code from the last used query by wpdb
1697
+	 *
1698
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1699
+	 */
1700
+	public static function last_wpdb_error_code()
1701
+	{
1702
+		global $wpdb;
1703
+		if ($wpdb->use_mysqli) {
1704
+			return mysqli_errno($wpdb->dbh);
1705
+		} else {
1706
+			return mysql_errno($wpdb->dbh);
1707
+		}
1708
+	}
1709
+
1710
+	/**
1711
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1712
+	 *
1713
+	 * @global wpdb  $wpdb
1714
+	 * @deprecated instead use TableAnalysis::tableExists()
1715
+	 * @param string $table_name with or without $wpdb->prefix
1716
+	 * @return boolean
1717
+	 */
1718
+	public static function table_exists($table_name)
1719
+	{
1720
+		return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1721
+	}
1722
+
1723
+	/**
1724
+	 * Resets the cache on EEH_Activation
1725
+	 */
1726
+	public static function reset()
1727
+	{
1728
+		self::$_default_creator_id                             = null;
1729
+		self::$_initialized_db_content_already_in_this_request = false;
1730
+	}
1731 1731
 }
1732 1732
 // End of file EEH_Activation.helper.php
1733 1733
 // Location: /helpers/EEH_Activation.core.php
Please login to merge, or discard this patch.