Completed
Branch FET-10486-add-timestamp-checki... (786b14)
by
unknown
79:06 queued 65:28
created
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.
core/libraries/shortcodes/EE_Transaction_Shortcodes.lib.php 3 patches
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -31,10 +31,10 @@  discard block
 block discarded – undo
31 31
  */
32 32
 class EE_Transaction_Shortcodes extends EE_Shortcodes {
33 33
 
34
-    /**
35
-     * @var EE_Payment_Method $_invoice_pm the invoiec payment method for use in invoices etc
36
-     */
37
-    protected $_invoice_pm;
34
+	/**
35
+	 * @var EE_Payment_Method $_invoice_pm the invoiec payment method for use in invoices etc
36
+	 */
37
+	protected $_invoice_pm;
38 38
 
39 39
 	/**
40 40
 	 * EE_Transaction_Shortcodes constructor.
@@ -378,17 +378,17 @@  discard block
 block discarded – undo
378 378
 	 * @return \EE_Payment_Method|null
379 379
 	 */
380 380
 	private function _get_invoice_payment_method(){
381
-	    if( ! $this->_invoice_pm instanceof EE_Payment_Method ) {
382
-            $transaction = $this->_data->txn instanceof EE_Transaction ? $this->_data->txn : null;
383
-            $transaction = ! $transaction instanceof EE_Transaction
384
-                           && is_array($this->_extra_data)
385
-                           && isset($this->_extra_data['data'])
386
-                           && $this->_extra_data['data'] instanceof EE_Messages_Addressee
387
-                ? $this->_extra_data['data']->txn : $transaction;
388
-            //get the invoice payment method, and remember it for the next call too
389
-            $this->_invoice_pm = apply_filters( 'FHEE__EE_Transaction_Shortcodes__get_payment_method__default', EEM_Payment_Method::instance()->get_one_of_type( 'Invoice' ), $transaction );
390
-        }
391
-        return $this->_invoice_pm;
381
+		if( ! $this->_invoice_pm instanceof EE_Payment_Method ) {
382
+			$transaction = $this->_data->txn instanceof EE_Transaction ? $this->_data->txn : null;
383
+			$transaction = ! $transaction instanceof EE_Transaction
384
+						   && is_array($this->_extra_data)
385
+						   && isset($this->_extra_data['data'])
386
+						   && $this->_extra_data['data'] instanceof EE_Messages_Addressee
387
+				? $this->_extra_data['data']->txn : $transaction;
388
+			//get the invoice payment method, and remember it for the next call too
389
+			$this->_invoice_pm = apply_filters( 'FHEE__EE_Transaction_Shortcodes__get_payment_method__default', EEM_Payment_Method::instance()->get_one_of_type( 'Invoice' ), $transaction );
390
+		}
391
+		return $this->_invoice_pm;
392 392
 	}
393 393
 
394 394
 
Please login to merge, or discard this patch.
Spacing   +160 added lines, -160 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-if (!defined('EVENT_ESPRESSO_VERSION') )
3
+if ( ! defined('EVENT_ESPRESSO_VERSION'))
4 4
 	exit('NO direct script access allowed');
5 5
 
6 6
 /**
@@ -45,50 +45,50 @@  discard block
 block discarded – undo
45 45
 
46 46
 
47 47
 	protected function _init_props() {
48
-		$this->label = esc_html__( 'Transaction Shortcodes', 'event_espresso' );
49
-		$this->description = esc_html__( 'All shortcodes specific to transaction related data', 'event_espresso' );
48
+		$this->label = esc_html__('Transaction Shortcodes', 'event_espresso');
49
+		$this->description = esc_html__('All shortcodes specific to transaction related data', 'event_espresso');
50 50
 		$this->_shortcodes = array(
51
-			'[TXN_ID]' => esc_html__( 'The transaction id for the purchase.', 'event_espresso' ),
52
-			'[PAYMENT_URL]' => esc_html__( 'This is a link to make a payment for the event', 'event_espresso' ),
53
-			'[PAYMENT_LINK_IF_NEEDED_*]' => esc_html__( 'This is a special dynamic shortcode that allows one to insert a payment link conditional on there being amount owing on the transaction. Three params are available on this shortcode:', 'event_espresso' ) . '<ul>'
54
-				. '<li>' . sprintf( esc_html__( '%sclass:%s This can be used to indicate css class is given to the containing css element (default is "callout").', 'event_espresso' ), '<strong>', '</strong>' ) . '</li>'
55
-				. '<li>' . sprintf( esc_html__( '%scustom_text:%s This should be a sprintf format text string (with %%s for where the hyperlink tags go) that is used for the generated link text (The default is "You can %%smake a payment here »%%s.)', 'event_espresso' ), '<strong>', '</strong>' ) . '</li>'
56
-				. '<li>' . sprintf( esc_html__( '%scontainer_tag:%s Use this to indicate what container tag you want surrounding the payment link (default is "p").', 'event_espresso' ), '<strong>', '</strong>' ) . '</li>'
51
+			'[TXN_ID]' => esc_html__('The transaction id for the purchase.', 'event_espresso'),
52
+			'[PAYMENT_URL]' => esc_html__('This is a link to make a payment for the event', 'event_espresso'),
53
+			'[PAYMENT_LINK_IF_NEEDED_*]' => esc_html__('This is a special dynamic shortcode that allows one to insert a payment link conditional on there being amount owing on the transaction. Three params are available on this shortcode:', 'event_espresso').'<ul>'
54
+				. '<li>'.sprintf(esc_html__('%sclass:%s This can be used to indicate css class is given to the containing css element (default is "callout").', 'event_espresso'), '<strong>', '</strong>').'</li>'
55
+				. '<li>'.sprintf(esc_html__('%scustom_text:%s This should be a sprintf format text string (with %%s for where the hyperlink tags go) that is used for the generated link text (The default is "You can %%smake a payment here »%%s.)', 'event_espresso'), '<strong>', '</strong>').'</li>'
56
+				. '<li>'.sprintf(esc_html__('%scontainer_tag:%s Use this to indicate what container tag you want surrounding the payment link (default is "p").', 'event_espresso'), '<strong>', '</strong>').'</li>'
57 57
 				. '</ul>',
58
-			'[PAYMENT_DUE_DATE_*]' => esc_html__( 'This is a special dynamic shortcode that allows one to output a payment due date.  It will only result in a date shown if there is money owing.  Three parameters are available on this shortcode:', 'event_espresso' )
58
+			'[PAYMENT_DUE_DATE_*]' => esc_html__('This is a special dynamic shortcode that allows one to output a payment due date.  It will only result in a date shown if there is money owing.  Three parameters are available on this shortcode:', 'event_espresso')
59 59
 				. '<ul>'
60
-				. '<li>' . sprintf( esc_html__( '%sformat:%s This is used to indicate what format the date is in.  Default is whatever is set as date formats for your website.', 'event_espresso' ), '<strong>', '</strong>' ) . '</li>'
61
-				. '<li>' . sprintf( esc_html__( '%sdays_until_due:%s This is the number of days form the transaction creation date that the payment is due.  Defaults to 30.', 'event_espresso' ), '<strong>', '</strong>' ) . '</li>'
62
-				. '<li>' . sprintf( esc_html__( '%sprefix_text:%s You can use this to indicate what text will prefix the date string.  Defaults to "Payment in full due by:"', 'event_espresso' ), '<strong>', '</strong>' ) . '</li>',
63
-			'[INVOICE_LINK]' => esc_html__( 'This is a full html link to the invoice', 'event_espresso' ),
64
-			'[INVOICE_URL]' => esc_html__( 'This is just the url for the invoice', 'event_espresso' ),
65
-			'[INVOICE_LOGO_URL]' => esc_html__( 'This returns the url for the logo uploaded via the invoice settings page.', 'event_espresso' ),
66
-			'[INVOICE_LOGO]' => esc_html__( 'This returns the logo uploaded via the invoice settings page wrapped in img_tags and with a "logo screen" classes. The image size is also set in the img tags automatically to match the uploaded logo.', 'event_espresso' ),
67
-			'[INVOICE_PAYEE_NAME]' => esc_html__( 'This will parse to either: the value of the "Company Name" field in the invoice payment method settings; if that is blank, then the value of the Company Name in the "Your Organization Settings", if that is blank then an empty string.', 'event_espresso' ),
68
-			'[INVOICE_PAYEE_ADDRESS]' => esc_html__( 'This will parse to either: the value of the "Company Address" field in the invoice payment method settings; if that is blank, then the value of the Company Address in the "Your Organization Settings", if that is blank then an empty string.', 'event_espresso' ),
69
-			'[INVOICE_PAYMENT_INSTRUCTIONS]' => esc_html__( 'This will parse to the value of the "Payment Instructions" field found on the Invoice payment methods settings page', 'event_espresso' ),
70
-			'[INVOICE_PAYEE_EMAIL]' => esc_html__( 'This will parse to either: the value of the "Company Email" field in the invoice payment method settings; if that is blank, then the value of the Company Email in the "Your Organization Settings", if that is blank then an empty string.', 'event_espresso' ),
71
-			'[INVOICE_PAYEE_TAX_NUMBER_*]' => sprintf( esc_html__( 'This will parse to either: the value of the "Company Tax Number" field in the invoice payment method settings; if that is blank, then the value of the Company Tax Number in the "Your Organization Settings", if that is blank then an empty string. Note this is also a special dynamic shortcode. You can use the "prefix" parameter to indicate what text you want to use as a prefix before this tax number.  It defaults to "VAT/Tax Number:". To change this prefix you do the following format for this shortcode: %1$s[INVOICE_PAYEE_TAX_NUMBER_* prefix="GST:"]%2$s and that will output: GST: 12345t56.  If you have no tax number in your settings, then no prefix will be output either.', 'event_espresso' ), '<code>', '</code>' ),
72
-			'[TOTAL_COST]' => esc_html__( 'The total cost for the transaction', 'event_espresso' ),
73
-			'[TXN_STATUS]' => esc_html__( 'The transaction status for the transaction.', 'event_espresso' ),
74
-			'[TXN_STATUS_ID]' => esc_html__( 'The ID representing the transaction status as saved in the db.  This tends to be useful for including with css classes for styling certain statuses differently from others.', 'event_espresso' ),
75
-			'[PAYMENT_STATUS]' => esc_html__( 'The transaction status for the transaction. This parses to the same value as the [TXN_STATUS] shortcode and still remains here for legacy support.', 'event_espresso' ),
76
-			'[PAYMENT_GATEWAY]' => esc_html__( 'The payment gateway used for the transaction', 'event_espresso' ),
77
-			'[AMOUNT_PAID]' => esc_html__( 'The amount paid or refunded.  This will only have a value if there was a payment or refund at the time of generating the message.', 'event_espresso' ),
78
-			'[LAST_AMOUNT_PAID]' => esc_html__( 'This is the last payment or refund made on the transaction related to the message being generated.', 'event_espresso' ),
79
-			'[TOTAL_AMOUNT_PAID]' => esc_html__( 'This parses to the total amount paid over all payments', 'event_espresso' ),
80
-			'[TOTAL_OWING]' => esc_html__( 'The total owing on a transaction with no attributes.', 'event_espresso' ),
81
-			'[TXN_SUBTOTAL]' => esc_html__( 'The subtotal for all txn line items.', 'event_espresso' ),
82
-			'[TXN_TAX_SUBTOTAL]' => esc_html__( 'The subtotal for all tax line items.', 'event_espresso' ),
83
-			'[OWING_STATUS_MESSAGE_*]' => esc_html__( 'A dynamic shortcode for adjusting how total owing gets shown. The acceptable attributes on the shortcode are:', 'event_espresso' ) . '<p></ul>' .
84
-				'<li><strong>still_owing</strong>:' . esc_html__( 'If the transaction is not paid in full, then whatever is set for this attribute is shown (otherwise its just the amount owing). The default is:', 'event_espresso' ) . sprintf( esc_html__( '%sPlease make a payment.%s', 'event_espresso' ),  '<a href="[PAYMENT_URL]" class="noPrint">', '</a>' ) . '</li>' .
85
-				'<li><strong>none_owing</strong>:' . esc_html__( 'If the transaction is paid in full, then you can indicate how this gets displayed.  Note, that it defaults to just be the total owing.', 'event_espresso' ) . '</li></ul></p>',
86
-			'[TXN_TOTAL_TICKETS]' => esc_html__( 'The total number of all tickets purchased in a transaction', 'event_espresso' ),
87
-			'[TKT_QTY_PURCHASED]' => sprintf( esc_html__( 'The total number of all tickets purchased in a transaction. %1$sNOTE: This shortcode is good to use in the "[TICKET_LIST]" field but has been deprecated from all other contexts in favor of the more explicit [TXN_TOTAL_TICKETS] shortcode.%2$s', 'event_espresso' ), '<strong>', '</strong>' ),
88
-			'[TRANSACTION_ADMIN_URL]' => esc_html__( 'The url to the admin page for this transaction', 'event_espresso' ),
89
-			'[RECEIPT_URL]' => esc_html__( 'This parses to the generated url for retrieving the receipt for the transaction', 'event_espresso' ),
90
-			'[INVOICE_RECEIPT_SWITCHER_URL]' => esc_html__( 'This parses to the url that will switch to the receipt if an invoice is displayed, and switch to the invoice if receipt is displayed. If a message type OTHER than invoice or receipt is displayed then this will just return the url for the invoice. If the related message type is not active  then will parse to an empty string.', 'event_espresso' ),
91
-			'[INVOICE_RECEIPT_SWITCHER_BUTTON]' => sprintf( esc_html__( 'The same as %1$s[INVOICE_RECEIPT_SWITCHER_URL]%2$s except this returns the html for a button linked to the invoice or receipt.', 'event_espresso' ), '<code>', '</code>' )
60
+				. '<li>'.sprintf(esc_html__('%sformat:%s This is used to indicate what format the date is in.  Default is whatever is set as date formats for your website.', 'event_espresso'), '<strong>', '</strong>').'</li>'
61
+				. '<li>'.sprintf(esc_html__('%sdays_until_due:%s This is the number of days form the transaction creation date that the payment is due.  Defaults to 30.', 'event_espresso'), '<strong>', '</strong>').'</li>'
62
+				. '<li>'.sprintf(esc_html__('%sprefix_text:%s You can use this to indicate what text will prefix the date string.  Defaults to "Payment in full due by:"', 'event_espresso'), '<strong>', '</strong>').'</li>',
63
+			'[INVOICE_LINK]' => esc_html__('This is a full html link to the invoice', 'event_espresso'),
64
+			'[INVOICE_URL]' => esc_html__('This is just the url for the invoice', 'event_espresso'),
65
+			'[INVOICE_LOGO_URL]' => esc_html__('This returns the url for the logo uploaded via the invoice settings page.', 'event_espresso'),
66
+			'[INVOICE_LOGO]' => esc_html__('This returns the logo uploaded via the invoice settings page wrapped in img_tags and with a "logo screen" classes. The image size is also set in the img tags automatically to match the uploaded logo.', 'event_espresso'),
67
+			'[INVOICE_PAYEE_NAME]' => esc_html__('This will parse to either: the value of the "Company Name" field in the invoice payment method settings; if that is blank, then the value of the Company Name in the "Your Organization Settings", if that is blank then an empty string.', 'event_espresso'),
68
+			'[INVOICE_PAYEE_ADDRESS]' => esc_html__('This will parse to either: the value of the "Company Address" field in the invoice payment method settings; if that is blank, then the value of the Company Address in the "Your Organization Settings", if that is blank then an empty string.', 'event_espresso'),
69
+			'[INVOICE_PAYMENT_INSTRUCTIONS]' => esc_html__('This will parse to the value of the "Payment Instructions" field found on the Invoice payment methods settings page', 'event_espresso'),
70
+			'[INVOICE_PAYEE_EMAIL]' => esc_html__('This will parse to either: the value of the "Company Email" field in the invoice payment method settings; if that is blank, then the value of the Company Email in the "Your Organization Settings", if that is blank then an empty string.', 'event_espresso'),
71
+			'[INVOICE_PAYEE_TAX_NUMBER_*]' => sprintf(esc_html__('This will parse to either: the value of the "Company Tax Number" field in the invoice payment method settings; if that is blank, then the value of the Company Tax Number in the "Your Organization Settings", if that is blank then an empty string. Note this is also a special dynamic shortcode. You can use the "prefix" parameter to indicate what text you want to use as a prefix before this tax number.  It defaults to "VAT/Tax Number:". To change this prefix you do the following format for this shortcode: %1$s[INVOICE_PAYEE_TAX_NUMBER_* prefix="GST:"]%2$s and that will output: GST: 12345t56.  If you have no tax number in your settings, then no prefix will be output either.', 'event_espresso'), '<code>', '</code>'),
72
+			'[TOTAL_COST]' => esc_html__('The total cost for the transaction', 'event_espresso'),
73
+			'[TXN_STATUS]' => esc_html__('The transaction status for the transaction.', 'event_espresso'),
74
+			'[TXN_STATUS_ID]' => esc_html__('The ID representing the transaction status as saved in the db.  This tends to be useful for including with css classes for styling certain statuses differently from others.', 'event_espresso'),
75
+			'[PAYMENT_STATUS]' => esc_html__('The transaction status for the transaction. This parses to the same value as the [TXN_STATUS] shortcode and still remains here for legacy support.', 'event_espresso'),
76
+			'[PAYMENT_GATEWAY]' => esc_html__('The payment gateway used for the transaction', 'event_espresso'),
77
+			'[AMOUNT_PAID]' => esc_html__('The amount paid or refunded.  This will only have a value if there was a payment or refund at the time of generating the message.', 'event_espresso'),
78
+			'[LAST_AMOUNT_PAID]' => esc_html__('This is the last payment or refund made on the transaction related to the message being generated.', 'event_espresso'),
79
+			'[TOTAL_AMOUNT_PAID]' => esc_html__('This parses to the total amount paid over all payments', 'event_espresso'),
80
+			'[TOTAL_OWING]' => esc_html__('The total owing on a transaction with no attributes.', 'event_espresso'),
81
+			'[TXN_SUBTOTAL]' => esc_html__('The subtotal for all txn line items.', 'event_espresso'),
82
+			'[TXN_TAX_SUBTOTAL]' => esc_html__('The subtotal for all tax line items.', 'event_espresso'),
83
+			'[OWING_STATUS_MESSAGE_*]' => esc_html__('A dynamic shortcode for adjusting how total owing gets shown. The acceptable attributes on the shortcode are:', 'event_espresso').'<p></ul>'.
84
+				'<li><strong>still_owing</strong>:'.esc_html__('If the transaction is not paid in full, then whatever is set for this attribute is shown (otherwise its just the amount owing). The default is:', 'event_espresso').sprintf(esc_html__('%sPlease make a payment.%s', 'event_espresso'), '<a href="[PAYMENT_URL]" class="noPrint">', '</a>').'</li>'.
85
+				'<li><strong>none_owing</strong>:'.esc_html__('If the transaction is paid in full, then you can indicate how this gets displayed.  Note, that it defaults to just be the total owing.', 'event_espresso').'</li></ul></p>',
86
+			'[TXN_TOTAL_TICKETS]' => esc_html__('The total number of all tickets purchased in a transaction', 'event_espresso'),
87
+			'[TKT_QTY_PURCHASED]' => sprintf(esc_html__('The total number of all tickets purchased in a transaction. %1$sNOTE: This shortcode is good to use in the "[TICKET_LIST]" field but has been deprecated from all other contexts in favor of the more explicit [TXN_TOTAL_TICKETS] shortcode.%2$s', 'event_espresso'), '<strong>', '</strong>'),
88
+			'[TRANSACTION_ADMIN_URL]' => esc_html__('The url to the admin page for this transaction', 'event_espresso'),
89
+			'[RECEIPT_URL]' => esc_html__('This parses to the generated url for retrieving the receipt for the transaction', 'event_espresso'),
90
+			'[INVOICE_RECEIPT_SWITCHER_URL]' => esc_html__('This parses to the url that will switch to the receipt if an invoice is displayed, and switch to the invoice if receipt is displayed. If a message type OTHER than invoice or receipt is displayed then this will just return the url for the invoice. If the related message type is not active  then will parse to an empty string.', 'event_espresso'),
91
+			'[INVOICE_RECEIPT_SWITCHER_BUTTON]' => sprintf(esc_html__('The same as %1$s[INVOICE_RECEIPT_SWITCHER_URL]%2$s except this returns the html for a button linked to the invoice or receipt.', 'event_espresso'), '<code>', '</code>')
92 92
 			);
93 93
 	}
94 94
 
@@ -99,40 +99,40 @@  discard block
 block discarded – undo
99 99
 	 * @param  string $shortcode the shortcode to be parsed.
100 100
 	 * @return string parsed shortcode
101 101
 	 */
102
-	protected function _parser( $shortcode ) {
102
+	protected function _parser($shortcode) {
103 103
 
104 104
 		//attempt to get the transaction.  Since this is potentially used in more fields, we may have to look in the _extra_data for the transaction.
105 105
 		$transaction = $this->_data->txn instanceof EE_Transaction ? $this->_data->txn : null;
106
-		$transaction = ! $transaction instanceof EE_Transaction && is_array( $this->_extra_data ) &&  isset( $this->_extra_data['data'] ) && $this->_extra_data['data'] instanceof EE_Messages_Addressee ? $this->_extra_data['data']->txn: $transaction;
106
+		$transaction = ! $transaction instanceof EE_Transaction && is_array($this->_extra_data) && isset($this->_extra_data['data']) && $this->_extra_data['data'] instanceof EE_Messages_Addressee ? $this->_extra_data['data']->txn : $transaction;
107 107
 
108 108
 		//payment
109 109
 		$payment = $this->_data->payment instanceof EE_Payment ? $this->_data->payment : null;
110
-		$payment = ! $payment instanceof EE_Payment && is_array( $this->_extra_data ) &&  isset( $this->_extra_data['data'] ) && $this->_extra_data['data'] instanceof EE_Messages_Addressee ? $this->_extra_data['data']->payment: $payment;
110
+		$payment = ! $payment instanceof EE_Payment && is_array($this->_extra_data) && isset($this->_extra_data['data']) && $this->_extra_data['data'] instanceof EE_Messages_Addressee ? $this->_extra_data['data']->payment : $payment;
111 111
 
112 112
 
113
-		if ( ! $transaction instanceof EE_Transaction ) {
113
+		if ( ! $transaction instanceof EE_Transaction) {
114 114
 			return '';
115 115
 		}
116 116
 
117
-		switch ( $shortcode ) {
117
+		switch ($shortcode) {
118 118
 			case '[TXN_ID]' :
119 119
 				return $transaction->ID();
120 120
 				break;
121 121
 
122 122
 			case '[PAYMENT_URL]' :
123 123
 				$payment_url = $transaction->payment_overview_url();
124
-				return empty( $payment_url ) ? esc_html__( 'http://dummypaymenturlforpreview.com', 'event_espresso' ) : $payment_url;
124
+				return empty($payment_url) ? esc_html__('http://dummypaymenturlforpreview.com', 'event_espresso') : $payment_url;
125 125
 				break;
126 126
 
127 127
 			case '[INVOICE_LINK]' :
128 128
 				$invoice_url = $transaction->invoice_url();
129
-				$invoice_url = empty( $invoice_url ) ? 'http://dummyinvoicelinksforpreview.com' : $invoice_url;
130
-				return sprintf( esc_html__( '%sClick here for Invoice%s', 'event_espresso' ), '<a href="' . $invoice_url . '">', '</a>' );
129
+				$invoice_url = empty($invoice_url) ? 'http://dummyinvoicelinksforpreview.com' : $invoice_url;
130
+				return sprintf(esc_html__('%sClick here for Invoice%s', 'event_espresso'), '<a href="'.$invoice_url.'">', '</a>');
131 131
 				break; /**/
132 132
 
133 133
 			case '[INVOICE_URL]' :
134 134
 				$invoice_url = $transaction->invoice_url();
135
-				return empty( $invoice_url ) ? 'http://dummyinvoicelinksforpreview.com' : $invoice_url;
135
+				return empty($invoice_url) ? 'http://dummyinvoicelinksforpreview.com' : $invoice_url;
136 136
 				break;
137 137
 
138 138
 			case '[INVOICE_LOGO_URL]' :
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
 				break;
141 141
 
142 142
 			case '[INVOICE_LOGO]' :
143
-				return $this->_get_invoice_logo( true );
143
+				return $this->_get_invoice_logo(true);
144 144
 				break;
145 145
 
146 146
 			case '[INVOICE_PAYEE_NAME]' :
@@ -162,18 +162,18 @@  discard block
 block discarded – undo
162 162
 
163 163
 			case '[TOTAL_COST]' :
164 164
 				$total = $transaction->total();
165
-				return ! empty($total) ? EEH_Template::format_currency( $total ) : '';
165
+				return ! empty($total) ? EEH_Template::format_currency($total) : '';
166 166
 				break;
167 167
 
168 168
 			case '[PAYMENT_STATUS]' :
169 169
 				$status = $transaction->pretty_status();
170
-				return ! empty($status) ? $status : esc_html__( 'Unknown', 'event_espresso' );
170
+				return ! empty($status) ? $status : esc_html__('Unknown', 'event_espresso');
171 171
 				break; /**/
172 172
 
173 173
 			// note the [payment_status] shortcode is kind of misleading because payment status might be different from txn status so I'm adding this here for clarity.
174 174
 			case '[TXN_STATUS]':
175 175
 				$status = $transaction->pretty_status();
176
-				return ! empty( $status ) ? $status : esc_html__( 'Unknown', 'event_espresso' );
176
+				return ! empty($status) ? $status : esc_html__('Unknown', 'event_espresso');
177 177
 				break;
178 178
 
179 179
 			case '[TXN_STATUS_ID]' :
@@ -181,36 +181,36 @@  discard block
 block discarded – undo
181 181
 				break;
182 182
 
183 183
 			case '[PAYMENT_GATEWAY]' :
184
-				return $this->_get_payment_gateway( $transaction );
184
+				return $this->_get_payment_gateway($transaction);
185 185
 				break;
186 186
 
187 187
 			case '[AMOUNT_PAID]' :
188 188
 				return $payment instanceof EE_Payment
189
-					? EEH_Template::format_currency( $payment->amount() )
190
-					: EEH_Template::format_currency( 0 );
189
+					? EEH_Template::format_currency($payment->amount())
190
+					: EEH_Template::format_currency(0);
191 191
 				break;
192 192
 
193 193
 			case '[LAST_AMOUNT_PAID]' :
194 194
 				$last_payment = $transaction->last_payment();
195 195
 				return $last_payment instanceof EE_Payment
196
-					? EEH_Template::format_currency( $last_payment->amount() )
197
-					: EEH_Template::format_currency( 0 );
196
+					? EEH_Template::format_currency($last_payment->amount())
197
+					: EEH_Template::format_currency(0);
198 198
 
199 199
 			case '[TOTAL_AMOUNT_PAID]' :
200
-				return EEH_Template::format_currency( $transaction->paid() );
200
+				return EEH_Template::format_currency($transaction->paid());
201 201
 				break;
202 202
 
203 203
 			case '[TOTAL_OWING]' :
204 204
 				$total_owing = $transaction->remaining();
205
-				return EEH_Template::format_currency( $total_owing );
205
+				return EEH_Template::format_currency($total_owing);
206 206
 				break;
207 207
 
208 208
 			case '[TXN_SUBTOTAL]' :
209
-				return EEH_Template::format_currency( $this->_get_subtotal() );
209
+				return EEH_Template::format_currency($this->_get_subtotal());
210 210
 				break;
211 211
 
212 212
 			case '[TXN_TAX_SUBTOTAL]' :
213
-				return EEH_Template::format_currency( $this->_get_subtotal( true ) );
213
+				return EEH_Template::format_currency($this->_get_subtotal(true));
214 214
 				break;
215 215
 
216 216
 			case '[TKT_QTY_PURCHASED]' :
@@ -219,9 +219,9 @@  discard block
 block discarded – undo
219 219
 				break;
220 220
 
221 221
 			case '[TRANSACTION_ADMIN_URL]' :
222
-				require_once EE_CORE . 'admin/EE_Admin_Page.core.php';
223
-				$query_args = array( 'page' => 'espresso_transactions', 'action' => 'view_transaction', 'TXN_ID' => $transaction->ID() );
224
-				$url = EE_Admin_Page::add_query_args_and_nonce( $query_args, admin_url( 'admin.php' ) );
222
+				require_once EE_CORE.'admin/EE_Admin_Page.core.php';
223
+				$query_args = array('page' => 'espresso_transactions', 'action' => 'view_transaction', 'TXN_ID' => $transaction->ID());
224
+				$url = EE_Admin_Page::add_query_args_and_nonce($query_args, admin_url('admin.php'));
225 225
 				return $url;
226 226
 				break;
227 227
 
@@ -229,14 +229,14 @@  discard block
 block discarded – undo
229 229
 				//get primary_registration
230 230
 				$reg = $this->_data->primary_reg_obj;
231 231
 
232
-				if ( ! $reg instanceof EE_Registration ) {
232
+				if ( ! $reg instanceof EE_Registration) {
233 233
 					return '';
234 234
 				}
235 235
 				return $reg->receipt_url();
236 236
 				break;
237 237
 
238 238
 			case '[INVOICE_RECEIPT_SWITCHER_URL]' :
239
-				return $this->_get_invoice_receipt_switcher( false );
239
+				return $this->_get_invoice_receipt_switcher(false);
240 240
 				break;
241 241
 
242 242
 			case '[INVOICE_RECEIPT_SWITCHER_BUTTON]' :
@@ -246,20 +246,20 @@  discard block
 block discarded – undo
246 246
 
247 247
 		}
248 248
 
249
-		if ( strpos( $shortcode, '[OWING_STATUS_MESSAGE_*' ) !== false ) {
250
-			return $this->_get_custom_total_owing( $shortcode );
249
+		if (strpos($shortcode, '[OWING_STATUS_MESSAGE_*') !== false) {
250
+			return $this->_get_custom_total_owing($shortcode);
251 251
 		}
252 252
 
253
-		if ( strpos( $shortcode, '[INVOICE_PAYEE_TAX_NUMBER_*' ) !== false ) {
254
-			return $this->_get_invoice_payee_tax_number( $shortcode );
253
+		if (strpos($shortcode, '[INVOICE_PAYEE_TAX_NUMBER_*') !== false) {
254
+			return $this->_get_invoice_payee_tax_number($shortcode);
255 255
 		}
256 256
 
257
-		if ( strpos( $shortcode, '[PAYMENT_LINK_IF_NEEDED_*' ) !== false ) {
258
-			return $this->_get_payment_link_if_needed( $shortcode );
257
+		if (strpos($shortcode, '[PAYMENT_LINK_IF_NEEDED_*') !== false) {
258
+			return $this->_get_payment_link_if_needed($shortcode);
259 259
 		}
260 260
 
261
-		if ( strpos( $shortcode, '[PAYMENT_DUE_DATE_*' ) !== false ) {
262
-			return $this->_get_payment_due_date( $shortcode, $transaction );
261
+		if (strpos($shortcode, '[PAYMENT_DUE_DATE_*') !== false) {
262
+			return $this->_get_payment_due_date($shortcode, $transaction);
263 263
 		}
264 264
 
265 265
 		return '';
@@ -276,19 +276,19 @@  discard block
 block discarded – undo
276 276
 	 *
277 277
 	 * @return string parsed.
278 278
 	 */
279
-	private function _get_custom_total_owing( $shortcode ) {
280
-		$valid_shortcodes = array( 'transaction' );
281
-		$attrs = $this->_get_shortcode_attrs( $shortcode );
279
+	private function _get_custom_total_owing($shortcode) {
280
+		$valid_shortcodes = array('transaction');
281
+		$attrs = $this->_get_shortcode_attrs($shortcode);
282 282
 
283 283
 		//ensure default is set.
284 284
 		$addressee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
285 285
 		$total_owing = $addressee instanceof EE_Messages_Addressee && $addressee->txn instanceof EE_Transaction ? $addressee->txn->remaining() : 0;
286 286
 
287
-		if ( $total_owing > 0 ) {
288
-			$owing_content = ! empty( $attrs['still_owing'] ) ? $attrs['still_owing'] : sprintf( esc_html__( '%sPlease make a payment.%s', 'event_espresso' ),  '<a href="[PAYMENT_URL]" class="noPrint">', '</a>' );
289
-			$owing_content = $this->_shortcode_helper->parse_message_template( $owing_content, $addressee, $valid_shortcodes, $this->_message_type, $this->_messenger, $this->_message );
287
+		if ($total_owing > 0) {
288
+			$owing_content = ! empty($attrs['still_owing']) ? $attrs['still_owing'] : sprintf(esc_html__('%sPlease make a payment.%s', 'event_espresso'), '<a href="[PAYMENT_URL]" class="noPrint">', '</a>');
289
+			$owing_content = $this->_shortcode_helper->parse_message_template($owing_content, $addressee, $valid_shortcodes, $this->_message_type, $this->_messenger, $this->_message);
290 290
 		} else {
291
-			$owing_content = ! empty( $attrs['none_owing']) ? $attrs['none_owing'] : '';
291
+			$owing_content = ! empty($attrs['none_owing']) ? $attrs['none_owing'] : '';
292 292
 		}
293 293
 
294 294
 		return $owing_content;
@@ -300,8 +300,8 @@  discard block
 block discarded – undo
300 300
 	 * @param EE_Transaction $transaction
301 301
 	 * @return string
302 302
 	 */
303
-	private function _get_payment_gateway( $transaction ) {
304
-		$pm = $this->_get_invoice_payment_method( $transaction );
303
+	private function _get_payment_gateway($transaction) {
304
+		$pm = $this->_get_invoice_payment_method($transaction);
305 305
 		return $pm instanceof EE_Payment_Method ? $pm->name() : '';
306 306
 	}
307 307
 
@@ -316,37 +316,37 @@  discard block
 block discarded – undo
316 316
 	 *
317 317
 	 * @return string url or html
318 318
 	 */
319
-	private function _get_invoice_logo( $img_tags = false ) {
319
+	private function _get_invoice_logo($img_tags = false) {
320 320
 		//try to get the invoice payment method's logo for this transaction image first
321 321
 		$pm = $this->_get_invoice_payment_method();
322
-		if ( $pm instanceof EE_Payment_Method ){
323
-			$invoice_logo_url = $pm->get_extra_meta( 'pdf_logo_image', true );
322
+		if ($pm instanceof EE_Payment_Method) {
323
+			$invoice_logo_url = $pm->get_extra_meta('pdf_logo_image', true);
324 324
 		} else {
325 325
 			$invoice_logo_url = null;
326 326
 		}
327
-		if ( empty( $invoice_logo_url ) ){
327
+		if (empty($invoice_logo_url)) {
328 328
 			$invoice_logo_url = EE_Registry::instance()->CFG->organization->logo_url;
329 329
 		}
330 330
 
331
-		if ( empty( $invoice_logo_url ) ) {
331
+		if (empty($invoice_logo_url)) {
332 332
 			return '';
333 333
 		}
334 334
 
335
-		if ( ! $img_tags ) {
335
+		if ( ! $img_tags) {
336 336
 			return $invoice_logo_url;
337 337
 		}
338 338
 
339 339
 		//image tags have been requested.
340
-		$image_size = getimagesize( $invoice_logo_url );
340
+		$image_size = getimagesize($invoice_logo_url);
341 341
 
342 342
 		//if image is wider than 300px, set the width to 300
343
-		if ( $image_size[0] > 300 ) {
343
+		if ($image_size[0] > 300) {
344 344
 			$image_width = 300;
345 345
 		} else {
346 346
 			$image_width = $image_size[0];
347 347
 		}
348 348
 
349
-		return '<img class="logo screen" src="' . $invoice_logo_url . '" width="' . $image_width . '" alt="logo" />';
349
+		return '<img class="logo screen" src="'.$invoice_logo_url.'" width="'.$image_width.'" alt="logo" />';
350 350
 	}
351 351
 
352 352
 
@@ -363,10 +363,10 @@  discard block
 block discarded – undo
363 363
 	private function _get_invoice_payee_name() {
364 364
 		$payee_name = null;
365 365
 		$pm = $this->_get_invoice_payment_method();
366
-		if ( $pm instanceof EE_Payment_Method ){
367
-			$payee_name = $pm->get_extra_meta( 'pdf_payee_name', true );
366
+		if ($pm instanceof EE_Payment_Method) {
367
+			$payee_name = $pm->get_extra_meta('pdf_payee_name', true);
368 368
 		}
369
-		$payee_name = empty( $payee_name ) ? EE_Registry::instance()->CFG->organization->get_pretty( 'name' ) : $payee_name;
369
+		$payee_name = empty($payee_name) ? EE_Registry::instance()->CFG->organization->get_pretty('name') : $payee_name;
370 370
 		return $payee_name;
371 371
 	}
372 372
 
@@ -377,8 +377,8 @@  discard block
 block discarded – undo
377 377
 	 *
378 378
 	 * @return \EE_Payment_Method|null
379 379
 	 */
380
-	private function _get_invoice_payment_method(){
381
-	    if( ! $this->_invoice_pm instanceof EE_Payment_Method ) {
380
+	private function _get_invoice_payment_method() {
381
+	    if ( ! $this->_invoice_pm instanceof EE_Payment_Method) {
382 382
             $transaction = $this->_data->txn instanceof EE_Transaction ? $this->_data->txn : null;
383 383
             $transaction = ! $transaction instanceof EE_Transaction
384 384
                            && is_array($this->_extra_data)
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
                            && $this->_extra_data['data'] instanceof EE_Messages_Addressee
387 387
                 ? $this->_extra_data['data']->txn : $transaction;
388 388
             //get the invoice payment method, and remember it for the next call too
389
-            $this->_invoice_pm = apply_filters( 'FHEE__EE_Transaction_Shortcodes__get_payment_method__default', EEM_Payment_Method::instance()->get_one_of_type( 'Invoice' ), $transaction );
389
+            $this->_invoice_pm = apply_filters('FHEE__EE_Transaction_Shortcodes__get_payment_method__default', EEM_Payment_Method::instance()->get_one_of_type('Invoice'), $transaction);
390 390
         }
391 391
         return $this->_invoice_pm;
392 392
 	}
@@ -404,10 +404,10 @@  discard block
 block discarded – undo
404 404
 	private function _get_invoice_payee_email() {
405 405
 		$payee_email = null;
406 406
 		$pm = $this->_get_invoice_payment_method();
407
-		if ( $pm instanceof EE_Payment_Method ){
408
-			$payee_email = $pm->get_extra_meta( 'pdf_payee_email', true );
407
+		if ($pm instanceof EE_Payment_Method) {
408
+			$payee_email = $pm->get_extra_meta('pdf_payee_email', true);
409 409
 		}
410
-		$payee_email = empty( $payee_email ) ? EE_Registry::instance()->CFG->organization->get_pretty( 'email' ) : $payee_email;
410
+		$payee_email = empty($payee_email) ? EE_Registry::instance()->CFG->organization->get_pretty('email') : $payee_email;
411 411
 		return $payee_email;
412 412
 	}
413 413
 
@@ -423,24 +423,24 @@  discard block
 block discarded – undo
423 423
 	 *
424 424
 	 * @return string
425 425
 	 */
426
-	private function _get_invoice_payee_tax_number( $shortcode ) {
426
+	private function _get_invoice_payee_tax_number($shortcode) {
427 427
 		$payee_tax_number = null;
428 428
 		$pm = $this->_get_invoice_payment_method();
429
-		if ( $pm instanceof EE_Payment_Method ){
430
-			$payee_tax_number = $pm->get_extra_meta( 'pdf_payee_tax_number', true );
429
+		if ($pm instanceof EE_Payment_Method) {
430
+			$payee_tax_number = $pm->get_extra_meta('pdf_payee_tax_number', true);
431 431
 		}
432
-		$payee_tax_number = empty( $payee_tax_number ) ? EE_Registry::instance()->CFG->organization->vat : $payee_tax_number;
432
+		$payee_tax_number = empty($payee_tax_number) ? EE_Registry::instance()->CFG->organization->vat : $payee_tax_number;
433 433
 
434
-		if ( empty( $payee_tax_number ) ) {
434
+		if (empty($payee_tax_number)) {
435 435
 			return '';
436 436
 		}
437 437
 
438 438
 		//any attributes?
439
-		$attrs = $this->_get_shortcode_attrs( $shortcode );
439
+		$attrs = $this->_get_shortcode_attrs($shortcode);
440 440
 
441 441
 		//prefix?
442
-		$prefix = isset( $attrs['prefix'] ) ? $attrs['prefix'] : esc_html__( 'VAT/Tax Number: ', 'event_espresso' );
443
-		return $prefix . $payee_tax_number;
442
+		$prefix = isset($attrs['prefix']) ? $attrs['prefix'] : esc_html__('VAT/Tax Number: ', 'event_espresso');
443
+		return $prefix.$payee_tax_number;
444 444
 	}
445 445
 
446 446
 
@@ -457,22 +457,22 @@  discard block
 block discarded – undo
457 457
 	private function _get_invoice_payee_address() {
458 458
 		$payee_address = null;
459 459
 		$pm = $this->_get_invoice_payment_method();
460
-		if ( $pm instanceof EE_Payment_Method ){
461
-			$payee_address = $pm->get_extra_meta( 'pdf_payee_address', true );
460
+		if ($pm instanceof EE_Payment_Method) {
461
+			$payee_address = $pm->get_extra_meta('pdf_payee_address', true);
462 462
 		}
463
-		if ( empty( $payee_address ) ) {
463
+		if (empty($payee_address)) {
464 464
 			$organization = EE_Registry::instance()->CFG->organization;
465
-			$payee_address = $organization->get_pretty( 'address_1' ) . '<br>';
466
-			$payee_address .= ! empty( $organization->address_2 ) ? $organization->get_pretty( 'address_2' ) . '<br>' : '';
467
-			$payee_address .= $organization->get_pretty( 'city' ) . '<br>';
465
+			$payee_address = $organization->get_pretty('address_1').'<br>';
466
+			$payee_address .= ! empty($organization->address_2) ? $organization->get_pretty('address_2').'<br>' : '';
467
+			$payee_address .= $organization->get_pretty('city').'<br>';
468 468
 
469 469
 			//state
470
-			$state = EE_Registry::instance()->load_model( 'State' )->get_one_by_ID( $organization->STA_ID );
471
-			$payee_address .= $state instanceof EE_State ? $state->name()  : '';
470
+			$state = EE_Registry::instance()->load_model('State')->get_one_by_ID($organization->STA_ID);
471
+			$payee_address .= $state instanceof EE_State ? $state->name() : '';
472 472
 
473 473
 			//Country
474
-			$payee_address .= ! empty( $organization->CNT_ISO ) ? ', ' . $organization->CNT_ISO . '<br>' : '';
475
-			$payee_address .= ! empty( $organization->zip ) ? $organization->zip : '';
474
+			$payee_address .= ! empty($organization->CNT_ISO) ? ', '.$organization->CNT_ISO.'<br>' : '';
475
+			$payee_address .= ! empty($organization->zip) ? $organization->zip : '';
476 476
 		}
477 477
 		return $payee_address;
478 478
 	}
@@ -490,7 +490,7 @@  discard block
 block discarded – undo
490 490
 	private function _get_invoice_payment_instructions() {
491 491
 		$instructions = null;
492 492
 		$pm = $this->_get_invoice_payment_method();
493
-		return ( $pm instanceof EE_Payment_Method ) ? $pm->get_extra_meta( 'pdf_instructions', true ) : '';
493
+		return ($pm instanceof EE_Payment_Method) ? $pm->get_extra_meta('pdf_instructions', true) : '';
494 494
 	}
495 495
 
496 496
 
@@ -504,27 +504,27 @@  discard block
 block discarded – undo
504 504
 	 *
505 505
 	 * @return string
506 506
 	 */
507
-	protected function _get_invoice_receipt_switcher( $button = true ) {
507
+	protected function _get_invoice_receipt_switcher($button = true) {
508 508
 		$reg = $this->_data->primary_reg_obj;
509
-		$message_type = isset( $this->_extra_data['message_type'] ) ? $this->_extra_data['message_type'] : '';
510
-		if ( ! $reg instanceof EE_Registration || empty( $message_type ) ) {
509
+		$message_type = isset($this->_extra_data['message_type']) ? $this->_extra_data['message_type'] : '';
510
+		if ( ! $reg instanceof EE_Registration || empty($message_type)) {
511 511
 			return '';
512 512
 		}
513 513
 
514
-		$switch_to_invoice = ! $message_type instanceof EE_Invoice_message_type  ? true : false;
515
-		$switch_to_label = $switch_to_invoice && ! $message_type instanceof EE_Receipt_message_type ? esc_html__( 'View Invoice', 'event_espresso' ) : esc_html__( 'Switch to Invoice', 'event_espresso' );
516
-		$switch_to_label = ! $switch_to_invoice ? esc_html__( 'Switch to Receipt', 'event_espresso' ) : $switch_to_label;
514
+		$switch_to_invoice = ! $message_type instanceof EE_Invoice_message_type ? true : false;
515
+		$switch_to_label = $switch_to_invoice && ! $message_type instanceof EE_Receipt_message_type ? esc_html__('View Invoice', 'event_espresso') : esc_html__('Switch to Invoice', 'event_espresso');
516
+		$switch_to_label = ! $switch_to_invoice ? esc_html__('Switch to Receipt', 'event_espresso') : $switch_to_label;
517 517
 		$switch_to_url = $switch_to_invoice ? $reg->invoice_url() : $reg->receipt_url();
518 518
 
519
-		if ( ! $button ) {
519
+		if ( ! $button) {
520 520
 			return $switch_to_url;
521 521
 		}
522 522
 
523
-		if ( ! empty( $switch_to_url ) ) {
523
+		if ( ! empty($switch_to_url)) {
524 524
 
525 525
 			return  '
526
-	<form method="post" action="' . $switch_to_url . '" >
527
-		<input class="print_button" type="submit" value="' . $switch_to_label . '" />
526
+	<form method="post" action="' . $switch_to_url.'" >
527
+		<input class="print_button" type="submit" value="' . $switch_to_label.'" />
528 528
 	</form>
529 529
 			';
530 530
 		}
@@ -542,10 +542,10 @@  discard block
 block discarded – undo
542 542
 	 *
543 543
 	 * @return int
544 544
 	 */
545
-	private function _get_subtotal( $tax = false ) {
546
-		$grand_total = isset( $this->_data->grand_total_line_item ) ? $this->_data->grand_total_line_item : null;
545
+	private function _get_subtotal($tax = false) {
546
+		$grand_total = isset($this->_data->grand_total_line_item) ? $this->_data->grand_total_line_item : null;
547 547
 
548
-		if ( ! $grand_total instanceof EE_Line_Item ) {
548
+		if ( ! $grand_total instanceof EE_Line_Item) {
549 549
 			return 0;
550 550
 		}
551 551
 
@@ -564,26 +564,26 @@  discard block
 block discarded – undo
564 564
 	 *
565 565
 	 * @return string parsed.
566 566
 	 */
567
-	private function _get_payment_link_if_needed( $shortcode ) {
568
-		$valid_shortcodes = array( 'transaction' );
569
-		$attrs = $this->_get_shortcode_attrs( $shortcode );
567
+	private function _get_payment_link_if_needed($shortcode) {
568
+		$valid_shortcodes = array('transaction');
569
+		$attrs = $this->_get_shortcode_attrs($shortcode);
570 570
 
571 571
 		//ensure default is set.
572 572
 		$addressee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
573 573
 		$total_owing = $addressee instanceof EE_Messages_Addressee && $addressee->txn instanceof EE_Transaction ? $addressee->txn->remaining() : 0;
574 574
 
575
-		if ( $total_owing > 0 ) {
576
-			$class = isset( $attrs['class'] ) ? $attrs['class'] : 'callout';
577
-			$custom_text = isset( $attrs['custom_text'] ) ? $attrs['custom_text'] : 'You can %smake a payment here »%s.';
578
-			$container_tag = isset( $attrs['container_tag'] ) ? $attrs['container_tag'] : 'p';
579
-			$opening_tag = ! empty( $container_tag ) ? '<' . $container_tag : '';
580
-			$opening_tag .= ! empty( $opening_tag ) && ! empty( $class ) ? ' class="' . $class . '"' : $opening_tag;
581
-			$opening_tag .= ! empty( $opening_tag ) ? '>' : $opening_tag;
582
-			$closing_tag = ! empty( $container_tag ) ? '</' . $container_tag .'>' : '';
583
-			$content = $opening_tag . sprintf( $custom_text, '<a href="[PAYMENT_URL]">', '</a>' ) . $closing_tag;
575
+		if ($total_owing > 0) {
576
+			$class = isset($attrs['class']) ? $attrs['class'] : 'callout';
577
+			$custom_text = isset($attrs['custom_text']) ? $attrs['custom_text'] : 'You can %smake a payment here »%s.';
578
+			$container_tag = isset($attrs['container_tag']) ? $attrs['container_tag'] : 'p';
579
+			$opening_tag = ! empty($container_tag) ? '<'.$container_tag : '';
580
+			$opening_tag .= ! empty($opening_tag) && ! empty($class) ? ' class="'.$class.'"' : $opening_tag;
581
+			$opening_tag .= ! empty($opening_tag) ? '>' : $opening_tag;
582
+			$closing_tag = ! empty($container_tag) ? '</'.$container_tag.'>' : '';
583
+			$content = $opening_tag.sprintf($custom_text, '<a href="[PAYMENT_URL]">', '</a>').$closing_tag;
584 584
 
585 585
 			//we need to re run this string through the parser to catch any shortcodes that are in it.
586
-			$owing_content = $this->_shortcode_helper->parse_message_template( $content, $addressee, $valid_shortcodes, $this->_message_type, $this->_messenger, $this->_message );
586
+			$owing_content = $this->_shortcode_helper->parse_message_template($content, $addressee, $valid_shortcodes, $this->_message_type, $this->_messenger, $this->_message);
587 587
 		} else {
588 588
 			return '';
589 589
 		}
@@ -603,31 +603,31 @@  discard block
 block discarded – undo
603 603
 	 * @param EE_Transaction $transaction
604 604
 	 * @return string
605 605
 	 */
606
-	protected function _get_payment_due_date( $shortcode, EE_Transaction $transaction ) {
606
+	protected function _get_payment_due_date($shortcode, EE_Transaction $transaction) {
607 607
 		//if transaction is paid in full then we can just return an empty string
608
-		if ( $transaction->remaining() === 0 ) {
608
+		if ($transaction->remaining() === 0) {
609 609
 			return '';
610 610
 		}
611 611
 
612
-		$attrs = $this->_get_shortcode_attrs( $shortcode );
613
-		$format = isset( $attrs['format'] ) ? $attrs['format'] : get_option( 'date_format' );
614
-		$days_until_due = isset( $attrs['days_until_due'] ) ? (int) $attrs['days_until_due'] : 30;
615
-		$prefix_text = isset( $attrs['prefix_text'] ) ? $attrs['prefix_text'] : esc_html__( 'Payment in full due by: ', 'event_espresso' );
616
-		$transaction_created = $transaction->get_DateTime_object( 'TXN_timestamp' );
612
+		$attrs = $this->_get_shortcode_attrs($shortcode);
613
+		$format = isset($attrs['format']) ? $attrs['format'] : get_option('date_format');
614
+		$days_until_due = isset($attrs['days_until_due']) ? (int) $attrs['days_until_due'] : 30;
615
+		$prefix_text = isset($attrs['prefix_text']) ? $attrs['prefix_text'] : esc_html__('Payment in full due by: ', 'event_espresso');
616
+		$transaction_created = $transaction->get_DateTime_object('TXN_timestamp');
617 617
 
618 618
 		//setup date due:
619 619
 		try {
620
-			if ( $transaction_created instanceof DateTime ) {
621
-				$date_due = $transaction_created->add( new DateInterval( 'P' . $days_until_due . 'D' ) )->format( $format );
620
+			if ($transaction_created instanceof DateTime) {
621
+				$date_due = $transaction_created->add(new DateInterval('P'.$days_until_due.'D'))->format($format);
622 622
 			} else {
623 623
 				throw new Exception();
624 624
 			}
625
-		} catch( Exception $e ) {
625
+		} catch (Exception $e) {
626 626
 			//format was likely invalid.
627 627
 			$date_due = 'Unable to calculate date due, likely the format string is invalid.';
628 628
 		}
629 629
 
630
-		return $prefix_text . $date_due;
630
+		return $prefix_text.$date_due;
631 631
 	}
632 632
 
633 633
 } //end EE_Transaction Shortcodes library
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,7 @@
 block discarded – undo
1 1
 <?php
2
-if (!defined('EVENT_ESPRESSO_VERSION') )
2
+if (!defined('EVENT_ESPRESSO_VERSION') ) {
3 3
 	exit('NO direct script access allowed');
4
+}
4 5
 
5 6
 /**
6 7
  * Event Espresso
Please login to merge, or discard this patch.
admin_pages/maintenance/templates/ee_data_reset_and_delete.template.php 1 patch
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -7,14 +7,14 @@  discard block
 block discarded – undo
7 7
 /** @var string $delete_db_url */
8 8
 ?>
9 9
 <h2>
10
-	<?php esc_html_e( 'Reset/Delete Data for Event Espresso', 'event_espresso' );?>
10
+	<?php esc_html_e('Reset/Delete Data for Event Espresso', 'event_espresso'); ?>
11 11
 </h2>
12 12
 <br />
13 13
 
14 14
 <!-- reset DB url is here. Just need to make it look pretty and unhide it-->
15 15
 <div class="padding">
16
-	<h4 class="espresso-header"><span class="dashicons dashicons-update ee-icon-size-22"></span><?php esc_html_e('Reset Event Espresso Capabilities', 'event_espresso');?></h4>
17
-	<p><?php esc_html_e('Use this to reset the capabilities on WP roles to the defaults as defined via EE_Capabilities.  Note this reset does not REMOVE any existing capabilities, it just ensures that all the defaults are ADDED to the roles.', 'event_espresso');?></p>
16
+	<h4 class="espresso-header"><span class="dashicons dashicons-update ee-icon-size-22"></span><?php esc_html_e('Reset Event Espresso Capabilities', 'event_espresso'); ?></h4>
17
+	<p><?php esc_html_e('Use this to reset the capabilities on WP roles to the defaults as defined via EE_Capabilities.  Note this reset does not REMOVE any existing capabilities, it just ensures that all the defaults are ADDED to the roles.', 'event_espresso'); ?></p>
18 18
 	<div class="float-right"><?php echo $reset_capabilities_button; ?></div>
19 19
 	<div class="clear"></div>
20 20
 </div>
@@ -22,24 +22,24 @@  discard block
 block discarded – undo
22 22
 <br />
23 23
 
24 24
 <div class="padding">
25
-	<h4 class="espresso-header"><span class="dashicons dashicons-update ee-icon-size-22"></span><?php esc_html_e('Reset Event Espresso Tables', 'event_espresso');?></h4>
26
-	<p><?php esc_html_e('Use this to reset Event Espresso Data and return your site to how it was just after first activating Event Espresso.', 'event_espresso');?></p>
27
-	<div class="float-right"><a class="button button-primary" href="<?php echo $reset_db_url;?>"><?php esc_html_e('Reset Event Espresso Tables', 'event_espresso');?></a></div>
25
+	<h4 class="espresso-header"><span class="dashicons dashicons-update ee-icon-size-22"></span><?php esc_html_e('Reset Event Espresso Tables', 'event_espresso'); ?></h4>
26
+	<p><?php esc_html_e('Use this to reset Event Espresso Data and return your site to how it was just after first activating Event Espresso.', 'event_espresso'); ?></p>
27
+	<div class="float-right"><a class="button button-primary" href="<?php echo $reset_db_url; ?>"><?php esc_html_e('Reset Event Espresso Tables', 'event_espresso'); ?></a></div>
28 28
 	<div class="clear"></div>
29 29
 </div>
30 30
 <br />
31 31
 <br />
32 32
 
33 33
 <div class="padding">
34
-	<h4 class="espresso-header"><span class="dashicons dashicons-post-trash ee-icon-size-22"></span><?php esc_html_e('Permanently Delete ALL Event Espresso Tables and Data', 'event_espresso');?></h4>
35
-	<p><?php esc_html_e('If you know for certain that you will no longer be using Event Espresso and you wish to remove ALL traces of the plugin from your system, then perform the following steps.', 'event_espresso');?></p>
36
-	<p class="important-notice"><?php printf( esc_html__('Please note: %sThis is permanent and can NOT be undone.%s', 'event_espresso'), '<strong>', '</strong>' ); ?><br/></p>
34
+	<h4 class="espresso-header"><span class="dashicons dashicons-post-trash ee-icon-size-22"></span><?php esc_html_e('Permanently Delete ALL Event Espresso Tables and Data', 'event_espresso'); ?></h4>
35
+	<p><?php esc_html_e('If you know for certain that you will no longer be using Event Espresso and you wish to remove ALL traces of the plugin from your system, then perform the following steps.', 'event_espresso'); ?></p>
36
+	<p class="important-notice"><?php printf(esc_html__('Please note: %sThis is permanent and can NOT be undone.%s', 'event_espresso'), '<strong>', '</strong>'); ?><br/></p>
37 37
 	<ol>
38
-		<li><?php  printf( esc_html__('First, click the button below to permanently delete all Event Espresso tables, records, and options from your WordPress database . If you receive a "500 Internal Server Error" or a blank white screen, it means the server has timed out due to the large number of records being updated. This is not a cause for concern. Simply %1$srefresh the page%2$s and the Database Update will continue where it left off.', 'event_espresso'), '<strong>', '</strong>' );?></li>
39
-		<li><?php printf( esc_html__('Then, locate Event Espresso on the WordPress Plugins page, and click on %sDelete%s', 'event_espresso'), '<strong>', '</strong>' ); ?></li>
40
-        <li><?php printf( esc_html__('Once you are on the Delete Plugin page, click on %sYes, Delete these files and data%s', 'event_espresso'), '<strong>', '</strong>' ); ?></li>
38
+		<li><?php  printf(esc_html__('First, click the button below to permanently delete all Event Espresso tables, records, and options from your WordPress database . If you receive a "500 Internal Server Error" or a blank white screen, it means the server has timed out due to the large number of records being updated. This is not a cause for concern. Simply %1$srefresh the page%2$s and the Database Update will continue where it left off.', 'event_espresso'), '<strong>', '</strong>'); ?></li>
39
+		<li><?php printf(esc_html__('Then, locate Event Espresso on the WordPress Plugins page, and click on %sDelete%s', 'event_espresso'), '<strong>', '</strong>'); ?></li>
40
+        <li><?php printf(esc_html__('Once you are on the Delete Plugin page, click on %sYes, Delete these files and data%s', 'event_espresso'), '<strong>', '</strong>'); ?></li>
41 41
 	</ol>
42
-	<div class="float-right"><a href="<?php echo $delete_db_url; ?>" id="delete-all-data-btn" class="button-primary"><?php esc_html_e('Permanently Delete All Event Espresso Data', 'event_espresso');?></a></div>
42
+	<div class="float-right"><a href="<?php echo $delete_db_url; ?>" id="delete-all-data-btn" class="button-primary"><?php esc_html_e('Permanently Delete All Event Espresso Data', 'event_espresso'); ?></a></div>
43 43
 	<div class="clear"></div>
44 44
 </div>
45 45
 <br/>
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.
Spacing   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -532,11 +532,11 @@  discard block
 block discarded – undo
532 532
     {
533 533
         wp_register_style(
534 534
             'events-admin-css',
535
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
535
+            EVENTS_ASSETS_URL.'events-admin-page.css',
536 536
             array(),
537 537
             EVENT_ESPRESSO_VERSION
538 538
         );
539
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
539
+        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL.'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
540 540
         wp_enqueue_style('events-admin-css');
541 541
         wp_enqueue_style('ee-cat-admin');
542 542
         //todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
@@ -544,7 +544,7 @@  discard block
 block discarded – undo
544 544
         //scripts
545 545
         wp_register_script(
546 546
             'event_editor_js',
547
-            EVENTS_ASSETS_URL . 'event_editor.js',
547
+            EVENTS_ASSETS_URL.'event_editor.js',
548 548
             array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
549 549
             EVENT_ESPRESSO_VERSION,
550 550
             true
@@ -576,7 +576,7 @@  discard block
 block discarded – undo
576 576
         wp_enqueue_style('espresso-ui-theme');
577 577
         wp_register_style(
578 578
             'event-editor-css',
579
-            EVENTS_ASSETS_URL . 'event-editor.css',
579
+            EVENTS_ASSETS_URL.'event-editor.css',
580 580
             array('ee-admin-css'),
581 581
             EVENT_ESPRESSO_VERSION
582 582
         );
@@ -584,7 +584,7 @@  discard block
 block discarded – undo
584 584
         //scripts
585 585
         wp_register_script(
586 586
             'event-datetime-metabox',
587
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
587
+            EVENTS_ASSETS_URL.'event-datetime-metabox.js',
588 588
             array('event_editor_js', 'ee-datepicker'),
589 589
             EVENT_ESPRESSO_VERSION
590 590
         );
@@ -750,7 +750,7 @@  discard block
 block discarded – undo
750 750
                         '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.',
751 751
                         'event_espresso'
752 752
                     ),
753
-                    '<a href="' . admin_url('options-general.php') . '">',
753
+                    '<a href="'.admin_url('options-general.php').'">',
754 754
                     '</a>'
755 755
                 ),
756 756
                 __FILE__,
@@ -820,31 +820,31 @@  discard block
 block discarded – undo
820 820
         $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
821 821
         $statuses = array(
822 822
             'sold_out_status'  => array(
823
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
823
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::sold_out,
824 824
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
825 825
             ),
826 826
             'active_status'    => array(
827
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
827
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::active,
828 828
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
829 829
             ),
830 830
             'upcoming_status'  => array(
831
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
831
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::upcoming,
832 832
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
833 833
             ),
834 834
             'postponed_status' => array(
835
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
835
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::postponed,
836 836
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
837 837
             ),
838 838
             'cancelled_status' => array(
839
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
839
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::cancelled,
840 840
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
841 841
             ),
842 842
             'expired_status'   => array(
843
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
843
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::expired,
844 844
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
845 845
             ),
846 846
             'inactive_status'  => array(
847
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
847
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::inactive,
848 848
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
849 849
             ),
850 850
         );
@@ -908,7 +908,7 @@  discard block
 block discarded – undo
908 908
     {
909 909
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
910 910
         $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
911
-            ? (array)$this->_template_args['after_list_table']
911
+            ? (array) $this->_template_args['after_list_table']
912 912
             : array();
913 913
         $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
914 914
                                                                               . EEH_Template::get_button_or_link(
@@ -917,7 +917,7 @@  discard block
 block discarded – undo
917 917
                 'button'
918 918
             );
919 919
         $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
920
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
920
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
921 921
                 'create_new',
922 922
                 'add',
923 923
                 array(),
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
      */
1048 1048
     protected function _default_venue_update(\EE_Event $evtobj, $data)
1049 1049
     {
1050
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1050
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1051 1051
         $venue_model = EE_Registry::instance()->load_model('Venue');
1052 1052
         $rows_affected = null;
1053 1053
         $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
@@ -1171,7 +1171,7 @@  discard block
 block discarded – undo
1171 1171
             if (empty($tkt['TKT_start_date'])) {
1172 1172
                 //let's use now in the set timezone.
1173 1173
                 $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1174
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1174
+                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0].' '.$incoming_date_formats[1]);
1175 1175
             }
1176 1176
             if (empty($tkt['TKT_end_date'])) {
1177 1177
                 //use the start date of the first datetime
@@ -1460,7 +1460,7 @@  discard block
 block discarded – undo
1460 1460
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1461 1461
         // load template
1462 1462
         EEH_Template::display_template(
1463
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1463
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1464 1464
             $publish_box_extra_args
1465 1465
         );
1466 1466
     }
@@ -1587,7 +1587,7 @@  discard block
 block discarded – undo
1587 1587
         );
1588 1588
         $template = apply_filters(
1589 1589
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1590
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1590
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1591 1591
         );
1592 1592
         EEH_Template::display_template($template, $template_args);
1593 1593
     }
@@ -1606,7 +1606,7 @@  discard block
 block discarded – undo
1606 1606
     private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1607 1607
     {
1608 1608
         $template_args = array(
1609
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1609
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1610 1610
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1611 1611
                 : '',
1612 1612
             'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
@@ -1660,7 +1660,7 @@  discard block
 block discarded – undo
1660 1660
         $template_args = array_merge($template_args, $price_args);
1661 1661
         $template = apply_filters(
1662 1662
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1663
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1663
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1664 1664
             $ticket
1665 1665
         );
1666 1666
         return EEH_Template::display_template($template, $template_args, true);
@@ -1712,7 +1712,7 @@  discard block
 block discarded – undo
1712 1712
             $default_reg_status_values
1713 1713
         );
1714 1714
         EEH_Template::display_template(
1715
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1715
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1716 1716
             $template_args
1717 1717
         );
1718 1718
     }
@@ -1735,7 +1735,7 @@  discard block
 block discarded – undo
1735 1735
     {
1736 1736
         $EEME = $this->_event_model();
1737 1737
         $offset = ($current_page - 1) * $per_page;
1738
-        $limit = $count ? null : $offset . ',' . $per_page;
1738
+        $limit = $count ? null : $offset.','.$per_page;
1739 1739
         $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1740 1740
         $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1741 1741
         if (isset($this->_req_data['month_range'])) {
@@ -1769,7 +1769,7 @@  discard block
 block discarded – undo
1769 1769
         $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1770 1770
         if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1771 1771
             $DateTime = new DateTime(
1772
-                $year_r . '-' . $month_r . '-01 00:00:00',
1772
+                $year_r.'-'.$month_r.'-01 00:00:00',
1773 1773
                 new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1774 1774
             );
1775 1775
             $start = $DateTime->format(implode(' ', $start_formats));
@@ -1815,7 +1815,7 @@  discard block
 block discarded – undo
1815 1815
         }
1816 1816
         //search query handling
1817 1817
         if (isset($this->_req_data['s'])) {
1818
-            $search_string = '%' . $this->_req_data['s'] . '%';
1818
+            $search_string = '%'.$this->_req_data['s'].'%';
1819 1819
             $where['OR'] = array(
1820 1820
                 'EVT_name'       => array('LIKE', $search_string),
1821 1821
                 'EVT_desc'       => array('LIKE', $search_string),
@@ -1949,7 +1949,7 @@  discard block
 block discarded – undo
1949 1949
         if ( ! empty($event_status)) {
1950 1950
             $success = true;
1951 1951
             //determine the event id and set to array.
1952
-            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
1952
+            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
1953 1953
             // loop thru events
1954 1954
             foreach ($EVT_IDs as $EVT_ID) {
1955 1955
                 if ($EVT_ID = absint($EVT_ID)) {
@@ -2097,7 +2097,7 @@  discard block
 block discarded – undo
2097 2097
         // get list of events with no prices
2098 2098
         $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2099 2099
         //determine the event id and set to array.
2100
-        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
2100
+        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2101 2101
         // loop thru events
2102 2102
         foreach ($EVT_IDs as $EVT_ID) {
2103 2103
             $EVT_ID = absint($EVT_ID);
@@ -2280,7 +2280,7 @@  discard block
 block discarded – undo
2280 2280
         $this->_set_add_edit_form_tags('update_default_event_settings');
2281 2281
         $this->_set_publish_post_box_vars(null, false, false, null, false);
2282 2282
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2283
-            EVENTS_TEMPLATE_PATH . 'event_settings.template.php',
2283
+            EVENTS_TEMPLATE_PATH.'event_settings.template.php',
2284 2284
             $this->_template_args,
2285 2285
             true
2286 2286
         );
@@ -2325,10 +2325,10 @@  discard block
 block discarded – undo
2325 2325
                                                . 'caffeinated_template_features.jpg" alt="'
2326 2326
                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2327 2327
                                                . '" />';
2328
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__(
2328
+        $this->_template_args['preview_text'] = '<strong>'.esc_html__(
2329 2329
                 '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.',
2330 2330
                 'event_espresso'
2331
-            ) . '</strong>';
2331
+            ).'</strong>';
2332 2332
         $this->display_admin_caf_preview_page('template_settings_tab');
2333 2333
     }
2334 2334
 
@@ -2377,7 +2377,7 @@  discard block
 block discarded – undo
2377 2377
     {
2378 2378
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2379 2379
         $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2380
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2380
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
2381 2381
                 'add_category',
2382 2382
                 'add_category',
2383 2383
                 array(),
@@ -2453,7 +2453,7 @@  discard block
 block discarded – undo
2453 2453
             'disable'                  => '',
2454 2454
             'disabled_message'         => false,
2455 2455
         );
2456
-        $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2456
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2457 2457
         return EEH_Template::display_template($template, $template_args, true);
2458 2458
     }
2459 2459
 
@@ -2461,8 +2461,8 @@  discard block
 block discarded – undo
2461 2461
 
2462 2462
     protected function _delete_categories()
2463 2463
     {
2464
-        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array)$this->_req_data['EVT_CAT_ID']
2465
-            : (array)$this->_req_data['category_id'];
2464
+        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2465
+            : (array) $this->_req_data['category_id'];
2466 2466
         foreach ($cat_ids as $cat_id) {
2467 2467
             $this->_delete_category($cat_id);
2468 2468
         }
@@ -2563,7 +2563,7 @@  discard block
 block discarded – undo
2563 2563
         $limit = ($current_page - 1) * $per_page;
2564 2564
         $where = array('taxonomy' => 'espresso_event_categories');
2565 2565
         if (isset($this->_req_data['s'])) {
2566
-            $sstr = '%' . $this->_req_data['s'] . '%';
2566
+            $sstr = '%'.$this->_req_data['s'].'%';
2567 2567
             $where['OR'] = array(
2568 2568
                 'Term.name'   => array('LIKE', $sstr),
2569 2569
                 'description' => array('LIKE', $sstr),
@@ -2572,7 +2572,7 @@  discard block
 block discarded – undo
2572 2572
         $query_params = array(
2573 2573
             $where,
2574 2574
             'order_by'   => array($orderby => $order),
2575
-            'limit'      => $limit . ',' . $per_page,
2575
+            'limit'      => $limit.','.$per_page,
2576 2576
             'force_join' => array('Term'),
2577 2577
         );
2578 2578
         $categories = $count
Please login to merge, or discard this patch.
Indentation   +2570 added lines, -2570 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,2576 +17,2576 @@  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
-                ),
407
-                'help_tour'     => array('Event_Default_Settings_Help_Tour'),
408
-                'require_nonce' => false,
409
-            ),
410
-            //template settings
411
-            'template_settings'      => array(
412
-                'nav'           => array(
413
-                    'label' => esc_html__('Templates', 'event_espresso'),
414
-                    'order' => 30,
415
-                ),
416
-                'metaboxes'     => $this->_default_espresso_metaboxes,
417
-                'help_tabs'     => array(
418
-                    'general_settings_templates_help_tab' => array(
419
-                        'title'    => esc_html__('Templates', 'event_espresso'),
420
-                        'filename' => 'general_settings_templates',
421
-                    ),
422
-                ),
423
-                'help_tour'     => array('Templates_Help_Tour'),
424
-                'require_nonce' => false,
425
-            ),
426
-            //event category stuff
427
-            'add_category'           => array(
428
-                'nav'           => array(
429
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
430
-                    'order'      => 15,
431
-                    'persistent' => false,
432
-                ),
433
-                'help_tabs'     => array(
434
-                    'add_category_help_tab' => array(
435
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
436
-                        'filename' => 'events_add_category',
437
-                    ),
438
-                ),
439
-                'help_tour'     => array('Event_Add_Category_Help_Tour'),
440
-                'metaboxes'     => array('_publish_post_box'),
441
-                'require_nonce' => false,
442
-            ),
443
-            'edit_category'          => array(
444
-                'nav'           => array(
445
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
446
-                    'order'      => 15,
447
-                    'persistent' => false,
448
-                    'url'        => isset($this->_req_data['EVT_CAT_ID'])
449
-                        ? add_query_arg(
450
-                            array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']),
451
-                            $this->_current_page_view_url
452
-                        )
453
-                        : $this->_admin_base_url,
454
-                ),
455
-                'help_tabs'     => array(
456
-                    'edit_category_help_tab' => array(
457
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
458
-                        'filename' => 'events_edit_category',
459
-                    ),
460
-                ),
461
-                /*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
462
-                'metaboxes'     => array('_publish_post_box'),
463
-                'require_nonce' => false,
464
-            ),
465
-            'category_list'          => array(
466
-                'nav'           => array(
467
-                    'label' => esc_html__('Categories', 'event_espresso'),
468
-                    'order' => 20,
469
-                ),
470
-                'list_table'    => 'Event_Categories_Admin_List_Table',
471
-                'help_tabs'     => array(
472
-                    'events_categories_help_tab'                       => array(
473
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
474
-                        'filename' => 'events_categories',
475
-                    ),
476
-                    'events_categories_table_column_headings_help_tab' => array(
477
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
478
-                        'filename' => 'events_categories_table_column_headings',
479
-                    ),
480
-                    'events_categories_view_help_tab'                  => array(
481
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
482
-                        'filename' => 'events_categories_views',
483
-                    ),
484
-                    'events_categories_other_help_tab'                 => array(
485
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
486
-                        'filename' => 'events_categories_other',
487
-                    ),
488
-                ),
489
-                'help_tour'     => array(
490
-                    'Event_Categories_Help_Tour',
491
-                ),
492
-                'metaboxes'     => $this->_default_espresso_metaboxes,
493
-                'require_nonce' => false,
494
-            ),
495
-        );
496
-    }
497
-
498
-
499
-
500
-    protected function _add_screen_options()
501
-    {
502
-        //todo
503
-    }
504
-
505
-
506
-
507
-    protected function _add_screen_options_default()
508
-    {
509
-        $this->_per_page_screen_option();
510
-    }
511
-
512
-
513
-
514
-    protected function _add_screen_options_category_list()
515
-    {
516
-        $page_title = $this->_admin_page_title;
517
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
518
-        $this->_per_page_screen_option();
519
-        $this->_admin_page_title = $page_title;
520
-    }
521
-
522
-
523
-
524
-    protected function _add_feature_pointers()
525
-    {
526
-        //todo
527
-    }
528
-
529
-
530
-
531
-    public function load_scripts_styles()
532
-    {
533
-        wp_register_style(
534
-            'events-admin-css',
535
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
536
-            array(),
537
-            EVENT_ESPRESSO_VERSION
538
-        );
539
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
540
-        wp_enqueue_style('events-admin-css');
541
-        wp_enqueue_style('ee-cat-admin');
542
-        //todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
543
-        //registers for all views
544
-        //scripts
545
-        wp_register_script(
546
-            'event_editor_js',
547
-            EVENTS_ASSETS_URL . 'event_editor.js',
548
-            array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
549
-            EVENT_ESPRESSO_VERSION,
550
-            true
551
-        );
552
-    }
553
-
554
-
555
-
556
-    /**
557
-     * enqueuing scripts and styles specific to this view
558
-     *
559
-     * @return void
560
-     */
561
-    public function load_scripts_styles_create_new()
562
-    {
563
-        $this->load_scripts_styles_edit();
564
-    }
565
-
566
-
567
-
568
-    /**
569
-     * enqueuing scripts and styles specific to this view
570
-     *
571
-     * @return void
572
-     */
573
-    public function load_scripts_styles_edit()
574
-    {
575
-        //styles
576
-        wp_enqueue_style('espresso-ui-theme');
577
-        wp_register_style(
578
-            'event-editor-css',
579
-            EVENTS_ASSETS_URL . 'event-editor.css',
580
-            array('ee-admin-css'),
581
-            EVENT_ESPRESSO_VERSION
582
-        );
583
-        wp_enqueue_style('event-editor-css');
584
-        //scripts
585
-        wp_register_script(
586
-            'event-datetime-metabox',
587
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
588
-            array('event_editor_js', 'ee-datepicker'),
589
-            EVENT_ESPRESSO_VERSION
590
-        );
591
-        wp_enqueue_script('event-datetime-metabox');
592
-    }
593
-
594
-
595
-
596
-    public function load_scripts_styles_add_category()
597
-    {
598
-        $this->load_scripts_styles_edit_category();
599
-    }
600
-
601
-
602
-
603
-    public function load_scripts_styles_edit_category()
604
-    {
605
-    }
606
-
607
-
608
-
609
-    protected function _set_list_table_views_category_list()
610
-    {
611
-        $this->_views = array(
612
-            'all' => array(
613
-                'slug'        => 'all',
614
-                'label'       => esc_html__('All', 'event_espresso'),
615
-                'count'       => 0,
616
-                'bulk_action' => array(
617
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
618
-                ),
619
-            ),
620
-        );
621
-    }
622
-
623
-
624
-
625
-    public function admin_init()
626
-    {
627
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
628
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
629
-            'event_espresso'
630
-        );
631
-    }
632
-
633
-
634
-
635
-    //nothing needed for events with these methods.
636
-    public function admin_notices()
637
-    {
638
-    }
639
-
640
-
641
-
642
-    public function admin_footer_scripts()
643
-    {
644
-    }
645
-
646
-
647
-
648
-    /**
649
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
650
-     * warning (via EE_Error::add_error());
651
-     *
652
-     * @param  EE_Event $event Event object
653
-     * @access public
654
-     * @return void
655
-     */
656
-    public function verify_event_edit($event = null)
657
-    {
658
-        // no event?
659
-        if (empty($event)) {
660
-            // set event
661
-            $event = $this->_cpt_model_obj;
662
-        }
663
-        // STILL no event?
664
-        if (empty ($event)) {
665
-            return;
666
-        }
667
-        $orig_status = $event->status();
668
-        // first check if event is active.
669
-        if (
670
-            $orig_status === EEM_Event::cancelled
671
-            || $orig_status === EEM_Event::postponed
672
-            || $event->is_expired()
673
-            || $event->is_inactive()
674
-        ) {
675
-            return;
676
-        }
677
-        //made it here so it IS active... next check that any of the tickets are sold.
678
-        if ($event->is_sold_out(true)) {
679
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
680
-                EE_Error::add_attention(
681
-                    sprintf(
682
-                        esc_html__(
683
-                            '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.',
684
-                            'event_espresso'
685
-                        ),
686
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
687
-                    )
688
-                );
689
-            }
690
-            return;
691
-        } else if ($orig_status === EEM_Event::sold_out) {
692
-            EE_Error::add_attention(
693
-                sprintf(
694
-                    esc_html__(
695
-                        '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.',
696
-                        'event_espresso'
697
-                    ),
698
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
699
-                )
700
-            );
701
-        }
702
-        //now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
703
-        if ( ! $event->tickets_on_sale()) {
704
-            return;
705
-        }
706
-        //made it here so show warning
707
-        $this->_edit_event_warning();
708
-    }
709
-
710
-
711
-
712
-    /**
713
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
714
-     * When needed, hook this into a EE_Error::add_error() notice.
715
-     *
716
-     * @access protected
717
-     * @return void
718
-     */
719
-    protected function _edit_event_warning()
720
-    {
721
-        // we don't want to add warnings during these requests
722
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
723
-            return;
724
-        }
725
-        EE_Error::add_attention(
726
-            esc_html__(
727
-                '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.',
728
-                'event_espresso'
729
-            )
730
-        );
731
-    }
732
-
733
-
734
-
735
-    /**
736
-     * When a user is creating a new event, notify them if they haven't set their timezone.
737
-     * Otherwise, do the normal logic
738
-     *
739
-     * @return string
740
-     * @throws \EE_Error
741
-     */
742
-    protected function _create_new_cpt_item()
743
-    {
744
-        $gmt_offset = get_option('gmt_offset');
745
-        //only nag them about setting their timezone if it's their first event, and they haven't already done it
746
-        if ($gmt_offset === '0' && ! EEM_Event::instance()->exists(array())) {
747
-            EE_Error::add_attention(
748
-                sprintf(
749
-                    __(
750
-                        '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.',
751
-                        'event_espresso'
752
-                    ),
753
-                    '<a href="' . admin_url('options-general.php') . '">',
754
-                    '</a>'
755
-                ),
756
-                __FILE__,
757
-                __FUNCTION__,
758
-                __LINE__
759
-            );
760
-        }
761
-        return parent::_create_new_cpt_item();
762
-    }
763
-
764
-
765
-
766
-    protected function _set_list_table_views_default()
767
-    {
768
-        $this->_views = array(
769
-            'all'   => array(
770
-                'slug'        => 'all',
771
-                'label'       => esc_html__('View All Events', 'event_espresso'),
772
-                'count'       => 0,
773
-                'bulk_action' => array(
774
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
775
-                ),
776
-            ),
777
-            'draft' => array(
778
-                'slug'        => 'draft',
779
-                'label'       => esc_html__('Draft', 'event_espresso'),
780
-                'count'       => 0,
781
-                'bulk_action' => array(
782
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
783
-                ),
784
-            ),
785
-        );
786
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
787
-            $this->_views['trash'] = array(
788
-                'slug'        => 'trash',
789
-                'label'       => esc_html__('Trash', 'event_espresso'),
790
-                'count'       => 0,
791
-                'bulk_action' => array(
792
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
793
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
794
-                ),
795
-            );
796
-        }
797
-    }
798
-
799
-
800
-
801
-    /**
802
-     * @return array
803
-     */
804
-    protected function _event_legend_items()
805
-    {
806
-        $items = array(
807
-            'view_details'   => array(
808
-                'class' => 'dashicons dashicons-search',
809
-                'desc'  => esc_html__('View Event', 'event_espresso'),
810
-            ),
811
-            'edit_event'     => array(
812
-                'class' => 'ee-icon ee-icon-calendar-edit',
813
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
814
-            ),
815
-            'view_attendees' => array(
816
-                'class' => 'dashicons dashicons-groups',
817
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
818
-            ),
819
-        );
820
-        $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
821
-        $statuses = array(
822
-            'sold_out_status'  => array(
823
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
824
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
825
-            ),
826
-            'active_status'    => array(
827
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
828
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
829
-            ),
830
-            'upcoming_status'  => array(
831
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
832
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
833
-            ),
834
-            'postponed_status' => array(
835
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
836
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
837
-            ),
838
-            'cancelled_status' => array(
839
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
840
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
841
-            ),
842
-            'expired_status'   => array(
843
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
844
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
845
-            ),
846
-            'inactive_status'  => array(
847
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
848
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
849
-            ),
850
-        );
851
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
852
-        return array_merge($items, $statuses);
853
-    }
854
-
855
-
856
-
857
-    /**
858
-     * _event_model
859
-     *
860
-     * @return EEM_Event
861
-     */
862
-    private function _event_model()
863
-    {
864
-        if ( ! $this->_event_model instanceof EEM_Event) {
865
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
866
-        }
867
-        return $this->_event_model;
868
-    }
869
-
870
-
871
-
872
-    /**
873
-     * Adds extra buttons to the WP CPT permalink field row.
874
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
875
-     *
876
-     * @param  string $return    the current html
877
-     * @param  int    $id        the post id for the page
878
-     * @param  string $new_title What the title is
879
-     * @param  string $new_slug  what the slug is
880
-     * @return string            The new html string for the permalink area
881
-     */
882
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
883
-    {
884
-        //make sure this is only when editing
885
-        if ( ! empty($id)) {
886
-            $post = get_post($id);
887
-            $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
888
-                       . esc_html__('Shortcode', 'event_espresso')
889
-                       . '</a> ';
890
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
891
-                       . $post->ID
892
-                       . ']">';
893
-        }
894
-        return $return;
895
-    }
896
-
897
-
898
-
899
-    /**
900
-     * _events_overview_list_table
901
-     * This contains the logic for showing the events_overview list
902
-     *
903
-     * @access protected
904
-     * @return void
905
-     * @throws \EE_Error
906
-     */
907
-    protected function _events_overview_list_table()
908
-    {
909
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
910
-        $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
911
-            ? (array)$this->_template_args['after_list_table']
912
-            : array();
913
-        $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
914
-                                                                              . EEH_Template::get_button_or_link(
915
-                get_post_type_archive_link('espresso_events'),
916
-                esc_html__("View Event Archive Page", "event_espresso"),
917
-                'button'
918
-            );
919
-        $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
920
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
921
-                'create_new',
922
-                'add',
923
-                array(),
924
-                'add-new-h2'
925
-            );
926
-        $this->display_admin_list_table_page_with_no_sidebar();
927
-    }
928
-
929
-
930
-
931
-    /**
932
-     * this allows for extra misc actions in the default WP publish box
933
-     *
934
-     * @return void
935
-     */
936
-    public function extra_misc_actions_publish_box()
937
-    {
938
-        $this->_generate_publish_box_extra_content();
939
-    }
940
-
941
-
942
-
943
-    /**
944
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
945
-     * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
946
-     * data.
947
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
948
-     * ALSO very important.  When a post transitions from scheduled to published, the save_post action is fired but you
949
-     * will NOT have any _POST data containing any extra info you may have from other meta saves.  So MAKE sure that
950
-     * you handle this accordingly.
951
-     *
952
-     * @access protected
953
-     * @abstract
954
-     * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
955
-     * @param  object $post    The post object of the cpt that was saved.
956
-     * @return void
957
-     */
958
-    protected function _insert_update_cpt_item($post_id, $post)
959
-    {
960
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
961
-            //get out we're not processing an event save.
962
-            return;
963
-        }
964
-        $event_values = array(
965
-            'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
966
-            'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
967
-            'EVT_additional_limit'            => min(
968
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
969
-                ! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
970
-            ),
971
-            'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
972
-                ? $this->_req_data['EVT_default_registration_status']
973
-                : EE_Registry::instance()->CFG->registration->default_STS_ID,
974
-            'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
975
-            'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
976
-            'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
977
-                ? $this->_req_data['timezone_string'] : null,
978
-            'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
979
-                ? $this->_req_data['externalURL'] : null,
980
-            'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
981
-                ? $this->_req_data['event_phone'] : null,
982
-        );
983
-        //update event
984
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
985
-        //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!
986
-        $get_one_where = array($this->_event_model()->primary_key_name() => $post_id, 'status' => $post->post_status);
987
-        $event = $this->_event_model()->get_one(array($get_one_where));
988
-        //the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
989
-        $event_update_callbacks = apply_filters(
990
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
991
-            array(array($this, '_default_venue_update'), array($this, '_default_tickets_update'))
992
-        );
993
-        $att_success = true;
994
-        foreach ($event_update_callbacks as $e_callback) {
995
-            $_succ = call_user_func_array($e_callback, array($event, $this->_req_data));
996
-            $att_success = ! $att_success ? $att_success
997
-                : $_succ; //if ANY of these updates fail then we want the appropriate global error message
998
-        }
999
-        //any errors?
1000
-        if ($success && false === $att_success) {
1001
-            EE_Error::add_error(
1002
-                esc_html__(
1003
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1004
-                    'event_espresso'
1005
-                ),
1006
-                __FILE__,
1007
-                __FUNCTION__,
1008
-                __LINE__
1009
-            );
1010
-        } else if ($success === false) {
1011
-            EE_Error::add_error(
1012
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1013
-                __FILE__,
1014
-                __FUNCTION__,
1015
-                __LINE__
1016
-            );
1017
-        }
1018
-    }
1019
-
1020
-
1021
-
1022
-    /**
1023
-     * @see parent::restore_item()
1024
-     * @param int $post_id
1025
-     * @param int $revision_id
1026
-     */
1027
-    protected function _restore_cpt_item($post_id, $revision_id)
1028
-    {
1029
-        //copy existing event meta to new post
1030
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1031
-        if ($post_evt instanceof EE_Event) {
1032
-            //meta revision restore
1033
-            $post_evt->restore_revision($revision_id);
1034
-            //related objs restore
1035
-            $post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1036
-        }
1037
-    }
1038
-
1039
-
1040
-
1041
-    /**
1042
-     * Attach the venue to the Event
1043
-     *
1044
-     * @param  \EE_Event $evtobj Event Object to add the venue to
1045
-     * @param  array     $data   The request data from the form
1046
-     * @return bool           Success or fail.
1047
-     */
1048
-    protected function _default_venue_update(\EE_Event $evtobj, $data)
1049
-    {
1050
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1051
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1052
-        $rows_affected = null;
1053
-        $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1054
-        // very important.  If we don't have a venue name...
1055
-        // then we'll get out because not necessary to create empty venue
1056
-        if (empty($data['venue_title'])) {
1057
-            return false;
1058
-        }
1059
-        $venue_array = array(
1060
-            'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1061
-            'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1062
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1063
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1064
-            'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1065
-                : null,
1066
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1067
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1068
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1069
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1070
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1071
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1072
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1073
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1074
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1075
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1076
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1077
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1078
-            'status'              => 'publish',
1079
-        );
1080
-        //if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1081
-        if ( ! empty($venue_id)) {
1082
-            $update_where = array($venue_model->primary_key_name() => $venue_id);
1083
-            $rows_affected = $venue_model->update($venue_array, array($update_where));
1084
-            //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.
1085
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1086
-            return $rows_affected > 0 ? true : false;
1087
-        } else {
1088
-            //we insert the venue
1089
-            $venue_id = $venue_model->insert($venue_array);
1090
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1091
-            return ! empty($venue_id) ? true : false;
1092
-        }
1093
-        //when we have the ancestor come in it's already been handled by the revision save.
1094
-    }
1095
-
1096
-
1097
-
1098
-    /**
1099
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1100
-     *
1101
-     * @param  EE_Event $evtobj The Event object we're attaching data to
1102
-     * @param  array    $data   The request data from the form
1103
-     * @return array
1104
-     */
1105
-    protected function _default_tickets_update(EE_Event $evtobj, $data)
1106
-    {
1107
-        $success = true;
1108
-        $saved_dtt = null;
1109
-        $saved_tickets = array();
1110
-        $incoming_date_formats = array('Y-m-d', 'h:i a');
1111
-        foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1112
-            //trim all values to ensure any excess whitespace is removed.
1113
-            $dtt = array_map('trim', $dtt);
1114
-            $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1115
-                : $dtt['DTT_EVT_start'];
1116
-            $datetime_values = array(
1117
-                'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1118
-                'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1119
-                'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1120
-                'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1121
-                'DTT_order'     => $row,
1122
-            );
1123
-            //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.
1124
-            if ( ! empty($dtt['DTT_ID'])) {
1125
-                $DTM = EE_Registry::instance()
1126
-                                  ->load_model('Datetime', array($evtobj->get_timezone()))
1127
-                                  ->get_one_by_ID($dtt['DTT_ID']);
1128
-                $DTM->set_date_format($incoming_date_formats[0]);
1129
-                $DTM->set_time_format($incoming_date_formats[1]);
1130
-                foreach ($datetime_values as $field => $value) {
1131
-                    $DTM->set($field, $value);
1132
-                }
1133
-                //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.
1134
-                $saved_dtts[$DTM->ID()] = $DTM;
1135
-            } else {
1136
-                $DTM = EE_Registry::instance()->load_class(
1137
-                    'Datetime',
1138
-                    array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1139
-                    false,
1140
-                    false
1141
-                );
1142
-                foreach ($datetime_values as $field => $value) {
1143
-                    $DTM->set($field, $value);
1144
-                }
1145
-            }
1146
-            $DTM->save();
1147
-            $DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1148
-            //load DTT helper
1149
-            //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.
1150
-            if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1151
-                $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1152
-                $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1153
-                $DTT->save();
1154
-            }
1155
-            //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.
1156
-            $saved_dtt = $DTT;
1157
-            $success = ! $success ? $success : $DTT;
1158
-            //if ANY of these updates fail then we want the appropriate global error message.
1159
-            // //todo this is actually sucky we need a better error message but this is what it is for now.
1160
-        }
1161
-        //no dtts get deleted so we don't do any of that logic here.
1162
-        //update tickets next
1163
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1164
-        foreach ($data['edit_tickets'] as $row => $tkt) {
1165
-            $incoming_date_formats = array('Y-m-d', 'h:i a');
1166
-            $update_prices = false;
1167
-            $ticket_price = isset($data['edit_prices'][$row][1]['PRC_amount'])
1168
-                ? $data['edit_prices'][$row][1]['PRC_amount'] : 0;
1169
-            // trim inputs to ensure any excess whitespace is removed.
1170
-            $tkt = array_map('trim', $tkt);
1171
-            if (empty($tkt['TKT_start_date'])) {
1172
-                //let's use now in the set timezone.
1173
-                $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1174
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1175
-            }
1176
-            if (empty($tkt['TKT_end_date'])) {
1177
-                //use the start date of the first datetime
1178
-                $dtt = $evtobj->first_datetime();
1179
-                $tkt['TKT_end_date'] = $dtt->start_date_and_time(
1180
-                    $incoming_date_formats[0],
1181
-                    $incoming_date_formats[1]
1182
-                );
1183
-            }
1184
-            $TKT_values = array(
1185
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1186
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1187
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1188
-                'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1189
-                'TKT_start_date'  => $tkt['TKT_start_date'],
1190
-                'TKT_end_date'    => $tkt['TKT_end_date'],
1191
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1192
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1193
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1194
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1195
-                'TKT_row'         => $row,
1196
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1197
-                'TKT_price'       => $ticket_price,
1198
-            );
1199
-            //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.
1200
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1201
-                $TKT_values['TKT_ID'] = 0;
1202
-                $TKT_values['TKT_is_default'] = 0;
1203
-                $TKT_values['TKT_price'] = $ticket_price;
1204
-                $update_prices = true;
1205
-            }
1206
-            //if we have a TKT_ID then we need to get that existing TKT_obj and update it
1207
-            //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.
1208
-            //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.
1209
-            if ( ! empty($tkt['TKT_ID'])) {
1210
-                $TKT = EE_Registry::instance()
1211
-                                  ->load_model('Ticket', array($evtobj->get_timezone()))
1212
-                                  ->get_one_by_ID($tkt['TKT_ID']);
1213
-                if ($TKT instanceof EE_Ticket) {
1214
-                    $ticket_sold = $TKT->count_related(
1215
-                        'Registration',
1216
-                        array(
1217
-                            array(
1218
-                                'STS_ID' => array(
1219
-                                    'NOT IN',
1220
-                                    array(EEM_Registration::status_id_incomplete),
1221
-                                ),
1222
-                            ),
1223
-                        )
1224
-                    ) > 0 ? true : false;
1225
-                    //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.
1226
-                    $create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price')
1227
-                                      && ! $TKT->get(
1228
-                        'TKT_deleted'
1229
-                    ) ? true : false;
1230
-                    $TKT->set_date_format($incoming_date_formats[0]);
1231
-                    $TKT->set_time_format($incoming_date_formats[1]);
1232
-                    //set new values
1233
-                    foreach ($TKT_values as $field => $value) {
1234
-                        if ($field == 'TKT_qty') {
1235
-                            $TKT->set_qty($value);
1236
-                        } else {
1237
-                            $TKT->set($field, $value);
1238
-                        }
1239
-                    }
1240
-                    //if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1241
-                    if ($create_new_TKT) {
1242
-                        //archive the old ticket first
1243
-                        $TKT->set('TKT_deleted', 1);
1244
-                        $TKT->save();
1245
-                        //make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1246
-                        $saved_tickets[$TKT->ID()] = $TKT;
1247
-                        //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.
1248
-                        $TKT = clone $TKT;
1249
-                        $TKT->set('TKT_ID', 0);
1250
-                        $TKT->set('TKT_deleted', 0);
1251
-                        $TKT->set('TKT_price', $ticket_price);
1252
-                        $TKT->set('TKT_sold', 0);
1253
-                        //now we need to make sure that $new prices are created as well and attached to new ticket.
1254
-                        $update_prices = true;
1255
-                    }
1256
-                    //make sure price is set if it hasn't been already
1257
-                    $TKT->set('TKT_price', $ticket_price);
1258
-                }
1259
-            } else {
1260
-                //no TKT_id so a new TKT
1261
-                $TKT_values['TKT_price'] = $ticket_price;
1262
-                $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1263
-                if ($TKT instanceof EE_Ticket) {
1264
-                    //need to reset values to properly account for the date formats
1265
-                    $TKT->set_date_format($incoming_date_formats[0]);
1266
-                    $TKT->set_time_format($incoming_date_formats[1]);
1267
-                    $TKT->set_timezone($evtobj->get_timezone());
1268
-                    //set new values
1269
-                    foreach ($TKT_values as $field => $value) {
1270
-                        if ($field == 'TKT_qty') {
1271
-                            $TKT->set_qty($value);
1272
-                        } else {
1273
-                            $TKT->set($field, $value);
1274
-                        }
1275
-                    }
1276
-                    $update_prices = true;
1277
-                }
1278
-            }
1279
-            // cap ticket qty by datetime reg limits
1280
-            $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1281
-            //update ticket.
1282
-            $TKT->save();
1283
-            //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.
1284
-            if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1285
-                $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1286
-                $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1287
-                $TKT->save();
1288
-            }
1289
-            //initially let's add the ticket to the dtt
1290
-            $saved_dtt->_add_relation_to($TKT, 'Ticket');
1291
-            $saved_tickets[$TKT->ID()] = $TKT;
1292
-            //add prices to ticket
1293
-            $this->_add_prices_to_ticket($data['edit_prices'][$row], $TKT, $update_prices);
1294
-        }
1295
-        //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.
1296
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
1297
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1298
-        foreach ($tickets_removed as $id) {
1299
-            $id = absint($id);
1300
-            //get the ticket for this id
1301
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1302
-            //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)
1303
-            $dtts = $tkt_to_remove->get_many_related('Datetime');
1304
-            foreach ($dtts as $dtt) {
1305
-                $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1306
-            }
1307
-            //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))
1308
-            $tkt_to_remove->delete_related_permanently('Price');
1309
-            //finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1310
-            $tkt_to_remove->delete_permanently();
1311
-        }
1312
-        return array($saved_dtt, $saved_tickets);
1313
-    }
1314
-
1315
-
1316
-
1317
-    /**
1318
-     * This attaches a list of given prices to a ticket.
1319
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1320
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1321
-     * price info and prices are automatically "archived" via the ticket.
1322
-     *
1323
-     * @access  private
1324
-     * @param array     $prices     Array of prices from the form.
1325
-     * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1326
-     * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1327
-     * @return  void
1328
-     */
1329
-    private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1330
-    {
1331
-        foreach ($prices as $row => $prc) {
1332
-            $PRC_values = array(
1333
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1334
-                'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1335
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1336
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1337
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1338
-                'PRC_is_default' => 0, //make sure prices are NOT set as default from this context
1339
-                'PRC_order'      => $row,
1340
-            );
1341
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
1342
-                $PRC_values['PRC_ID'] = 0;
1343
-                $PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1344
-            } else {
1345
-                $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1346
-                //update this price with new values
1347
-                foreach ($PRC_values as $field => $newprc) {
1348
-                    $PRC->set($field, $newprc);
1349
-                }
1350
-                $PRC->save();
1351
-            }
1352
-            $ticket->_add_relation_to($PRC, 'Price');
1353
-        }
1354
-    }
1355
-
1356
-
1357
-
1358
-    /**
1359
-     * Add in our autosave ajax handlers
1360
-     *
1361
-     * @return void
1362
-     */
1363
-    protected function _ee_autosave_create_new()
1364
-    {
1365
-        // $this->_ee_autosave_edit();
1366
-    }
1367
-
1368
-
1369
-
1370
-    protected function _ee_autosave_edit()
1371
-    {
1372
-        return; //TEMPORARILY EXITING CAUSE THIS IS A TODO
1373
-    }
1374
-
1375
-
1376
-
1377
-    /**
1378
-     *    _generate_publish_box_extra_content
1379
-     *
1380
-     * @access private
1381
-     * @return void
1382
-     */
1383
-    private function _generate_publish_box_extra_content()
1384
-    {
1385
-        //load formatter helper
1386
-        //args for getting related registrations
1387
-        $approved_query_args = array(
1388
-            array(
1389
-                'REG_deleted' => 0,
1390
-                'STS_ID'      => EEM_Registration::status_id_approved,
1391
-            ),
1392
-        );
1393
-        $not_approved_query_args = array(
1394
-            array(
1395
-                'REG_deleted' => 0,
1396
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1397
-            ),
1398
-        );
1399
-        $pending_payment_query_args = array(
1400
-            array(
1401
-                'REG_deleted' => 0,
1402
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1403
-            ),
1404
-        );
1405
-        // publish box
1406
-        $publish_box_extra_args = array(
1407
-            'view_approved_reg_url'        => add_query_arg(
1408
-                array(
1409
-                    'action'      => 'default',
1410
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1411
-                    '_reg_status' => EEM_Registration::status_id_approved,
1412
-                ),
1413
-                REG_ADMIN_URL
1414
-            ),
1415
-            'view_not_approved_reg_url'    => add_query_arg(
1416
-                array(
1417
-                    'action'      => 'default',
1418
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1419
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1420
-                ),
1421
-                REG_ADMIN_URL
1422
-            ),
1423
-            'view_pending_payment_reg_url' => add_query_arg(
1424
-                array(
1425
-                    'action'      => 'default',
1426
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1427
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1428
-                ),
1429
-                REG_ADMIN_URL
1430
-            ),
1431
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1432
-                'Registration',
1433
-                $approved_query_args
1434
-            ),
1435
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1436
-                'Registration',
1437
-                $not_approved_query_args
1438
-            ),
1439
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1440
-                'Registration',
1441
-                $pending_payment_query_args
1442
-            ),
1443
-            'misc_pub_section_class'       => apply_filters(
1444
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1445
-                'misc-pub-section'
1446
-            ),
1447
-            //'email_attendees_url' => add_query_arg(
1448
-            //	array(
1449
-            //		'event_admin_reports' => 'event_newsletter',
1450
-            //		'event_id' => $this->_cpt_model_obj->id
1451
-            //	),
1452
-            //	'admin.php?page=espresso_registrations'
1453
-            //),
1454
-        );
1455
-        ob_start();
1456
-        do_action(
1457
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1458
-            $this->_cpt_model_obj
1459
-        );
1460
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1461
-        // load template
1462
-        EEH_Template::display_template(
1463
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1464
-            $publish_box_extra_args
1465
-        );
1466
-    }
1467
-
1468
-
1469
-
1470
-    /**
1471
-     * This just returns whatever is set as the _event object property
1472
-     * //todo this will become obsolete once the models are in place
1473
-     *
1474
-     * @return object
1475
-     */
1476
-    public function get_event_object()
1477
-    {
1478
-        return $this->_cpt_model_obj;
1479
-    }
1480
-
1481
-
1482
-
1483
-
1484
-    /** METABOXES * */
1485
-    /**
1486
-     * _register_event_editor_meta_boxes
1487
-     * add all metaboxes related to the event_editor
1488
-     *
1489
-     * @return void
1490
-     */
1491
-    protected function _register_event_editor_meta_boxes()
1492
-    {
1493
-        $this->verify_cpt_object();
1494
-        add_meta_box(
1495
-            'espresso_event_editor_tickets',
1496
-            esc_html__('Event Datetime & Ticket', 'event_espresso'),
1497
-            array($this, 'ticket_metabox'),
1498
-            $this->page_slug,
1499
-            'normal',
1500
-            'high'
1501
-        );
1502
-        add_meta_box(
1503
-            'espresso_event_editor_event_options',
1504
-            esc_html__('Event Registration Options', 'event_espresso'),
1505
-            array($this, 'registration_options_meta_box'),
1506
-            $this->page_slug,
1507
-            'side',
1508
-            'default'
1509
-        );
1510
-        // NOTE: if you're looking for other metaboxes in here,
1511
-        // where a metabox has a related management page in the admin
1512
-        // you will find it setup in the related management page's "_Hooks" file.
1513
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1514
-    }
1515
-
1516
-
1517
-
1518
-    public function ticket_metabox()
1519
-    {
1520
-        $existing_datetime_ids = $existing_ticket_ids = array();
1521
-        //defaults for template args
1522
-        $template_args = array(
1523
-            'existing_datetime_ids'    => '',
1524
-            'event_datetime_help_link' => '',
1525
-            'ticket_options_help_link' => '',
1526
-            'time'                     => null,
1527
-            'ticket_rows'              => '',
1528
-            'existing_ticket_ids'      => '',
1529
-            'total_ticket_rows'        => 1,
1530
-            'ticket_js_structure'      => '',
1531
-            'trash_icon'               => 'ee-lock-icon',
1532
-            'disabled'                 => '',
1533
-        );
1534
-        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1535
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1536
-        /**
1537
-         * 1. Start with retrieving Datetimes
1538
-         * 2. Fore each datetime get related tickets
1539
-         * 3. For each ticket get related prices
1540
-         */
1541
-        $times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1542
-        /** @type EE_Datetime $first_datetime */
1543
-        $first_datetime = reset($times);
1544
-        //do we get related tickets?
1545
-        if ($first_datetime instanceof EE_Datetime
1546
-            && $first_datetime->ID() !== 0
1547
-        ) {
1548
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1549
-            $template_args['time'] = $first_datetime;
1550
-            $related_tickets = $first_datetime->tickets(
1551
-                array(
1552
-                    array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1553
-                    'default_where_conditions' => 'none',
1554
-                )
1555
-            );
1556
-            if ( ! empty($related_tickets)) {
1557
-                $template_args['total_ticket_rows'] = count($related_tickets);
1558
-                $row = 0;
1559
-                foreach ($related_tickets as $ticket) {
1560
-                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1561
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1562
-                    $row++;
1563
-                }
1564
-            } else {
1565
-                $template_args['total_ticket_rows'] = 1;
1566
-                /** @type EE_Ticket $ticket */
1567
-                $ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1568
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1569
-            }
1570
-        } else {
1571
-            $template_args['time'] = $times[0];
1572
-            /** @type EE_Ticket $ticket */
1573
-            $ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1574
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1575
-            // NOTE: we're just sending the first default row
1576
-            // (decaf can't manage default tickets so this should be sufficient);
1577
-        }
1578
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1579
-            'event_editor_event_datetimes_help_tab'
1580
-        );
1581
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1582
-        $template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1583
-        $template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1584
-        $template_args['ticket_js_structure'] = $this->_get_ticket_row(
1585
-            EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1586
-            true
1587
-        );
1588
-        $template = apply_filters(
1589
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1590
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1591
-        );
1592
-        EEH_Template::display_template($template, $template_args);
1593
-    }
1594
-
1595
-
1596
-
1597
-    /**
1598
-     * Setup an individual ticket form for the decaf event editor page
1599
-     *
1600
-     * @access private
1601
-     * @param  EE_Ticket $ticket   the ticket object
1602
-     * @param  boolean   $skeleton whether we're generating a skeleton for js manipulation
1603
-     * @param int        $row
1604
-     * @return string generated html for the ticket row.
1605
-     */
1606
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1607
-    {
1608
-        $template_args = array(
1609
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1610
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1611
-                : '',
1612
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1613
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1614
-            'TKT_name'            => $ticket->get('TKT_name'),
1615
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1616
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1617
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1618
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1619
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1620
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1621
-            'trash_icon'          => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')))
1622
-                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1623
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1624
-            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1625
-                : ' disabled=disabled',
1626
-        );
1627
-        $price = $ticket->ID() !== 0
1628
-            ? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1629
-            : EE_Registry::instance()->load_model('Price')->create_default_object();
1630
-        $price_args = array(
1631
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1632
-            'PRC_amount'            => $price->get('PRC_amount'),
1633
-            'PRT_ID'                => $price->get('PRT_ID'),
1634
-            'PRC_ID'                => $price->get('PRC_ID'),
1635
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1636
-        );
1637
-        //make sure we have default start and end dates if skeleton
1638
-        //handle rows that should NOT be empty
1639
-        if (empty($template_args['TKT_start_date'])) {
1640
-            //if empty then the start date will be now.
1641
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1642
-        }
1643
-        if (empty($template_args['TKT_end_date'])) {
1644
-            //get the earliest datetime (if present);
1645
-            $earliest_dtt = $this->_cpt_model_obj->ID() > 0
1646
-                ? $this->_cpt_model_obj->get_first_related(
1647
-                    'Datetime',
1648
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1649
-                )
1650
-                : null;
1651
-            if ( ! empty($earliest_dtt)) {
1652
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1653
-            } else {
1654
-                $template_args['TKT_end_date'] = date(
1655
-                    'Y-m-d h:i a',
1656
-                    mktime(0, 0, 0, date("m"), date("d") + 7, date("Y"))
1657
-                );
1658
-            }
1659
-        }
1660
-        $template_args = array_merge($template_args, $price_args);
1661
-        $template = apply_filters(
1662
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1663
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1664
-            $ticket
1665
-        );
1666
-        return EEH_Template::display_template($template, $template_args, true);
1667
-    }
1668
-
1669
-
1670
-
1671
-    public function registration_options_meta_box()
1672
-    {
1673
-        $yes_no_values = array(
1674
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1675
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1676
-        );
1677
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1678
-            array(
1679
-                EEM_Registration::status_id_cancelled,
1680
-                EEM_Registration::status_id_declined,
1681
-                EEM_Registration::status_id_incomplete,
1682
-            ),
1683
-            true
1684
-        );
1685
-        //$template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1686
-        $template_args['_event'] = $this->_cpt_model_obj;
1687
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1688
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1689
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1690
-            'default_reg_status',
1691
-            $default_reg_status_values,
1692
-            $this->_cpt_model_obj->default_registration_status()
1693
-        );
1694
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
1695
-            'display_desc',
1696
-            $yes_no_values,
1697
-            $this->_cpt_model_obj->display_description()
1698
-        );
1699
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1700
-            'display_ticket_selector',
1701
-            $yes_no_values,
1702
-            $this->_cpt_model_obj->display_ticket_selector(),
1703
-            '',
1704
-            '',
1705
-            false
1706
-        );
1707
-        $template_args['additional_registration_options'] = apply_filters(
1708
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1709
-            '',
1710
-            $template_args,
1711
-            $yes_no_values,
1712
-            $default_reg_status_values
1713
-        );
1714
-        EEH_Template::display_template(
1715
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1716
-            $template_args
1717
-        );
1718
-    }
1719
-
1720
-
1721
-
1722
-    /**
1723
-     * _get_events()
1724
-     * This method simply returns all the events (for the given _view and paging)
1725
-     *
1726
-     * @access public
1727
-     * @param int  $per_page     count of items per page (20 default);
1728
-     * @param int  $current_page what is the current page being viewed.
1729
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1730
-     *                           If FALSE then we return an array of event objects
1731
-     *                           that match the given _view and paging parameters.
1732
-     * @return array an array of event objects.
1733
-     */
1734
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1735
-    {
1736
-        $EEME = $this->_event_model();
1737
-        $offset = ($current_page - 1) * $per_page;
1738
-        $limit = $count ? null : $offset . ',' . $per_page;
1739
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1740
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1741
-        if (isset($this->_req_data['month_range'])) {
1742
-            $pieces = explode(' ', $this->_req_data['month_range'], 3);
1743
-            //simulate the FIRST day of the month, that fixes issues for months like February
1744
-            //where PHP doesn't know what to assume for date.
1745
-            //@see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1746
-            $month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1747
-            $year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1748
-        }
1749
-        $where = array();
1750
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1751
-        //determine what post_status our condition will have for the query.
1752
-        switch ($status) {
1753
-            case 'month' :
1754
-            case 'today' :
1755
-            case null :
1756
-            case 'all' :
1757
-                break;
1758
-            case 'draft' :
1759
-                $where['status'] = array('IN', array('draft', 'auto-draft'));
1760
-                break;
1761
-            default :
1762
-                $where['status'] = $status;
1763
-        }
1764
-        //categories?
1765
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1766
-            ? $this->_req_data['EVT_CAT'] : null;
1767
-        if ( ! empty ($category)) {
1768
-            $where['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1769
-            $where['Term_Taxonomy.term_id'] = $category;
1770
-        }
1771
-        //date where conditions
1772
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1773
-        if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1774
-            $DateTime = new DateTime(
1775
-                $year_r . '-' . $month_r . '-01 00:00:00',
1776
-                new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1777
-            );
1778
-            $start = $DateTime->format(implode(' ', $start_formats));
1779
-            $end = $DateTime->setDate($year_r, $month_r, $DateTime
1780
-                ->format('t'))->setTime(23, 59, 59)
1781
-                            ->format(implode(' ', $start_formats));
1782
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1783
-        } else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') {
1784
-            $DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1785
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1786
-            $end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1787
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1788
-        } else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') {
1789
-            $now = date('Y-m-01');
1790
-            $DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1791
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1792
-            $end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1793
-                            ->setTime(23, 59, 59)
1794
-                            ->format(implode(' ', $start_formats));
1795
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1796
-        }
1797
-        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1798
-            $where['EVT_wp_user'] = get_current_user_id();
1799
-        } else {
1800
-            if ( ! isset($where['status'])) {
1801
-                if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1802
-                    $where['OR'] = array(
1803
-                        'status*restrict_private' => array('!=', 'private'),
1804
-                        'AND'                     => array(
1805
-                            'status*inclusive' => array('=', 'private'),
1806
-                            'EVT_wp_user'      => get_current_user_id(),
1807
-                        ),
1808
-                    );
1809
-                }
1810
-            }
1811
-        }
1812
-        if (isset($this->_req_data['EVT_wp_user'])) {
1813
-            if ($this->_req_data['EVT_wp_user'] != get_current_user_id()
1814
-                && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1815
-            ) {
1816
-                $where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1817
-            }
1818
-        }
1819
-        //search query handling
1820
-        if (isset($this->_req_data['s'])) {
1821
-            $search_string = '%' . $this->_req_data['s'] . '%';
1822
-            $where['OR'] = array(
1823
-                'EVT_name'       => array('LIKE', $search_string),
1824
-                'EVT_desc'       => array('LIKE', $search_string),
1825
-                'EVT_short_desc' => array('LIKE', $search_string),
1826
-            );
1827
-        }
1828
-        $where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1829
-        $query_params = apply_filters(
1830
-            'FHEE__Events_Admin_Page__get_events__query_params',
1831
-            array(
1832
-                $where,
1833
-                'limit'    => $limit,
1834
-                'order_by' => $orderby,
1835
-                'order'    => $order,
1836
-                'group_by' => 'EVT_ID',
1837
-            ),
1838
-            $this->_req_data
1839
-        );
1840
-        //let's first check if we have special requests coming in.
1841
-        if (isset($this->_req_data['active_status'])) {
1842
-            switch ($this->_req_data['active_status']) {
1843
-                case 'upcoming' :
1844
-                    return $EEME->get_upcoming_events($query_params, $count);
1845
-                    break;
1846
-                case 'expired' :
1847
-                    return $EEME->get_expired_events($query_params, $count);
1848
-                    break;
1849
-                case 'active' :
1850
-                    return $EEME->get_active_events($query_params, $count);
1851
-                    break;
1852
-                case 'inactive' :
1853
-                    return $EEME->get_inactive_events($query_params, $count);
1854
-                    break;
1855
-            }
1856
-        }
1857
-        $events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1858
-        return $events;
1859
-    }
1860
-
1861
-
1862
-
1863
-    /**
1864
-     * handling for WordPress CPT actions (trash, restore, delete)
1865
-     *
1866
-     * @param string $post_id
1867
-     */
1868
-    public function trash_cpt_item($post_id)
1869
-    {
1870
-        $this->_req_data['EVT_ID'] = $post_id;
1871
-        $this->_trash_or_restore_event('trash', false);
1872
-    }
1873
-
1874
-
1875
-
1876
-    /**
1877
-     * @param string $post_id
1878
-     */
1879
-    public function restore_cpt_item($post_id)
1880
-    {
1881
-        $this->_req_data['EVT_ID'] = $post_id;
1882
-        $this->_trash_or_restore_event('draft', false);
1883
-    }
1884
-
1885
-
1886
-
1887
-    /**
1888
-     * @param string $post_id
1889
-     */
1890
-    public function delete_cpt_item($post_id)
1891
-    {
1892
-        $this->_req_data['EVT_ID'] = $post_id;
1893
-        $this->_delete_event(false);
1894
-    }
1895
-
1896
-
1897
-
1898
-    /**
1899
-     * _trash_or_restore_event
1900
-     *
1901
-     * @access protected
1902
-     * @param  string $event_status
1903
-     * @param bool    $redirect_after
1904
-     */
1905
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
1906
-    {
1907
-        //determine the event id and set to array.
1908
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
1909
-        // loop thru events
1910
-        if ($EVT_ID) {
1911
-            // clean status
1912
-            $event_status = sanitize_key($event_status);
1913
-            // grab status
1914
-            if ( ! empty($event_status)) {
1915
-                $success = $this->_change_event_status($EVT_ID, $event_status);
1916
-            } else {
1917
-                $success = false;
1918
-                $msg = esc_html__(
1919
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1920
-                    'event_espresso'
1921
-                );
1922
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1923
-            }
1924
-        } else {
1925
-            $success = false;
1926
-            $msg = esc_html__(
1927
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
1928
-                'event_espresso'
1929
-            );
1930
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1931
-        }
1932
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1933
-        if ($redirect_after) {
1934
-            $this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
1935
-        }
1936
-    }
1937
-
1938
-
1939
-
1940
-    /**
1941
-     * _trash_or_restore_events
1942
-     *
1943
-     * @access protected
1944
-     * @param  string $event_status
1945
-     * @return void
1946
-     */
1947
-    protected function _trash_or_restore_events($event_status = 'trash')
1948
-    {
1949
-        // clean status
1950
-        $event_status = sanitize_key($event_status);
1951
-        // grab status
1952
-        if ( ! empty($event_status)) {
1953
-            $success = true;
1954
-            //determine the event id and set to array.
1955
-            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
1956
-            // loop thru events
1957
-            foreach ($EVT_IDs as $EVT_ID) {
1958
-                if ($EVT_ID = absint($EVT_ID)) {
1959
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
1960
-                    $success = $results !== false ? $success : false;
1961
-                } else {
1962
-                    $msg = sprintf(
1963
-                        esc_html__(
1964
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
1965
-                            'event_espresso'
1966
-                        ),
1967
-                        $EVT_ID
1968
-                    );
1969
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1970
-                    $success = false;
1971
-                }
1972
-            }
1973
-        } else {
1974
-            $success = false;
1975
-            $msg = esc_html__(
1976
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1977
-                'event_espresso'
1978
-            );
1979
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1980
-        }
1981
-        // in order to force a pluralized result message we need to send back a success status greater than 1
1982
-        $success = $success ? 2 : false;
1983
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1984
-        $this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
1985
-    }
1986
-
1987
-
1988
-
1989
-    /**
1990
-     * _trash_or_restore_events
1991
-     *
1992
-     * @access  private
1993
-     * @param  int    $EVT_ID
1994
-     * @param  string $event_status
1995
-     * @return bool
1996
-     */
1997
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
1998
-    {
1999
-        // grab event id
2000
-        if ( ! $EVT_ID) {
2001
-            $msg = esc_html__(
2002
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2003
-                'event_espresso'
2004
-            );
2005
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2006
-            return false;
2007
-        }
2008
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2009
-        // clean status
2010
-        $event_status = sanitize_key($event_status);
2011
-        // grab status
2012
-        if (empty($event_status)) {
2013
-            $msg = esc_html__(
2014
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2015
-                'event_espresso'
2016
-            );
2017
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2018
-            return false;
2019
-        }
2020
-        // was event trashed or restored ?
2021
-        switch ($event_status) {
2022
-            case 'draft' :
2023
-                $action = 'restored from the trash';
2024
-                $hook = 'AHEE_event_restored_from_trash';
2025
-                break;
2026
-            case 'trash' :
2027
-                $action = 'moved to the trash';
2028
-                $hook = 'AHEE_event_moved_to_trash';
2029
-                break;
2030
-            default :
2031
-                $action = 'updated';
2032
-                $hook = false;
2033
-        }
2034
-        //use class to change status
2035
-        $this->_cpt_model_obj->set_status($event_status);
2036
-        $success = $this->_cpt_model_obj->save();
2037
-        if ($success === false) {
2038
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2039
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2040
-            return false;
2041
-        }
2042
-        if ($hook) {
2043
-            do_action($hook);
2044
-        }
2045
-        return true;
2046
-    }
2047
-
2048
-
2049
-
2050
-    /**
2051
-     * _delete_event
2052
-     *
2053
-     * @access protected
2054
-     * @param bool $redirect_after
2055
-     */
2056
-    protected function _delete_event($redirect_after = true)
2057
-    {
2058
-        //determine the event id and set to array.
2059
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2060
-        $EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2061
-        // loop thru events
2062
-        if ($EVT_ID) {
2063
-            $success = $this->_permanently_delete_event($EVT_ID);
2064
-            // get list of events with no prices
2065
-            $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2066
-            // remove this event from the list of events with no prices
2067
-            if (isset($espresso_no_ticket_prices[$EVT_ID])) {
2068
-                unset($espresso_no_ticket_prices[$EVT_ID]);
2069
-            }
2070
-            update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2071
-        } else {
2072
-            $success = false;
2073
-            $msg = esc_html__(
2074
-                'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2075
-                'event_espresso'
2076
-            );
2077
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2078
-        }
2079
-        if ($redirect_after) {
2080
-            $this->_redirect_after_action(
2081
-                $success,
2082
-                'Event',
2083
-                'deleted',
2084
-                array('action' => 'default', 'status' => 'trash')
2085
-            );
2086
-        }
2087
-    }
2088
-
2089
-
2090
-
2091
-    /**
2092
-     * _delete_events
2093
-     *
2094
-     * @access protected
2095
-     * @return void
2096
-     */
2097
-    protected function _delete_events()
2098
-    {
2099
-        $success = true;
2100
-        // get list of events with no prices
2101
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2102
-        //determine the event id and set to array.
2103
-        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
2104
-        // loop thru events
2105
-        foreach ($EVT_IDs as $EVT_ID) {
2106
-            $EVT_ID = absint($EVT_ID);
2107
-            if ($EVT_ID) {
2108
-                $results = $this->_permanently_delete_event($EVT_ID);
2109
-                $success = $results !== false ? $success : false;
2110
-                // remove this event from the list of events with no prices
2111
-                unset($espresso_no_ticket_prices[$EVT_ID]);
2112
-            } else {
2113
-                $success = false;
2114
-                $msg = esc_html__(
2115
-                    'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2116
-                    'event_espresso'
2117
-                );
2118
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2119
-            }
2120
-        }
2121
-        update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2122
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2123
-        $success = $success ? 2 : false;
2124
-        $this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2125
-    }
2126
-
2127
-
2128
-
2129
-    /**
2130
-     * _permanently_delete_event
2131
-     *
2132
-     * @access  private
2133
-     * @param  int $EVT_ID
2134
-     * @return bool
2135
-     */
2136
-    private function _permanently_delete_event($EVT_ID = 0)
2137
-    {
2138
-        // grab event id
2139
-        if ( ! $EVT_ID) {
2140
-            $msg = esc_html__(
2141
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2142
-                'event_espresso'
2143
-            );
2144
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2145
-            return false;
2146
-        }
2147
-        if (
2148
-            ! $this->_cpt_model_obj instanceof EE_Event
2149
-            || $this->_cpt_model_obj->ID() !== $EVT_ID
2150
-        ) {
2151
-            $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2152
-        }
2153
-        if ( ! $this->_cpt_model_obj instanceof EE_Event) {
2154
-            return false;
2155
-        }
2156
-        //need to delete related tickets and prices first.
2157
-        $datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2158
-        foreach ($datetimes as $datetime) {
2159
-            $this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2160
-            $tickets = $datetime->get_many_related('Ticket');
2161
-            foreach ($tickets as $ticket) {
2162
-                $ticket->_remove_relation_to($datetime, 'Datetime');
2163
-                $ticket->delete_related_permanently('Price');
2164
-                $ticket->delete_permanently();
2165
-            }
2166
-            $datetime->delete();
2167
-        }
2168
-        //what about related venues or terms?
2169
-        $venues = $this->_cpt_model_obj->get_many_related('Venue');
2170
-        foreach ($venues as $venue) {
2171
-            $this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2172
-        }
2173
-        //any attached question groups?
2174
-        $question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2175
-        if ( ! empty($question_groups)) {
2176
-            foreach ($question_groups as $question_group) {
2177
-                $this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2178
-            }
2179
-        }
2180
-        //Message Template Groups
2181
-        $this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2182
-        /** @type EE_Term_Taxonomy[] $term_taxonomies */
2183
-        $term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2184
-        foreach ($term_taxonomies as $term_taxonomy) {
2185
-            $this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2186
-        }
2187
-        $success = $this->_cpt_model_obj->delete_permanently();
2188
-        // did it all go as planned ?
2189
-        if ($success) {
2190
-            $msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2191
-            EE_Error::add_success($msg);
2192
-        } else {
2193
-            $msg = sprintf(
2194
-                esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2195
-                $EVT_ID
2196
-            );
2197
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2198
-            return false;
2199
-        }
2200
-        do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2201
-        return true;
2202
-    }
2203
-
2204
-
2205
-
2206
-    /**
2207
-     * get total number of events
2208
-     *
2209
-     * @access public
2210
-     * @return int
2211
-     */
2212
-    public function total_events()
2213
-    {
2214
-        $count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2215
-        return $count;
2216
-    }
2217
-
2218
-
2219
-
2220
-    /**
2221
-     * get total number of draft events
2222
-     *
2223
-     * @access public
2224
-     * @return int
2225
-     */
2226
-    public function total_events_draft()
2227
-    {
2228
-        $where = array(
2229
-            'status' => array('IN', array('draft', 'auto-draft')),
2230
-        );
2231
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2232
-        return $count;
2233
-    }
2234
-
2235
-
2236
-
2237
-    /**
2238
-     * get total number of trashed events
2239
-     *
2240
-     * @access public
2241
-     * @return int
2242
-     */
2243
-    public function total_trashed_events()
2244
-    {
2245
-        $where = array(
2246
-            'status' => 'trash',
2247
-        );
2248
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2249
-        return $count;
2250
-    }
2251
-
2252
-
2253
-
2254
-    /**
2255
-     *    _default_event_settings
2256
-     *    This generates the Default Settings Tab
2257
-     *
2258
-     * @return void
2259
-     */
2260
-    protected function _default_event_settings()
2261
-    {
2262
-        $this->_template_args['values'] = $this->_yes_no_values;
2263
-        $this->_template_args['reg_status_array'] = EEM_Registration::reg_status_array(
2264
-        // exclude array
2265
-            array(
2266
-                EEM_Registration::status_id_cancelled,
2267
-                EEM_Registration::status_id_declined,
2268
-                EEM_Registration::status_id_incomplete,
2269
-                EEM_Registration::status_id_wait_list,
2270
-            ),
2271
-            // translated
2272
-            true
2273
-        );
2274
-        $this->_template_args['default_reg_status'] = isset(
2275
-                                                          EE_Registry::instance()->CFG->registration->default_STS_ID
2276
-                                                      )
2277
-                                                      && array_key_exists(
2278
-                                                          EE_Registry::instance()->CFG->registration->default_STS_ID,
2279
-                                                          $this->_template_args['reg_status_array']
2280
-                                                      )
2281
-            ? sanitize_text_field(EE_Registry::instance()->CFG->registration->default_STS_ID)
2282
-            : EEM_Registration::status_id_pending_payment;
2283
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2284
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2285
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2286
-            EVENTS_TEMPLATE_PATH . 'event_settings.template.php',
2287
-            $this->_template_args,
2288
-            true
2289
-        );
2290
-        $this->display_admin_page_with_sidebar();
2291
-    }
2292
-
2293
-
2294
-
2295
-    /**
2296
-     * _update_default_event_settings
2297
-     *
2298
-     * @access protected
2299
-     * @return void
2300
-     */
2301
-    protected function _update_default_event_settings()
2302
-    {
2303
-        EE_Config::instance()->registration->default_STS_ID = isset($this->_req_data['default_reg_status'])
2304
-            ? sanitize_text_field($this->_req_data['default_reg_status'])
2305
-            : EEM_Registration::status_id_pending_payment;
2306
-        $what = 'Default Event Settings';
2307
-        $success = $this->_update_espresso_configuration(
2308
-            $what,
2309
-            EE_Config::instance(),
2310
-            __FILE__,
2311
-            __FUNCTION__,
2312
-            __LINE__
2313
-        );
2314
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'default_event_settings'));
2315
-    }
2316
-
2317
-
2318
-
2319
-    /*************        Templates        *************/
2320
-    protected function _template_settings()
2321
-    {
2322
-        $this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2323
-        $this->_template_args['preview_img'] = '<img src="'
2324
-                                               . EVENTS_ASSETS_URL
2325
-                                               . DS
2326
-                                               . 'images'
2327
-                                               . DS
2328
-                                               . 'caffeinated_template_features.jpg" alt="'
2329
-                                               . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2330
-                                               . '" />';
2331
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__(
2332
-                '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.',
2333
-                'event_espresso'
2334
-            ) . '</strong>';
2335
-        $this->display_admin_caf_preview_page('template_settings_tab');
2336
-    }
2337
-
2338
-
2339
-    /** Event Category Stuff **/
2340
-    /**
2341
-     * set the _category property with the category object for the loaded page.
2342
-     *
2343
-     * @access private
2344
-     * @return void
2345
-     */
2346
-    private function _set_category_object()
2347
-    {
2348
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2349
-            return;
2350
-        } //already have the category object so get out.
2351
-        //set default category object
2352
-        $this->_set_empty_category_object();
2353
-        //only set if we've got an id
2354
-        if ( ! isset($this->_req_data['EVT_CAT_ID'])) {
2355
-            return;
2356
-        }
2357
-        $category_id = absint($this->_req_data['EVT_CAT_ID']);
2358
-        $term = get_term($category_id, 'espresso_event_categories');
2359
-        if ( ! empty($term)) {
2360
-            $this->_category->category_name = $term->name;
2361
-            $this->_category->category_identifier = $term->slug;
2362
-            $this->_category->category_desc = $term->description;
2363
-            $this->_category->id = $term->term_id;
2364
-            $this->_category->parent = $term->parent;
2365
-        }
2366
-    }
2367
-
2368
-
2369
-
2370
-    private function _set_empty_category_object()
2371
-    {
2372
-        $this->_category = new stdClass();
2373
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2374
-        $this->_category->id = $this->_category->parent = 0;
2375
-    }
2376
-
2377
-
2378
-
2379
-    protected function _category_list_table()
2380
-    {
2381
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2382
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2383
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2384
-                'add_category',
2385
-                'add_category',
2386
-                array(),
2387
-                'add-new-h2'
2388
-            );
2389
-        $this->display_admin_list_table_page_with_sidebar();
2390
-    }
2391
-
2392
-
2393
-
2394
-    /**
2395
-     * @param $view
2396
-     */
2397
-    protected function _category_details($view)
2398
-    {
2399
-        //load formatter helper
2400
-        //load field generator helper
2401
-        $route = $view == 'edit' ? 'update_category' : 'insert_category';
2402
-        $this->_set_add_edit_form_tags($route);
2403
-        $this->_set_category_object();
2404
-        $id = ! empty($this->_category->id) ? $this->_category->id : '';
2405
-        $delete_action = 'delete_category';
2406
-        //custom redirect
2407
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2408
-            array('action' => 'category_list'),
2409
-            $this->_admin_base_url
2410
-        );
2411
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2412
-        //take care of contents
2413
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2414
-        $this->display_admin_page_with_sidebar();
2415
-    }
2416
-
2417
-
2418
-
2419
-    /**
2420
-     * @return mixed
2421
-     */
2422
-    protected function _category_details_content()
2423
-    {
2424
-        $editor_args['category_desc'] = array(
2425
-            'type'          => 'wp_editor',
2426
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2427
-            'class'         => 'my_editor_custom',
2428
-            'wpeditor_args' => array('media_buttons' => false),
2429
-        );
2430
-        $_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2431
-        $all_terms = get_terms(
2432
-            array('espresso_event_categories'),
2433
-            array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2434
-        );
2435
-        //setup category select for term parents.
2436
-        $category_select_values[] = array(
2437
-            'text' => esc_html__('No Parent', 'event_espresso'),
2438
-            'id'   => 0,
2439
-        );
2440
-        foreach ($all_terms as $term) {
2441
-            $category_select_values[] = array(
2442
-                'text' => $term->name,
2443
-                'id'   => $term->term_id,
2444
-            );
2445
-        }
2446
-        $category_select = EEH_Form_Fields::select_input(
2447
-            'category_parent',
2448
-            $category_select_values,
2449
-            $this->_category->parent
2450
-        );
2451
-        $template_args = array(
2452
-            'category'                 => $this->_category,
2453
-            'category_select'          => $category_select,
2454
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2455
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2456
-            'disable'                  => '',
2457
-            'disabled_message'         => false,
2458
-        );
2459
-        $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2460
-        return EEH_Template::display_template($template, $template_args, true);
2461
-    }
2462
-
2463
-
2464
-
2465
-    protected function _delete_categories()
2466
-    {
2467
-        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array)$this->_req_data['EVT_CAT_ID']
2468
-            : (array)$this->_req_data['category_id'];
2469
-        foreach ($cat_ids as $cat_id) {
2470
-            $this->_delete_category($cat_id);
2471
-        }
2472
-        //doesn't matter what page we're coming from... we're going to the same place after delete.
2473
-        $query_args = array(
2474
-            'action' => 'category_list',
2475
-        );
2476
-        $this->_redirect_after_action(0, '', '', $query_args);
2477
-    }
2478
-
2479
-
2480
-
2481
-    /**
2482
-     * @param $cat_id
2483
-     */
2484
-    protected function _delete_category($cat_id)
2485
-    {
2486
-        $cat_id = absint($cat_id);
2487
-        wp_delete_term($cat_id, 'espresso_event_categories');
2488
-    }
2489
-
2490
-
2491
-
2492
-    /**
2493
-     * @param $new_category
2494
-     */
2495
-    protected function _insert_or_update_category($new_category)
2496
-    {
2497
-        $cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2498
-        $success = 0; //we already have a success message so lets not send another.
2499
-        if ($cat_id) {
2500
-            $query_args = array(
2501
-                'action'     => 'edit_category',
2502
-                'EVT_CAT_ID' => $cat_id,
2503
-            );
2504
-        } else {
2505
-            $query_args = array('action' => 'add_category');
2506
-        }
2507
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2508
-    }
2509
-
2510
-
2511
-
2512
-    /**
2513
-     * @param bool $update
2514
-     * @return bool|mixed|string
2515
-     */
2516
-    private function _insert_category($update = false)
2517
-    {
2518
-        $cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2519
-        $category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2520
-        $category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2521
-        $category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2522
-        if (empty($category_name)) {
2523
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2524
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2525
-            return false;
2526
-        }
2527
-        $term_args = array(
2528
-            'name'        => $category_name,
2529
-            'description' => $category_desc,
2530
-            'parent'      => $category_parent,
2531
-        );
2532
-        //was the category_identifier input disabled?
2533
-        if (isset($this->_req_data['category_identifier'])) {
2534
-            $term_args['slug'] = $this->_req_data['category_identifier'];
2535
-        }
2536
-        $insert_ids = $update
2537
-            ? wp_update_term($cat_id, 'espresso_event_categories', $term_args)
2538
-            : wp_insert_term($category_name, 'espresso_event_categories', $term_args);
2539
-        if ( ! is_array($insert_ids)) {
2540
-            $msg = esc_html__(
2541
-                'An error occurred and the category has not been saved to the database.',
2542
-                'event_espresso'
2543
-            );
2544
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2545
-        } else {
2546
-            $cat_id = $insert_ids['term_id'];
2547
-            $msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2548
-            EE_Error::add_success($msg);
2549
-        }
2550
-        return $cat_id;
2551
-    }
2552
-
2553
-
2554
-
2555
-    /**
2556
-     * @param int  $per_page
2557
-     * @param int  $current_page
2558
-     * @param bool $count
2559
-     * @return \EE_Base_Class[]|int
2560
-     */
2561
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2562
-    {
2563
-        //testing term stuff
2564
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2565
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2566
-        $limit = ($current_page - 1) * $per_page;
2567
-        $where = array('taxonomy' => 'espresso_event_categories');
2568
-        if (isset($this->_req_data['s'])) {
2569
-            $sstr = '%' . $this->_req_data['s'] . '%';
2570
-            $where['OR'] = array(
2571
-                'Term.name'   => array('LIKE', $sstr),
2572
-                'description' => array('LIKE', $sstr),
2573
-            );
2574
-        }
2575
-        $query_params = array(
2576
-            $where,
2577
-            'order_by'   => array($orderby => $order),
2578
-            'limit'      => $limit . ',' . $per_page,
2579
-            'force_join' => array('Term'),
2580
-        );
2581
-        $categories = $count
2582
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2583
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2584
-        return $categories;
2585
-    }
2586
-
2587
-
2588
-
2589
-    /* end category stuff */
2590
-    /**************/
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
+				),
407
+				'help_tour'     => array('Event_Default_Settings_Help_Tour'),
408
+				'require_nonce' => false,
409
+			),
410
+			//template settings
411
+			'template_settings'      => array(
412
+				'nav'           => array(
413
+					'label' => esc_html__('Templates', 'event_espresso'),
414
+					'order' => 30,
415
+				),
416
+				'metaboxes'     => $this->_default_espresso_metaboxes,
417
+				'help_tabs'     => array(
418
+					'general_settings_templates_help_tab' => array(
419
+						'title'    => esc_html__('Templates', 'event_espresso'),
420
+						'filename' => 'general_settings_templates',
421
+					),
422
+				),
423
+				'help_tour'     => array('Templates_Help_Tour'),
424
+				'require_nonce' => false,
425
+			),
426
+			//event category stuff
427
+			'add_category'           => array(
428
+				'nav'           => array(
429
+					'label'      => esc_html__('Add Category', 'event_espresso'),
430
+					'order'      => 15,
431
+					'persistent' => false,
432
+				),
433
+				'help_tabs'     => array(
434
+					'add_category_help_tab' => array(
435
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
436
+						'filename' => 'events_add_category',
437
+					),
438
+				),
439
+				'help_tour'     => array('Event_Add_Category_Help_Tour'),
440
+				'metaboxes'     => array('_publish_post_box'),
441
+				'require_nonce' => false,
442
+			),
443
+			'edit_category'          => array(
444
+				'nav'           => array(
445
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
446
+					'order'      => 15,
447
+					'persistent' => false,
448
+					'url'        => isset($this->_req_data['EVT_CAT_ID'])
449
+						? add_query_arg(
450
+							array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']),
451
+							$this->_current_page_view_url
452
+						)
453
+						: $this->_admin_base_url,
454
+				),
455
+				'help_tabs'     => array(
456
+					'edit_category_help_tab' => array(
457
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
458
+						'filename' => 'events_edit_category',
459
+					),
460
+				),
461
+				/*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
462
+				'metaboxes'     => array('_publish_post_box'),
463
+				'require_nonce' => false,
464
+			),
465
+			'category_list'          => array(
466
+				'nav'           => array(
467
+					'label' => esc_html__('Categories', 'event_espresso'),
468
+					'order' => 20,
469
+				),
470
+				'list_table'    => 'Event_Categories_Admin_List_Table',
471
+				'help_tabs'     => array(
472
+					'events_categories_help_tab'                       => array(
473
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
474
+						'filename' => 'events_categories',
475
+					),
476
+					'events_categories_table_column_headings_help_tab' => array(
477
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
478
+						'filename' => 'events_categories_table_column_headings',
479
+					),
480
+					'events_categories_view_help_tab'                  => array(
481
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
482
+						'filename' => 'events_categories_views',
483
+					),
484
+					'events_categories_other_help_tab'                 => array(
485
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
486
+						'filename' => 'events_categories_other',
487
+					),
488
+				),
489
+				'help_tour'     => array(
490
+					'Event_Categories_Help_Tour',
491
+				),
492
+				'metaboxes'     => $this->_default_espresso_metaboxes,
493
+				'require_nonce' => false,
494
+			),
495
+		);
496
+	}
497
+
498
+
499
+
500
+	protected function _add_screen_options()
501
+	{
502
+		//todo
503
+	}
504
+
505
+
506
+
507
+	protected function _add_screen_options_default()
508
+	{
509
+		$this->_per_page_screen_option();
510
+	}
511
+
512
+
513
+
514
+	protected function _add_screen_options_category_list()
515
+	{
516
+		$page_title = $this->_admin_page_title;
517
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
518
+		$this->_per_page_screen_option();
519
+		$this->_admin_page_title = $page_title;
520
+	}
521
+
522
+
523
+
524
+	protected function _add_feature_pointers()
525
+	{
526
+		//todo
527
+	}
528
+
529
+
530
+
531
+	public function load_scripts_styles()
532
+	{
533
+		wp_register_style(
534
+			'events-admin-css',
535
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
536
+			array(),
537
+			EVENT_ESPRESSO_VERSION
538
+		);
539
+		wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
540
+		wp_enqueue_style('events-admin-css');
541
+		wp_enqueue_style('ee-cat-admin');
542
+		//todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
543
+		//registers for all views
544
+		//scripts
545
+		wp_register_script(
546
+			'event_editor_js',
547
+			EVENTS_ASSETS_URL . 'event_editor.js',
548
+			array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
549
+			EVENT_ESPRESSO_VERSION,
550
+			true
551
+		);
552
+	}
553
+
554
+
555
+
556
+	/**
557
+	 * enqueuing scripts and styles specific to this view
558
+	 *
559
+	 * @return void
560
+	 */
561
+	public function load_scripts_styles_create_new()
562
+	{
563
+		$this->load_scripts_styles_edit();
564
+	}
565
+
566
+
567
+
568
+	/**
569
+	 * enqueuing scripts and styles specific to this view
570
+	 *
571
+	 * @return void
572
+	 */
573
+	public function load_scripts_styles_edit()
574
+	{
575
+		//styles
576
+		wp_enqueue_style('espresso-ui-theme');
577
+		wp_register_style(
578
+			'event-editor-css',
579
+			EVENTS_ASSETS_URL . 'event-editor.css',
580
+			array('ee-admin-css'),
581
+			EVENT_ESPRESSO_VERSION
582
+		);
583
+		wp_enqueue_style('event-editor-css');
584
+		//scripts
585
+		wp_register_script(
586
+			'event-datetime-metabox',
587
+			EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
588
+			array('event_editor_js', 'ee-datepicker'),
589
+			EVENT_ESPRESSO_VERSION
590
+		);
591
+		wp_enqueue_script('event-datetime-metabox');
592
+	}
593
+
594
+
595
+
596
+	public function load_scripts_styles_add_category()
597
+	{
598
+		$this->load_scripts_styles_edit_category();
599
+	}
600
+
601
+
602
+
603
+	public function load_scripts_styles_edit_category()
604
+	{
605
+	}
606
+
607
+
608
+
609
+	protected function _set_list_table_views_category_list()
610
+	{
611
+		$this->_views = array(
612
+			'all' => array(
613
+				'slug'        => 'all',
614
+				'label'       => esc_html__('All', 'event_espresso'),
615
+				'count'       => 0,
616
+				'bulk_action' => array(
617
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
618
+				),
619
+			),
620
+		);
621
+	}
622
+
623
+
624
+
625
+	public function admin_init()
626
+	{
627
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
628
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
629
+			'event_espresso'
630
+		);
631
+	}
632
+
633
+
634
+
635
+	//nothing needed for events with these methods.
636
+	public function admin_notices()
637
+	{
638
+	}
639
+
640
+
641
+
642
+	public function admin_footer_scripts()
643
+	{
644
+	}
645
+
646
+
647
+
648
+	/**
649
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
650
+	 * warning (via EE_Error::add_error());
651
+	 *
652
+	 * @param  EE_Event $event Event object
653
+	 * @access public
654
+	 * @return void
655
+	 */
656
+	public function verify_event_edit($event = null)
657
+	{
658
+		// no event?
659
+		if (empty($event)) {
660
+			// set event
661
+			$event = $this->_cpt_model_obj;
662
+		}
663
+		// STILL no event?
664
+		if (empty ($event)) {
665
+			return;
666
+		}
667
+		$orig_status = $event->status();
668
+		// first check if event is active.
669
+		if (
670
+			$orig_status === EEM_Event::cancelled
671
+			|| $orig_status === EEM_Event::postponed
672
+			|| $event->is_expired()
673
+			|| $event->is_inactive()
674
+		) {
675
+			return;
676
+		}
677
+		//made it here so it IS active... next check that any of the tickets are sold.
678
+		if ($event->is_sold_out(true)) {
679
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
680
+				EE_Error::add_attention(
681
+					sprintf(
682
+						esc_html__(
683
+							'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.',
684
+							'event_espresso'
685
+						),
686
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
687
+					)
688
+				);
689
+			}
690
+			return;
691
+		} else if ($orig_status === EEM_Event::sold_out) {
692
+			EE_Error::add_attention(
693
+				sprintf(
694
+					esc_html__(
695
+						'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.',
696
+						'event_espresso'
697
+					),
698
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
699
+				)
700
+			);
701
+		}
702
+		//now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
703
+		if ( ! $event->tickets_on_sale()) {
704
+			return;
705
+		}
706
+		//made it here so show warning
707
+		$this->_edit_event_warning();
708
+	}
709
+
710
+
711
+
712
+	/**
713
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
714
+	 * When needed, hook this into a EE_Error::add_error() notice.
715
+	 *
716
+	 * @access protected
717
+	 * @return void
718
+	 */
719
+	protected function _edit_event_warning()
720
+	{
721
+		// we don't want to add warnings during these requests
722
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
723
+			return;
724
+		}
725
+		EE_Error::add_attention(
726
+			esc_html__(
727
+				'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.',
728
+				'event_espresso'
729
+			)
730
+		);
731
+	}
732
+
733
+
734
+
735
+	/**
736
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
737
+	 * Otherwise, do the normal logic
738
+	 *
739
+	 * @return string
740
+	 * @throws \EE_Error
741
+	 */
742
+	protected function _create_new_cpt_item()
743
+	{
744
+		$gmt_offset = get_option('gmt_offset');
745
+		//only nag them about setting their timezone if it's their first event, and they haven't already done it
746
+		if ($gmt_offset === '0' && ! EEM_Event::instance()->exists(array())) {
747
+			EE_Error::add_attention(
748
+				sprintf(
749
+					__(
750
+						'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.',
751
+						'event_espresso'
752
+					),
753
+					'<a href="' . admin_url('options-general.php') . '">',
754
+					'</a>'
755
+				),
756
+				__FILE__,
757
+				__FUNCTION__,
758
+				__LINE__
759
+			);
760
+		}
761
+		return parent::_create_new_cpt_item();
762
+	}
763
+
764
+
765
+
766
+	protected function _set_list_table_views_default()
767
+	{
768
+		$this->_views = array(
769
+			'all'   => array(
770
+				'slug'        => 'all',
771
+				'label'       => esc_html__('View All Events', 'event_espresso'),
772
+				'count'       => 0,
773
+				'bulk_action' => array(
774
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
775
+				),
776
+			),
777
+			'draft' => array(
778
+				'slug'        => 'draft',
779
+				'label'       => esc_html__('Draft', 'event_espresso'),
780
+				'count'       => 0,
781
+				'bulk_action' => array(
782
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
783
+				),
784
+			),
785
+		);
786
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
787
+			$this->_views['trash'] = array(
788
+				'slug'        => 'trash',
789
+				'label'       => esc_html__('Trash', 'event_espresso'),
790
+				'count'       => 0,
791
+				'bulk_action' => array(
792
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
793
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
794
+				),
795
+			);
796
+		}
797
+	}
798
+
799
+
800
+
801
+	/**
802
+	 * @return array
803
+	 */
804
+	protected function _event_legend_items()
805
+	{
806
+		$items = array(
807
+			'view_details'   => array(
808
+				'class' => 'dashicons dashicons-search',
809
+				'desc'  => esc_html__('View Event', 'event_espresso'),
810
+			),
811
+			'edit_event'     => array(
812
+				'class' => 'ee-icon ee-icon-calendar-edit',
813
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
814
+			),
815
+			'view_attendees' => array(
816
+				'class' => 'dashicons dashicons-groups',
817
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
818
+			),
819
+		);
820
+		$items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
821
+		$statuses = array(
822
+			'sold_out_status'  => array(
823
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
824
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
825
+			),
826
+			'active_status'    => array(
827
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
828
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
829
+			),
830
+			'upcoming_status'  => array(
831
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
832
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
833
+			),
834
+			'postponed_status' => array(
835
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
836
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
837
+			),
838
+			'cancelled_status' => array(
839
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
840
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
841
+			),
842
+			'expired_status'   => array(
843
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
844
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
845
+			),
846
+			'inactive_status'  => array(
847
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
848
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
849
+			),
850
+		);
851
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
852
+		return array_merge($items, $statuses);
853
+	}
854
+
855
+
856
+
857
+	/**
858
+	 * _event_model
859
+	 *
860
+	 * @return EEM_Event
861
+	 */
862
+	private function _event_model()
863
+	{
864
+		if ( ! $this->_event_model instanceof EEM_Event) {
865
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
866
+		}
867
+		return $this->_event_model;
868
+	}
869
+
870
+
871
+
872
+	/**
873
+	 * Adds extra buttons to the WP CPT permalink field row.
874
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
875
+	 *
876
+	 * @param  string $return    the current html
877
+	 * @param  int    $id        the post id for the page
878
+	 * @param  string $new_title What the title is
879
+	 * @param  string $new_slug  what the slug is
880
+	 * @return string            The new html string for the permalink area
881
+	 */
882
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
883
+	{
884
+		//make sure this is only when editing
885
+		if ( ! empty($id)) {
886
+			$post = get_post($id);
887
+			$return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
888
+					   . esc_html__('Shortcode', 'event_espresso')
889
+					   . '</a> ';
890
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
891
+					   . $post->ID
892
+					   . ']">';
893
+		}
894
+		return $return;
895
+	}
896
+
897
+
898
+
899
+	/**
900
+	 * _events_overview_list_table
901
+	 * This contains the logic for showing the events_overview list
902
+	 *
903
+	 * @access protected
904
+	 * @return void
905
+	 * @throws \EE_Error
906
+	 */
907
+	protected function _events_overview_list_table()
908
+	{
909
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
910
+		$this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
911
+			? (array)$this->_template_args['after_list_table']
912
+			: array();
913
+		$this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
914
+																			  . EEH_Template::get_button_or_link(
915
+				get_post_type_archive_link('espresso_events'),
916
+				esc_html__("View Event Archive Page", "event_espresso"),
917
+				'button'
918
+			);
919
+		$this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
920
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
921
+				'create_new',
922
+				'add',
923
+				array(),
924
+				'add-new-h2'
925
+			);
926
+		$this->display_admin_list_table_page_with_no_sidebar();
927
+	}
928
+
929
+
930
+
931
+	/**
932
+	 * this allows for extra misc actions in the default WP publish box
933
+	 *
934
+	 * @return void
935
+	 */
936
+	public function extra_misc_actions_publish_box()
937
+	{
938
+		$this->_generate_publish_box_extra_content();
939
+	}
940
+
941
+
942
+
943
+	/**
944
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
945
+	 * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
946
+	 * data.
947
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
948
+	 * ALSO very important.  When a post transitions from scheduled to published, the save_post action is fired but you
949
+	 * will NOT have any _POST data containing any extra info you may have from other meta saves.  So MAKE sure that
950
+	 * you handle this accordingly.
951
+	 *
952
+	 * @access protected
953
+	 * @abstract
954
+	 * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
955
+	 * @param  object $post    The post object of the cpt that was saved.
956
+	 * @return void
957
+	 */
958
+	protected function _insert_update_cpt_item($post_id, $post)
959
+	{
960
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
961
+			//get out we're not processing an event save.
962
+			return;
963
+		}
964
+		$event_values = array(
965
+			'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
966
+			'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
967
+			'EVT_additional_limit'            => min(
968
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
969
+				! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
970
+			),
971
+			'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
972
+				? $this->_req_data['EVT_default_registration_status']
973
+				: EE_Registry::instance()->CFG->registration->default_STS_ID,
974
+			'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
975
+			'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
976
+			'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
977
+				? $this->_req_data['timezone_string'] : null,
978
+			'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
979
+				? $this->_req_data['externalURL'] : null,
980
+			'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
981
+				? $this->_req_data['event_phone'] : null,
982
+		);
983
+		//update event
984
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
985
+		//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!
986
+		$get_one_where = array($this->_event_model()->primary_key_name() => $post_id, 'status' => $post->post_status);
987
+		$event = $this->_event_model()->get_one(array($get_one_where));
988
+		//the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
989
+		$event_update_callbacks = apply_filters(
990
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
991
+			array(array($this, '_default_venue_update'), array($this, '_default_tickets_update'))
992
+		);
993
+		$att_success = true;
994
+		foreach ($event_update_callbacks as $e_callback) {
995
+			$_succ = call_user_func_array($e_callback, array($event, $this->_req_data));
996
+			$att_success = ! $att_success ? $att_success
997
+				: $_succ; //if ANY of these updates fail then we want the appropriate global error message
998
+		}
999
+		//any errors?
1000
+		if ($success && false === $att_success) {
1001
+			EE_Error::add_error(
1002
+				esc_html__(
1003
+					'Event Details saved successfully but something went wrong with saving attachments.',
1004
+					'event_espresso'
1005
+				),
1006
+				__FILE__,
1007
+				__FUNCTION__,
1008
+				__LINE__
1009
+			);
1010
+		} else if ($success === false) {
1011
+			EE_Error::add_error(
1012
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1013
+				__FILE__,
1014
+				__FUNCTION__,
1015
+				__LINE__
1016
+			);
1017
+		}
1018
+	}
1019
+
1020
+
1021
+
1022
+	/**
1023
+	 * @see parent::restore_item()
1024
+	 * @param int $post_id
1025
+	 * @param int $revision_id
1026
+	 */
1027
+	protected function _restore_cpt_item($post_id, $revision_id)
1028
+	{
1029
+		//copy existing event meta to new post
1030
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1031
+		if ($post_evt instanceof EE_Event) {
1032
+			//meta revision restore
1033
+			$post_evt->restore_revision($revision_id);
1034
+			//related objs restore
1035
+			$post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1036
+		}
1037
+	}
1038
+
1039
+
1040
+
1041
+	/**
1042
+	 * Attach the venue to the Event
1043
+	 *
1044
+	 * @param  \EE_Event $evtobj Event Object to add the venue to
1045
+	 * @param  array     $data   The request data from the form
1046
+	 * @return bool           Success or fail.
1047
+	 */
1048
+	protected function _default_venue_update(\EE_Event $evtobj, $data)
1049
+	{
1050
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1051
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1052
+		$rows_affected = null;
1053
+		$venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1054
+		// very important.  If we don't have a venue name...
1055
+		// then we'll get out because not necessary to create empty venue
1056
+		if (empty($data['venue_title'])) {
1057
+			return false;
1058
+		}
1059
+		$venue_array = array(
1060
+			'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1061
+			'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1062
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1063
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1064
+			'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1065
+				: null,
1066
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1067
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1068
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1069
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1070
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1071
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1072
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1073
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1074
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1075
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1076
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1077
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1078
+			'status'              => 'publish',
1079
+		);
1080
+		//if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1081
+		if ( ! empty($venue_id)) {
1082
+			$update_where = array($venue_model->primary_key_name() => $venue_id);
1083
+			$rows_affected = $venue_model->update($venue_array, array($update_where));
1084
+			//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.
1085
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1086
+			return $rows_affected > 0 ? true : false;
1087
+		} else {
1088
+			//we insert the venue
1089
+			$venue_id = $venue_model->insert($venue_array);
1090
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1091
+			return ! empty($venue_id) ? true : false;
1092
+		}
1093
+		//when we have the ancestor come in it's already been handled by the revision save.
1094
+	}
1095
+
1096
+
1097
+
1098
+	/**
1099
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1100
+	 *
1101
+	 * @param  EE_Event $evtobj The Event object we're attaching data to
1102
+	 * @param  array    $data   The request data from the form
1103
+	 * @return array
1104
+	 */
1105
+	protected function _default_tickets_update(EE_Event $evtobj, $data)
1106
+	{
1107
+		$success = true;
1108
+		$saved_dtt = null;
1109
+		$saved_tickets = array();
1110
+		$incoming_date_formats = array('Y-m-d', 'h:i a');
1111
+		foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1112
+			//trim all values to ensure any excess whitespace is removed.
1113
+			$dtt = array_map('trim', $dtt);
1114
+			$dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1115
+				: $dtt['DTT_EVT_start'];
1116
+			$datetime_values = array(
1117
+				'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1118
+				'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1119
+				'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1120
+				'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1121
+				'DTT_order'     => $row,
1122
+			);
1123
+			//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.
1124
+			if ( ! empty($dtt['DTT_ID'])) {
1125
+				$DTM = EE_Registry::instance()
1126
+								  ->load_model('Datetime', array($evtobj->get_timezone()))
1127
+								  ->get_one_by_ID($dtt['DTT_ID']);
1128
+				$DTM->set_date_format($incoming_date_formats[0]);
1129
+				$DTM->set_time_format($incoming_date_formats[1]);
1130
+				foreach ($datetime_values as $field => $value) {
1131
+					$DTM->set($field, $value);
1132
+				}
1133
+				//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.
1134
+				$saved_dtts[$DTM->ID()] = $DTM;
1135
+			} else {
1136
+				$DTM = EE_Registry::instance()->load_class(
1137
+					'Datetime',
1138
+					array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1139
+					false,
1140
+					false
1141
+				);
1142
+				foreach ($datetime_values as $field => $value) {
1143
+					$DTM->set($field, $value);
1144
+				}
1145
+			}
1146
+			$DTM->save();
1147
+			$DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1148
+			//load DTT helper
1149
+			//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.
1150
+			if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1151
+				$DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1152
+				$DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1153
+				$DTT->save();
1154
+			}
1155
+			//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.
1156
+			$saved_dtt = $DTT;
1157
+			$success = ! $success ? $success : $DTT;
1158
+			//if ANY of these updates fail then we want the appropriate global error message.
1159
+			// //todo this is actually sucky we need a better error message but this is what it is for now.
1160
+		}
1161
+		//no dtts get deleted so we don't do any of that logic here.
1162
+		//update tickets next
1163
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1164
+		foreach ($data['edit_tickets'] as $row => $tkt) {
1165
+			$incoming_date_formats = array('Y-m-d', 'h:i a');
1166
+			$update_prices = false;
1167
+			$ticket_price = isset($data['edit_prices'][$row][1]['PRC_amount'])
1168
+				? $data['edit_prices'][$row][1]['PRC_amount'] : 0;
1169
+			// trim inputs to ensure any excess whitespace is removed.
1170
+			$tkt = array_map('trim', $tkt);
1171
+			if (empty($tkt['TKT_start_date'])) {
1172
+				//let's use now in the set timezone.
1173
+				$now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1174
+				$tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1175
+			}
1176
+			if (empty($tkt['TKT_end_date'])) {
1177
+				//use the start date of the first datetime
1178
+				$dtt = $evtobj->first_datetime();
1179
+				$tkt['TKT_end_date'] = $dtt->start_date_and_time(
1180
+					$incoming_date_formats[0],
1181
+					$incoming_date_formats[1]
1182
+				);
1183
+			}
1184
+			$TKT_values = array(
1185
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1186
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1187
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1188
+				'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1189
+				'TKT_start_date'  => $tkt['TKT_start_date'],
1190
+				'TKT_end_date'    => $tkt['TKT_end_date'],
1191
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1192
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1193
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1194
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1195
+				'TKT_row'         => $row,
1196
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1197
+				'TKT_price'       => $ticket_price,
1198
+			);
1199
+			//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.
1200
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1201
+				$TKT_values['TKT_ID'] = 0;
1202
+				$TKT_values['TKT_is_default'] = 0;
1203
+				$TKT_values['TKT_price'] = $ticket_price;
1204
+				$update_prices = true;
1205
+			}
1206
+			//if we have a TKT_ID then we need to get that existing TKT_obj and update it
1207
+			//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.
1208
+			//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.
1209
+			if ( ! empty($tkt['TKT_ID'])) {
1210
+				$TKT = EE_Registry::instance()
1211
+								  ->load_model('Ticket', array($evtobj->get_timezone()))
1212
+								  ->get_one_by_ID($tkt['TKT_ID']);
1213
+				if ($TKT instanceof EE_Ticket) {
1214
+					$ticket_sold = $TKT->count_related(
1215
+						'Registration',
1216
+						array(
1217
+							array(
1218
+								'STS_ID' => array(
1219
+									'NOT IN',
1220
+									array(EEM_Registration::status_id_incomplete),
1221
+								),
1222
+							),
1223
+						)
1224
+					) > 0 ? true : false;
1225
+					//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.
1226
+					$create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price')
1227
+									  && ! $TKT->get(
1228
+						'TKT_deleted'
1229
+					) ? true : false;
1230
+					$TKT->set_date_format($incoming_date_formats[0]);
1231
+					$TKT->set_time_format($incoming_date_formats[1]);
1232
+					//set new values
1233
+					foreach ($TKT_values as $field => $value) {
1234
+						if ($field == 'TKT_qty') {
1235
+							$TKT->set_qty($value);
1236
+						} else {
1237
+							$TKT->set($field, $value);
1238
+						}
1239
+					}
1240
+					//if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1241
+					if ($create_new_TKT) {
1242
+						//archive the old ticket first
1243
+						$TKT->set('TKT_deleted', 1);
1244
+						$TKT->save();
1245
+						//make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1246
+						$saved_tickets[$TKT->ID()] = $TKT;
1247
+						//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.
1248
+						$TKT = clone $TKT;
1249
+						$TKT->set('TKT_ID', 0);
1250
+						$TKT->set('TKT_deleted', 0);
1251
+						$TKT->set('TKT_price', $ticket_price);
1252
+						$TKT->set('TKT_sold', 0);
1253
+						//now we need to make sure that $new prices are created as well and attached to new ticket.
1254
+						$update_prices = true;
1255
+					}
1256
+					//make sure price is set if it hasn't been already
1257
+					$TKT->set('TKT_price', $ticket_price);
1258
+				}
1259
+			} else {
1260
+				//no TKT_id so a new TKT
1261
+				$TKT_values['TKT_price'] = $ticket_price;
1262
+				$TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1263
+				if ($TKT instanceof EE_Ticket) {
1264
+					//need to reset values to properly account for the date formats
1265
+					$TKT->set_date_format($incoming_date_formats[0]);
1266
+					$TKT->set_time_format($incoming_date_formats[1]);
1267
+					$TKT->set_timezone($evtobj->get_timezone());
1268
+					//set new values
1269
+					foreach ($TKT_values as $field => $value) {
1270
+						if ($field == 'TKT_qty') {
1271
+							$TKT->set_qty($value);
1272
+						} else {
1273
+							$TKT->set($field, $value);
1274
+						}
1275
+					}
1276
+					$update_prices = true;
1277
+				}
1278
+			}
1279
+			// cap ticket qty by datetime reg limits
1280
+			$TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1281
+			//update ticket.
1282
+			$TKT->save();
1283
+			//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.
1284
+			if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1285
+				$TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1286
+				$TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1287
+				$TKT->save();
1288
+			}
1289
+			//initially let's add the ticket to the dtt
1290
+			$saved_dtt->_add_relation_to($TKT, 'Ticket');
1291
+			$saved_tickets[$TKT->ID()] = $TKT;
1292
+			//add prices to ticket
1293
+			$this->_add_prices_to_ticket($data['edit_prices'][$row], $TKT, $update_prices);
1294
+		}
1295
+		//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.
1296
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
1297
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1298
+		foreach ($tickets_removed as $id) {
1299
+			$id = absint($id);
1300
+			//get the ticket for this id
1301
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1302
+			//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)
1303
+			$dtts = $tkt_to_remove->get_many_related('Datetime');
1304
+			foreach ($dtts as $dtt) {
1305
+				$tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1306
+			}
1307
+			//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))
1308
+			$tkt_to_remove->delete_related_permanently('Price');
1309
+			//finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1310
+			$tkt_to_remove->delete_permanently();
1311
+		}
1312
+		return array($saved_dtt, $saved_tickets);
1313
+	}
1314
+
1315
+
1316
+
1317
+	/**
1318
+	 * This attaches a list of given prices to a ticket.
1319
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1320
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1321
+	 * price info and prices are automatically "archived" via the ticket.
1322
+	 *
1323
+	 * @access  private
1324
+	 * @param array     $prices     Array of prices from the form.
1325
+	 * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1326
+	 * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1327
+	 * @return  void
1328
+	 */
1329
+	private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1330
+	{
1331
+		foreach ($prices as $row => $prc) {
1332
+			$PRC_values = array(
1333
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1334
+				'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1335
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1336
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1337
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1338
+				'PRC_is_default' => 0, //make sure prices are NOT set as default from this context
1339
+				'PRC_order'      => $row,
1340
+			);
1341
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
1342
+				$PRC_values['PRC_ID'] = 0;
1343
+				$PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1344
+			} else {
1345
+				$PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1346
+				//update this price with new values
1347
+				foreach ($PRC_values as $field => $newprc) {
1348
+					$PRC->set($field, $newprc);
1349
+				}
1350
+				$PRC->save();
1351
+			}
1352
+			$ticket->_add_relation_to($PRC, 'Price');
1353
+		}
1354
+	}
1355
+
1356
+
1357
+
1358
+	/**
1359
+	 * Add in our autosave ajax handlers
1360
+	 *
1361
+	 * @return void
1362
+	 */
1363
+	protected function _ee_autosave_create_new()
1364
+	{
1365
+		// $this->_ee_autosave_edit();
1366
+	}
1367
+
1368
+
1369
+
1370
+	protected function _ee_autosave_edit()
1371
+	{
1372
+		return; //TEMPORARILY EXITING CAUSE THIS IS A TODO
1373
+	}
1374
+
1375
+
1376
+
1377
+	/**
1378
+	 *    _generate_publish_box_extra_content
1379
+	 *
1380
+	 * @access private
1381
+	 * @return void
1382
+	 */
1383
+	private function _generate_publish_box_extra_content()
1384
+	{
1385
+		//load formatter helper
1386
+		//args for getting related registrations
1387
+		$approved_query_args = array(
1388
+			array(
1389
+				'REG_deleted' => 0,
1390
+				'STS_ID'      => EEM_Registration::status_id_approved,
1391
+			),
1392
+		);
1393
+		$not_approved_query_args = array(
1394
+			array(
1395
+				'REG_deleted' => 0,
1396
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1397
+			),
1398
+		);
1399
+		$pending_payment_query_args = array(
1400
+			array(
1401
+				'REG_deleted' => 0,
1402
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1403
+			),
1404
+		);
1405
+		// publish box
1406
+		$publish_box_extra_args = array(
1407
+			'view_approved_reg_url'        => add_query_arg(
1408
+				array(
1409
+					'action'      => 'default',
1410
+					'event_id'    => $this->_cpt_model_obj->ID(),
1411
+					'_reg_status' => EEM_Registration::status_id_approved,
1412
+				),
1413
+				REG_ADMIN_URL
1414
+			),
1415
+			'view_not_approved_reg_url'    => add_query_arg(
1416
+				array(
1417
+					'action'      => 'default',
1418
+					'event_id'    => $this->_cpt_model_obj->ID(),
1419
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1420
+				),
1421
+				REG_ADMIN_URL
1422
+			),
1423
+			'view_pending_payment_reg_url' => add_query_arg(
1424
+				array(
1425
+					'action'      => 'default',
1426
+					'event_id'    => $this->_cpt_model_obj->ID(),
1427
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1428
+				),
1429
+				REG_ADMIN_URL
1430
+			),
1431
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1432
+				'Registration',
1433
+				$approved_query_args
1434
+			),
1435
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1436
+				'Registration',
1437
+				$not_approved_query_args
1438
+			),
1439
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1440
+				'Registration',
1441
+				$pending_payment_query_args
1442
+			),
1443
+			'misc_pub_section_class'       => apply_filters(
1444
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1445
+				'misc-pub-section'
1446
+			),
1447
+			//'email_attendees_url' => add_query_arg(
1448
+			//	array(
1449
+			//		'event_admin_reports' => 'event_newsletter',
1450
+			//		'event_id' => $this->_cpt_model_obj->id
1451
+			//	),
1452
+			//	'admin.php?page=espresso_registrations'
1453
+			//),
1454
+		);
1455
+		ob_start();
1456
+		do_action(
1457
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1458
+			$this->_cpt_model_obj
1459
+		);
1460
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1461
+		// load template
1462
+		EEH_Template::display_template(
1463
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1464
+			$publish_box_extra_args
1465
+		);
1466
+	}
1467
+
1468
+
1469
+
1470
+	/**
1471
+	 * This just returns whatever is set as the _event object property
1472
+	 * //todo this will become obsolete once the models are in place
1473
+	 *
1474
+	 * @return object
1475
+	 */
1476
+	public function get_event_object()
1477
+	{
1478
+		return $this->_cpt_model_obj;
1479
+	}
1480
+
1481
+
1482
+
1483
+
1484
+	/** METABOXES * */
1485
+	/**
1486
+	 * _register_event_editor_meta_boxes
1487
+	 * add all metaboxes related to the event_editor
1488
+	 *
1489
+	 * @return void
1490
+	 */
1491
+	protected function _register_event_editor_meta_boxes()
1492
+	{
1493
+		$this->verify_cpt_object();
1494
+		add_meta_box(
1495
+			'espresso_event_editor_tickets',
1496
+			esc_html__('Event Datetime & Ticket', 'event_espresso'),
1497
+			array($this, 'ticket_metabox'),
1498
+			$this->page_slug,
1499
+			'normal',
1500
+			'high'
1501
+		);
1502
+		add_meta_box(
1503
+			'espresso_event_editor_event_options',
1504
+			esc_html__('Event Registration Options', 'event_espresso'),
1505
+			array($this, 'registration_options_meta_box'),
1506
+			$this->page_slug,
1507
+			'side',
1508
+			'default'
1509
+		);
1510
+		// NOTE: if you're looking for other metaboxes in here,
1511
+		// where a metabox has a related management page in the admin
1512
+		// you will find it setup in the related management page's "_Hooks" file.
1513
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1514
+	}
1515
+
1516
+
1517
+
1518
+	public function ticket_metabox()
1519
+	{
1520
+		$existing_datetime_ids = $existing_ticket_ids = array();
1521
+		//defaults for template args
1522
+		$template_args = array(
1523
+			'existing_datetime_ids'    => '',
1524
+			'event_datetime_help_link' => '',
1525
+			'ticket_options_help_link' => '',
1526
+			'time'                     => null,
1527
+			'ticket_rows'              => '',
1528
+			'existing_ticket_ids'      => '',
1529
+			'total_ticket_rows'        => 1,
1530
+			'ticket_js_structure'      => '',
1531
+			'trash_icon'               => 'ee-lock-icon',
1532
+			'disabled'                 => '',
1533
+		);
1534
+		$event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1535
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1536
+		/**
1537
+		 * 1. Start with retrieving Datetimes
1538
+		 * 2. Fore each datetime get related tickets
1539
+		 * 3. For each ticket get related prices
1540
+		 */
1541
+		$times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1542
+		/** @type EE_Datetime $first_datetime */
1543
+		$first_datetime = reset($times);
1544
+		//do we get related tickets?
1545
+		if ($first_datetime instanceof EE_Datetime
1546
+			&& $first_datetime->ID() !== 0
1547
+		) {
1548
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1549
+			$template_args['time'] = $first_datetime;
1550
+			$related_tickets = $first_datetime->tickets(
1551
+				array(
1552
+					array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1553
+					'default_where_conditions' => 'none',
1554
+				)
1555
+			);
1556
+			if ( ! empty($related_tickets)) {
1557
+				$template_args['total_ticket_rows'] = count($related_tickets);
1558
+				$row = 0;
1559
+				foreach ($related_tickets as $ticket) {
1560
+					$existing_ticket_ids[] = $ticket->get('TKT_ID');
1561
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1562
+					$row++;
1563
+				}
1564
+			} else {
1565
+				$template_args['total_ticket_rows'] = 1;
1566
+				/** @type EE_Ticket $ticket */
1567
+				$ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1568
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1569
+			}
1570
+		} else {
1571
+			$template_args['time'] = $times[0];
1572
+			/** @type EE_Ticket $ticket */
1573
+			$ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1574
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1575
+			// NOTE: we're just sending the first default row
1576
+			// (decaf can't manage default tickets so this should be sufficient);
1577
+		}
1578
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1579
+			'event_editor_event_datetimes_help_tab'
1580
+		);
1581
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1582
+		$template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1583
+		$template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1584
+		$template_args['ticket_js_structure'] = $this->_get_ticket_row(
1585
+			EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1586
+			true
1587
+		);
1588
+		$template = apply_filters(
1589
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1590
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1591
+		);
1592
+		EEH_Template::display_template($template, $template_args);
1593
+	}
1594
+
1595
+
1596
+
1597
+	/**
1598
+	 * Setup an individual ticket form for the decaf event editor page
1599
+	 *
1600
+	 * @access private
1601
+	 * @param  EE_Ticket $ticket   the ticket object
1602
+	 * @param  boolean   $skeleton whether we're generating a skeleton for js manipulation
1603
+	 * @param int        $row
1604
+	 * @return string generated html for the ticket row.
1605
+	 */
1606
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1607
+	{
1608
+		$template_args = array(
1609
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1610
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1611
+				: '',
1612
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1613
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1614
+			'TKT_name'            => $ticket->get('TKT_name'),
1615
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1616
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1617
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1618
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1619
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1620
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1621
+			'trash_icon'          => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')))
1622
+									 && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1623
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1624
+			'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1625
+				: ' disabled=disabled',
1626
+		);
1627
+		$price = $ticket->ID() !== 0
1628
+			? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1629
+			: EE_Registry::instance()->load_model('Price')->create_default_object();
1630
+		$price_args = array(
1631
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1632
+			'PRC_amount'            => $price->get('PRC_amount'),
1633
+			'PRT_ID'                => $price->get('PRT_ID'),
1634
+			'PRC_ID'                => $price->get('PRC_ID'),
1635
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1636
+		);
1637
+		//make sure we have default start and end dates if skeleton
1638
+		//handle rows that should NOT be empty
1639
+		if (empty($template_args['TKT_start_date'])) {
1640
+			//if empty then the start date will be now.
1641
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1642
+		}
1643
+		if (empty($template_args['TKT_end_date'])) {
1644
+			//get the earliest datetime (if present);
1645
+			$earliest_dtt = $this->_cpt_model_obj->ID() > 0
1646
+				? $this->_cpt_model_obj->get_first_related(
1647
+					'Datetime',
1648
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1649
+				)
1650
+				: null;
1651
+			if ( ! empty($earliest_dtt)) {
1652
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1653
+			} else {
1654
+				$template_args['TKT_end_date'] = date(
1655
+					'Y-m-d h:i a',
1656
+					mktime(0, 0, 0, date("m"), date("d") + 7, date("Y"))
1657
+				);
1658
+			}
1659
+		}
1660
+		$template_args = array_merge($template_args, $price_args);
1661
+		$template = apply_filters(
1662
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1663
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1664
+			$ticket
1665
+		);
1666
+		return EEH_Template::display_template($template, $template_args, true);
1667
+	}
1668
+
1669
+
1670
+
1671
+	public function registration_options_meta_box()
1672
+	{
1673
+		$yes_no_values = array(
1674
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1675
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1676
+		);
1677
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1678
+			array(
1679
+				EEM_Registration::status_id_cancelled,
1680
+				EEM_Registration::status_id_declined,
1681
+				EEM_Registration::status_id_incomplete,
1682
+			),
1683
+			true
1684
+		);
1685
+		//$template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1686
+		$template_args['_event'] = $this->_cpt_model_obj;
1687
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1688
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1689
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1690
+			'default_reg_status',
1691
+			$default_reg_status_values,
1692
+			$this->_cpt_model_obj->default_registration_status()
1693
+		);
1694
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
1695
+			'display_desc',
1696
+			$yes_no_values,
1697
+			$this->_cpt_model_obj->display_description()
1698
+		);
1699
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1700
+			'display_ticket_selector',
1701
+			$yes_no_values,
1702
+			$this->_cpt_model_obj->display_ticket_selector(),
1703
+			'',
1704
+			'',
1705
+			false
1706
+		);
1707
+		$template_args['additional_registration_options'] = apply_filters(
1708
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1709
+			'',
1710
+			$template_args,
1711
+			$yes_no_values,
1712
+			$default_reg_status_values
1713
+		);
1714
+		EEH_Template::display_template(
1715
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1716
+			$template_args
1717
+		);
1718
+	}
1719
+
1720
+
1721
+
1722
+	/**
1723
+	 * _get_events()
1724
+	 * This method simply returns all the events (for the given _view and paging)
1725
+	 *
1726
+	 * @access public
1727
+	 * @param int  $per_page     count of items per page (20 default);
1728
+	 * @param int  $current_page what is the current page being viewed.
1729
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1730
+	 *                           If FALSE then we return an array of event objects
1731
+	 *                           that match the given _view and paging parameters.
1732
+	 * @return array an array of event objects.
1733
+	 */
1734
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1735
+	{
1736
+		$EEME = $this->_event_model();
1737
+		$offset = ($current_page - 1) * $per_page;
1738
+		$limit = $count ? null : $offset . ',' . $per_page;
1739
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1740
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1741
+		if (isset($this->_req_data['month_range'])) {
1742
+			$pieces = explode(' ', $this->_req_data['month_range'], 3);
1743
+			//simulate the FIRST day of the month, that fixes issues for months like February
1744
+			//where PHP doesn't know what to assume for date.
1745
+			//@see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1746
+			$month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1747
+			$year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1748
+		}
1749
+		$where = array();
1750
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1751
+		//determine what post_status our condition will have for the query.
1752
+		switch ($status) {
1753
+			case 'month' :
1754
+			case 'today' :
1755
+			case null :
1756
+			case 'all' :
1757
+				break;
1758
+			case 'draft' :
1759
+				$where['status'] = array('IN', array('draft', 'auto-draft'));
1760
+				break;
1761
+			default :
1762
+				$where['status'] = $status;
1763
+		}
1764
+		//categories?
1765
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1766
+			? $this->_req_data['EVT_CAT'] : null;
1767
+		if ( ! empty ($category)) {
1768
+			$where['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1769
+			$where['Term_Taxonomy.term_id'] = $category;
1770
+		}
1771
+		//date where conditions
1772
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1773
+		if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1774
+			$DateTime = new DateTime(
1775
+				$year_r . '-' . $month_r . '-01 00:00:00',
1776
+				new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1777
+			);
1778
+			$start = $DateTime->format(implode(' ', $start_formats));
1779
+			$end = $DateTime->setDate($year_r, $month_r, $DateTime
1780
+				->format('t'))->setTime(23, 59, 59)
1781
+							->format(implode(' ', $start_formats));
1782
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1783
+		} else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') {
1784
+			$DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1785
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1786
+			$end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1787
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1788
+		} else if (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') {
1789
+			$now = date('Y-m-01');
1790
+			$DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1791
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1792
+			$end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1793
+							->setTime(23, 59, 59)
1794
+							->format(implode(' ', $start_formats));
1795
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1796
+		}
1797
+		if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1798
+			$where['EVT_wp_user'] = get_current_user_id();
1799
+		} else {
1800
+			if ( ! isset($where['status'])) {
1801
+				if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1802
+					$where['OR'] = array(
1803
+						'status*restrict_private' => array('!=', 'private'),
1804
+						'AND'                     => array(
1805
+							'status*inclusive' => array('=', 'private'),
1806
+							'EVT_wp_user'      => get_current_user_id(),
1807
+						),
1808
+					);
1809
+				}
1810
+			}
1811
+		}
1812
+		if (isset($this->_req_data['EVT_wp_user'])) {
1813
+			if ($this->_req_data['EVT_wp_user'] != get_current_user_id()
1814
+				&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1815
+			) {
1816
+				$where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1817
+			}
1818
+		}
1819
+		//search query handling
1820
+		if (isset($this->_req_data['s'])) {
1821
+			$search_string = '%' . $this->_req_data['s'] . '%';
1822
+			$where['OR'] = array(
1823
+				'EVT_name'       => array('LIKE', $search_string),
1824
+				'EVT_desc'       => array('LIKE', $search_string),
1825
+				'EVT_short_desc' => array('LIKE', $search_string),
1826
+			);
1827
+		}
1828
+		$where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1829
+		$query_params = apply_filters(
1830
+			'FHEE__Events_Admin_Page__get_events__query_params',
1831
+			array(
1832
+				$where,
1833
+				'limit'    => $limit,
1834
+				'order_by' => $orderby,
1835
+				'order'    => $order,
1836
+				'group_by' => 'EVT_ID',
1837
+			),
1838
+			$this->_req_data
1839
+		);
1840
+		//let's first check if we have special requests coming in.
1841
+		if (isset($this->_req_data['active_status'])) {
1842
+			switch ($this->_req_data['active_status']) {
1843
+				case 'upcoming' :
1844
+					return $EEME->get_upcoming_events($query_params, $count);
1845
+					break;
1846
+				case 'expired' :
1847
+					return $EEME->get_expired_events($query_params, $count);
1848
+					break;
1849
+				case 'active' :
1850
+					return $EEME->get_active_events($query_params, $count);
1851
+					break;
1852
+				case 'inactive' :
1853
+					return $EEME->get_inactive_events($query_params, $count);
1854
+					break;
1855
+			}
1856
+		}
1857
+		$events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1858
+		return $events;
1859
+	}
1860
+
1861
+
1862
+
1863
+	/**
1864
+	 * handling for WordPress CPT actions (trash, restore, delete)
1865
+	 *
1866
+	 * @param string $post_id
1867
+	 */
1868
+	public function trash_cpt_item($post_id)
1869
+	{
1870
+		$this->_req_data['EVT_ID'] = $post_id;
1871
+		$this->_trash_or_restore_event('trash', false);
1872
+	}
1873
+
1874
+
1875
+
1876
+	/**
1877
+	 * @param string $post_id
1878
+	 */
1879
+	public function restore_cpt_item($post_id)
1880
+	{
1881
+		$this->_req_data['EVT_ID'] = $post_id;
1882
+		$this->_trash_or_restore_event('draft', false);
1883
+	}
1884
+
1885
+
1886
+
1887
+	/**
1888
+	 * @param string $post_id
1889
+	 */
1890
+	public function delete_cpt_item($post_id)
1891
+	{
1892
+		$this->_req_data['EVT_ID'] = $post_id;
1893
+		$this->_delete_event(false);
1894
+	}
1895
+
1896
+
1897
+
1898
+	/**
1899
+	 * _trash_or_restore_event
1900
+	 *
1901
+	 * @access protected
1902
+	 * @param  string $event_status
1903
+	 * @param bool    $redirect_after
1904
+	 */
1905
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
1906
+	{
1907
+		//determine the event id and set to array.
1908
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
1909
+		// loop thru events
1910
+		if ($EVT_ID) {
1911
+			// clean status
1912
+			$event_status = sanitize_key($event_status);
1913
+			// grab status
1914
+			if ( ! empty($event_status)) {
1915
+				$success = $this->_change_event_status($EVT_ID, $event_status);
1916
+			} else {
1917
+				$success = false;
1918
+				$msg = esc_html__(
1919
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1920
+					'event_espresso'
1921
+				);
1922
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1923
+			}
1924
+		} else {
1925
+			$success = false;
1926
+			$msg = esc_html__(
1927
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
1928
+				'event_espresso'
1929
+			);
1930
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1931
+		}
1932
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1933
+		if ($redirect_after) {
1934
+			$this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
1935
+		}
1936
+	}
1937
+
1938
+
1939
+
1940
+	/**
1941
+	 * _trash_or_restore_events
1942
+	 *
1943
+	 * @access protected
1944
+	 * @param  string $event_status
1945
+	 * @return void
1946
+	 */
1947
+	protected function _trash_or_restore_events($event_status = 'trash')
1948
+	{
1949
+		// clean status
1950
+		$event_status = sanitize_key($event_status);
1951
+		// grab status
1952
+		if ( ! empty($event_status)) {
1953
+			$success = true;
1954
+			//determine the event id and set to array.
1955
+			$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
1956
+			// loop thru events
1957
+			foreach ($EVT_IDs as $EVT_ID) {
1958
+				if ($EVT_ID = absint($EVT_ID)) {
1959
+					$results = $this->_change_event_status($EVT_ID, $event_status);
1960
+					$success = $results !== false ? $success : false;
1961
+				} else {
1962
+					$msg = sprintf(
1963
+						esc_html__(
1964
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
1965
+							'event_espresso'
1966
+						),
1967
+						$EVT_ID
1968
+					);
1969
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1970
+					$success = false;
1971
+				}
1972
+			}
1973
+		} else {
1974
+			$success = false;
1975
+			$msg = esc_html__(
1976
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1977
+				'event_espresso'
1978
+			);
1979
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1980
+		}
1981
+		// in order to force a pluralized result message we need to send back a success status greater than 1
1982
+		$success = $success ? 2 : false;
1983
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1984
+		$this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
1985
+	}
1986
+
1987
+
1988
+
1989
+	/**
1990
+	 * _trash_or_restore_events
1991
+	 *
1992
+	 * @access  private
1993
+	 * @param  int    $EVT_ID
1994
+	 * @param  string $event_status
1995
+	 * @return bool
1996
+	 */
1997
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
1998
+	{
1999
+		// grab event id
2000
+		if ( ! $EVT_ID) {
2001
+			$msg = esc_html__(
2002
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2003
+				'event_espresso'
2004
+			);
2005
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2006
+			return false;
2007
+		}
2008
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2009
+		// clean status
2010
+		$event_status = sanitize_key($event_status);
2011
+		// grab status
2012
+		if (empty($event_status)) {
2013
+			$msg = esc_html__(
2014
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2015
+				'event_espresso'
2016
+			);
2017
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2018
+			return false;
2019
+		}
2020
+		// was event trashed or restored ?
2021
+		switch ($event_status) {
2022
+			case 'draft' :
2023
+				$action = 'restored from the trash';
2024
+				$hook = 'AHEE_event_restored_from_trash';
2025
+				break;
2026
+			case 'trash' :
2027
+				$action = 'moved to the trash';
2028
+				$hook = 'AHEE_event_moved_to_trash';
2029
+				break;
2030
+			default :
2031
+				$action = 'updated';
2032
+				$hook = false;
2033
+		}
2034
+		//use class to change status
2035
+		$this->_cpt_model_obj->set_status($event_status);
2036
+		$success = $this->_cpt_model_obj->save();
2037
+		if ($success === false) {
2038
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2039
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2040
+			return false;
2041
+		}
2042
+		if ($hook) {
2043
+			do_action($hook);
2044
+		}
2045
+		return true;
2046
+	}
2047
+
2048
+
2049
+
2050
+	/**
2051
+	 * _delete_event
2052
+	 *
2053
+	 * @access protected
2054
+	 * @param bool $redirect_after
2055
+	 */
2056
+	protected function _delete_event($redirect_after = true)
2057
+	{
2058
+		//determine the event id and set to array.
2059
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2060
+		$EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2061
+		// loop thru events
2062
+		if ($EVT_ID) {
2063
+			$success = $this->_permanently_delete_event($EVT_ID);
2064
+			// get list of events with no prices
2065
+			$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2066
+			// remove this event from the list of events with no prices
2067
+			if (isset($espresso_no_ticket_prices[$EVT_ID])) {
2068
+				unset($espresso_no_ticket_prices[$EVT_ID]);
2069
+			}
2070
+			update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2071
+		} else {
2072
+			$success = false;
2073
+			$msg = esc_html__(
2074
+				'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2075
+				'event_espresso'
2076
+			);
2077
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2078
+		}
2079
+		if ($redirect_after) {
2080
+			$this->_redirect_after_action(
2081
+				$success,
2082
+				'Event',
2083
+				'deleted',
2084
+				array('action' => 'default', 'status' => 'trash')
2085
+			);
2086
+		}
2087
+	}
2088
+
2089
+
2090
+
2091
+	/**
2092
+	 * _delete_events
2093
+	 *
2094
+	 * @access protected
2095
+	 * @return void
2096
+	 */
2097
+	protected function _delete_events()
2098
+	{
2099
+		$success = true;
2100
+		// get list of events with no prices
2101
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2102
+		//determine the event id and set to array.
2103
+		$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array)$this->_req_data['EVT_IDs'] : array();
2104
+		// loop thru events
2105
+		foreach ($EVT_IDs as $EVT_ID) {
2106
+			$EVT_ID = absint($EVT_ID);
2107
+			if ($EVT_ID) {
2108
+				$results = $this->_permanently_delete_event($EVT_ID);
2109
+				$success = $results !== false ? $success : false;
2110
+				// remove this event from the list of events with no prices
2111
+				unset($espresso_no_ticket_prices[$EVT_ID]);
2112
+			} else {
2113
+				$success = false;
2114
+				$msg = esc_html__(
2115
+					'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2116
+					'event_espresso'
2117
+				);
2118
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2119
+			}
2120
+		}
2121
+		update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2122
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2123
+		$success = $success ? 2 : false;
2124
+		$this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2125
+	}
2126
+
2127
+
2128
+
2129
+	/**
2130
+	 * _permanently_delete_event
2131
+	 *
2132
+	 * @access  private
2133
+	 * @param  int $EVT_ID
2134
+	 * @return bool
2135
+	 */
2136
+	private function _permanently_delete_event($EVT_ID = 0)
2137
+	{
2138
+		// grab event id
2139
+		if ( ! $EVT_ID) {
2140
+			$msg = esc_html__(
2141
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2142
+				'event_espresso'
2143
+			);
2144
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2145
+			return false;
2146
+		}
2147
+		if (
2148
+			! $this->_cpt_model_obj instanceof EE_Event
2149
+			|| $this->_cpt_model_obj->ID() !== $EVT_ID
2150
+		) {
2151
+			$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2152
+		}
2153
+		if ( ! $this->_cpt_model_obj instanceof EE_Event) {
2154
+			return false;
2155
+		}
2156
+		//need to delete related tickets and prices first.
2157
+		$datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2158
+		foreach ($datetimes as $datetime) {
2159
+			$this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2160
+			$tickets = $datetime->get_many_related('Ticket');
2161
+			foreach ($tickets as $ticket) {
2162
+				$ticket->_remove_relation_to($datetime, 'Datetime');
2163
+				$ticket->delete_related_permanently('Price');
2164
+				$ticket->delete_permanently();
2165
+			}
2166
+			$datetime->delete();
2167
+		}
2168
+		//what about related venues or terms?
2169
+		$venues = $this->_cpt_model_obj->get_many_related('Venue');
2170
+		foreach ($venues as $venue) {
2171
+			$this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2172
+		}
2173
+		//any attached question groups?
2174
+		$question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2175
+		if ( ! empty($question_groups)) {
2176
+			foreach ($question_groups as $question_group) {
2177
+				$this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2178
+			}
2179
+		}
2180
+		//Message Template Groups
2181
+		$this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2182
+		/** @type EE_Term_Taxonomy[] $term_taxonomies */
2183
+		$term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2184
+		foreach ($term_taxonomies as $term_taxonomy) {
2185
+			$this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2186
+		}
2187
+		$success = $this->_cpt_model_obj->delete_permanently();
2188
+		// did it all go as planned ?
2189
+		if ($success) {
2190
+			$msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2191
+			EE_Error::add_success($msg);
2192
+		} else {
2193
+			$msg = sprintf(
2194
+				esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2195
+				$EVT_ID
2196
+			);
2197
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2198
+			return false;
2199
+		}
2200
+		do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2201
+		return true;
2202
+	}
2203
+
2204
+
2205
+
2206
+	/**
2207
+	 * get total number of events
2208
+	 *
2209
+	 * @access public
2210
+	 * @return int
2211
+	 */
2212
+	public function total_events()
2213
+	{
2214
+		$count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2215
+		return $count;
2216
+	}
2217
+
2218
+
2219
+
2220
+	/**
2221
+	 * get total number of draft events
2222
+	 *
2223
+	 * @access public
2224
+	 * @return int
2225
+	 */
2226
+	public function total_events_draft()
2227
+	{
2228
+		$where = array(
2229
+			'status' => array('IN', array('draft', 'auto-draft')),
2230
+		);
2231
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2232
+		return $count;
2233
+	}
2234
+
2235
+
2236
+
2237
+	/**
2238
+	 * get total number of trashed events
2239
+	 *
2240
+	 * @access public
2241
+	 * @return int
2242
+	 */
2243
+	public function total_trashed_events()
2244
+	{
2245
+		$where = array(
2246
+			'status' => 'trash',
2247
+		);
2248
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2249
+		return $count;
2250
+	}
2251
+
2252
+
2253
+
2254
+	/**
2255
+	 *    _default_event_settings
2256
+	 *    This generates the Default Settings Tab
2257
+	 *
2258
+	 * @return void
2259
+	 */
2260
+	protected function _default_event_settings()
2261
+	{
2262
+		$this->_template_args['values'] = $this->_yes_no_values;
2263
+		$this->_template_args['reg_status_array'] = EEM_Registration::reg_status_array(
2264
+		// exclude array
2265
+			array(
2266
+				EEM_Registration::status_id_cancelled,
2267
+				EEM_Registration::status_id_declined,
2268
+				EEM_Registration::status_id_incomplete,
2269
+				EEM_Registration::status_id_wait_list,
2270
+			),
2271
+			// translated
2272
+			true
2273
+		);
2274
+		$this->_template_args['default_reg_status'] = isset(
2275
+														  EE_Registry::instance()->CFG->registration->default_STS_ID
2276
+													  )
2277
+													  && array_key_exists(
2278
+														  EE_Registry::instance()->CFG->registration->default_STS_ID,
2279
+														  $this->_template_args['reg_status_array']
2280
+													  )
2281
+			? sanitize_text_field(EE_Registry::instance()->CFG->registration->default_STS_ID)
2282
+			: EEM_Registration::status_id_pending_payment;
2283
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2284
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2285
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2286
+			EVENTS_TEMPLATE_PATH . 'event_settings.template.php',
2287
+			$this->_template_args,
2288
+			true
2289
+		);
2290
+		$this->display_admin_page_with_sidebar();
2291
+	}
2292
+
2293
+
2294
+
2295
+	/**
2296
+	 * _update_default_event_settings
2297
+	 *
2298
+	 * @access protected
2299
+	 * @return void
2300
+	 */
2301
+	protected function _update_default_event_settings()
2302
+	{
2303
+		EE_Config::instance()->registration->default_STS_ID = isset($this->_req_data['default_reg_status'])
2304
+			? sanitize_text_field($this->_req_data['default_reg_status'])
2305
+			: EEM_Registration::status_id_pending_payment;
2306
+		$what = 'Default Event Settings';
2307
+		$success = $this->_update_espresso_configuration(
2308
+			$what,
2309
+			EE_Config::instance(),
2310
+			__FILE__,
2311
+			__FUNCTION__,
2312
+			__LINE__
2313
+		);
2314
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'default_event_settings'));
2315
+	}
2316
+
2317
+
2318
+
2319
+	/*************        Templates        *************/
2320
+	protected function _template_settings()
2321
+	{
2322
+		$this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2323
+		$this->_template_args['preview_img'] = '<img src="'
2324
+											   . EVENTS_ASSETS_URL
2325
+											   . DS
2326
+											   . 'images'
2327
+											   . DS
2328
+											   . 'caffeinated_template_features.jpg" alt="'
2329
+											   . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2330
+											   . '" />';
2331
+		$this->_template_args['preview_text'] = '<strong>' . esc_html__(
2332
+				'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.',
2333
+				'event_espresso'
2334
+			) . '</strong>';
2335
+		$this->display_admin_caf_preview_page('template_settings_tab');
2336
+	}
2337
+
2338
+
2339
+	/** Event Category Stuff **/
2340
+	/**
2341
+	 * set the _category property with the category object for the loaded page.
2342
+	 *
2343
+	 * @access private
2344
+	 * @return void
2345
+	 */
2346
+	private function _set_category_object()
2347
+	{
2348
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2349
+			return;
2350
+		} //already have the category object so get out.
2351
+		//set default category object
2352
+		$this->_set_empty_category_object();
2353
+		//only set if we've got an id
2354
+		if ( ! isset($this->_req_data['EVT_CAT_ID'])) {
2355
+			return;
2356
+		}
2357
+		$category_id = absint($this->_req_data['EVT_CAT_ID']);
2358
+		$term = get_term($category_id, 'espresso_event_categories');
2359
+		if ( ! empty($term)) {
2360
+			$this->_category->category_name = $term->name;
2361
+			$this->_category->category_identifier = $term->slug;
2362
+			$this->_category->category_desc = $term->description;
2363
+			$this->_category->id = $term->term_id;
2364
+			$this->_category->parent = $term->parent;
2365
+		}
2366
+	}
2367
+
2368
+
2369
+
2370
+	private function _set_empty_category_object()
2371
+	{
2372
+		$this->_category = new stdClass();
2373
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2374
+		$this->_category->id = $this->_category->parent = 0;
2375
+	}
2376
+
2377
+
2378
+
2379
+	protected function _category_list_table()
2380
+	{
2381
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2382
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2383
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2384
+				'add_category',
2385
+				'add_category',
2386
+				array(),
2387
+				'add-new-h2'
2388
+			);
2389
+		$this->display_admin_list_table_page_with_sidebar();
2390
+	}
2391
+
2392
+
2393
+
2394
+	/**
2395
+	 * @param $view
2396
+	 */
2397
+	protected function _category_details($view)
2398
+	{
2399
+		//load formatter helper
2400
+		//load field generator helper
2401
+		$route = $view == 'edit' ? 'update_category' : 'insert_category';
2402
+		$this->_set_add_edit_form_tags($route);
2403
+		$this->_set_category_object();
2404
+		$id = ! empty($this->_category->id) ? $this->_category->id : '';
2405
+		$delete_action = 'delete_category';
2406
+		//custom redirect
2407
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2408
+			array('action' => 'category_list'),
2409
+			$this->_admin_base_url
2410
+		);
2411
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2412
+		//take care of contents
2413
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2414
+		$this->display_admin_page_with_sidebar();
2415
+	}
2416
+
2417
+
2418
+
2419
+	/**
2420
+	 * @return mixed
2421
+	 */
2422
+	protected function _category_details_content()
2423
+	{
2424
+		$editor_args['category_desc'] = array(
2425
+			'type'          => 'wp_editor',
2426
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2427
+			'class'         => 'my_editor_custom',
2428
+			'wpeditor_args' => array('media_buttons' => false),
2429
+		);
2430
+		$_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2431
+		$all_terms = get_terms(
2432
+			array('espresso_event_categories'),
2433
+			array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2434
+		);
2435
+		//setup category select for term parents.
2436
+		$category_select_values[] = array(
2437
+			'text' => esc_html__('No Parent', 'event_espresso'),
2438
+			'id'   => 0,
2439
+		);
2440
+		foreach ($all_terms as $term) {
2441
+			$category_select_values[] = array(
2442
+				'text' => $term->name,
2443
+				'id'   => $term->term_id,
2444
+			);
2445
+		}
2446
+		$category_select = EEH_Form_Fields::select_input(
2447
+			'category_parent',
2448
+			$category_select_values,
2449
+			$this->_category->parent
2450
+		);
2451
+		$template_args = array(
2452
+			'category'                 => $this->_category,
2453
+			'category_select'          => $category_select,
2454
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2455
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2456
+			'disable'                  => '',
2457
+			'disabled_message'         => false,
2458
+		);
2459
+		$template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2460
+		return EEH_Template::display_template($template, $template_args, true);
2461
+	}
2462
+
2463
+
2464
+
2465
+	protected function _delete_categories()
2466
+	{
2467
+		$cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array)$this->_req_data['EVT_CAT_ID']
2468
+			: (array)$this->_req_data['category_id'];
2469
+		foreach ($cat_ids as $cat_id) {
2470
+			$this->_delete_category($cat_id);
2471
+		}
2472
+		//doesn't matter what page we're coming from... we're going to the same place after delete.
2473
+		$query_args = array(
2474
+			'action' => 'category_list',
2475
+		);
2476
+		$this->_redirect_after_action(0, '', '', $query_args);
2477
+	}
2478
+
2479
+
2480
+
2481
+	/**
2482
+	 * @param $cat_id
2483
+	 */
2484
+	protected function _delete_category($cat_id)
2485
+	{
2486
+		$cat_id = absint($cat_id);
2487
+		wp_delete_term($cat_id, 'espresso_event_categories');
2488
+	}
2489
+
2490
+
2491
+
2492
+	/**
2493
+	 * @param $new_category
2494
+	 */
2495
+	protected function _insert_or_update_category($new_category)
2496
+	{
2497
+		$cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2498
+		$success = 0; //we already have a success message so lets not send another.
2499
+		if ($cat_id) {
2500
+			$query_args = array(
2501
+				'action'     => 'edit_category',
2502
+				'EVT_CAT_ID' => $cat_id,
2503
+			);
2504
+		} else {
2505
+			$query_args = array('action' => 'add_category');
2506
+		}
2507
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2508
+	}
2509
+
2510
+
2511
+
2512
+	/**
2513
+	 * @param bool $update
2514
+	 * @return bool|mixed|string
2515
+	 */
2516
+	private function _insert_category($update = false)
2517
+	{
2518
+		$cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2519
+		$category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2520
+		$category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2521
+		$category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2522
+		if (empty($category_name)) {
2523
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2524
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2525
+			return false;
2526
+		}
2527
+		$term_args = array(
2528
+			'name'        => $category_name,
2529
+			'description' => $category_desc,
2530
+			'parent'      => $category_parent,
2531
+		);
2532
+		//was the category_identifier input disabled?
2533
+		if (isset($this->_req_data['category_identifier'])) {
2534
+			$term_args['slug'] = $this->_req_data['category_identifier'];
2535
+		}
2536
+		$insert_ids = $update
2537
+			? wp_update_term($cat_id, 'espresso_event_categories', $term_args)
2538
+			: wp_insert_term($category_name, 'espresso_event_categories', $term_args);
2539
+		if ( ! is_array($insert_ids)) {
2540
+			$msg = esc_html__(
2541
+				'An error occurred and the category has not been saved to the database.',
2542
+				'event_espresso'
2543
+			);
2544
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2545
+		} else {
2546
+			$cat_id = $insert_ids['term_id'];
2547
+			$msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2548
+			EE_Error::add_success($msg);
2549
+		}
2550
+		return $cat_id;
2551
+	}
2552
+
2553
+
2554
+
2555
+	/**
2556
+	 * @param int  $per_page
2557
+	 * @param int  $current_page
2558
+	 * @param bool $count
2559
+	 * @return \EE_Base_Class[]|int
2560
+	 */
2561
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2562
+	{
2563
+		//testing term stuff
2564
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2565
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2566
+		$limit = ($current_page - 1) * $per_page;
2567
+		$where = array('taxonomy' => 'espresso_event_categories');
2568
+		if (isset($this->_req_data['s'])) {
2569
+			$sstr = '%' . $this->_req_data['s'] . '%';
2570
+			$where['OR'] = array(
2571
+				'Term.name'   => array('LIKE', $sstr),
2572
+				'description' => array('LIKE', $sstr),
2573
+			);
2574
+		}
2575
+		$query_params = array(
2576
+			$where,
2577
+			'order_by'   => array($orderby => $order),
2578
+			'limit'      => $limit . ',' . $per_page,
2579
+			'force_join' => array('Term'),
2580
+		);
2581
+		$categories = $count
2582
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2583
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2584
+		return $categories;
2585
+	}
2586
+
2587
+
2588
+
2589
+	/* end category stuff */
2590
+	/**************/
2591 2591
 }
2592 2592
 //end class Events_Admin_Page
Please login to merge, or discard this patch.
modules/single_page_checkout/EED_Single_Page_Checkout.module.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -781,7 +781,7 @@  discard block
 block discarded – undo
781 781
      * _get_transaction_and_cart_for_previous_visit
782 782
      *
783 783
      * @access private
784
-     * @return mixed EE_Transaction|NULL
784
+     * @return EE_Transaction|null EE_Transaction|NULL
785 785
      */
786 786
     private function _get_transaction_and_cart_for_previous_visit()
787 787
     {
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
      *    generates a new EE_Transaction object and adds it to the $_transaction property.
864 864
      *
865 865
      * @access private
866
-     * @return mixed EE_Transaction|NULL
866
+     * @return EE_Transaction|null EE_Transaction|NULL
867 867
      */
868 868
     private function _initialize_transaction()
869 869
     {
Please login to merge, or discard this patch.
Indentation   +1704 added lines, -1704 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,1709 +17,1709 @@  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
-            // hook into the top of pre_get_posts to set the reg step routing, which gives other modules or plugins a chance to modify the reg steps, but just before the routes get called
112
-            add_action('pre_get_posts', array('EED_Single_Page_Checkout', 'load_reg_steps'), 1);
113
-            return;
114
-        }
115
-        // going to start an output buffer in case anything gets accidentally output that might disrupt our JSON response
116
-        ob_start();
117
-        EED_Single_Page_Checkout::load_request_handler();
118
-        EED_Single_Page_Checkout::load_reg_steps();
119
-        // set ajax hooks
120
-        add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
121
-        add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
122
-        add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
123
-        add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
124
-        add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
125
-        add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
126
-    }
127
-
128
-
129
-
130
-    /**
131
-     *    process ajax request
132
-     *
133
-     * @param string $ajax_action
134
-     * @throws \EE_Error
135
-     */
136
-    public static function process_ajax_request($ajax_action)
137
-    {
138
-        EE_Registry::instance()->REQ->set('action', $ajax_action);
139
-        EED_Single_Page_Checkout::instance()->_initialize();
140
-    }
141
-
142
-
143
-
144
-    /**
145
-     *    ajax display registration step
146
-     *
147
-     * @throws \EE_Error
148
-     */
149
-    public static function display_reg_step()
150
-    {
151
-        EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
152
-    }
153
-
154
-
155
-
156
-    /**
157
-     *    ajax process registration step
158
-     *
159
-     * @throws \EE_Error
160
-     */
161
-    public static function process_reg_step()
162
-    {
163
-        EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
164
-    }
165
-
166
-
167
-
168
-    /**
169
-     *    ajax process registration step
170
-     *
171
-     * @throws \EE_Error
172
-     */
173
-    public static function update_reg_step()
174
-    {
175
-        EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
176
-    }
177
-
178
-
179
-
180
-    /**
181
-     *   update_checkout
182
-     *
183
-     * @access public
184
-     * @return void
185
-     * @throws \EE_Error
186
-     */
187
-    public static function update_checkout()
188
-    {
189
-        EED_Single_Page_Checkout::process_ajax_request('update_checkout');
190
-    }
191
-
192
-
193
-
194
-    /**
195
-     *    load_request_handler
196
-     *
197
-     * @access    public
198
-     * @return    void
199
-     */
200
-    public static function load_request_handler()
201
-    {
202
-        // load core Request_Handler class
203
-        if ( ! isset(EE_Registry::instance()->REQ)) {
204
-            EE_Registry::instance()->load_core('Request_Handler');
205
-        }
206
-    }
207
-
208
-
209
-
210
-    /**
211
-     *    set_definitions
212
-     *
213
-     * @access    public
214
-     * @return    void
215
-     * @throws \EE_Error
216
-     */
217
-    public static function set_definitions()
218
-    {
219
-        define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS);
220
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
221
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
222
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
223
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
224
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
225
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
226
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
227
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
228
-            __('%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',
229
-                'event_espresso'),
230
-            '<h4 class="important-notice">',
231
-            '</h4>',
232
-            '<br />',
233
-            '<p>',
234
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
235
-            '">',
236
-            '</a>',
237
-            '</p>'
238
-        );
239
-    }
240
-
241
-
242
-
243
-    /**
244
-     * load_reg_steps
245
-     * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
246
-     *
247
-     * @access    private
248
-     * @throws EE_Error
249
-     * @return void
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_reg_steps();
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_reg_steps();
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_flip($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
-     *    run
438
-     *
439
-     * @access    public
440
-     * @param WP_Query $WP_Query
441
-     * @return    void
442
-     * @throws \EE_Error
443
-     */
444
-    public static function init($WP_Query)
445
-    {
446
-        EED_Single_Page_Checkout::instance()->run($WP_Query);
447
-    }
448
-
449
-
450
-
451
-    /**
452
-     *    _initialize - initial module setup
453
-     *
454
-     * @access    private
455
-     * @throws EE_Error
456
-     * @return    void
457
-     */
458
-    private function _initialize()
459
-    {
460
-        // ensure SPCO doesn't run twice
461
-        if (EED_Single_Page_Checkout::$_initialized) {
462
-            return;
463
-        }
464
-        try {
465
-            $this->_verify_session();
466
-            // setup the EE_Checkout object
467
-            $this->checkout = $this->_initialize_checkout();
468
-            // filter checkout
469
-            $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
470
-            // get the $_GET
471
-            $this->_get_request_vars();
472
-            if ($this->_block_bots()) {
473
-                return;
474
-            }
475
-            // filter continue_reg
476
-            $this->checkout->continue_reg = apply_filters('FHEE__EED_Single_Page_Checkout__init___continue_reg', true, $this->checkout);
477
-            // load the reg steps array
478
-            if ( ! $this->_load_and_instantiate_reg_steps()) {
479
-                EED_Single_Page_Checkout::$_initialized = true;
480
-                return;
481
-            }
482
-            // set the current step
483
-            $this->checkout->set_current_step($this->checkout->step);
484
-            // and the next step
485
-            $this->checkout->set_next_step();
486
-            // verify that everything has been setup correctly
487
-            if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
488
-                EED_Single_Page_Checkout::$_initialized = true;
489
-                return;
490
-            }
491
-            // lock the transaction
492
-            $this->checkout->transaction->lock();
493
-            // make sure all of our cached objects are added to their respective model entity mappers
494
-            $this->checkout->refresh_all_entities();
495
-            // set amount owing
496
-            $this->checkout->amount_owing = $this->checkout->transaction->remaining();
497
-            // initialize each reg step, which gives them the chance to potentially alter the process
498
-            $this->_initialize_reg_steps();
499
-            // DEBUG LOG
500
-            //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
501
-            // get reg form
502
-            if( ! $this->_check_form_submission()) {
503
-                EED_Single_Page_Checkout::$_initialized = true;
504
-                return;
505
-            }
506
-            // checkout the action!!!
507
-            $this->_process_form_action();
508
-            // add some style and make it dance
509
-            $this->add_styles_and_scripts();
510
-            // kk... SPCO has successfully run
511
-            EED_Single_Page_Checkout::$_initialized = true;
512
-            // set no cache headers and constants
513
-            EE_System::do_not_cache();
514
-            // add anchor
515
-            add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
516
-            // remove transaction lock
517
-            add_action('shutdown', array($this, 'unlock_transaction'), 1);
518
-        } catch (Exception $e) {
519
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
520
-        }
521
-    }
522
-
523
-
524
-
525
-    /**
526
-     *    _verify_session
527
-     * checks that the session is valid and not expired
528
-     *
529
-     * @access    private
530
-     * @throws EE_Error
531
-     */
532
-    private function _verify_session()
533
-    {
534
-        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
535
-            throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
536
-        }
537
-        // is session still valid ?
538
-        if (EE_Registry::instance()->SSN->expired() && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '') {
539
-            $this->checkout = new EE_Checkout();
540
-            EE_Registry::instance()->SSN->reset_cart();
541
-            EE_Registry::instance()->SSN->reset_checkout();
542
-            EE_Registry::instance()->SSN->reset_transaction();
543
-            EE_Error::add_attention(EE_Registry::$i18n_js_strings['registration_expiration_notice'], __FILE__,
544
-                __FUNCTION__, __LINE__);
545
-            EE_Registry::instance()->SSN->reset_expired();
546
-        }
547
-    }
548
-
549
-
550
-
551
-    /**
552
-     *    _initialize_checkout
553
-     * loads and instantiates EE_Checkout
554
-     *
555
-     * @access    private
556
-     * @throws EE_Error
557
-     * @return EE_Checkout
558
-     */
559
-    private function _initialize_checkout()
560
-    {
561
-        // look in session for existing checkout
562
-        /** @type EE_Checkout $checkout */
563
-        $checkout = EE_Registry::instance()->SSN->checkout();
564
-        // verify
565
-        if ( ! $checkout instanceof EE_Checkout) {
566
-            // instantiate EE_Checkout object for handling the properties of the current checkout process
567
-            $checkout = EE_Registry::instance()->load_file(SPCO_INC_PATH, 'EE_Checkout', 'class', array(), false);
568
-        } else {
569
-            if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
570
-                $this->unlock_transaction();
571
-                wp_safe_redirect($checkout->redirect_url);
572
-                exit();
573
-            }
574
-        }
575
-        $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
576
-        // verify again
577
-        if ( ! $checkout instanceof EE_Checkout) {
578
-            throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
579
-        }
580
-        // reset anything that needs a clean slate for each request
581
-        $checkout->reset_for_current_request();
582
-        return $checkout;
583
-    }
584
-
585
-
586
-
587
-    /**
588
-     *    _get_request_vars
589
-     *
590
-     * @access    private
591
-     * @return    void
592
-     * @throws \EE_Error
593
-     */
594
-    private function _get_request_vars()
595
-    {
596
-        // load classes
597
-        EED_Single_Page_Checkout::load_request_handler();
598
-        //make sure this request is marked as belonging to EE
599
-        EE_Registry::instance()->REQ->set_espresso_page(true);
600
-        // which step is being requested ?
601
-        $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
602
-        // which step is being edited ?
603
-        $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
604
-        // and what we're doing on the current step
605
-        $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
606
-        // timestamp
607
-        $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
608
-        // returning to edit ?
609
-        $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
610
-        // or some other kind of revisit ?
611
-        $this->checkout->revisit = filter_var(
612
-            EE_Registry::instance()->REQ->get('revisit', false),
613
-            FILTER_VALIDATE_BOOLEAN
614
-        );
615
-        // and whether or not to generate a reg form for this request
616
-        $this->checkout->generate_reg_form = filter_var(
617
-            EE_Registry::instance()->REQ->get('generate_reg_form', true),
618
-            FILTER_VALIDATE_BOOLEAN
619
-        );
620
-        // and whether or not to process a reg form submission for this request
621
-        $this->checkout->process_form_submission = filter_var(
622
-            EE_Registry::instance()->REQ->get(
623
-                'process_form_submission',
624
-                $this->checkout->action === 'process_reg_step'
625
-            ),
626
-            FILTER_VALIDATE_BOOLEAN
627
-        );
628
-        $this->checkout->process_form_submission = filter_var(
629
-            $this->checkout->action !== 'display_spco_reg_step'
630
-                ? $this->checkout->process_form_submission
631
-                : false,
632
-            FILTER_VALIDATE_BOOLEAN
633
-        );
634
-        // $this->_display_request_vars();
635
-    }
636
-
637
-
638
-
639
-    /**
640
-     *  _display_request_vars
641
-     *
642
-     * @access    protected
643
-     * @return    void
644
-     */
645
-    protected function _display_request_vars()
646
-    {
647
-        if ( ! WP_DEBUG) {
648
-            return;
649
-        }
650
-        EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
651
-        EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
652
-        EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
653
-        EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
654
-        EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
655
-        EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
656
-        EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
657
-        EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
658
-    }
659
-
660
-
661
-
662
-    /**
663
-     * _block_bots
664
-     * checks that the incoming request has either of the following set:
665
-     *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
666
-     *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
667
-     * so if you're not coming from the Ticket Selector nor returning for a valid IP...
668
-     * then where you coming from man?
669
-     *
670
-     * @return boolean
671
-     */
672
-    private function _block_bots()
673
-    {
674
-        $invalid_checkout_access = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
675
-        if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
676
-            return true;
677
-        }
678
-        return false;
679
-    }
680
-
681
-
682
-
683
-    /**
684
-     *    _get_first_step
685
-     *  gets slug for first step in $_reg_steps_array
686
-     *
687
-     * @access    private
688
-     * @throws EE_Error
689
-     * @return    string
690
-     */
691
-    private function _get_first_step()
692
-    {
693
-        $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
694
-        return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
695
-    }
696
-
697
-
698
-
699
-    /**
700
-     *    _load_and_instantiate_reg_steps
701
-     *  instantiates each reg step based on the loaded reg_steps array
702
-     *
703
-     * @access    private
704
-     * @throws EE_Error
705
-     * @return    bool
706
-     */
707
-    private function _load_and_instantiate_reg_steps()
708
-    {
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
-            ) {
775
-                return true;
776
-            }
777
-            // instantiate step class using file path and class name
778
-            $reg_step_obj = EE_Registry::instance()->load_file(
779
-                $reg_step['file_path'],
780
-                $reg_step['class_name'],
781
-                'class',
782
-                $this->checkout,
783
-                false
784
-            );
785
-            // did we gets the goods ?
786
-            if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
787
-                // set reg step order based on config
788
-                $reg_step_obj->set_order($order);
789
-                // add instantiated reg step object to the master reg steps array
790
-                $this->checkout->add_reg_step($reg_step_obj);
791
-            } else {
792
-                EE_Error::add_error(
793
-                    __('The current step could not be set.', 'event_espresso'),
794
-                    __FILE__, __FUNCTION__, __LINE__
795
-                );
796
-                return false;
797
-            }
798
-        } else {
799
-            if (WP_DEBUG) {
800
-                EE_Error::add_error(
801
-                    sprintf(
802
-                        __('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'),
803
-                        isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
804
-                        isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
805
-                        isset($reg_step['slug']) ? $reg_step['slug'] : '',
806
-                        '<ul>',
807
-                        '<li>',
808
-                        '</li>',
809
-                        '</ul>'
810
-                    ),
811
-                    __FILE__, __FUNCTION__, __LINE__
812
-                );
813
-            }
814
-            return false;
815
-        }
816
-        return true;
817
-    }
818
-
819
-
820
-
821
-    /**
822
-     * _verify_transaction_and_get_registrations
823
-     *
824
-     * @access private
825
-     * @return bool
826
-     */
827
-    private function _verify_transaction_and_get_registrations()
828
-    {
829
-        // was there already a valid transaction in the checkout from the session ?
830
-        if ( ! $this->checkout->transaction instanceof EE_Transaction) {
831
-            // get transaction from db or session
832
-            $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
833
-                ? $this->_get_transaction_and_cart_for_previous_visit()
834
-                : $this->_get_cart_for_current_session_and_setup_new_transaction();
835
-            if ( ! $this->checkout->transaction instanceof EE_Transaction) {
836
-                EE_Error::add_error(
837
-                    __('Your Registration and Transaction information could not be retrieved from the db.',
838
-                        'event_espresso'),
839
-                    __FILE__, __FUNCTION__, __LINE__
840
-                );
841
-                $this->checkout->transaction = EE_Transaction::new_instance();
842
-                // add some style and make it dance
843
-                $this->add_styles_and_scripts();
844
-                EED_Single_Page_Checkout::$_initialized = true;
845
-                return false;
846
-            }
847
-            // and the registrations for the transaction
848
-            $this->_get_registrations($this->checkout->transaction);
849
-        }
850
-        return true;
851
-    }
852
-
853
-
854
-
855
-    /**
856
-     * _get_transaction_and_cart_for_previous_visit
857
-     *
858
-     * @access private
859
-     * @return mixed EE_Transaction|NULL
860
-     */
861
-    private function _get_transaction_and_cart_for_previous_visit()
862
-    {
863
-        /** @var $TXN_model EEM_Transaction */
864
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
865
-        // 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
866
-        $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
867
-        // verify transaction
868
-        if ($transaction instanceof EE_Transaction) {
869
-            // and get the cart that was used for that transaction
870
-            $this->checkout->cart = $this->_get_cart_for_transaction($transaction);
871
-            return $transaction;
872
-        } else {
873
-            EE_Error::add_error(__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
874
-            return null;
875
-        }
876
-    }
877
-
878
-
879
-
880
-    /**
881
-     * _get_cart_for_transaction
882
-     *
883
-     * @access private
884
-     * @param EE_Transaction $transaction
885
-     * @return EE_Cart
886
-     */
887
-    private function _get_cart_for_transaction($transaction)
888
-    {
889
-        return $this->checkout->get_cart_for_transaction($transaction);
890
-    }
891
-
892
-
893
-
894
-    /**
895
-     * get_cart_for_transaction
896
-     *
897
-     * @access public
898
-     * @param EE_Transaction $transaction
899
-     * @return EE_Cart
900
-     */
901
-    public function get_cart_for_transaction(EE_Transaction $transaction)
902
-    {
903
-        return $this->checkout->get_cart_for_transaction($transaction);
904
-    }
905
-
906
-
907
-
908
-    /**
909
-     * _get_transaction_and_cart_for_current_session
910
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
911
-     *
912
-     * @access private
913
-     * @return EE_Transaction
914
-     * @throws \EE_Error
915
-     */
916
-    private function _get_cart_for_current_session_and_setup_new_transaction()
917
-    {
918
-        //  if there's no transaction, then this is the FIRST visit to SPCO
919
-        // so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
920
-        $this->checkout->cart = $this->_get_cart_for_transaction(null);
921
-        // and then create a new transaction
922
-        $transaction = $this->_initialize_transaction();
923
-        // verify transaction
924
-        if ($transaction instanceof EE_Transaction) {
925
-            // save it so that we have an ID for other objects to use
926
-            $transaction->save();
927
-            // and save TXN data to the cart
928
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
929
-        } else {
930
-            EE_Error::add_error(__('A Valid Transaction could not be initialized.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
931
-        }
932
-        return $transaction;
933
-    }
934
-
935
-
936
-
937
-    /**
938
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
939
-     *
940
-     * @access private
941
-     * @return mixed EE_Transaction|NULL
942
-     */
943
-    private function _initialize_transaction()
944
-    {
945
-        try {
946
-            // ensure cart totals have been calculated
947
-            $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
948
-            // grab the cart grand total
949
-            $cart_total = $this->checkout->cart->get_cart_grand_total();
950
-            // create new TXN
951
-            $transaction = EE_Transaction::new_instance(
952
-                array(
953
-                    'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
954
-                    'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
955
-                    'TXN_paid'      => 0,
956
-                    'STS_ID'        => EEM_Transaction::failed_status_code,
957
-                )
958
-            );
959
-            // save it so that we have an ID for other objects to use
960
-            $transaction->save();
961
-            // set cron job for following up on TXNs after their session has expired
962
-            EE_Cron_Tasks::schedule_expired_transaction_check(
963
-                EE_Registry::instance()->SSN->expiration() + 1,
964
-                $transaction->ID()
965
-            );
966
-            return $transaction;
967
-        } catch (Exception $e) {
968
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
969
-        }
970
-        return null;
971
-    }
972
-
973
-
974
-
975
-    /**
976
-     * _get_registrations
977
-     *
978
-     * @access private
979
-     * @param EE_Transaction $transaction
980
-     * @return void
981
-     * @throws \EventEspresso\core\exceptions\InvalidEntityException
982
-     * @throws \EE_Error
983
-     */
984
-    private function _get_registrations(EE_Transaction $transaction)
985
-    {
986
-        // first step: grab the registrants  { : o
987
-        $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
988
-        // verify registrations have been set
989
-        if (empty($registrations)) {
990
-            // if no cached registrations, then check the db
991
-            $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
992
-            // still nothing ? well as long as this isn't a revisit
993
-            if (empty($registrations) && ! $this->checkout->revisit) {
994
-                // generate new registrations from scratch
995
-                $registrations = $this->_initialize_registrations($transaction);
996
-            }
997
-        }
998
-        // sort by their original registration order
999
-        usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1000
-        // then loop thru the array
1001
-        foreach ($registrations as $registration) {
1002
-            // verify each registration
1003
-            if ($registration instanceof EE_Registration) {
1004
-                // we display all attendee info for the primary registrant
1005
-                if ($this->checkout->reg_url_link === $registration->reg_url_link()
1006
-                    && $registration->is_primary_registrant()
1007
-                ) {
1008
-                    $this->checkout->primary_revisit = true;
1009
-                    break;
1010
-                } else if ($this->checkout->revisit
1011
-                           && $this->checkout->reg_url_link !== $registration->reg_url_link()
1012
-                ) {
1013
-                    // but hide info if it doesn't belong to you
1014
-                    $transaction->clear_cache('Registration', $registration->ID());
1015
-                }
1016
-                $this->checkout->set_reg_status_updated($registration->ID(), false);
1017
-            }
1018
-        }
1019
-    }
1020
-
1021
-
1022
-
1023
-    /**
1024
-     *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1025
-     *
1026
-     * @access private
1027
-     * @param EE_Transaction $transaction
1028
-     * @return    array
1029
-     * @throws \EventEspresso\core\exceptions\InvalidEntityException
1030
-     * @throws \EE_Error
1031
-     */
1032
-    private function _initialize_registrations(EE_Transaction $transaction)
1033
-    {
1034
-        $att_nmbr = 0;
1035
-        $registrations = array();
1036
-        if ($transaction instanceof EE_Transaction) {
1037
-            /** @type EE_Registration_Processor $registration_processor */
1038
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1039
-            $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1040
-            // now let's add the cart items to the $transaction
1041
-            foreach ($this->checkout->cart->get_tickets() as $line_item) {
1042
-                //do the following for each ticket of this type they selected
1043
-                for ($x = 1; $x <= $line_item->quantity(); $x++) {
1044
-                    $att_nmbr++;
1045
-                    /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1046
-                    $CreateRegistrationCommand = EE_Registry::instance()
1047
-                                                            ->create(
1048
-                                                                'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1049
-                                                                array(
1050
-                                                                    $transaction,
1051
-                                                                    $line_item,
1052
-                                                                    $att_nmbr,
1053
-                                                                    $this->checkout->total_ticket_count,
1054
-                                                                )
1055
-                                                            );
1056
-                    // override capabilities for frontend registrations
1057
-                    if ( ! is_admin()) {
1058
-                        $CreateRegistrationCommand->setCapCheck(
1059
-                            new PublicCapabilities('', 'create_new_registration')
1060
-                        );
1061
-                    }
1062
-                    $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1063
-                    if ( ! $registration instanceof EE_Registration) {
1064
-                        throw new InvalidEntityException($registration, 'EE_Registration');
1065
-                    }
1066
-                    $registrations[ $registration->ID() ] = $registration;
1067
-                }
1068
-            }
1069
-            $registration_processor->fix_reg_final_price_rounding_issue($transaction);
1070
-        }
1071
-        return $registrations;
1072
-    }
1073
-
1074
-
1075
-
1076
-    /**
1077
-     * sorts registrations by REG_count
1078
-     *
1079
-     * @access public
1080
-     * @param EE_Registration $reg_A
1081
-     * @param EE_Registration $reg_B
1082
-     * @return int
1083
-     */
1084
-    public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1085
-    {
1086
-        // this shouldn't ever happen within the same TXN, but oh well
1087
-        if ($reg_A->count() === $reg_B->count()) {
1088
-            return 0;
1089
-        }
1090
-        return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1091
-    }
1092
-
1093
-
1094
-
1095
-    /**
1096
-     *    _final_verifications
1097
-     * just makes sure that everything is set up correctly before proceeding
1098
-     *
1099
-     * @access    private
1100
-     * @return    bool
1101
-     * @throws \EE_Error
1102
-     */
1103
-    private function _final_verifications()
1104
-    {
1105
-        // filter checkout
1106
-        $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout);
1107
-        //verify that current step is still set correctly
1108
-        if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1109
-            EE_Error::add_error(
1110
-                __('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'),
1111
-                __FILE__,
1112
-                __FUNCTION__,
1113
-                __LINE__
1114
-            );
1115
-            return false;
1116
-        }
1117
-        // if returning to SPCO, then verify that primary registrant is set
1118
-        if ( ! empty($this->checkout->reg_url_link)) {
1119
-            $valid_registrant = $this->checkout->transaction->primary_registration();
1120
-            if ( ! $valid_registrant instanceof EE_Registration) {
1121
-                EE_Error::add_error(
1122
-                    __('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'),
1123
-                    __FILE__,
1124
-                    __FUNCTION__,
1125
-                    __LINE__
1126
-                );
1127
-                return false;
1128
-            }
1129
-            $valid_registrant = null;
1130
-            foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) {
1131
-                if (
1132
-                    $registration instanceof EE_Registration
1133
-                    && $registration->reg_url_link() === $this->checkout->reg_url_link
1134
-                ) {
1135
-                    $valid_registrant = $registration;
1136
-                }
1137
-            }
1138
-            if ( ! $valid_registrant instanceof EE_Registration) {
1139
-                // hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1140
-                if (EED_Single_Page_Checkout::$_checkout_verified) {
1141
-                    // clear the session, mark the checkout as unverified, and try again
1142
-                    EE_Registry::instance()->SSN->clear_session();
1143
-                    EED_Single_Page_Checkout::$_initialized = false;
1144
-                    EED_Single_Page_Checkout::$_checkout_verified = false;
1145
-                    $this->_initialize();
1146
-                    EE_Error::reset_notices();
1147
-                    return false;
1148
-                }
1149
-                EE_Error::add_error(
1150
-                    __('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'),
1151
-                    __FILE__,
1152
-                    __FUNCTION__,
1153
-                    __LINE__
1154
-                );
1155
-                return false;
1156
-            }
1157
-        }
1158
-        // now that things have been kinda sufficiently verified,
1159
-        // let's add the checkout to the session so that's available other systems
1160
-        EE_Registry::instance()->SSN->set_checkout($this->checkout);
1161
-        return true;
1162
-    }
1163
-
1164
-
1165
-
1166
-    /**
1167
-     *    _initialize_reg_steps
1168
-     * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1169
-     * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1170
-     *
1171
-     * @access    private
1172
-     * @param bool $reinitializing
1173
-     * @throws \EE_Error
1174
-     */
1175
-    private function _initialize_reg_steps($reinitializing = false)
1176
-    {
1177
-        $this->checkout->set_reg_step_initiated($this->checkout->current_step);
1178
-        // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1179
-        foreach ($this->checkout->reg_steps as $reg_step) {
1180
-            if ( ! $reg_step->initialize_reg_step()) {
1181
-                // if not initialized then maybe this step is being removed...
1182
-                if ( ! $reinitializing && $reg_step->is_current_step()) {
1183
-                    // if it was the current step, then we need to start over here
1184
-                    $this->_initialize_reg_steps(true);
1185
-                    return;
1186
-                }
1187
-                continue;
1188
-            }
1189
-            // add css and JS for current step
1190
-            $reg_step->enqueue_styles_and_scripts();
1191
-            // i18n
1192
-            $reg_step->translate_js_strings();
1193
-            if ($reg_step->is_current_step()) {
1194
-                // the text that appears on the reg step form submit button
1195
-                $reg_step->set_submit_button_text();
1196
-            }
1197
-        }
1198
-        // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1199
-        do_action("AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", $this->checkout->current_step);
1200
-    }
1201
-
1202
-
1203
-
1204
-    /**
1205
-     * _check_form_submission
1206
-     *
1207
-     * @access private
1208
-     * @return boolean
1209
-     */
1210
-    private function _check_form_submission()
1211
-    {
1212
-        //does this request require the reg form to be generated ?
1213
-        if ($this->checkout->generate_reg_form) {
1214
-            // ever heard that song by Blue Rodeo ?
1215
-            try {
1216
-                $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1217
-                // if not displaying a form, then check for form submission
1218
-                if (
1219
-                    $this->checkout->process_form_submission
1220
-                    && $this->checkout->current_step->reg_form->was_submitted()
1221
-                ) {
1222
-                    // clear out any old data in case this step is being run again
1223
-                    $this->checkout->current_step->set_valid_data(array());
1224
-                    // capture submitted form data
1225
-                    $this->checkout->current_step->reg_form->receive_form_submission(
1226
-                        apply_filters('FHEE__Single_Page_Checkout___check_form_submission__request_params', EE_Registry::instance()->REQ->params(), $this->checkout)
1227
-                    );
1228
-                    // validate submitted form data
1229
-                    if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1230
-                        // thou shall not pass !!!
1231
-                        $this->checkout->continue_reg = false;
1232
-                        // any form validation errors?
1233
-                        if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1234
-                            $submission_error_messages = array();
1235
-                            // bad, bad, bad registrant
1236
-                            foreach ($this->checkout->current_step->reg_form->get_validation_errors_accumulated() as $validation_error) {
1237
-                                if ($validation_error instanceof EE_Validation_Error) {
1238
-                                    $submission_error_messages[] = sprintf(
1239
-                                        __('%s : %s', 'event_espresso'),
1240
-                                        $validation_error->get_form_section()->html_label_text(),
1241
-                                        $validation_error->getMessage()
1242
-                                    );
1243
-                                }
1244
-                            }
1245
-                            EE_Error::add_error(implode('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__);
1246
-                        }
1247
-                        // well not really... what will happen is we'll just get redirected back to redo the current step
1248
-                        $this->go_to_next_step();
1249
-                        return false;
1250
-                    }
1251
-                }
1252
-            } catch (EE_Error $e) {
1253
-                $e->get_error();
1254
-            }
1255
-        }
1256
-        return true;
1257
-    }
1258
-
1259
-
1260
-
1261
-    /**
1262
-     * _process_action
1263
-     *
1264
-     * @access private
1265
-     * @return void
1266
-     * @throws \EE_Error
1267
-     */
1268
-    private function _process_form_action()
1269
-    {
1270
-        // what cha wanna do?
1271
-        switch ($this->checkout->action) {
1272
-            // AJAX next step reg form
1273
-            case 'display_spco_reg_step' :
1274
-                $this->checkout->redirect = false;
1275
-                if (EE_Registry::instance()->REQ->ajax) {
1276
-                    $this->checkout->json_response->set_reg_step_html($this->checkout->current_step->display_reg_form());
1277
-                }
1278
-                break;
1279
-            default :
1280
-                // meh... do one of those other steps first
1281
-                if ( ! empty($this->checkout->action) && is_callable(array($this->checkout->current_step, $this->checkout->action))) {
1282
-                    // dynamically creates hook point like: AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1283
-                    do_action("AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1284
-                    // call action on current step
1285
-                    if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1286
-                        // good registrant, you get to proceed
1287
-                        if (
1288
-                            $this->checkout->current_step->success_message() !== ''
1289
-                            && apply_filters(
1290
-                                'FHEE__Single_Page_Checkout___process_form_action__display_success',
1291
-                                false
1292
-                            )
1293
-                        ) {
1294
-                            EE_Error::add_success(
1295
-                                $this->checkout->current_step->success_message()
1296
-                                . '<br />' . $this->checkout->next_step->_instructions()
1297
-                            );
1298
-                        }
1299
-                        // pack it up, pack it in...
1300
-                        $this->_setup_redirect();
1301
-                    }
1302
-                    // dynamically creates hook point like: AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1303
-                    do_action("AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1304
-                } else {
1305
-                    EE_Error::add_error(
1306
-                        sprintf(
1307
-                            __('The requested form action "%s" does not exist for the current "%s" registration step.', 'event_espresso'),
1308
-                            $this->checkout->action,
1309
-                            $this->checkout->current_step->name()
1310
-                        ),
1311
-                        __FILE__,
1312
-                        __FUNCTION__,
1313
-                        __LINE__
1314
-                    );
1315
-                }
1316
-            // end default
1317
-        }
1318
-        // store our progress so far
1319
-        $this->checkout->stash_transaction_and_checkout();
1320
-        // advance to the next step! If you pass GO, collect $200
1321
-        $this->go_to_next_step();
1322
-    }
1323
-
1324
-
1325
-
1326
-    /**
1327
-     *        add_styles_and_scripts
1328
-     *
1329
-     * @access        public
1330
-     * @return        void
1331
-     */
1332
-    public function add_styles_and_scripts()
1333
-    {
1334
-        // i18n
1335
-        $this->translate_js_strings();
1336
-        if ($this->checkout->admin_request) {
1337
-            add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1338
-        } else {
1339
-            add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1340
-        }
1341
-    }
1342
-
1343
-
1344
-
1345
-    /**
1346
-     *        translate_js_strings
1347
-     *
1348
-     * @access        public
1349
-     * @return        void
1350
-     */
1351
-    public function translate_js_strings()
1352
-    {
1353
-        EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1354
-        EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1355
-        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');
1356
-        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');
1357
-        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');
1358
-        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');
1359
-        EE_Registry::$i18n_js_strings['reg_step_error'] = __('This registration step could not be completed. Please refresh the page and try again.', 'event_espresso');
1360
-        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');
1361
-        EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1362
-            __('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'),
1363
-            '<br/>',
1364
-            '<br/>'
1365
-        );
1366
-        EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1367
-        EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1368
-        EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1369
-        EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1370
-        EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1371
-        EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1372
-        EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1373
-        EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1374
-        EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1375
-        EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1376
-        EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1377
-        EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1378
-        EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1379
-        EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1380
-        EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1381
-        EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1382
-        EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1383
-        EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1384
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1385
-            __(
1386
-                '%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',
1387
-                'event_espresso'
1388
-            ),
1389
-            '<h4 class="important-notice">',
1390
-            '</h4>',
1391
-            '<br />',
1392
-            '<p>',
1393
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1394
-            '">',
1395
-            '</a>',
1396
-            '</p>'
1397
-        );
1398
-        EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters('FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', true);
1399
-        EE_Registry::$i18n_js_strings['session_extension'] = absint(
1400
-            apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1401
-        );
1402
-        EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1403
-            'M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1404
-        );
1405
-    }
1406
-
1407
-
1408
-
1409
-    /**
1410
-     *    enqueue_styles_and_scripts
1411
-     *
1412
-     * @access        public
1413
-     * @return        void
1414
-     * @throws \EE_Error
1415
-     */
1416
-    public function enqueue_styles_and_scripts()
1417
-    {
1418
-        // load css
1419
-        wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1420
-        wp_enqueue_style('single_page_checkout');
1421
-        // load JS
1422
-        wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1423
-        wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1424
-        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
-        if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1426
-            $this->checkout->registration_form->enqueue_js();
1427
-        }
1428
-        if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1429
-            $this->checkout->current_step->reg_form->enqueue_js();
1430
-        }
1431
-        wp_enqueue_script('single_page_checkout');
1432
-        /**
1433
-         * global action hook for enqueueing styles and scripts with
1434
-         * spco calls.
1435
-         */
1436
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1437
-        /**
1438
-         * dynamic action hook for enqueueing styles and scripts with spco calls.
1439
-         * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1440
-         */
1441
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this);
1442
-    }
1443
-
1444
-
1445
-
1446
-    /**
1447
-     *    display the Registration Single Page Checkout Form
1448
-     *
1449
-     * @access    private
1450
-     * @return    void
1451
-     * @throws \EE_Error
1452
-     */
1453
-    private function _display_spco_reg_form()
1454
-    {
1455
-        // if registering via the admin, just display the reg form for the current step
1456
-        if ($this->checkout->admin_request) {
1457
-            EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1458
-        } else {
1459
-            // add powered by EE msg
1460
-            add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1461
-            $empty_cart = count($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)) < 1
1462
-                ? true
1463
-                : false;
1464
-            EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1465
-            $cookies_not_set_msg = '';
1466
-            if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1467
-                $cookies_not_set_msg = apply_filters(
1468
-                    'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1469
-                    sprintf(
1470
-                        __(
1471
-                            '%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',
1472
-                            'event_espresso'
1473
-                        ),
1474
-                        '<div class="ee-attention">',
1475
-                        '</div>',
1476
-                        '<h6 class="important-notice">',
1477
-                        '</h6>',
1478
-                        '<p>',
1479
-                        '</p>',
1480
-                        '<br />',
1481
-                        '<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1482
-                        '</a>'
1483
-                    )
1484
-                );
1485
-            }
1486
-            $this->checkout->registration_form = new EE_Form_Section_Proper(
1487
-                array(
1488
-                    'name'            => 'single-page-checkout',
1489
-                    'html_id'         => 'ee-single-page-checkout-dv',
1490
-                    'layout_strategy' =>
1491
-                        new EE_Template_Layout(
1492
-                            array(
1493
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1494
-                                'template_args'        => array(
1495
-                                    'empty_cart'              => $empty_cart,
1496
-                                    'revisit'                 => $this->checkout->revisit,
1497
-                                    'reg_steps'               => $this->checkout->reg_steps,
1498
-                                    'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1499
-                                        ? $this->checkout->next_step->slug()
1500
-                                        : '',
1501
-                                    'cancel_page_url'         => $this->checkout->cancel_page_url,
1502
-                                    'empty_msg'               => apply_filters(
1503
-                                        'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1504
-                                        sprintf(
1505
-                                            __('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1506
-                                                'event_espresso'),
1507
-                                            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1508
-                                            '">',
1509
-                                            '</a>'
1510
-                                        )
1511
-                                    ),
1512
-                                    'cookies_not_set_msg'     => $cookies_not_set_msg,
1513
-                                    'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1514
-                                    'session_expiration'      =>
1515
-                                        date('M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)),
1516
-                                ),
1517
-                            )
1518
-                        ),
1519
-                )
1520
-            );
1521
-            // load template and add to output sent that gets filtered into the_content()
1522
-            EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1523
-        }
1524
-    }
1525
-
1526
-
1527
-
1528
-    /**
1529
-     *    add_extra_finalize_registration_inputs
1530
-     *
1531
-     * @access    public
1532
-     * @param $next_step
1533
-     * @internal  param string $label
1534
-     * @return void
1535
-     */
1536
-    public function add_extra_finalize_registration_inputs($next_step)
1537
-    {
1538
-        if ($next_step === 'finalize_registration') {
1539
-            echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1540
-        }
1541
-    }
1542
-
1543
-
1544
-
1545
-    /**
1546
-     *    display_registration_footer
1547
-     *
1548
-     * @access    public
1549
-     * @return    string
1550
-     */
1551
-    public static function display_registration_footer()
1552
-    {
1553
-        if (
1554
-        apply_filters(
1555
-            'FHEE__EE_Front__Controller__show_reg_footer',
1556
-            EE_Registry::instance()->CFG->admin->show_reg_footer
1557
-        )
1558
-        ) {
1559
-            add_filter(
1560
-                'FHEE__EEH_Template__powered_by_event_espresso__url',
1561
-                function ($url) {
1562
-                    return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1563
-                }
1564
-            );
1565
-            echo apply_filters(
1566
-                'FHEE__EE_Front_Controller__display_registration_footer',
1567
-                \EEH_Template::powered_by_event_espresso(
1568
-                    '',
1569
-                    'espresso-registration-footer-dv',
1570
-                    array('utm_content' => 'registration_checkout')
1571
-                )
1572
-            );
1573
-        }
1574
-        return '';
1575
-    }
1576
-
1577
-
1578
-
1579
-    /**
1580
-     *    unlock_transaction
1581
-     *
1582
-     * @access    public
1583
-     * @return    void
1584
-     * @throws \EE_Error
1585
-     */
1586
-    public function unlock_transaction()
1587
-    {
1588
-        if ($this->checkout->transaction instanceof EE_Transaction) {
1589
-            $this->checkout->transaction->unlock();
1590
-        }
1591
-    }
1592
-
1593
-
1594
-
1595
-    /**
1596
-     *        _setup_redirect
1597
-     *
1598
-     * @access    private
1599
-     * @return void
1600
-     */
1601
-    private function _setup_redirect()
1602
-    {
1603
-        if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1604
-            $this->checkout->redirect = true;
1605
-            if (empty($this->checkout->redirect_url)) {
1606
-                $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1607
-            }
1608
-            $this->checkout->redirect_url = apply_filters(
1609
-                'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1610
-                $this->checkout->redirect_url,
1611
-                $this->checkout
1612
-            );
1613
-        }
1614
-    }
1615
-
1616
-
1617
-
1618
-    /**
1619
-     *   handle ajax message responses and redirects
1620
-     *
1621
-     * @access public
1622
-     * @return void
1623
-     * @throws \EE_Error
1624
-     */
1625
-    public function go_to_next_step()
1626
-    {
1627
-        if (EE_Registry::instance()->REQ->ajax) {
1628
-            // capture contents of output buffer we started earlier in the request, and insert into JSON response
1629
-            $this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1630
-        }
1631
-        $this->unlock_transaction();
1632
-        // just return for these conditions
1633
-        if (
1634
-            $this->checkout->admin_request
1635
-            || $this->checkout->action === 'redirect_form'
1636
-            || $this->checkout->action === 'update_checkout'
1637
-        ) {
1638
-            return;
1639
-        }
1640
-        // AJAX response
1641
-        $this->_handle_json_response();
1642
-        // redirect to next step or the Thank You page
1643
-        $this->_handle_html_redirects();
1644
-        // hmmm... must be something wrong, so let's just display the form again !
1645
-        $this->_display_spco_reg_form();
1646
-    }
1647
-
1648
-
1649
-
1650
-    /**
1651
-     *   _handle_json_response
1652
-     *
1653
-     * @access protected
1654
-     * @return void
1655
-     */
1656
-    protected function _handle_json_response()
1657
-    {
1658
-        // if this is an ajax request
1659
-        if (EE_Registry::instance()->REQ->ajax) {
1660
-            // DEBUG LOG
1661
-            //$this->checkout->log(
1662
-            //	__CLASS__, __FUNCTION__, __LINE__,
1663
-            //	array(
1664
-            //		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1665
-            //		'redirect'                   => $this->checkout->redirect,
1666
-            //		'continue_reg'               => $this->checkout->continue_reg,
1667
-            //	)
1668
-            //);
1669
-            $this->checkout->json_response->set_registration_time_limit(
1670
-                $this->checkout->get_registration_time_limit()
1671
-            );
1672
-            $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1673
-            // just send the ajax (
1674
-            $json_response = apply_filters(
1675
-                'FHEE__EE_Single_Page_Checkout__JSON_response',
1676
-                $this->checkout->json_response
1677
-            );
1678
-            echo $json_response;
1679
-            exit();
1680
-        }
1681
-    }
1682
-
1683
-
1684
-
1685
-    /**
1686
-     *   _handle_redirects
1687
-     *
1688
-     * @access protected
1689
-     * @return void
1690
-     */
1691
-    protected function _handle_html_redirects()
1692
-    {
1693
-        // going somewhere ?
1694
-        if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1695
-            // store notices in a transient
1696
-            EE_Error::get_notices(false, true, true);
1697
-            // DEBUG LOG
1698
-            //$this->checkout->log(
1699
-            //	__CLASS__, __FUNCTION__, __LINE__,
1700
-            //	array(
1701
-            //		'headers_sent' => headers_sent(),
1702
-            //		'redirect_url'     => $this->checkout->redirect_url,
1703
-            //		'headers_list'    => headers_list(),
1704
-            //	)
1705
-            //);
1706
-            wp_safe_redirect($this->checkout->redirect_url);
1707
-            exit();
1708
-        }
1709
-    }
1710
-
1711
-
1712
-
1713
-    /**
1714
-     *   set_checkout_anchor
1715
-     *
1716
-     * @access public
1717
-     * @return void
1718
-     */
1719
-    public function set_checkout_anchor()
1720
-    {
1721
-        echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1722
-    }
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
+			// hook into the top of pre_get_posts to set the reg step routing, which gives other modules or plugins a chance to modify the reg steps, but just before the routes get called
112
+			add_action('pre_get_posts', array('EED_Single_Page_Checkout', 'load_reg_steps'), 1);
113
+			return;
114
+		}
115
+		// going to start an output buffer in case anything gets accidentally output that might disrupt our JSON response
116
+		ob_start();
117
+		EED_Single_Page_Checkout::load_request_handler();
118
+		EED_Single_Page_Checkout::load_reg_steps();
119
+		// set ajax hooks
120
+		add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
121
+		add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
122
+		add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
123
+		add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
124
+		add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
125
+		add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
126
+	}
127
+
128
+
129
+
130
+	/**
131
+	 *    process ajax request
132
+	 *
133
+	 * @param string $ajax_action
134
+	 * @throws \EE_Error
135
+	 */
136
+	public static function process_ajax_request($ajax_action)
137
+	{
138
+		EE_Registry::instance()->REQ->set('action', $ajax_action);
139
+		EED_Single_Page_Checkout::instance()->_initialize();
140
+	}
141
+
142
+
143
+
144
+	/**
145
+	 *    ajax display registration step
146
+	 *
147
+	 * @throws \EE_Error
148
+	 */
149
+	public static function display_reg_step()
150
+	{
151
+		EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
152
+	}
153
+
154
+
155
+
156
+	/**
157
+	 *    ajax process registration step
158
+	 *
159
+	 * @throws \EE_Error
160
+	 */
161
+	public static function process_reg_step()
162
+	{
163
+		EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
164
+	}
165
+
166
+
167
+
168
+	/**
169
+	 *    ajax process registration step
170
+	 *
171
+	 * @throws \EE_Error
172
+	 */
173
+	public static function update_reg_step()
174
+	{
175
+		EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
176
+	}
177
+
178
+
179
+
180
+	/**
181
+	 *   update_checkout
182
+	 *
183
+	 * @access public
184
+	 * @return void
185
+	 * @throws \EE_Error
186
+	 */
187
+	public static function update_checkout()
188
+	{
189
+		EED_Single_Page_Checkout::process_ajax_request('update_checkout');
190
+	}
191
+
192
+
193
+
194
+	/**
195
+	 *    load_request_handler
196
+	 *
197
+	 * @access    public
198
+	 * @return    void
199
+	 */
200
+	public static function load_request_handler()
201
+	{
202
+		// load core Request_Handler class
203
+		if ( ! isset(EE_Registry::instance()->REQ)) {
204
+			EE_Registry::instance()->load_core('Request_Handler');
205
+		}
206
+	}
207
+
208
+
209
+
210
+	/**
211
+	 *    set_definitions
212
+	 *
213
+	 * @access    public
214
+	 * @return    void
215
+	 * @throws \EE_Error
216
+	 */
217
+	public static function set_definitions()
218
+	{
219
+		define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS);
220
+		define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
221
+		define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
222
+		define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
223
+		define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
224
+		define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
225
+		define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
226
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
227
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
228
+			__('%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',
229
+				'event_espresso'),
230
+			'<h4 class="important-notice">',
231
+			'</h4>',
232
+			'<br />',
233
+			'<p>',
234
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
235
+			'">',
236
+			'</a>',
237
+			'</p>'
238
+		);
239
+	}
240
+
241
+
242
+
243
+	/**
244
+	 * load_reg_steps
245
+	 * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
246
+	 *
247
+	 * @access    private
248
+	 * @throws EE_Error
249
+	 * @return void
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_reg_steps();
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_reg_steps();
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_flip($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
+	 *    run
438
+	 *
439
+	 * @access    public
440
+	 * @param WP_Query $WP_Query
441
+	 * @return    void
442
+	 * @throws \EE_Error
443
+	 */
444
+	public static function init($WP_Query)
445
+	{
446
+		EED_Single_Page_Checkout::instance()->run($WP_Query);
447
+	}
448
+
449
+
450
+
451
+	/**
452
+	 *    _initialize - initial module setup
453
+	 *
454
+	 * @access    private
455
+	 * @throws EE_Error
456
+	 * @return    void
457
+	 */
458
+	private function _initialize()
459
+	{
460
+		// ensure SPCO doesn't run twice
461
+		if (EED_Single_Page_Checkout::$_initialized) {
462
+			return;
463
+		}
464
+		try {
465
+			$this->_verify_session();
466
+			// setup the EE_Checkout object
467
+			$this->checkout = $this->_initialize_checkout();
468
+			// filter checkout
469
+			$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
470
+			// get the $_GET
471
+			$this->_get_request_vars();
472
+			if ($this->_block_bots()) {
473
+				return;
474
+			}
475
+			// filter continue_reg
476
+			$this->checkout->continue_reg = apply_filters('FHEE__EED_Single_Page_Checkout__init___continue_reg', true, $this->checkout);
477
+			// load the reg steps array
478
+			if ( ! $this->_load_and_instantiate_reg_steps()) {
479
+				EED_Single_Page_Checkout::$_initialized = true;
480
+				return;
481
+			}
482
+			// set the current step
483
+			$this->checkout->set_current_step($this->checkout->step);
484
+			// and the next step
485
+			$this->checkout->set_next_step();
486
+			// verify that everything has been setup correctly
487
+			if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
488
+				EED_Single_Page_Checkout::$_initialized = true;
489
+				return;
490
+			}
491
+			// lock the transaction
492
+			$this->checkout->transaction->lock();
493
+			// make sure all of our cached objects are added to their respective model entity mappers
494
+			$this->checkout->refresh_all_entities();
495
+			// set amount owing
496
+			$this->checkout->amount_owing = $this->checkout->transaction->remaining();
497
+			// initialize each reg step, which gives them the chance to potentially alter the process
498
+			$this->_initialize_reg_steps();
499
+			// DEBUG LOG
500
+			//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
501
+			// get reg form
502
+			if( ! $this->_check_form_submission()) {
503
+				EED_Single_Page_Checkout::$_initialized = true;
504
+				return;
505
+			}
506
+			// checkout the action!!!
507
+			$this->_process_form_action();
508
+			// add some style and make it dance
509
+			$this->add_styles_and_scripts();
510
+			// kk... SPCO has successfully run
511
+			EED_Single_Page_Checkout::$_initialized = true;
512
+			// set no cache headers and constants
513
+			EE_System::do_not_cache();
514
+			// add anchor
515
+			add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
516
+			// remove transaction lock
517
+			add_action('shutdown', array($this, 'unlock_transaction'), 1);
518
+		} catch (Exception $e) {
519
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
520
+		}
521
+	}
522
+
523
+
524
+
525
+	/**
526
+	 *    _verify_session
527
+	 * checks that the session is valid and not expired
528
+	 *
529
+	 * @access    private
530
+	 * @throws EE_Error
531
+	 */
532
+	private function _verify_session()
533
+	{
534
+		if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
535
+			throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
536
+		}
537
+		// is session still valid ?
538
+		if (EE_Registry::instance()->SSN->expired() && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '') {
539
+			$this->checkout = new EE_Checkout();
540
+			EE_Registry::instance()->SSN->reset_cart();
541
+			EE_Registry::instance()->SSN->reset_checkout();
542
+			EE_Registry::instance()->SSN->reset_transaction();
543
+			EE_Error::add_attention(EE_Registry::$i18n_js_strings['registration_expiration_notice'], __FILE__,
544
+				__FUNCTION__, __LINE__);
545
+			EE_Registry::instance()->SSN->reset_expired();
546
+		}
547
+	}
548
+
549
+
550
+
551
+	/**
552
+	 *    _initialize_checkout
553
+	 * loads and instantiates EE_Checkout
554
+	 *
555
+	 * @access    private
556
+	 * @throws EE_Error
557
+	 * @return EE_Checkout
558
+	 */
559
+	private function _initialize_checkout()
560
+	{
561
+		// look in session for existing checkout
562
+		/** @type EE_Checkout $checkout */
563
+		$checkout = EE_Registry::instance()->SSN->checkout();
564
+		// verify
565
+		if ( ! $checkout instanceof EE_Checkout) {
566
+			// instantiate EE_Checkout object for handling the properties of the current checkout process
567
+			$checkout = EE_Registry::instance()->load_file(SPCO_INC_PATH, 'EE_Checkout', 'class', array(), false);
568
+		} else {
569
+			if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
570
+				$this->unlock_transaction();
571
+				wp_safe_redirect($checkout->redirect_url);
572
+				exit();
573
+			}
574
+		}
575
+		$checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
576
+		// verify again
577
+		if ( ! $checkout instanceof EE_Checkout) {
578
+			throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
579
+		}
580
+		// reset anything that needs a clean slate for each request
581
+		$checkout->reset_for_current_request();
582
+		return $checkout;
583
+	}
584
+
585
+
586
+
587
+	/**
588
+	 *    _get_request_vars
589
+	 *
590
+	 * @access    private
591
+	 * @return    void
592
+	 * @throws \EE_Error
593
+	 */
594
+	private function _get_request_vars()
595
+	{
596
+		// load classes
597
+		EED_Single_Page_Checkout::load_request_handler();
598
+		//make sure this request is marked as belonging to EE
599
+		EE_Registry::instance()->REQ->set_espresso_page(true);
600
+		// which step is being requested ?
601
+		$this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
602
+		// which step is being edited ?
603
+		$this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
604
+		// and what we're doing on the current step
605
+		$this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
606
+		// timestamp
607
+		$this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
608
+		// returning to edit ?
609
+		$this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
610
+		// or some other kind of revisit ?
611
+		$this->checkout->revisit = filter_var(
612
+			EE_Registry::instance()->REQ->get('revisit', false),
613
+			FILTER_VALIDATE_BOOLEAN
614
+		);
615
+		// and whether or not to generate a reg form for this request
616
+		$this->checkout->generate_reg_form = filter_var(
617
+			EE_Registry::instance()->REQ->get('generate_reg_form', true),
618
+			FILTER_VALIDATE_BOOLEAN
619
+		);
620
+		// and whether or not to process a reg form submission for this request
621
+		$this->checkout->process_form_submission = filter_var(
622
+			EE_Registry::instance()->REQ->get(
623
+				'process_form_submission',
624
+				$this->checkout->action === 'process_reg_step'
625
+			),
626
+			FILTER_VALIDATE_BOOLEAN
627
+		);
628
+		$this->checkout->process_form_submission = filter_var(
629
+			$this->checkout->action !== 'display_spco_reg_step'
630
+				? $this->checkout->process_form_submission
631
+				: false,
632
+			FILTER_VALIDATE_BOOLEAN
633
+		);
634
+		// $this->_display_request_vars();
635
+	}
636
+
637
+
638
+
639
+	/**
640
+	 *  _display_request_vars
641
+	 *
642
+	 * @access    protected
643
+	 * @return    void
644
+	 */
645
+	protected function _display_request_vars()
646
+	{
647
+		if ( ! WP_DEBUG) {
648
+			return;
649
+		}
650
+		EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
651
+		EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
652
+		EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
653
+		EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
654
+		EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
655
+		EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
656
+		EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
657
+		EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
658
+	}
659
+
660
+
661
+
662
+	/**
663
+	 * _block_bots
664
+	 * checks that the incoming request has either of the following set:
665
+	 *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
666
+	 *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
667
+	 * so if you're not coming from the Ticket Selector nor returning for a valid IP...
668
+	 * then where you coming from man?
669
+	 *
670
+	 * @return boolean
671
+	 */
672
+	private function _block_bots()
673
+	{
674
+		$invalid_checkout_access = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
675
+		if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
676
+			return true;
677
+		}
678
+		return false;
679
+	}
680
+
681
+
682
+
683
+	/**
684
+	 *    _get_first_step
685
+	 *  gets slug for first step in $_reg_steps_array
686
+	 *
687
+	 * @access    private
688
+	 * @throws EE_Error
689
+	 * @return    string
690
+	 */
691
+	private function _get_first_step()
692
+	{
693
+		$first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
694
+		return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
695
+	}
696
+
697
+
698
+
699
+	/**
700
+	 *    _load_and_instantiate_reg_steps
701
+	 *  instantiates each reg step based on the loaded reg_steps array
702
+	 *
703
+	 * @access    private
704
+	 * @throws EE_Error
705
+	 * @return    bool
706
+	 */
707
+	private function _load_and_instantiate_reg_steps()
708
+	{
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
+			) {
775
+				return true;
776
+			}
777
+			// instantiate step class using file path and class name
778
+			$reg_step_obj = EE_Registry::instance()->load_file(
779
+				$reg_step['file_path'],
780
+				$reg_step['class_name'],
781
+				'class',
782
+				$this->checkout,
783
+				false
784
+			);
785
+			// did we gets the goods ?
786
+			if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
787
+				// set reg step order based on config
788
+				$reg_step_obj->set_order($order);
789
+				// add instantiated reg step object to the master reg steps array
790
+				$this->checkout->add_reg_step($reg_step_obj);
791
+			} else {
792
+				EE_Error::add_error(
793
+					__('The current step could not be set.', 'event_espresso'),
794
+					__FILE__, __FUNCTION__, __LINE__
795
+				);
796
+				return false;
797
+			}
798
+		} else {
799
+			if (WP_DEBUG) {
800
+				EE_Error::add_error(
801
+					sprintf(
802
+						__('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'),
803
+						isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
804
+						isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
805
+						isset($reg_step['slug']) ? $reg_step['slug'] : '',
806
+						'<ul>',
807
+						'<li>',
808
+						'</li>',
809
+						'</ul>'
810
+					),
811
+					__FILE__, __FUNCTION__, __LINE__
812
+				);
813
+			}
814
+			return false;
815
+		}
816
+		return true;
817
+	}
818
+
819
+
820
+
821
+	/**
822
+	 * _verify_transaction_and_get_registrations
823
+	 *
824
+	 * @access private
825
+	 * @return bool
826
+	 */
827
+	private function _verify_transaction_and_get_registrations()
828
+	{
829
+		// was there already a valid transaction in the checkout from the session ?
830
+		if ( ! $this->checkout->transaction instanceof EE_Transaction) {
831
+			// get transaction from db or session
832
+			$this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
833
+				? $this->_get_transaction_and_cart_for_previous_visit()
834
+				: $this->_get_cart_for_current_session_and_setup_new_transaction();
835
+			if ( ! $this->checkout->transaction instanceof EE_Transaction) {
836
+				EE_Error::add_error(
837
+					__('Your Registration and Transaction information could not be retrieved from the db.',
838
+						'event_espresso'),
839
+					__FILE__, __FUNCTION__, __LINE__
840
+				);
841
+				$this->checkout->transaction = EE_Transaction::new_instance();
842
+				// add some style and make it dance
843
+				$this->add_styles_and_scripts();
844
+				EED_Single_Page_Checkout::$_initialized = true;
845
+				return false;
846
+			}
847
+			// and the registrations for the transaction
848
+			$this->_get_registrations($this->checkout->transaction);
849
+		}
850
+		return true;
851
+	}
852
+
853
+
854
+
855
+	/**
856
+	 * _get_transaction_and_cart_for_previous_visit
857
+	 *
858
+	 * @access private
859
+	 * @return mixed EE_Transaction|NULL
860
+	 */
861
+	private function _get_transaction_and_cart_for_previous_visit()
862
+	{
863
+		/** @var $TXN_model EEM_Transaction */
864
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
865
+		// 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
866
+		$transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
867
+		// verify transaction
868
+		if ($transaction instanceof EE_Transaction) {
869
+			// and get the cart that was used for that transaction
870
+			$this->checkout->cart = $this->_get_cart_for_transaction($transaction);
871
+			return $transaction;
872
+		} else {
873
+			EE_Error::add_error(__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
874
+			return null;
875
+		}
876
+	}
877
+
878
+
879
+
880
+	/**
881
+	 * _get_cart_for_transaction
882
+	 *
883
+	 * @access private
884
+	 * @param EE_Transaction $transaction
885
+	 * @return EE_Cart
886
+	 */
887
+	private function _get_cart_for_transaction($transaction)
888
+	{
889
+		return $this->checkout->get_cart_for_transaction($transaction);
890
+	}
891
+
892
+
893
+
894
+	/**
895
+	 * get_cart_for_transaction
896
+	 *
897
+	 * @access public
898
+	 * @param EE_Transaction $transaction
899
+	 * @return EE_Cart
900
+	 */
901
+	public function get_cart_for_transaction(EE_Transaction $transaction)
902
+	{
903
+		return $this->checkout->get_cart_for_transaction($transaction);
904
+	}
905
+
906
+
907
+
908
+	/**
909
+	 * _get_transaction_and_cart_for_current_session
910
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
911
+	 *
912
+	 * @access private
913
+	 * @return EE_Transaction
914
+	 * @throws \EE_Error
915
+	 */
916
+	private function _get_cart_for_current_session_and_setup_new_transaction()
917
+	{
918
+		//  if there's no transaction, then this is the FIRST visit to SPCO
919
+		// so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
920
+		$this->checkout->cart = $this->_get_cart_for_transaction(null);
921
+		// and then create a new transaction
922
+		$transaction = $this->_initialize_transaction();
923
+		// verify transaction
924
+		if ($transaction instanceof EE_Transaction) {
925
+			// save it so that we have an ID for other objects to use
926
+			$transaction->save();
927
+			// and save TXN data to the cart
928
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
929
+		} else {
930
+			EE_Error::add_error(__('A Valid Transaction could not be initialized.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
931
+		}
932
+		return $transaction;
933
+	}
934
+
935
+
936
+
937
+	/**
938
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
939
+	 *
940
+	 * @access private
941
+	 * @return mixed EE_Transaction|NULL
942
+	 */
943
+	private function _initialize_transaction()
944
+	{
945
+		try {
946
+			// ensure cart totals have been calculated
947
+			$this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
948
+			// grab the cart grand total
949
+			$cart_total = $this->checkout->cart->get_cart_grand_total();
950
+			// create new TXN
951
+			$transaction = EE_Transaction::new_instance(
952
+				array(
953
+					'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
954
+					'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
955
+					'TXN_paid'      => 0,
956
+					'STS_ID'        => EEM_Transaction::failed_status_code,
957
+				)
958
+			);
959
+			// save it so that we have an ID for other objects to use
960
+			$transaction->save();
961
+			// set cron job for following up on TXNs after their session has expired
962
+			EE_Cron_Tasks::schedule_expired_transaction_check(
963
+				EE_Registry::instance()->SSN->expiration() + 1,
964
+				$transaction->ID()
965
+			);
966
+			return $transaction;
967
+		} catch (Exception $e) {
968
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
969
+		}
970
+		return null;
971
+	}
972
+
973
+
974
+
975
+	/**
976
+	 * _get_registrations
977
+	 *
978
+	 * @access private
979
+	 * @param EE_Transaction $transaction
980
+	 * @return void
981
+	 * @throws \EventEspresso\core\exceptions\InvalidEntityException
982
+	 * @throws \EE_Error
983
+	 */
984
+	private function _get_registrations(EE_Transaction $transaction)
985
+	{
986
+		// first step: grab the registrants  { : o
987
+		$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
988
+		// verify registrations have been set
989
+		if (empty($registrations)) {
990
+			// if no cached registrations, then check the db
991
+			$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
992
+			// still nothing ? well as long as this isn't a revisit
993
+			if (empty($registrations) && ! $this->checkout->revisit) {
994
+				// generate new registrations from scratch
995
+				$registrations = $this->_initialize_registrations($transaction);
996
+			}
997
+		}
998
+		// sort by their original registration order
999
+		usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1000
+		// then loop thru the array
1001
+		foreach ($registrations as $registration) {
1002
+			// verify each registration
1003
+			if ($registration instanceof EE_Registration) {
1004
+				// we display all attendee info for the primary registrant
1005
+				if ($this->checkout->reg_url_link === $registration->reg_url_link()
1006
+					&& $registration->is_primary_registrant()
1007
+				) {
1008
+					$this->checkout->primary_revisit = true;
1009
+					break;
1010
+				} else if ($this->checkout->revisit
1011
+						   && $this->checkout->reg_url_link !== $registration->reg_url_link()
1012
+				) {
1013
+					// but hide info if it doesn't belong to you
1014
+					$transaction->clear_cache('Registration', $registration->ID());
1015
+				}
1016
+				$this->checkout->set_reg_status_updated($registration->ID(), false);
1017
+			}
1018
+		}
1019
+	}
1020
+
1021
+
1022
+
1023
+	/**
1024
+	 *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1025
+	 *
1026
+	 * @access private
1027
+	 * @param EE_Transaction $transaction
1028
+	 * @return    array
1029
+	 * @throws \EventEspresso\core\exceptions\InvalidEntityException
1030
+	 * @throws \EE_Error
1031
+	 */
1032
+	private function _initialize_registrations(EE_Transaction $transaction)
1033
+	{
1034
+		$att_nmbr = 0;
1035
+		$registrations = array();
1036
+		if ($transaction instanceof EE_Transaction) {
1037
+			/** @type EE_Registration_Processor $registration_processor */
1038
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1039
+			$this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1040
+			// now let's add the cart items to the $transaction
1041
+			foreach ($this->checkout->cart->get_tickets() as $line_item) {
1042
+				//do the following for each ticket of this type they selected
1043
+				for ($x = 1; $x <= $line_item->quantity(); $x++) {
1044
+					$att_nmbr++;
1045
+					/** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1046
+					$CreateRegistrationCommand = EE_Registry::instance()
1047
+															->create(
1048
+																'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1049
+																array(
1050
+																	$transaction,
1051
+																	$line_item,
1052
+																	$att_nmbr,
1053
+																	$this->checkout->total_ticket_count,
1054
+																)
1055
+															);
1056
+					// override capabilities for frontend registrations
1057
+					if ( ! is_admin()) {
1058
+						$CreateRegistrationCommand->setCapCheck(
1059
+							new PublicCapabilities('', 'create_new_registration')
1060
+						);
1061
+					}
1062
+					$registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1063
+					if ( ! $registration instanceof EE_Registration) {
1064
+						throw new InvalidEntityException($registration, 'EE_Registration');
1065
+					}
1066
+					$registrations[ $registration->ID() ] = $registration;
1067
+				}
1068
+			}
1069
+			$registration_processor->fix_reg_final_price_rounding_issue($transaction);
1070
+		}
1071
+		return $registrations;
1072
+	}
1073
+
1074
+
1075
+
1076
+	/**
1077
+	 * sorts registrations by REG_count
1078
+	 *
1079
+	 * @access public
1080
+	 * @param EE_Registration $reg_A
1081
+	 * @param EE_Registration $reg_B
1082
+	 * @return int
1083
+	 */
1084
+	public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1085
+	{
1086
+		// this shouldn't ever happen within the same TXN, but oh well
1087
+		if ($reg_A->count() === $reg_B->count()) {
1088
+			return 0;
1089
+		}
1090
+		return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1091
+	}
1092
+
1093
+
1094
+
1095
+	/**
1096
+	 *    _final_verifications
1097
+	 * just makes sure that everything is set up correctly before proceeding
1098
+	 *
1099
+	 * @access    private
1100
+	 * @return    bool
1101
+	 * @throws \EE_Error
1102
+	 */
1103
+	private function _final_verifications()
1104
+	{
1105
+		// filter checkout
1106
+		$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout);
1107
+		//verify that current step is still set correctly
1108
+		if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1109
+			EE_Error::add_error(
1110
+				__('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'),
1111
+				__FILE__,
1112
+				__FUNCTION__,
1113
+				__LINE__
1114
+			);
1115
+			return false;
1116
+		}
1117
+		// if returning to SPCO, then verify that primary registrant is set
1118
+		if ( ! empty($this->checkout->reg_url_link)) {
1119
+			$valid_registrant = $this->checkout->transaction->primary_registration();
1120
+			if ( ! $valid_registrant instanceof EE_Registration) {
1121
+				EE_Error::add_error(
1122
+					__('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'),
1123
+					__FILE__,
1124
+					__FUNCTION__,
1125
+					__LINE__
1126
+				);
1127
+				return false;
1128
+			}
1129
+			$valid_registrant = null;
1130
+			foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) {
1131
+				if (
1132
+					$registration instanceof EE_Registration
1133
+					&& $registration->reg_url_link() === $this->checkout->reg_url_link
1134
+				) {
1135
+					$valid_registrant = $registration;
1136
+				}
1137
+			}
1138
+			if ( ! $valid_registrant instanceof EE_Registration) {
1139
+				// hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1140
+				if (EED_Single_Page_Checkout::$_checkout_verified) {
1141
+					// clear the session, mark the checkout as unverified, and try again
1142
+					EE_Registry::instance()->SSN->clear_session();
1143
+					EED_Single_Page_Checkout::$_initialized = false;
1144
+					EED_Single_Page_Checkout::$_checkout_verified = false;
1145
+					$this->_initialize();
1146
+					EE_Error::reset_notices();
1147
+					return false;
1148
+				}
1149
+				EE_Error::add_error(
1150
+					__('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'),
1151
+					__FILE__,
1152
+					__FUNCTION__,
1153
+					__LINE__
1154
+				);
1155
+				return false;
1156
+			}
1157
+		}
1158
+		// now that things have been kinda sufficiently verified,
1159
+		// let's add the checkout to the session so that's available other systems
1160
+		EE_Registry::instance()->SSN->set_checkout($this->checkout);
1161
+		return true;
1162
+	}
1163
+
1164
+
1165
+
1166
+	/**
1167
+	 *    _initialize_reg_steps
1168
+	 * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1169
+	 * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1170
+	 *
1171
+	 * @access    private
1172
+	 * @param bool $reinitializing
1173
+	 * @throws \EE_Error
1174
+	 */
1175
+	private function _initialize_reg_steps($reinitializing = false)
1176
+	{
1177
+		$this->checkout->set_reg_step_initiated($this->checkout->current_step);
1178
+		// loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1179
+		foreach ($this->checkout->reg_steps as $reg_step) {
1180
+			if ( ! $reg_step->initialize_reg_step()) {
1181
+				// if not initialized then maybe this step is being removed...
1182
+				if ( ! $reinitializing && $reg_step->is_current_step()) {
1183
+					// if it was the current step, then we need to start over here
1184
+					$this->_initialize_reg_steps(true);
1185
+					return;
1186
+				}
1187
+				continue;
1188
+			}
1189
+			// add css and JS for current step
1190
+			$reg_step->enqueue_styles_and_scripts();
1191
+			// i18n
1192
+			$reg_step->translate_js_strings();
1193
+			if ($reg_step->is_current_step()) {
1194
+				// the text that appears on the reg step form submit button
1195
+				$reg_step->set_submit_button_text();
1196
+			}
1197
+		}
1198
+		// dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1199
+		do_action("AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", $this->checkout->current_step);
1200
+	}
1201
+
1202
+
1203
+
1204
+	/**
1205
+	 * _check_form_submission
1206
+	 *
1207
+	 * @access private
1208
+	 * @return boolean
1209
+	 */
1210
+	private function _check_form_submission()
1211
+	{
1212
+		//does this request require the reg form to be generated ?
1213
+		if ($this->checkout->generate_reg_form) {
1214
+			// ever heard that song by Blue Rodeo ?
1215
+			try {
1216
+				$this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1217
+				// if not displaying a form, then check for form submission
1218
+				if (
1219
+					$this->checkout->process_form_submission
1220
+					&& $this->checkout->current_step->reg_form->was_submitted()
1221
+				) {
1222
+					// clear out any old data in case this step is being run again
1223
+					$this->checkout->current_step->set_valid_data(array());
1224
+					// capture submitted form data
1225
+					$this->checkout->current_step->reg_form->receive_form_submission(
1226
+						apply_filters('FHEE__Single_Page_Checkout___check_form_submission__request_params', EE_Registry::instance()->REQ->params(), $this->checkout)
1227
+					);
1228
+					// validate submitted form data
1229
+					if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1230
+						// thou shall not pass !!!
1231
+						$this->checkout->continue_reg = false;
1232
+						// any form validation errors?
1233
+						if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1234
+							$submission_error_messages = array();
1235
+							// bad, bad, bad registrant
1236
+							foreach ($this->checkout->current_step->reg_form->get_validation_errors_accumulated() as $validation_error) {
1237
+								if ($validation_error instanceof EE_Validation_Error) {
1238
+									$submission_error_messages[] = sprintf(
1239
+										__('%s : %s', 'event_espresso'),
1240
+										$validation_error->get_form_section()->html_label_text(),
1241
+										$validation_error->getMessage()
1242
+									);
1243
+								}
1244
+							}
1245
+							EE_Error::add_error(implode('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__);
1246
+						}
1247
+						// well not really... what will happen is we'll just get redirected back to redo the current step
1248
+						$this->go_to_next_step();
1249
+						return false;
1250
+					}
1251
+				}
1252
+			} catch (EE_Error $e) {
1253
+				$e->get_error();
1254
+			}
1255
+		}
1256
+		return true;
1257
+	}
1258
+
1259
+
1260
+
1261
+	/**
1262
+	 * _process_action
1263
+	 *
1264
+	 * @access private
1265
+	 * @return void
1266
+	 * @throws \EE_Error
1267
+	 */
1268
+	private function _process_form_action()
1269
+	{
1270
+		// what cha wanna do?
1271
+		switch ($this->checkout->action) {
1272
+			// AJAX next step reg form
1273
+			case 'display_spco_reg_step' :
1274
+				$this->checkout->redirect = false;
1275
+				if (EE_Registry::instance()->REQ->ajax) {
1276
+					$this->checkout->json_response->set_reg_step_html($this->checkout->current_step->display_reg_form());
1277
+				}
1278
+				break;
1279
+			default :
1280
+				// meh... do one of those other steps first
1281
+				if ( ! empty($this->checkout->action) && is_callable(array($this->checkout->current_step, $this->checkout->action))) {
1282
+					// dynamically creates hook point like: AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1283
+					do_action("AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1284
+					// call action on current step
1285
+					if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1286
+						// good registrant, you get to proceed
1287
+						if (
1288
+							$this->checkout->current_step->success_message() !== ''
1289
+							&& apply_filters(
1290
+								'FHEE__Single_Page_Checkout___process_form_action__display_success',
1291
+								false
1292
+							)
1293
+						) {
1294
+							EE_Error::add_success(
1295
+								$this->checkout->current_step->success_message()
1296
+								. '<br />' . $this->checkout->next_step->_instructions()
1297
+							);
1298
+						}
1299
+						// pack it up, pack it in...
1300
+						$this->_setup_redirect();
1301
+					}
1302
+					// dynamically creates hook point like: AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1303
+					do_action("AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step);
1304
+				} else {
1305
+					EE_Error::add_error(
1306
+						sprintf(
1307
+							__('The requested form action "%s" does not exist for the current "%s" registration step.', 'event_espresso'),
1308
+							$this->checkout->action,
1309
+							$this->checkout->current_step->name()
1310
+						),
1311
+						__FILE__,
1312
+						__FUNCTION__,
1313
+						__LINE__
1314
+					);
1315
+				}
1316
+			// end default
1317
+		}
1318
+		// store our progress so far
1319
+		$this->checkout->stash_transaction_and_checkout();
1320
+		// advance to the next step! If you pass GO, collect $200
1321
+		$this->go_to_next_step();
1322
+	}
1323
+
1324
+
1325
+
1326
+	/**
1327
+	 *        add_styles_and_scripts
1328
+	 *
1329
+	 * @access        public
1330
+	 * @return        void
1331
+	 */
1332
+	public function add_styles_and_scripts()
1333
+	{
1334
+		// i18n
1335
+		$this->translate_js_strings();
1336
+		if ($this->checkout->admin_request) {
1337
+			add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1338
+		} else {
1339
+			add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1340
+		}
1341
+	}
1342
+
1343
+
1344
+
1345
+	/**
1346
+	 *        translate_js_strings
1347
+	 *
1348
+	 * @access        public
1349
+	 * @return        void
1350
+	 */
1351
+	public function translate_js_strings()
1352
+	{
1353
+		EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1354
+		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1355
+		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');
1356
+		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');
1357
+		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');
1358
+		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');
1359
+		EE_Registry::$i18n_js_strings['reg_step_error'] = __('This registration step could not be completed. Please refresh the page and try again.', 'event_espresso');
1360
+		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');
1361
+		EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1362
+			__('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'),
1363
+			'<br/>',
1364
+			'<br/>'
1365
+		);
1366
+		EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1367
+		EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1368
+		EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1369
+		EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1370
+		EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1371
+		EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1372
+		EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1373
+		EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1374
+		EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1375
+		EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1376
+		EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1377
+		EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1378
+		EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1379
+		EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1380
+		EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1381
+		EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1382
+		EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1383
+		EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1384
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1385
+			__(
1386
+				'%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',
1387
+				'event_espresso'
1388
+			),
1389
+			'<h4 class="important-notice">',
1390
+			'</h4>',
1391
+			'<br />',
1392
+			'<p>',
1393
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1394
+			'">',
1395
+			'</a>',
1396
+			'</p>'
1397
+		);
1398
+		EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters('FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', true);
1399
+		EE_Registry::$i18n_js_strings['session_extension'] = absint(
1400
+			apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1401
+		);
1402
+		EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1403
+			'M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1404
+		);
1405
+	}
1406
+
1407
+
1408
+
1409
+	/**
1410
+	 *    enqueue_styles_and_scripts
1411
+	 *
1412
+	 * @access        public
1413
+	 * @return        void
1414
+	 * @throws \EE_Error
1415
+	 */
1416
+	public function enqueue_styles_and_scripts()
1417
+	{
1418
+		// load css
1419
+		wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1420
+		wp_enqueue_style('single_page_checkout');
1421
+		// load JS
1422
+		wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1423
+		wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1424
+		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
+		if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1426
+			$this->checkout->registration_form->enqueue_js();
1427
+		}
1428
+		if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1429
+			$this->checkout->current_step->reg_form->enqueue_js();
1430
+		}
1431
+		wp_enqueue_script('single_page_checkout');
1432
+		/**
1433
+		 * global action hook for enqueueing styles and scripts with
1434
+		 * spco calls.
1435
+		 */
1436
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1437
+		/**
1438
+		 * dynamic action hook for enqueueing styles and scripts with spco calls.
1439
+		 * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1440
+		 */
1441
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this);
1442
+	}
1443
+
1444
+
1445
+
1446
+	/**
1447
+	 *    display the Registration Single Page Checkout Form
1448
+	 *
1449
+	 * @access    private
1450
+	 * @return    void
1451
+	 * @throws \EE_Error
1452
+	 */
1453
+	private function _display_spco_reg_form()
1454
+	{
1455
+		// if registering via the admin, just display the reg form for the current step
1456
+		if ($this->checkout->admin_request) {
1457
+			EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1458
+		} else {
1459
+			// add powered by EE msg
1460
+			add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1461
+			$empty_cart = count($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)) < 1
1462
+				? true
1463
+				: false;
1464
+			EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1465
+			$cookies_not_set_msg = '';
1466
+			if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1467
+				$cookies_not_set_msg = apply_filters(
1468
+					'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1469
+					sprintf(
1470
+						__(
1471
+							'%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',
1472
+							'event_espresso'
1473
+						),
1474
+						'<div class="ee-attention">',
1475
+						'</div>',
1476
+						'<h6 class="important-notice">',
1477
+						'</h6>',
1478
+						'<p>',
1479
+						'</p>',
1480
+						'<br />',
1481
+						'<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1482
+						'</a>'
1483
+					)
1484
+				);
1485
+			}
1486
+			$this->checkout->registration_form = new EE_Form_Section_Proper(
1487
+				array(
1488
+					'name'            => 'single-page-checkout',
1489
+					'html_id'         => 'ee-single-page-checkout-dv',
1490
+					'layout_strategy' =>
1491
+						new EE_Template_Layout(
1492
+							array(
1493
+								'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1494
+								'template_args'        => array(
1495
+									'empty_cart'              => $empty_cart,
1496
+									'revisit'                 => $this->checkout->revisit,
1497
+									'reg_steps'               => $this->checkout->reg_steps,
1498
+									'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1499
+										? $this->checkout->next_step->slug()
1500
+										: '',
1501
+									'cancel_page_url'         => $this->checkout->cancel_page_url,
1502
+									'empty_msg'               => apply_filters(
1503
+										'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1504
+										sprintf(
1505
+											__('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1506
+												'event_espresso'),
1507
+											'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1508
+											'">',
1509
+											'</a>'
1510
+										)
1511
+									),
1512
+									'cookies_not_set_msg'     => $cookies_not_set_msg,
1513
+									'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1514
+									'session_expiration'      =>
1515
+										date('M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)),
1516
+								),
1517
+							)
1518
+						),
1519
+				)
1520
+			);
1521
+			// load template and add to output sent that gets filtered into the_content()
1522
+			EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1523
+		}
1524
+	}
1525
+
1526
+
1527
+
1528
+	/**
1529
+	 *    add_extra_finalize_registration_inputs
1530
+	 *
1531
+	 * @access    public
1532
+	 * @param $next_step
1533
+	 * @internal  param string $label
1534
+	 * @return void
1535
+	 */
1536
+	public function add_extra_finalize_registration_inputs($next_step)
1537
+	{
1538
+		if ($next_step === 'finalize_registration') {
1539
+			echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1540
+		}
1541
+	}
1542
+
1543
+
1544
+
1545
+	/**
1546
+	 *    display_registration_footer
1547
+	 *
1548
+	 * @access    public
1549
+	 * @return    string
1550
+	 */
1551
+	public static function display_registration_footer()
1552
+	{
1553
+		if (
1554
+		apply_filters(
1555
+			'FHEE__EE_Front__Controller__show_reg_footer',
1556
+			EE_Registry::instance()->CFG->admin->show_reg_footer
1557
+		)
1558
+		) {
1559
+			add_filter(
1560
+				'FHEE__EEH_Template__powered_by_event_espresso__url',
1561
+				function ($url) {
1562
+					return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1563
+				}
1564
+			);
1565
+			echo apply_filters(
1566
+				'FHEE__EE_Front_Controller__display_registration_footer',
1567
+				\EEH_Template::powered_by_event_espresso(
1568
+					'',
1569
+					'espresso-registration-footer-dv',
1570
+					array('utm_content' => 'registration_checkout')
1571
+				)
1572
+			);
1573
+		}
1574
+		return '';
1575
+	}
1576
+
1577
+
1578
+
1579
+	/**
1580
+	 *    unlock_transaction
1581
+	 *
1582
+	 * @access    public
1583
+	 * @return    void
1584
+	 * @throws \EE_Error
1585
+	 */
1586
+	public function unlock_transaction()
1587
+	{
1588
+		if ($this->checkout->transaction instanceof EE_Transaction) {
1589
+			$this->checkout->transaction->unlock();
1590
+		}
1591
+	}
1592
+
1593
+
1594
+
1595
+	/**
1596
+	 *        _setup_redirect
1597
+	 *
1598
+	 * @access    private
1599
+	 * @return void
1600
+	 */
1601
+	private function _setup_redirect()
1602
+	{
1603
+		if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1604
+			$this->checkout->redirect = true;
1605
+			if (empty($this->checkout->redirect_url)) {
1606
+				$this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1607
+			}
1608
+			$this->checkout->redirect_url = apply_filters(
1609
+				'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1610
+				$this->checkout->redirect_url,
1611
+				$this->checkout
1612
+			);
1613
+		}
1614
+	}
1615
+
1616
+
1617
+
1618
+	/**
1619
+	 *   handle ajax message responses and redirects
1620
+	 *
1621
+	 * @access public
1622
+	 * @return void
1623
+	 * @throws \EE_Error
1624
+	 */
1625
+	public function go_to_next_step()
1626
+	{
1627
+		if (EE_Registry::instance()->REQ->ajax) {
1628
+			// capture contents of output buffer we started earlier in the request, and insert into JSON response
1629
+			$this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1630
+		}
1631
+		$this->unlock_transaction();
1632
+		// just return for these conditions
1633
+		if (
1634
+			$this->checkout->admin_request
1635
+			|| $this->checkout->action === 'redirect_form'
1636
+			|| $this->checkout->action === 'update_checkout'
1637
+		) {
1638
+			return;
1639
+		}
1640
+		// AJAX response
1641
+		$this->_handle_json_response();
1642
+		// redirect to next step or the Thank You page
1643
+		$this->_handle_html_redirects();
1644
+		// hmmm... must be something wrong, so let's just display the form again !
1645
+		$this->_display_spco_reg_form();
1646
+	}
1647
+
1648
+
1649
+
1650
+	/**
1651
+	 *   _handle_json_response
1652
+	 *
1653
+	 * @access protected
1654
+	 * @return void
1655
+	 */
1656
+	protected function _handle_json_response()
1657
+	{
1658
+		// if this is an ajax request
1659
+		if (EE_Registry::instance()->REQ->ajax) {
1660
+			// DEBUG LOG
1661
+			//$this->checkout->log(
1662
+			//	__CLASS__, __FUNCTION__, __LINE__,
1663
+			//	array(
1664
+			//		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1665
+			//		'redirect'                   => $this->checkout->redirect,
1666
+			//		'continue_reg'               => $this->checkout->continue_reg,
1667
+			//	)
1668
+			//);
1669
+			$this->checkout->json_response->set_registration_time_limit(
1670
+				$this->checkout->get_registration_time_limit()
1671
+			);
1672
+			$this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1673
+			// just send the ajax (
1674
+			$json_response = apply_filters(
1675
+				'FHEE__EE_Single_Page_Checkout__JSON_response',
1676
+				$this->checkout->json_response
1677
+			);
1678
+			echo $json_response;
1679
+			exit();
1680
+		}
1681
+	}
1682
+
1683
+
1684
+
1685
+	/**
1686
+	 *   _handle_redirects
1687
+	 *
1688
+	 * @access protected
1689
+	 * @return void
1690
+	 */
1691
+	protected function _handle_html_redirects()
1692
+	{
1693
+		// going somewhere ?
1694
+		if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1695
+			// store notices in a transient
1696
+			EE_Error::get_notices(false, true, true);
1697
+			// DEBUG LOG
1698
+			//$this->checkout->log(
1699
+			//	__CLASS__, __FUNCTION__, __LINE__,
1700
+			//	array(
1701
+			//		'headers_sent' => headers_sent(),
1702
+			//		'redirect_url'     => $this->checkout->redirect_url,
1703
+			//		'headers_list'    => headers_list(),
1704
+			//	)
1705
+			//);
1706
+			wp_safe_redirect($this->checkout->redirect_url);
1707
+			exit();
1708
+		}
1709
+	}
1710
+
1711
+
1712
+
1713
+	/**
1714
+	 *   set_checkout_anchor
1715
+	 *
1716
+	 * @access public
1717
+	 * @return void
1718
+	 */
1719
+	public function set_checkout_anchor()
1720
+	{
1721
+		echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1722
+	}
1723 1723
 
1724 1724
 
1725 1725
 
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -216,13 +216,13 @@  discard block
 block discarded – undo
216 216
      */
217 217
     public static function set_definitions()
218 218
     {
219
-        define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS);
220
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
221
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
222
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
223
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
224
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
225
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
219
+        define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS).DS);
220
+        define('SPCO_CSS_URL', plugin_dir_url(__FILE__).'css'.DS);
221
+        define('SPCO_IMG_URL', plugin_dir_url(__FILE__).'img'.DS);
222
+        define('SPCO_JS_URL', plugin_dir_url(__FILE__).'js'.DS);
223
+        define('SPCO_INC_PATH', SPCO_BASE_PATH.'inc'.DS);
224
+        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH.'reg_steps'.DS);
225
+        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH.'templates'.DS);
226 226
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
227 227
         EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
228 228
             __('%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',
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
             '</h4>',
232 232
             '<br />',
233 233
             '<p>',
234
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
234
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
235 235
             '">',
236 236
             '</a>',
237 237
             '</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,
@@ -499,7 +499,7 @@  discard block
 block discarded – undo
499 499
             // DEBUG LOG
500 500
             //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
501 501
             // get reg form
502
-            if( ! $this->_check_form_submission()) {
502
+            if ( ! $this->_check_form_submission()) {
503 503
                 EED_Single_Page_Checkout::$_initialized = true;
504 504
                 return;
505 505
             }
@@ -1063,7 +1063,7 @@  discard block
 block discarded – undo
1063 1063
                     if ( ! $registration instanceof EE_Registration) {
1064 1064
                         throw new InvalidEntityException($registration, 'EE_Registration');
1065 1065
                     }
1066
-                    $registrations[ $registration->ID() ] = $registration;
1066
+                    $registrations[$registration->ID()] = $registration;
1067 1067
                 }
1068 1068
             }
1069 1069
             $registration_processor->fix_reg_final_price_rounding_issue($transaction);
@@ -1293,7 +1293,7 @@  discard block
 block discarded – undo
1293 1293
                         ) {
1294 1294
                             EE_Error::add_success(
1295 1295
                                 $this->checkout->current_step->success_message()
1296
-                                . '<br />' . $this->checkout->next_step->_instructions()
1296
+                                . '<br />'.$this->checkout->next_step->_instructions()
1297 1297
                             );
1298 1298
                         }
1299 1299
                         // pack it up, pack it in...
@@ -1390,7 +1390,7 @@  discard block
 block discarded – undo
1390 1390
             '</h4>',
1391 1391
             '<br />',
1392 1392
             '<p>',
1393
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1393
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
1394 1394
             '">',
1395 1395
             '</a>',
1396 1396
             '</p>'
@@ -1416,12 +1416,12 @@  discard block
 block discarded – undo
1416 1416
     public function enqueue_styles_and_scripts()
1417 1417
     {
1418 1418
         // load css
1419
-        wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1419
+        wp_register_style('single_page_checkout', SPCO_CSS_URL.'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION);
1420 1420
         wp_enqueue_style('single_page_checkout');
1421 1421
         // load JS
1422
-        wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1423
-        wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1424
-        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);
1422
+        wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL.'jquery	.plugin.min.js', array('jquery'), '1.0.1', true);
1423
+        wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL.'jquery	.countdown.min.js', array('jquery_plugin'), '2.0.2', true);
1424
+        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 1425
         if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1426 1426
             $this->checkout->registration_form->enqueue_js();
1427 1427
         }
@@ -1438,7 +1438,7 @@  discard block
 block discarded – undo
1438 1438
          * dynamic action hook for enqueueing styles and scripts with spco calls.
1439 1439
          * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1440 1440
          */
1441
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this);
1441
+        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__'.$this->checkout->current_step->slug(), $this);
1442 1442
     }
1443 1443
 
1444 1444
 
@@ -1490,7 +1490,7 @@  discard block
 block discarded – undo
1490 1490
                     'layout_strategy' =>
1491 1491
                         new EE_Template_Layout(
1492 1492
                             array(
1493
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1493
+                                'layout_template_file' => SPCO_TEMPLATES_PATH.'registration_page_wrapper.template.php',
1494 1494
                                 'template_args'        => array(
1495 1495
                                     'empty_cart'              => $empty_cart,
1496 1496
                                     'revisit'                 => $this->checkout->revisit,
@@ -1504,7 +1504,7 @@  discard block
 block discarded – undo
1504 1504
                                         sprintf(
1505 1505
                                             __('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1506 1506
                                                 'event_espresso'),
1507
-                                            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1507
+                                            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
1508 1508
                                             '">',
1509 1509
                                             '</a>'
1510 1510
                                         )
@@ -1558,7 +1558,7 @@  discard block
 block discarded – undo
1558 1558
         ) {
1559 1559
             add_filter(
1560 1560
                 'FHEE__EEH_Template__powered_by_event_espresso__url',
1561
-                function ($url) {
1561
+                function($url) {
1562 1562
                     return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1563 1563
                 }
1564 1564
             );
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.
admin/extend/registrations/EE_Event_Registrations_List_Table.class.php 2 patches
Indentation   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 		$this->_columns = array_merge( $columns, $this->_columns );
88 88
 		$this->_primary_column = '_REG_att_checked_in';
89 89
 		if ( ! empty( $evt_id )
90
-		     && EE_Registry::instance()->CAP->current_user_can(
90
+			 && EE_Registry::instance()->CAP->current_user_can(
91 91
 				'ee_read_registrations',
92 92
 				'espresso_registrations_registrations_reports',
93 93
 				$evt_id
@@ -104,28 +104,28 @@  discard block
 block discarded – undo
104 104
 				),
105 105
 			);
106 106
 		}
107
-        $this->_bottom_buttons['report_filtered'] = array(
108
-            'route'         => 'registrations_checkin_report',
109
-            'extra_request' => array(
110
-                'use_filters' => true,
111
-                'filters'     => array_merge(
112
-                    array(
113
-                        'EVT_ID' => $evt_id,
114
-                    ),
115
-                    array_diff_key(
116
-                        $this->_req_data,
117
-                        array_flip(
118
-                            array(
119
-                                'page',
120
-                                'action',
121
-                                'default_nonce',
122
-                            )
123
-                        )
124
-                    )
125
-                ),
126
-                'return_url'  => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
127
-            ),
128
-        );
107
+		$this->_bottom_buttons['report_filtered'] = array(
108
+			'route'         => 'registrations_checkin_report',
109
+			'extra_request' => array(
110
+				'use_filters' => true,
111
+				'filters'     => array_merge(
112
+					array(
113
+						'EVT_ID' => $evt_id,
114
+					),
115
+					array_diff_key(
116
+						$this->_req_data,
117
+						array_flip(
118
+							array(
119
+								'page',
120
+								'action',
121
+								'default_nonce',
122
+							)
123
+						)
124
+					)
125
+				),
126
+				'return_url'  => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
127
+			),
128
+		);
129 129
 		$this->_sortable_columns = array(
130 130
 			//true means its already sorted
131 131
 			'ATT_name' => array( 'ATT_name' => true ),
@@ -211,8 +211,8 @@  discard block
 block discarded – undo
211 211
 			if ( count( $this->_dtts_for_event ) > 1 ) {
212 212
 				$dtts[0] = __( 'To toggle check-in status, select a datetime.', 'event_espresso' );
213 213
 				foreach ( $this->_dtts_for_event as $dtt ) {
214
-                    $datetime_string = $dtt->name();
215
-                    $datetime_string = ! empty($datetime_string ) ? ' (' . $datetime_string . ')' : '';
214
+					$datetime_string = $dtt->name();
215
+					$datetime_string = ! empty($datetime_string ) ? ' (' . $datetime_string . ')' : '';
216 216
 					$datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time() . $datetime_string;
217 217
 					$dtts[ $dtt->ID() ] = $datetime_string;
218 218
 				}
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
 		$checkinstatus = $item->check_in_status_for_datetime( $this->_cur_dtt_id );
307 307
 		$nonce = wp_create_nonce( 'checkin_nonce' );
308 308
 		$toggle_active = ! empty ( $this->_cur_dtt_id )
309
-		                 && EE_Registry::instance()->CAP->current_user_can(
309
+						 && EE_Registry::instance()->CAP->current_user_can(
310 310
 			'ee_edit_checkin',
311 311
 			'espresso_registrations_toggle_checkin_status',
312 312
 			$item->ID()
@@ -315,11 +315,11 @@  discard block
 block discarded – undo
315 315
 			: '';
316 316
 		$mobile_view_content = ' <span class="show-on-mobile-view-only">' . $attendee_name . '</span>';
317 317
 		return '<span class="checkin-icons checkedin-status-' . $checkinstatus . $toggle_active . '"'
318
-		       . ' data-_regid="' . $item->ID() . '"'
319
-		       . ' data-dttid="' . $this->_cur_dtt_id . '"'
320
-		       . ' data-nonce="' . $nonce . '">'
321
-		       . '</span>'
322
-		       . $mobile_view_content;
318
+			   . ' data-_regid="' . $item->ID() . '"'
319
+			   . ' data-dttid="' . $this->_cur_dtt_id . '"'
320
+			   . ' data-nonce="' . $nonce . '">'
321
+			   . '</span>'
322
+			   . $mobile_view_content;
323 323
 	}
324 324
 
325 325
 
@@ -344,8 +344,8 @@  discard block
 block discarded – undo
344 344
 			'espresso_registrations_edit_attendee'
345 345
 		)
346 346
 			? '<a href="' . $edit_lnk_url . '" title="' . esc_attr__( 'Edit Contact', 'event_espresso' ) . '">'
347
-			    . $item->attendee()->full_name()
348
-			    . '</a>'
347
+				. $item->attendee()->full_name()
348
+				. '</a>'
349 349
 			: $item->attendee()->full_name();
350 350
 		$name_link .= $item->count() === 1
351 351
 			? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>	'
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
 			? $latest_related_datetime->ID()
381 381
 			: $DTT_ID;
382 382
 		if ( ! empty( $DTT_ID )
383
-		     && EE_Registry::instance()->CAP->current_user_can(
383
+			 && EE_Registry::instance()->CAP->current_user_can(
384 384
 				'ee_read_checkins',
385 385
 				'espresso_registrations_registration_checkins'
386 386
 			)
@@ -480,15 +480,15 @@  discard block
 block discarded – undo
480 480
 				) ? '
481 481
 				<span class="reg-pad-rght">
482 482
 					<a class="status-'
483
-				    . $item->transaction()->status_ID()
484
-				    . '" href="'
485
-				    . $view_txn_lnk_url
486
-				    . '"  title="'
487
-				    . esc_attr__( 'View Transaction', 'event_espresso' )
488
-				    . '">
483
+					. $item->transaction()->status_ID()
484
+					. '" href="'
485
+					. $view_txn_lnk_url
486
+					. '"  title="'
487
+					. esc_attr__( 'View Transaction', 'event_espresso' )
488
+					. '">
489 489
 						'
490
-				    . $item->transaction()->pretty_paid()
491
-				    . '
490
+					. $item->transaction()->pretty_paid()
491
+					. '
492 492
 					</a>
493 493
 				<span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
494 494
 			}
@@ -521,12 +521,12 @@  discard block
 block discarded – undo
521 521
 				'ee_read_transaction',
522 522
 				'espresso_transactions_view_transaction'
523 523
 			) ? '<a href="'
524
-			    . $view_txn_url
525
-			    . '" title="'
526
-			    . esc_attr__( 'View Transaction', 'event_espresso' )
527
-			    . '"><span class="reg-pad-rght">'
528
-			    . $txn_total
529
-			    . '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>';
524
+				. $view_txn_url
525
+				. '" title="'
526
+				. esc_attr__( 'View Transaction', 'event_espresso' )
527
+				. '"><span class="reg-pad-rght">'
528
+				. $txn_total
529
+				. '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>';
530 530
 		} else {
531 531
 			return '<span class="reg-pad-rght"></span>';
532 532
 		}
Please login to merge, or discard this patch.
Spacing   +114 added lines, -114 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1
-<?php if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
2
-	exit( 'No direct script access allowed' );
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -42,51 +42,51 @@  discard block
 block discarded – undo
42 42
 	 *
43 43
 	 * @param \Registrations_Admin_Page $admin_page
44 44
 	 */
45
-	public function __construct( $admin_page ) {
46
-		parent::__construct( $admin_page );
45
+	public function __construct($admin_page) {
46
+		parent::__construct($admin_page);
47 47
 		$this->_status = $this->_admin_page->get_registration_status_array();
48 48
 	}
49 49
 
50 50
 
51 51
 
52 52
 	protected function _setup_data() {
53
-		$this->_data = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees( $this->_per_page )
54
-			: $this->_admin_page->get_event_attendees( $this->_per_page, false, true );
53
+		$this->_data = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees($this->_per_page)
54
+			: $this->_admin_page->get_event_attendees($this->_per_page, false, true);
55 55
 		$this->_all_data_count = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees(
56 56
 			$this->_per_page,
57 57
 			true
58
-		) : $this->_admin_page->get_event_attendees( $this->_per_page, true, true );
58
+		) : $this->_admin_page->get_event_attendees($this->_per_page, true, true);
59 59
 	}
60 60
 
61 61
 
62 62
 
63 63
 	protected function _set_properties() {
64
-		$evt_id = isset( $this->_req_data['event_id'] ) ? $this->_req_data['event_id'] : null;
64
+		$evt_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null;
65 65
 		$this->_wp_list_args = array(
66
-			'singular' => __( 'registrant', 'event_espresso' ),
67
-			'plural'   => __( 'registrants', 'event_espresso' ),
66
+			'singular' => __('registrant', 'event_espresso'),
67
+			'plural'   => __('registrants', 'event_espresso'),
68 68
 			'ajax'     => true,
69 69
 			'screen'   => $this->_admin_page->get_current_screen()->id,
70 70
 		);
71 71
 		$columns = array();
72 72
 		//$columns['_Reg_Status'] = '';
73
-		if ( ! empty( $evt_id ) ) {
73
+		if ( ! empty($evt_id)) {
74 74
 			$columns['cb'] = '<input type="checkbox" />'; //Render a checkbox instead of text
75 75
 			$this->_has_checkbox_column = true;
76 76
 		}
77 77
 		$this->_columns = array(
78 78
 			'_REG_att_checked_in' => '<span class="dashicons dashicons-yes ee-icon-size-18"></span>',
79
-			'ATT_name'            => __( 'Registrant', 'event_espresso' ),
80
-			'ATT_email'           => __( 'Email Address', 'event_espresso' ),
81
-			'Event'               => __( 'Event', 'event_espresso' ),
82
-			'PRC_name'            => __( 'TKT Option', 'event_espresso' ),
83
-			'_REG_final_price'    => __( 'Price', 'event_espresso' ),
84
-			'TXN_paid'            => __( 'Paid', 'event_espresso' ),
85
-			'TXN_total'           => __( 'Total', 'event_espresso' ),
79
+			'ATT_name'            => __('Registrant', 'event_espresso'),
80
+			'ATT_email'           => __('Email Address', 'event_espresso'),
81
+			'Event'               => __('Event', 'event_espresso'),
82
+			'PRC_name'            => __('TKT Option', 'event_espresso'),
83
+			'_REG_final_price'    => __('Price', 'event_espresso'),
84
+			'TXN_paid'            => __('Paid', 'event_espresso'),
85
+			'TXN_total'           => __('Total', 'event_espresso'),
86 86
 		);
87
-		$this->_columns = array_merge( $columns, $this->_columns );
87
+		$this->_columns = array_merge($columns, $this->_columns);
88 88
 		$this->_primary_column = '_REG_att_checked_in';
89
-		if ( ! empty( $evt_id )
89
+		if ( ! empty($evt_id)
90 90
 		     && EE_Registry::instance()->CAP->current_user_can(
91 91
 				'ee_read_registrations',
92 92
 				'espresso_registrations_registrations_reports',
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
 					'extra_request' =>
100 100
 						array(
101 101
 							'EVT_ID'     => $evt_id,
102
-							'return_url' => urlencode( "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" ),
102
+							'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
103 103
 						),
104 104
 				),
105 105
 			);
@@ -128,11 +128,11 @@  discard block
 block discarded – undo
128 128
         );
129 129
 		$this->_sortable_columns = array(
130 130
 			//true means its already sorted
131
-			'ATT_name' => array( 'ATT_name' => true ),
132
-			'Event'    => array( 'Event.EVT.Name' => false ),
131
+			'ATT_name' => array('ATT_name' => true),
132
+			'Event'    => array('Event.EVT.Name' => false),
133 133
 		);
134 134
 		$this->_hidden_columns = array();
135
-		$this->_evt = EEM_Event::instance()->get_one_by_ID( $evt_id );
135
+		$this->_evt = EEM_Event::instance()->get_one_by_ID($evt_id);
136 136
 		$this->_dtts_for_event = $this->_evt instanceof EE_Event ? $this->_evt->datetimes_ordered() : array();
137 137
 	}
138 138
 
@@ -142,11 +142,11 @@  discard block
 block discarded – undo
142 142
 	 * @param \EE_Registration $item
143 143
 	 * @return string
144 144
 	 */
145
-	protected function _get_row_class( $item ) {
146
-		$class = parent::_get_row_class( $item );
145
+	protected function _get_row_class($item) {
146
+		$class = parent::_get_row_class($item);
147 147
 		//add status class
148
-		$class .= ' ee-status-strip reg-status-' . $item->status_ID();
149
-		if ( $this->_has_checkbox_column ) {
148
+		$class .= ' ee-status-strip reg-status-'.$item->status_ID();
149
+		if ($this->_has_checkbox_column) {
150 150
 			$class .= ' has-checkbox-column';
151 151
 		}
152 152
 		return $class;
@@ -160,61 +160,61 @@  discard block
 block discarded – undo
160 160
 	 */
161 161
 	protected function _get_table_filters() {
162 162
 		$filters = $where = array();
163
-		$current_EVT_ID = isset( $this->_req_data['event_id'] ) ? (int) $this->_req_data['event_id'] : 0;
164
-		if ( empty( $this->_dtts_for_event ) || count( $this->_dtts_for_event ) === 1 ) {
163
+		$current_EVT_ID = isset($this->_req_data['event_id']) ? (int) $this->_req_data['event_id'] : 0;
164
+		if (empty($this->_dtts_for_event) || count($this->_dtts_for_event) === 1) {
165 165
 			//this means we don't have an event so let's setup a filter dropdown for all the events to select
166 166
 			//note possible capability restrictions
167
-			if ( ! EE_Registry::instance()->CAP->current_user_can( 'ee_read_private_events', 'get_events' ) ) {
168
-				$where['status**'] = array( '!=', 'private' );
167
+			if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
168
+				$where['status**'] = array('!=', 'private');
169 169
 			}
170
-			if ( ! EE_Registry::instance()->CAP->current_user_can( 'ee_read_others_events', 'get_events' ) ) {
170
+			if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
171 171
 				$where['EVT_wp_user'] = get_current_user_id();
172 172
 			}
173 173
 			$events = EEM_Event::instance()->get_all(
174 174
 				array(
175 175
 					$where,
176
-					'order_by' => array( 'Datetime.DTT_EVT_start' => 'DESC' ),
176
+					'order_by' => array('Datetime.DTT_EVT_start' => 'DESC'),
177 177
 				)
178 178
 			);
179 179
 			$evts[] = array(
180 180
 				'id'   => 0,
181
-				'text' => __( 'To toggle Check-in status, select an event', 'event_espresso' ),
181
+				'text' => __('To toggle Check-in status, select an event', 'event_espresso'),
182 182
 			);
183 183
 			$checked = 'checked';
184 184
 			/** @var EE_Event $evt */
185
-			foreach ( $events as $evt ) {
185
+			foreach ($events as $evt) {
186 186
 				//any registrations for this event?
187
-				if ( ! $evt->get_count_of_all_registrations() ) {
187
+				if ( ! $evt->get_count_of_all_registrations()) {
188 188
 					continue;
189 189
 				}
190 190
 				$evts[] = array(
191 191
 					'id'    => $evt->ID(),
192
-					'text'  => $evt->get( 'EVT_name' ),
192
+					'text'  => $evt->get('EVT_name'),
193 193
 					'class' => $evt->is_expired() ? 'ee-expired-event' : '',
194 194
 				);
195
-				if ( $evt->ID() === $current_EVT_ID && $evt->is_expired() ) {
195
+				if ($evt->ID() === $current_EVT_ID && $evt->is_expired()) {
196 196
 					$checked = '';
197 197
 				}
198 198
 			}
199 199
 			$event_filter = '<div class="ee-event-filter">';
200
-			$event_filter .= EEH_Form_Fields::select_input( 'event_id', $evts, $current_EVT_ID );
200
+			$event_filter .= EEH_Form_Fields::select_input('event_id', $evts, $current_EVT_ID);
201 201
 			$event_filter .= '<span class="ee-event-filter-toggle">';
202
-			$event_filter .= '<input type="checkbox" id="js-ee-hide-expired-events" ' . $checked . '> ';
203
-			$event_filter .= __( 'Hide Expired Events', 'event_espresso' );
202
+			$event_filter .= '<input type="checkbox" id="js-ee-hide-expired-events" '.$checked.'> ';
203
+			$event_filter .= __('Hide Expired Events', 'event_espresso');
204 204
 			$event_filter .= '</span>';
205 205
 			$event_filter .= '</div>';
206 206
 			$filters[] = $event_filter;
207 207
 		}
208
-		if ( ! empty( $this->_dtts_for_event ) ) {
208
+		if ( ! empty($this->_dtts_for_event)) {
209 209
 			//DTT datetimes filter
210
-			$this->_cur_dtt_id = isset( $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : 0;
211
-			if ( count( $this->_dtts_for_event ) > 1 ) {
212
-				$dtts[0] = __( 'To toggle check-in status, select a datetime.', 'event_espresso' );
213
-				foreach ( $this->_dtts_for_event as $dtt ) {
210
+			$this->_cur_dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0;
211
+			if (count($this->_dtts_for_event) > 1) {
212
+				$dtts[0] = __('To toggle check-in status, select a datetime.', 'event_espresso');
213
+				foreach ($this->_dtts_for_event as $dtt) {
214 214
                     $datetime_string = $dtt->name();
215
-                    $datetime_string = ! empty($datetime_string ) ? ' (' . $datetime_string . ')' : '';
216
-					$datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time() . $datetime_string;
217
-					$dtts[ $dtt->ID() ] = $datetime_string;
215
+                    $datetime_string = ! empty($datetime_string) ? ' ('.$datetime_string.')' : '';
216
+					$datetime_string = $dtt->start_date_and_time().' - '.$dtt->end_date_and_time().$datetime_string;
217
+					$dtts[$dtt->ID()] = $datetime_string;
218 218
 				}
219 219
 				$input = new EE_Select_Input(
220 220
 					$dtts,
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
 					)
226 226
 				);
227 227
 				$filters[] = $input->get_html_for_input();
228
-				$filters[] = '<input type="hidden" name="event_id" value="' . $current_EVT_ID . '">';
228
+				$filters[] = '<input type="hidden" name="event_id" value="'.$current_EVT_ID.'">';
229 229
 			}
230 230
 		}
231 231
 		return $filters;
@@ -244,22 +244,22 @@  discard block
 block discarded – undo
244 244
 	 * @throws \EE_Error
245 245
 	 */
246 246
 	protected function _get_total_event_attendees() {
247
-		$EVT_ID = isset( $this->_req_data['event_id'] ) ? absint( $this->_req_data['event_id'] ) : false;
247
+		$EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
248 248
 		$DTT_ID = $this->_cur_dtt_id;
249 249
 		$query_params = array();
250
-		if ( $EVT_ID ) {
250
+		if ($EVT_ID) {
251 251
 			$query_params[0]['EVT_ID'] = $EVT_ID;
252 252
 		}
253 253
 		//if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
254
-		if ( $DTT_ID ) {
254
+		if ($DTT_ID) {
255 255
 			$query_params[0]['Ticket.Datetime.DTT_ID'] = $DTT_ID;
256 256
 		}
257 257
 		$status_ids_array = apply_filters(
258 258
 			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
259
-			array( EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved )
259
+			array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved)
260 260
 		);
261
-		$query_params[0]['STS_ID'] = array( 'IN', $status_ids_array );
262
-		return EEM_Registration::instance()->count( $query_params );
261
+		$query_params[0]['STS_ID'] = array('IN', $status_ids_array);
262
+		return EEM_Registration::instance()->count($query_params);
263 263
 	}
264 264
 
265 265
 
@@ -268,8 +268,8 @@  discard block
 block discarded – undo
268 268
 	 * @param \EE_Registration $item
269 269
 	 * @return string
270 270
 	 */
271
-	public function column__Reg_Status( EE_Registration $item ) {
272
-		return '<span class="ee-status-strip ee-status-strip-td reg-status-' . $item->status_ID() . '"></span>';
271
+	public function column__Reg_Status(EE_Registration $item) {
272
+		return '<span class="ee-status-strip ee-status-strip-td reg-status-'.$item->status_ID().'"></span>';
273 273
 	}
274 274
 
275 275
 
@@ -279,8 +279,8 @@  discard block
 block discarded – undo
279 279
 	 * @return string
280 280
 	 * @throws \EE_Error
281 281
 	 */
282
-	public function column_cb( $item ) {
283
-		return sprintf( '<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID() );
282
+	public function column_cb($item) {
283
+		return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
284 284
 	}
285 285
 
286 286
 
@@ -292,20 +292,20 @@  discard block
 block discarded – undo
292 292
 	 * @return string
293 293
 	 * @throws \EE_Error
294 294
 	 */
295
-	public function column__REG_att_checked_in( EE_Registration $item ) {
295
+	public function column__REG_att_checked_in(EE_Registration $item) {
296 296
 		$attendee = $item->attendee();
297 297
 		$attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : '';
298 298
 
299
-		if ( $this->_cur_dtt_id === 0 && count( $this->_dtts_for_event ) === 1 ) {
299
+		if ($this->_cur_dtt_id === 0 && count($this->_dtts_for_event) === 1) {
300 300
 			$latest_related_datetime = $item->get_latest_related_datetime();
301
-			if ( $latest_related_datetime instanceof EE_Datetime ) {
301
+			if ($latest_related_datetime instanceof EE_Datetime) {
302 302
 				$this->_cur_dtt_id = $latest_related_datetime->ID();
303 303
 			}
304 304
 		}
305 305
 
306
-		$checkinstatus = $item->check_in_status_for_datetime( $this->_cur_dtt_id );
307
-		$nonce = wp_create_nonce( 'checkin_nonce' );
308
-		$toggle_active = ! empty ( $this->_cur_dtt_id )
306
+		$checkinstatus = $item->check_in_status_for_datetime($this->_cur_dtt_id);
307
+		$nonce = wp_create_nonce('checkin_nonce');
308
+		$toggle_active = ! empty ($this->_cur_dtt_id)
309 309
 		                 && EE_Registry::instance()->CAP->current_user_can(
310 310
 			'ee_edit_checkin',
311 311
 			'espresso_registrations_toggle_checkin_status',
@@ -313,11 +313,11 @@  discard block
 block discarded – undo
313 313
 		)
314 314
 			? ' clickable trigger-checkin'
315 315
 			: '';
316
-		$mobile_view_content = ' <span class="show-on-mobile-view-only">' . $attendee_name . '</span>';
317
-		return '<span class="checkin-icons checkedin-status-' . $checkinstatus . $toggle_active . '"'
318
-		       . ' data-_regid="' . $item->ID() . '"'
319
-		       . ' data-dttid="' . $this->_cur_dtt_id . '"'
320
-		       . ' data-nonce="' . $nonce . '">'
316
+		$mobile_view_content = ' <span class="show-on-mobile-view-only">'.$attendee_name.'</span>';
317
+		return '<span class="checkin-icons checkedin-status-'.$checkinstatus.$toggle_active.'"'
318
+		       . ' data-_regid="'.$item->ID().'"'
319
+		       . ' data-dttid="'.$this->_cur_dtt_id.'"'
320
+		       . ' data-nonce="'.$nonce.'">'
321 321
 		       . '</span>'
322 322
 		       . $mobile_view_content;
323 323
 	}
@@ -329,21 +329,21 @@  discard block
 block discarded – undo
329 329
 	 * @return mixed|string|void
330 330
 	 * @throws \EE_Error
331 331
 	 */
332
-	public function column_ATT_name( EE_Registration $item ) {
332
+	public function column_ATT_name(EE_Registration $item) {
333 333
 		$attendee = $item->attendee();
334
-		if ( ! $attendee instanceof EE_Attendee ) {
335
-			return __( 'No contact record for this registration.', 'event_espresso' );
334
+		if ( ! $attendee instanceof EE_Attendee) {
335
+			return __('No contact record for this registration.', 'event_espresso');
336 336
 		}
337 337
 		// edit attendee link
338 338
 		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
339
-			array( 'action' => 'view_registration', '_REG_ID' => $item->ID() ),
339
+			array('action' => 'view_registration', '_REG_ID' => $item->ID()),
340 340
 			REG_ADMIN_URL
341 341
 		);
342 342
 		$name_link = EE_Registry::instance()->CAP->current_user_can(
343 343
 			'ee_edit_contacts',
344 344
 			'espresso_registrations_edit_attendee'
345 345
 		)
346
-			? '<a href="' . $edit_lnk_url . '" title="' . esc_attr__( 'Edit Contact', 'event_espresso' ) . '">'
346
+			? '<a href="'.$edit_lnk_url.'" title="'.esc_attr__('Edit Contact', 'event_espresso').'">'
347 347
 			    . $item->attendee()->full_name()
348 348
 			    . '</a>'
349 349
 			: $item->attendee()->full_name();
@@ -351,10 +351,10 @@  discard block
 block discarded – undo
351 351
 			? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>	'
352 352
 			: '';
353 353
 		//add group details
354
-		$name_link .= '&nbsp;' . sprintf( __( '(%s of %s)', 'event_espresso' ), $item->count(), $item->group_size() );
354
+		$name_link .= '&nbsp;'.sprintf(__('(%s of %s)', 'event_espresso'), $item->count(), $item->group_size());
355 355
 		//add regcode
356 356
 		$link = EE_Admin_Page::add_query_args_and_nonce(
357
-			array( 'action' => 'view_registration', '_REG_ID' => $item->ID() ),
357
+			array('action' => 'view_registration', '_REG_ID' => $item->ID()),
358 358
 			REG_ADMIN_URL
359 359
 		);
360 360
 		$name_link .= '<br>';
@@ -363,44 +363,44 @@  discard block
 block discarded – undo
363 363
 			'view_registration',
364 364
 			$item->ID()
365 365
 		)
366
-			? '<a href="' . $link . '" title="' . esc_attr__( 'View Registration Details', 'event_espresso' ) . '">'
366
+			? '<a href="'.$link.'" title="'.esc_attr__('View Registration Details', 'event_espresso').'">'
367 367
 			  . $item->reg_code()
368 368
 			  . '</a>'
369 369
 			: $item->reg_code();
370 370
 		//status
371 371
 		$name_link .= '<br><span class="ee-status-text-small">';
372
-		$name_link .= EEH_Template::pretty_status( $item->status_ID(), false, 'sentence' );
372
+		$name_link .= EEH_Template::pretty_status($item->status_ID(), false, 'sentence');
373 373
 		$name_link .= '</span>';
374 374
 		$actions = array();
375 375
 		$DTT_ID = $this->_cur_dtt_id;
376
-		$latest_related_datetime = empty( $DTT_ID ) && ! empty( $this->_req_data['event_id'] ) && $item instanceof EE_Registration
376
+		$latest_related_datetime = empty($DTT_ID) && ! empty($this->_req_data['event_id']) && $item instanceof EE_Registration
377 377
 			? $item->get_latest_related_datetime()
378 378
 			: null;
379 379
 		$DTT_ID = $latest_related_datetime instanceof EE_Datetime
380 380
 			? $latest_related_datetime->ID()
381 381
 			: $DTT_ID;
382
-		if ( ! empty( $DTT_ID )
382
+		if ( ! empty($DTT_ID)
383 383
 		     && EE_Registry::instance()->CAP->current_user_can(
384 384
 				'ee_read_checkins',
385 385
 				'espresso_registrations_registration_checkins'
386 386
 			)
387 387
 		) {
388 388
 			$checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
389
-				array( 'action' => 'registration_checkins', '_REGID' => $item->ID(), 'DTT_ID' => $DTT_ID )
389
+				array('action' => 'registration_checkins', '_REGID' => $item->ID(), 'DTT_ID' => $DTT_ID)
390 390
 			);
391 391
 			// get the timestamps for this registration's checkins, related to the selected datetime
392
-			$timestamps = $item->get_many_related( 'Checkin', array( array( 'DTT_ID' => $DTT_ID ) ) );
393
-			if( ! empty( $timestamps ) ) {
392
+			$timestamps = $item->get_many_related('Checkin', array(array('DTT_ID' => $DTT_ID)));
393
+			if ( ! empty($timestamps)) {
394 394
 				// show only the last timestamp
395
-				$last_timestamp = end( $timestamps )->get_datetime( 'CHK_timestamp' );
396
-				$actions['checkin'] = '<a href="' . $checkin_list_url . '" title="' . esc_attr__(
395
+				$last_timestamp = end($timestamps)->get_datetime('CHK_timestamp');
396
+				$actions['checkin'] = '<a href="'.$checkin_list_url.'" title="'.esc_attr__(
397 397
 						'View this registrant\'s check-ins/checkouts for the datetime',
398 398
 						'event_espresso'
399
-					) . '">' . $last_timestamp . '</a>';
399
+					).'">'.$last_timestamp.'</a>';
400 400
 			}
401 401
 		} 
402
-		return ( ! empty( $DTT_ID ) && ! empty( $timestamps ) ) 
403
-			? sprintf( '%1$s %2$s', $name_link, $this->row_actions( $actions, true ) ) 
402
+		return ( ! empty($DTT_ID) && ! empty($timestamps)) 
403
+			? sprintf('%1$s %2$s', $name_link, $this->row_actions($actions, true)) 
404 404
 			: $name_link;
405 405
 	}
406 406
 
@@ -410,7 +410,7 @@  discard block
 block discarded – undo
410 410
 	 * @param \EE_Registration $item
411 411
 	 * @return string
412 412
 	 */
413
-	public function column_ATT_email( EE_Registration $item ) {
413
+	public function column_ATT_email(EE_Registration $item) {
414 414
 		$attendee = $item->attendee();
415 415
 		return $attendee instanceof EE_Attendee ? $attendee->email() : '';
416 416
 	}
@@ -422,22 +422,22 @@  discard block
 block discarded – undo
422 422
 	 * @return bool|string
423 423
 	 * @throws \EE_Error
424 424
 	 */
425
-	public function column_Event( EE_Registration $item ) {
425
+	public function column_Event(EE_Registration $item) {
426 426
 		try {
427 427
 			$event = $this->_evt instanceof EE_Event ? $this->_evt : $item->event();
428 428
 			$chkin_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
429
-				array( 'action' => 'event_registrations', 'event_id' => $event->ID() ),
429
+				array('action' => 'event_registrations', 'event_id' => $event->ID()),
430 430
 				REG_ADMIN_URL
431 431
 			);
432 432
 			$event_label = EE_Registry::instance()->CAP->current_user_can(
433 433
 				'ee_read_checkins',
434 434
 				'espresso_registrations_registration_checkins'
435
-			) ? '<a href="' . $chkin_lnk_url . '" title="' . esc_attr__(
435
+			) ? '<a href="'.$chkin_lnk_url.'" title="'.esc_attr__(
436 436
 					'View Checkins for this Event',
437 437
 					'event_espresso'
438
-				) . '">' . $event->name() . '</a>' : $event->name();
439
-		} catch ( \EventEspresso\core\exceptions\EntityNotFoundException $e ) {
440
-			$event_label = esc_html__( 'Unknown', 'event_espresso' );
438
+				).'">'.$event->name().'</a>' : $event->name();
439
+		} catch (\EventEspresso\core\exceptions\EntityNotFoundException $e) {
440
+			$event_label = esc_html__('Unknown', 'event_espresso');
441 441
 		}
442 442
 		return $event_label;
443 443
 	}
@@ -448,8 +448,8 @@  discard block
 block discarded – undo
448 448
 	 * @param \EE_Registration $item
449 449
 	 * @return mixed|string|void
450 450
 	 */
451
-	public function column_PRC_name( EE_Registration $item ) {
452
-		return $item->ticket() instanceof EE_Ticket ? $item->ticket()->name() : __( "Unknown", "event_espresso" );
451
+	public function column_PRC_name(EE_Registration $item) {
452
+		return $item->ticket() instanceof EE_Ticket ? $item->ticket()->name() : __("Unknown", "event_espresso");
453 453
 	}
454 454
 
455 455
 
@@ -460,8 +460,8 @@  discard block
 block discarded – undo
460 460
 	 * @param \EE_Registration $item
461 461
 	 * @return string
462 462
 	 */
463
-	public function column__REG_final_price( EE_Registration $item ) {
464
-		return '<span class="reg-pad-rght">' . ' ' . $item->pretty_final_price() . '</span>';
463
+	public function column__REG_final_price(EE_Registration $item) {
464
+		return '<span class="reg-pad-rght">'.' '.$item->pretty_final_price().'</span>';
465 465
 	}
466 466
 
467 467
 
@@ -473,13 +473,13 @@  discard block
 block discarded – undo
473 473
 	 * @return string
474 474
 	 * @throws \EE_Error
475 475
 	 */
476
-	public function column_TXN_paid( EE_Registration $item ) {
477
-		if ( $item->count() === 1 ) {
478
-			if ( $item->transaction()->paid() >= $item->transaction()->total() ) {
476
+	public function column_TXN_paid(EE_Registration $item) {
477
+		if ($item->count() === 1) {
478
+			if ($item->transaction()->paid() >= $item->transaction()->total()) {
479 479
 				return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
480 480
 			} else {
481 481
 				$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
482
-					array( 'action' => 'view_transaction', 'TXN_ID' => $item->transaction_ID() ),
482
+					array('action' => 'view_transaction', 'TXN_ID' => $item->transaction_ID()),
483 483
 					TXN_ADMIN_URL
484 484
 				);
485 485
 				return EE_Registry::instance()->CAP->current_user_can(
@@ -492,13 +492,13 @@  discard block
 block discarded – undo
492 492
 				    . '" href="'
493 493
 				    . $view_txn_lnk_url
494 494
 				    . '"  title="'
495
-				    . esc_attr__( 'View Transaction', 'event_espresso' )
495
+				    . esc_attr__('View Transaction', 'event_espresso')
496 496
 				    . '">
497 497
 						'
498 498
 				    . $item->transaction()->pretty_paid()
499 499
 				    . '
500 500
 					</a>
501
-				<span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
501
+				<span>' : '<span class="reg-pad-rght">'.$item->transaction()->pretty_paid().'</span>';
502 502
 			}
503 503
 		} else {
504 504
 			return '<span class="reg-pad-rght"></span>';
@@ -514,13 +514,13 @@  discard block
 block discarded – undo
514 514
 	 * @return string
515 515
 	 * @throws \EE_Error
516 516
 	 */
517
-	public function column_TXN_total( EE_Registration $item ) {
517
+	public function column_TXN_total(EE_Registration $item) {
518 518
 		$txn = $item->transaction();
519
-		$view_txn_url = add_query_arg( array( 'action' => 'view_transaction', 'TXN_ID' => $txn->ID() ), TXN_ADMIN_URL );
520
-		if ( $item->get( 'REG_count' ) === 1 ) {
519
+		$view_txn_url = add_query_arg(array('action' => 'view_transaction', 'TXN_ID' => $txn->ID()), TXN_ADMIN_URL);
520
+		if ($item->get('REG_count') === 1) {
521 521
 			$line_total_obj = $txn->total_line_item();
522 522
 			$txn_total = $line_total_obj instanceof EE_Line_Item
523
-				? $line_total_obj->get_pretty( 'LIN_total' )
523
+				? $line_total_obj->get_pretty('LIN_total')
524 524
 				: __(
525 525
 					'View Transaction',
526 526
 					'event_espresso'
@@ -531,10 +531,10 @@  discard block
 block discarded – undo
531 531
 			) ? '<a href="'
532 532
 			    . $view_txn_url
533 533
 			    . '" title="'
534
-			    . esc_attr__( 'View Transaction', 'event_espresso' )
534
+			    . esc_attr__('View Transaction', 'event_espresso')
535 535
 			    . '"><span class="reg-pad-rght">'
536 536
 			    . $txn_total
537
-			    . '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>';
537
+			    . '</span></a>' : '<span class="reg-pad-rght">'.$txn_total.'</span>';
538 538
 		} else {
539 539
 			return '<span class="reg-pad-rght"></span>';
540 540
 		}
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   +1336 added lines, -1336 removed lines patch added patch discarded remove patch
@@ -16,1372 +16,1372 @@
 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 = $this->_dependency_map->get_alias($class_name);
590
-        if ( ! class_exists($class_name)) {
591
-            // maybe the class is registered with a preceding \
592
-            $class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
593
-            // still doesn't exist ?
594
-            if ( ! class_exists($class_name)) {
595
-                return null;
596
-            }
597
-        }
598
-        // if we're only loading the class and it already exists, then let's just return true immediately
599
-        if ($load_only) {
600
-            return true;
601
-        }
602
-        $addon = $addon ? 'addon' : '';
603
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
604
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
605
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
606
-        if ($this->_cache_on && $cache && ! $load_only) {
607
-            // return object if it's already cached
608
-            $cached_class = $this->_get_cached_class($class_name, $addon);
609
-            if ($cached_class !== null) {
610
-                return $cached_class;
611
-            }
612
-        }
613
-        // instantiate the requested object
614
-        $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
615
-        if ($this->_cache_on && $cache) {
616
-            // save it for later... kinda like gum  { : $
617
-            $this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
618
-        }
619
-        $this->_cache_on = true;
620
-        return $class_obj;
621
-    }
622
-
623
-
624
-
625
-    /**
626
-     * instantiates, caches, and injects dependencies for classes
627
-     *
628
-     * @param array       $file_paths   an array of paths to folders to look in
629
-     * @param string      $class_prefix EE  or EEM or... ???
630
-     * @param bool|string $class_name   $class name
631
-     * @param string      $type         file type - core? class? helper? model?
632
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
633
-     * @param bool        $from_db      some classes are instantiated from the db
634
-     *                                  and thus call a different method to instantiate
635
-     * @param bool        $cache        whether to cache the instantiated object for reuse
636
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
637
-     * @return null|object|bool         null = failure to load or instantiate class object.
638
-     *                                  object = class loaded and instantiated successfully.
639
-     *                                  bool = fail or success when $load_only is true
640
-     */
641
-    protected function _load(
642
-        $file_paths = array(),
643
-        $class_prefix = 'EE_',
644
-        $class_name = false,
645
-        $type = 'class',
646
-        $arguments = array(),
647
-        $from_db = false,
648
-        $cache = true,
649
-        $load_only = false
650
-    ) {
651
-        // strip php file extension
652
-        $class_name = str_replace('.php', '', trim($class_name));
653
-        // does the class have a prefix ?
654
-        if ( ! empty($class_prefix) && $class_prefix != 'addon') {
655
-            // make sure $class_prefix is uppercase
656
-            $class_prefix = strtoupper(trim($class_prefix));
657
-            // add class prefix ONCE!!!
658
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
659
-        }
660
-        $class_name = $this->_dependency_map->get_alias($class_name);
661
-        $class_exists = class_exists($class_name);
662
-        // if we're only loading the class and it already exists, then let's just return true immediately
663
-        if ($load_only && $class_exists) {
664
-            return true;
665
-        }
666
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
667
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
668
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
669
-        if ($this->_cache_on && $cache && ! $load_only) {
670
-            // return object if it's already cached
671
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix);
672
-            if ($cached_class !== null) {
673
-                return $cached_class;
674
-            }
675
-        }
676
-        // if the class doesn't already exist.. then we need to try and find the file and load it
677
-        if ( ! $class_exists) {
678
-            // get full path to file
679
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
680
-            // load the file
681
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
682
-            // if loading failed, or we are only loading a file but NOT instantiating an object
683
-            if ( ! $loaded || $load_only) {
684
-                // return boolean if only loading, or null if an object was expected
685
-                return $load_only ? $loaded : null;
686
-            }
687
-        }
688
-        // instantiate the requested object
689
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
690
-        if ($this->_cache_on && $cache) {
691
-            // save it for later... kinda like gum  { : $
692
-            $this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
693
-        }
694
-        $this->_cache_on = true;
695
-        return $class_obj;
696
-    }
697
-
698
-
699
-
700
-    /**
701
-     * _get_cached_class
702
-     * attempts to find a cached version of the requested class
703
-     * by looking in the following places:
704
-     *        $this->{$class_abbreviation}            ie:    $this->CART
705
-     *        $this->{$class_name}                        ie:    $this->Some_Class
706
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
707
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
708
-     *
709
-     * @access protected
710
-     * @param string $class_name
711
-     * @param string $class_prefix
712
-     * @return mixed
713
-     */
714
-    protected function _get_cached_class($class_name, $class_prefix = '')
715
-    {
716
-        if (isset($this->_class_abbreviations[$class_name])) {
717
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
718
-        } else {
719
-            // have to specify something, but not anything that will conflict
720
-            $class_abbreviation = 'FANCY_BATMAN_PANTS';
721
-        }
722
-        // check if class has already been loaded, and return it if it has been
723
-        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
724
-            return $this->{$class_abbreviation};
725
-        } else if (isset ($this->{$class_name})) {
726
-            return $this->{$class_name};
727
-        } else if (isset ($this->LIB->{$class_name})) {
728
-            return $this->LIB->{$class_name};
729
-        } else if ($class_prefix == 'addon' && isset ($this->addons->{$class_name})) {
730
-            return $this->addons->{$class_name};
731
-        }
732
-        return null;
733
-    }
734
-
735
-
736
-
737
-    /**
738
-     * _resolve_path
739
-     * attempts to find a full valid filepath for the requested class.
740
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
741
-     * then returns that path if the target file has been found and is readable
742
-     *
743
-     * @access protected
744
-     * @param string $class_name
745
-     * @param string $type
746
-     * @param array  $file_paths
747
-     * @return string | bool
748
-     */
749
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
750
-    {
751
-        // make sure $file_paths is an array
752
-        $file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
753
-        // cycle thru paths
754
-        foreach ($file_paths as $key => $file_path) {
755
-            // convert all separators to proper DS, if no filepath, then use EE_CLASSES
756
-            $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
757
-            // prep file type
758
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
759
-            // build full file path
760
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
761
-            //does the file exist and can be read ?
762
-            if (is_readable($file_paths[$key])) {
763
-                return $file_paths[$key];
764
-            }
765
-        }
766
-        return false;
767
-    }
768
-
769
-
770
-
771
-    /**
772
-     * _require_file
773
-     * basically just performs a require_once()
774
-     * but with some error handling
775
-     *
776
-     * @access protected
777
-     * @param  string $path
778
-     * @param  string $class_name
779
-     * @param  string $type
780
-     * @param  array  $file_paths
781
-     * @return boolean
782
-     * @throws \EE_Error
783
-     */
784
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
785
-    {
786
-        // don't give up! you gotta...
787
-        try {
788
-            //does the file exist and can it be read ?
789
-            if ( ! $path) {
790
-                // so sorry, can't find the file
791
-                throw new EE_Error (
792
-                    sprintf(
793
-                        __('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'),
794
-                        trim($type, '.'),
795
-                        $class_name,
796
-                        '<br />' . implode(',<br />', $file_paths)
797
-                    )
798
-                );
799
-            }
800
-            // get the file
801
-            require_once($path);
802
-            // if the class isn't already declared somewhere
803
-            if (class_exists($class_name, false) === false) {
804
-                // so sorry, not a class
805
-                throw new EE_Error(
806
-                    sprintf(
807
-                        __('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
808
-                        $type,
809
-                        $path,
810
-                        $class_name
811
-                    )
812
-                );
813
-            }
814
-        } catch (EE_Error $e) {
815
-            $e->get_error();
816
-            return false;
817
-        }
818
-        return true;
819
-    }
820
-
821
-
822
-
823
-    /**
824
-     * _create_object
825
-     * Attempts to instantiate the requested class via any of the
826
-     * commonly used instantiation methods employed throughout EE.
827
-     * The priority for instantiation is as follows:
828
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
829
-     *        - model objects via their 'new_instance_from_db' method
830
-     *        - model objects via their 'new_instance' method
831
-     *        - "singleton" classes" via their 'instance' method
832
-     *    - standard instantiable classes via their __constructor
833
-     * Prior to instantiation, if the classname exists in the dependency_map,
834
-     * then the constructor for the requested class will be examined to determine
835
-     * if any dependencies exist, and if they can be injected.
836
-     * If so, then those classes will be added to the array of arguments passed to the constructor
837
-     *
838
-     * @access protected
839
-     * @param string $class_name
840
-     * @param array  $arguments
841
-     * @param string $type
842
-     * @param bool   $from_db
843
-     * @return null | object
844
-     * @throws \EE_Error
845
-     */
846
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
847
-    {
848
-        $class_obj = null;
849
-        $instantiation_mode = '0) none';
850
-        // don't give up! you gotta...
851
-        try {
852
-            // create reflection
853
-            $reflector = $this->get_ReflectionClass($class_name);
854
-            // make sure arguments are an array
855
-            $arguments = is_array($arguments) ? $arguments : array($arguments);
856
-            // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
857
-            // else wrap it in an additional array so that it doesn't get split into multiple parameters
858
-            $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
859
-                ? $arguments
860
-                : array($arguments);
861
-            // attempt to inject dependencies ?
862
-            if ($this->_dependency_map->has($class_name)) {
863
-                $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
864
-            }
865
-            // instantiate the class if possible
866
-            if ($reflector->isAbstract()) {
867
-                // nothing to instantiate, loading file was enough
868
-                // does not throw an exception so $instantiation_mode is unused
869
-                // $instantiation_mode = "1) no constructor abstract class";
870
-                $class_obj = true;
871
-            } else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
872
-                // no constructor = static methods only... nothing to instantiate, loading file was enough
873
-                $instantiation_mode = "2) no constructor but instantiable";
874
-                $class_obj = $reflector->newInstance();
875
-            } else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
876
-                $instantiation_mode = "3) new_instance_from_db()";
877
-                $class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
878
-            } else if (method_exists($class_name, 'new_instance')) {
879
-                $instantiation_mode = "4) new_instance()";
880
-                $class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
881
-            } else if (method_exists($class_name, 'instance')) {
882
-                $instantiation_mode = "5) instance()";
883
-                $class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
884
-            } else if ($reflector->isInstantiable()) {
885
-                $instantiation_mode = "6) constructor";
886
-                $class_obj = $reflector->newInstanceArgs($arguments);
887
-            } else {
888
-                // heh ? something's not right !
889
-                throw new EE_Error(
890
-                    sprintf(
891
-                        __('The %s file %s could not be instantiated.', 'event_espresso'),
892
-                        $type,
893
-                        $class_name
894
-                    )
895
-                );
896
-            }
897
-        } catch (Exception $e) {
898
-            if ( ! $e instanceof EE_Error) {
899
-                $e = new EE_Error(
900
-                    sprintf(
901
-                        __('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
902
-                        $class_name,
903
-                        '<br />',
904
-                        $e->getMessage(),
905
-                        $instantiation_mode
906
-                    )
907
-                );
908
-            }
909
-            $e->get_error();
910
-        }
911
-        return $class_obj;
912
-    }
913
-
914
-
915
-
916
-    /**
917
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
918
-     * @param array $array
919
-     * @return bool
920
-     */
921
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
922
-    {
923
-        return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
924
-    }
925
-
926
-
927
-
928
-    /**
929
-     * getReflectionClass
930
-     * checks if a ReflectionClass object has already been generated for a class
931
-     * and returns that instead of creating a new one
932
-     *
933
-     * @access public
934
-     * @param string $class_name
935
-     * @return ReflectionClass
936
-     */
937
-    public function get_ReflectionClass($class_name)
938
-    {
939
-        if (
940
-            ! isset($this->_reflectors[$class_name])
941
-            || ! $this->_reflectors[$class_name] instanceof ReflectionClass
942
-        ) {
943
-            $this->_reflectors[$class_name] = new ReflectionClass($class_name);
944
-        }
945
-        return $this->_reflectors[$class_name];
946
-    }
947
-
948
-
949
-
950
-    /**
951
-     * _resolve_dependencies
952
-     * examines the constructor for the requested class to determine
953
-     * if any dependencies exist, and if they can be injected.
954
-     * If so, then those classes will be added to the array of arguments passed to the constructor
955
-     * PLZ NOTE: this is achieved by type hinting the constructor params
956
-     * For example:
957
-     *        if attempting to load a class "Foo" with the following constructor:
958
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
959
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
960
-     *        but only IF they are NOT already present in the incoming arguments array,
961
-     *        and the correct classes can be loaded
962
-     *
963
-     * @access protected
964
-     * @param ReflectionClass $reflector
965
-     * @param string          $class_name
966
-     * @param array           $arguments
967
-     * @return array
968
-     * @throws \ReflectionException
969
-     */
970
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
971
-    {
972
-        // let's examine the constructor
973
-        $constructor = $reflector->getConstructor();
974
-        // whu? huh? nothing?
975
-        if ( ! $constructor) {
976
-            return $arguments;
977
-        }
978
-        // get constructor parameters
979
-        $params = $constructor->getParameters();
980
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
981
-        $argument_keys = array_keys($arguments);
982
-        // now loop thru all of the constructors expected parameters
983
-        foreach ($params as $index => $param) {
984
-            // is this a dependency for a specific class ?
985
-            $param_class = $param->getClass() ? $param->getClass()->name : null;
986
-            if (
987
-                // param is not even a class
988
-                empty($param_class)
989
-                // and something already exists in the incoming arguments for this param
990
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
991
-            ) {
992
-                // so let's skip this argument and move on to the next
993
-                continue;
994
-            } else if (
995
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
996
-                ! empty($param_class)
997
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
998
-                && $arguments[$argument_keys[$index]] instanceof $param_class
999
-            ) {
1000
-                // skip this argument and move on to the next
1001
-                continue;
1002
-            } else if (
1003
-                // parameter is type hinted as a class, and should be injected
1004
-                ! empty($param_class)
1005
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1006
-            ) {
1007
-                $arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1008
-            } else {
1009
-                try {
1010
-                    $arguments[$index] = $param->getDefaultValue();
1011
-                } catch (ReflectionException $e) {
1012
-                    throw new ReflectionException(
1013
-                        sprintf(
1014
-                            __('%1$s for parameter "$%2$s"', 'event_espresso'),
1015
-                            $e->getMessage(),
1016
-                            $param->getName()
1017
-                        )
1018
-                    );
1019
-                }
1020
-            }
1021
-        }
1022
-        return $arguments;
1023
-    }
1024
-
1025
-
1026
-
1027
-    /**
1028
-     * @access protected
1029
-     * @param string $class_name
1030
-     * @param string $param_class
1031
-     * @param array  $arguments
1032
-     * @param mixed  $index
1033
-     * @return array
1034
-     */
1035
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1036
-    {
1037
-        $dependency = null;
1038
-        // should dependency be loaded from cache ?
1039
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1040
-                    !== EE_Dependency_Map::load_new_object
1041
-            ? true
1042
-            : false;
1043
-        // we might have a dependency...
1044
-        // let's MAYBE try and find it in our cache if that's what's been requested
1045
-        $cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1046
-        // and grab it if it exists
1047
-        if ($cached_class instanceof $param_class) {
1048
-            $dependency = $cached_class;
1049
-        } else if ($param_class != $class_name) {
1050
-            // obtain the loader method from the dependency map
1051
-            $loader = $this->_dependency_map->class_loader($param_class);
1052
-            // is loader a custom closure ?
1053
-            if ($loader instanceof Closure) {
1054
-                $dependency = $loader();
1055
-            } else {
1056
-                // set the cache on property for the recursive loading call
1057
-                $this->_cache_on = $cache_on;
1058
-                // if not, then let's try and load it via the registry
1059
-                if (method_exists($this, $loader)) {
1060
-                    $dependency = $this->{$loader}($param_class);
1061
-                } else {
1062
-                    $dependency = $this->create($param_class, array(), $cache_on);
1063
-                }
1064
-            }
1065
-        }
1066
-        // did we successfully find the correct dependency ?
1067
-        if ($dependency instanceof $param_class) {
1068
-            // then let's inject it into the incoming array of arguments at the correct location
1069
-            if (isset($argument_keys[$index])) {
1070
-                $arguments[$argument_keys[$index]] = $dependency;
1071
-            } else {
1072
-                $arguments[$index] = $dependency;
1073
-            }
1074
-        }
1075
-        return $arguments;
1076
-    }
1077
-
1078
-
1079
-
1080
-    /**
1081
-     * _set_cached_class
1082
-     * attempts to cache the instantiated class locally
1083
-     * in one of the following places, in the following order:
1084
-     *        $this->{class_abbreviation}   ie:    $this->CART
1085
-     *        $this->{$class_name}          ie:    $this->Some_Class
1086
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1087
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1088
-     *
1089
-     * @access protected
1090
-     * @param object $class_obj
1091
-     * @param string $class_name
1092
-     * @param string $class_prefix
1093
-     * @param bool   $from_db
1094
-     * @return void
1095
-     */
1096
-    protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1097
-    {
1098
-        if (empty($class_obj)) {
1099
-            return;
1100
-        }
1101
-        // return newly instantiated class
1102
-        if (isset($this->_class_abbreviations[$class_name])) {
1103
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
1104
-            $this->{$class_abbreviation} = $class_obj;
1105
-        } else if (property_exists($this, $class_name)) {
1106
-            $this->{$class_name} = $class_obj;
1107
-        } else if ($class_prefix == 'addon') {
1108
-            $this->addons->{$class_name} = $class_obj;
1109
-        } else if ( ! $from_db) {
1110
-            $this->LIB->{$class_name} = $class_obj;
1111
-        }
1112
-    }
1113
-
1114
-
1115
-
1116
-    /**
1117
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1118
-     *
1119
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1120
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1121
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1122
-     * @param array  $arguments
1123
-     * @return object
1124
-     */
1125
-    public static function factory($classname, $arguments = array())
1126
-    {
1127
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1128
-        if ($loader instanceof Closure) {
1129
-            return $loader($arguments);
1130
-        } else if (method_exists(EE_Registry::instance(), $loader)) {
1131
-            return EE_Registry::instance()->{$loader}($classname, $arguments);
1132
-        }
1133
-        return null;
1134
-    }
1135
-
1136
-
1137
-
1138
-    /**
1139
-     * Gets the addon by its name/slug (not classname. For that, just
1140
-     * use the classname as the property name on EE_Config::instance()->addons)
1141
-     *
1142
-     * @param string $name
1143
-     * @return EE_Addon
1144
-     */
1145
-    public function get_addon_by_name($name)
1146
-    {
1147
-        foreach ($this->addons as $addon) {
1148
-            if ($addon->name() == $name) {
1149
-                return $addon;
1150
-            }
1151
-        }
1152
-        return null;
1153
-    }
1154
-
1155
-
1156
-
1157
-    /**
1158
-     * 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
1159
-     * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1160
-     *
1161
-     * @return EE_Addon[] where the KEYS are the addon's name()
1162
-     */
1163
-    public function get_addons_by_name()
1164
-    {
1165
-        $addons = array();
1166
-        foreach ($this->addons as $addon) {
1167
-            $addons[$addon->name()] = $addon;
1168
-        }
1169
-        return $addons;
1170
-    }
1171
-
1172
-
1173
-
1174
-    /**
1175
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1176
-     * a stale copy of it around
1177
-     *
1178
-     * @param string $model_name
1179
-     * @return \EEM_Base
1180
-     * @throws \EE_Error
1181
-     */
1182
-    public function reset_model($model_name)
1183
-    {
1184
-        $model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1185
-        if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1186
-            return null;
1187
-        }
1188
-        //get that model reset it and make sure we nuke the old reference to it
1189
-        if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1190
-            $this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1191
-        } else {
1192
-            throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1193
-        }
1194
-        return $this->LIB->{$model_class_name};
1195
-    }
1196
-
1197
-
1198
-
1199
-    /**
1200
-     * Resets the registry.
1201
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1202
-     * is used in a multisite install.  Here is a list of things that are NOT reset.
1203
-     * - $_dependency_map
1204
-     * - $_class_abbreviations
1205
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1206
-     * - $REQ:  Still on the same request so no need to change.
1207
-     * - $CAP: There is no site specific state in the EE_Capability class.
1208
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1209
-     *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1210
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1211
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1212
-     *             switch or on the restore.
1213
-     * - $modules
1214
-     * - $shortcodes
1215
-     * - $widgets
1216
-     *
1217
-     * @param boolean $hard             whether to reset data in the database too, or just refresh
1218
-     *                                  the Registry to its state at the beginning of the request
1219
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1220
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1221
-     *                                  currently reinstantiate the singletons at the moment)
1222
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1223
-     *                                  code instead can just change the model context to a different blog id if necessary
1224
-     * @return EE_Registry
1225
-     */
1226
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1227
-    {
1228
-        $instance = self::instance();
1229
-        EEH_Activation::reset();
1230
-        //properties that get reset
1231
-        $instance->_cache_on = true;
1232
-        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1233
-        $instance->CART = null;
1234
-        $instance->MRM = null;
1235
-        $instance->AssetsRegistry = new Registry();
1236
-        //messages reset
1237
-        EED_Messages::reset();
1238
-        if ($reset_models) {
1239
-            foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1240
-                $instance->reset_model($model_name);
1241
-            }
1242
-        }
1243
-        $instance->LIB = new stdClass();
1244
-        return $instance;
1245
-    }
1246
-
1247
-
1248
-
1249
-    /**
1250
-     * @override magic methods
1251
-     * @return void
1252
-     */
1253
-    final function __destruct()
1254
-    {
1255
-    }
1256
-
1257
-
1258
-
1259
-    /**
1260
-     * @param $a
1261
-     * @param $b
1262
-     */
1263
-    final function __call($a, $b)
1264
-    {
1265
-    }
1266
-
1267
-
1268
-
1269
-    /**
1270
-     * @param $a
1271
-     */
1272
-    final function __get($a)
1273
-    {
1274
-    }
1275
-
1276
-
1277
-
1278
-    /**
1279
-     * @param $a
1280
-     * @param $b
1281
-     */
1282
-    final function __set($a, $b)
1283
-    {
1284
-    }
1285
-
1286
-
1287
-
1288
-    /**
1289
-     * @param $a
1290
-     */
1291
-    final function __isset($a)
1292
-    {
1293
-    }
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 = $this->_dependency_map->get_alias($class_name);
590
+		if ( ! class_exists($class_name)) {
591
+			// maybe the class is registered with a preceding \
592
+			$class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
593
+			// still doesn't exist ?
594
+			if ( ! class_exists($class_name)) {
595
+				return null;
596
+			}
597
+		}
598
+		// if we're only loading the class and it already exists, then let's just return true immediately
599
+		if ($load_only) {
600
+			return true;
601
+		}
602
+		$addon = $addon ? 'addon' : '';
603
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
604
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
605
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
606
+		if ($this->_cache_on && $cache && ! $load_only) {
607
+			// return object if it's already cached
608
+			$cached_class = $this->_get_cached_class($class_name, $addon);
609
+			if ($cached_class !== null) {
610
+				return $cached_class;
611
+			}
612
+		}
613
+		// instantiate the requested object
614
+		$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
615
+		if ($this->_cache_on && $cache) {
616
+			// save it for later... kinda like gum  { : $
617
+			$this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
618
+		}
619
+		$this->_cache_on = true;
620
+		return $class_obj;
621
+	}
622
+
623
+
624
+
625
+	/**
626
+	 * instantiates, caches, and injects dependencies for classes
627
+	 *
628
+	 * @param array       $file_paths   an array of paths to folders to look in
629
+	 * @param string      $class_prefix EE  or EEM or... ???
630
+	 * @param bool|string $class_name   $class name
631
+	 * @param string      $type         file type - core? class? helper? model?
632
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
633
+	 * @param bool        $from_db      some classes are instantiated from the db
634
+	 *                                  and thus call a different method to instantiate
635
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
636
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
637
+	 * @return null|object|bool         null = failure to load or instantiate class object.
638
+	 *                                  object = class loaded and instantiated successfully.
639
+	 *                                  bool = fail or success when $load_only is true
640
+	 */
641
+	protected function _load(
642
+		$file_paths = array(),
643
+		$class_prefix = 'EE_',
644
+		$class_name = false,
645
+		$type = 'class',
646
+		$arguments = array(),
647
+		$from_db = false,
648
+		$cache = true,
649
+		$load_only = false
650
+	) {
651
+		// strip php file extension
652
+		$class_name = str_replace('.php', '', trim($class_name));
653
+		// does the class have a prefix ?
654
+		if ( ! empty($class_prefix) && $class_prefix != 'addon') {
655
+			// make sure $class_prefix is uppercase
656
+			$class_prefix = strtoupper(trim($class_prefix));
657
+			// add class prefix ONCE!!!
658
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
659
+		}
660
+		$class_name = $this->_dependency_map->get_alias($class_name);
661
+		$class_exists = class_exists($class_name);
662
+		// if we're only loading the class and it already exists, then let's just return true immediately
663
+		if ($load_only && $class_exists) {
664
+			return true;
665
+		}
666
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
667
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
668
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
669
+		if ($this->_cache_on && $cache && ! $load_only) {
670
+			// return object if it's already cached
671
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix);
672
+			if ($cached_class !== null) {
673
+				return $cached_class;
674
+			}
675
+		}
676
+		// if the class doesn't already exist.. then we need to try and find the file and load it
677
+		if ( ! $class_exists) {
678
+			// get full path to file
679
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
680
+			// load the file
681
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
682
+			// if loading failed, or we are only loading a file but NOT instantiating an object
683
+			if ( ! $loaded || $load_only) {
684
+				// return boolean if only loading, or null if an object was expected
685
+				return $load_only ? $loaded : null;
686
+			}
687
+		}
688
+		// instantiate the requested object
689
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
690
+		if ($this->_cache_on && $cache) {
691
+			// save it for later... kinda like gum  { : $
692
+			$this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
693
+		}
694
+		$this->_cache_on = true;
695
+		return $class_obj;
696
+	}
697
+
698
+
699
+
700
+	/**
701
+	 * _get_cached_class
702
+	 * attempts to find a cached version of the requested class
703
+	 * by looking in the following places:
704
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
705
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
706
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
707
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
708
+	 *
709
+	 * @access protected
710
+	 * @param string $class_name
711
+	 * @param string $class_prefix
712
+	 * @return mixed
713
+	 */
714
+	protected function _get_cached_class($class_name, $class_prefix = '')
715
+	{
716
+		if (isset($this->_class_abbreviations[$class_name])) {
717
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
718
+		} else {
719
+			// have to specify something, but not anything that will conflict
720
+			$class_abbreviation = 'FANCY_BATMAN_PANTS';
721
+		}
722
+		// check if class has already been loaded, and return it if it has been
723
+		if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
724
+			return $this->{$class_abbreviation};
725
+		} else if (isset ($this->{$class_name})) {
726
+			return $this->{$class_name};
727
+		} else if (isset ($this->LIB->{$class_name})) {
728
+			return $this->LIB->{$class_name};
729
+		} else if ($class_prefix == 'addon' && isset ($this->addons->{$class_name})) {
730
+			return $this->addons->{$class_name};
731
+		}
732
+		return null;
733
+	}
734
+
735
+
736
+
737
+	/**
738
+	 * _resolve_path
739
+	 * attempts to find a full valid filepath for the requested class.
740
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
741
+	 * then returns that path if the target file has been found and is readable
742
+	 *
743
+	 * @access protected
744
+	 * @param string $class_name
745
+	 * @param string $type
746
+	 * @param array  $file_paths
747
+	 * @return string | bool
748
+	 */
749
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
750
+	{
751
+		// make sure $file_paths is an array
752
+		$file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
753
+		// cycle thru paths
754
+		foreach ($file_paths as $key => $file_path) {
755
+			// convert all separators to proper DS, if no filepath, then use EE_CLASSES
756
+			$file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
757
+			// prep file type
758
+			$type = ! empty($type) ? trim($type, '.') . '.' : '';
759
+			// build full file path
760
+			$file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
761
+			//does the file exist and can be read ?
762
+			if (is_readable($file_paths[$key])) {
763
+				return $file_paths[$key];
764
+			}
765
+		}
766
+		return false;
767
+	}
768
+
769
+
770
+
771
+	/**
772
+	 * _require_file
773
+	 * basically just performs a require_once()
774
+	 * but with some error handling
775
+	 *
776
+	 * @access protected
777
+	 * @param  string $path
778
+	 * @param  string $class_name
779
+	 * @param  string $type
780
+	 * @param  array  $file_paths
781
+	 * @return boolean
782
+	 * @throws \EE_Error
783
+	 */
784
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
785
+	{
786
+		// don't give up! you gotta...
787
+		try {
788
+			//does the file exist and can it be read ?
789
+			if ( ! $path) {
790
+				// so sorry, can't find the file
791
+				throw new EE_Error (
792
+					sprintf(
793
+						__('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'),
794
+						trim($type, '.'),
795
+						$class_name,
796
+						'<br />' . implode(',<br />', $file_paths)
797
+					)
798
+				);
799
+			}
800
+			// get the file
801
+			require_once($path);
802
+			// if the class isn't already declared somewhere
803
+			if (class_exists($class_name, false) === false) {
804
+				// so sorry, not a class
805
+				throw new EE_Error(
806
+					sprintf(
807
+						__('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
808
+						$type,
809
+						$path,
810
+						$class_name
811
+					)
812
+				);
813
+			}
814
+		} catch (EE_Error $e) {
815
+			$e->get_error();
816
+			return false;
817
+		}
818
+		return true;
819
+	}
820
+
821
+
822
+
823
+	/**
824
+	 * _create_object
825
+	 * Attempts to instantiate the requested class via any of the
826
+	 * commonly used instantiation methods employed throughout EE.
827
+	 * The priority for instantiation is as follows:
828
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
829
+	 *        - model objects via their 'new_instance_from_db' method
830
+	 *        - model objects via their 'new_instance' method
831
+	 *        - "singleton" classes" via their 'instance' method
832
+	 *    - standard instantiable classes via their __constructor
833
+	 * Prior to instantiation, if the classname exists in the dependency_map,
834
+	 * then the constructor for the requested class will be examined to determine
835
+	 * if any dependencies exist, and if they can be injected.
836
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
837
+	 *
838
+	 * @access protected
839
+	 * @param string $class_name
840
+	 * @param array  $arguments
841
+	 * @param string $type
842
+	 * @param bool   $from_db
843
+	 * @return null | object
844
+	 * @throws \EE_Error
845
+	 */
846
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
847
+	{
848
+		$class_obj = null;
849
+		$instantiation_mode = '0) none';
850
+		// don't give up! you gotta...
851
+		try {
852
+			// create reflection
853
+			$reflector = $this->get_ReflectionClass($class_name);
854
+			// make sure arguments are an array
855
+			$arguments = is_array($arguments) ? $arguments : array($arguments);
856
+			// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
857
+			// else wrap it in an additional array so that it doesn't get split into multiple parameters
858
+			$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
859
+				? $arguments
860
+				: array($arguments);
861
+			// attempt to inject dependencies ?
862
+			if ($this->_dependency_map->has($class_name)) {
863
+				$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
864
+			}
865
+			// instantiate the class if possible
866
+			if ($reflector->isAbstract()) {
867
+				// nothing to instantiate, loading file was enough
868
+				// does not throw an exception so $instantiation_mode is unused
869
+				// $instantiation_mode = "1) no constructor abstract class";
870
+				$class_obj = true;
871
+			} else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
872
+				// no constructor = static methods only... nothing to instantiate, loading file was enough
873
+				$instantiation_mode = "2) no constructor but instantiable";
874
+				$class_obj = $reflector->newInstance();
875
+			} else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
876
+				$instantiation_mode = "3) new_instance_from_db()";
877
+				$class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
878
+			} else if (method_exists($class_name, 'new_instance')) {
879
+				$instantiation_mode = "4) new_instance()";
880
+				$class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
881
+			} else if (method_exists($class_name, 'instance')) {
882
+				$instantiation_mode = "5) instance()";
883
+				$class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
884
+			} else if ($reflector->isInstantiable()) {
885
+				$instantiation_mode = "6) constructor";
886
+				$class_obj = $reflector->newInstanceArgs($arguments);
887
+			} else {
888
+				// heh ? something's not right !
889
+				throw new EE_Error(
890
+					sprintf(
891
+						__('The %s file %s could not be instantiated.', 'event_espresso'),
892
+						$type,
893
+						$class_name
894
+					)
895
+				);
896
+			}
897
+		} catch (Exception $e) {
898
+			if ( ! $e instanceof EE_Error) {
899
+				$e = new EE_Error(
900
+					sprintf(
901
+						__('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
902
+						$class_name,
903
+						'<br />',
904
+						$e->getMessage(),
905
+						$instantiation_mode
906
+					)
907
+				);
908
+			}
909
+			$e->get_error();
910
+		}
911
+		return $class_obj;
912
+	}
913
+
914
+
915
+
916
+	/**
917
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
918
+	 * @param array $array
919
+	 * @return bool
920
+	 */
921
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
922
+	{
923
+		return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
924
+	}
925
+
926
+
927
+
928
+	/**
929
+	 * getReflectionClass
930
+	 * checks if a ReflectionClass object has already been generated for a class
931
+	 * and returns that instead of creating a new one
932
+	 *
933
+	 * @access public
934
+	 * @param string $class_name
935
+	 * @return ReflectionClass
936
+	 */
937
+	public function get_ReflectionClass($class_name)
938
+	{
939
+		if (
940
+			! isset($this->_reflectors[$class_name])
941
+			|| ! $this->_reflectors[$class_name] instanceof ReflectionClass
942
+		) {
943
+			$this->_reflectors[$class_name] = new ReflectionClass($class_name);
944
+		}
945
+		return $this->_reflectors[$class_name];
946
+	}
947
+
948
+
949
+
950
+	/**
951
+	 * _resolve_dependencies
952
+	 * examines the constructor for the requested class to determine
953
+	 * if any dependencies exist, and if they can be injected.
954
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
955
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
956
+	 * For example:
957
+	 *        if attempting to load a class "Foo" with the following constructor:
958
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
959
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
960
+	 *        but only IF they are NOT already present in the incoming arguments array,
961
+	 *        and the correct classes can be loaded
962
+	 *
963
+	 * @access protected
964
+	 * @param ReflectionClass $reflector
965
+	 * @param string          $class_name
966
+	 * @param array           $arguments
967
+	 * @return array
968
+	 * @throws \ReflectionException
969
+	 */
970
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
971
+	{
972
+		// let's examine the constructor
973
+		$constructor = $reflector->getConstructor();
974
+		// whu? huh? nothing?
975
+		if ( ! $constructor) {
976
+			return $arguments;
977
+		}
978
+		// get constructor parameters
979
+		$params = $constructor->getParameters();
980
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
981
+		$argument_keys = array_keys($arguments);
982
+		// now loop thru all of the constructors expected parameters
983
+		foreach ($params as $index => $param) {
984
+			// is this a dependency for a specific class ?
985
+			$param_class = $param->getClass() ? $param->getClass()->name : null;
986
+			if (
987
+				// param is not even a class
988
+				empty($param_class)
989
+				// and something already exists in the incoming arguments for this param
990
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
991
+			) {
992
+				// so let's skip this argument and move on to the next
993
+				continue;
994
+			} else if (
995
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
996
+				! empty($param_class)
997
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
998
+				&& $arguments[$argument_keys[$index]] instanceof $param_class
999
+			) {
1000
+				// skip this argument and move on to the next
1001
+				continue;
1002
+			} else if (
1003
+				// parameter is type hinted as a class, and should be injected
1004
+				! empty($param_class)
1005
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1006
+			) {
1007
+				$arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1008
+			} else {
1009
+				try {
1010
+					$arguments[$index] = $param->getDefaultValue();
1011
+				} catch (ReflectionException $e) {
1012
+					throw new ReflectionException(
1013
+						sprintf(
1014
+							__('%1$s for parameter "$%2$s"', 'event_espresso'),
1015
+							$e->getMessage(),
1016
+							$param->getName()
1017
+						)
1018
+					);
1019
+				}
1020
+			}
1021
+		}
1022
+		return $arguments;
1023
+	}
1024
+
1025
+
1026
+
1027
+	/**
1028
+	 * @access protected
1029
+	 * @param string $class_name
1030
+	 * @param string $param_class
1031
+	 * @param array  $arguments
1032
+	 * @param mixed  $index
1033
+	 * @return array
1034
+	 */
1035
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1036
+	{
1037
+		$dependency = null;
1038
+		// should dependency be loaded from cache ?
1039
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1040
+					!== EE_Dependency_Map::load_new_object
1041
+			? true
1042
+			: false;
1043
+		// we might have a dependency...
1044
+		// let's MAYBE try and find it in our cache if that's what's been requested
1045
+		$cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1046
+		// and grab it if it exists
1047
+		if ($cached_class instanceof $param_class) {
1048
+			$dependency = $cached_class;
1049
+		} else if ($param_class != $class_name) {
1050
+			// obtain the loader method from the dependency map
1051
+			$loader = $this->_dependency_map->class_loader($param_class);
1052
+			// is loader a custom closure ?
1053
+			if ($loader instanceof Closure) {
1054
+				$dependency = $loader();
1055
+			} else {
1056
+				// set the cache on property for the recursive loading call
1057
+				$this->_cache_on = $cache_on;
1058
+				// if not, then let's try and load it via the registry
1059
+				if (method_exists($this, $loader)) {
1060
+					$dependency = $this->{$loader}($param_class);
1061
+				} else {
1062
+					$dependency = $this->create($param_class, array(), $cache_on);
1063
+				}
1064
+			}
1065
+		}
1066
+		// did we successfully find the correct dependency ?
1067
+		if ($dependency instanceof $param_class) {
1068
+			// then let's inject it into the incoming array of arguments at the correct location
1069
+			if (isset($argument_keys[$index])) {
1070
+				$arguments[$argument_keys[$index]] = $dependency;
1071
+			} else {
1072
+				$arguments[$index] = $dependency;
1073
+			}
1074
+		}
1075
+		return $arguments;
1076
+	}
1077
+
1078
+
1079
+
1080
+	/**
1081
+	 * _set_cached_class
1082
+	 * attempts to cache the instantiated class locally
1083
+	 * in one of the following places, in the following order:
1084
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1085
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1086
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1087
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1088
+	 *
1089
+	 * @access protected
1090
+	 * @param object $class_obj
1091
+	 * @param string $class_name
1092
+	 * @param string $class_prefix
1093
+	 * @param bool   $from_db
1094
+	 * @return void
1095
+	 */
1096
+	protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1097
+	{
1098
+		if (empty($class_obj)) {
1099
+			return;
1100
+		}
1101
+		// return newly instantiated class
1102
+		if (isset($this->_class_abbreviations[$class_name])) {
1103
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
1104
+			$this->{$class_abbreviation} = $class_obj;
1105
+		} else if (property_exists($this, $class_name)) {
1106
+			$this->{$class_name} = $class_obj;
1107
+		} else if ($class_prefix == 'addon') {
1108
+			$this->addons->{$class_name} = $class_obj;
1109
+		} else if ( ! $from_db) {
1110
+			$this->LIB->{$class_name} = $class_obj;
1111
+		}
1112
+	}
1113
+
1114
+
1115
+
1116
+	/**
1117
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1118
+	 *
1119
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1120
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1121
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1122
+	 * @param array  $arguments
1123
+	 * @return object
1124
+	 */
1125
+	public static function factory($classname, $arguments = array())
1126
+	{
1127
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1128
+		if ($loader instanceof Closure) {
1129
+			return $loader($arguments);
1130
+		} else if (method_exists(EE_Registry::instance(), $loader)) {
1131
+			return EE_Registry::instance()->{$loader}($classname, $arguments);
1132
+		}
1133
+		return null;
1134
+	}
1135
+
1136
+
1137
+
1138
+	/**
1139
+	 * Gets the addon by its name/slug (not classname. For that, just
1140
+	 * use the classname as the property name on EE_Config::instance()->addons)
1141
+	 *
1142
+	 * @param string $name
1143
+	 * @return EE_Addon
1144
+	 */
1145
+	public function get_addon_by_name($name)
1146
+	{
1147
+		foreach ($this->addons as $addon) {
1148
+			if ($addon->name() == $name) {
1149
+				return $addon;
1150
+			}
1151
+		}
1152
+		return null;
1153
+	}
1154
+
1155
+
1156
+
1157
+	/**
1158
+	 * 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
1159
+	 * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1160
+	 *
1161
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1162
+	 */
1163
+	public function get_addons_by_name()
1164
+	{
1165
+		$addons = array();
1166
+		foreach ($this->addons as $addon) {
1167
+			$addons[$addon->name()] = $addon;
1168
+		}
1169
+		return $addons;
1170
+	}
1171
+
1172
+
1173
+
1174
+	/**
1175
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1176
+	 * a stale copy of it around
1177
+	 *
1178
+	 * @param string $model_name
1179
+	 * @return \EEM_Base
1180
+	 * @throws \EE_Error
1181
+	 */
1182
+	public function reset_model($model_name)
1183
+	{
1184
+		$model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1185
+		if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1186
+			return null;
1187
+		}
1188
+		//get that model reset it and make sure we nuke the old reference to it
1189
+		if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1190
+			$this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1191
+		} else {
1192
+			throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1193
+		}
1194
+		return $this->LIB->{$model_class_name};
1195
+	}
1196
+
1197
+
1198
+
1199
+	/**
1200
+	 * Resets the registry.
1201
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1202
+	 * is used in a multisite install.  Here is a list of things that are NOT reset.
1203
+	 * - $_dependency_map
1204
+	 * - $_class_abbreviations
1205
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1206
+	 * - $REQ:  Still on the same request so no need to change.
1207
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1208
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1209
+	 *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1210
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1211
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1212
+	 *             switch or on the restore.
1213
+	 * - $modules
1214
+	 * - $shortcodes
1215
+	 * - $widgets
1216
+	 *
1217
+	 * @param boolean $hard             whether to reset data in the database too, or just refresh
1218
+	 *                                  the Registry to its state at the beginning of the request
1219
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1220
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1221
+	 *                                  currently reinstantiate the singletons at the moment)
1222
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1223
+	 *                                  code instead can just change the model context to a different blog id if necessary
1224
+	 * @return EE_Registry
1225
+	 */
1226
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1227
+	{
1228
+		$instance = self::instance();
1229
+		EEH_Activation::reset();
1230
+		//properties that get reset
1231
+		$instance->_cache_on = true;
1232
+		$instance->CFG = EE_Config::reset($hard, $reinstantiate);
1233
+		$instance->CART = null;
1234
+		$instance->MRM = null;
1235
+		$instance->AssetsRegistry = new Registry();
1236
+		//messages reset
1237
+		EED_Messages::reset();
1238
+		if ($reset_models) {
1239
+			foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1240
+				$instance->reset_model($model_name);
1241
+			}
1242
+		}
1243
+		$instance->LIB = new stdClass();
1244
+		return $instance;
1245
+	}
1246
+
1247
+
1248
+
1249
+	/**
1250
+	 * @override magic methods
1251
+	 * @return void
1252
+	 */
1253
+	final function __destruct()
1254
+	{
1255
+	}
1256
+
1257
+
1258
+
1259
+	/**
1260
+	 * @param $a
1261
+	 * @param $b
1262
+	 */
1263
+	final function __call($a, $b)
1264
+	{
1265
+	}
1266
+
1267
+
1268
+
1269
+	/**
1270
+	 * @param $a
1271
+	 */
1272
+	final function __get($a)
1273
+	{
1274
+	}
1275
+
1276
+
1277
+
1278
+	/**
1279
+	 * @param $a
1280
+	 * @param $b
1281
+	 */
1282
+	final function __set($a, $b)
1283
+	{
1284
+	}
1285
+
1286
+
1287
+
1288
+	/**
1289
+	 * @param $a
1290
+	 */
1291
+	final function __isset($a)
1292
+	{
1293
+	}
1294 1294
 
1295 1295
 
1296 1296
 
1297
-    /**
1298
-     * @param $a
1299
-     */
1300
-    final function __unset($a)
1301
-    {
1302
-    }
1297
+	/**
1298
+	 * @param $a
1299
+	 */
1300
+	final function __unset($a)
1301
+	{
1302
+	}
1303 1303
 
1304 1304
 
1305 1305
 
1306
-    /**
1307
-     * @return array
1308
-     */
1309
-    final function __sleep()
1310
-    {
1311
-        return array();
1312
-    }
1306
+	/**
1307
+	 * @return array
1308
+	 */
1309
+	final function __sleep()
1310
+	{
1311
+		return array();
1312
+	}
1313 1313
 
1314 1314
 
1315 1315
 
1316
-    final function __wakeup()
1317
-    {
1318
-    }
1316
+	final function __wakeup()
1317
+	{
1318
+	}
1319 1319
 
1320 1320
 
1321 1321
 
1322
-    /**
1323
-     * @return string
1324
-     */
1325
-    final function __toString()
1326
-    {
1327
-        return '';
1328
-    }
1322
+	/**
1323
+	 * @return string
1324
+	 */
1325
+	final function __toString()
1326
+	{
1327
+		return '';
1328
+	}
1329 1329
 
1330 1330
 
1331 1331
 
1332
-    final function __invoke()
1333
-    {
1334
-    }
1332
+	final function __invoke()
1333
+	{
1334
+	}
1335 1335
 
1336 1336
 
1337 1337
 
1338
-    final static function __set_state()
1339
-    {
1340
-    }
1338
+	final static function __set_state()
1339
+	{
1340
+	}
1341 1341
 
1342 1342
 
1343 1343
 
1344
-    final function __clone()
1345
-    {
1346
-    }
1344
+	final function __clone()
1345
+	{
1346
+	}
1347 1347
 
1348 1348
 
1349 1349
 
1350
-    /**
1351
-     * @param $a
1352
-     * @param $b
1353
-     */
1354
-    final static function __callStatic($a, $b)
1355
-    {
1356
-    }
1350
+	/**
1351
+	 * @param $a
1352
+	 * @param $b
1353
+	 */
1354
+	final static function __callStatic($a, $b)
1355
+	{
1356
+	}
1357 1357
 
1358 1358
 
1359 1359
 
1360
-    /**
1361
-     * Gets all the custom post type models defined
1362
-     *
1363
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1364
-     */
1365
-    public function cpt_models()
1366
-    {
1367
-        $cpt_models = array();
1368
-        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1369
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1370
-                $cpt_models[$short_name] = $classname;
1371
-            }
1372
-        }
1373
-        return $cpt_models;
1374
-    }
1360
+	/**
1361
+	 * Gets all the custom post type models defined
1362
+	 *
1363
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1364
+	 */
1365
+	public function cpt_models()
1366
+	{
1367
+		$cpt_models = array();
1368
+		foreach ($this->non_abstract_db_models as $short_name => $classname) {
1369
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1370
+				$cpt_models[$short_name] = $classname;
1371
+			}
1372
+		}
1373
+		return $cpt_models;
1374
+	}
1375 1375
 
1376 1376
 
1377 1377
 
1378
-    /**
1379
-     * @return \EE_Config
1380
-     */
1381
-    public static function CFG()
1382
-    {
1383
-        return self::instance()->CFG;
1384
-    }
1378
+	/**
1379
+	 * @return \EE_Config
1380
+	 */
1381
+	public static function CFG()
1382
+	{
1383
+		return self::instance()->CFG;
1384
+	}
1385 1385
 
1386 1386
 
1387 1387
 }
Please login to merge, or discard this patch.