Completed
Branch FET-8209-allow-multiple-carts (f5b2f0)
by
unknown
108:40 queued 97:50
created
maintenance/templates/ee_confirm_migration_crash_report_sent.template.php 1 patch
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -5,39 +5,39 @@  discard block
 block discarded – undo
5 5
 /** @type string $reset_db_action_url */
6 6
 /** @type EE_Data_Migration_Script_Base $most_recent_migration */
7 7
 ?>
8
-<?php if ( $success ) { ?>
9
-	<h1><?php _e( "Database Update Crash Report Sent", "event_espresso" ); ?></h1>
10
-	<p><?php _e( "A crash report email was sent to Event Espresso. You should hear back from us soon.", "event_espresso" ); ?></p>
8
+<?php if ($success) { ?>
9
+	<h1><?php _e("Database Update Crash Report Sent", "event_espresso"); ?></h1>
10
+	<p><?php _e("A crash report email was sent to Event Espresso. You should hear back from us soon.", "event_espresso"); ?></p>
11 11
 <?php } else {//didn't send email properly ?>
12
-	<h1><?php _e( "Migration Report not sent", "event_espresso" ); ?></h1>
13
-	<p><?php _e( "An error occurred and we were not able to automatically send a report to Event Espresso support.", "event_espresso" ); ?></p>
14
-	<p><?php printf( esc_html__( "Please copy-and-paste the system information below to %s", "event_espresso" ), '<a href="mailto:' . EE_SUPPORT_EMAIL . '">' .EE_SUPPORT_EMAIL . "</a>" ); ?></p>
12
+	<h1><?php _e("Migration Report not sent", "event_espresso"); ?></h1>
13
+	<p><?php _e("An error occurred and we were not able to automatically send a report to Event Espresso support.", "event_espresso"); ?></p>
14
+	<p><?php printf(esc_html__("Please copy-and-paste the system information below to %s", "event_espresso"), '<a href="mailto:'.EE_SUPPORT_EMAIL.'">'.EE_SUPPORT_EMAIL."</a>"); ?></p>
15 15
 	<label>
16
-		<?php _e( "system status info", "event_espresso" ); ?>
17
-		<textarea name="system_status_info" class="system_status_info"><?php print_r( EEM_System_Status::instance()->get_system_stati() ); ?></textarea>
16
+		<?php _e("system status info", "event_espresso"); ?>
17
+		<textarea name="system_status_info" class="system_status_info"><?php print_r(EEM_System_Status::instance()->get_system_stati()); ?></textarea>
18 18
 	</label>
19 19
 <?php } ?>
20 20
 
21 21
 
22
-<h1><?php _e( "What's next?", 'event_espresso' ); ?></h1>
23
-<p><?php _e( "Well, it depends on your situation:", 'event_espresso' ); ?></p>
22
+<h1><?php _e("What's next?", 'event_espresso'); ?></h1>
23
+<p><?php _e("Well, it depends on your situation:", 'event_espresso'); ?></p>
24 24
 <div class='ee-table-wrap'>
25 25
 	<table>
26 26
 		<thead>
27 27
 			<tr>
28
-				<th><?php _e( "Your Situation", 'event_espresso' ); ?></th>
29
-				<th><?php _e( "Suggested Action", 'event_espresso' ); ?></th>
28
+				<th><?php _e("Your Situation", 'event_espresso'); ?></th>
29
+				<th><?php _e("Suggested Action", 'event_espresso'); ?></th>
30 30
 			</tr>
31 31
 		</thead>
32 32
 		<tbody>
33 33
 			<tr>
34
-				<td><p class='big-text'><?php _e( "I want to retry migrating my data", 'event_espresso' ); ?></p></td>
34
+				<td><p class='big-text'><?php _e("I want to retry migrating my data", 'event_espresso'); ?></p></td>
35 35
 				<td>
36 36
 					<p>
37 37
 						<?php
38 38
 						printf(
39
-							esc_html__( 'First, %1$s check the forums %2$s to see if there is a solution before re-attempting the Database Update. Often it helps to deactivate other plugins which may have conflicts; or it may help to add %3$s to your %4$s wp-config.php%5$s (which will make the update run slower, but may resolve any memory exhaustion errors.', 'event_espresso' ),
40
-							"<a href='" . EE_SUPPORT_EMAIL . "' target='_blank'>",
39
+							esc_html__('First, %1$s check the forums %2$s to see if there is a solution before re-attempting the Database Update. Often it helps to deactivate other plugins which may have conflicts; or it may help to add %3$s to your %4$s wp-config.php%5$s (which will make the update run slower, but may resolve any memory exhaustion errors.', 'event_espresso'),
40
+							"<a href='".EE_SUPPORT_EMAIL."' target='_blank'>",
41 41
 							'</a>',
42 42
 							'<pre lang="php">define( EE_MIGRATION_STEP_SIZE, 10 );</pre>',
43 43
 							'<b>',
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
 					<p>
50 50
 						<?php
51 51
 						printf(
52
-							esc_html__( 'To retry updating your data: restore to the backup you made before the update and reactivate EE (and any addons you are using) and re-run the Database Update. If you did not make a database backup and are migrating from EE3: delete your EE4 data (use the %1$s Reset/Delete Data tab above%2$s), and then reactivate EE4, and then re-run the migration and updates. If you did not make a database backup, are only updating from a previous install of EE4, have found a solution to the fatal error you received, and are willing to possibly have some data lost, %3$sattempt to continue migrating%2$s.', 'event_espresso' ),
52
+							esc_html__('To retry updating your data: restore to the backup you made before the update and reactivate EE (and any addons you are using) and re-run the Database Update. If you did not make a database backup and are migrating from EE3: delete your EE4 data (use the %1$s Reset/Delete Data tab above%2$s), and then reactivate EE4, and then re-run the migration and updates. If you did not make a database backup, are only updating from a previous install of EE4, have found a solution to the fatal error you received, and are willing to possibly have some data lost, %3$sattempt to continue migrating%2$s.', 'event_espresso'),
53 53
 							"<a href='$reset_db_page_url'>",
54 54
 							"</a>",
55 55
 							"<a class='button-primary' href='$reattempt_action_url'>"
@@ -60,13 +60,13 @@  discard block
 block discarded – undo
60 60
 			</tr>
61 61
 			<tr>
62 62
 				<td>
63
-					<p class='big-text'><?php _e( "I want to hear from Support before proceeding", 'event_espresso' ); ?></p>
63
+					<p class='big-text'><?php _e("I want to hear from Support before proceeding", 'event_espresso'); ?></p>
64 64
 				</td>
65 65
 				<td>
66 66
 					<?php
67 67
 					printf(
68
-						esc_html__( 'Just make sure you\'ve %1$s checked for a solution in the forums,%2$s and properly contacted Support. We will get back to you as soon as possible', 'event_espresso' ),
69
-						"<a href='" . EE_SUPPORT_EMAIL . "'>",
68
+						esc_html__('Just make sure you\'ve %1$s checked for a solution in the forums,%2$s and properly contacted Support. We will get back to you as soon as possible', 'event_espresso'),
69
+						"<a href='".EE_SUPPORT_EMAIL."'>",
70 70
 						"</a>"
71 71
 					);
72 72
 					?>
@@ -74,12 +74,12 @@  discard block
 block discarded – undo
74 74
 			</tr>
75 75
 			<tr>
76 76
 				<td>
77
-					<p class='big-text'><?php printf( esc_html__( 'I don\'t need my old EE %s data', 'event_espresso' ), $most_recent_migration->slug() ); ?></p>
77
+					<p class='big-text'><?php printf(esc_html__('I don\'t need my old EE %s data', 'event_espresso'), $most_recent_migration->slug()); ?></p>
78 78
 				</td>
79 79
 				<td>
80 80
 					<?php
81 81
 					printf(
82
-						esc_html__( 'If you are ok with losing all the EE %1$s data, you can skip the Database Updates and %2$s use EE4 with only default Data%3$s', 'event_espresso' ),
82
+						esc_html__('If you are ok with losing all the EE %1$s data, you can skip the Database Updates and %2$s use EE4 with only default Data%3$s', 'event_espresso'),
83 83
 						$most_recent_migration->slug(),
84 84
 						"<a id='do-not-migrate' class='do-not-migrate button-primary' href='$reset_db_action_url'>",
85 85
 						"</a>"
@@ -89,20 +89,20 @@  discard block
 block discarded – undo
89 89
 			</tr>
90 90
 			<tr>
91 91
 				<td>
92
-					<p class='big-text'><?php printf( esc_html__( 'I want to go back to my old version of EE %1$s', 'event_espresso' ), $most_recent_migration->slug() ); ?>
92
+					<p class='big-text'><?php printf(esc_html__('I want to go back to my old version of EE %1$s', 'event_espresso'), $most_recent_migration->slug()); ?>
93 93
 				</td>
94 94
 				<td>
95 95
 					<p>
96 96
 					<?php
97 97
 					printf(
98
-						esc_html__( 'Then we suggest you re-activate the old version of EE %3$s and restore your database to the backup you made just before the Database Update . If you didn\'t backup your database and are migrating from EE3, you can also delete your EE4 data (use on the %1$s"Reset/Delete Data" tab above%2$s), and then reactivate EE3 from the plugins page. Note: some of your EE3 shortcodes may have been changed to their EE4 equivalents, so you will need to change them back.', 'event_espresso' ),
98
+						esc_html__('Then we suggest you re-activate the old version of EE %3$s and restore your database to the backup you made just before the Database Update . If you didn\'t backup your database and are migrating from EE3, you can also delete your EE4 data (use on the %1$s"Reset/Delete Data" tab above%2$s), and then reactivate EE3 from the plugins page. Note: some of your EE3 shortcodes may have been changed to their EE4 equivalents, so you will need to change them back.', 'event_espresso'),
99 99
 						"<a href='$reset_db_page_url'>",
100 100
 						"</a>",
101 101
 						$most_recent_migration->slug()
102 102
 					);
103 103
 					?>
104 104
 					</p>
105
-					<p><?php _e( "If you ever decide to re-attempt using EE4, you will again be given the option to migrate your EE3 data or not.", 'event_espresso' ); ?></p>
105
+					<p><?php _e("If you ever decide to re-attempt using EE4, you will again be given the option to migrate your EE3 data or not.", 'event_espresso'); ?></p>
106 106
 				</td>
107 107
 			</tr>
108 108
 
Please login to merge, or discard this patch.
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 (empty ($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 (empty ($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   +36 added lines, -36 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
         );
@@ -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.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -214,16 +214,16 @@  discard block
 block discarded – undo
214 214
      */
215 215
     public static function set_definitions()
216 216
     {
217
-        if(defined('SPCO_BASE_PATH')) {
217
+        if (defined('SPCO_BASE_PATH')) {
218 218
             return;
219 219
         }
220
-        define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS);
221
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
222
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
223
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
224
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
225
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
226
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
220
+        define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS).DS);
221
+        define('SPCO_CSS_URL', plugin_dir_url(__FILE__).'css'.DS);
222
+        define('SPCO_IMG_URL', plugin_dir_url(__FILE__).'img'.DS);
223
+        define('SPCO_JS_URL', plugin_dir_url(__FILE__).'js'.DS);
224
+        define('SPCO_INC_PATH', SPCO_BASE_PATH.'inc'.DS);
225
+        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH.'reg_steps'.DS);
226
+        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH.'templates'.DS);
227 227
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
228 228
         EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
229 229
             __('%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',
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
             '</h4>',
233 233
             '<br />',
234 234
             '<p>',
235
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
235
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
236 236
             '">',
237 237
             '</a>',
238 238
             '</p>'
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
             return;
256 256
         }
257 257
         // filter list of reg_steps
258
-        $reg_steps_to_load = (array)apply_filters(
258
+        $reg_steps_to_load = (array) apply_filters(
259 259
             'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
260 260
             EED_Single_Page_Checkout::get_reg_steps()
261 261
         );
@@ -299,25 +299,25 @@  discard block
 block discarded – undo
299 299
         if (empty($reg_steps)) {
300 300
             $reg_steps = array(
301 301
                 10  => array(
302
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
302
+                    'file_path'  => SPCO_REG_STEPS_PATH.'attendee_information',
303 303
                     'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
304 304
                     'slug'       => 'attendee_information',
305 305
                     'has_hooks'  => false,
306 306
                 ),
307 307
                 20  => array(
308
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
308
+                    'file_path'  => SPCO_REG_STEPS_PATH.'registration_confirmation',
309 309
                     'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
310 310
                     'slug'       => 'registration_confirmation',
311 311
                     'has_hooks'  => false,
312 312
                 ),
313 313
                 30  => array(
314
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
314
+                    'file_path'  => SPCO_REG_STEPS_PATH.'payment_options',
315 315
                     'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
316 316
                     'slug'       => 'payment_options',
317 317
                     'has_hooks'  => true,
318 318
                 ),
319 319
                 999 => array(
320
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
320
+                    'file_path'  => SPCO_REG_STEPS_PATH.'finalize_registration',
321 321
                     'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
322 322
                     'slug'       => 'finalize_registration',
323 323
                     'has_hooks'  => false,
@@ -497,7 +497,7 @@  discard block
 block discarded – undo
497 497
             // DEBUG LOG
498 498
             //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
499 499
             // get reg form
500
-            if( ! $this->_check_form_submission()) {
500
+            if ( ! $this->_check_form_submission()) {
501 501
                 EED_Single_Page_Checkout::$_initialized = true;
502 502
                 return;
503 503
             }
@@ -1062,7 +1062,7 @@  discard block
 block discarded – undo
1062 1062
                     if ( ! $registration instanceof EE_Registration) {
1063 1063
                         throw new InvalidEntityException($registration, 'EE_Registration');
1064 1064
                     }
1065
-                    $registrations[ $registration->ID() ] = $registration;
1065
+                    $registrations[$registration->ID()] = $registration;
1066 1066
                 }
1067 1067
             }
1068 1068
             $registration_processor->fix_reg_final_price_rounding_issue($transaction);
@@ -1296,7 +1296,7 @@  discard block
 block discarded – undo
1296 1296
                         ) {
1297 1297
                             EE_Error::add_success(
1298 1298
                                 $this->checkout->current_step->success_message()
1299
-                                . '<br />' . $this->checkout->next_step->_instructions()
1299
+                                . '<br />'.$this->checkout->next_step->_instructions()
1300 1300
                             );
1301 1301
                         }
1302 1302
                         // pack it up, pack it in...
@@ -1393,7 +1393,7 @@  discard block
 block discarded – undo
1393 1393
             '</h4>',
1394 1394
             '<br />',
1395 1395
             '<p>',
1396
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1396
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
1397 1397
             '">',
1398 1398
             '</a>',
1399 1399
             '</p>'
@@ -1419,12 +1419,12 @@  discard block
 block discarded – undo
1419 1419
     public function enqueue_styles_and_scripts()
1420 1420
     {
1421 1421
         // load css
1422
-        wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1422
+        wp_register_style('single_page_checkout', SPCO_CSS_URL.'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1423 1423
         wp_enqueue_style('single_page_checkout');
1424 1424
         // load JS
1425
-        wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1426
-        wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1427
-        wp_register_script('single_page_checkout', SPCO_JS_URL . 'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true);
1425
+        wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL.'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1426
+        wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL.'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1427
+        wp_register_script('single_page_checkout', SPCO_JS_URL.'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true);
1428 1428
         if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1429 1429
             $this->checkout->registration_form->enqueue_js();
1430 1430
         }
@@ -1441,7 +1441,7 @@  discard block
 block discarded – undo
1441 1441
          * dynamic action hook for enqueueing styles and scripts with spco calls.
1442 1442
          * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1443 1443
          */
1444
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this);
1444
+        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__'.$this->checkout->current_step->slug(), $this);
1445 1445
     }
1446 1446
 
1447 1447
 
@@ -1493,7 +1493,7 @@  discard block
 block discarded – undo
1493 1493
                     'layout_strategy' =>
1494 1494
                         new EE_Template_Layout(
1495 1495
                             array(
1496
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1496
+                                'layout_template_file' => SPCO_TEMPLATES_PATH.'registration_page_wrapper.template.php',
1497 1497
                                 'template_args'        => array(
1498 1498
                                     'empty_cart'              => $empty_cart,
1499 1499
                                     'revisit'                 => $this->checkout->revisit,
@@ -1507,7 +1507,7 @@  discard block
 block discarded – undo
1507 1507
                                         sprintf(
1508 1508
                                             __('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1509 1509
                                                 'event_espresso'),
1510
-                                            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1510
+                                            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
1511 1511
                                             '">',
1512 1512
                                             '</a>'
1513 1513
                                         )
@@ -1564,7 +1564,7 @@  discard block
 block discarded – undo
1564 1564
         ) {
1565 1565
             add_filter(
1566 1566
                 'FHEE__EEH_Template__powered_by_event_espresso__url',
1567
-                function ($url) {
1567
+                function($url) {
1568 1568
                     return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1569 1569
                 }
1570 1570
             );
Please login to merge, or discard this patch.
Indentation   +1718 added lines, -1718 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 use EventEspresso\core\exceptions\InvalidEntityException;
3 3
 
4 4
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -17,1723 +17,1723 @@  discard block
 block discarded – undo
17 17
 class EED_Single_Page_Checkout extends EED_Module
18 18
 {
19 19
 
20
-    /**
21
-     * $_initialized - has the SPCO controller already been initialized ?
22
-     *
23
-     * @access private
24
-     * @var bool $_initialized
25
-     */
26
-    private static $_initialized = false;
27
-
28
-
29
-    /**
30
-     * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
31
-     *
32
-     * @access private
33
-     * @var bool $_valid_checkout
34
-     */
35
-    private static $_checkout_verified = true;
36
-
37
-    /**
38
-     *    $_reg_steps_array - holds initial array of reg steps
39
-     *
40
-     * @access private
41
-     * @var array $_reg_steps_array
42
-     */
43
-    private static $_reg_steps_array = array();
44
-
45
-    /**
46
-     *    $checkout - EE_Checkout object for handling the properties of the current checkout process
47
-     *
48
-     * @access public
49
-     * @var EE_Checkout $checkout
50
-     */
51
-    public $checkout;
52
-
53
-
54
-
55
-    /**
56
-     * @return EED_Single_Page_Checkout
57
-     */
58
-    public static function instance()
59
-    {
60
-        add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
61
-        return parent::get_instance(__CLASS__);
62
-    }
63
-
64
-
65
-
66
-    /**
67
-     * @return EE_CART
68
-     */
69
-    public function cart()
70
-    {
71
-        return $this->checkout->cart;
72
-    }
73
-
74
-
75
-
76
-    /**
77
-     * @return EE_Transaction
78
-     */
79
-    public function transaction()
80
-    {
81
-        return $this->checkout->transaction;
82
-    }
83
-
84
-
85
-
86
-    /**
87
-     *    set_hooks - for hooking into EE Core, other modules, etc
88
-     *
89
-     * @access    public
90
-     * @return    void
91
-     * @throws \EE_Error
92
-     */
93
-    public static function set_hooks()
94
-    {
95
-        EED_Single_Page_Checkout::set_definitions();
96
-    }
97
-
98
-
99
-
100
-    /**
101
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
102
-     *
103
-     * @access    public
104
-     * @return    void
105
-     * @throws \EE_Error
106
-     */
107
-    public static function set_hooks_admin()
108
-    {
109
-        EED_Single_Page_Checkout::set_definitions();
110
-        if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
111
-            return;
112
-        }
113
-        // going to start an output buffer in case anything gets accidentally output that might disrupt our JSON response
114
-        ob_start();
115
-        EED_Single_Page_Checkout::load_request_handler();
116
-        EED_Single_Page_Checkout::load_reg_steps();
117
-        // set ajax hooks
118
-        add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
119
-        add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
120
-        add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
121
-        add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
122
-        add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
123
-        add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
124
-    }
125
-
126
-
127
-
128
-    /**
129
-     *    process ajax request
130
-     *
131
-     * @param string $ajax_action
132
-     * @throws \EE_Error
133
-     */
134
-    public static function process_ajax_request($ajax_action)
135
-    {
136
-        EE_Registry::instance()->REQ->set('action', $ajax_action);
137
-        EED_Single_Page_Checkout::instance()->_initialize();
138
-    }
139
-
140
-
141
-
142
-    /**
143
-     *    ajax display registration step
144
-     *
145
-     * @throws \EE_Error
146
-     */
147
-    public static function display_reg_step()
148
-    {
149
-        EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
150
-    }
151
-
152
-
153
-
154
-    /**
155
-     *    ajax process registration step
156
-     *
157
-     * @throws \EE_Error
158
-     */
159
-    public static function process_reg_step()
160
-    {
161
-        EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
162
-    }
163
-
164
-
165
-
166
-    /**
167
-     *    ajax process registration step
168
-     *
169
-     * @throws \EE_Error
170
-     */
171
-    public static function update_reg_step()
172
-    {
173
-        EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
174
-    }
175
-
176
-
177
-
178
-    /**
179
-     *   update_checkout
180
-     *
181
-     * @access public
182
-     * @return void
183
-     * @throws \EE_Error
184
-     */
185
-    public static function update_checkout()
186
-    {
187
-        EED_Single_Page_Checkout::process_ajax_request('update_checkout');
188
-    }
189
-
190
-
191
-
192
-    /**
193
-     *    load_request_handler
194
-     *
195
-     * @access    public
196
-     * @return    void
197
-     */
198
-    public static function load_request_handler()
199
-    {
200
-        // load core Request_Handler class
201
-        if ( ! isset(EE_Registry::instance()->REQ)) {
202
-            EE_Registry::instance()->load_core('Request_Handler');
203
-        }
204
-    }
205
-
206
-
207
-
208
-    /**
209
-     *    set_definitions
210
-     *
211
-     * @access    public
212
-     * @return    void
213
-     * @throws \EE_Error
214
-     */
215
-    public static function set_definitions()
216
-    {
217
-        if(defined('SPCO_BASE_PATH')) {
218
-            return;
219
-        }
220
-        define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS);
221
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
222
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
223
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
224
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
225
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
226
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
227
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
228
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
229
-            __('%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',
230
-                'event_espresso'),
231
-            '<h4 class="important-notice">',
232
-            '</h4>',
233
-            '<br />',
234
-            '<p>',
235
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
236
-            '">',
237
-            '</a>',
238
-            '</p>'
239
-        );
240
-    }
241
-
242
-
243
-
244
-    /**
245
-     * load_reg_steps
246
-     * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
247
-     *
248
-     * @access    private
249
-     * @throws \EE_Error
250
-     */
251
-    public static function load_reg_steps()
252
-    {
253
-        static $reg_steps_loaded = false;
254
-        if ($reg_steps_loaded) {
255
-            return;
256
-        }
257
-        // filter list of reg_steps
258
-        $reg_steps_to_load = (array)apply_filters(
259
-            'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
260
-            EED_Single_Page_Checkout::get_reg_steps()
261
-        );
262
-        // sort by key (order)
263
-        ksort($reg_steps_to_load);
264
-        // loop through folders
265
-        foreach ($reg_steps_to_load as $order => $reg_step) {
266
-            // we need a
267
-            if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
268
-                // copy over to the reg_steps_array
269
-                EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
270
-                // register custom key route for each reg step
271
-                // ie: step=>"slug" - this is the entire reason we load the reg steps array now
272
-                EE_Config::register_route($reg_step['slug'], 'EED_Single_Page_Checkout', 'run', 'step');
273
-                // add AJAX or other hooks
274
-                if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
275
-                    // setup autoloaders if necessary
276
-                    if ( ! class_exists($reg_step['class_name'])) {
277
-                        EEH_Autoloader::register_autoloaders_for_each_file_in_folder($reg_step['file_path'], true);
278
-                    }
279
-                    if (is_callable($reg_step['class_name'], 'set_hooks')) {
280
-                        call_user_func(array($reg_step['class_name'], 'set_hooks'));
281
-                    }
282
-                }
283
-            }
284
-        }
285
-        $reg_steps_loaded = true;
286
-    }
287
-
288
-
289
-
290
-    /**
291
-     *    get_reg_steps
292
-     *
293
-     * @access    public
294
-     * @return    array
295
-     */
296
-    public static function get_reg_steps()
297
-    {
298
-        $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
299
-        if (empty($reg_steps)) {
300
-            $reg_steps = array(
301
-                10  => array(
302
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
303
-                    'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
304
-                    'slug'       => 'attendee_information',
305
-                    'has_hooks'  => false,
306
-                ),
307
-                20  => array(
308
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
309
-                    'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
310
-                    'slug'       => 'registration_confirmation',
311
-                    'has_hooks'  => false,
312
-                ),
313
-                30  => array(
314
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
315
-                    'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
316
-                    'slug'       => 'payment_options',
317
-                    'has_hooks'  => true,
318
-                ),
319
-                999 => array(
320
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
321
-                    'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
322
-                    'slug'       => 'finalize_registration',
323
-                    'has_hooks'  => false,
324
-                ),
325
-            );
326
-        }
327
-        return $reg_steps;
328
-    }
329
-
330
-
331
-
332
-    /**
333
-     *    registration_checkout_for_admin
334
-     *
335
-     * @access    public
336
-     * @return    string
337
-     * @throws \EE_Error
338
-     */
339
-    public static function registration_checkout_for_admin()
340
-    {
341
-        EED_Single_Page_Checkout::load_request_handler();
342
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
343
-        EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
344
-        EE_Registry::instance()->REQ->set('process_form_submission', false);
345
-        EED_Single_Page_Checkout::instance()->_initialize();
346
-        EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
347
-        return EE_Registry::instance()->REQ->get_output();
348
-    }
349
-
350
-
351
-
352
-    /**
353
-     * process_registration_from_admin
354
-     *
355
-     * @access public
356
-     * @return \EE_Transaction
357
-     * @throws \EE_Error
358
-     */
359
-    public static function process_registration_from_admin()
360
-    {
361
-        EED_Single_Page_Checkout::load_request_handler();
362
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
363
-        EE_Registry::instance()->REQ->set('action', 'process_reg_step');
364
-        EE_Registry::instance()->REQ->set('process_form_submission', true);
365
-        EED_Single_Page_Checkout::instance()->_initialize();
366
-        if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
367
-            $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
368
-            if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
369
-                EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
370
-                if ($final_reg_step->process_reg_step()) {
371
-                    $final_reg_step->set_completed();
372
-                    EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
373
-                    return EED_Single_Page_Checkout::instance()->checkout->transaction;
374
-                }
375
-            }
376
-        }
377
-        return null;
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     *    run
384
-     *
385
-     * @access    public
386
-     * @param WP_Query $WP_Query
387
-     * @return    void
388
-     * @throws \EE_Error
389
-     */
390
-    public function run($WP_Query)
391
-    {
392
-        if (
393
-            $WP_Query instanceof WP_Query
394
-            && $WP_Query->is_main_query()
395
-            && apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
396
-            && $this->_is_reg_checkout()
397
-        ) {
398
-            $this->_initialize();
399
-        }
400
-    }
401
-
402
-
403
-
404
-    /**
405
-     * determines whether current url matches reg page url
406
-     *
407
-     * @return bool
408
-     */
409
-    protected function _is_reg_checkout()
410
-    {
411
-        // get current permalink for reg page without any extra query args
412
-        $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
413
-        // get request URI for current request, but without the scheme or host
414
-        $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
415
-        $current_request_uri = html_entity_decode($current_request_uri);
416
-        // get array of query args from the current request URI
417
-        $query_args = \EEH_URL::get_query_string($current_request_uri);
418
-        // grab page id if it is set
419
-        $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
420
-        // and remove the page id from the query args (we will re-add it later)
421
-        unset($query_args['page_id']);
422
-        // now strip all query args from current request URI
423
-        $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
424
-        // and re-add the page id if it was set
425
-        if ($page_id) {
426
-            $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
427
-        }
428
-        // remove slashes and ?
429
-        $current_request_uri = trim($current_request_uri, '?/');
430
-        // is current request URI part of the known full reg page URL ?
431
-        return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
432
-    }
433
-
434
-
435
-
436
-    /**
437
-     * @param WP_Query $wp_query
438
-     * @return    void
439
-     * @throws \EE_Error
440
-     */
441
-    public static function init($wp_query)
442
-    {
443
-        EED_Single_Page_Checkout::instance()->run($wp_query);
444
-    }
445
-
446
-
447
-
448
-    /**
449
-     *    _initialize - initial module setup
450
-     *
451
-     * @access    private
452
-     * @throws EE_Error
453
-     * @return    void
454
-     */
455
-    private function _initialize()
456
-    {
457
-        // ensure SPCO doesn't run twice
458
-        if (EED_Single_Page_Checkout::$_initialized) {
459
-            return;
460
-        }
461
-        try {
462
-            EED_Single_Page_Checkout::load_reg_steps();
463
-            $this->_verify_session();
464
-            // setup the EE_Checkout object
465
-            $this->checkout = $this->_initialize_checkout();
466
-            // filter checkout
467
-            $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
468
-            // get the $_GET
469
-            $this->_get_request_vars();
470
-            if ($this->_block_bots()) {
471
-                return;
472
-            }
473
-            // filter continue_reg
474
-            $this->checkout->continue_reg = apply_filters('FHEE__EED_Single_Page_Checkout__init___continue_reg', true, $this->checkout);
475
-            // load the reg steps array
476
-            if ( ! $this->_load_and_instantiate_reg_steps()) {
477
-                EED_Single_Page_Checkout::$_initialized = true;
478
-                return;
479
-            }
480
-            // set the current step
481
-            $this->checkout->set_current_step($this->checkout->step);
482
-            // and the next step
483
-            $this->checkout->set_next_step();
484
-            // verify that everything has been setup correctly
485
-            if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
486
-                EED_Single_Page_Checkout::$_initialized = true;
487
-                return;
488
-            }
489
-            // lock the transaction
490
-            $this->checkout->transaction->lock();
491
-            // make sure all of our cached objects are added to their respective model entity mappers
492
-            $this->checkout->refresh_all_entities();
493
-            // set amount owing
494
-            $this->checkout->amount_owing = $this->checkout->transaction->remaining();
495
-            // initialize each reg step, which gives them the chance to potentially alter the process
496
-            $this->_initialize_reg_steps();
497
-            // DEBUG LOG
498
-            //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
499
-            // get reg form
500
-            if( ! $this->_check_form_submission()) {
501
-                EED_Single_Page_Checkout::$_initialized = true;
502
-                return;
503
-            }
504
-            // checkout the action!!!
505
-            $this->_process_form_action();
506
-            // add some style and make it dance
507
-            $this->add_styles_and_scripts();
508
-            // kk... SPCO has successfully run
509
-            EED_Single_Page_Checkout::$_initialized = true;
510
-            // set no cache headers and constants
511
-            EE_System::do_not_cache();
512
-            // add anchor
513
-            add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
514
-            // remove transaction lock
515
-            add_action('shutdown', array($this, 'unlock_transaction'), 1);
516
-        } catch (Exception $e) {
517
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
518
-        }
519
-    }
520
-
521
-
522
-
523
-    /**
524
-     *    _verify_session
525
-     * checks that the session is valid and not expired
526
-     *
527
-     * @access    private
528
-     * @throws EE_Error
529
-     */
530
-    private function _verify_session()
531
-    {
532
-        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
533
-            throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
534
-        }
535
-        // is session still valid ?
536
-        if (EE_Registry::instance()->SSN->expired() && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '') {
537
-            $this->checkout = new EE_Checkout();
538
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
539
-            // EE_Registry::instance()->SSN->reset_cart();
540
-            // EE_Registry::instance()->SSN->reset_checkout();
541
-            // EE_Registry::instance()->SSN->reset_transaction();
542
-            EE_Error::add_attention(EE_Registry::$i18n_js_strings['registration_expiration_notice'], __FILE__,
543
-                __FUNCTION__, __LINE__);
544
-            // EE_Registry::instance()->SSN->reset_expired();
545
-        }
546
-    }
547
-
548
-
549
-
550
-    /**
551
-     *    _initialize_checkout
552
-     * loads and instantiates EE_Checkout
553
-     *
554
-     * @access    private
555
-     * @throws EE_Error
556
-     * @return EE_Checkout
557
-     */
558
-    private function _initialize_checkout()
559
-    {
560
-        // look in session for existing checkout
561
-        /** @type EE_Checkout $checkout */
562
-        $checkout = EE_Registry::instance()->SSN->checkout();
563
-        // verify
564
-        if ( ! $checkout instanceof EE_Checkout) {
565
-            // instantiate EE_Checkout object for handling the properties of the current checkout process
566
-            $checkout = EE_Registry::instance()->load_file(SPCO_INC_PATH, 'EE_Checkout', 'class', array(), false);
567
-        } else {
568
-            if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
569
-                $this->unlock_transaction();
570
-                wp_safe_redirect($checkout->redirect_url);
571
-                exit();
572
-            }
573
-        }
574
-        $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
575
-        // verify again
576
-        if ( ! $checkout instanceof EE_Checkout) {
577
-            throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
578
-        }
579
-        // reset anything that needs a clean slate for each request
580
-        $checkout->reset_for_current_request();
581
-        return $checkout;
582
-    }
583
-
584
-
585
-
586
-    /**
587
-     *    _get_request_vars
588
-     *
589
-     * @access    private
590
-     * @return    void
591
-     * @throws \EE_Error
592
-     */
593
-    private function _get_request_vars()
594
-    {
595
-        // load classes
596
-        EED_Single_Page_Checkout::load_request_handler();
597
-        //make sure this request is marked as belonging to EE
598
-        EE_Registry::instance()->REQ->set_espresso_page(true);
599
-        // which step is being requested ?
600
-        $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
601
-        // which step is being edited ?
602
-        $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
603
-        // and what we're doing on the current step
604
-        $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
605
-        // timestamp
606
-        $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
607
-        // returning to edit ?
608
-        $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
609
-        // or some other kind of revisit ?
610
-        $this->checkout->revisit = filter_var(
611
-            EE_Registry::instance()->REQ->get('revisit', false),
612
-            FILTER_VALIDATE_BOOLEAN
613
-        );
614
-        // and whether or not to generate a reg form for this request
615
-        $this->checkout->generate_reg_form = filter_var(
616
-            EE_Registry::instance()->REQ->get('generate_reg_form', true),
617
-            FILTER_VALIDATE_BOOLEAN
618
-        );
619
-        // and whether or not to process a reg form submission for this request
620
-        $this->checkout->process_form_submission = filter_var(
621
-            EE_Registry::instance()->REQ->get(
622
-                'process_form_submission',
623
-                $this->checkout->action === 'process_reg_step'
624
-            ),
625
-            FILTER_VALIDATE_BOOLEAN
626
-        );
627
-        $this->checkout->process_form_submission = filter_var(
628
-            $this->checkout->action !== 'display_spco_reg_step'
629
-                ? $this->checkout->process_form_submission
630
-                : false,
631
-            FILTER_VALIDATE_BOOLEAN
632
-        );
633
-        // $this->_display_request_vars();
634
-    }
635
-
636
-
637
-
638
-    /**
639
-     *  _display_request_vars
640
-     *
641
-     * @access    protected
642
-     * @return    void
643
-     */
644
-    protected function _display_request_vars()
645
-    {
646
-        if ( ! WP_DEBUG) {
647
-            return;
648
-        }
649
-        EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
650
-        EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
651
-        EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
652
-        EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
653
-        EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
654
-        EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
655
-        EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
656
-        EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
657
-    }
658
-
659
-
660
-
661
-    /**
662
-     * _block_bots
663
-     * checks that the incoming request has either of the following set:
664
-     *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
665
-     *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
666
-     * so if you're not coming from the Ticket Selector nor returning for a valid IP...
667
-     * then where you coming from man?
668
-     *
669
-     * @return boolean
670
-     */
671
-    private function _block_bots()
672
-    {
673
-        $invalid_checkout_access = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
674
-        if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
675
-            return true;
676
-        }
677
-        return false;
678
-    }
679
-
680
-
681
-
682
-    /**
683
-     *    _get_first_step
684
-     *  gets slug for first step in $_reg_steps_array
685
-     *
686
-     * @access    private
687
-     * @throws EE_Error
688
-     * @return    string
689
-     */
690
-    private function _get_first_step()
691
-    {
692
-        $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
693
-        return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
694
-    }
695
-
696
-
697
-
698
-    /**
699
-     *    _load_and_instantiate_reg_steps
700
-     *  instantiates each reg step based on the loaded reg_steps array
701
-     *
702
-     * @access    private
703
-     * @throws EE_Error
704
-     * @return    bool
705
-     */
706
-    private function _load_and_instantiate_reg_steps()
707
-    {
708
-        do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
709
-        // have reg_steps already been instantiated ?
710
-        if (
711
-            empty($this->checkout->reg_steps)
712
-            || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
713
-        ) {
714
-            // if not, then loop through raw reg steps array
715
-            foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
716
-                if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
717
-                    return false;
718
-                }
719
-            }
720
-            EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
721
-            EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
722
-            // skip the registration_confirmation page ?
723
-            if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
724
-                // just remove it from the reg steps array
725
-                $this->checkout->remove_reg_step('registration_confirmation', false);
726
-            } else if (
727
-                isset($this->checkout->reg_steps['registration_confirmation'])
728
-                && EE_Registry::instance()->CFG->registration->reg_confirmation_last
729
-            ) {
730
-                // set the order to something big like 100
731
-                $this->checkout->set_reg_step_order('registration_confirmation', 100);
732
-            }
733
-            // filter the array for good luck
734
-            $this->checkout->reg_steps = apply_filters(
735
-                'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
736
-                $this->checkout->reg_steps
737
-            );
738
-            // finally re-sort based on the reg step class order properties
739
-            $this->checkout->sort_reg_steps();
740
-        } else {
741
-            foreach ($this->checkout->reg_steps as $reg_step) {
742
-                // set all current step stati to FALSE
743
-                $reg_step->set_is_current_step(false);
744
-            }
745
-        }
746
-        if (empty($this->checkout->reg_steps)) {
747
-            EE_Error::add_error(__('No Reg Steps were loaded..', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
748
-            return false;
749
-        }
750
-        // make reg step details available to JS
751
-        $this->checkout->set_reg_step_JSON_info();
752
-        return true;
753
-    }
754
-
755
-
756
-
757
-    /**
758
-     *     _load_and_instantiate_reg_step
759
-     *
760
-     * @access    private
761
-     * @param array $reg_step
762
-     * @param int   $order
763
-     * @return bool
764
-     */
765
-    private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
766
-    {
767
-        // we need a file_path, class_name, and slug to add a reg step
768
-        if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
769
-            // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
770
-            if (
771
-                $this->checkout->reg_url_link
772
-                && $this->checkout->step !== $reg_step['slug']
773
-                && $reg_step['slug'] !== 'finalize_registration'
774
-                // normally at this point we would NOT load the reg step, but this filter can change that
775
-                && apply_filters(
776
-                    'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
777
-                    true,
778
-                    $reg_step,
779
-                    $this->checkout
780
-                )
781
-            ) {
782
-                return true;
783
-            }
784
-            // instantiate step class using file path and class name
785
-            $reg_step_obj = EE_Registry::instance()->load_file(
786
-                $reg_step['file_path'],
787
-                $reg_step['class_name'],
788
-                'class',
789
-                $this->checkout,
790
-                false
791
-            );
792
-            // did we gets the goods ?
793
-            if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
794
-                // set reg step order based on config
795
-                $reg_step_obj->set_order($order);
796
-                // add instantiated reg step object to the master reg steps array
797
-                $this->checkout->add_reg_step($reg_step_obj);
798
-            } else {
799
-                EE_Error::add_error(
800
-                    __('The current step could not be set.', 'event_espresso'),
801
-                    __FILE__, __FUNCTION__, __LINE__
802
-                );
803
-                return false;
804
-            }
805
-        } else {
806
-            if (WP_DEBUG) {
807
-                EE_Error::add_error(
808
-                    sprintf(
809
-                        __('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', 'event_espresso'),
810
-                        isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
811
-                        isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
812
-                        isset($reg_step['slug']) ? $reg_step['slug'] : '',
813
-                        '<ul>',
814
-                        '<li>',
815
-                        '</li>',
816
-                        '</ul>'
817
-                    ),
818
-                    __FILE__, __FUNCTION__, __LINE__
819
-                );
820
-            }
821
-            return false;
822
-        }
823
-        return true;
824
-    }
825
-
826
-
827
-
828
-    /**
829
-     * _verify_transaction_and_get_registrations
830
-     *
831
-     * @access private
832
-     * @return bool
833
-     */
834
-    private function _verify_transaction_and_get_registrations()
835
-    {
836
-        // was there already a valid transaction in the checkout from the session ?
837
-        if ( ! $this->checkout->transaction instanceof EE_Transaction) {
838
-            // get transaction from db or session
839
-            $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
840
-                ? $this->_get_transaction_and_cart_for_previous_visit()
841
-                : $this->_get_cart_for_current_session_and_setup_new_transaction();
842
-            if ( ! $this->checkout->transaction instanceof EE_Transaction) {
843
-                EE_Error::add_error(
844
-                    __('Your Registration and Transaction information could not be retrieved from the db.',
845
-                        'event_espresso'),
846
-                    __FILE__, __FUNCTION__, __LINE__
847
-                );
848
-                $this->checkout->transaction = EE_Transaction::new_instance();
849
-                // add some style and make it dance
850
-                $this->add_styles_and_scripts();
851
-                EED_Single_Page_Checkout::$_initialized = true;
852
-                return false;
853
-            }
854
-            // and the registrations for the transaction
855
-            $this->_get_registrations($this->checkout->transaction);
856
-        }
857
-        return true;
858
-    }
859
-
860
-
861
-
862
-    /**
863
-     * _get_transaction_and_cart_for_previous_visit
864
-     *
865
-     * @access private
866
-     * @return mixed EE_Transaction|NULL
867
-     */
868
-    private function _get_transaction_and_cart_for_previous_visit()
869
-    {
870
-        /** @var $TXN_model EEM_Transaction */
871
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
872
-        // because the reg_url_link is present in the request, this is a return visit to SPCO, so we'll get the transaction data from the db
873
-        $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
874
-        // verify transaction
875
-        if ($transaction instanceof EE_Transaction) {
876
-            // and get the cart that was used for that transaction
877
-            $this->checkout->cart = $this->_get_cart_for_transaction($transaction);
878
-            return $transaction;
879
-        } else {
880
-            EE_Error::add_error(__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
881
-            return null;
882
-        }
883
-    }
884
-
885
-
886
-
887
-    /**
888
-     * _get_cart_for_transaction
889
-     *
890
-     * @access private
891
-     * @param EE_Transaction $transaction
892
-     * @return EE_Cart
893
-     */
894
-    private function _get_cart_for_transaction($transaction)
895
-    {
896
-        return $this->checkout->get_cart_for_transaction($transaction);
897
-    }
898
-
899
-
900
-
901
-    /**
902
-     * get_cart_for_transaction
903
-     *
904
-     * @access public
905
-     * @param EE_Transaction $transaction
906
-     * @return EE_Cart
907
-     */
908
-    public function get_cart_for_transaction(EE_Transaction $transaction)
909
-    {
910
-        return $this->checkout->get_cart_for_transaction($transaction);
911
-    }
912
-
913
-
914
-
915
-    /**
916
-     * _get_transaction_and_cart_for_current_session
917
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
918
-     *
919
-     * @access private
920
-     * @return EE_Transaction
921
-     * @throws \EE_Error
922
-     */
923
-    private function _get_cart_for_current_session_and_setup_new_transaction()
924
-    {
925
-        //  if there's no transaction, then this is the FIRST visit to SPCO
926
-        // so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
927
-        $this->checkout->cart = $this->_get_cart_for_transaction(null);
928
-        // and then create a new transaction
929
-        $transaction = $this->_initialize_transaction();
930
-        // verify transaction
931
-        if ($transaction instanceof EE_Transaction) {
932
-            // save it so that we have an ID for other objects to use
933
-            $transaction->save();
934
-            // and save TXN data to the cart
935
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
936
-        } else {
937
-            EE_Error::add_error(__('A Valid Transaction could not be initialized.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
938
-        }
939
-        return $transaction;
940
-    }
941
-
942
-
943
-
944
-    /**
945
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
946
-     *
947
-     * @access private
948
-     * @return mixed EE_Transaction|NULL
949
-     */
950
-    private function _initialize_transaction()
951
-    {
952
-        try {
953
-            // ensure cart totals have been calculated
954
-            $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
955
-            // grab the cart grand total
956
-            $cart_total = $this->checkout->cart->get_cart_grand_total();
957
-            // create new TXN
958
-            $transaction = EE_Transaction::new_instance(
959
-                array(
960
-                    'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
961
-                    'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
962
-                    'TXN_paid'      => 0,
963
-                    'STS_ID'        => EEM_Transaction::failed_status_code,
964
-                )
965
-            );
966
-            // save it so that we have an ID for other objects to use
967
-            $transaction->save();
968
-            // set cron job for following up on TXNs after their session has expired
969
-            EE_Cron_Tasks::schedule_expired_transaction_check(
970
-                EE_Registry::instance()->SSN->expiration() + 1,
971
-                $transaction->ID()
972
-            );
973
-            return $transaction;
974
-        } catch (Exception $e) {
975
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
976
-        }
977
-        return null;
978
-    }
979
-
980
-
981
-
982
-    /**
983
-     * _get_registrations
984
-     *
985
-     * @access private
986
-     * @param EE_Transaction $transaction
987
-     * @return void
988
-     * @throws \EventEspresso\core\exceptions\InvalidEntityException
989
-     * @throws \EE_Error
990
-     */
991
-    private function _get_registrations(EE_Transaction $transaction)
992
-    {
993
-        // first step: grab the registrants  { : o
994
-        $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
995
-        // verify registrations have been set
996
-        if (empty($registrations)) {
997
-            // if no cached registrations, then check the db
998
-            $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
999
-            // still nothing ? well as long as this isn't a revisit
1000
-            if (empty($registrations) && ! $this->checkout->revisit) {
1001
-                // generate new registrations from scratch
1002
-                $registrations = $this->_initialize_registrations($transaction);
1003
-            }
1004
-        }
1005
-        // sort by their original registration order
1006
-        usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1007
-        // then loop thru the array
1008
-        foreach ($registrations as $registration) {
1009
-            // verify each registration
1010
-            if ($registration instanceof EE_Registration) {
1011
-                // we display all attendee info for the primary registrant
1012
-                if ($this->checkout->reg_url_link === $registration->reg_url_link()
1013
-                    && $registration->is_primary_registrant()
1014
-                ) {
1015
-                    $this->checkout->primary_revisit = true;
1016
-                    break;
1017
-                } else if ($this->checkout->revisit
1018
-                           && $this->checkout->reg_url_link !== $registration->reg_url_link()
1019
-                ) {
1020
-                    // but hide info if it doesn't belong to you
1021
-                    $transaction->clear_cache('Registration', $registration->ID());
1022
-                }
1023
-                $this->checkout->set_reg_status_updated($registration->ID(), false);
1024
-            }
1025
-        }
1026
-    }
1027
-
1028
-
1029
-
1030
-    /**
1031
-     *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1032
-     *
1033
-     * @access private
1034
-     * @param EE_Transaction $transaction
1035
-     * @return    array
1036
-     * @throws \EventEspresso\core\exceptions\InvalidEntityException
1037
-     * @throws \EE_Error
1038
-     */
1039
-    private function _initialize_registrations(EE_Transaction $transaction)
1040
-    {
1041
-        $att_nmbr = 0;
1042
-        $registrations = array();
1043
-        if ($transaction instanceof EE_Transaction) {
1044
-            /** @type EE_Registration_Processor $registration_processor */
1045
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1046
-            $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1047
-            // now let's add the cart items to the $transaction
1048
-            foreach ($this->checkout->cart->get_tickets() as $line_item) {
1049
-                //do the following for each ticket of this type they selected
1050
-                for ($x = 1; $x <= $line_item->quantity(); $x++) {
1051
-                    $att_nmbr++;
1052
-                    /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1053
-                    $CreateRegistrationCommand = EE_Registry::instance()
1054
-                                                            ->create(
1055
-                                                                'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1056
-                                                                array(
1057
-                                                                    $transaction,
1058
-                                                                    $line_item,
1059
-                                                                    $att_nmbr,
1060
-                                                                    $this->checkout->total_ticket_count,
1061
-                                                                )
1062
-                                                            );
1063
-                    // override capabilities for frontend registrations
1064
-                    if ( ! is_admin()) {
1065
-                        $CreateRegistrationCommand->setCapCheck(
1066
-                            new PublicCapabilities('', 'create_new_registration')
1067
-                        );
1068
-                    }
1069
-                    $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1070
-                    if ( ! $registration instanceof EE_Registration) {
1071
-                        throw new InvalidEntityException($registration, 'EE_Registration');
1072
-                    }
1073
-                    $registrations[ $registration->ID() ] = $registration;
1074
-                }
1075
-            }
1076
-            $registration_processor->fix_reg_final_price_rounding_issue($transaction);
1077
-        }
1078
-        return $registrations;
1079
-    }
1080
-
1081
-
1082
-
1083
-    /**
1084
-     * sorts registrations by REG_count
1085
-     *
1086
-     * @access public
1087
-     * @param EE_Registration $reg_A
1088
-     * @param EE_Registration $reg_B
1089
-     * @return int
1090
-     */
1091
-    public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1092
-    {
1093
-        // this shouldn't ever happen within the same TXN, but oh well
1094
-        if ($reg_A->count() === $reg_B->count()) {
1095
-            return 0;
1096
-        }
1097
-        return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1098
-    }
1099
-
1100
-
1101
-
1102
-    /**
1103
-     *    _final_verifications
1104
-     * just makes sure that everything is set up correctly before proceeding
1105
-     *
1106
-     * @access    private
1107
-     * @return    bool
1108
-     * @throws \EE_Error
1109
-     */
1110
-    private function _final_verifications()
1111
-    {
1112
-        // filter checkout
1113
-        $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout);
1114
-        //verify that current step is still set correctly
1115
-        if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1116
-            EE_Error::add_error(
1117
-                __('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'),
1118
-                __FILE__,
1119
-                __FUNCTION__,
1120
-                __LINE__
1121
-            );
1122
-            return false;
1123
-        }
1124
-        // if returning to SPCO, then verify that primary registrant is set
1125
-        if ( ! empty($this->checkout->reg_url_link)) {
1126
-            $valid_registrant = $this->checkout->transaction->primary_registration();
1127
-            if ( ! $valid_registrant instanceof EE_Registration) {
1128
-                EE_Error::add_error(
1129
-                    __('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'),
1130
-                    __FILE__,
1131
-                    __FUNCTION__,
1132
-                    __LINE__
1133
-                );
1134
-                return false;
1135
-            }
1136
-            $valid_registrant = null;
1137
-            foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) {
1138
-                if (
1139
-                    $registration instanceof EE_Registration
1140
-                    && $registration->reg_url_link() === $this->checkout->reg_url_link
1141
-                ) {
1142
-                    $valid_registrant = $registration;
1143
-                }
1144
-            }
1145
-            if ( ! $valid_registrant instanceof EE_Registration) {
1146
-                // hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1147
-                if (EED_Single_Page_Checkout::$_checkout_verified) {
1148
-                    // clear the session, mark the checkout as unverified, and try again
1149
-                    EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1150
-                    EED_Single_Page_Checkout::$_initialized = false;
1151
-                    EED_Single_Page_Checkout::$_checkout_verified = false;
1152
-                    $this->_initialize();
1153
-                    EE_Error::reset_notices();
1154
-                    return false;
1155
-                }
1156
-                EE_Error::add_error(
1157
-                    __('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.', 'event_espresso'),
1158
-                    __FILE__,
1159
-                    __FUNCTION__,
1160
-                    __LINE__
1161
-                );
1162
-                return false;
1163
-            }
1164
-        }
1165
-        // now that things have been kinda sufficiently verified,
1166
-        // let's add the checkout to the session so that it's available to other systems
1167
-        EE_Registry::instance()->SSN->set_checkout($this->checkout);
1168
-        return true;
1169
-    }
1170
-
1171
-
1172
-
1173
-    /**
1174
-     *    _initialize_reg_steps
1175
-     * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1176
-     * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1177
-     *
1178
-     * @access    private
1179
-     * @param bool $reinitializing
1180
-     * @throws \EE_Error
1181
-     */
1182
-    private function _initialize_reg_steps($reinitializing = false)
1183
-    {
1184
-        $this->checkout->set_reg_step_initiated($this->checkout->current_step);
1185
-        // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1186
-        foreach ($this->checkout->reg_steps as $reg_step) {
1187
-            if ( ! $reg_step->initialize_reg_step()) {
1188
-                // if not initialized then maybe this step is being removed...
1189
-                if ( ! $reinitializing && $reg_step->is_current_step()) {
1190
-                    // if it was the current step, then we need to start over here
1191
-                    $this->_initialize_reg_steps(true);
1192
-                    return;
1193
-                }
1194
-                continue;
1195
-            }
1196
-            // add css and JS for current step
1197
-            $reg_step->enqueue_styles_and_scripts();
1198
-            // i18n
1199
-            $reg_step->translate_js_strings();
1200
-            if ($reg_step->is_current_step()) {
1201
-                // the text that appears on the reg step form submit button
1202
-                $reg_step->set_submit_button_text();
1203
-            }
1204
-        }
1205
-        // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1206
-        do_action("AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", $this->checkout->current_step);
1207
-    }
1208
-
1209
-
1210
-
1211
-    /**
1212
-     * _check_form_submission
1213
-     *
1214
-     * @access private
1215
-     * @return boolean
1216
-     */
1217
-    private function _check_form_submission()
1218
-    {
1219
-        //does this request require the reg form to be generated ?
1220
-        if ($this->checkout->generate_reg_form) {
1221
-            // ever heard that song by Blue Rodeo ?
1222
-            try {
1223
-                $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1224
-                // if not displaying a form, then check for form submission
1225
-                if (
1226
-                    $this->checkout->process_form_submission
1227
-                    && $this->checkout->current_step->reg_form->was_submitted()
1228
-                ) {
1229
-                    // clear out any old data in case this step is being run again
1230
-                    $this->checkout->current_step->set_valid_data(array());
1231
-                    // capture submitted form data
1232
-                    $this->checkout->current_step->reg_form->receive_form_submission(
1233
-                        apply_filters(
1234
-                            'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1235
-                            EE_Registry::instance()->REQ->params(),
1236
-                            $this->checkout
1237
-                        )
1238
-                    );
1239
-                    // validate submitted form data
1240
-                    if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1241
-                        // thou shall not pass !!!
1242
-                        $this->checkout->continue_reg = false;
1243
-                        // any form validation errors?
1244
-                        if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1245
-                            $submission_error_messages = array();
1246
-                            // bad, bad, bad registrant
1247
-                            foreach ($this->checkout->current_step->reg_form->get_validation_errors_accumulated() as $validation_error) {
1248
-                                if ($validation_error instanceof EE_Validation_Error) {
1249
-                                    $submission_error_messages[] = sprintf(
1250
-                                        __('%s : %s', 'event_espresso'),
1251
-                                        $validation_error->get_form_section()->html_label_text(),
1252
-                                        $validation_error->getMessage()
1253
-                                    );
1254
-                                }
1255
-                            }
1256
-                            EE_Error::add_error(implode('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__);
1257
-                        }
1258
-                        // well not really... what will happen is we'll just get redirected back to redo the current step
1259
-                        $this->go_to_next_step();
1260
-                        return false;
1261
-                    }
1262
-                }
1263
-            } catch (EE_Error $e) {
1264
-                $e->get_error();
1265
-            }
1266
-        }
1267
-        return true;
1268
-    }
1269
-
1270
-
1271
-
1272
-    /**
1273
-     * _process_action
1274
-     *
1275
-     * @access private
1276
-     * @return void
1277
-     * @throws \EE_Error
1278
-     */
1279
-    private function _process_form_action()
1280
-    {
1281
-        // what cha wanna do?
1282
-        switch ($this->checkout->action) {
1283
-            // AJAX next step reg form
1284
-            case 'display_spco_reg_step' :
1285
-                $this->checkout->redirect = false;
1286
-                if (EE_Registry::instance()->REQ->ajax) {
1287
-                    $this->checkout->json_response->set_reg_step_html($this->checkout->current_step->display_reg_form());
1288
-                }
1289
-                break;
1290
-            default :
1291
-                // meh... do one of those other steps first
1292
-                if ( ! empty($this->checkout->action) && is_callable(array($this->checkout->current_step, $this->checkout->action))) {
1293
-                    // dynamically creates hook point like: AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1294
-                    do_action("AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1295
-                    // call action on current step
1296
-                    if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1297
-                        // good registrant, you get to proceed
1298
-                        if (
1299
-                            $this->checkout->current_step->success_message() !== ''
1300
-                            && apply_filters(
1301
-                                'FHEE__Single_Page_Checkout___process_form_action__display_success',
1302
-                                false
1303
-                            )
1304
-                        ) {
1305
-                            EE_Error::add_success(
1306
-                                $this->checkout->current_step->success_message()
1307
-                                . '<br />' . $this->checkout->next_step->_instructions()
1308
-                            );
1309
-                        }
1310
-                        // pack it up, pack it in...
1311
-                        $this->_setup_redirect();
1312
-                    }
1313
-                    // dynamically creates hook point like: AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1314
-                    do_action("AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1315
-                } else {
1316
-                    EE_Error::add_error(
1317
-                        sprintf(
1318
-                            __('The requested form action "%s" does not exist for the current "%s" registration step.', 'event_espresso'),
1319
-                            $this->checkout->action,
1320
-                            $this->checkout->current_step->name()
1321
-                        ),
1322
-                        __FILE__,
1323
-                        __FUNCTION__,
1324
-                        __LINE__
1325
-                    );
1326
-                }
1327
-            // end default
1328
-        }
1329
-        // store our progress so far
1330
-        $this->checkout->stash_transaction_and_checkout();
1331
-        // advance to the next step! If you pass GO, collect $200
1332
-        $this->go_to_next_step();
1333
-    }
1334
-
1335
-
1336
-
1337
-    /**
1338
-     *        add_styles_and_scripts
1339
-     *
1340
-     * @access        public
1341
-     * @return        void
1342
-     */
1343
-    public function add_styles_and_scripts()
1344
-    {
1345
-        // i18n
1346
-        $this->translate_js_strings();
1347
-        if ($this->checkout->admin_request) {
1348
-            add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1349
-        } else {
1350
-            add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1351
-        }
1352
-    }
1353
-
1354
-
1355
-
1356
-    /**
1357
-     *        translate_js_strings
1358
-     *
1359
-     * @access        public
1360
-     * @return        void
1361
-     */
1362
-    public function translate_js_strings()
1363
-    {
1364
-        EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1365
-        EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1366
-        EE_Registry::$i18n_js_strings['server_error'] = __('An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso');
1367
-        EE_Registry::$i18n_js_strings['invalid_json_response'] = __('An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso');
1368
-        EE_Registry::$i18n_js_strings['validation_error'] = __('There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', 'event_espresso');
1369
-        EE_Registry::$i18n_js_strings['invalid_payment_method'] = __('There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', 'event_espresso');
1370
-        EE_Registry::$i18n_js_strings['reg_step_error'] = __('This registration step could not be completed. Please refresh the page and try again.', 'event_espresso');
1371
-        EE_Registry::$i18n_js_strings['invalid_coupon'] = __('We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', 'event_espresso');
1372
-        EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1373
-            __('Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', 'event_espresso'),
1374
-            '<br/>',
1375
-            '<br/>'
1376
-        );
1377
-        EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1378
-        EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1379
-        EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1380
-        EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1381
-        EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1382
-        EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1383
-        EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1384
-        EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1385
-        EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1386
-        EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1387
-        EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1388
-        EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1389
-        EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1390
-        EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1391
-        EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1392
-        EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1393
-        EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1394
-        EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1395
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1396
-            __(
1397
-                '%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',
1398
-                'event_espresso'
1399
-            ),
1400
-            '<h4 class="important-notice">',
1401
-            '</h4>',
1402
-            '<br />',
1403
-            '<p>',
1404
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1405
-            '">',
1406
-            '</a>',
1407
-            '</p>'
1408
-        );
1409
-        EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters('FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', true);
1410
-        EE_Registry::$i18n_js_strings['session_extension'] = absint(
1411
-            apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1412
-        );
1413
-        EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1414
-            'M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1415
-        );
1416
-    }
1417
-
1418
-
1419
-
1420
-    /**
1421
-     *    enqueue_styles_and_scripts
1422
-     *
1423
-     * @access        public
1424
-     * @return        void
1425
-     * @throws \EE_Error
1426
-     */
1427
-    public function enqueue_styles_and_scripts()
1428
-    {
1429
-        // load css
1430
-        wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1431
-        wp_enqueue_style('single_page_checkout');
1432
-        // load JS
1433
-        wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1434
-        wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1435
-        wp_register_script('single_page_checkout', SPCO_JS_URL . 'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true);
1436
-        if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1437
-            $this->checkout->registration_form->enqueue_js();
1438
-        }
1439
-        if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1440
-            $this->checkout->current_step->reg_form->enqueue_js();
1441
-        }
1442
-        wp_enqueue_script('single_page_checkout');
1443
-        /**
1444
-         * global action hook for enqueueing styles and scripts with
1445
-         * spco calls.
1446
-         */
1447
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1448
-        /**
1449
-         * dynamic action hook for enqueueing styles and scripts with spco calls.
1450
-         * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1451
-         */
1452
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this);
1453
-    }
1454
-
1455
-
1456
-
1457
-    /**
1458
-     *    display the Registration Single Page Checkout Form
1459
-     *
1460
-     * @access    private
1461
-     * @return    void
1462
-     * @throws \EE_Error
1463
-     */
1464
-    private function _display_spco_reg_form()
1465
-    {
1466
-        // if registering via the admin, just display the reg form for the current step
1467
-        if ($this->checkout->admin_request) {
1468
-            EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1469
-        } else {
1470
-            // add powered by EE msg
1471
-            add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1472
-            $empty_cart = count($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)) < 1
1473
-                ? true
1474
-                : false;
1475
-            EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1476
-            $cookies_not_set_msg = '';
1477
-            if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1478
-                $cookies_not_set_msg = apply_filters(
1479
-                    'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1480
-                    sprintf(
1481
-                        __(
1482
-                            '%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',
1483
-                            'event_espresso'
1484
-                        ),
1485
-                        '<div class="ee-attention">',
1486
-                        '</div>',
1487
-                        '<h6 class="important-notice">',
1488
-                        '</h6>',
1489
-                        '<p>',
1490
-                        '</p>',
1491
-                        '<br />',
1492
-                        '<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1493
-                        '</a>'
1494
-                    )
1495
-                );
1496
-            }
1497
-            $this->checkout->registration_form = new EE_Form_Section_Proper(
1498
-                array(
1499
-                    'name'            => 'single-page-checkout',
1500
-                    'html_id'         => 'ee-single-page-checkout-dv',
1501
-                    'layout_strategy' =>
1502
-                        new EE_Template_Layout(
1503
-                            array(
1504
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1505
-                                'template_args'        => array(
1506
-                                    'empty_cart'              => $empty_cart,
1507
-                                    'revisit'                 => $this->checkout->revisit,
1508
-                                    'reg_steps'               => $this->checkout->reg_steps,
1509
-                                    'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1510
-                                        ? $this->checkout->next_step->slug()
1511
-                                        : '',
1512
-                                    'cancel_page_url'         => $this->checkout->cancel_page_url,
1513
-                                    'empty_msg'               => apply_filters(
1514
-                                        'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1515
-                                        sprintf(
1516
-                                            __('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1517
-                                                'event_espresso'),
1518
-                                            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1519
-                                            '">',
1520
-                                            '</a>'
1521
-                                        )
1522
-                                    ),
1523
-                                    'cookies_not_set_msg'     => $cookies_not_set_msg,
1524
-                                    'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1525
-                                    'session_expiration'      => gmdate(
1526
-                                        'M d, Y H:i:s',
1527
-                                        EE_Registry::instance()->SSN->expiration()
1528
-                                        + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1529
-                                    ),
1530
-                                ),
1531
-                            )
1532
-                        ),
1533
-                )
1534
-            );
1535
-            // load template and add to output sent that gets filtered into the_content()
1536
-            EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1537
-        }
1538
-    }
1539
-
1540
-
1541
-
1542
-    /**
1543
-     *    add_extra_finalize_registration_inputs
1544
-     *
1545
-     * @access    public
1546
-     * @param $next_step
1547
-     * @internal  param string $label
1548
-     * @return void
1549
-     */
1550
-    public function add_extra_finalize_registration_inputs($next_step)
1551
-    {
1552
-        if ($next_step === 'finalize_registration') {
1553
-            echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1554
-        }
1555
-    }
1556
-
1557
-
1558
-
1559
-    /**
1560
-     *    display_registration_footer
1561
-     *
1562
-     * @access    public
1563
-     * @return    string
1564
-     */
1565
-    public static function display_registration_footer()
1566
-    {
1567
-        if (
1568
-        apply_filters(
1569
-            'FHEE__EE_Front__Controller__show_reg_footer',
1570
-            EE_Registry::instance()->CFG->admin->show_reg_footer
1571
-        )
1572
-        ) {
1573
-            add_filter(
1574
-                'FHEE__EEH_Template__powered_by_event_espresso__url',
1575
-                function ($url) {
1576
-                    return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1577
-                }
1578
-            );
1579
-            echo apply_filters(
1580
-                'FHEE__EE_Front_Controller__display_registration_footer',
1581
-                \EEH_Template::powered_by_event_espresso(
1582
-                    '',
1583
-                    'espresso-registration-footer-dv',
1584
-                    array('utm_content' => 'registration_checkout')
1585
-                )
1586
-            );
1587
-        }
1588
-        return '';
1589
-    }
1590
-
1591
-
1592
-
1593
-    /**
1594
-     *    unlock_transaction
1595
-     *
1596
-     * @access    public
1597
-     * @return    void
1598
-     * @throws \EE_Error
1599
-     */
1600
-    public function unlock_transaction()
1601
-    {
1602
-        if ($this->checkout->transaction instanceof EE_Transaction) {
1603
-            $this->checkout->transaction->unlock();
1604
-        }
1605
-    }
1606
-
1607
-
1608
-
1609
-    /**
1610
-     *        _setup_redirect
1611
-     *
1612
-     * @access    private
1613
-     * @return void
1614
-     */
1615
-    private function _setup_redirect()
1616
-    {
1617
-        if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1618
-            $this->checkout->redirect = true;
1619
-            if (empty($this->checkout->redirect_url)) {
1620
-                $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1621
-            }
1622
-            $this->checkout->redirect_url = apply_filters(
1623
-                'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1624
-                $this->checkout->redirect_url,
1625
-                $this->checkout
1626
-            );
1627
-        }
1628
-    }
1629
-
1630
-
1631
-
1632
-    /**
1633
-     *   handle ajax message responses and redirects
1634
-     *
1635
-     * @access public
1636
-     * @return void
1637
-     * @throws \EE_Error
1638
-     */
1639
-    public function go_to_next_step()
1640
-    {
1641
-        if (EE_Registry::instance()->REQ->ajax) {
1642
-            // capture contents of output buffer we started earlier in the request, and insert into JSON response
1643
-            $this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1644
-        }
1645
-        $this->unlock_transaction();
1646
-        // just return for these conditions
1647
-        if (
1648
-            $this->checkout->admin_request
1649
-            || $this->checkout->action === 'redirect_form'
1650
-            || $this->checkout->action === 'update_checkout'
1651
-        ) {
1652
-            return;
1653
-        }
1654
-        // AJAX response
1655
-        $this->_handle_json_response();
1656
-        // redirect to next step or the Thank You page
1657
-        $this->_handle_html_redirects();
1658
-        // hmmm... must be something wrong, so let's just display the form again !
1659
-        $this->_display_spco_reg_form();
1660
-    }
1661
-
1662
-
1663
-
1664
-    /**
1665
-     *   _handle_json_response
1666
-     *
1667
-     * @access protected
1668
-     * @return void
1669
-     */
1670
-    protected function _handle_json_response()
1671
-    {
1672
-        // if this is an ajax request
1673
-        if (EE_Registry::instance()->REQ->ajax) {
1674
-            // DEBUG LOG
1675
-            //$this->checkout->log(
1676
-            //	__CLASS__, __FUNCTION__, __LINE__,
1677
-            //	array(
1678
-            //		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1679
-            //		'redirect'                   => $this->checkout->redirect,
1680
-            //		'continue_reg'               => $this->checkout->continue_reg,
1681
-            //	)
1682
-            //);
1683
-            $this->checkout->json_response->set_registration_time_limit(
1684
-                $this->checkout->get_registration_time_limit()
1685
-            );
1686
-            $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1687
-            // just send the ajax (
1688
-            $json_response = apply_filters(
1689
-                'FHEE__EE_Single_Page_Checkout__JSON_response',
1690
-                $this->checkout->json_response
1691
-            );
1692
-            echo $json_response;
1693
-            exit();
1694
-        }
1695
-    }
1696
-
1697
-
1698
-
1699
-    /**
1700
-     *   _handle_redirects
1701
-     *
1702
-     * @access protected
1703
-     * @return void
1704
-     */
1705
-    protected function _handle_html_redirects()
1706
-    {
1707
-        // going somewhere ?
1708
-        if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1709
-            // store notices in a transient
1710
-            EE_Error::get_notices(false, true, true);
1711
-            // DEBUG LOG
1712
-            //$this->checkout->log(
1713
-            //	__CLASS__, __FUNCTION__, __LINE__,
1714
-            //	array(
1715
-            //		'headers_sent' => headers_sent(),
1716
-            //		'redirect_url'     => $this->checkout->redirect_url,
1717
-            //		'headers_list'    => headers_list(),
1718
-            //	)
1719
-            //);
1720
-            wp_safe_redirect($this->checkout->redirect_url);
1721
-            exit();
1722
-        }
1723
-    }
1724
-
1725
-
1726
-
1727
-    /**
1728
-     *   set_checkout_anchor
1729
-     *
1730
-     * @access public
1731
-     * @return void
1732
-     */
1733
-    public function set_checkout_anchor()
1734
-    {
1735
-        echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1736
-    }
20
+	/**
21
+	 * $_initialized - has the SPCO controller already been initialized ?
22
+	 *
23
+	 * @access private
24
+	 * @var bool $_initialized
25
+	 */
26
+	private static $_initialized = false;
27
+
28
+
29
+	/**
30
+	 * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
31
+	 *
32
+	 * @access private
33
+	 * @var bool $_valid_checkout
34
+	 */
35
+	private static $_checkout_verified = true;
36
+
37
+	/**
38
+	 *    $_reg_steps_array - holds initial array of reg steps
39
+	 *
40
+	 * @access private
41
+	 * @var array $_reg_steps_array
42
+	 */
43
+	private static $_reg_steps_array = array();
44
+
45
+	/**
46
+	 *    $checkout - EE_Checkout object for handling the properties of the current checkout process
47
+	 *
48
+	 * @access public
49
+	 * @var EE_Checkout $checkout
50
+	 */
51
+	public $checkout;
52
+
53
+
54
+
55
+	/**
56
+	 * @return EED_Single_Page_Checkout
57
+	 */
58
+	public static function instance()
59
+	{
60
+		add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
61
+		return parent::get_instance(__CLASS__);
62
+	}
63
+
64
+
65
+
66
+	/**
67
+	 * @return EE_CART
68
+	 */
69
+	public function cart()
70
+	{
71
+		return $this->checkout->cart;
72
+	}
73
+
74
+
75
+
76
+	/**
77
+	 * @return EE_Transaction
78
+	 */
79
+	public function transaction()
80
+	{
81
+		return $this->checkout->transaction;
82
+	}
83
+
84
+
85
+
86
+	/**
87
+	 *    set_hooks - for hooking into EE Core, other modules, etc
88
+	 *
89
+	 * @access    public
90
+	 * @return    void
91
+	 * @throws \EE_Error
92
+	 */
93
+	public static function set_hooks()
94
+	{
95
+		EED_Single_Page_Checkout::set_definitions();
96
+	}
97
+
98
+
99
+
100
+	/**
101
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
102
+	 *
103
+	 * @access    public
104
+	 * @return    void
105
+	 * @throws \EE_Error
106
+	 */
107
+	public static function set_hooks_admin()
108
+	{
109
+		EED_Single_Page_Checkout::set_definitions();
110
+		if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
111
+			return;
112
+		}
113
+		// going to start an output buffer in case anything gets accidentally output that might disrupt our JSON response
114
+		ob_start();
115
+		EED_Single_Page_Checkout::load_request_handler();
116
+		EED_Single_Page_Checkout::load_reg_steps();
117
+		// set ajax hooks
118
+		add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
119
+		add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
120
+		add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
121
+		add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
122
+		add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
123
+		add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
124
+	}
125
+
126
+
127
+
128
+	/**
129
+	 *    process ajax request
130
+	 *
131
+	 * @param string $ajax_action
132
+	 * @throws \EE_Error
133
+	 */
134
+	public static function process_ajax_request($ajax_action)
135
+	{
136
+		EE_Registry::instance()->REQ->set('action', $ajax_action);
137
+		EED_Single_Page_Checkout::instance()->_initialize();
138
+	}
139
+
140
+
141
+
142
+	/**
143
+	 *    ajax display registration step
144
+	 *
145
+	 * @throws \EE_Error
146
+	 */
147
+	public static function display_reg_step()
148
+	{
149
+		EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
150
+	}
151
+
152
+
153
+
154
+	/**
155
+	 *    ajax process registration step
156
+	 *
157
+	 * @throws \EE_Error
158
+	 */
159
+	public static function process_reg_step()
160
+	{
161
+		EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
162
+	}
163
+
164
+
165
+
166
+	/**
167
+	 *    ajax process registration step
168
+	 *
169
+	 * @throws \EE_Error
170
+	 */
171
+	public static function update_reg_step()
172
+	{
173
+		EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
174
+	}
175
+
176
+
177
+
178
+	/**
179
+	 *   update_checkout
180
+	 *
181
+	 * @access public
182
+	 * @return void
183
+	 * @throws \EE_Error
184
+	 */
185
+	public static function update_checkout()
186
+	{
187
+		EED_Single_Page_Checkout::process_ajax_request('update_checkout');
188
+	}
189
+
190
+
191
+
192
+	/**
193
+	 *    load_request_handler
194
+	 *
195
+	 * @access    public
196
+	 * @return    void
197
+	 */
198
+	public static function load_request_handler()
199
+	{
200
+		// load core Request_Handler class
201
+		if ( ! isset(EE_Registry::instance()->REQ)) {
202
+			EE_Registry::instance()->load_core('Request_Handler');
203
+		}
204
+	}
205
+
206
+
207
+
208
+	/**
209
+	 *    set_definitions
210
+	 *
211
+	 * @access    public
212
+	 * @return    void
213
+	 * @throws \EE_Error
214
+	 */
215
+	public static function set_definitions()
216
+	{
217
+		if(defined('SPCO_BASE_PATH')) {
218
+			return;
219
+		}
220
+		define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS);
221
+		define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
222
+		define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
223
+		define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
224
+		define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
225
+		define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
226
+		define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
227
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
228
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
229
+			__('%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',
230
+				'event_espresso'),
231
+			'<h4 class="important-notice">',
232
+			'</h4>',
233
+			'<br />',
234
+			'<p>',
235
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
236
+			'">',
237
+			'</a>',
238
+			'</p>'
239
+		);
240
+	}
241
+
242
+
243
+
244
+	/**
245
+	 * load_reg_steps
246
+	 * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
247
+	 *
248
+	 * @access    private
249
+	 * @throws \EE_Error
250
+	 */
251
+	public static function load_reg_steps()
252
+	{
253
+		static $reg_steps_loaded = false;
254
+		if ($reg_steps_loaded) {
255
+			return;
256
+		}
257
+		// filter list of reg_steps
258
+		$reg_steps_to_load = (array)apply_filters(
259
+			'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
260
+			EED_Single_Page_Checkout::get_reg_steps()
261
+		);
262
+		// sort by key (order)
263
+		ksort($reg_steps_to_load);
264
+		// loop through folders
265
+		foreach ($reg_steps_to_load as $order => $reg_step) {
266
+			// we need a
267
+			if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
268
+				// copy over to the reg_steps_array
269
+				EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
270
+				// register custom key route for each reg step
271
+				// ie: step=>"slug" - this is the entire reason we load the reg steps array now
272
+				EE_Config::register_route($reg_step['slug'], 'EED_Single_Page_Checkout', 'run', 'step');
273
+				// add AJAX or other hooks
274
+				if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
275
+					// setup autoloaders if necessary
276
+					if ( ! class_exists($reg_step['class_name'])) {
277
+						EEH_Autoloader::register_autoloaders_for_each_file_in_folder($reg_step['file_path'], true);
278
+					}
279
+					if (is_callable($reg_step['class_name'], 'set_hooks')) {
280
+						call_user_func(array($reg_step['class_name'], 'set_hooks'));
281
+					}
282
+				}
283
+			}
284
+		}
285
+		$reg_steps_loaded = true;
286
+	}
287
+
288
+
289
+
290
+	/**
291
+	 *    get_reg_steps
292
+	 *
293
+	 * @access    public
294
+	 * @return    array
295
+	 */
296
+	public static function get_reg_steps()
297
+	{
298
+		$reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
299
+		if (empty($reg_steps)) {
300
+			$reg_steps = array(
301
+				10  => array(
302
+					'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
303
+					'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
304
+					'slug'       => 'attendee_information',
305
+					'has_hooks'  => false,
306
+				),
307
+				20  => array(
308
+					'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
309
+					'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
310
+					'slug'       => 'registration_confirmation',
311
+					'has_hooks'  => false,
312
+				),
313
+				30  => array(
314
+					'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
315
+					'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
316
+					'slug'       => 'payment_options',
317
+					'has_hooks'  => true,
318
+				),
319
+				999 => array(
320
+					'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
321
+					'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
322
+					'slug'       => 'finalize_registration',
323
+					'has_hooks'  => false,
324
+				),
325
+			);
326
+		}
327
+		return $reg_steps;
328
+	}
329
+
330
+
331
+
332
+	/**
333
+	 *    registration_checkout_for_admin
334
+	 *
335
+	 * @access    public
336
+	 * @return    string
337
+	 * @throws \EE_Error
338
+	 */
339
+	public static function registration_checkout_for_admin()
340
+	{
341
+		EED_Single_Page_Checkout::load_request_handler();
342
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
343
+		EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
344
+		EE_Registry::instance()->REQ->set('process_form_submission', false);
345
+		EED_Single_Page_Checkout::instance()->_initialize();
346
+		EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
347
+		return EE_Registry::instance()->REQ->get_output();
348
+	}
349
+
350
+
351
+
352
+	/**
353
+	 * process_registration_from_admin
354
+	 *
355
+	 * @access public
356
+	 * @return \EE_Transaction
357
+	 * @throws \EE_Error
358
+	 */
359
+	public static function process_registration_from_admin()
360
+	{
361
+		EED_Single_Page_Checkout::load_request_handler();
362
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
363
+		EE_Registry::instance()->REQ->set('action', 'process_reg_step');
364
+		EE_Registry::instance()->REQ->set('process_form_submission', true);
365
+		EED_Single_Page_Checkout::instance()->_initialize();
366
+		if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
367
+			$final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
368
+			if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
369
+				EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
370
+				if ($final_reg_step->process_reg_step()) {
371
+					$final_reg_step->set_completed();
372
+					EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
373
+					return EED_Single_Page_Checkout::instance()->checkout->transaction;
374
+				}
375
+			}
376
+		}
377
+		return null;
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 *    run
384
+	 *
385
+	 * @access    public
386
+	 * @param WP_Query $WP_Query
387
+	 * @return    void
388
+	 * @throws \EE_Error
389
+	 */
390
+	public function run($WP_Query)
391
+	{
392
+		if (
393
+			$WP_Query instanceof WP_Query
394
+			&& $WP_Query->is_main_query()
395
+			&& apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
396
+			&& $this->_is_reg_checkout()
397
+		) {
398
+			$this->_initialize();
399
+		}
400
+	}
401
+
402
+
403
+
404
+	/**
405
+	 * determines whether current url matches reg page url
406
+	 *
407
+	 * @return bool
408
+	 */
409
+	protected function _is_reg_checkout()
410
+	{
411
+		// get current permalink for reg page without any extra query args
412
+		$reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
413
+		// get request URI for current request, but without the scheme or host
414
+		$current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
415
+		$current_request_uri = html_entity_decode($current_request_uri);
416
+		// get array of query args from the current request URI
417
+		$query_args = \EEH_URL::get_query_string($current_request_uri);
418
+		// grab page id if it is set
419
+		$page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
420
+		// and remove the page id from the query args (we will re-add it later)
421
+		unset($query_args['page_id']);
422
+		// now strip all query args from current request URI
423
+		$current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
424
+		// and re-add the page id if it was set
425
+		if ($page_id) {
426
+			$current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
427
+		}
428
+		// remove slashes and ?
429
+		$current_request_uri = trim($current_request_uri, '?/');
430
+		// is current request URI part of the known full reg page URL ?
431
+		return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
432
+	}
433
+
434
+
435
+
436
+	/**
437
+	 * @param WP_Query $wp_query
438
+	 * @return    void
439
+	 * @throws \EE_Error
440
+	 */
441
+	public static function init($wp_query)
442
+	{
443
+		EED_Single_Page_Checkout::instance()->run($wp_query);
444
+	}
445
+
446
+
447
+
448
+	/**
449
+	 *    _initialize - initial module setup
450
+	 *
451
+	 * @access    private
452
+	 * @throws EE_Error
453
+	 * @return    void
454
+	 */
455
+	private function _initialize()
456
+	{
457
+		// ensure SPCO doesn't run twice
458
+		if (EED_Single_Page_Checkout::$_initialized) {
459
+			return;
460
+		}
461
+		try {
462
+			EED_Single_Page_Checkout::load_reg_steps();
463
+			$this->_verify_session();
464
+			// setup the EE_Checkout object
465
+			$this->checkout = $this->_initialize_checkout();
466
+			// filter checkout
467
+			$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
468
+			// get the $_GET
469
+			$this->_get_request_vars();
470
+			if ($this->_block_bots()) {
471
+				return;
472
+			}
473
+			// filter continue_reg
474
+			$this->checkout->continue_reg = apply_filters('FHEE__EED_Single_Page_Checkout__init___continue_reg', true, $this->checkout);
475
+			// load the reg steps array
476
+			if ( ! $this->_load_and_instantiate_reg_steps()) {
477
+				EED_Single_Page_Checkout::$_initialized = true;
478
+				return;
479
+			}
480
+			// set the current step
481
+			$this->checkout->set_current_step($this->checkout->step);
482
+			// and the next step
483
+			$this->checkout->set_next_step();
484
+			// verify that everything has been setup correctly
485
+			if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
486
+				EED_Single_Page_Checkout::$_initialized = true;
487
+				return;
488
+			}
489
+			// lock the transaction
490
+			$this->checkout->transaction->lock();
491
+			// make sure all of our cached objects are added to their respective model entity mappers
492
+			$this->checkout->refresh_all_entities();
493
+			// set amount owing
494
+			$this->checkout->amount_owing = $this->checkout->transaction->remaining();
495
+			// initialize each reg step, which gives them the chance to potentially alter the process
496
+			$this->_initialize_reg_steps();
497
+			// DEBUG LOG
498
+			//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
499
+			// get reg form
500
+			if( ! $this->_check_form_submission()) {
501
+				EED_Single_Page_Checkout::$_initialized = true;
502
+				return;
503
+			}
504
+			// checkout the action!!!
505
+			$this->_process_form_action();
506
+			// add some style and make it dance
507
+			$this->add_styles_and_scripts();
508
+			// kk... SPCO has successfully run
509
+			EED_Single_Page_Checkout::$_initialized = true;
510
+			// set no cache headers and constants
511
+			EE_System::do_not_cache();
512
+			// add anchor
513
+			add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
514
+			// remove transaction lock
515
+			add_action('shutdown', array($this, 'unlock_transaction'), 1);
516
+		} catch (Exception $e) {
517
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
518
+		}
519
+	}
520
+
521
+
522
+
523
+	/**
524
+	 *    _verify_session
525
+	 * checks that the session is valid and not expired
526
+	 *
527
+	 * @access    private
528
+	 * @throws EE_Error
529
+	 */
530
+	private function _verify_session()
531
+	{
532
+		if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
533
+			throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
534
+		}
535
+		// is session still valid ?
536
+		if (EE_Registry::instance()->SSN->expired() && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '') {
537
+			$this->checkout = new EE_Checkout();
538
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
539
+			// EE_Registry::instance()->SSN->reset_cart();
540
+			// EE_Registry::instance()->SSN->reset_checkout();
541
+			// EE_Registry::instance()->SSN->reset_transaction();
542
+			EE_Error::add_attention(EE_Registry::$i18n_js_strings['registration_expiration_notice'], __FILE__,
543
+				__FUNCTION__, __LINE__);
544
+			// EE_Registry::instance()->SSN->reset_expired();
545
+		}
546
+	}
547
+
548
+
549
+
550
+	/**
551
+	 *    _initialize_checkout
552
+	 * loads and instantiates EE_Checkout
553
+	 *
554
+	 * @access    private
555
+	 * @throws EE_Error
556
+	 * @return EE_Checkout
557
+	 */
558
+	private function _initialize_checkout()
559
+	{
560
+		// look in session for existing checkout
561
+		/** @type EE_Checkout $checkout */
562
+		$checkout = EE_Registry::instance()->SSN->checkout();
563
+		// verify
564
+		if ( ! $checkout instanceof EE_Checkout) {
565
+			// instantiate EE_Checkout object for handling the properties of the current checkout process
566
+			$checkout = EE_Registry::instance()->load_file(SPCO_INC_PATH, 'EE_Checkout', 'class', array(), false);
567
+		} else {
568
+			if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
569
+				$this->unlock_transaction();
570
+				wp_safe_redirect($checkout->redirect_url);
571
+				exit();
572
+			}
573
+		}
574
+		$checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
575
+		// verify again
576
+		if ( ! $checkout instanceof EE_Checkout) {
577
+			throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
578
+		}
579
+		// reset anything that needs a clean slate for each request
580
+		$checkout->reset_for_current_request();
581
+		return $checkout;
582
+	}
583
+
584
+
585
+
586
+	/**
587
+	 *    _get_request_vars
588
+	 *
589
+	 * @access    private
590
+	 * @return    void
591
+	 * @throws \EE_Error
592
+	 */
593
+	private function _get_request_vars()
594
+	{
595
+		// load classes
596
+		EED_Single_Page_Checkout::load_request_handler();
597
+		//make sure this request is marked as belonging to EE
598
+		EE_Registry::instance()->REQ->set_espresso_page(true);
599
+		// which step is being requested ?
600
+		$this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
601
+		// which step is being edited ?
602
+		$this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
603
+		// and what we're doing on the current step
604
+		$this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
605
+		// timestamp
606
+		$this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
607
+		// returning to edit ?
608
+		$this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
609
+		// or some other kind of revisit ?
610
+		$this->checkout->revisit = filter_var(
611
+			EE_Registry::instance()->REQ->get('revisit', false),
612
+			FILTER_VALIDATE_BOOLEAN
613
+		);
614
+		// and whether or not to generate a reg form for this request
615
+		$this->checkout->generate_reg_form = filter_var(
616
+			EE_Registry::instance()->REQ->get('generate_reg_form', true),
617
+			FILTER_VALIDATE_BOOLEAN
618
+		);
619
+		// and whether or not to process a reg form submission for this request
620
+		$this->checkout->process_form_submission = filter_var(
621
+			EE_Registry::instance()->REQ->get(
622
+				'process_form_submission',
623
+				$this->checkout->action === 'process_reg_step'
624
+			),
625
+			FILTER_VALIDATE_BOOLEAN
626
+		);
627
+		$this->checkout->process_form_submission = filter_var(
628
+			$this->checkout->action !== 'display_spco_reg_step'
629
+				? $this->checkout->process_form_submission
630
+				: false,
631
+			FILTER_VALIDATE_BOOLEAN
632
+		);
633
+		// $this->_display_request_vars();
634
+	}
635
+
636
+
637
+
638
+	/**
639
+	 *  _display_request_vars
640
+	 *
641
+	 * @access    protected
642
+	 * @return    void
643
+	 */
644
+	protected function _display_request_vars()
645
+	{
646
+		if ( ! WP_DEBUG) {
647
+			return;
648
+		}
649
+		EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
650
+		EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
651
+		EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
652
+		EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
653
+		EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
654
+		EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
655
+		EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
656
+		EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
657
+	}
658
+
659
+
660
+
661
+	/**
662
+	 * _block_bots
663
+	 * checks that the incoming request has either of the following set:
664
+	 *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
665
+	 *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
666
+	 * so if you're not coming from the Ticket Selector nor returning for a valid IP...
667
+	 * then where you coming from man?
668
+	 *
669
+	 * @return boolean
670
+	 */
671
+	private function _block_bots()
672
+	{
673
+		$invalid_checkout_access = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
674
+		if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
675
+			return true;
676
+		}
677
+		return false;
678
+	}
679
+
680
+
681
+
682
+	/**
683
+	 *    _get_first_step
684
+	 *  gets slug for first step in $_reg_steps_array
685
+	 *
686
+	 * @access    private
687
+	 * @throws EE_Error
688
+	 * @return    string
689
+	 */
690
+	private function _get_first_step()
691
+	{
692
+		$first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
693
+		return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
694
+	}
695
+
696
+
697
+
698
+	/**
699
+	 *    _load_and_instantiate_reg_steps
700
+	 *  instantiates each reg step based on the loaded reg_steps array
701
+	 *
702
+	 * @access    private
703
+	 * @throws EE_Error
704
+	 * @return    bool
705
+	 */
706
+	private function _load_and_instantiate_reg_steps()
707
+	{
708
+		do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
709
+		// have reg_steps already been instantiated ?
710
+		if (
711
+			empty($this->checkout->reg_steps)
712
+			|| apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
713
+		) {
714
+			// if not, then loop through raw reg steps array
715
+			foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
716
+				if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
717
+					return false;
718
+				}
719
+			}
720
+			EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
721
+			EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
722
+			// skip the registration_confirmation page ?
723
+			if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
724
+				// just remove it from the reg steps array
725
+				$this->checkout->remove_reg_step('registration_confirmation', false);
726
+			} else if (
727
+				isset($this->checkout->reg_steps['registration_confirmation'])
728
+				&& EE_Registry::instance()->CFG->registration->reg_confirmation_last
729
+			) {
730
+				// set the order to something big like 100
731
+				$this->checkout->set_reg_step_order('registration_confirmation', 100);
732
+			}
733
+			// filter the array for good luck
734
+			$this->checkout->reg_steps = apply_filters(
735
+				'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
736
+				$this->checkout->reg_steps
737
+			);
738
+			// finally re-sort based on the reg step class order properties
739
+			$this->checkout->sort_reg_steps();
740
+		} else {
741
+			foreach ($this->checkout->reg_steps as $reg_step) {
742
+				// set all current step stati to FALSE
743
+				$reg_step->set_is_current_step(false);
744
+			}
745
+		}
746
+		if (empty($this->checkout->reg_steps)) {
747
+			EE_Error::add_error(__('No Reg Steps were loaded..', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
748
+			return false;
749
+		}
750
+		// make reg step details available to JS
751
+		$this->checkout->set_reg_step_JSON_info();
752
+		return true;
753
+	}
754
+
755
+
756
+
757
+	/**
758
+	 *     _load_and_instantiate_reg_step
759
+	 *
760
+	 * @access    private
761
+	 * @param array $reg_step
762
+	 * @param int   $order
763
+	 * @return bool
764
+	 */
765
+	private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
766
+	{
767
+		// we need a file_path, class_name, and slug to add a reg step
768
+		if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
769
+			// if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
770
+			if (
771
+				$this->checkout->reg_url_link
772
+				&& $this->checkout->step !== $reg_step['slug']
773
+				&& $reg_step['slug'] !== 'finalize_registration'
774
+				// normally at this point we would NOT load the reg step, but this filter can change that
775
+				&& apply_filters(
776
+					'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
777
+					true,
778
+					$reg_step,
779
+					$this->checkout
780
+				)
781
+			) {
782
+				return true;
783
+			}
784
+			// instantiate step class using file path and class name
785
+			$reg_step_obj = EE_Registry::instance()->load_file(
786
+				$reg_step['file_path'],
787
+				$reg_step['class_name'],
788
+				'class',
789
+				$this->checkout,
790
+				false
791
+			);
792
+			// did we gets the goods ?
793
+			if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
794
+				// set reg step order based on config
795
+				$reg_step_obj->set_order($order);
796
+				// add instantiated reg step object to the master reg steps array
797
+				$this->checkout->add_reg_step($reg_step_obj);
798
+			} else {
799
+				EE_Error::add_error(
800
+					__('The current step could not be set.', 'event_espresso'),
801
+					__FILE__, __FUNCTION__, __LINE__
802
+				);
803
+				return false;
804
+			}
805
+		} else {
806
+			if (WP_DEBUG) {
807
+				EE_Error::add_error(
808
+					sprintf(
809
+						__('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', 'event_espresso'),
810
+						isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
811
+						isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
812
+						isset($reg_step['slug']) ? $reg_step['slug'] : '',
813
+						'<ul>',
814
+						'<li>',
815
+						'</li>',
816
+						'</ul>'
817
+					),
818
+					__FILE__, __FUNCTION__, __LINE__
819
+				);
820
+			}
821
+			return false;
822
+		}
823
+		return true;
824
+	}
825
+
826
+
827
+
828
+	/**
829
+	 * _verify_transaction_and_get_registrations
830
+	 *
831
+	 * @access private
832
+	 * @return bool
833
+	 */
834
+	private function _verify_transaction_and_get_registrations()
835
+	{
836
+		// was there already a valid transaction in the checkout from the session ?
837
+		if ( ! $this->checkout->transaction instanceof EE_Transaction) {
838
+			// get transaction from db or session
839
+			$this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
840
+				? $this->_get_transaction_and_cart_for_previous_visit()
841
+				: $this->_get_cart_for_current_session_and_setup_new_transaction();
842
+			if ( ! $this->checkout->transaction instanceof EE_Transaction) {
843
+				EE_Error::add_error(
844
+					__('Your Registration and Transaction information could not be retrieved from the db.',
845
+						'event_espresso'),
846
+					__FILE__, __FUNCTION__, __LINE__
847
+				);
848
+				$this->checkout->transaction = EE_Transaction::new_instance();
849
+				// add some style and make it dance
850
+				$this->add_styles_and_scripts();
851
+				EED_Single_Page_Checkout::$_initialized = true;
852
+				return false;
853
+			}
854
+			// and the registrations for the transaction
855
+			$this->_get_registrations($this->checkout->transaction);
856
+		}
857
+		return true;
858
+	}
859
+
860
+
861
+
862
+	/**
863
+	 * _get_transaction_and_cart_for_previous_visit
864
+	 *
865
+	 * @access private
866
+	 * @return mixed EE_Transaction|NULL
867
+	 */
868
+	private function _get_transaction_and_cart_for_previous_visit()
869
+	{
870
+		/** @var $TXN_model EEM_Transaction */
871
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
872
+		// because the reg_url_link is present in the request, this is a return visit to SPCO, so we'll get the transaction data from the db
873
+		$transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
874
+		// verify transaction
875
+		if ($transaction instanceof EE_Transaction) {
876
+			// and get the cart that was used for that transaction
877
+			$this->checkout->cart = $this->_get_cart_for_transaction($transaction);
878
+			return $transaction;
879
+		} else {
880
+			EE_Error::add_error(__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
881
+			return null;
882
+		}
883
+	}
884
+
885
+
886
+
887
+	/**
888
+	 * _get_cart_for_transaction
889
+	 *
890
+	 * @access private
891
+	 * @param EE_Transaction $transaction
892
+	 * @return EE_Cart
893
+	 */
894
+	private function _get_cart_for_transaction($transaction)
895
+	{
896
+		return $this->checkout->get_cart_for_transaction($transaction);
897
+	}
898
+
899
+
900
+
901
+	/**
902
+	 * get_cart_for_transaction
903
+	 *
904
+	 * @access public
905
+	 * @param EE_Transaction $transaction
906
+	 * @return EE_Cart
907
+	 */
908
+	public function get_cart_for_transaction(EE_Transaction $transaction)
909
+	{
910
+		return $this->checkout->get_cart_for_transaction($transaction);
911
+	}
912
+
913
+
914
+
915
+	/**
916
+	 * _get_transaction_and_cart_for_current_session
917
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
918
+	 *
919
+	 * @access private
920
+	 * @return EE_Transaction
921
+	 * @throws \EE_Error
922
+	 */
923
+	private function _get_cart_for_current_session_and_setup_new_transaction()
924
+	{
925
+		//  if there's no transaction, then this is the FIRST visit to SPCO
926
+		// so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
927
+		$this->checkout->cart = $this->_get_cart_for_transaction(null);
928
+		// and then create a new transaction
929
+		$transaction = $this->_initialize_transaction();
930
+		// verify transaction
931
+		if ($transaction instanceof EE_Transaction) {
932
+			// save it so that we have an ID for other objects to use
933
+			$transaction->save();
934
+			// and save TXN data to the cart
935
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
936
+		} else {
937
+			EE_Error::add_error(__('A Valid Transaction could not be initialized.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
938
+		}
939
+		return $transaction;
940
+	}
941
+
942
+
943
+
944
+	/**
945
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
946
+	 *
947
+	 * @access private
948
+	 * @return mixed EE_Transaction|NULL
949
+	 */
950
+	private function _initialize_transaction()
951
+	{
952
+		try {
953
+			// ensure cart totals have been calculated
954
+			$this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
955
+			// grab the cart grand total
956
+			$cart_total = $this->checkout->cart->get_cart_grand_total();
957
+			// create new TXN
958
+			$transaction = EE_Transaction::new_instance(
959
+				array(
960
+					'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
961
+					'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
962
+					'TXN_paid'      => 0,
963
+					'STS_ID'        => EEM_Transaction::failed_status_code,
964
+				)
965
+			);
966
+			// save it so that we have an ID for other objects to use
967
+			$transaction->save();
968
+			// set cron job for following up on TXNs after their session has expired
969
+			EE_Cron_Tasks::schedule_expired_transaction_check(
970
+				EE_Registry::instance()->SSN->expiration() + 1,
971
+				$transaction->ID()
972
+			);
973
+			return $transaction;
974
+		} catch (Exception $e) {
975
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
976
+		}
977
+		return null;
978
+	}
979
+
980
+
981
+
982
+	/**
983
+	 * _get_registrations
984
+	 *
985
+	 * @access private
986
+	 * @param EE_Transaction $transaction
987
+	 * @return void
988
+	 * @throws \EventEspresso\core\exceptions\InvalidEntityException
989
+	 * @throws \EE_Error
990
+	 */
991
+	private function _get_registrations(EE_Transaction $transaction)
992
+	{
993
+		// first step: grab the registrants  { : o
994
+		$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
995
+		// verify registrations have been set
996
+		if (empty($registrations)) {
997
+			// if no cached registrations, then check the db
998
+			$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
999
+			// still nothing ? well as long as this isn't a revisit
1000
+			if (empty($registrations) && ! $this->checkout->revisit) {
1001
+				// generate new registrations from scratch
1002
+				$registrations = $this->_initialize_registrations($transaction);
1003
+			}
1004
+		}
1005
+		// sort by their original registration order
1006
+		usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1007
+		// then loop thru the array
1008
+		foreach ($registrations as $registration) {
1009
+			// verify each registration
1010
+			if ($registration instanceof EE_Registration) {
1011
+				// we display all attendee info for the primary registrant
1012
+				if ($this->checkout->reg_url_link === $registration->reg_url_link()
1013
+					&& $registration->is_primary_registrant()
1014
+				) {
1015
+					$this->checkout->primary_revisit = true;
1016
+					break;
1017
+				} else if ($this->checkout->revisit
1018
+						   && $this->checkout->reg_url_link !== $registration->reg_url_link()
1019
+				) {
1020
+					// but hide info if it doesn't belong to you
1021
+					$transaction->clear_cache('Registration', $registration->ID());
1022
+				}
1023
+				$this->checkout->set_reg_status_updated($registration->ID(), false);
1024
+			}
1025
+		}
1026
+	}
1027
+
1028
+
1029
+
1030
+	/**
1031
+	 *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1032
+	 *
1033
+	 * @access private
1034
+	 * @param EE_Transaction $transaction
1035
+	 * @return    array
1036
+	 * @throws \EventEspresso\core\exceptions\InvalidEntityException
1037
+	 * @throws \EE_Error
1038
+	 */
1039
+	private function _initialize_registrations(EE_Transaction $transaction)
1040
+	{
1041
+		$att_nmbr = 0;
1042
+		$registrations = array();
1043
+		if ($transaction instanceof EE_Transaction) {
1044
+			/** @type EE_Registration_Processor $registration_processor */
1045
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1046
+			$this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1047
+			// now let's add the cart items to the $transaction
1048
+			foreach ($this->checkout->cart->get_tickets() as $line_item) {
1049
+				//do the following for each ticket of this type they selected
1050
+				for ($x = 1; $x <= $line_item->quantity(); $x++) {
1051
+					$att_nmbr++;
1052
+					/** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1053
+					$CreateRegistrationCommand = EE_Registry::instance()
1054
+															->create(
1055
+																'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1056
+																array(
1057
+																	$transaction,
1058
+																	$line_item,
1059
+																	$att_nmbr,
1060
+																	$this->checkout->total_ticket_count,
1061
+																)
1062
+															);
1063
+					// override capabilities for frontend registrations
1064
+					if ( ! is_admin()) {
1065
+						$CreateRegistrationCommand->setCapCheck(
1066
+							new PublicCapabilities('', 'create_new_registration')
1067
+						);
1068
+					}
1069
+					$registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1070
+					if ( ! $registration instanceof EE_Registration) {
1071
+						throw new InvalidEntityException($registration, 'EE_Registration');
1072
+					}
1073
+					$registrations[ $registration->ID() ] = $registration;
1074
+				}
1075
+			}
1076
+			$registration_processor->fix_reg_final_price_rounding_issue($transaction);
1077
+		}
1078
+		return $registrations;
1079
+	}
1080
+
1081
+
1082
+
1083
+	/**
1084
+	 * sorts registrations by REG_count
1085
+	 *
1086
+	 * @access public
1087
+	 * @param EE_Registration $reg_A
1088
+	 * @param EE_Registration $reg_B
1089
+	 * @return int
1090
+	 */
1091
+	public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1092
+	{
1093
+		// this shouldn't ever happen within the same TXN, but oh well
1094
+		if ($reg_A->count() === $reg_B->count()) {
1095
+			return 0;
1096
+		}
1097
+		return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1098
+	}
1099
+
1100
+
1101
+
1102
+	/**
1103
+	 *    _final_verifications
1104
+	 * just makes sure that everything is set up correctly before proceeding
1105
+	 *
1106
+	 * @access    private
1107
+	 * @return    bool
1108
+	 * @throws \EE_Error
1109
+	 */
1110
+	private function _final_verifications()
1111
+	{
1112
+		// filter checkout
1113
+		$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout);
1114
+		//verify that current step is still set correctly
1115
+		if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1116
+			EE_Error::add_error(
1117
+				__('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'),
1118
+				__FILE__,
1119
+				__FUNCTION__,
1120
+				__LINE__
1121
+			);
1122
+			return false;
1123
+		}
1124
+		// if returning to SPCO, then verify that primary registrant is set
1125
+		if ( ! empty($this->checkout->reg_url_link)) {
1126
+			$valid_registrant = $this->checkout->transaction->primary_registration();
1127
+			if ( ! $valid_registrant instanceof EE_Registration) {
1128
+				EE_Error::add_error(
1129
+					__('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'),
1130
+					__FILE__,
1131
+					__FUNCTION__,
1132
+					__LINE__
1133
+				);
1134
+				return false;
1135
+			}
1136
+			$valid_registrant = null;
1137
+			foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) {
1138
+				if (
1139
+					$registration instanceof EE_Registration
1140
+					&& $registration->reg_url_link() === $this->checkout->reg_url_link
1141
+				) {
1142
+					$valid_registrant = $registration;
1143
+				}
1144
+			}
1145
+			if ( ! $valid_registrant instanceof EE_Registration) {
1146
+				// hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1147
+				if (EED_Single_Page_Checkout::$_checkout_verified) {
1148
+					// clear the session, mark the checkout as unverified, and try again
1149
+					EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1150
+					EED_Single_Page_Checkout::$_initialized = false;
1151
+					EED_Single_Page_Checkout::$_checkout_verified = false;
1152
+					$this->_initialize();
1153
+					EE_Error::reset_notices();
1154
+					return false;
1155
+				}
1156
+				EE_Error::add_error(
1157
+					__('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.', 'event_espresso'),
1158
+					__FILE__,
1159
+					__FUNCTION__,
1160
+					__LINE__
1161
+				);
1162
+				return false;
1163
+			}
1164
+		}
1165
+		// now that things have been kinda sufficiently verified,
1166
+		// let's add the checkout to the session so that it's available to other systems
1167
+		EE_Registry::instance()->SSN->set_checkout($this->checkout);
1168
+		return true;
1169
+	}
1170
+
1171
+
1172
+
1173
+	/**
1174
+	 *    _initialize_reg_steps
1175
+	 * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1176
+	 * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1177
+	 *
1178
+	 * @access    private
1179
+	 * @param bool $reinitializing
1180
+	 * @throws \EE_Error
1181
+	 */
1182
+	private function _initialize_reg_steps($reinitializing = false)
1183
+	{
1184
+		$this->checkout->set_reg_step_initiated($this->checkout->current_step);
1185
+		// loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1186
+		foreach ($this->checkout->reg_steps as $reg_step) {
1187
+			if ( ! $reg_step->initialize_reg_step()) {
1188
+				// if not initialized then maybe this step is being removed...
1189
+				if ( ! $reinitializing && $reg_step->is_current_step()) {
1190
+					// if it was the current step, then we need to start over here
1191
+					$this->_initialize_reg_steps(true);
1192
+					return;
1193
+				}
1194
+				continue;
1195
+			}
1196
+			// add css and JS for current step
1197
+			$reg_step->enqueue_styles_and_scripts();
1198
+			// i18n
1199
+			$reg_step->translate_js_strings();
1200
+			if ($reg_step->is_current_step()) {
1201
+				// the text that appears on the reg step form submit button
1202
+				$reg_step->set_submit_button_text();
1203
+			}
1204
+		}
1205
+		// dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1206
+		do_action("AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", $this->checkout->current_step);
1207
+	}
1208
+
1209
+
1210
+
1211
+	/**
1212
+	 * _check_form_submission
1213
+	 *
1214
+	 * @access private
1215
+	 * @return boolean
1216
+	 */
1217
+	private function _check_form_submission()
1218
+	{
1219
+		//does this request require the reg form to be generated ?
1220
+		if ($this->checkout->generate_reg_form) {
1221
+			// ever heard that song by Blue Rodeo ?
1222
+			try {
1223
+				$this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1224
+				// if not displaying a form, then check for form submission
1225
+				if (
1226
+					$this->checkout->process_form_submission
1227
+					&& $this->checkout->current_step->reg_form->was_submitted()
1228
+				) {
1229
+					// clear out any old data in case this step is being run again
1230
+					$this->checkout->current_step->set_valid_data(array());
1231
+					// capture submitted form data
1232
+					$this->checkout->current_step->reg_form->receive_form_submission(
1233
+						apply_filters(
1234
+							'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1235
+							EE_Registry::instance()->REQ->params(),
1236
+							$this->checkout
1237
+						)
1238
+					);
1239
+					// validate submitted form data
1240
+					if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1241
+						// thou shall not pass !!!
1242
+						$this->checkout->continue_reg = false;
1243
+						// any form validation errors?
1244
+						if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1245
+							$submission_error_messages = array();
1246
+							// bad, bad, bad registrant
1247
+							foreach ($this->checkout->current_step->reg_form->get_validation_errors_accumulated() as $validation_error) {
1248
+								if ($validation_error instanceof EE_Validation_Error) {
1249
+									$submission_error_messages[] = sprintf(
1250
+										__('%s : %s', 'event_espresso'),
1251
+										$validation_error->get_form_section()->html_label_text(),
1252
+										$validation_error->getMessage()
1253
+									);
1254
+								}
1255
+							}
1256
+							EE_Error::add_error(implode('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__);
1257
+						}
1258
+						// well not really... what will happen is we'll just get redirected back to redo the current step
1259
+						$this->go_to_next_step();
1260
+						return false;
1261
+					}
1262
+				}
1263
+			} catch (EE_Error $e) {
1264
+				$e->get_error();
1265
+			}
1266
+		}
1267
+		return true;
1268
+	}
1269
+
1270
+
1271
+
1272
+	/**
1273
+	 * _process_action
1274
+	 *
1275
+	 * @access private
1276
+	 * @return void
1277
+	 * @throws \EE_Error
1278
+	 */
1279
+	private function _process_form_action()
1280
+	{
1281
+		// what cha wanna do?
1282
+		switch ($this->checkout->action) {
1283
+			// AJAX next step reg form
1284
+			case 'display_spco_reg_step' :
1285
+				$this->checkout->redirect = false;
1286
+				if (EE_Registry::instance()->REQ->ajax) {
1287
+					$this->checkout->json_response->set_reg_step_html($this->checkout->current_step->display_reg_form());
1288
+				}
1289
+				break;
1290
+			default :
1291
+				// meh... do one of those other steps first
1292
+				if ( ! empty($this->checkout->action) && is_callable(array($this->checkout->current_step, $this->checkout->action))) {
1293
+					// dynamically creates hook point like: AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1294
+					do_action("AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1295
+					// call action on current step
1296
+					if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1297
+						// good registrant, you get to proceed
1298
+						if (
1299
+							$this->checkout->current_step->success_message() !== ''
1300
+							&& apply_filters(
1301
+								'FHEE__Single_Page_Checkout___process_form_action__display_success',
1302
+								false
1303
+							)
1304
+						) {
1305
+							EE_Error::add_success(
1306
+								$this->checkout->current_step->success_message()
1307
+								. '<br />' . $this->checkout->next_step->_instructions()
1308
+							);
1309
+						}
1310
+						// pack it up, pack it in...
1311
+						$this->_setup_redirect();
1312
+					}
1313
+					// dynamically creates hook point like: AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1314
+					do_action("AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1315
+				} else {
1316
+					EE_Error::add_error(
1317
+						sprintf(
1318
+							__('The requested form action "%s" does not exist for the current "%s" registration step.', 'event_espresso'),
1319
+							$this->checkout->action,
1320
+							$this->checkout->current_step->name()
1321
+						),
1322
+						__FILE__,
1323
+						__FUNCTION__,
1324
+						__LINE__
1325
+					);
1326
+				}
1327
+			// end default
1328
+		}
1329
+		// store our progress so far
1330
+		$this->checkout->stash_transaction_and_checkout();
1331
+		// advance to the next step! If you pass GO, collect $200
1332
+		$this->go_to_next_step();
1333
+	}
1334
+
1335
+
1336
+
1337
+	/**
1338
+	 *        add_styles_and_scripts
1339
+	 *
1340
+	 * @access        public
1341
+	 * @return        void
1342
+	 */
1343
+	public function add_styles_and_scripts()
1344
+	{
1345
+		// i18n
1346
+		$this->translate_js_strings();
1347
+		if ($this->checkout->admin_request) {
1348
+			add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1349
+		} else {
1350
+			add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1351
+		}
1352
+	}
1353
+
1354
+
1355
+
1356
+	/**
1357
+	 *        translate_js_strings
1358
+	 *
1359
+	 * @access        public
1360
+	 * @return        void
1361
+	 */
1362
+	public function translate_js_strings()
1363
+	{
1364
+		EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1365
+		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1366
+		EE_Registry::$i18n_js_strings['server_error'] = __('An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso');
1367
+		EE_Registry::$i18n_js_strings['invalid_json_response'] = __('An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso');
1368
+		EE_Registry::$i18n_js_strings['validation_error'] = __('There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', 'event_espresso');
1369
+		EE_Registry::$i18n_js_strings['invalid_payment_method'] = __('There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', 'event_espresso');
1370
+		EE_Registry::$i18n_js_strings['reg_step_error'] = __('This registration step could not be completed. Please refresh the page and try again.', 'event_espresso');
1371
+		EE_Registry::$i18n_js_strings['invalid_coupon'] = __('We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', 'event_espresso');
1372
+		EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1373
+			__('Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', 'event_espresso'),
1374
+			'<br/>',
1375
+			'<br/>'
1376
+		);
1377
+		EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1378
+		EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1379
+		EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1380
+		EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1381
+		EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1382
+		EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1383
+		EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1384
+		EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1385
+		EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1386
+		EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1387
+		EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1388
+		EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1389
+		EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1390
+		EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1391
+		EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1392
+		EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1393
+		EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1394
+		EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1395
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1396
+			__(
1397
+				'%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',
1398
+				'event_espresso'
1399
+			),
1400
+			'<h4 class="important-notice">',
1401
+			'</h4>',
1402
+			'<br />',
1403
+			'<p>',
1404
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1405
+			'">',
1406
+			'</a>',
1407
+			'</p>'
1408
+		);
1409
+		EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters('FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', true);
1410
+		EE_Registry::$i18n_js_strings['session_extension'] = absint(
1411
+			apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1412
+		);
1413
+		EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1414
+			'M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1415
+		);
1416
+	}
1417
+
1418
+
1419
+
1420
+	/**
1421
+	 *    enqueue_styles_and_scripts
1422
+	 *
1423
+	 * @access        public
1424
+	 * @return        void
1425
+	 * @throws \EE_Error
1426
+	 */
1427
+	public function enqueue_styles_and_scripts()
1428
+	{
1429
+		// load css
1430
+		wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1431
+		wp_enqueue_style('single_page_checkout');
1432
+		// load JS
1433
+		wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1434
+		wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1435
+		wp_register_script('single_page_checkout', SPCO_JS_URL . 'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true);
1436
+		if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1437
+			$this->checkout->registration_form->enqueue_js();
1438
+		}
1439
+		if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1440
+			$this->checkout->current_step->reg_form->enqueue_js();
1441
+		}
1442
+		wp_enqueue_script('single_page_checkout');
1443
+		/**
1444
+		 * global action hook for enqueueing styles and scripts with
1445
+		 * spco calls.
1446
+		 */
1447
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1448
+		/**
1449
+		 * dynamic action hook for enqueueing styles and scripts with spco calls.
1450
+		 * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1451
+		 */
1452
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this);
1453
+	}
1454
+
1455
+
1456
+
1457
+	/**
1458
+	 *    display the Registration Single Page Checkout Form
1459
+	 *
1460
+	 * @access    private
1461
+	 * @return    void
1462
+	 * @throws \EE_Error
1463
+	 */
1464
+	private function _display_spco_reg_form()
1465
+	{
1466
+		// if registering via the admin, just display the reg form for the current step
1467
+		if ($this->checkout->admin_request) {
1468
+			EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1469
+		} else {
1470
+			// add powered by EE msg
1471
+			add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1472
+			$empty_cart = count($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)) < 1
1473
+				? true
1474
+				: false;
1475
+			EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1476
+			$cookies_not_set_msg = '';
1477
+			if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1478
+				$cookies_not_set_msg = apply_filters(
1479
+					'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1480
+					sprintf(
1481
+						__(
1482
+							'%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',
1483
+							'event_espresso'
1484
+						),
1485
+						'<div class="ee-attention">',
1486
+						'</div>',
1487
+						'<h6 class="important-notice">',
1488
+						'</h6>',
1489
+						'<p>',
1490
+						'</p>',
1491
+						'<br />',
1492
+						'<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1493
+						'</a>'
1494
+					)
1495
+				);
1496
+			}
1497
+			$this->checkout->registration_form = new EE_Form_Section_Proper(
1498
+				array(
1499
+					'name'            => 'single-page-checkout',
1500
+					'html_id'         => 'ee-single-page-checkout-dv',
1501
+					'layout_strategy' =>
1502
+						new EE_Template_Layout(
1503
+							array(
1504
+								'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1505
+								'template_args'        => array(
1506
+									'empty_cart'              => $empty_cart,
1507
+									'revisit'                 => $this->checkout->revisit,
1508
+									'reg_steps'               => $this->checkout->reg_steps,
1509
+									'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1510
+										? $this->checkout->next_step->slug()
1511
+										: '',
1512
+									'cancel_page_url'         => $this->checkout->cancel_page_url,
1513
+									'empty_msg'               => apply_filters(
1514
+										'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1515
+										sprintf(
1516
+											__('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1517
+												'event_espresso'),
1518
+											'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1519
+											'">',
1520
+											'</a>'
1521
+										)
1522
+									),
1523
+									'cookies_not_set_msg'     => $cookies_not_set_msg,
1524
+									'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1525
+									'session_expiration'      => gmdate(
1526
+										'M d, Y H:i:s',
1527
+										EE_Registry::instance()->SSN->expiration()
1528
+										+ (get_option('gmt_offset') * HOUR_IN_SECONDS)
1529
+									),
1530
+								),
1531
+							)
1532
+						),
1533
+				)
1534
+			);
1535
+			// load template and add to output sent that gets filtered into the_content()
1536
+			EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1537
+		}
1538
+	}
1539
+
1540
+
1541
+
1542
+	/**
1543
+	 *    add_extra_finalize_registration_inputs
1544
+	 *
1545
+	 * @access    public
1546
+	 * @param $next_step
1547
+	 * @internal  param string $label
1548
+	 * @return void
1549
+	 */
1550
+	public function add_extra_finalize_registration_inputs($next_step)
1551
+	{
1552
+		if ($next_step === 'finalize_registration') {
1553
+			echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1554
+		}
1555
+	}
1556
+
1557
+
1558
+
1559
+	/**
1560
+	 *    display_registration_footer
1561
+	 *
1562
+	 * @access    public
1563
+	 * @return    string
1564
+	 */
1565
+	public static function display_registration_footer()
1566
+	{
1567
+		if (
1568
+		apply_filters(
1569
+			'FHEE__EE_Front__Controller__show_reg_footer',
1570
+			EE_Registry::instance()->CFG->admin->show_reg_footer
1571
+		)
1572
+		) {
1573
+			add_filter(
1574
+				'FHEE__EEH_Template__powered_by_event_espresso__url',
1575
+				function ($url) {
1576
+					return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1577
+				}
1578
+			);
1579
+			echo apply_filters(
1580
+				'FHEE__EE_Front_Controller__display_registration_footer',
1581
+				\EEH_Template::powered_by_event_espresso(
1582
+					'',
1583
+					'espresso-registration-footer-dv',
1584
+					array('utm_content' => 'registration_checkout')
1585
+				)
1586
+			);
1587
+		}
1588
+		return '';
1589
+	}
1590
+
1591
+
1592
+
1593
+	/**
1594
+	 *    unlock_transaction
1595
+	 *
1596
+	 * @access    public
1597
+	 * @return    void
1598
+	 * @throws \EE_Error
1599
+	 */
1600
+	public function unlock_transaction()
1601
+	{
1602
+		if ($this->checkout->transaction instanceof EE_Transaction) {
1603
+			$this->checkout->transaction->unlock();
1604
+		}
1605
+	}
1606
+
1607
+
1608
+
1609
+	/**
1610
+	 *        _setup_redirect
1611
+	 *
1612
+	 * @access    private
1613
+	 * @return void
1614
+	 */
1615
+	private function _setup_redirect()
1616
+	{
1617
+		if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1618
+			$this->checkout->redirect = true;
1619
+			if (empty($this->checkout->redirect_url)) {
1620
+				$this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1621
+			}
1622
+			$this->checkout->redirect_url = apply_filters(
1623
+				'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1624
+				$this->checkout->redirect_url,
1625
+				$this->checkout
1626
+			);
1627
+		}
1628
+	}
1629
+
1630
+
1631
+
1632
+	/**
1633
+	 *   handle ajax message responses and redirects
1634
+	 *
1635
+	 * @access public
1636
+	 * @return void
1637
+	 * @throws \EE_Error
1638
+	 */
1639
+	public function go_to_next_step()
1640
+	{
1641
+		if (EE_Registry::instance()->REQ->ajax) {
1642
+			// capture contents of output buffer we started earlier in the request, and insert into JSON response
1643
+			$this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1644
+		}
1645
+		$this->unlock_transaction();
1646
+		// just return for these conditions
1647
+		if (
1648
+			$this->checkout->admin_request
1649
+			|| $this->checkout->action === 'redirect_form'
1650
+			|| $this->checkout->action === 'update_checkout'
1651
+		) {
1652
+			return;
1653
+		}
1654
+		// AJAX response
1655
+		$this->_handle_json_response();
1656
+		// redirect to next step or the Thank You page
1657
+		$this->_handle_html_redirects();
1658
+		// hmmm... must be something wrong, so let's just display the form again !
1659
+		$this->_display_spco_reg_form();
1660
+	}
1661
+
1662
+
1663
+
1664
+	/**
1665
+	 *   _handle_json_response
1666
+	 *
1667
+	 * @access protected
1668
+	 * @return void
1669
+	 */
1670
+	protected function _handle_json_response()
1671
+	{
1672
+		// if this is an ajax request
1673
+		if (EE_Registry::instance()->REQ->ajax) {
1674
+			// DEBUG LOG
1675
+			//$this->checkout->log(
1676
+			//	__CLASS__, __FUNCTION__, __LINE__,
1677
+			//	array(
1678
+			//		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1679
+			//		'redirect'                   => $this->checkout->redirect,
1680
+			//		'continue_reg'               => $this->checkout->continue_reg,
1681
+			//	)
1682
+			//);
1683
+			$this->checkout->json_response->set_registration_time_limit(
1684
+				$this->checkout->get_registration_time_limit()
1685
+			);
1686
+			$this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1687
+			// just send the ajax (
1688
+			$json_response = apply_filters(
1689
+				'FHEE__EE_Single_Page_Checkout__JSON_response',
1690
+				$this->checkout->json_response
1691
+			);
1692
+			echo $json_response;
1693
+			exit();
1694
+		}
1695
+	}
1696
+
1697
+
1698
+
1699
+	/**
1700
+	 *   _handle_redirects
1701
+	 *
1702
+	 * @access protected
1703
+	 * @return void
1704
+	 */
1705
+	protected function _handle_html_redirects()
1706
+	{
1707
+		// going somewhere ?
1708
+		if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1709
+			// store notices in a transient
1710
+			EE_Error::get_notices(false, true, true);
1711
+			// DEBUG LOG
1712
+			//$this->checkout->log(
1713
+			//	__CLASS__, __FUNCTION__, __LINE__,
1714
+			//	array(
1715
+			//		'headers_sent' => headers_sent(),
1716
+			//		'redirect_url'     => $this->checkout->redirect_url,
1717
+			//		'headers_list'    => headers_list(),
1718
+			//	)
1719
+			//);
1720
+			wp_safe_redirect($this->checkout->redirect_url);
1721
+			exit();
1722
+		}
1723
+	}
1724
+
1725
+
1726
+
1727
+	/**
1728
+	 *   set_checkout_anchor
1729
+	 *
1730
+	 * @access public
1731
+	 * @return void
1732
+	 */
1733
+	public function set_checkout_anchor()
1734
+	{
1735
+		echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1736
+	}
1737 1737
 
1738 1738
 
1739 1739
 
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.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -285,13 +285,13 @@  discard block
 block discarded – undo
285 285
      */
286 286
     public static function localize_i18n_js_strings()
287 287
     {
288
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
288
+        $i18n_js_strings = (array) EE_Registry::$i18n_js_strings;
289 289
         foreach ($i18n_js_strings as $key => $value) {
290 290
             if (is_scalar($value)) {
291
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
291
+                $i18n_js_strings[$key] = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
292 292
             }
293 293
         }
294
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
294
+        return "/* <![CDATA[ */ var eei18n = ".wp_json_encode($i18n_js_strings).'; /* ]]> */';
295 295
     }
296 296
 
297 297
 
@@ -342,9 +342,9 @@  discard block
 block discarded – undo
342 342
                 EE_CORE,
343 343
                 EE_ADMIN,
344 344
                 EE_CPTS,
345
-                EE_CORE . 'data_migration_scripts' . DS,
346
-                EE_CORE . 'request_stack' . DS,
347
-                EE_CORE . 'middleware' . DS,
345
+                EE_CORE.'data_migration_scripts'.DS,
346
+                EE_CORE.'request_stack'.DS,
347
+                EE_CORE.'middleware'.DS,
348 348
             )
349 349
         );
350 350
         // retrieve instantiated class
@@ -367,7 +367,7 @@  discard block
 block discarded – undo
367 367
         $service_paths = apply_filters(
368 368
             'FHEE__EE_Registry__load_service__service_paths',
369 369
             array(
370
-                EE_CORE . 'services' . DS,
370
+                EE_CORE.'services'.DS,
371 371
             )
372 372
         );
373 373
         // retrieve instantiated class
@@ -447,10 +447,10 @@  discard block
 block discarded – undo
447 447
     {
448 448
         $paths = array(
449 449
             EE_LIBRARIES,
450
-            EE_LIBRARIES . 'messages' . DS,
451
-            EE_LIBRARIES . 'shortcodes' . DS,
452
-            EE_LIBRARIES . 'qtips' . DS,
453
-            EE_LIBRARIES . 'payment_methods' . DS,
450
+            EE_LIBRARIES.'messages'.DS,
451
+            EE_LIBRARIES.'shortcodes'.DS,
452
+            EE_LIBRARIES.'qtips'.DS,
453
+            EE_LIBRARIES.'payment_methods'.DS,
454 454
         );
455 455
         // retrieve instantiated class
456 456
         return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
@@ -489,10 +489,10 @@  discard block
 block discarded – undo
489 489
     public function load_model_class($class_name, $arguments = array(), $load_only = true)
490 490
     {
491 491
         $paths = array(
492
-            EE_MODELS . 'fields' . DS,
493
-            EE_MODELS . 'helpers' . DS,
494
-            EE_MODELS . 'relations' . DS,
495
-            EE_MODELS . 'strategies' . DS,
492
+            EE_MODELS.'fields'.DS,
493
+            EE_MODELS.'helpers'.DS,
494
+            EE_MODELS.'relations'.DS,
495
+            EE_MODELS.'strategies'.DS,
496 496
         );
497 497
         // retrieve instantiated class
498 498
         return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
@@ -578,7 +578,7 @@  discard block
 block discarded – undo
578 578
         $class_name = $this->_dependency_map->get_alias($class_name);
579 579
         if ( ! class_exists($class_name)) {
580 580
             // maybe the class is registered with a preceding \
581
-            $class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
581
+            $class_name = strpos($class_name, '\\') !== 0 ? '\\'.$class_name : $class_name;
582 582
             // still doesn't exist ?
583 583
             if ( ! class_exists($class_name)) {
584 584
                 return null;
@@ -644,7 +644,7 @@  discard block
 block discarded – undo
644 644
             // make sure $class_prefix is uppercase
645 645
             $class_prefix = strtoupper(trim($class_prefix));
646 646
             // add class prefix ONCE!!!
647
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
647
+            $class_name = $class_prefix.str_replace($class_prefix, '', $class_name);
648 648
         }
649 649
         $class_name = $this->_dependency_map->get_alias($class_name);
650 650
         $class_exists = class_exists($class_name);
@@ -744,9 +744,9 @@  discard block
 block discarded – undo
744 744
             // convert all separators to proper DS, if no filepath, then use EE_CLASSES
745 745
             $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
746 746
             // prep file type
747
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
747
+            $type = ! empty($type) ? trim($type, '.').'.' : '';
748 748
             // build full file path
749
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
749
+            $file_paths[$key] = rtrim($file_path, DS).DS.$class_name.'.'.$type.'php';
750 750
             //does the file exist and can be read ?
751 751
             if (is_readable($file_paths[$key])) {
752 752
                 return $file_paths[$key];
@@ -777,12 +777,12 @@  discard block
 block discarded – undo
777 777
             //does the file exist and can it be read ?
778 778
             if ( ! $path) {
779 779
                 // so sorry, can't find the file
780
-                throw new EE_Error (
780
+                throw new EE_Error(
781 781
                     sprintf(
782 782
                         __('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'),
783 783
                         trim($type, '.'),
784 784
                         $class_name,
785
-                        '<br />' . implode(',<br />', $file_paths)
785
+                        '<br />'.implode(',<br />', $file_paths)
786 786
                     )
787 787
                 );
788 788
             }
Please login to merge, or discard this patch.
Indentation   +1338 added lines, -1338 removed lines patch added patch discarded remove patch
@@ -16,1374 +16,1374 @@
 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
-     *    $addons - StdClass object for holding addons which have registered themselves to work with EE core
118
-     *
119
-     * @access    public
120
-     * @var    EE_Addon[]
121
-     */
122
-    public $addons = null;
123
-
124
-    /**
125
-     *    $models
126
-     * @access    public
127
-     * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
128
-     */
129
-    public $models = array();
130
-
131
-    /**
132
-     *    $modules
133
-     * @access    public
134
-     * @var    EED_Module[] $modules
135
-     */
136
-    public $modules = null;
137
-
138
-    /**
139
-     *    $shortcodes
140
-     * @access    public
141
-     * @var    EES_Shortcode[] $shortcodes
142
-     */
143
-    public $shortcodes = null;
144
-
145
-    /**
146
-     *    $widgets
147
-     * @access    public
148
-     * @var    WP_Widget[] $widgets
149
-     */
150
-    public $widgets = null;
151
-
152
-    /**
153
-     * $non_abstract_db_models
154
-     * @access public
155
-     * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
156
-     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
157
-     * Keys are model "short names" (eg "Event") as used in model relations, and values are
158
-     * classnames (eg "EEM_Event")
159
-     */
160
-    public $non_abstract_db_models = array();
161
-
162
-
163
-    /**
164
-     *    $i18n_js_strings - internationalization for JS strings
165
-     *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
166
-     *    in js file:  var translatedString = eei18n.string_key;
167
-     *
168
-     * @access    public
169
-     * @var    array
170
-     */
171
-    public static $i18n_js_strings = array();
172
-
173
-
174
-    /**
175
-     *    $main_file - path to espresso.php
176
-     *
177
-     * @access    public
178
-     * @var    array
179
-     */
180
-    public $main_file;
181
-
182
-    /**
183
-     * array of ReflectionClass objects where the key is the class name
184
-     *
185
-     * @access    public
186
-     * @var ReflectionClass[]
187
-     */
188
-    public $_reflectors;
189
-
190
-    /**
191
-     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
192
-     *
193
-     * @access    protected
194
-     * @var boolean $_cache_on
195
-     */
196
-    protected $_cache_on = true;
197
-
198
-
199
-
200
-    /**
201
-     * @singleton method used to instantiate class object
202
-     * @access    public
203
-     * @param  \EE_Dependency_Map $dependency_map
204
-     * @return \EE_Registry instance
205
-     */
206
-    public static function instance(\EE_Dependency_Map $dependency_map = null)
207
-    {
208
-        // check if class object is instantiated
209
-        if ( ! self::$_instance instanceof EE_Registry) {
210
-            self::$_instance = new EE_Registry($dependency_map);
211
-        }
212
-        return self::$_instance;
213
-    }
214
-
215
-
216
-
217
-    /**
218
-     *protected constructor to prevent direct creation
219
-     *
220
-     * @Constructor
221
-     * @access protected
222
-     * @param  \EE_Dependency_Map $dependency_map
223
-     * @return \EE_Registry
224
-     */
225
-    protected function __construct(\EE_Dependency_Map $dependency_map)
226
-    {
227
-        $this->_dependency_map = $dependency_map;
228
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
229
-    }
230
-
231
-
232
-
233
-    /**
234
-     * initialize
235
-     */
236
-    public function initialize()
237
-    {
238
-        $this->_class_abbreviations = apply_filters(
239
-            'FHEE__EE_Registry____construct___class_abbreviations',
240
-            array(
241
-                'EE_Config'                                       => 'CFG',
242
-                'EE_Session'                                      => 'SSN',
243
-                'EE_Capabilities'                                 => 'CAP',
244
-                'EE_Cart'                                         => 'CART',
245
-                'EE_Network_Config'                               => 'NET_CFG',
246
-                'EE_Request_Handler'                              => 'REQ',
247
-                'EE_Message_Resource_Manager'                     => 'MRM',
248
-                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
249
-            )
250
-        );
251
-        // class library
252
-        $this->LIB = new stdClass();
253
-        $this->addons = new stdClass();
254
-        $this->modules = new stdClass();
255
-        $this->shortcodes = new stdClass();
256
-        $this->widgets = new stdClass();
257
-        $this->load_core('Base', array(), true);
258
-        // add our request and response objects to the cache
259
-        $request_loader = $this->_dependency_map->class_loader('EE_Request');
260
-        $this->_set_cached_class(
261
-            $request_loader(),
262
-            'EE_Request'
263
-        );
264
-        $response_loader = $this->_dependency_map->class_loader('EE_Response');
265
-        $this->_set_cached_class(
266
-            $response_loader(),
267
-            'EE_Response'
268
-        );
269
-        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
270
-    }
271
-
272
-
273
-
274
-    /**
275
-     *    init
276
-     *
277
-     * @access    public
278
-     * @return    void
279
-     */
280
-    public function init()
281
-    {
282
-        $this->AssetsRegistry = new Registry();
283
-        // Get current page protocol
284
-        $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
285
-        // Output admin-ajax.php URL with same protocol as current page
286
-        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
287
-        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
288
-    }
289
-
290
-
291
-
292
-    /**
293
-     * localize_i18n_js_strings
294
-     *
295
-     * @return string
296
-     */
297
-    public static function localize_i18n_js_strings()
298
-    {
299
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
300
-        foreach ($i18n_js_strings as $key => $value) {
301
-            if (is_scalar($value)) {
302
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
303
-            }
304
-        }
305
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
306
-    }
307
-
308
-
309
-
310
-    /**
311
-     * @param mixed string | EED_Module $module
312
-     */
313
-    public function add_module($module)
314
-    {
315
-        if ($module instanceof EED_Module) {
316
-            $module_class = get_class($module);
317
-            $this->modules->{$module_class} = $module;
318
-        } else {
319
-            if ( ! class_exists('EE_Module_Request_Router')) {
320
-                $this->load_core('Module_Request_Router');
321
-            }
322
-            $this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
323
-        }
324
-    }
325
-
326
-
327
-
328
-    /**
329
-     * @param string $module_name
330
-     * @return mixed EED_Module | NULL
331
-     */
332
-    public function get_module($module_name = '')
333
-    {
334
-        return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
335
-    }
336
-
337
-
338
-
339
-    /**
340
-     *    loads core classes - must be singletons
341
-     *
342
-     * @access    public
343
-     * @param string $class_name - simple class name ie: session
344
-     * @param mixed  $arguments
345
-     * @param bool   $load_only
346
-     * @return mixed
347
-     */
348
-    public function load_core($class_name, $arguments = array(), $load_only = false)
349
-    {
350
-        $core_paths = apply_filters(
351
-            'FHEE__EE_Registry__load_core__core_paths',
352
-            array(
353
-                EE_CORE,
354
-                EE_ADMIN,
355
-                EE_CPTS,
356
-                EE_CORE . 'data_migration_scripts' . DS,
357
-                EE_CORE . 'request_stack' . DS,
358
-                EE_CORE . 'middleware' . DS,
359
-            )
360
-        );
361
-        // retrieve instantiated class
362
-        return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     *    loads service classes
369
-     *
370
-     * @access    public
371
-     * @param string $class_name - simple class name ie: session
372
-     * @param mixed  $arguments
373
-     * @param bool   $load_only
374
-     * @return mixed
375
-     */
376
-    public function load_service($class_name, $arguments = array(), $load_only = false)
377
-    {
378
-        $service_paths = apply_filters(
379
-            'FHEE__EE_Registry__load_service__service_paths',
380
-            array(
381
-                EE_CORE . 'services' . DS,
382
-            )
383
-        );
384
-        // retrieve instantiated class
385
-        return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
386
-    }
387
-
388
-
389
-
390
-    /**
391
-     *    loads data_migration_scripts
392
-     *
393
-     * @access    public
394
-     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
395
-     * @param mixed  $arguments
396
-     * @return EE_Data_Migration_Script_Base|mixed
397
-     */
398
-    public function load_dms($class_name, $arguments = array())
399
-    {
400
-        // retrieve instantiated class
401
-        return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
402
-    }
403
-
404
-
405
-
406
-    /**
407
-     *    loads object creating classes - must be singletons
408
-     *
409
-     * @param string $class_name - simple class name ie: attendee
410
-     * @param mixed  $arguments  - an array of arguments to pass to the class
411
-     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
412
-     * @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)
413
-     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
414
-     * @return EE_Base_Class | bool
415
-     */
416
-    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
417
-    {
418
-        $paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
419
-            EE_CORE,
420
-            EE_CLASSES,
421
-            EE_BUSINESS,
422
-        ));
423
-        // retrieve instantiated class
424
-        return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
425
-    }
426
-
427
-
428
-
429
-    /**
430
-     *    loads helper classes - must be singletons
431
-     *
432
-     * @param string $class_name - simple class name ie: price
433
-     * @param mixed  $arguments
434
-     * @param bool   $load_only
435
-     * @return EEH_Base | bool
436
-     */
437
-    public function load_helper($class_name, $arguments = array(), $load_only = true)
438
-    {
439
-        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
440
-        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
441
-        // retrieve instantiated class
442
-        return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     *    loads core classes - must be singletons
449
-     *
450
-     * @access    public
451
-     * @param string $class_name - simple class name ie: session
452
-     * @param mixed  $arguments
453
-     * @param bool   $load_only
454
-     * @param bool   $cache      whether to cache the object or not.
455
-     * @return mixed
456
-     */
457
-    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
458
-    {
459
-        $paths = array(
460
-            EE_LIBRARIES,
461
-            EE_LIBRARIES . 'messages' . DS,
462
-            EE_LIBRARIES . 'shortcodes' . DS,
463
-            EE_LIBRARIES . 'qtips' . DS,
464
-            EE_LIBRARIES . 'payment_methods' . DS,
465
-        );
466
-        // retrieve instantiated class
467
-        return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
468
-    }
469
-
470
-
471
-
472
-    /**
473
-     *    loads model classes - must be singletons
474
-     *
475
-     * @param string $class_name - simple class name ie: price
476
-     * @param mixed  $arguments
477
-     * @param bool   $load_only
478
-     * @return EEM_Base | bool
479
-     */
480
-    public function load_model($class_name, $arguments = array(), $load_only = false)
481
-    {
482
-        $paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
483
-            EE_MODELS,
484
-            EE_CORE,
485
-        ));
486
-        // retrieve instantiated class
487
-        return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
488
-    }
489
-
490
-
491
-
492
-    /**
493
-     *    loads model classes - must be singletons
494
-     *
495
-     * @param string $class_name - simple class name ie: price
496
-     * @param mixed  $arguments
497
-     * @param bool   $load_only
498
-     * @return mixed | bool
499
-     */
500
-    public function load_model_class($class_name, $arguments = array(), $load_only = true)
501
-    {
502
-        $paths = array(
503
-            EE_MODELS . 'fields' . DS,
504
-            EE_MODELS . 'helpers' . DS,
505
-            EE_MODELS . 'relations' . DS,
506
-            EE_MODELS . 'strategies' . DS,
507
-        );
508
-        // retrieve instantiated class
509
-        return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
510
-    }
511
-
512
-
513
-
514
-    /**
515
-     * Determines if $model_name is the name of an actual EE model.
516
-     *
517
-     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
518
-     * @return boolean
519
-     */
520
-    public function is_model_name($model_name)
521
-    {
522
-        return isset($this->models[$model_name]) ? true : false;
523
-    }
524
-
525
-
526
-
527
-    /**
528
-     *    generic class loader
529
-     *
530
-     * @param string $path_to_file - directory path to file location, not including filename
531
-     * @param string $file_name    - file name  ie:  my_file.php, including extension
532
-     * @param string $type         - file type - core? class? helper? model?
533
-     * @param mixed  $arguments
534
-     * @param bool   $load_only
535
-     * @return mixed
536
-     */
537
-    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
538
-    {
539
-        // retrieve instantiated class
540
-        return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
541
-    }
542
-
543
-
544
-
545
-    /**
546
-     *    load_addon
547
-     *
548
-     * @param string $path_to_file - directory path to file location, not including filename
549
-     * @param string $class_name   - full class name  ie:  My_Class
550
-     * @param string $type         - file type - core? class? helper? model?
551
-     * @param mixed  $arguments
552
-     * @param bool   $load_only
553
-     * @return EE_Addon
554
-     */
555
-    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
556
-    {
557
-        // retrieve instantiated class
558
-        return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
559
-    }
560
-
561
-
562
-
563
-    /**
564
-     * instantiates, caches, and automatically resolves dependencies
565
-     * for classes that use a Fully Qualified Class Name.
566
-     * if the class is not capable of being loaded using PSR-4 autoloading,
567
-     * then you need to use one of the existing load_*() methods
568
-     * which can resolve the classname and filepath from the passed arguments
569
-     *
570
-     * @param bool|string $class_name   Fully Qualified Class Name
571
-     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
572
-     * @param bool        $cache        whether to cache the instantiated object for reuse
573
-     * @param bool        $from_db      some classes are instantiated from the db
574
-     *                                  and thus call a different method to instantiate
575
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
576
-     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
577
-     * @return mixed                    null = failure to load or instantiate class object.
578
-     *                                  object = class loaded and instantiated successfully.
579
-     *                                  bool = fail or success when $load_only is true
580
-     */
581
-    public function create(
582
-        $class_name = false,
583
-        $arguments = array(),
584
-        $cache = false,
585
-        $from_db = false,
586
-        $load_only = false,
587
-        $addon = false
588
-    ) {
589
-        $class_name = ltrim($class_name, '\\');
590
-        $class_name = $this->_dependency_map->get_alias($class_name);
591
-        if ( ! class_exists($class_name)) {
592
-            // maybe the class is registered with a preceding \
593
-            $class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
594
-            // still doesn't exist ?
595
-            if ( ! class_exists($class_name)) {
596
-                return null;
597
-            }
598
-        }
599
-        // if we're only loading the class and it already exists, then let's just return true immediately
600
-        if ($load_only) {
601
-            return true;
602
-        }
603
-        $addon = $addon ? 'addon' : '';
604
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
605
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
606
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
607
-        if ($this->_cache_on && $cache && ! $load_only) {
608
-            // return object if it's already cached
609
-            $cached_class = $this->_get_cached_class($class_name, $addon);
610
-            if ($cached_class !== null) {
611
-                return $cached_class;
612
-            }
613
-        }
614
-        // instantiate the requested object
615
-        $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
616
-        if ($this->_cache_on && $cache) {
617
-            // save it for later... kinda like gum  { : $
618
-            $this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
619
-        }
620
-        $this->_cache_on = true;
621
-        return $class_obj;
622
-    }
623
-
624
-
625
-
626
-    /**
627
-     * instantiates, caches, and injects dependencies for classes
628
-     *
629
-     * @param array       $file_paths   an array of paths to folders to look in
630
-     * @param string      $class_prefix EE  or EEM or... ???
631
-     * @param bool|string $class_name   $class name
632
-     * @param string      $type         file type - core? class? helper? model?
633
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
634
-     * @param bool        $from_db      some classes are instantiated from the db
635
-     *                                  and thus call a different method to instantiate
636
-     * @param bool        $cache        whether to cache the instantiated object for reuse
637
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
638
-     * @return null|object|bool         null = failure to load or instantiate class object.
639
-     *                                  object = class loaded and instantiated successfully.
640
-     *                                  bool = fail or success when $load_only is true
641
-     */
642
-    protected function _load(
643
-        $file_paths = array(),
644
-        $class_prefix = 'EE_',
645
-        $class_name = false,
646
-        $type = 'class',
647
-        $arguments = array(),
648
-        $from_db = false,
649
-        $cache = true,
650
-        $load_only = false
651
-    ) {
652
-        $class_name = ltrim($class_name, '\\');
653
-        // strip php file extension
654
-        $class_name = str_replace('.php', '', trim($class_name));
655
-        // does the class have a prefix ?
656
-        if ( ! empty($class_prefix) && $class_prefix != 'addon') {
657
-            // make sure $class_prefix is uppercase
658
-            $class_prefix = strtoupper(trim($class_prefix));
659
-            // add class prefix ONCE!!!
660
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
661
-        }
662
-        $class_name = $this->_dependency_map->get_alias($class_name);
663
-        $class_exists = class_exists($class_name);
664
-        // if we're only loading the class and it already exists, then let's just return true immediately
665
-        if ($load_only && $class_exists) {
666
-            return true;
667
-        }
668
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
669
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
670
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
671
-        if ($this->_cache_on && $cache && ! $load_only) {
672
-            // return object if it's already cached
673
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix);
674
-            if ($cached_class !== null) {
675
-                return $cached_class;
676
-            }
677
-        }
678
-        // if the class doesn't already exist.. then we need to try and find the file and load it
679
-        if ( ! $class_exists) {
680
-            // get full path to file
681
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
682
-            // load the file
683
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
684
-            // if loading failed, or we are only loading a file but NOT instantiating an object
685
-            if ( ! $loaded || $load_only) {
686
-                // return boolean if only loading, or null if an object was expected
687
-                return $load_only ? $loaded : null;
688
-            }
689
-        }
690
-        // instantiate the requested object
691
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
692
-        if ($this->_cache_on && $cache) {
693
-            // save it for later... kinda like gum  { : $
694
-            $this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
695
-        }
696
-        $this->_cache_on = true;
697
-        return $class_obj;
698
-    }
699
-
700
-
701
-
702
-    /**
703
-     * _get_cached_class
704
-     * attempts to find a cached version of the requested class
705
-     * by looking in the following places:
706
-     *        $this->{$class_abbreviation}            ie:    $this->CART
707
-     *        $this->{$class_name}                        ie:    $this->Some_Class
708
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
709
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
710
-     *
711
-     * @access protected
712
-     * @param string $class_name
713
-     * @param string $class_prefix
714
-     * @return mixed
715
-     */
716
-    protected function _get_cached_class($class_name, $class_prefix = '')
717
-    {
718
-        if (isset($this->_class_abbreviations[$class_name])) {
719
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
720
-        } else {
721
-            // have to specify something, but not anything that will conflict
722
-            $class_abbreviation = 'FANCY_BATMAN_PANTS';
723
-        }
724
-        // check if class has already been loaded, and return it if it has been
725
-        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
726
-            return $this->{$class_abbreviation};
727
-        } else if (isset ($this->{$class_name})) {
728
-            return $this->{$class_name};
729
-        } else if (isset ($this->LIB->{$class_name})) {
730
-            return $this->LIB->{$class_name};
731
-        } else if ($class_prefix == 'addon' && isset ($this->addons->{$class_name})) {
732
-            return $this->addons->{$class_name};
733
-        }
734
-        return null;
735
-    }
736
-
737
-
738
-
739
-    /**
740
-     * _resolve_path
741
-     * attempts to find a full valid filepath for the requested class.
742
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
743
-     * then returns that path if the target file has been found and is readable
744
-     *
745
-     * @access protected
746
-     * @param string $class_name
747
-     * @param string $type
748
-     * @param array  $file_paths
749
-     * @return string | bool
750
-     */
751
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
752
-    {
753
-        // make sure $file_paths is an array
754
-        $file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
755
-        // cycle thru paths
756
-        foreach ($file_paths as $key => $file_path) {
757
-            // convert all separators to proper DS, if no filepath, then use EE_CLASSES
758
-            $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
759
-            // prep file type
760
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
761
-            // build full file path
762
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
763
-            //does the file exist and can be read ?
764
-            if (is_readable($file_paths[$key])) {
765
-                return $file_paths[$key];
766
-            }
767
-        }
768
-        return false;
769
-    }
770
-
771
-
772
-
773
-    /**
774
-     * _require_file
775
-     * basically just performs a require_once()
776
-     * but with some error handling
777
-     *
778
-     * @access protected
779
-     * @param  string $path
780
-     * @param  string $class_name
781
-     * @param  string $type
782
-     * @param  array  $file_paths
783
-     * @return boolean
784
-     * @throws \EE_Error
785
-     */
786
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
787
-    {
788
-        // don't give up! you gotta...
789
-        try {
790
-            //does the file exist and can it be read ?
791
-            if ( ! $path) {
792
-                // so sorry, can't find the file
793
-                throw new EE_Error (
794
-                    sprintf(
795
-                        __('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'),
796
-                        trim($type, '.'),
797
-                        $class_name,
798
-                        '<br />' . implode(',<br />', $file_paths)
799
-                    )
800
-                );
801
-            }
802
-            // get the file
803
-            require_once($path);
804
-            // if the class isn't already declared somewhere
805
-            if (class_exists($class_name, false) === false) {
806
-                // so sorry, not a class
807
-                throw new EE_Error(
808
-                    sprintf(
809
-                        __('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
810
-                        $type,
811
-                        $path,
812
-                        $class_name
813
-                    )
814
-                );
815
-            }
816
-        } catch (EE_Error $e) {
817
-            $e->get_error();
818
-            return false;
819
-        }
820
-        return true;
821
-    }
822
-
823
-
824
-
825
-    /**
826
-     * _create_object
827
-     * Attempts to instantiate the requested class via any of the
828
-     * commonly used instantiation methods employed throughout EE.
829
-     * The priority for instantiation is as follows:
830
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
831
-     *        - model objects via their 'new_instance_from_db' method
832
-     *        - model objects via their 'new_instance' method
833
-     *        - "singleton" classes" via their 'instance' method
834
-     *    - standard instantiable classes via their __constructor
835
-     * Prior to instantiation, if the classname exists in the dependency_map,
836
-     * then the constructor for the requested class will be examined to determine
837
-     * if any dependencies exist, and if they can be injected.
838
-     * If so, then those classes will be added to the array of arguments passed to the constructor
839
-     *
840
-     * @access protected
841
-     * @param string $class_name
842
-     * @param array  $arguments
843
-     * @param string $type
844
-     * @param bool   $from_db
845
-     * @return null | object
846
-     * @throws \EE_Error
847
-     */
848
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
849
-    {
850
-        $class_obj = null;
851
-        $instantiation_mode = '0) none';
852
-        // don't give up! you gotta...
853
-        try {
854
-            // create reflection
855
-            $reflector = $this->get_ReflectionClass($class_name);
856
-            // make sure arguments are an array
857
-            $arguments = is_array($arguments) ? $arguments : array($arguments);
858
-            // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
859
-            // else wrap it in an additional array so that it doesn't get split into multiple parameters
860
-            $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
861
-                ? $arguments
862
-                : array($arguments);
863
-            // attempt to inject dependencies ?
864
-            if ($this->_dependency_map->has($class_name)) {
865
-                $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
866
-            }
867
-            // instantiate the class if possible
868
-            if ($reflector->isAbstract()) {
869
-                // nothing to instantiate, loading file was enough
870
-                // does not throw an exception so $instantiation_mode is unused
871
-                // $instantiation_mode = "1) no constructor abstract class";
872
-                $class_obj = true;
873
-            } else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
874
-                // no constructor = static methods only... nothing to instantiate, loading file was enough
875
-                $instantiation_mode = "2) no constructor but instantiable";
876
-                $class_obj = $reflector->newInstance();
877
-            } else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
878
-                $instantiation_mode = "3) new_instance_from_db()";
879
-                $class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
880
-            } else if (method_exists($class_name, 'new_instance')) {
881
-                $instantiation_mode = "4) new_instance()";
882
-                $class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
883
-            } else if (method_exists($class_name, 'instance')) {
884
-                $instantiation_mode = "5) instance()";
885
-                $class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
886
-            } else if ($reflector->isInstantiable()) {
887
-                $instantiation_mode = "6) constructor";
888
-                $class_obj = $reflector->newInstanceArgs($arguments);
889
-            } else {
890
-                // heh ? something's not right !
891
-                throw new EE_Error(
892
-                    sprintf(
893
-                        __('The %s file %s could not be instantiated.', 'event_espresso'),
894
-                        $type,
895
-                        $class_name
896
-                    )
897
-                );
898
-            }
899
-        } catch (Exception $e) {
900
-            if ( ! $e instanceof EE_Error) {
901
-                $e = new EE_Error(
902
-                    sprintf(
903
-                        __('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
904
-                        $class_name,
905
-                        '<br />',
906
-                        $e->getMessage(),
907
-                        $instantiation_mode
908
-                    )
909
-                );
910
-            }
911
-            $e->get_error();
912
-        }
913
-        return $class_obj;
914
-    }
915
-
916
-
917
-
918
-    /**
919
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
920
-     * @param array $array
921
-     * @return bool
922
-     */
923
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
924
-    {
925
-        return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
926
-    }
927
-
928
-
929
-
930
-    /**
931
-     * getReflectionClass
932
-     * checks if a ReflectionClass object has already been generated for a class
933
-     * and returns that instead of creating a new one
934
-     *
935
-     * @access public
936
-     * @param string $class_name
937
-     * @return ReflectionClass
938
-     */
939
-    public function get_ReflectionClass($class_name)
940
-    {
941
-        if (
942
-            ! isset($this->_reflectors[$class_name])
943
-            || ! $this->_reflectors[$class_name] instanceof ReflectionClass
944
-        ) {
945
-            $this->_reflectors[$class_name] = new ReflectionClass($class_name);
946
-        }
947
-        return $this->_reflectors[$class_name];
948
-    }
949
-
950
-
951
-
952
-    /**
953
-     * _resolve_dependencies
954
-     * examines the constructor for the requested class to determine
955
-     * if any dependencies exist, and if they can be injected.
956
-     * If so, then those classes will be added to the array of arguments passed to the constructor
957
-     * PLZ NOTE: this is achieved by type hinting the constructor params
958
-     * For example:
959
-     *        if attempting to load a class "Foo" with the following constructor:
960
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
961
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
962
-     *        but only IF they are NOT already present in the incoming arguments array,
963
-     *        and the correct classes can be loaded
964
-     *
965
-     * @access protected
966
-     * @param ReflectionClass $reflector
967
-     * @param string          $class_name
968
-     * @param array           $arguments
969
-     * @return array
970
-     * @throws \ReflectionException
971
-     */
972
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
973
-    {
974
-        // let's examine the constructor
975
-        $constructor = $reflector->getConstructor();
976
-        // whu? huh? nothing?
977
-        if ( ! $constructor) {
978
-            return $arguments;
979
-        }
980
-        // get constructor parameters
981
-        $params = $constructor->getParameters();
982
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
983
-        $argument_keys = array_keys($arguments);
984
-        // now loop thru all of the constructors expected parameters
985
-        foreach ($params as $index => $param) {
986
-            // is this a dependency for a specific class ?
987
-            $param_class = $param->getClass() ? $param->getClass()->name : null;
988
-            if (
989
-                // param is not even a class
990
-                empty($param_class)
991
-                // and something already exists in the incoming arguments for this param
992
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
993
-            ) {
994
-                // so let's skip this argument and move on to the next
995
-                continue;
996
-            } else if (
997
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
998
-                ! empty($param_class)
999
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1000
-                && $arguments[$argument_keys[$index]] instanceof $param_class
1001
-            ) {
1002
-                // skip this argument and move on to the next
1003
-                continue;
1004
-            } else if (
1005
-                // parameter is type hinted as a class, and should be injected
1006
-                ! empty($param_class)
1007
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1008
-            ) {
1009
-                $arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1010
-            } else {
1011
-                try {
1012
-                    $arguments[$index] = $param->getDefaultValue();
1013
-                } catch (ReflectionException $e) {
1014
-                    throw new ReflectionException(
1015
-                        sprintf(
1016
-                            __('%1$s for parameter "$%2$s"', 'event_espresso'),
1017
-                            $e->getMessage(),
1018
-                            $param->getName()
1019
-                        )
1020
-                    );
1021
-                }
1022
-            }
1023
-        }
1024
-        return $arguments;
1025
-    }
1026
-
1027
-
1028
-
1029
-    /**
1030
-     * @access protected
1031
-     * @param string $class_name
1032
-     * @param string $param_class
1033
-     * @param array  $arguments
1034
-     * @param mixed  $index
1035
-     * @return array
1036
-     */
1037
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1038
-    {
1039
-        $dependency = null;
1040
-        // should dependency be loaded from cache ?
1041
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1042
-                    !== EE_Dependency_Map::load_new_object
1043
-            ? true
1044
-            : false;
1045
-        // we might have a dependency...
1046
-        // let's MAYBE try and find it in our cache if that's what's been requested
1047
-        $cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1048
-        // and grab it if it exists
1049
-        if ($cached_class instanceof $param_class) {
1050
-            $dependency = $cached_class;
1051
-        } else if ($param_class != $class_name) {
1052
-            // obtain the loader method from the dependency map
1053
-            $loader = $this->_dependency_map->class_loader($param_class);
1054
-            // is loader a custom closure ?
1055
-            if ($loader instanceof Closure) {
1056
-                $dependency = $loader();
1057
-            } else {
1058
-                // set the cache on property for the recursive loading call
1059
-                $this->_cache_on = $cache_on;
1060
-                // if not, then let's try and load it via the registry
1061
-                if (method_exists($this, $loader)) {
1062
-                    $dependency = $this->{$loader}($param_class);
1063
-                } else {
1064
-                    $dependency = $this->create($param_class, array(), $cache_on);
1065
-                }
1066
-            }
1067
-        }
1068
-        // did we successfully find the correct dependency ?
1069
-        if ($dependency instanceof $param_class) {
1070
-            // then let's inject it into the incoming array of arguments at the correct location
1071
-            if (isset($argument_keys[$index])) {
1072
-                $arguments[$argument_keys[$index]] = $dependency;
1073
-            } else {
1074
-                $arguments[$index] = $dependency;
1075
-            }
1076
-        }
1077
-        return $arguments;
1078
-    }
1079
-
1080
-
1081
-
1082
-    /**
1083
-     * _set_cached_class
1084
-     * attempts to cache the instantiated class locally
1085
-     * in one of the following places, in the following order:
1086
-     *        $this->{class_abbreviation}   ie:    $this->CART
1087
-     *        $this->{$class_name}          ie:    $this->Some_Class
1088
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1089
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1090
-     *
1091
-     * @access protected
1092
-     * @param object $class_obj
1093
-     * @param string $class_name
1094
-     * @param string $class_prefix
1095
-     * @param bool   $from_db
1096
-     * @return void
1097
-     */
1098
-    protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1099
-    {
1100
-        if (empty($class_obj)) {
1101
-            return;
1102
-        }
1103
-        // return newly instantiated class
1104
-        if (isset($this->_class_abbreviations[$class_name])) {
1105
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
1106
-            $this->{$class_abbreviation} = $class_obj;
1107
-        } else if (property_exists($this, $class_name)) {
1108
-            $this->{$class_name} = $class_obj;
1109
-        } else if ($class_prefix == 'addon') {
1110
-            $this->addons->{$class_name} = $class_obj;
1111
-        } else if ( ! $from_db) {
1112
-            $this->LIB->{$class_name} = $class_obj;
1113
-        }
1114
-    }
1115
-
1116
-
1117
-
1118
-    /**
1119
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1120
-     *
1121
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1122
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1123
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1124
-     * @param array  $arguments
1125
-     * @return object
1126
-     */
1127
-    public static function factory($classname, $arguments = array())
1128
-    {
1129
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1130
-        if ($loader instanceof Closure) {
1131
-            return $loader($arguments);
1132
-        } else if (method_exists(EE_Registry::instance(), $loader)) {
1133
-            return EE_Registry::instance()->{$loader}($classname, $arguments);
1134
-        }
1135
-        return null;
1136
-    }
1137
-
1138
-
1139
-
1140
-    /**
1141
-     * Gets the addon by its name/slug (not classname. For that, just
1142
-     * use the classname as the property name on EE_Config::instance()->addons)
1143
-     *
1144
-     * @param string $name
1145
-     * @return EE_Addon
1146
-     */
1147
-    public function get_addon_by_name($name)
1148
-    {
1149
-        foreach ($this->addons as $addon) {
1150
-            if ($addon->name() == $name) {
1151
-                return $addon;
1152
-            }
1153
-        }
1154
-        return null;
1155
-    }
1156
-
1157
-
1158
-
1159
-    /**
1160
-     * 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
1161
-     * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1162
-     *
1163
-     * @return EE_Addon[] where the KEYS are the addon's name()
1164
-     */
1165
-    public function get_addons_by_name()
1166
-    {
1167
-        $addons = array();
1168
-        foreach ($this->addons as $addon) {
1169
-            $addons[$addon->name()] = $addon;
1170
-        }
1171
-        return $addons;
1172
-    }
1173
-
1174
-
1175
-
1176
-    /**
1177
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1178
-     * a stale copy of it around
1179
-     *
1180
-     * @param string $model_name
1181
-     * @return \EEM_Base
1182
-     * @throws \EE_Error
1183
-     */
1184
-    public function reset_model($model_name)
1185
-    {
1186
-        $model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1187
-        if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1188
-            return null;
1189
-        }
1190
-        //get that model reset it and make sure we nuke the old reference to it
1191
-        if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1192
-            $this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1193
-        } else {
1194
-            throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1195
-        }
1196
-        return $this->LIB->{$model_class_name};
1197
-    }
1198
-
1199
-
1200
-
1201
-    /**
1202
-     * Resets the registry.
1203
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1204
-     * is used in a multisite install.  Here is a list of things that are NOT reset.
1205
-     * - $_dependency_map
1206
-     * - $_class_abbreviations
1207
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1208
-     * - $REQ:  Still on the same request so no need to change.
1209
-     * - $CAP: There is no site specific state in the EE_Capability class.
1210
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1211
-     *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1212
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1213
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1214
-     *             switch or on the restore.
1215
-     * - $modules
1216
-     * - $shortcodes
1217
-     * - $widgets
1218
-     *
1219
-     * @param boolean $hard             whether to reset data in the database too, or just refresh
1220
-     *                                  the Registry to its state at the beginning of the request
1221
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1222
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1223
-     *                                  currently reinstantiate the singletons at the moment)
1224
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1225
-     *                                  code instead can just change the model context to a different blog id if necessary
1226
-     * @return EE_Registry
1227
-     */
1228
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1229
-    {
1230
-        $instance = self::instance();
1231
-        EEH_Activation::reset();
1232
-        //properties that get reset
1233
-        $instance->_cache_on = true;
1234
-        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1235
-        $instance->CART = null;
1236
-        $instance->MRM = null;
1237
-        $instance->AssetsRegistry = new Registry();
1238
-        //messages reset
1239
-        EED_Messages::reset();
1240
-        if ($reset_models) {
1241
-            foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1242
-                $instance->reset_model($model_name);
1243
-            }
1244
-        }
1245
-        $instance->LIB = new stdClass();
1246
-        return $instance;
1247
-    }
1248
-
1249
-
1250
-
1251
-    /**
1252
-     * @override magic methods
1253
-     * @return void
1254
-     */
1255
-    final function __destruct()
1256
-    {
1257
-    }
1258
-
1259
-
1260
-
1261
-    /**
1262
-     * @param $a
1263
-     * @param $b
1264
-     */
1265
-    final function __call($a, $b)
1266
-    {
1267
-    }
1268
-
1269
-
1270
-
1271
-    /**
1272
-     * @param $a
1273
-     */
1274
-    final function __get($a)
1275
-    {
1276
-    }
1277
-
1278
-
1279
-
1280
-    /**
1281
-     * @param $a
1282
-     * @param $b
1283
-     */
1284
-    final function __set($a, $b)
1285
-    {
1286
-    }
1287
-
1288
-
1289
-
1290
-    /**
1291
-     * @param $a
1292
-     */
1293
-    final function __isset($a)
1294
-    {
1295
-    }
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
+	 *    $addons - StdClass object for holding addons which have registered themselves to work with EE core
118
+	 *
119
+	 * @access    public
120
+	 * @var    EE_Addon[]
121
+	 */
122
+	public $addons = null;
123
+
124
+	/**
125
+	 *    $models
126
+	 * @access    public
127
+	 * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
128
+	 */
129
+	public $models = array();
130
+
131
+	/**
132
+	 *    $modules
133
+	 * @access    public
134
+	 * @var    EED_Module[] $modules
135
+	 */
136
+	public $modules = null;
137
+
138
+	/**
139
+	 *    $shortcodes
140
+	 * @access    public
141
+	 * @var    EES_Shortcode[] $shortcodes
142
+	 */
143
+	public $shortcodes = null;
144
+
145
+	/**
146
+	 *    $widgets
147
+	 * @access    public
148
+	 * @var    WP_Widget[] $widgets
149
+	 */
150
+	public $widgets = null;
151
+
152
+	/**
153
+	 * $non_abstract_db_models
154
+	 * @access public
155
+	 * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
156
+	 * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
157
+	 * Keys are model "short names" (eg "Event") as used in model relations, and values are
158
+	 * classnames (eg "EEM_Event")
159
+	 */
160
+	public $non_abstract_db_models = array();
161
+
162
+
163
+	/**
164
+	 *    $i18n_js_strings - internationalization for JS strings
165
+	 *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
166
+	 *    in js file:  var translatedString = eei18n.string_key;
167
+	 *
168
+	 * @access    public
169
+	 * @var    array
170
+	 */
171
+	public static $i18n_js_strings = array();
172
+
173
+
174
+	/**
175
+	 *    $main_file - path to espresso.php
176
+	 *
177
+	 * @access    public
178
+	 * @var    array
179
+	 */
180
+	public $main_file;
181
+
182
+	/**
183
+	 * array of ReflectionClass objects where the key is the class name
184
+	 *
185
+	 * @access    public
186
+	 * @var ReflectionClass[]
187
+	 */
188
+	public $_reflectors;
189
+
190
+	/**
191
+	 * boolean flag to indicate whether or not to load/save dependencies from/to the cache
192
+	 *
193
+	 * @access    protected
194
+	 * @var boolean $_cache_on
195
+	 */
196
+	protected $_cache_on = true;
197
+
198
+
199
+
200
+	/**
201
+	 * @singleton method used to instantiate class object
202
+	 * @access    public
203
+	 * @param  \EE_Dependency_Map $dependency_map
204
+	 * @return \EE_Registry instance
205
+	 */
206
+	public static function instance(\EE_Dependency_Map $dependency_map = null)
207
+	{
208
+		// check if class object is instantiated
209
+		if ( ! self::$_instance instanceof EE_Registry) {
210
+			self::$_instance = new EE_Registry($dependency_map);
211
+		}
212
+		return self::$_instance;
213
+	}
214
+
215
+
216
+
217
+	/**
218
+	 *protected constructor to prevent direct creation
219
+	 *
220
+	 * @Constructor
221
+	 * @access protected
222
+	 * @param  \EE_Dependency_Map $dependency_map
223
+	 * @return \EE_Registry
224
+	 */
225
+	protected function __construct(\EE_Dependency_Map $dependency_map)
226
+	{
227
+		$this->_dependency_map = $dependency_map;
228
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
229
+	}
230
+
231
+
232
+
233
+	/**
234
+	 * initialize
235
+	 */
236
+	public function initialize()
237
+	{
238
+		$this->_class_abbreviations = apply_filters(
239
+			'FHEE__EE_Registry____construct___class_abbreviations',
240
+			array(
241
+				'EE_Config'                                       => 'CFG',
242
+				'EE_Session'                                      => 'SSN',
243
+				'EE_Capabilities'                                 => 'CAP',
244
+				'EE_Cart'                                         => 'CART',
245
+				'EE_Network_Config'                               => 'NET_CFG',
246
+				'EE_Request_Handler'                              => 'REQ',
247
+				'EE_Message_Resource_Manager'                     => 'MRM',
248
+				'EventEspresso\core\services\commands\CommandBus' => 'BUS',
249
+			)
250
+		);
251
+		// class library
252
+		$this->LIB = new stdClass();
253
+		$this->addons = new stdClass();
254
+		$this->modules = new stdClass();
255
+		$this->shortcodes = new stdClass();
256
+		$this->widgets = new stdClass();
257
+		$this->load_core('Base', array(), true);
258
+		// add our request and response objects to the cache
259
+		$request_loader = $this->_dependency_map->class_loader('EE_Request');
260
+		$this->_set_cached_class(
261
+			$request_loader(),
262
+			'EE_Request'
263
+		);
264
+		$response_loader = $this->_dependency_map->class_loader('EE_Response');
265
+		$this->_set_cached_class(
266
+			$response_loader(),
267
+			'EE_Response'
268
+		);
269
+		add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
270
+	}
271
+
272
+
273
+
274
+	/**
275
+	 *    init
276
+	 *
277
+	 * @access    public
278
+	 * @return    void
279
+	 */
280
+	public function init()
281
+	{
282
+		$this->AssetsRegistry = new Registry();
283
+		// Get current page protocol
284
+		$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
285
+		// Output admin-ajax.php URL with same protocol as current page
286
+		self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
287
+		self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
288
+	}
289
+
290
+
291
+
292
+	/**
293
+	 * localize_i18n_js_strings
294
+	 *
295
+	 * @return string
296
+	 */
297
+	public static function localize_i18n_js_strings()
298
+	{
299
+		$i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
300
+		foreach ($i18n_js_strings as $key => $value) {
301
+			if (is_scalar($value)) {
302
+				$i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
303
+			}
304
+		}
305
+		return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
306
+	}
307
+
308
+
309
+
310
+	/**
311
+	 * @param mixed string | EED_Module $module
312
+	 */
313
+	public function add_module($module)
314
+	{
315
+		if ($module instanceof EED_Module) {
316
+			$module_class = get_class($module);
317
+			$this->modules->{$module_class} = $module;
318
+		} else {
319
+			if ( ! class_exists('EE_Module_Request_Router')) {
320
+				$this->load_core('Module_Request_Router');
321
+			}
322
+			$this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
323
+		}
324
+	}
325
+
326
+
327
+
328
+	/**
329
+	 * @param string $module_name
330
+	 * @return mixed EED_Module | NULL
331
+	 */
332
+	public function get_module($module_name = '')
333
+	{
334
+		return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
335
+	}
336
+
337
+
338
+
339
+	/**
340
+	 *    loads core classes - must be singletons
341
+	 *
342
+	 * @access    public
343
+	 * @param string $class_name - simple class name ie: session
344
+	 * @param mixed  $arguments
345
+	 * @param bool   $load_only
346
+	 * @return mixed
347
+	 */
348
+	public function load_core($class_name, $arguments = array(), $load_only = false)
349
+	{
350
+		$core_paths = apply_filters(
351
+			'FHEE__EE_Registry__load_core__core_paths',
352
+			array(
353
+				EE_CORE,
354
+				EE_ADMIN,
355
+				EE_CPTS,
356
+				EE_CORE . 'data_migration_scripts' . DS,
357
+				EE_CORE . 'request_stack' . DS,
358
+				EE_CORE . 'middleware' . DS,
359
+			)
360
+		);
361
+		// retrieve instantiated class
362
+		return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 *    loads service classes
369
+	 *
370
+	 * @access    public
371
+	 * @param string $class_name - simple class name ie: session
372
+	 * @param mixed  $arguments
373
+	 * @param bool   $load_only
374
+	 * @return mixed
375
+	 */
376
+	public function load_service($class_name, $arguments = array(), $load_only = false)
377
+	{
378
+		$service_paths = apply_filters(
379
+			'FHEE__EE_Registry__load_service__service_paths',
380
+			array(
381
+				EE_CORE . 'services' . DS,
382
+			)
383
+		);
384
+		// retrieve instantiated class
385
+		return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
386
+	}
387
+
388
+
389
+
390
+	/**
391
+	 *    loads data_migration_scripts
392
+	 *
393
+	 * @access    public
394
+	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
395
+	 * @param mixed  $arguments
396
+	 * @return EE_Data_Migration_Script_Base|mixed
397
+	 */
398
+	public function load_dms($class_name, $arguments = array())
399
+	{
400
+		// retrieve instantiated class
401
+		return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
402
+	}
403
+
404
+
405
+
406
+	/**
407
+	 *    loads object creating classes - must be singletons
408
+	 *
409
+	 * @param string $class_name - simple class name ie: attendee
410
+	 * @param mixed  $arguments  - an array of arguments to pass to the class
411
+	 * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
412
+	 * @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)
413
+	 * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
414
+	 * @return EE_Base_Class | bool
415
+	 */
416
+	public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
417
+	{
418
+		$paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
419
+			EE_CORE,
420
+			EE_CLASSES,
421
+			EE_BUSINESS,
422
+		));
423
+		// retrieve instantiated class
424
+		return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
425
+	}
426
+
427
+
428
+
429
+	/**
430
+	 *    loads helper classes - must be singletons
431
+	 *
432
+	 * @param string $class_name - simple class name ie: price
433
+	 * @param mixed  $arguments
434
+	 * @param bool   $load_only
435
+	 * @return EEH_Base | bool
436
+	 */
437
+	public function load_helper($class_name, $arguments = array(), $load_only = true)
438
+	{
439
+		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
440
+		$helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
441
+		// retrieve instantiated class
442
+		return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 *    loads core classes - must be singletons
449
+	 *
450
+	 * @access    public
451
+	 * @param string $class_name - simple class name ie: session
452
+	 * @param mixed  $arguments
453
+	 * @param bool   $load_only
454
+	 * @param bool   $cache      whether to cache the object or not.
455
+	 * @return mixed
456
+	 */
457
+	public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
458
+	{
459
+		$paths = array(
460
+			EE_LIBRARIES,
461
+			EE_LIBRARIES . 'messages' . DS,
462
+			EE_LIBRARIES . 'shortcodes' . DS,
463
+			EE_LIBRARIES . 'qtips' . DS,
464
+			EE_LIBRARIES . 'payment_methods' . DS,
465
+		);
466
+		// retrieve instantiated class
467
+		return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
468
+	}
469
+
470
+
471
+
472
+	/**
473
+	 *    loads model classes - must be singletons
474
+	 *
475
+	 * @param string $class_name - simple class name ie: price
476
+	 * @param mixed  $arguments
477
+	 * @param bool   $load_only
478
+	 * @return EEM_Base | bool
479
+	 */
480
+	public function load_model($class_name, $arguments = array(), $load_only = false)
481
+	{
482
+		$paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
483
+			EE_MODELS,
484
+			EE_CORE,
485
+		));
486
+		// retrieve instantiated class
487
+		return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
488
+	}
489
+
490
+
491
+
492
+	/**
493
+	 *    loads model classes - must be singletons
494
+	 *
495
+	 * @param string $class_name - simple class name ie: price
496
+	 * @param mixed  $arguments
497
+	 * @param bool   $load_only
498
+	 * @return mixed | bool
499
+	 */
500
+	public function load_model_class($class_name, $arguments = array(), $load_only = true)
501
+	{
502
+		$paths = array(
503
+			EE_MODELS . 'fields' . DS,
504
+			EE_MODELS . 'helpers' . DS,
505
+			EE_MODELS . 'relations' . DS,
506
+			EE_MODELS . 'strategies' . DS,
507
+		);
508
+		// retrieve instantiated class
509
+		return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
510
+	}
511
+
512
+
513
+
514
+	/**
515
+	 * Determines if $model_name is the name of an actual EE model.
516
+	 *
517
+	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
518
+	 * @return boolean
519
+	 */
520
+	public function is_model_name($model_name)
521
+	{
522
+		return isset($this->models[$model_name]) ? true : false;
523
+	}
524
+
525
+
526
+
527
+	/**
528
+	 *    generic class loader
529
+	 *
530
+	 * @param string $path_to_file - directory path to file location, not including filename
531
+	 * @param string $file_name    - file name  ie:  my_file.php, including extension
532
+	 * @param string $type         - file type - core? class? helper? model?
533
+	 * @param mixed  $arguments
534
+	 * @param bool   $load_only
535
+	 * @return mixed
536
+	 */
537
+	public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
538
+	{
539
+		// retrieve instantiated class
540
+		return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
541
+	}
542
+
543
+
544
+
545
+	/**
546
+	 *    load_addon
547
+	 *
548
+	 * @param string $path_to_file - directory path to file location, not including filename
549
+	 * @param string $class_name   - full class name  ie:  My_Class
550
+	 * @param string $type         - file type - core? class? helper? model?
551
+	 * @param mixed  $arguments
552
+	 * @param bool   $load_only
553
+	 * @return EE_Addon
554
+	 */
555
+	public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
556
+	{
557
+		// retrieve instantiated class
558
+		return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
559
+	}
560
+
561
+
562
+
563
+	/**
564
+	 * instantiates, caches, and automatically resolves dependencies
565
+	 * for classes that use a Fully Qualified Class Name.
566
+	 * if the class is not capable of being loaded using PSR-4 autoloading,
567
+	 * then you need to use one of the existing load_*() methods
568
+	 * which can resolve the classname and filepath from the passed arguments
569
+	 *
570
+	 * @param bool|string $class_name   Fully Qualified Class Name
571
+	 * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
572
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
573
+	 * @param bool        $from_db      some classes are instantiated from the db
574
+	 *                                  and thus call a different method to instantiate
575
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
576
+	 * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
577
+	 * @return mixed                    null = failure to load or instantiate class object.
578
+	 *                                  object = class loaded and instantiated successfully.
579
+	 *                                  bool = fail or success when $load_only is true
580
+	 */
581
+	public function create(
582
+		$class_name = false,
583
+		$arguments = array(),
584
+		$cache = false,
585
+		$from_db = false,
586
+		$load_only = false,
587
+		$addon = false
588
+	) {
589
+		$class_name = ltrim($class_name, '\\');
590
+		$class_name = $this->_dependency_map->get_alias($class_name);
591
+		if ( ! class_exists($class_name)) {
592
+			// maybe the class is registered with a preceding \
593
+			$class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
594
+			// still doesn't exist ?
595
+			if ( ! class_exists($class_name)) {
596
+				return null;
597
+			}
598
+		}
599
+		// if we're only loading the class and it already exists, then let's just return true immediately
600
+		if ($load_only) {
601
+			return true;
602
+		}
603
+		$addon = $addon ? 'addon' : '';
604
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
605
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
606
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
607
+		if ($this->_cache_on && $cache && ! $load_only) {
608
+			// return object if it's already cached
609
+			$cached_class = $this->_get_cached_class($class_name, $addon);
610
+			if ($cached_class !== null) {
611
+				return $cached_class;
612
+			}
613
+		}
614
+		// instantiate the requested object
615
+		$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
616
+		if ($this->_cache_on && $cache) {
617
+			// save it for later... kinda like gum  { : $
618
+			$this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
619
+		}
620
+		$this->_cache_on = true;
621
+		return $class_obj;
622
+	}
623
+
624
+
625
+
626
+	/**
627
+	 * instantiates, caches, and injects dependencies for classes
628
+	 *
629
+	 * @param array       $file_paths   an array of paths to folders to look in
630
+	 * @param string      $class_prefix EE  or EEM or... ???
631
+	 * @param bool|string $class_name   $class name
632
+	 * @param string      $type         file type - core? class? helper? model?
633
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
634
+	 * @param bool        $from_db      some classes are instantiated from the db
635
+	 *                                  and thus call a different method to instantiate
636
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
637
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
638
+	 * @return null|object|bool         null = failure to load or instantiate class object.
639
+	 *                                  object = class loaded and instantiated successfully.
640
+	 *                                  bool = fail or success when $load_only is true
641
+	 */
642
+	protected function _load(
643
+		$file_paths = array(),
644
+		$class_prefix = 'EE_',
645
+		$class_name = false,
646
+		$type = 'class',
647
+		$arguments = array(),
648
+		$from_db = false,
649
+		$cache = true,
650
+		$load_only = false
651
+	) {
652
+		$class_name = ltrim($class_name, '\\');
653
+		// strip php file extension
654
+		$class_name = str_replace('.php', '', trim($class_name));
655
+		// does the class have a prefix ?
656
+		if ( ! empty($class_prefix) && $class_prefix != 'addon') {
657
+			// make sure $class_prefix is uppercase
658
+			$class_prefix = strtoupper(trim($class_prefix));
659
+			// add class prefix ONCE!!!
660
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
661
+		}
662
+		$class_name = $this->_dependency_map->get_alias($class_name);
663
+		$class_exists = class_exists($class_name);
664
+		// if we're only loading the class and it already exists, then let's just return true immediately
665
+		if ($load_only && $class_exists) {
666
+			return true;
667
+		}
668
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
669
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
670
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
671
+		if ($this->_cache_on && $cache && ! $load_only) {
672
+			// return object if it's already cached
673
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix);
674
+			if ($cached_class !== null) {
675
+				return $cached_class;
676
+			}
677
+		}
678
+		// if the class doesn't already exist.. then we need to try and find the file and load it
679
+		if ( ! $class_exists) {
680
+			// get full path to file
681
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
682
+			// load the file
683
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
684
+			// if loading failed, or we are only loading a file but NOT instantiating an object
685
+			if ( ! $loaded || $load_only) {
686
+				// return boolean if only loading, or null if an object was expected
687
+				return $load_only ? $loaded : null;
688
+			}
689
+		}
690
+		// instantiate the requested object
691
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
692
+		if ($this->_cache_on && $cache) {
693
+			// save it for later... kinda like gum  { : $
694
+			$this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
695
+		}
696
+		$this->_cache_on = true;
697
+		return $class_obj;
698
+	}
699
+
700
+
701
+
702
+	/**
703
+	 * _get_cached_class
704
+	 * attempts to find a cached version of the requested class
705
+	 * by looking in the following places:
706
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
707
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
708
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
709
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
710
+	 *
711
+	 * @access protected
712
+	 * @param string $class_name
713
+	 * @param string $class_prefix
714
+	 * @return mixed
715
+	 */
716
+	protected function _get_cached_class($class_name, $class_prefix = '')
717
+	{
718
+		if (isset($this->_class_abbreviations[$class_name])) {
719
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
720
+		} else {
721
+			// have to specify something, but not anything that will conflict
722
+			$class_abbreviation = 'FANCY_BATMAN_PANTS';
723
+		}
724
+		// check if class has already been loaded, and return it if it has been
725
+		if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
726
+			return $this->{$class_abbreviation};
727
+		} else if (isset ($this->{$class_name})) {
728
+			return $this->{$class_name};
729
+		} else if (isset ($this->LIB->{$class_name})) {
730
+			return $this->LIB->{$class_name};
731
+		} else if ($class_prefix == 'addon' && isset ($this->addons->{$class_name})) {
732
+			return $this->addons->{$class_name};
733
+		}
734
+		return null;
735
+	}
736
+
737
+
738
+
739
+	/**
740
+	 * _resolve_path
741
+	 * attempts to find a full valid filepath for the requested class.
742
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
743
+	 * then returns that path if the target file has been found and is readable
744
+	 *
745
+	 * @access protected
746
+	 * @param string $class_name
747
+	 * @param string $type
748
+	 * @param array  $file_paths
749
+	 * @return string | bool
750
+	 */
751
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
752
+	{
753
+		// make sure $file_paths is an array
754
+		$file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
755
+		// cycle thru paths
756
+		foreach ($file_paths as $key => $file_path) {
757
+			// convert all separators to proper DS, if no filepath, then use EE_CLASSES
758
+			$file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
759
+			// prep file type
760
+			$type = ! empty($type) ? trim($type, '.') . '.' : '';
761
+			// build full file path
762
+			$file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
763
+			//does the file exist and can be read ?
764
+			if (is_readable($file_paths[$key])) {
765
+				return $file_paths[$key];
766
+			}
767
+		}
768
+		return false;
769
+	}
770
+
771
+
772
+
773
+	/**
774
+	 * _require_file
775
+	 * basically just performs a require_once()
776
+	 * but with some error handling
777
+	 *
778
+	 * @access protected
779
+	 * @param  string $path
780
+	 * @param  string $class_name
781
+	 * @param  string $type
782
+	 * @param  array  $file_paths
783
+	 * @return boolean
784
+	 * @throws \EE_Error
785
+	 */
786
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
787
+	{
788
+		// don't give up! you gotta...
789
+		try {
790
+			//does the file exist and can it be read ?
791
+			if ( ! $path) {
792
+				// so sorry, can't find the file
793
+				throw new EE_Error (
794
+					sprintf(
795
+						__('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'),
796
+						trim($type, '.'),
797
+						$class_name,
798
+						'<br />' . implode(',<br />', $file_paths)
799
+					)
800
+				);
801
+			}
802
+			// get the file
803
+			require_once($path);
804
+			// if the class isn't already declared somewhere
805
+			if (class_exists($class_name, false) === false) {
806
+				// so sorry, not a class
807
+				throw new EE_Error(
808
+					sprintf(
809
+						__('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
810
+						$type,
811
+						$path,
812
+						$class_name
813
+					)
814
+				);
815
+			}
816
+		} catch (EE_Error $e) {
817
+			$e->get_error();
818
+			return false;
819
+		}
820
+		return true;
821
+	}
822
+
823
+
824
+
825
+	/**
826
+	 * _create_object
827
+	 * Attempts to instantiate the requested class via any of the
828
+	 * commonly used instantiation methods employed throughout EE.
829
+	 * The priority for instantiation is as follows:
830
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
831
+	 *        - model objects via their 'new_instance_from_db' method
832
+	 *        - model objects via their 'new_instance' method
833
+	 *        - "singleton" classes" via their 'instance' method
834
+	 *    - standard instantiable classes via their __constructor
835
+	 * Prior to instantiation, if the classname exists in the dependency_map,
836
+	 * then the constructor for the requested class will be examined to determine
837
+	 * if any dependencies exist, and if they can be injected.
838
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
839
+	 *
840
+	 * @access protected
841
+	 * @param string $class_name
842
+	 * @param array  $arguments
843
+	 * @param string $type
844
+	 * @param bool   $from_db
845
+	 * @return null | object
846
+	 * @throws \EE_Error
847
+	 */
848
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
849
+	{
850
+		$class_obj = null;
851
+		$instantiation_mode = '0) none';
852
+		// don't give up! you gotta...
853
+		try {
854
+			// create reflection
855
+			$reflector = $this->get_ReflectionClass($class_name);
856
+			// make sure arguments are an array
857
+			$arguments = is_array($arguments) ? $arguments : array($arguments);
858
+			// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
859
+			// else wrap it in an additional array so that it doesn't get split into multiple parameters
860
+			$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
861
+				? $arguments
862
+				: array($arguments);
863
+			// attempt to inject dependencies ?
864
+			if ($this->_dependency_map->has($class_name)) {
865
+				$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
866
+			}
867
+			// instantiate the class if possible
868
+			if ($reflector->isAbstract()) {
869
+				// nothing to instantiate, loading file was enough
870
+				// does not throw an exception so $instantiation_mode is unused
871
+				// $instantiation_mode = "1) no constructor abstract class";
872
+				$class_obj = true;
873
+			} else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
874
+				// no constructor = static methods only... nothing to instantiate, loading file was enough
875
+				$instantiation_mode = "2) no constructor but instantiable";
876
+				$class_obj = $reflector->newInstance();
877
+			} else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
878
+				$instantiation_mode = "3) new_instance_from_db()";
879
+				$class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
880
+			} else if (method_exists($class_name, 'new_instance')) {
881
+				$instantiation_mode = "4) new_instance()";
882
+				$class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
883
+			} else if (method_exists($class_name, 'instance')) {
884
+				$instantiation_mode = "5) instance()";
885
+				$class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
886
+			} else if ($reflector->isInstantiable()) {
887
+				$instantiation_mode = "6) constructor";
888
+				$class_obj = $reflector->newInstanceArgs($arguments);
889
+			} else {
890
+				// heh ? something's not right !
891
+				throw new EE_Error(
892
+					sprintf(
893
+						__('The %s file %s could not be instantiated.', 'event_espresso'),
894
+						$type,
895
+						$class_name
896
+					)
897
+				);
898
+			}
899
+		} catch (Exception $e) {
900
+			if ( ! $e instanceof EE_Error) {
901
+				$e = new EE_Error(
902
+					sprintf(
903
+						__('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
904
+						$class_name,
905
+						'<br />',
906
+						$e->getMessage(),
907
+						$instantiation_mode
908
+					)
909
+				);
910
+			}
911
+			$e->get_error();
912
+		}
913
+		return $class_obj;
914
+	}
915
+
916
+
917
+
918
+	/**
919
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
920
+	 * @param array $array
921
+	 * @return bool
922
+	 */
923
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
924
+	{
925
+		return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
926
+	}
927
+
928
+
929
+
930
+	/**
931
+	 * getReflectionClass
932
+	 * checks if a ReflectionClass object has already been generated for a class
933
+	 * and returns that instead of creating a new one
934
+	 *
935
+	 * @access public
936
+	 * @param string $class_name
937
+	 * @return ReflectionClass
938
+	 */
939
+	public function get_ReflectionClass($class_name)
940
+	{
941
+		if (
942
+			! isset($this->_reflectors[$class_name])
943
+			|| ! $this->_reflectors[$class_name] instanceof ReflectionClass
944
+		) {
945
+			$this->_reflectors[$class_name] = new ReflectionClass($class_name);
946
+		}
947
+		return $this->_reflectors[$class_name];
948
+	}
949
+
950
+
951
+
952
+	/**
953
+	 * _resolve_dependencies
954
+	 * examines the constructor for the requested class to determine
955
+	 * if any dependencies exist, and if they can be injected.
956
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
957
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
958
+	 * For example:
959
+	 *        if attempting to load a class "Foo" with the following constructor:
960
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
961
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
962
+	 *        but only IF they are NOT already present in the incoming arguments array,
963
+	 *        and the correct classes can be loaded
964
+	 *
965
+	 * @access protected
966
+	 * @param ReflectionClass $reflector
967
+	 * @param string          $class_name
968
+	 * @param array           $arguments
969
+	 * @return array
970
+	 * @throws \ReflectionException
971
+	 */
972
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
973
+	{
974
+		// let's examine the constructor
975
+		$constructor = $reflector->getConstructor();
976
+		// whu? huh? nothing?
977
+		if ( ! $constructor) {
978
+			return $arguments;
979
+		}
980
+		// get constructor parameters
981
+		$params = $constructor->getParameters();
982
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
983
+		$argument_keys = array_keys($arguments);
984
+		// now loop thru all of the constructors expected parameters
985
+		foreach ($params as $index => $param) {
986
+			// is this a dependency for a specific class ?
987
+			$param_class = $param->getClass() ? $param->getClass()->name : null;
988
+			if (
989
+				// param is not even a class
990
+				empty($param_class)
991
+				// and something already exists in the incoming arguments for this param
992
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
993
+			) {
994
+				// so let's skip this argument and move on to the next
995
+				continue;
996
+			} else if (
997
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
998
+				! empty($param_class)
999
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1000
+				&& $arguments[$argument_keys[$index]] instanceof $param_class
1001
+			) {
1002
+				// skip this argument and move on to the next
1003
+				continue;
1004
+			} else if (
1005
+				// parameter is type hinted as a class, and should be injected
1006
+				! empty($param_class)
1007
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1008
+			) {
1009
+				$arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1010
+			} else {
1011
+				try {
1012
+					$arguments[$index] = $param->getDefaultValue();
1013
+				} catch (ReflectionException $e) {
1014
+					throw new ReflectionException(
1015
+						sprintf(
1016
+							__('%1$s for parameter "$%2$s"', 'event_espresso'),
1017
+							$e->getMessage(),
1018
+							$param->getName()
1019
+						)
1020
+					);
1021
+				}
1022
+			}
1023
+		}
1024
+		return $arguments;
1025
+	}
1026
+
1027
+
1028
+
1029
+	/**
1030
+	 * @access protected
1031
+	 * @param string $class_name
1032
+	 * @param string $param_class
1033
+	 * @param array  $arguments
1034
+	 * @param mixed  $index
1035
+	 * @return array
1036
+	 */
1037
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1038
+	{
1039
+		$dependency = null;
1040
+		// should dependency be loaded from cache ?
1041
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1042
+					!== EE_Dependency_Map::load_new_object
1043
+			? true
1044
+			: false;
1045
+		// we might have a dependency...
1046
+		// let's MAYBE try and find it in our cache if that's what's been requested
1047
+		$cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1048
+		// and grab it if it exists
1049
+		if ($cached_class instanceof $param_class) {
1050
+			$dependency = $cached_class;
1051
+		} else if ($param_class != $class_name) {
1052
+			// obtain the loader method from the dependency map
1053
+			$loader = $this->_dependency_map->class_loader($param_class);
1054
+			// is loader a custom closure ?
1055
+			if ($loader instanceof Closure) {
1056
+				$dependency = $loader();
1057
+			} else {
1058
+				// set the cache on property for the recursive loading call
1059
+				$this->_cache_on = $cache_on;
1060
+				// if not, then let's try and load it via the registry
1061
+				if (method_exists($this, $loader)) {
1062
+					$dependency = $this->{$loader}($param_class);
1063
+				} else {
1064
+					$dependency = $this->create($param_class, array(), $cache_on);
1065
+				}
1066
+			}
1067
+		}
1068
+		// did we successfully find the correct dependency ?
1069
+		if ($dependency instanceof $param_class) {
1070
+			// then let's inject it into the incoming array of arguments at the correct location
1071
+			if (isset($argument_keys[$index])) {
1072
+				$arguments[$argument_keys[$index]] = $dependency;
1073
+			} else {
1074
+				$arguments[$index] = $dependency;
1075
+			}
1076
+		}
1077
+		return $arguments;
1078
+	}
1079
+
1080
+
1081
+
1082
+	/**
1083
+	 * _set_cached_class
1084
+	 * attempts to cache the instantiated class locally
1085
+	 * in one of the following places, in the following order:
1086
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1087
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1088
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1089
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1090
+	 *
1091
+	 * @access protected
1092
+	 * @param object $class_obj
1093
+	 * @param string $class_name
1094
+	 * @param string $class_prefix
1095
+	 * @param bool   $from_db
1096
+	 * @return void
1097
+	 */
1098
+	protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1099
+	{
1100
+		if (empty($class_obj)) {
1101
+			return;
1102
+		}
1103
+		// return newly instantiated class
1104
+		if (isset($this->_class_abbreviations[$class_name])) {
1105
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
1106
+			$this->{$class_abbreviation} = $class_obj;
1107
+		} else if (property_exists($this, $class_name)) {
1108
+			$this->{$class_name} = $class_obj;
1109
+		} else if ($class_prefix == 'addon') {
1110
+			$this->addons->{$class_name} = $class_obj;
1111
+		} else if ( ! $from_db) {
1112
+			$this->LIB->{$class_name} = $class_obj;
1113
+		}
1114
+	}
1115
+
1116
+
1117
+
1118
+	/**
1119
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1120
+	 *
1121
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1122
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1123
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1124
+	 * @param array  $arguments
1125
+	 * @return object
1126
+	 */
1127
+	public static function factory($classname, $arguments = array())
1128
+	{
1129
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1130
+		if ($loader instanceof Closure) {
1131
+			return $loader($arguments);
1132
+		} else if (method_exists(EE_Registry::instance(), $loader)) {
1133
+			return EE_Registry::instance()->{$loader}($classname, $arguments);
1134
+		}
1135
+		return null;
1136
+	}
1137
+
1138
+
1139
+
1140
+	/**
1141
+	 * Gets the addon by its name/slug (not classname. For that, just
1142
+	 * use the classname as the property name on EE_Config::instance()->addons)
1143
+	 *
1144
+	 * @param string $name
1145
+	 * @return EE_Addon
1146
+	 */
1147
+	public function get_addon_by_name($name)
1148
+	{
1149
+		foreach ($this->addons as $addon) {
1150
+			if ($addon->name() == $name) {
1151
+				return $addon;
1152
+			}
1153
+		}
1154
+		return null;
1155
+	}
1156
+
1157
+
1158
+
1159
+	/**
1160
+	 * 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
1161
+	 * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1162
+	 *
1163
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1164
+	 */
1165
+	public function get_addons_by_name()
1166
+	{
1167
+		$addons = array();
1168
+		foreach ($this->addons as $addon) {
1169
+			$addons[$addon->name()] = $addon;
1170
+		}
1171
+		return $addons;
1172
+	}
1173
+
1174
+
1175
+
1176
+	/**
1177
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1178
+	 * a stale copy of it around
1179
+	 *
1180
+	 * @param string $model_name
1181
+	 * @return \EEM_Base
1182
+	 * @throws \EE_Error
1183
+	 */
1184
+	public function reset_model($model_name)
1185
+	{
1186
+		$model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1187
+		if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1188
+			return null;
1189
+		}
1190
+		//get that model reset it and make sure we nuke the old reference to it
1191
+		if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1192
+			$this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1193
+		} else {
1194
+			throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1195
+		}
1196
+		return $this->LIB->{$model_class_name};
1197
+	}
1198
+
1199
+
1200
+
1201
+	/**
1202
+	 * Resets the registry.
1203
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1204
+	 * is used in a multisite install.  Here is a list of things that are NOT reset.
1205
+	 * - $_dependency_map
1206
+	 * - $_class_abbreviations
1207
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1208
+	 * - $REQ:  Still on the same request so no need to change.
1209
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1210
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1211
+	 *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1212
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1213
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1214
+	 *             switch or on the restore.
1215
+	 * - $modules
1216
+	 * - $shortcodes
1217
+	 * - $widgets
1218
+	 *
1219
+	 * @param boolean $hard             whether to reset data in the database too, or just refresh
1220
+	 *                                  the Registry to its state at the beginning of the request
1221
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1222
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1223
+	 *                                  currently reinstantiate the singletons at the moment)
1224
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1225
+	 *                                  code instead can just change the model context to a different blog id if necessary
1226
+	 * @return EE_Registry
1227
+	 */
1228
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1229
+	{
1230
+		$instance = self::instance();
1231
+		EEH_Activation::reset();
1232
+		//properties that get reset
1233
+		$instance->_cache_on = true;
1234
+		$instance->CFG = EE_Config::reset($hard, $reinstantiate);
1235
+		$instance->CART = null;
1236
+		$instance->MRM = null;
1237
+		$instance->AssetsRegistry = new Registry();
1238
+		//messages reset
1239
+		EED_Messages::reset();
1240
+		if ($reset_models) {
1241
+			foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1242
+				$instance->reset_model($model_name);
1243
+			}
1244
+		}
1245
+		$instance->LIB = new stdClass();
1246
+		return $instance;
1247
+	}
1248
+
1249
+
1250
+
1251
+	/**
1252
+	 * @override magic methods
1253
+	 * @return void
1254
+	 */
1255
+	final function __destruct()
1256
+	{
1257
+	}
1258
+
1259
+
1260
+
1261
+	/**
1262
+	 * @param $a
1263
+	 * @param $b
1264
+	 */
1265
+	final function __call($a, $b)
1266
+	{
1267
+	}
1268
+
1269
+
1270
+
1271
+	/**
1272
+	 * @param $a
1273
+	 */
1274
+	final function __get($a)
1275
+	{
1276
+	}
1277
+
1278
+
1279
+
1280
+	/**
1281
+	 * @param $a
1282
+	 * @param $b
1283
+	 */
1284
+	final function __set($a, $b)
1285
+	{
1286
+	}
1287
+
1288
+
1289
+
1290
+	/**
1291
+	 * @param $a
1292
+	 */
1293
+	final function __isset($a)
1294
+	{
1295
+	}
1296 1296
 
1297 1297
 
1298 1298
 
1299
-    /**
1300
-     * @param $a
1301
-     */
1302
-    final function __unset($a)
1303
-    {
1304
-    }
1299
+	/**
1300
+	 * @param $a
1301
+	 */
1302
+	final function __unset($a)
1303
+	{
1304
+	}
1305 1305
 
1306 1306
 
1307 1307
 
1308
-    /**
1309
-     * @return array
1310
-     */
1311
-    final function __sleep()
1312
-    {
1313
-        return array();
1314
-    }
1308
+	/**
1309
+	 * @return array
1310
+	 */
1311
+	final function __sleep()
1312
+	{
1313
+		return array();
1314
+	}
1315 1315
 
1316 1316
 
1317 1317
 
1318
-    final function __wakeup()
1319
-    {
1320
-    }
1318
+	final function __wakeup()
1319
+	{
1320
+	}
1321 1321
 
1322 1322
 
1323 1323
 
1324
-    /**
1325
-     * @return string
1326
-     */
1327
-    final function __toString()
1328
-    {
1329
-        return '';
1330
-    }
1324
+	/**
1325
+	 * @return string
1326
+	 */
1327
+	final function __toString()
1328
+	{
1329
+		return '';
1330
+	}
1331 1331
 
1332 1332
 
1333 1333
 
1334
-    final function __invoke()
1335
-    {
1336
-    }
1334
+	final function __invoke()
1335
+	{
1336
+	}
1337 1337
 
1338 1338
 
1339 1339
 
1340
-    final static function __set_state()
1341
-    {
1342
-    }
1340
+	final static function __set_state()
1341
+	{
1342
+	}
1343 1343
 
1344 1344
 
1345 1345
 
1346
-    final function __clone()
1347
-    {
1348
-    }
1346
+	final function __clone()
1347
+	{
1348
+	}
1349 1349
 
1350 1350
 
1351 1351
 
1352
-    /**
1353
-     * @param $a
1354
-     * @param $b
1355
-     */
1356
-    final static function __callStatic($a, $b)
1357
-    {
1358
-    }
1352
+	/**
1353
+	 * @param $a
1354
+	 * @param $b
1355
+	 */
1356
+	final static function __callStatic($a, $b)
1357
+	{
1358
+	}
1359 1359
 
1360 1360
 
1361 1361
 
1362
-    /**
1363
-     * Gets all the custom post type models defined
1364
-     *
1365
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1366
-     */
1367
-    public function cpt_models()
1368
-    {
1369
-        $cpt_models = array();
1370
-        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1371
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1372
-                $cpt_models[$short_name] = $classname;
1373
-            }
1374
-        }
1375
-        return $cpt_models;
1376
-    }
1362
+	/**
1363
+	 * Gets all the custom post type models defined
1364
+	 *
1365
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1366
+	 */
1367
+	public function cpt_models()
1368
+	{
1369
+		$cpt_models = array();
1370
+		foreach ($this->non_abstract_db_models as $short_name => $classname) {
1371
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1372
+				$cpt_models[$short_name] = $classname;
1373
+			}
1374
+		}
1375
+		return $cpt_models;
1376
+	}
1377 1377
 
1378 1378
 
1379 1379
 
1380
-    /**
1381
-     * @return \EE_Config
1382
-     */
1383
-    public static function CFG()
1384
-    {
1385
-        return self::instance()->CFG;
1386
-    }
1380
+	/**
1381
+	 * @return \EE_Config
1382
+	 */
1383
+	public static function CFG()
1384
+	{
1385
+		return self::instance()->CFG;
1386
+	}
1387 1387
 
1388 1388
 
1389 1389
 }
Please login to merge, or discard this patch.