@@ -13,105 +13,105 @@ |
||
13 | 13 | class EE_PMT_Paypal_Standard extends EE_PMT_Base |
14 | 14 | { |
15 | 15 | |
16 | - const shipping_info_none = 1; |
|
17 | - const shipping_info_optional = 0; |
|
18 | - const shipping_info_required = 2; |
|
19 | - |
|
20 | - |
|
21 | - |
|
22 | - /** |
|
23 | - * @param null $pm_instance |
|
24 | - * @return \EE_PMT_Paypal_Standard |
|
25 | - * @throws \EE_Error |
|
26 | - */ |
|
27 | - public function __construct($pm_instance = null) |
|
28 | - { |
|
29 | - require_once($this->file_folder().'EEG_Paypal_Standard.gateway.php'); |
|
30 | - $this->_gateway = new EEG_Paypal_Standard(); |
|
31 | - $this->_pretty_name = __("PayPal Standard", 'event_espresso'); |
|
32 | - $this->_default_description = sprintf( |
|
33 | - __( |
|
34 | - 'Upon submitting this form, you will be forwarded to PayPal to make your payment. %1$sMake sure you return to this site in order to properly finalize your registration.%2$s', |
|
35 | - 'event_espresso' |
|
36 | - ), |
|
37 | - '<strong>', |
|
38 | - '</strong>' |
|
39 | - ); |
|
40 | - parent::__construct($pm_instance); |
|
41 | - $this->_default_button_url = $this->file_url().'lib/paypal-logo.png'; |
|
42 | - } |
|
43 | - |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * Creates the billing form for this payment method type |
|
48 | - * @param \EE_Transaction $transaction |
|
49 | - * @return NULL |
|
50 | - */ |
|
51 | - public function generate_new_billing_form(EE_Transaction $transaction = null) |
|
52 | - { |
|
53 | - return null; |
|
54 | - } |
|
55 | - |
|
56 | - |
|
57 | - |
|
58 | - /** |
|
59 | - * Gets the form for all the settings related to this payment method type |
|
60 | - * |
|
61 | - * @return EE_Payment_Method_Form |
|
62 | - * @throws \EE_Error |
|
63 | - */ |
|
64 | - public function generate_new_settings_form() |
|
65 | - { |
|
66 | - require_once($this->file_folder() . 'EE_Paypal_Standard_Form.form.php'); |
|
67 | - $form = new EE_Paypal_Standard_Form($this); |
|
68 | - $form->get_input('PMD_debug_mode')->set_html_label_text( |
|
69 | - sprintf(__("Use PayPal Sandbox %s", 'event_espresso'), $this->get_help_tab_link()) |
|
70 | - ); |
|
71 | - $form->get_input('shipping_details')->set_html_label_text( |
|
72 | - sprintf(__("Shipping Address Options %s", "event_espresso"), $this->get_help_tab_link()) |
|
73 | - ); |
|
74 | - return $form; |
|
75 | - } |
|
76 | - |
|
77 | - |
|
78 | - |
|
79 | - /** |
|
80 | - * Adds the help tab |
|
81 | - * @see EE_PMT_Base::help_tabs_config() |
|
82 | - * @return array |
|
83 | - */ |
|
84 | - public function help_tabs_config() |
|
85 | - { |
|
86 | - return array( |
|
87 | - $this->get_help_tab_name() => array( |
|
88 | - 'title'=> __("PayPal Standard Settings", 'event_espresso'), |
|
89 | - 'filename'=>'payment_methods_overview_paypalstandard' |
|
90 | - ) |
|
91 | - ); |
|
92 | - } |
|
93 | - |
|
94 | - |
|
95 | - |
|
96 | - /** |
|
97 | - * Logic to be accomplished when the payment attempt is complete. |
|
98 | - * Most payment methods don't need to do anything at this point; but some, like Mijireh, do. |
|
99 | - * (Mijireh was an offsite gateway which doesn't send an IPN. So when the user returns to EE from |
|
100 | - * Mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status |
|
101 | - * of the payment). Fed a transaction because it's always assumed to be the last payment that |
|
102 | - * |
|
103 | - * @param EE_Transaction $transaction |
|
104 | - * @return EE_Payment |
|
105 | - * @throws \EE_Error |
|
106 | - */ |
|
107 | - public function finalize_payment_for($transaction) |
|
108 | - { |
|
109 | - // PayPal standard actually sends the IPN info along with the user when they return to our site |
|
110 | - // so in case the IPN is arriving later, let's try to process an IPN! |
|
111 | - if ($_SERVER['REQUEST_METHOD'] === 'POST') { |
|
112 | - return $this->handle_ipn($_POST, $transaction); |
|
113 | - } else { |
|
114 | - return parent::finalize_payment_for($transaction); |
|
115 | - } |
|
116 | - } |
|
16 | + const shipping_info_none = 1; |
|
17 | + const shipping_info_optional = 0; |
|
18 | + const shipping_info_required = 2; |
|
19 | + |
|
20 | + |
|
21 | + |
|
22 | + /** |
|
23 | + * @param null $pm_instance |
|
24 | + * @return \EE_PMT_Paypal_Standard |
|
25 | + * @throws \EE_Error |
|
26 | + */ |
|
27 | + public function __construct($pm_instance = null) |
|
28 | + { |
|
29 | + require_once($this->file_folder().'EEG_Paypal_Standard.gateway.php'); |
|
30 | + $this->_gateway = new EEG_Paypal_Standard(); |
|
31 | + $this->_pretty_name = __("PayPal Standard", 'event_espresso'); |
|
32 | + $this->_default_description = sprintf( |
|
33 | + __( |
|
34 | + 'Upon submitting this form, you will be forwarded to PayPal to make your payment. %1$sMake sure you return to this site in order to properly finalize your registration.%2$s', |
|
35 | + 'event_espresso' |
|
36 | + ), |
|
37 | + '<strong>', |
|
38 | + '</strong>' |
|
39 | + ); |
|
40 | + parent::__construct($pm_instance); |
|
41 | + $this->_default_button_url = $this->file_url().'lib/paypal-logo.png'; |
|
42 | + } |
|
43 | + |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * Creates the billing form for this payment method type |
|
48 | + * @param \EE_Transaction $transaction |
|
49 | + * @return NULL |
|
50 | + */ |
|
51 | + public function generate_new_billing_form(EE_Transaction $transaction = null) |
|
52 | + { |
|
53 | + return null; |
|
54 | + } |
|
55 | + |
|
56 | + |
|
57 | + |
|
58 | + /** |
|
59 | + * Gets the form for all the settings related to this payment method type |
|
60 | + * |
|
61 | + * @return EE_Payment_Method_Form |
|
62 | + * @throws \EE_Error |
|
63 | + */ |
|
64 | + public function generate_new_settings_form() |
|
65 | + { |
|
66 | + require_once($this->file_folder() . 'EE_Paypal_Standard_Form.form.php'); |
|
67 | + $form = new EE_Paypal_Standard_Form($this); |
|
68 | + $form->get_input('PMD_debug_mode')->set_html_label_text( |
|
69 | + sprintf(__("Use PayPal Sandbox %s", 'event_espresso'), $this->get_help_tab_link()) |
|
70 | + ); |
|
71 | + $form->get_input('shipping_details')->set_html_label_text( |
|
72 | + sprintf(__("Shipping Address Options %s", "event_espresso"), $this->get_help_tab_link()) |
|
73 | + ); |
|
74 | + return $form; |
|
75 | + } |
|
76 | + |
|
77 | + |
|
78 | + |
|
79 | + /** |
|
80 | + * Adds the help tab |
|
81 | + * @see EE_PMT_Base::help_tabs_config() |
|
82 | + * @return array |
|
83 | + */ |
|
84 | + public function help_tabs_config() |
|
85 | + { |
|
86 | + return array( |
|
87 | + $this->get_help_tab_name() => array( |
|
88 | + 'title'=> __("PayPal Standard Settings", 'event_espresso'), |
|
89 | + 'filename'=>'payment_methods_overview_paypalstandard' |
|
90 | + ) |
|
91 | + ); |
|
92 | + } |
|
93 | + |
|
94 | + |
|
95 | + |
|
96 | + /** |
|
97 | + * Logic to be accomplished when the payment attempt is complete. |
|
98 | + * Most payment methods don't need to do anything at this point; but some, like Mijireh, do. |
|
99 | + * (Mijireh was an offsite gateway which doesn't send an IPN. So when the user returns to EE from |
|
100 | + * Mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status |
|
101 | + * of the payment). Fed a transaction because it's always assumed to be the last payment that |
|
102 | + * |
|
103 | + * @param EE_Transaction $transaction |
|
104 | + * @return EE_Payment |
|
105 | + * @throws \EE_Error |
|
106 | + */ |
|
107 | + public function finalize_payment_for($transaction) |
|
108 | + { |
|
109 | + // PayPal standard actually sends the IPN info along with the user when they return to our site |
|
110 | + // so in case the IPN is arriving later, let's try to process an IPN! |
|
111 | + if ($_SERVER['REQUEST_METHOD'] === 'POST') { |
|
112 | + return $this->handle_ipn($_POST, $transaction); |
|
113 | + } else { |
|
114 | + return parent::finalize_payment_for($transaction); |
|
115 | + } |
|
116 | + } |
|
117 | 117 | } |
@@ -15,9 +15,9 @@ discard block |
||
15 | 15 | $stages = glob(EE_CORE . 'data_migration_scripts/4_10_0_stages/*'); |
16 | 16 | $class_to_filepath = []; |
17 | 17 | foreach ($stages as $filepath) { |
18 | - $matches = []; |
|
19 | - preg_match('~4_10_0_stages/(.*).dmsstage.php~', $filepath, $matches); |
|
20 | - $class_to_filepath[ $matches[1] ] = $filepath; |
|
18 | + $matches = []; |
|
19 | + preg_match('~4_10_0_stages/(.*).dmsstage.php~', $filepath, $matches); |
|
20 | + $class_to_filepath[ $matches[1] ] = $filepath; |
|
21 | 21 | } |
22 | 22 | // give addons a chance to autoload their stages too |
23 | 23 | $class_to_filepath = apply_filters('FHEE__EE_DMS_4_10_0__autoloaded_stages', $class_to_filepath); |
@@ -35,66 +35,66 @@ discard block |
||
35 | 35 | */ |
36 | 36 | class EE_DMS_Core_4_10_0 extends EE_Data_Migration_Script_Base |
37 | 37 | { |
38 | - /** |
|
39 | - * |
|
40 | - * @param TableManager $table_manager |
|
41 | - * @param TableAnalysis $table_analysis |
|
42 | - */ |
|
43 | - public function __construct( |
|
44 | - TableManager $table_manager = null, |
|
45 | - TableAnalysis $table_analysis = null, |
|
46 | - EE_DMS_Core_4_9_0 $dms_4_9 |
|
47 | - ) { |
|
48 | - $this->previous_dms = $dms_4_9; |
|
49 | - $this->_pretty_name = esc_html__("Data Update to Event Espresso 4.10.0", "event_espresso"); |
|
50 | - $this->_priority = 10; |
|
51 | - $this->_migration_stages = array( |
|
52 | - new EE_DMS_4_10_0_Event_Question_Group(), |
|
53 | - ); |
|
54 | - parent::__construct($table_manager, $table_analysis); |
|
55 | - } |
|
38 | + /** |
|
39 | + * |
|
40 | + * @param TableManager $table_manager |
|
41 | + * @param TableAnalysis $table_analysis |
|
42 | + */ |
|
43 | + public function __construct( |
|
44 | + TableManager $table_manager = null, |
|
45 | + TableAnalysis $table_analysis = null, |
|
46 | + EE_DMS_Core_4_9_0 $dms_4_9 |
|
47 | + ) { |
|
48 | + $this->previous_dms = $dms_4_9; |
|
49 | + $this->_pretty_name = esc_html__("Data Update to Event Espresso 4.10.0", "event_espresso"); |
|
50 | + $this->_priority = 10; |
|
51 | + $this->_migration_stages = array( |
|
52 | + new EE_DMS_4_10_0_Event_Question_Group(), |
|
53 | + ); |
|
54 | + parent::__construct($table_manager, $table_analysis); |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | 58 | |
59 | - /** |
|
60 | - * Whether to migrate or not. |
|
61 | - * |
|
62 | - * @param array $version_array |
|
63 | - * @return bool |
|
64 | - */ |
|
65 | - public function can_migrate_from_version($version_array) |
|
66 | - { |
|
67 | - $version_string = $version_array['Core']; |
|
68 | - if (version_compare($version_string, '4.10.0.decaf', '<') && version_compare($version_string, '4.9.0.decaf', '>=')) { |
|
69 | - return true; |
|
70 | - } elseif (! $version_string) { |
|
71 | - // echo "no version string provided: $version_string"; |
|
72 | - // no version string provided... this must be pre 4.3 |
|
73 | - return false;// changed mind. dont want people thinking they should migrate yet because they cant |
|
74 | - } |
|
75 | - return false; |
|
76 | - } |
|
59 | + /** |
|
60 | + * Whether to migrate or not. |
|
61 | + * |
|
62 | + * @param array $version_array |
|
63 | + * @return bool |
|
64 | + */ |
|
65 | + public function can_migrate_from_version($version_array) |
|
66 | + { |
|
67 | + $version_string = $version_array['Core']; |
|
68 | + if (version_compare($version_string, '4.10.0.decaf', '<') && version_compare($version_string, '4.9.0.decaf', '>=')) { |
|
69 | + return true; |
|
70 | + } elseif (! $version_string) { |
|
71 | + // echo "no version string provided: $version_string"; |
|
72 | + // no version string provided... this must be pre 4.3 |
|
73 | + return false;// changed mind. dont want people thinking they should migrate yet because they cant |
|
74 | + } |
|
75 | + return false; |
|
76 | + } |
|
77 | 77 | |
78 | 78 | |
79 | 79 | |
80 | - /** |
|
81 | - * @return bool |
|
82 | - */ |
|
83 | - public function schema_changes_before_migration() |
|
84 | - { |
|
85 | - require_once(EE_HELPERS . 'EEH_Activation.helper.php'); |
|
86 | - $now_in_mysql = current_time('mysql', true); |
|
87 | - $table_name = 'esp_answer'; |
|
88 | - $sql = " ANS_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
80 | + /** |
|
81 | + * @return bool |
|
82 | + */ |
|
83 | + public function schema_changes_before_migration() |
|
84 | + { |
|
85 | + require_once(EE_HELPERS . 'EEH_Activation.helper.php'); |
|
86 | + $now_in_mysql = current_time('mysql', true); |
|
87 | + $table_name = 'esp_answer'; |
|
88 | + $sql = " ANS_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
89 | 89 | REG_ID int(10) unsigned NOT NULL, |
90 | 90 | QST_ID int(10) unsigned NOT NULL, |
91 | 91 | ANS_value text NOT NULL, |
92 | 92 | PRIMARY KEY (ANS_ID), |
93 | 93 | KEY REG_ID (REG_ID), |
94 | 94 | KEY QST_ID (QST_ID)"; |
95 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
96 | - $table_name = 'esp_attendee_meta'; |
|
97 | - $sql = "ATTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
95 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
96 | + $table_name = 'esp_attendee_meta'; |
|
97 | + $sql = "ATTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
98 | 98 | ATT_ID bigint(20) unsigned NOT NULL, |
99 | 99 | ATT_fname varchar(45) NOT NULL, |
100 | 100 | ATT_lname varchar(45) NOT NULL, |
@@ -111,9 +111,9 @@ discard block |
||
111 | 111 | KEY ATT_email (ATT_email(191)), |
112 | 112 | KEY ATT_lname (ATT_lname), |
113 | 113 | KEY ATT_fname (ATT_fname)"; |
114 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
115 | - $table_name = 'esp_checkin'; |
|
116 | - $sql = "CHK_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
114 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
115 | + $table_name = 'esp_checkin'; |
|
116 | + $sql = "CHK_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
117 | 117 | REG_ID int(10) unsigned NOT NULL, |
118 | 118 | DTT_ID int(10) unsigned NOT NULL, |
119 | 119 | CHK_in tinyint(1) unsigned NOT NULL DEFAULT 1, |
@@ -121,9 +121,9 @@ discard block |
||
121 | 121 | PRIMARY KEY (CHK_ID), |
122 | 122 | KEY REG_ID (REG_ID), |
123 | 123 | KEY DTT_ID (DTT_ID)"; |
124 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
125 | - $table_name = 'esp_country'; |
|
126 | - $sql = "CNT_ISO varchar(2) NOT NULL, |
|
124 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
125 | + $table_name = 'esp_country'; |
|
126 | + $sql = "CNT_ISO varchar(2) NOT NULL, |
|
127 | 127 | CNT_ISO3 varchar(3) NOT NULL, |
128 | 128 | RGN_ID tinyint(3) unsigned DEFAULT NULL, |
129 | 129 | CNT_name varchar(45) NOT NULL, |
@@ -139,29 +139,29 @@ discard block |
||
139 | 139 | CNT_is_EU tinyint(1) DEFAULT '0', |
140 | 140 | CNT_active tinyint(1) DEFAULT '0', |
141 | 141 | PRIMARY KEY (CNT_ISO)"; |
142 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
143 | - $table_name = 'esp_currency'; |
|
144 | - $sql = "CUR_code varchar(6) NOT NULL, |
|
142 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
143 | + $table_name = 'esp_currency'; |
|
144 | + $sql = "CUR_code varchar(6) NOT NULL, |
|
145 | 145 | CUR_single varchar(45) DEFAULT 'dollar', |
146 | 146 | CUR_plural varchar(45) DEFAULT 'dollars', |
147 | 147 | CUR_sign varchar(45) DEFAULT '$', |
148 | 148 | CUR_dec_plc varchar(1) NOT NULL DEFAULT '2', |
149 | 149 | CUR_active tinyint(1) DEFAULT '0', |
150 | 150 | PRIMARY KEY (CUR_code)"; |
151 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
152 | - // note: although this table is no longer in use, |
|
153 | - // it hasn't been removed because then queries to the model will have errors. |
|
154 | - // but you should expect this table and its corresponding model to be removed in |
|
155 | - // the next few months |
|
156 | - $table_name = 'esp_currency_payment_method'; |
|
157 | - $sql = "CPM_ID int(11) NOT NULL AUTO_INCREMENT, |
|
151 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
152 | + // note: although this table is no longer in use, |
|
153 | + // it hasn't been removed because then queries to the model will have errors. |
|
154 | + // but you should expect this table and its corresponding model to be removed in |
|
155 | + // the next few months |
|
156 | + $table_name = 'esp_currency_payment_method'; |
|
157 | + $sql = "CPM_ID int(11) NOT NULL AUTO_INCREMENT, |
|
158 | 158 | CUR_code varchar(6) NOT NULL, |
159 | 159 | PMD_ID int(11) NOT NULL, |
160 | 160 | PRIMARY KEY (CPM_ID), |
161 | 161 | KEY PMD_ID (PMD_ID)"; |
162 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
163 | - $table_name = 'esp_datetime'; |
|
164 | - $sql = "DTT_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
162 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
163 | + $table_name = 'esp_datetime'; |
|
164 | + $sql = "DTT_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
165 | 165 | EVT_ID bigint(20) unsigned NOT NULL, |
166 | 166 | DTT_name varchar(255) NOT NULL DEFAULT '', |
167 | 167 | DTT_description text NOT NULL, |
@@ -178,25 +178,25 @@ discard block |
||
178 | 178 | KEY DTT_EVT_start (DTT_EVT_start), |
179 | 179 | KEY EVT_ID (EVT_ID), |
180 | 180 | KEY DTT_is_primary (DTT_is_primary)"; |
181 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
182 | - $table_name = "esp_datetime_ticket"; |
|
183 | - $sql = "DTK_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
181 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
182 | + $table_name = "esp_datetime_ticket"; |
|
183 | + $sql = "DTK_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
184 | 184 | DTT_ID int(10) unsigned NOT NULL, |
185 | 185 | TKT_ID int(10) unsigned NOT NULL, |
186 | 186 | PRIMARY KEY (DTK_ID), |
187 | 187 | KEY DTT_ID (DTT_ID), |
188 | 188 | KEY TKT_ID (TKT_ID)"; |
189 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
190 | - $table_name = 'esp_event_message_template'; |
|
191 | - $sql = "EMT_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
|
189 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
190 | + $table_name = 'esp_event_message_template'; |
|
191 | + $sql = "EMT_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
|
192 | 192 | EVT_ID bigint(20) unsigned NOT NULL DEFAULT 0, |
193 | 193 | GRP_ID int(10) unsigned NOT NULL DEFAULT 0, |
194 | 194 | PRIMARY KEY (EMT_ID), |
195 | 195 | KEY EVT_ID (EVT_ID), |
196 | 196 | KEY GRP_ID (GRP_ID)"; |
197 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
198 | - $table_name = 'esp_event_meta'; |
|
199 | - $sql = "EVTM_ID int(10) NOT NULL AUTO_INCREMENT, |
|
197 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
198 | + $table_name = 'esp_event_meta'; |
|
199 | + $sql = "EVTM_ID int(10) NOT NULL AUTO_INCREMENT, |
|
200 | 200 | EVT_ID bigint(20) unsigned NOT NULL, |
201 | 201 | EVT_display_desc tinyint(1) unsigned NOT NULL DEFAULT 1, |
202 | 202 | EVT_display_ticket_selector tinyint(1) unsigned NOT NULL DEFAULT 1, |
@@ -211,9 +211,9 @@ discard block |
||
211 | 211 | EVT_donations tinyint(1) NULL, |
212 | 212 | PRIMARY KEY (EVTM_ID), |
213 | 213 | KEY EVT_ID (EVT_ID)"; |
214 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
215 | - $table_name = 'esp_event_question_group'; |
|
216 | - $sql = "EQG_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
214 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
215 | + $table_name = 'esp_event_question_group'; |
|
216 | + $sql = "EQG_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
217 | 217 | EVT_ID bigint(20) unsigned NOT NULL, |
218 | 218 | QSG_ID int(10) unsigned NOT NULL, |
219 | 219 | EQG_primary tinyint(1) unsigned NOT NULL DEFAULT 0, |
@@ -221,25 +221,25 @@ discard block |
||
221 | 221 | PRIMARY KEY (EQG_ID), |
222 | 222 | KEY EVT_ID (EVT_ID), |
223 | 223 | KEY QSG_ID (QSG_ID)"; |
224 | - $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB'); |
|
225 | - $table_name = 'esp_event_venue'; |
|
226 | - $sql = "EVV_ID int(11) NOT NULL AUTO_INCREMENT, |
|
224 | + $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB'); |
|
225 | + $table_name = 'esp_event_venue'; |
|
226 | + $sql = "EVV_ID int(11) NOT NULL AUTO_INCREMENT, |
|
227 | 227 | EVT_ID bigint(20) unsigned NOT NULL, |
228 | 228 | VNU_ID bigint(20) unsigned NOT NULL, |
229 | 229 | EVV_primary tinyint(1) unsigned NOT NULL DEFAULT 0, |
230 | 230 | PRIMARY KEY (EVV_ID)"; |
231 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
232 | - $table_name = 'esp_extra_meta'; |
|
233 | - $sql = "EXM_ID int(11) NOT NULL AUTO_INCREMENT, |
|
231 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
232 | + $table_name = 'esp_extra_meta'; |
|
233 | + $sql = "EXM_ID int(11) NOT NULL AUTO_INCREMENT, |
|
234 | 234 | OBJ_ID int(11) DEFAULT NULL, |
235 | 235 | EXM_type varchar(45) DEFAULT NULL, |
236 | 236 | EXM_key varchar(45) DEFAULT NULL, |
237 | 237 | EXM_value text, |
238 | 238 | PRIMARY KEY (EXM_ID), |
239 | 239 | KEY EXM_type (EXM_type,OBJ_ID,EXM_key)"; |
240 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
241 | - $table_name = 'esp_extra_join'; |
|
242 | - $sql = "EXJ_ID int(11) NOT NULL AUTO_INCREMENT, |
|
240 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
241 | + $table_name = 'esp_extra_join'; |
|
242 | + $sql = "EXJ_ID int(11) NOT NULL AUTO_INCREMENT, |
|
243 | 243 | EXJ_first_model_id varchar(6) NOT NULL, |
244 | 244 | EXJ_first_model_name varchar(20) NOT NULL, |
245 | 245 | EXJ_second_model_id varchar(6) NOT NULL, |
@@ -247,9 +247,9 @@ discard block |
||
247 | 247 | PRIMARY KEY (EXJ_ID), |
248 | 248 | KEY first_model (EXJ_first_model_name,EXJ_first_model_id), |
249 | 249 | KEY second_model (EXJ_second_model_name,EXJ_second_model_id)"; |
250 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
251 | - $table_name = 'esp_line_item'; |
|
252 | - $sql = "LIN_ID int(11) NOT NULL AUTO_INCREMENT, |
|
250 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
251 | + $table_name = 'esp_line_item'; |
|
252 | + $sql = "LIN_ID int(11) NOT NULL AUTO_INCREMENT, |
|
253 | 253 | LIN_code varchar(245) NOT NULL DEFAULT '', |
254 | 254 | TXN_ID int(11) DEFAULT NULL, |
255 | 255 | LIN_name varchar(245) NOT NULL DEFAULT '', |
@@ -270,9 +270,9 @@ discard block |
||
270 | 270 | KEY txn_type_timestamp (TXN_ID,LIN_type,LIN_timestamp), |
271 | 271 | KEY txn_obj_id_obj_type (TXN_ID,OBJ_ID,OBJ_type), |
272 | 272 | KEY obj_id_obj_type (OBJ_ID,OBJ_type)"; |
273 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
274 | - $table_name = 'esp_log'; |
|
275 | - $sql = "LOG_ID int(11) NOT NULL AUTO_INCREMENT, |
|
273 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
274 | + $table_name = 'esp_log'; |
|
275 | + $sql = "LOG_ID int(11) NOT NULL AUTO_INCREMENT, |
|
276 | 276 | LOG_time datetime DEFAULT NULL, |
277 | 277 | OBJ_ID varchar(45) DEFAULT NULL, |
278 | 278 | OBJ_type varchar(45) DEFAULT NULL, |
@@ -283,9 +283,9 @@ discard block |
||
283 | 283 | KEY LOG_time (LOG_time), |
284 | 284 | KEY OBJ (OBJ_type,OBJ_ID), |
285 | 285 | KEY LOG_type (LOG_type)"; |
286 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
287 | - $table_name = 'esp_message'; |
|
288 | - $sql = "MSG_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
|
286 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
287 | + $table_name = 'esp_message'; |
|
288 | + $sql = "MSG_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
|
289 | 289 | GRP_ID int(10) unsigned NULL, |
290 | 290 | MSG_token varchar(255) NULL, |
291 | 291 | TXN_ID int(10) unsigned NULL, |
@@ -317,18 +317,18 @@ discard block |
||
317 | 317 | KEY STS_ID (STS_ID), |
318 | 318 | KEY MSG_created (MSG_created), |
319 | 319 | KEY MSG_modified (MSG_modified)"; |
320 | - $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB'); |
|
321 | - $table_name = 'esp_message_template'; |
|
322 | - $sql = "MTP_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
320 | + $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB'); |
|
321 | + $table_name = 'esp_message_template'; |
|
322 | + $sql = "MTP_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
323 | 323 | GRP_ID int(10) unsigned NOT NULL, |
324 | 324 | MTP_context varchar(50) NOT NULL, |
325 | 325 | MTP_template_field varchar(30) NOT NULL, |
326 | 326 | MTP_content text NOT NULL, |
327 | 327 | PRIMARY KEY (MTP_ID), |
328 | 328 | KEY GRP_ID (GRP_ID)"; |
329 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
330 | - $table_name = 'esp_message_template_group'; |
|
331 | - $sql = "GRP_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
329 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
330 | + $table_name = 'esp_message_template_group'; |
|
331 | + $sql = "GRP_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
332 | 332 | MTP_user_id int(10) NOT NULL DEFAULT '1', |
333 | 333 | MTP_name varchar(245) NOT NULL DEFAULT '', |
334 | 334 | MTP_description varchar(245) NOT NULL DEFAULT '', |
@@ -340,9 +340,9 @@ discard block |
||
340 | 340 | MTP_is_active tinyint(1) NOT NULL DEFAULT '1', |
341 | 341 | PRIMARY KEY (GRP_ID), |
342 | 342 | KEY MTP_user_id (MTP_user_id)"; |
343 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
344 | - $table_name = 'esp_payment'; |
|
345 | - $sql = "PAY_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
343 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
344 | + $table_name = 'esp_payment'; |
|
345 | + $sql = "PAY_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
346 | 346 | TXN_ID int(10) unsigned DEFAULT NULL, |
347 | 347 | STS_ID varchar(3) DEFAULT NULL, |
348 | 348 | PAY_timestamp datetime NOT NULL DEFAULT '0000-00-00 00:00:00', |
@@ -359,9 +359,9 @@ discard block |
||
359 | 359 | PRIMARY KEY (PAY_ID), |
360 | 360 | KEY PAY_timestamp (PAY_timestamp), |
361 | 361 | KEY TXN_ID (TXN_ID)"; |
362 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
363 | - $table_name = 'esp_payment_method'; |
|
364 | - $sql = "PMD_ID int(11) NOT NULL AUTO_INCREMENT, |
|
362 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
363 | + $table_name = 'esp_payment_method'; |
|
364 | + $sql = "PMD_ID int(11) NOT NULL AUTO_INCREMENT, |
|
365 | 365 | PMD_type varchar(124) DEFAULT NULL, |
366 | 366 | PMD_name varchar(255) DEFAULT NULL, |
367 | 367 | PMD_desc text, |
@@ -377,24 +377,24 @@ discard block |
||
377 | 377 | PRIMARY KEY (PMD_ID), |
378 | 378 | UNIQUE KEY PMD_slug_UNIQUE (PMD_slug), |
379 | 379 | KEY PMD_type (PMD_type)"; |
380 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
381 | - $table_name = "esp_ticket_price"; |
|
382 | - $sql = "TKP_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
380 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
381 | + $table_name = "esp_ticket_price"; |
|
382 | + $sql = "TKP_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
383 | 383 | TKT_ID int(10) unsigned NOT NULL, |
384 | 384 | PRC_ID int(10) unsigned NOT NULL, |
385 | 385 | PRIMARY KEY (TKP_ID), |
386 | 386 | KEY TKT_ID (TKT_ID), |
387 | 387 | KEY PRC_ID (PRC_ID)"; |
388 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
389 | - $table_name = "esp_ticket_template"; |
|
390 | - $sql = "TTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
388 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
389 | + $table_name = "esp_ticket_template"; |
|
390 | + $sql = "TTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
391 | 391 | TTM_name varchar(45) NOT NULL, |
392 | 392 | TTM_description text, |
393 | 393 | TTM_file varchar(45), |
394 | 394 | PRIMARY KEY (TTM_ID)"; |
395 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
396 | - $table_name = 'esp_question'; |
|
397 | - $sql = 'QST_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
395 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
396 | + $table_name = 'esp_question'; |
|
397 | + $sql = 'QST_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
398 | 398 | QST_display_text text NOT NULL, |
399 | 399 | QST_admin_label varchar(255) NOT NULL, |
400 | 400 | QST_system varchar(25) DEFAULT NULL, |
@@ -408,18 +408,18 @@ discard block |
||
408 | 408 | QST_deleted tinyint(2) unsigned NOT NULL DEFAULT 0, |
409 | 409 | PRIMARY KEY (QST_ID), |
410 | 410 | KEY QST_order (QST_order)'; |
411 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
412 | - $table_name = 'esp_question_group_question'; |
|
413 | - $sql = "QGQ_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
411 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
412 | + $table_name = 'esp_question_group_question'; |
|
413 | + $sql = "QGQ_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
414 | 414 | QSG_ID int(10) unsigned NOT NULL, |
415 | 415 | QST_ID int(10) unsigned NOT NULL, |
416 | 416 | QGQ_order int(10) unsigned NOT NULL DEFAULT 0, |
417 | 417 | PRIMARY KEY (QGQ_ID), |
418 | 418 | KEY QST_ID (QST_ID), |
419 | 419 | KEY QSG_ID_order (QSG_ID,QGQ_order)"; |
420 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
421 | - $table_name = 'esp_question_option'; |
|
422 | - $sql = "QSO_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
420 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
421 | + $table_name = 'esp_question_option'; |
|
422 | + $sql = "QSO_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
423 | 423 | QSO_value varchar(255) NOT NULL, |
424 | 424 | QSO_desc text NOT NULL, |
425 | 425 | QST_ID int(10) unsigned NOT NULL, |
@@ -429,9 +429,9 @@ discard block |
||
429 | 429 | PRIMARY KEY (QSO_ID), |
430 | 430 | KEY QST_ID (QST_ID), |
431 | 431 | KEY QSO_order (QSO_order)"; |
432 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
433 | - $table_name = 'esp_registration'; |
|
434 | - $sql = "REG_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
432 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
433 | + $table_name = 'esp_registration'; |
|
434 | + $sql = "REG_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
435 | 435 | EVT_ID bigint(20) unsigned NOT NULL, |
436 | 436 | ATT_ID bigint(20) unsigned NOT NULL, |
437 | 437 | TXN_ID int(10) unsigned NOT NULL, |
@@ -455,18 +455,18 @@ discard block |
||
455 | 455 | KEY TKT_ID (TKT_ID), |
456 | 456 | KEY EVT_ID (EVT_ID), |
457 | 457 | KEY STS_ID (STS_ID)"; |
458 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
459 | - $table_name = 'esp_registration_payment'; |
|
460 | - $sql = "RPY_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
458 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
459 | + $table_name = 'esp_registration_payment'; |
|
460 | + $sql = "RPY_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
461 | 461 | REG_ID int(10) unsigned NOT NULL, |
462 | 462 | PAY_ID int(10) unsigned NULL, |
463 | 463 | RPY_amount decimal(12,3) NOT NULL DEFAULT '0.00', |
464 | 464 | PRIMARY KEY (RPY_ID), |
465 | 465 | KEY REG_ID (REG_ID), |
466 | 466 | KEY PAY_ID (PAY_ID)"; |
467 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
468 | - $table_name = 'esp_state'; |
|
469 | - $sql = "STA_ID smallint(5) unsigned NOT NULL AUTO_INCREMENT, |
|
467 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
468 | + $table_name = 'esp_state'; |
|
469 | + $sql = "STA_ID smallint(5) unsigned NOT NULL AUTO_INCREMENT, |
|
470 | 470 | CNT_ISO varchar(2) NOT NULL, |
471 | 471 | STA_abbrev varchar(24) NOT NULL, |
472 | 472 | STA_name varchar(100) NOT NULL, |
@@ -474,9 +474,9 @@ discard block |
||
474 | 474 | PRIMARY KEY (STA_ID), |
475 | 475 | KEY STA_abbrev (STA_abbrev), |
476 | 476 | KEY CNT_ISO (CNT_ISO)"; |
477 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
478 | - $table_name = 'esp_status'; |
|
479 | - $sql = "STS_ID varchar(3) NOT NULL, |
|
477 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
478 | + $table_name = 'esp_status'; |
|
479 | + $sql = "STS_ID varchar(3) NOT NULL, |
|
480 | 480 | STS_code varchar(45) NOT NULL, |
481 | 481 | STS_type varchar(45) NOT NULL, |
482 | 482 | STS_can_edit tinyint(1) NOT NULL DEFAULT 0, |
@@ -484,9 +484,9 @@ discard block |
||
484 | 484 | STS_open tinyint(1) NOT NULL DEFAULT 1, |
485 | 485 | UNIQUE KEY STS_ID_UNIQUE (STS_ID), |
486 | 486 | KEY STS_type (STS_type)"; |
487 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
488 | - $table_name = 'esp_transaction'; |
|
489 | - $sql = "TXN_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
487 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
488 | + $table_name = 'esp_transaction'; |
|
489 | + $sql = "TXN_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
490 | 490 | TXN_timestamp datetime NOT NULL DEFAULT '0000-00-00 00:00:00', |
491 | 491 | TXN_total decimal(12,3) DEFAULT '0.00', |
492 | 492 | TXN_paid decimal(12,3) NOT NULL DEFAULT '0.00', |
@@ -498,9 +498,9 @@ discard block |
||
498 | 498 | PRIMARY KEY (TXN_ID), |
499 | 499 | KEY TXN_timestamp (TXN_timestamp), |
500 | 500 | KEY STS_ID (STS_ID)"; |
501 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
502 | - $table_name = 'esp_venue_meta'; |
|
503 | - $sql = "VNUM_ID int(11) NOT NULL AUTO_INCREMENT, |
|
501 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
502 | + $table_name = 'esp_venue_meta'; |
|
503 | + $sql = "VNUM_ID int(11) NOT NULL AUTO_INCREMENT, |
|
504 | 504 | VNU_ID bigint(20) unsigned NOT NULL DEFAULT 0, |
505 | 505 | VNU_address varchar(255) DEFAULT NULL, |
506 | 506 | VNU_address2 varchar(255) DEFAULT NULL, |
@@ -519,10 +519,10 @@ discard block |
||
519 | 519 | KEY VNU_ID (VNU_ID), |
520 | 520 | KEY STA_ID (STA_ID), |
521 | 521 | KEY CNT_ISO (CNT_ISO)"; |
522 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
523 | - // modified tables |
|
524 | - $table_name = "esp_price"; |
|
525 | - $sql = "PRC_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
522 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
523 | + // modified tables |
|
524 | + $table_name = "esp_price"; |
|
525 | + $sql = "PRC_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
526 | 526 | PRT_ID tinyint(3) unsigned NOT NULL, |
527 | 527 | PRC_amount decimal(12,3) NOT NULL DEFAULT '0.00', |
528 | 528 | PRC_name varchar(245) NOT NULL, |
@@ -535,9 +535,9 @@ discard block |
||
535 | 535 | PRC_parent int(10) unsigned DEFAULT 0, |
536 | 536 | PRIMARY KEY (PRC_ID), |
537 | 537 | KEY PRT_ID (PRT_ID)"; |
538 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
539 | - $table_name = "esp_price_type"; |
|
540 | - $sql = "PRT_ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT, |
|
538 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
539 | + $table_name = "esp_price_type"; |
|
540 | + $sql = "PRT_ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT, |
|
541 | 541 | PRT_name varchar(45) NOT NULL, |
542 | 542 | PBT_ID tinyint(3) unsigned NOT NULL DEFAULT '1', |
543 | 543 | PRT_is_percent tinyint(1) NOT NULL DEFAULT '0', |
@@ -546,9 +546,9 @@ discard block |
||
546 | 546 | PRT_deleted tinyint(1) NOT NULL DEFAULT '0', |
547 | 547 | UNIQUE KEY PRT_name_UNIQUE (PRT_name), |
548 | 548 | PRIMARY KEY (PRT_ID)"; |
549 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
550 | - $table_name = "esp_ticket"; |
|
551 | - $sql = "TKT_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
549 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB '); |
|
550 | + $table_name = "esp_ticket"; |
|
551 | + $sql = "TKT_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
552 | 552 | TTM_ID int(10) unsigned NOT NULL, |
553 | 553 | TKT_name varchar(245) NOT NULL DEFAULT '', |
554 | 554 | TKT_description text NOT NULL, |
@@ -571,9 +571,9 @@ discard block |
||
571 | 571 | TKT_deleted tinyint(1) NOT NULL DEFAULT '0', |
572 | 572 | PRIMARY KEY (TKT_ID), |
573 | 573 | KEY TKT_start_date (TKT_start_date)"; |
574 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
575 | - $table_name = 'esp_question_group'; |
|
576 | - $sql = 'QSG_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
574 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
575 | + $table_name = 'esp_question_group'; |
|
576 | + $sql = 'QSG_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
|
577 | 577 | QSG_name varchar(255) NOT NULL, |
578 | 578 | QSG_identifier varchar(100) NOT NULL, |
579 | 579 | QSG_desc text NULL, |
@@ -586,70 +586,70 @@ discard block |
||
586 | 586 | PRIMARY KEY (QSG_ID), |
587 | 587 | UNIQUE KEY QSG_identifier_UNIQUE (QSG_identifier), |
588 | 588 | KEY QSG_order (QSG_order)'; |
589 | - $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
590 | - $this->insert_default_data(); |
|
591 | - return true; |
|
592 | - } |
|
589 | + $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB'); |
|
590 | + $this->insert_default_data(); |
|
591 | + return true; |
|
592 | + } |
|
593 | 593 | |
594 | - /** |
|
595 | - * Inserts default data on new installs |
|
596 | - * @since 4.10.0.p |
|
597 | - * @throws EE_Error |
|
598 | - * @throws InvalidArgumentException |
|
599 | - * @throws ReflectionException |
|
600 | - * @throws InvalidDataTypeException |
|
601 | - * @throws InvalidInterfaceException |
|
602 | - */ |
|
603 | - public function insert_default_data() |
|
604 | - { |
|
605 | - $this->previous_dms->insert_default_data(); |
|
606 | - $this->removeMijirehPM(); |
|
607 | - } |
|
594 | + /** |
|
595 | + * Inserts default data on new installs |
|
596 | + * @since 4.10.0.p |
|
597 | + * @throws EE_Error |
|
598 | + * @throws InvalidArgumentException |
|
599 | + * @throws ReflectionException |
|
600 | + * @throws InvalidDataTypeException |
|
601 | + * @throws InvalidInterfaceException |
|
602 | + */ |
|
603 | + public function insert_default_data() |
|
604 | + { |
|
605 | + $this->previous_dms->insert_default_data(); |
|
606 | + $this->removeMijirehPM(); |
|
607 | + } |
|
608 | 608 | |
609 | 609 | |
610 | 610 | |
611 | - /** |
|
612 | - * @return boolean |
|
613 | - */ |
|
614 | - public function schema_changes_after_migration() |
|
615 | - { |
|
616 | - return true; |
|
617 | - } |
|
611 | + /** |
|
612 | + * @return boolean |
|
613 | + */ |
|
614 | + public function schema_changes_after_migration() |
|
615 | + { |
|
616 | + return true; |
|
617 | + } |
|
618 | 618 | |
619 | 619 | |
620 | 620 | |
621 | - public function migration_page_hooks() |
|
622 | - { |
|
623 | - } |
|
621 | + public function migration_page_hooks() |
|
622 | + { |
|
623 | + } |
|
624 | 624 | |
625 | - /** |
|
626 | - * Mijireh was removed in $VID:$, but let's avoid having an error message because its files were removed, and don't |
|
627 | - * show old payments made with it as being by "Unknown". The fix is to make it an "Admin_Only" payment method |
|
628 | - * (like Invoice or Check) but don't allow it to be used in the admin either... so it's usable nowhere from now on, |
|
629 | - * but it still exists so there's no problems. |
|
630 | - * @since $VID:$ |
|
631 | - */ |
|
632 | - protected function removeMijirehPM() |
|
633 | - { |
|
634 | - global $wpdb; |
|
635 | - $wpdb->update( |
|
636 | - $wpdb->prefix . 'esp_payment_method', |
|
637 | - [ |
|
638 | - 'PMD_type' => 'Admin_Only', |
|
639 | - 'PMD_scope' => serialize(array()) |
|
640 | - ], |
|
641 | - [ |
|
642 | - 'PMD_type' => 'Mijireh' |
|
643 | - ], |
|
644 | - [ |
|
645 | - // update formats |
|
646 | - '%s', // PMD_type |
|
647 | - '%s', // PMD_scope |
|
648 | - ], |
|
649 | - [ |
|
650 | - // where formats |
|
651 | - '%s' |
|
652 | - ] |
|
653 | - ); |
|
654 | - } |
|
625 | + /** |
|
626 | + * Mijireh was removed in $VID:$, but let's avoid having an error message because its files were removed, and don't |
|
627 | + * show old payments made with it as being by "Unknown". The fix is to make it an "Admin_Only" payment method |
|
628 | + * (like Invoice or Check) but don't allow it to be used in the admin either... so it's usable nowhere from now on, |
|
629 | + * but it still exists so there's no problems. |
|
630 | + * @since $VID:$ |
|
631 | + */ |
|
632 | + protected function removeMijirehPM() |
|
633 | + { |
|
634 | + global $wpdb; |
|
635 | + $wpdb->update( |
|
636 | + $wpdb->prefix . 'esp_payment_method', |
|
637 | + [ |
|
638 | + 'PMD_type' => 'Admin_Only', |
|
639 | + 'PMD_scope' => serialize(array()) |
|
640 | + ], |
|
641 | + [ |
|
642 | + 'PMD_type' => 'Mijireh' |
|
643 | + ], |
|
644 | + [ |
|
645 | + // update formats |
|
646 | + '%s', // PMD_type |
|
647 | + '%s', // PMD_scope |
|
648 | + ], |
|
649 | + [ |
|
650 | + // where formats |
|
651 | + '%s' |
|
652 | + ] |
|
653 | + ); |
|
654 | + } |
|
655 | 655 | } |
@@ -12,12 +12,12 @@ discard block |
||
12 | 12 | // unfortunately, this needs to be done upon INCLUSION of this file, |
13 | 13 | // instead of construction, because it only gets constructed on first page load |
14 | 14 | // (all other times it gets resurrected from a wordpress option) |
15 | -$stages = glob(EE_CORE . 'data_migration_scripts/4_10_0_stages/*'); |
|
15 | +$stages = glob(EE_CORE.'data_migration_scripts/4_10_0_stages/*'); |
|
16 | 16 | $class_to_filepath = []; |
17 | 17 | foreach ($stages as $filepath) { |
18 | 18 | $matches = []; |
19 | 19 | preg_match('~4_10_0_stages/(.*).dmsstage.php~', $filepath, $matches); |
20 | - $class_to_filepath[ $matches[1] ] = $filepath; |
|
20 | + $class_to_filepath[$matches[1]] = $filepath; |
|
21 | 21 | } |
22 | 22 | // give addons a chance to autoload their stages too |
23 | 23 | $class_to_filepath = apply_filters('FHEE__EE_DMS_4_10_0__autoloaded_stages', $class_to_filepath); |
@@ -67,10 +67,10 @@ discard block |
||
67 | 67 | $version_string = $version_array['Core']; |
68 | 68 | if (version_compare($version_string, '4.10.0.decaf', '<') && version_compare($version_string, '4.9.0.decaf', '>=')) { |
69 | 69 | return true; |
70 | - } elseif (! $version_string) { |
|
70 | + } elseif ( ! $version_string) { |
|
71 | 71 | // echo "no version string provided: $version_string"; |
72 | 72 | // no version string provided... this must be pre 4.3 |
73 | - return false;// changed mind. dont want people thinking they should migrate yet because they cant |
|
73 | + return false; // changed mind. dont want people thinking they should migrate yet because they cant |
|
74 | 74 | } |
75 | 75 | return false; |
76 | 76 | } |
@@ -82,7 +82,7 @@ discard block |
||
82 | 82 | */ |
83 | 83 | public function schema_changes_before_migration() |
84 | 84 | { |
85 | - require_once(EE_HELPERS . 'EEH_Activation.helper.php'); |
|
85 | + require_once(EE_HELPERS.'EEH_Activation.helper.php'); |
|
86 | 86 | $now_in_mysql = current_time('mysql', true); |
87 | 87 | $table_name = 'esp_answer'; |
88 | 88 | $sql = " ANS_ID int(10) unsigned NOT NULL AUTO_INCREMENT, |
@@ -633,7 +633,7 @@ discard block |
||
633 | 633 | { |
634 | 634 | global $wpdb; |
635 | 635 | $wpdb->update( |
636 | - $wpdb->prefix . 'esp_payment_method', |
|
636 | + $wpdb->prefix.'esp_payment_method', |
|
637 | 637 | [ |
638 | 638 | 'PMD_type' => 'Admin_Only', |
639 | 639 | 'PMD_scope' => serialize(array()) |
@@ -18,842 +18,842 @@ |
||
18 | 18 | class EE_Payment_Processor extends EE_Processor_Base implements ResettableInterface |
19 | 19 | { |
20 | 20 | |
21 | - /** |
|
22 | - * @var EE_Payment_Processor $_instance |
|
23 | - * @access private |
|
24 | - */ |
|
25 | - private static $_instance; |
|
26 | - |
|
27 | - |
|
28 | - /** |
|
29 | - * @singleton method used to instantiate class object |
|
30 | - * @access public |
|
31 | - * @return EE_Payment_Processor instance |
|
32 | - */ |
|
33 | - public static function instance() |
|
34 | - { |
|
35 | - // check if class object is instantiated |
|
36 | - if (! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | - self::$_instance = new self(); |
|
38 | - } |
|
39 | - return self::$_instance; |
|
40 | - } |
|
41 | - |
|
42 | - |
|
43 | - /** |
|
44 | - * @return EE_Payment_Processor |
|
45 | - */ |
|
46 | - public static function reset() |
|
47 | - { |
|
48 | - self::$_instance = null; |
|
49 | - return self::instance(); |
|
50 | - } |
|
51 | - |
|
52 | - |
|
53 | - /** |
|
54 | - *private constructor to prevent direct creation |
|
55 | - * |
|
56 | - * @Constructor |
|
57 | - * @access private |
|
58 | - */ |
|
59 | - private function __construct() |
|
60 | - { |
|
61 | - do_action('AHEE__EE_Payment_Processor__construct'); |
|
62 | - add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
63 | - } |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
68 | - * appropriately. Saves the payment that is generated |
|
69 | - * |
|
70 | - * @param EE_Payment_Method $payment_method |
|
71 | - * @param EE_Transaction $transaction |
|
72 | - * @param float $amount if only part of the transaction is to be paid for, how much. |
|
73 | - * Leave null if payment is for the full amount owing |
|
74 | - * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
75 | - * Receive_form_submission() should have |
|
76 | - * already been called on the billing form |
|
77 | - * (ie, its inputs should have their normalized values set). |
|
78 | - * @param string $return_url string used mostly by offsite gateways to specify |
|
79 | - * where to go AFTER the offsite gateway |
|
80 | - * @param string $method like 'CART', indicates who the client who called this was |
|
81 | - * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
82 | - * @param boolean $update_txn whether or not to call |
|
83 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
84 | - * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
85 | - * @return EE_Payment |
|
86 | - * @throws EE_Error |
|
87 | - * @throws InvalidArgumentException |
|
88 | - * @throws ReflectionException |
|
89 | - * @throws RuntimeException |
|
90 | - * @throws InvalidDataTypeException |
|
91 | - * @throws InvalidInterfaceException |
|
92 | - */ |
|
93 | - public function process_payment( |
|
94 | - EE_Payment_Method $payment_method, |
|
95 | - EE_Transaction $transaction, |
|
96 | - $amount = null, |
|
97 | - $billing_form = null, |
|
98 | - $return_url = null, |
|
99 | - $method = 'CART', |
|
100 | - $by_admin = false, |
|
101 | - $update_txn = true, |
|
102 | - $cancel_url = '' |
|
103 | - ) { |
|
104 | - if ((float) $amount < 0) { |
|
105 | - throw new EE_Error( |
|
106 | - sprintf( |
|
107 | - __( |
|
108 | - 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
109 | - 'event_espresso' |
|
110 | - ), |
|
111 | - $amount, |
|
112 | - $transaction->ID() |
|
113 | - ) |
|
114 | - ); |
|
115 | - } |
|
116 | - // verify payment method |
|
117 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
118 | - $payment_method, |
|
119 | - true |
|
120 | - ); |
|
121 | - // verify transaction |
|
122 | - EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
123 | - $transaction->set_payment_method_ID($payment_method->ID()); |
|
124 | - // verify payment method type |
|
125 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
126 | - $payment = $payment_method->type_obj()->process_payment( |
|
127 | - $transaction, |
|
128 | - min($amount, $transaction->remaining()), // make sure we don't overcharge |
|
129 | - $billing_form, |
|
130 | - $return_url, |
|
131 | - add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
132 | - $method, |
|
133 | - $by_admin |
|
134 | - ); |
|
135 | - // check if payment method uses an off-site gateway |
|
136 | - if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
137 | - // don't process payments for off-site gateways yet because no payment has occurred yet |
|
138 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
139 | - } |
|
140 | - return $payment; |
|
141 | - } |
|
142 | - EE_Error::add_error( |
|
143 | - sprintf( |
|
144 | - __( |
|
145 | - 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
146 | - 'event_espresso' |
|
147 | - ), |
|
148 | - '<br/>', |
|
149 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
150 | - ), |
|
151 | - __FILE__, |
|
152 | - __FUNCTION__, |
|
153 | - __LINE__ |
|
154 | - ); |
|
155 | - return null; |
|
156 | - } |
|
157 | - |
|
158 | - |
|
159 | - /** |
|
160 | - * @param EE_Transaction|int $transaction |
|
161 | - * @param EE_Payment_Method $payment_method |
|
162 | - * @return string |
|
163 | - * @throws EE_Error |
|
164 | - * @throws InvalidArgumentException |
|
165 | - * @throws InvalidDataTypeException |
|
166 | - * @throws InvalidInterfaceException |
|
167 | - */ |
|
168 | - public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
169 | - { |
|
170 | - /** @type \EE_Transaction $transaction */ |
|
171 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
172 | - $primary_reg = $transaction->primary_registration(); |
|
173 | - if (! $primary_reg instanceof EE_Registration) { |
|
174 | - throw new EE_Error( |
|
175 | - sprintf( |
|
176 | - __( |
|
177 | - 'Cannot get IPN URL for transaction with ID %d because it has no primary registration', |
|
178 | - 'event_espresso' |
|
179 | - ), |
|
180 | - $transaction->ID() |
|
181 | - ) |
|
182 | - ); |
|
183 | - } |
|
184 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
185 | - $payment_method, |
|
186 | - true |
|
187 | - ); |
|
188 | - $url = add_query_arg( |
|
189 | - array( |
|
190 | - 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
191 | - 'ee_payment_method' => $payment_method->slug(), |
|
192 | - ), |
|
193 | - EE_Registry::instance()->CFG->core->txn_page_url() |
|
194 | - ); |
|
195 | - return $url; |
|
196 | - } |
|
197 | - |
|
198 | - |
|
199 | - /** |
|
200 | - * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
201 | - * we can easily find what registration the IPN is for and what payment method. |
|
202 | - * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
203 | - * If a payment is found for the IPN info, it is saved. |
|
204 | - * |
|
205 | - * @param array $_req_data eg $_REQUEST |
|
206 | - * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
207 | - * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
208 | - * @param boolean $update_txn whether or not to call |
|
209 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
210 | - * @param bool $separate_IPN_request whether the IPN uses a separate request (true, like PayPal) |
|
211 | - * or is processed manually (false, like Authorize.net) |
|
212 | - * @throws EE_Error |
|
213 | - * @throws Exception |
|
214 | - * @return EE_Payment |
|
215 | - * @throws \RuntimeException |
|
216 | - * @throws \ReflectionException |
|
217 | - * @throws \InvalidArgumentException |
|
218 | - * @throws InvalidInterfaceException |
|
219 | - * @throws InvalidDataTypeException |
|
220 | - */ |
|
221 | - public function process_ipn( |
|
222 | - $_req_data, |
|
223 | - $transaction = null, |
|
224 | - $payment_method = null, |
|
225 | - $update_txn = true, |
|
226 | - $separate_IPN_request = true |
|
227 | - ) { |
|
228 | - EE_Registry::instance()->load_model('Change_Log'); |
|
229 | - $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data); |
|
230 | - EE_Processor_Base::set_IPN($separate_IPN_request); |
|
231 | - $obj_for_log = null; |
|
232 | - if ($transaction instanceof EE_Transaction) { |
|
233 | - $obj_for_log = $transaction; |
|
234 | - if ($payment_method instanceof EE_Payment_Method) { |
|
235 | - $obj_for_log = EEM_Payment::instance()->get_one( |
|
236 | - array( |
|
237 | - array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
238 | - 'order_by' => array('PAY_timestamp' => 'desc'), |
|
239 | - ) |
|
240 | - ); |
|
241 | - } |
|
242 | - } elseif ($payment_method instanceof EE_Payment) { |
|
243 | - $obj_for_log = $payment_method; |
|
244 | - } |
|
245 | - $log = EEM_Change_Log::instance()->log( |
|
246 | - EEM_Change_Log::type_gateway, |
|
247 | - array('IPN data received' => $_req_data), |
|
248 | - $obj_for_log |
|
249 | - ); |
|
250 | - try { |
|
251 | - /** |
|
252 | - * @var EE_Payment $payment |
|
253 | - */ |
|
254 | - $payment = null; |
|
255 | - if ($transaction && $payment_method) { |
|
256 | - /** @type EE_Transaction $transaction */ |
|
257 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
258 | - /** @type EE_Payment_Method $payment_method */ |
|
259 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
260 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
261 | - try { |
|
262 | - $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
263 | - $log->set_object($payment); |
|
264 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
265 | - EEM_Change_Log::instance()->log( |
|
266 | - EEM_Change_Log::type_gateway, |
|
267 | - array( |
|
268 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
269 | - 'current_url' => EEH_URL::current_url(), |
|
270 | - 'payment' => $e->getPaymentProperties(), |
|
271 | - 'IPN_data' => $e->getIpnData(), |
|
272 | - ), |
|
273 | - $obj_for_log |
|
274 | - ); |
|
275 | - return $e->getPayment(); |
|
276 | - } |
|
277 | - } else { |
|
278 | - // not a payment |
|
279 | - EE_Error::add_error( |
|
280 | - sprintf( |
|
281 | - __( |
|
282 | - 'A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', |
|
283 | - 'event_espresso' |
|
284 | - ), |
|
285 | - '<br/>', |
|
286 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
287 | - ), |
|
288 | - __FILE__, |
|
289 | - __FUNCTION__, |
|
290 | - __LINE__ |
|
291 | - ); |
|
292 | - } |
|
293 | - } else { |
|
294 | - // that's actually pretty ok. The IPN just wasn't able |
|
295 | - // to identify which transaction or payment method this was for |
|
296 | - // give all active payment methods a chance to claim it |
|
297 | - $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
298 | - foreach ($active_payment_methods as $active_payment_method) { |
|
299 | - try { |
|
300 | - $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
301 | - $payment_method = $active_payment_method; |
|
302 | - EEM_Change_Log::instance()->log( |
|
303 | - EEM_Change_Log::type_gateway, |
|
304 | - array('IPN data' => $_req_data), |
|
305 | - $payment |
|
306 | - ); |
|
307 | - break; |
|
308 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
309 | - EEM_Change_Log::instance()->log( |
|
310 | - EEM_Change_Log::type_gateway, |
|
311 | - array( |
|
312 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
313 | - 'current_url' => EEH_URL::current_url(), |
|
314 | - 'payment' => $e->getPaymentProperties(), |
|
315 | - 'IPN_data' => $e->getIpnData(), |
|
316 | - ), |
|
317 | - $obj_for_log |
|
318 | - ); |
|
319 | - return $e->getPayment(); |
|
320 | - } catch (EE_Error $e) { |
|
321 | - // that's fine- it apparently couldn't handle the IPN |
|
322 | - } |
|
323 | - } |
|
324 | - } |
|
325 | - // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
326 | - if ($payment instanceof EE_Payment) { |
|
327 | - $payment->save(); |
|
328 | - // update the TXN |
|
329 | - $this->update_txn_based_on_payment( |
|
330 | - $transaction, |
|
331 | - $payment, |
|
332 | - $update_txn, |
|
333 | - $separate_IPN_request |
|
334 | - ); |
|
335 | - } else { |
|
336 | - // we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
337 | - if ($payment_method) { |
|
338 | - EEM_Change_Log::instance()->log( |
|
339 | - EEM_Change_Log::type_gateway, |
|
340 | - array('IPN data' => $_req_data), |
|
341 | - $payment_method |
|
342 | - ); |
|
343 | - } elseif ($transaction) { |
|
344 | - EEM_Change_Log::instance()->log( |
|
345 | - EEM_Change_Log::type_gateway, |
|
346 | - array('IPN data' => $_req_data), |
|
347 | - $transaction |
|
348 | - ); |
|
349 | - } |
|
350 | - } |
|
351 | - return $payment; |
|
352 | - } catch (EE_Error $e) { |
|
353 | - do_action( |
|
354 | - 'AHEE__log', |
|
355 | - __FILE__, |
|
356 | - __FUNCTION__, |
|
357 | - sprintf( |
|
358 | - __( |
|
359 | - 'Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', |
|
360 | - 'event_espresso' |
|
361 | - ), |
|
362 | - print_r($transaction, true), |
|
363 | - print_r($_req_data, true), |
|
364 | - $e->getMessage() |
|
365 | - ) |
|
366 | - ); |
|
367 | - throw $e; |
|
368 | - } |
|
369 | - } |
|
370 | - |
|
371 | - |
|
372 | - /** |
|
373 | - * Removes any non-printable illegal characters from the input, |
|
374 | - * which might cause a raucous when trying to insert into the database |
|
375 | - * |
|
376 | - * @param array $request_data |
|
377 | - * @return array |
|
378 | - */ |
|
379 | - protected function _remove_unusable_characters_from_array(array $request_data) |
|
380 | - { |
|
381 | - $return_data = array(); |
|
382 | - foreach ($request_data as $key => $value) { |
|
383 | - $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
384 | - $value |
|
385 | - ); |
|
386 | - } |
|
387 | - return $return_data; |
|
388 | - } |
|
389 | - |
|
390 | - |
|
391 | - /** |
|
392 | - * Removes any non-printable illegal characters from the input, |
|
393 | - * which might cause a raucous when trying to insert into the database |
|
394 | - * |
|
395 | - * @param string $request_data |
|
396 | - * @return string |
|
397 | - */ |
|
398 | - protected function _remove_unusable_characters($request_data) |
|
399 | - { |
|
400 | - return preg_replace('/[^[:print:]]/', '', $request_data); |
|
401 | - } |
|
402 | - |
|
403 | - |
|
404 | - /** |
|
405 | - * Should be called just before displaying the payment attempt results to the user, |
|
406 | - * when the payment attempt has finished. Some payment methods may have special |
|
407 | - * logic to perform here. For example, if process_payment() happens on a special request |
|
408 | - * and then the user is redirected to a page that displays the payment's status, this |
|
409 | - * should be called while loading the page that displays the payment's status. If the user is |
|
410 | - * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
411 | - * provider. |
|
412 | - * |
|
413 | - * @param EE_Transaction|int $transaction |
|
414 | - * @param bool $update_txn whether or not to call |
|
415 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
416 | - * @return EE_Payment |
|
417 | - * @throws EE_Error |
|
418 | - * @throws InvalidArgumentException |
|
419 | - * @throws ReflectionException |
|
420 | - * @throws RuntimeException |
|
421 | - * @throws InvalidDataTypeException |
|
422 | - * @throws InvalidInterfaceException |
|
423 | - * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
424 | - * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
425 | - */ |
|
426 | - public function finalize_payment_for($transaction, $update_txn = true) |
|
427 | - { |
|
428 | - /** @var $transaction EE_Transaction */ |
|
429 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
430 | - $last_payment_method = $transaction->payment_method(); |
|
431 | - if ($last_payment_method instanceof EE_Payment_Method) { |
|
432 | - $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
433 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
434 | - return $payment; |
|
435 | - } |
|
436 | - return null; |
|
437 | - } |
|
438 | - |
|
439 | - |
|
440 | - /** |
|
441 | - * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
442 | - * |
|
443 | - * @param EE_Payment_Method $payment_method |
|
444 | - * @param EE_Payment $payment_to_refund |
|
445 | - * @param array $refund_info |
|
446 | - * @return EE_Payment |
|
447 | - * @throws EE_Error |
|
448 | - * @throws InvalidArgumentException |
|
449 | - * @throws ReflectionException |
|
450 | - * @throws RuntimeException |
|
451 | - * @throws InvalidDataTypeException |
|
452 | - * @throws InvalidInterfaceException |
|
453 | - */ |
|
454 | - public function process_refund( |
|
455 | - EE_Payment_Method $payment_method, |
|
456 | - EE_Payment $payment_to_refund, |
|
457 | - array $refund_info = array() |
|
458 | - ) { |
|
459 | - if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
460 | - $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
461 | - $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
462 | - } |
|
463 | - return $payment_to_refund; |
|
464 | - } |
|
465 | - |
|
466 | - |
|
467 | - /** |
|
468 | - * This should be called each time there may have been an update to a |
|
469 | - * payment on a transaction (ie, we asked for a payment to process a |
|
470 | - * payment for a transaction, or we told a payment method about an IPN, or |
|
471 | - * we told a payment method to |
|
472 | - * "finalize_payment_for" (a transaction), or we told a payment method to |
|
473 | - * process a refund. This should handle firing the correct hooks to |
|
474 | - * indicate |
|
475 | - * what exactly happened and updating the transaction appropriately). This |
|
476 | - * could be integrated directly into EE_Transaction upon save, but we want |
|
477 | - * this logic to be separate from 'normal' plain-jane saving and updating |
|
478 | - * of transactions and payments, and to be tied to payment processing. |
|
479 | - * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
480 | - * of previous code to decide whether or not to save (because the payment passed into |
|
481 | - * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
482 | - * in which case we only want that payment object for some temporary usage during this request, |
|
483 | - * but we don't want it to be saved). |
|
484 | - * |
|
485 | - * @param EE_Transaction|int $transaction |
|
486 | - * @param EE_Payment $payment |
|
487 | - * @param boolean $update_txn |
|
488 | - * whether or not to call |
|
489 | - * EE_Transaction_Processor:: |
|
490 | - * update_transaction_and_registrations_after_checkout_or_payment() |
|
491 | - * (you can save 1 DB query if you know you're going |
|
492 | - * to save it later instead) |
|
493 | - * @param bool $IPN |
|
494 | - * if processing IPNs or other similar payment |
|
495 | - * related activities that occur in alternate |
|
496 | - * requests than the main one that is processing the |
|
497 | - * TXN, then set this to true to check whether the |
|
498 | - * TXN is locked before updating |
|
499 | - * @throws EE_Error |
|
500 | - * @throws InvalidArgumentException |
|
501 | - * @throws ReflectionException |
|
502 | - * @throws RuntimeException |
|
503 | - * @throws InvalidDataTypeException |
|
504 | - * @throws InvalidInterfaceException |
|
505 | - */ |
|
506 | - public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
507 | - { |
|
508 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
509 | - /** @type EE_Transaction $transaction */ |
|
510 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
511 | - // can we freely update the TXN at this moment? |
|
512 | - if ($IPN && $transaction->is_locked()) { |
|
513 | - // don't update the transaction at this exact moment |
|
514 | - // because the TXN is active in another request |
|
515 | - EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
516 | - time(), |
|
517 | - $transaction->ID(), |
|
518 | - $payment->ID() |
|
519 | - ); |
|
520 | - } else { |
|
521 | - // verify payment and that it has been saved |
|
522 | - if ($payment instanceof EE_Payment && $payment->ID()) { |
|
523 | - if ($payment->payment_method() instanceof EE_Payment_Method |
|
524 | - && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
525 | - ) { |
|
526 | - $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
527 | - // update TXN registrations with payment info |
|
528 | - $this->process_registration_payments($transaction, $payment); |
|
529 | - } |
|
530 | - $do_action = $payment->just_approved() |
|
531 | - ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
532 | - : $do_action; |
|
533 | - } else { |
|
534 | - // send out notifications |
|
535 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
536 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
537 | - } |
|
538 | - if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
539 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
540 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
541 | - // set new value for total paid |
|
542 | - $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
543 | - // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
544 | - if ($update_txn) { |
|
545 | - $this->_post_payment_processing($transaction, $payment, $IPN); |
|
546 | - } |
|
547 | - } |
|
548 | - // granular hook for others to use. |
|
549 | - do_action($do_action, $transaction, $payment); |
|
550 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
551 | - // global hook for others to use. |
|
552 | - do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
553 | - } |
|
554 | - } |
|
555 | - |
|
556 | - |
|
557 | - /** |
|
558 | - * update registrations REG_paid field after successful payment and link registrations with payment |
|
559 | - * |
|
560 | - * @param EE_Transaction $transaction |
|
561 | - * @param EE_Payment $payment |
|
562 | - * @param EE_Registration[] $registrations |
|
563 | - * @throws EE_Error |
|
564 | - * @throws InvalidArgumentException |
|
565 | - * @throws RuntimeException |
|
566 | - * @throws InvalidDataTypeException |
|
567 | - * @throws InvalidInterfaceException |
|
568 | - */ |
|
569 | - public function process_registration_payments( |
|
570 | - EE_Transaction $transaction, |
|
571 | - EE_Payment $payment, |
|
572 | - array $registrations = array() |
|
573 | - ) { |
|
574 | - // only process if payment was successful |
|
575 | - if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
576 | - return; |
|
577 | - } |
|
578 | - // EEM_Registration::instance()->show_next_x_db_queries(); |
|
579 | - if (empty($registrations)) { |
|
580 | - // find registrations with monies owing that can receive a payment |
|
581 | - $registrations = $transaction->registrations( |
|
582 | - array( |
|
583 | - array( |
|
584 | - // only these reg statuses can receive payments |
|
585 | - 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
586 | - 'REG_final_price' => array('!=', 0), |
|
587 | - 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
588 | - ), |
|
589 | - ) |
|
590 | - ); |
|
591 | - } |
|
592 | - // still nothing ??!?? |
|
593 | - if (empty($registrations)) { |
|
594 | - return; |
|
595 | - } |
|
596 | - // todo: break out the following logic into a separate strategy class |
|
597 | - // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
598 | - // todo: which would apply payments using the capitalist "first come first paid" approach |
|
599 | - // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
600 | - // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
601 | - // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
602 | - $refund = $payment->is_a_refund(); |
|
603 | - // how much is available to apply to registrations? |
|
604 | - $available_payment_amount = abs($payment->amount()); |
|
605 | - foreach ($registrations as $registration) { |
|
606 | - if ($registration instanceof EE_Registration) { |
|
607 | - // nothing left? |
|
608 | - if ($available_payment_amount <= 0) { |
|
609 | - break; |
|
610 | - } |
|
611 | - if ($refund) { |
|
612 | - $available_payment_amount = $this->process_registration_refund( |
|
613 | - $registration, |
|
614 | - $payment, |
|
615 | - $available_payment_amount |
|
616 | - ); |
|
617 | - } else { |
|
618 | - $available_payment_amount = $this->process_registration_payment( |
|
619 | - $registration, |
|
620 | - $payment, |
|
621 | - $available_payment_amount |
|
622 | - ); |
|
623 | - } |
|
624 | - } |
|
625 | - } |
|
626 | - if ($available_payment_amount > 0 |
|
627 | - && apply_filters( |
|
628 | - 'FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', |
|
629 | - false |
|
630 | - )) { |
|
631 | - EE_Error::add_attention( |
|
632 | - sprintf( |
|
633 | - __( |
|
634 | - 'A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
635 | - 'event_espresso' |
|
636 | - ), |
|
637 | - EEH_Template::format_currency($available_payment_amount), |
|
638 | - implode(', ', array_keys($registrations)), |
|
639 | - '<br/>', |
|
640 | - EEH_Template::format_currency($payment->amount()) |
|
641 | - ), |
|
642 | - __FILE__, |
|
643 | - __FUNCTION__, |
|
644 | - __LINE__ |
|
645 | - ); |
|
646 | - } |
|
647 | - } |
|
648 | - |
|
649 | - |
|
650 | - /** |
|
651 | - * update registration REG_paid field after successful payment and link registration with payment |
|
652 | - * |
|
653 | - * @param EE_Registration $registration |
|
654 | - * @param EE_Payment $payment |
|
655 | - * @param float $available_payment_amount |
|
656 | - * @return float |
|
657 | - * @throws EE_Error |
|
658 | - * @throws InvalidArgumentException |
|
659 | - * @throws RuntimeException |
|
660 | - * @throws InvalidDataTypeException |
|
661 | - * @throws InvalidInterfaceException |
|
662 | - */ |
|
663 | - public function process_registration_payment( |
|
664 | - EE_Registration $registration, |
|
665 | - EE_Payment $payment, |
|
666 | - $available_payment_amount = 0.00 |
|
667 | - ) { |
|
668 | - $owing = $registration->final_price() - $registration->paid(); |
|
669 | - if ($owing > 0) { |
|
670 | - // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
671 | - $payment_amount = min($available_payment_amount, $owing); |
|
672 | - // update $available_payment_amount |
|
673 | - $available_payment_amount -= $payment_amount; |
|
674 | - // calculate and set new REG_paid |
|
675 | - $registration->set_paid($registration->paid() + $payment_amount); |
|
676 | - // now save it |
|
677 | - $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
678 | - } |
|
679 | - return $available_payment_amount; |
|
680 | - } |
|
681 | - |
|
682 | - |
|
683 | - /** |
|
684 | - * update registration REG_paid field after successful payment and link registration with payment |
|
685 | - * |
|
686 | - * @param EE_Registration $registration |
|
687 | - * @param EE_Payment $payment |
|
688 | - * @param float $payment_amount |
|
689 | - * @return void |
|
690 | - * @throws EE_Error |
|
691 | - * @throws InvalidArgumentException |
|
692 | - * @throws InvalidDataTypeException |
|
693 | - * @throws InvalidInterfaceException |
|
694 | - */ |
|
695 | - protected function _apply_registration_payment( |
|
696 | - EE_Registration $registration, |
|
697 | - EE_Payment $payment, |
|
698 | - $payment_amount = 0.00 |
|
699 | - ) { |
|
700 | - // find any existing reg payment records for this registration and payment |
|
701 | - $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
702 | - array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
703 | - ); |
|
704 | - // if existing registration payment exists |
|
705 | - if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
706 | - // then update that record |
|
707 | - $existing_reg_payment->set_amount($payment_amount); |
|
708 | - $existing_reg_payment->save(); |
|
709 | - } else { |
|
710 | - // or add new relation between registration and payment and set amount |
|
711 | - $registration->_add_relation_to( |
|
712 | - $payment, |
|
713 | - 'Payment', |
|
714 | - array('RPY_amount' => $payment_amount) |
|
715 | - ); |
|
716 | - // make it stick |
|
717 | - $registration->save(); |
|
718 | - } |
|
719 | - } |
|
720 | - |
|
721 | - |
|
722 | - /** |
|
723 | - * update registration REG_paid field after refund and link registration with payment |
|
724 | - * |
|
725 | - * @param EE_Registration $registration |
|
726 | - * @param EE_Payment $payment |
|
727 | - * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
728 | - * @return float |
|
729 | - * @throws EE_Error |
|
730 | - * @throws InvalidArgumentException |
|
731 | - * @throws RuntimeException |
|
732 | - * @throws InvalidDataTypeException |
|
733 | - * @throws InvalidInterfaceException |
|
734 | - */ |
|
735 | - public function process_registration_refund( |
|
736 | - EE_Registration $registration, |
|
737 | - EE_Payment $payment, |
|
738 | - $available_refund_amount = 0.00 |
|
739 | - ) { |
|
740 | - // EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
741 | - if ($registration->paid() > 0) { |
|
742 | - // ensure $available_refund_amount is NOT negative |
|
743 | - $available_refund_amount = (float) abs($available_refund_amount); |
|
744 | - // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
745 | - $refund_amount = min($available_refund_amount, (float) $registration->paid()); |
|
746 | - // update $available_payment_amount |
|
747 | - $available_refund_amount -= $refund_amount; |
|
748 | - // calculate and set new REG_paid |
|
749 | - $registration->set_paid($registration->paid() - $refund_amount); |
|
750 | - // convert payment amount back to a negative value for storage in the db |
|
751 | - $refund_amount = (float) abs($refund_amount) * -1; |
|
752 | - // now save it |
|
753 | - $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
754 | - } |
|
755 | - return $available_refund_amount; |
|
756 | - } |
|
757 | - |
|
758 | - |
|
759 | - /** |
|
760 | - * Process payments and transaction after payment process completed. |
|
761 | - * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
762 | - * if this request happens to be processing an IPN, |
|
763 | - * then we will also set the Payment Options Reg Step to completed, |
|
764 | - * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
765 | - * |
|
766 | - * @param EE_Transaction $transaction |
|
767 | - * @param EE_Payment $payment |
|
768 | - * @param bool $IPN |
|
769 | - * @throws EE_Error |
|
770 | - * @throws InvalidArgumentException |
|
771 | - * @throws ReflectionException |
|
772 | - * @throws RuntimeException |
|
773 | - * @throws InvalidDataTypeException |
|
774 | - * @throws InvalidInterfaceException |
|
775 | - */ |
|
776 | - protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
777 | - { |
|
778 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
779 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
780 | - // is the Payment Options Reg Step completed ? |
|
781 | - $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
782 | - // if the Payment Options Reg Step is completed... |
|
783 | - $revisit = $payment_options_step_completed === true; |
|
784 | - // then this is kinda sorta a revisit with regards to payments at least |
|
785 | - $transaction_processor->set_revisit($revisit); |
|
786 | - // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
787 | - if ($IPN |
|
788 | - && $payment_options_step_completed !== true |
|
789 | - && ($payment->is_approved() || $payment->is_pending()) |
|
790 | - ) { |
|
791 | - $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
792 | - 'payment_options' |
|
793 | - ); |
|
794 | - } |
|
795 | - // maybe update status, but don't save transaction just yet |
|
796 | - $transaction->update_status_based_on_total_paid(false); |
|
797 | - // check if 'finalize_registration' step has been completed... |
|
798 | - $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
799 | - // if this is an IPN and the final step has not been initiated |
|
800 | - if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
801 | - // and if it hasn't already been set as being started... |
|
802 | - $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
803 | - } |
|
804 | - $transaction->save(); |
|
805 | - // because the above will return false if the final step was not fully completed, we need to check again... |
|
806 | - if ($IPN && $finalized !== false) { |
|
807 | - // and if we are all good to go, then send out notifications |
|
808 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
809 | - // ok, now process the transaction according to the payment |
|
810 | - $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
811 | - $transaction, |
|
812 | - $payment |
|
813 | - ); |
|
814 | - } |
|
815 | - // DEBUG LOG |
|
816 | - $payment_method = $payment->payment_method(); |
|
817 | - if ($payment_method instanceof EE_Payment_Method) { |
|
818 | - $payment_method_type_obj = $payment_method->type_obj(); |
|
819 | - if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
820 | - $gateway = $payment_method_type_obj->get_gateway(); |
|
821 | - if ($gateway instanceof EE_Gateway) { |
|
822 | - $gateway->log( |
|
823 | - array( |
|
824 | - 'message' => (string) __('Post Payment Transaction Details', 'event_espresso'), |
|
825 | - 'transaction' => $transaction->model_field_array(), |
|
826 | - 'finalized' => $finalized, |
|
827 | - 'IPN' => $IPN, |
|
828 | - 'deliver_notifications' => has_filter( |
|
829 | - 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
830 | - ), |
|
831 | - ), |
|
832 | - $payment |
|
833 | - ); |
|
834 | - } |
|
835 | - } |
|
836 | - } |
|
837 | - } |
|
838 | - |
|
839 | - |
|
840 | - /** |
|
841 | - * Force posts to PayPal to use TLS v1.2. See: |
|
842 | - * https://core.trac.wordpress.org/ticket/36320 |
|
843 | - * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
844 | - * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
845 | - * This will affect PayPal standard, pro, express, and Payflow. |
|
846 | - * |
|
847 | - * @param $handle |
|
848 | - * @param $r |
|
849 | - * @param $url |
|
850 | - */ |
|
851 | - public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
852 | - { |
|
853 | - if (strpos($url, 'https://') !== false && strpos($url, '.paypal.com') !== false) { |
|
854 | - // Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
855 | - // instead of the constant because it might not be defined |
|
856 | - curl_setopt($handle, CURLOPT_SSLVERSION, 6); |
|
857 | - } |
|
858 | - } |
|
21 | + /** |
|
22 | + * @var EE_Payment_Processor $_instance |
|
23 | + * @access private |
|
24 | + */ |
|
25 | + private static $_instance; |
|
26 | + |
|
27 | + |
|
28 | + /** |
|
29 | + * @singleton method used to instantiate class object |
|
30 | + * @access public |
|
31 | + * @return EE_Payment_Processor instance |
|
32 | + */ |
|
33 | + public static function instance() |
|
34 | + { |
|
35 | + // check if class object is instantiated |
|
36 | + if (! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | + self::$_instance = new self(); |
|
38 | + } |
|
39 | + return self::$_instance; |
|
40 | + } |
|
41 | + |
|
42 | + |
|
43 | + /** |
|
44 | + * @return EE_Payment_Processor |
|
45 | + */ |
|
46 | + public static function reset() |
|
47 | + { |
|
48 | + self::$_instance = null; |
|
49 | + return self::instance(); |
|
50 | + } |
|
51 | + |
|
52 | + |
|
53 | + /** |
|
54 | + *private constructor to prevent direct creation |
|
55 | + * |
|
56 | + * @Constructor |
|
57 | + * @access private |
|
58 | + */ |
|
59 | + private function __construct() |
|
60 | + { |
|
61 | + do_action('AHEE__EE_Payment_Processor__construct'); |
|
62 | + add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
63 | + } |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
68 | + * appropriately. Saves the payment that is generated |
|
69 | + * |
|
70 | + * @param EE_Payment_Method $payment_method |
|
71 | + * @param EE_Transaction $transaction |
|
72 | + * @param float $amount if only part of the transaction is to be paid for, how much. |
|
73 | + * Leave null if payment is for the full amount owing |
|
74 | + * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
75 | + * Receive_form_submission() should have |
|
76 | + * already been called on the billing form |
|
77 | + * (ie, its inputs should have their normalized values set). |
|
78 | + * @param string $return_url string used mostly by offsite gateways to specify |
|
79 | + * where to go AFTER the offsite gateway |
|
80 | + * @param string $method like 'CART', indicates who the client who called this was |
|
81 | + * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
82 | + * @param boolean $update_txn whether or not to call |
|
83 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
84 | + * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
85 | + * @return EE_Payment |
|
86 | + * @throws EE_Error |
|
87 | + * @throws InvalidArgumentException |
|
88 | + * @throws ReflectionException |
|
89 | + * @throws RuntimeException |
|
90 | + * @throws InvalidDataTypeException |
|
91 | + * @throws InvalidInterfaceException |
|
92 | + */ |
|
93 | + public function process_payment( |
|
94 | + EE_Payment_Method $payment_method, |
|
95 | + EE_Transaction $transaction, |
|
96 | + $amount = null, |
|
97 | + $billing_form = null, |
|
98 | + $return_url = null, |
|
99 | + $method = 'CART', |
|
100 | + $by_admin = false, |
|
101 | + $update_txn = true, |
|
102 | + $cancel_url = '' |
|
103 | + ) { |
|
104 | + if ((float) $amount < 0) { |
|
105 | + throw new EE_Error( |
|
106 | + sprintf( |
|
107 | + __( |
|
108 | + 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
109 | + 'event_espresso' |
|
110 | + ), |
|
111 | + $amount, |
|
112 | + $transaction->ID() |
|
113 | + ) |
|
114 | + ); |
|
115 | + } |
|
116 | + // verify payment method |
|
117 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
118 | + $payment_method, |
|
119 | + true |
|
120 | + ); |
|
121 | + // verify transaction |
|
122 | + EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
123 | + $transaction->set_payment_method_ID($payment_method->ID()); |
|
124 | + // verify payment method type |
|
125 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
126 | + $payment = $payment_method->type_obj()->process_payment( |
|
127 | + $transaction, |
|
128 | + min($amount, $transaction->remaining()), // make sure we don't overcharge |
|
129 | + $billing_form, |
|
130 | + $return_url, |
|
131 | + add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
132 | + $method, |
|
133 | + $by_admin |
|
134 | + ); |
|
135 | + // check if payment method uses an off-site gateway |
|
136 | + if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
137 | + // don't process payments for off-site gateways yet because no payment has occurred yet |
|
138 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
139 | + } |
|
140 | + return $payment; |
|
141 | + } |
|
142 | + EE_Error::add_error( |
|
143 | + sprintf( |
|
144 | + __( |
|
145 | + 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
146 | + 'event_espresso' |
|
147 | + ), |
|
148 | + '<br/>', |
|
149 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
150 | + ), |
|
151 | + __FILE__, |
|
152 | + __FUNCTION__, |
|
153 | + __LINE__ |
|
154 | + ); |
|
155 | + return null; |
|
156 | + } |
|
157 | + |
|
158 | + |
|
159 | + /** |
|
160 | + * @param EE_Transaction|int $transaction |
|
161 | + * @param EE_Payment_Method $payment_method |
|
162 | + * @return string |
|
163 | + * @throws EE_Error |
|
164 | + * @throws InvalidArgumentException |
|
165 | + * @throws InvalidDataTypeException |
|
166 | + * @throws InvalidInterfaceException |
|
167 | + */ |
|
168 | + public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
169 | + { |
|
170 | + /** @type \EE_Transaction $transaction */ |
|
171 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
172 | + $primary_reg = $transaction->primary_registration(); |
|
173 | + if (! $primary_reg instanceof EE_Registration) { |
|
174 | + throw new EE_Error( |
|
175 | + sprintf( |
|
176 | + __( |
|
177 | + 'Cannot get IPN URL for transaction with ID %d because it has no primary registration', |
|
178 | + 'event_espresso' |
|
179 | + ), |
|
180 | + $transaction->ID() |
|
181 | + ) |
|
182 | + ); |
|
183 | + } |
|
184 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
185 | + $payment_method, |
|
186 | + true |
|
187 | + ); |
|
188 | + $url = add_query_arg( |
|
189 | + array( |
|
190 | + 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
191 | + 'ee_payment_method' => $payment_method->slug(), |
|
192 | + ), |
|
193 | + EE_Registry::instance()->CFG->core->txn_page_url() |
|
194 | + ); |
|
195 | + return $url; |
|
196 | + } |
|
197 | + |
|
198 | + |
|
199 | + /** |
|
200 | + * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
201 | + * we can easily find what registration the IPN is for and what payment method. |
|
202 | + * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
203 | + * If a payment is found for the IPN info, it is saved. |
|
204 | + * |
|
205 | + * @param array $_req_data eg $_REQUEST |
|
206 | + * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
207 | + * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
208 | + * @param boolean $update_txn whether or not to call |
|
209 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
210 | + * @param bool $separate_IPN_request whether the IPN uses a separate request (true, like PayPal) |
|
211 | + * or is processed manually (false, like Authorize.net) |
|
212 | + * @throws EE_Error |
|
213 | + * @throws Exception |
|
214 | + * @return EE_Payment |
|
215 | + * @throws \RuntimeException |
|
216 | + * @throws \ReflectionException |
|
217 | + * @throws \InvalidArgumentException |
|
218 | + * @throws InvalidInterfaceException |
|
219 | + * @throws InvalidDataTypeException |
|
220 | + */ |
|
221 | + public function process_ipn( |
|
222 | + $_req_data, |
|
223 | + $transaction = null, |
|
224 | + $payment_method = null, |
|
225 | + $update_txn = true, |
|
226 | + $separate_IPN_request = true |
|
227 | + ) { |
|
228 | + EE_Registry::instance()->load_model('Change_Log'); |
|
229 | + $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data); |
|
230 | + EE_Processor_Base::set_IPN($separate_IPN_request); |
|
231 | + $obj_for_log = null; |
|
232 | + if ($transaction instanceof EE_Transaction) { |
|
233 | + $obj_for_log = $transaction; |
|
234 | + if ($payment_method instanceof EE_Payment_Method) { |
|
235 | + $obj_for_log = EEM_Payment::instance()->get_one( |
|
236 | + array( |
|
237 | + array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
238 | + 'order_by' => array('PAY_timestamp' => 'desc'), |
|
239 | + ) |
|
240 | + ); |
|
241 | + } |
|
242 | + } elseif ($payment_method instanceof EE_Payment) { |
|
243 | + $obj_for_log = $payment_method; |
|
244 | + } |
|
245 | + $log = EEM_Change_Log::instance()->log( |
|
246 | + EEM_Change_Log::type_gateway, |
|
247 | + array('IPN data received' => $_req_data), |
|
248 | + $obj_for_log |
|
249 | + ); |
|
250 | + try { |
|
251 | + /** |
|
252 | + * @var EE_Payment $payment |
|
253 | + */ |
|
254 | + $payment = null; |
|
255 | + if ($transaction && $payment_method) { |
|
256 | + /** @type EE_Transaction $transaction */ |
|
257 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
258 | + /** @type EE_Payment_Method $payment_method */ |
|
259 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
260 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
261 | + try { |
|
262 | + $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
263 | + $log->set_object($payment); |
|
264 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
265 | + EEM_Change_Log::instance()->log( |
|
266 | + EEM_Change_Log::type_gateway, |
|
267 | + array( |
|
268 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
269 | + 'current_url' => EEH_URL::current_url(), |
|
270 | + 'payment' => $e->getPaymentProperties(), |
|
271 | + 'IPN_data' => $e->getIpnData(), |
|
272 | + ), |
|
273 | + $obj_for_log |
|
274 | + ); |
|
275 | + return $e->getPayment(); |
|
276 | + } |
|
277 | + } else { |
|
278 | + // not a payment |
|
279 | + EE_Error::add_error( |
|
280 | + sprintf( |
|
281 | + __( |
|
282 | + 'A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', |
|
283 | + 'event_espresso' |
|
284 | + ), |
|
285 | + '<br/>', |
|
286 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
287 | + ), |
|
288 | + __FILE__, |
|
289 | + __FUNCTION__, |
|
290 | + __LINE__ |
|
291 | + ); |
|
292 | + } |
|
293 | + } else { |
|
294 | + // that's actually pretty ok. The IPN just wasn't able |
|
295 | + // to identify which transaction or payment method this was for |
|
296 | + // give all active payment methods a chance to claim it |
|
297 | + $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
298 | + foreach ($active_payment_methods as $active_payment_method) { |
|
299 | + try { |
|
300 | + $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
301 | + $payment_method = $active_payment_method; |
|
302 | + EEM_Change_Log::instance()->log( |
|
303 | + EEM_Change_Log::type_gateway, |
|
304 | + array('IPN data' => $_req_data), |
|
305 | + $payment |
|
306 | + ); |
|
307 | + break; |
|
308 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
309 | + EEM_Change_Log::instance()->log( |
|
310 | + EEM_Change_Log::type_gateway, |
|
311 | + array( |
|
312 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
313 | + 'current_url' => EEH_URL::current_url(), |
|
314 | + 'payment' => $e->getPaymentProperties(), |
|
315 | + 'IPN_data' => $e->getIpnData(), |
|
316 | + ), |
|
317 | + $obj_for_log |
|
318 | + ); |
|
319 | + return $e->getPayment(); |
|
320 | + } catch (EE_Error $e) { |
|
321 | + // that's fine- it apparently couldn't handle the IPN |
|
322 | + } |
|
323 | + } |
|
324 | + } |
|
325 | + // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
326 | + if ($payment instanceof EE_Payment) { |
|
327 | + $payment->save(); |
|
328 | + // update the TXN |
|
329 | + $this->update_txn_based_on_payment( |
|
330 | + $transaction, |
|
331 | + $payment, |
|
332 | + $update_txn, |
|
333 | + $separate_IPN_request |
|
334 | + ); |
|
335 | + } else { |
|
336 | + // we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
337 | + if ($payment_method) { |
|
338 | + EEM_Change_Log::instance()->log( |
|
339 | + EEM_Change_Log::type_gateway, |
|
340 | + array('IPN data' => $_req_data), |
|
341 | + $payment_method |
|
342 | + ); |
|
343 | + } elseif ($transaction) { |
|
344 | + EEM_Change_Log::instance()->log( |
|
345 | + EEM_Change_Log::type_gateway, |
|
346 | + array('IPN data' => $_req_data), |
|
347 | + $transaction |
|
348 | + ); |
|
349 | + } |
|
350 | + } |
|
351 | + return $payment; |
|
352 | + } catch (EE_Error $e) { |
|
353 | + do_action( |
|
354 | + 'AHEE__log', |
|
355 | + __FILE__, |
|
356 | + __FUNCTION__, |
|
357 | + sprintf( |
|
358 | + __( |
|
359 | + 'Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', |
|
360 | + 'event_espresso' |
|
361 | + ), |
|
362 | + print_r($transaction, true), |
|
363 | + print_r($_req_data, true), |
|
364 | + $e->getMessage() |
|
365 | + ) |
|
366 | + ); |
|
367 | + throw $e; |
|
368 | + } |
|
369 | + } |
|
370 | + |
|
371 | + |
|
372 | + /** |
|
373 | + * Removes any non-printable illegal characters from the input, |
|
374 | + * which might cause a raucous when trying to insert into the database |
|
375 | + * |
|
376 | + * @param array $request_data |
|
377 | + * @return array |
|
378 | + */ |
|
379 | + protected function _remove_unusable_characters_from_array(array $request_data) |
|
380 | + { |
|
381 | + $return_data = array(); |
|
382 | + foreach ($request_data as $key => $value) { |
|
383 | + $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
384 | + $value |
|
385 | + ); |
|
386 | + } |
|
387 | + return $return_data; |
|
388 | + } |
|
389 | + |
|
390 | + |
|
391 | + /** |
|
392 | + * Removes any non-printable illegal characters from the input, |
|
393 | + * which might cause a raucous when trying to insert into the database |
|
394 | + * |
|
395 | + * @param string $request_data |
|
396 | + * @return string |
|
397 | + */ |
|
398 | + protected function _remove_unusable_characters($request_data) |
|
399 | + { |
|
400 | + return preg_replace('/[^[:print:]]/', '', $request_data); |
|
401 | + } |
|
402 | + |
|
403 | + |
|
404 | + /** |
|
405 | + * Should be called just before displaying the payment attempt results to the user, |
|
406 | + * when the payment attempt has finished. Some payment methods may have special |
|
407 | + * logic to perform here. For example, if process_payment() happens on a special request |
|
408 | + * and then the user is redirected to a page that displays the payment's status, this |
|
409 | + * should be called while loading the page that displays the payment's status. If the user is |
|
410 | + * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
411 | + * provider. |
|
412 | + * |
|
413 | + * @param EE_Transaction|int $transaction |
|
414 | + * @param bool $update_txn whether or not to call |
|
415 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
416 | + * @return EE_Payment |
|
417 | + * @throws EE_Error |
|
418 | + * @throws InvalidArgumentException |
|
419 | + * @throws ReflectionException |
|
420 | + * @throws RuntimeException |
|
421 | + * @throws InvalidDataTypeException |
|
422 | + * @throws InvalidInterfaceException |
|
423 | + * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
424 | + * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
425 | + */ |
|
426 | + public function finalize_payment_for($transaction, $update_txn = true) |
|
427 | + { |
|
428 | + /** @var $transaction EE_Transaction */ |
|
429 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
430 | + $last_payment_method = $transaction->payment_method(); |
|
431 | + if ($last_payment_method instanceof EE_Payment_Method) { |
|
432 | + $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
433 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
434 | + return $payment; |
|
435 | + } |
|
436 | + return null; |
|
437 | + } |
|
438 | + |
|
439 | + |
|
440 | + /** |
|
441 | + * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
442 | + * |
|
443 | + * @param EE_Payment_Method $payment_method |
|
444 | + * @param EE_Payment $payment_to_refund |
|
445 | + * @param array $refund_info |
|
446 | + * @return EE_Payment |
|
447 | + * @throws EE_Error |
|
448 | + * @throws InvalidArgumentException |
|
449 | + * @throws ReflectionException |
|
450 | + * @throws RuntimeException |
|
451 | + * @throws InvalidDataTypeException |
|
452 | + * @throws InvalidInterfaceException |
|
453 | + */ |
|
454 | + public function process_refund( |
|
455 | + EE_Payment_Method $payment_method, |
|
456 | + EE_Payment $payment_to_refund, |
|
457 | + array $refund_info = array() |
|
458 | + ) { |
|
459 | + if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
460 | + $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
461 | + $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
462 | + } |
|
463 | + return $payment_to_refund; |
|
464 | + } |
|
465 | + |
|
466 | + |
|
467 | + /** |
|
468 | + * This should be called each time there may have been an update to a |
|
469 | + * payment on a transaction (ie, we asked for a payment to process a |
|
470 | + * payment for a transaction, or we told a payment method about an IPN, or |
|
471 | + * we told a payment method to |
|
472 | + * "finalize_payment_for" (a transaction), or we told a payment method to |
|
473 | + * process a refund. This should handle firing the correct hooks to |
|
474 | + * indicate |
|
475 | + * what exactly happened and updating the transaction appropriately). This |
|
476 | + * could be integrated directly into EE_Transaction upon save, but we want |
|
477 | + * this logic to be separate from 'normal' plain-jane saving and updating |
|
478 | + * of transactions and payments, and to be tied to payment processing. |
|
479 | + * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
480 | + * of previous code to decide whether or not to save (because the payment passed into |
|
481 | + * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
482 | + * in which case we only want that payment object for some temporary usage during this request, |
|
483 | + * but we don't want it to be saved). |
|
484 | + * |
|
485 | + * @param EE_Transaction|int $transaction |
|
486 | + * @param EE_Payment $payment |
|
487 | + * @param boolean $update_txn |
|
488 | + * whether or not to call |
|
489 | + * EE_Transaction_Processor:: |
|
490 | + * update_transaction_and_registrations_after_checkout_or_payment() |
|
491 | + * (you can save 1 DB query if you know you're going |
|
492 | + * to save it later instead) |
|
493 | + * @param bool $IPN |
|
494 | + * if processing IPNs or other similar payment |
|
495 | + * related activities that occur in alternate |
|
496 | + * requests than the main one that is processing the |
|
497 | + * TXN, then set this to true to check whether the |
|
498 | + * TXN is locked before updating |
|
499 | + * @throws EE_Error |
|
500 | + * @throws InvalidArgumentException |
|
501 | + * @throws ReflectionException |
|
502 | + * @throws RuntimeException |
|
503 | + * @throws InvalidDataTypeException |
|
504 | + * @throws InvalidInterfaceException |
|
505 | + */ |
|
506 | + public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
507 | + { |
|
508 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
509 | + /** @type EE_Transaction $transaction */ |
|
510 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
511 | + // can we freely update the TXN at this moment? |
|
512 | + if ($IPN && $transaction->is_locked()) { |
|
513 | + // don't update the transaction at this exact moment |
|
514 | + // because the TXN is active in another request |
|
515 | + EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
516 | + time(), |
|
517 | + $transaction->ID(), |
|
518 | + $payment->ID() |
|
519 | + ); |
|
520 | + } else { |
|
521 | + // verify payment and that it has been saved |
|
522 | + if ($payment instanceof EE_Payment && $payment->ID()) { |
|
523 | + if ($payment->payment_method() instanceof EE_Payment_Method |
|
524 | + && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
525 | + ) { |
|
526 | + $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
527 | + // update TXN registrations with payment info |
|
528 | + $this->process_registration_payments($transaction, $payment); |
|
529 | + } |
|
530 | + $do_action = $payment->just_approved() |
|
531 | + ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
532 | + : $do_action; |
|
533 | + } else { |
|
534 | + // send out notifications |
|
535 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
536 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
537 | + } |
|
538 | + if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
539 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
540 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
541 | + // set new value for total paid |
|
542 | + $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
543 | + // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
544 | + if ($update_txn) { |
|
545 | + $this->_post_payment_processing($transaction, $payment, $IPN); |
|
546 | + } |
|
547 | + } |
|
548 | + // granular hook for others to use. |
|
549 | + do_action($do_action, $transaction, $payment); |
|
550 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
551 | + // global hook for others to use. |
|
552 | + do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
553 | + } |
|
554 | + } |
|
555 | + |
|
556 | + |
|
557 | + /** |
|
558 | + * update registrations REG_paid field after successful payment and link registrations with payment |
|
559 | + * |
|
560 | + * @param EE_Transaction $transaction |
|
561 | + * @param EE_Payment $payment |
|
562 | + * @param EE_Registration[] $registrations |
|
563 | + * @throws EE_Error |
|
564 | + * @throws InvalidArgumentException |
|
565 | + * @throws RuntimeException |
|
566 | + * @throws InvalidDataTypeException |
|
567 | + * @throws InvalidInterfaceException |
|
568 | + */ |
|
569 | + public function process_registration_payments( |
|
570 | + EE_Transaction $transaction, |
|
571 | + EE_Payment $payment, |
|
572 | + array $registrations = array() |
|
573 | + ) { |
|
574 | + // only process if payment was successful |
|
575 | + if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
576 | + return; |
|
577 | + } |
|
578 | + // EEM_Registration::instance()->show_next_x_db_queries(); |
|
579 | + if (empty($registrations)) { |
|
580 | + // find registrations with monies owing that can receive a payment |
|
581 | + $registrations = $transaction->registrations( |
|
582 | + array( |
|
583 | + array( |
|
584 | + // only these reg statuses can receive payments |
|
585 | + 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
586 | + 'REG_final_price' => array('!=', 0), |
|
587 | + 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
588 | + ), |
|
589 | + ) |
|
590 | + ); |
|
591 | + } |
|
592 | + // still nothing ??!?? |
|
593 | + if (empty($registrations)) { |
|
594 | + return; |
|
595 | + } |
|
596 | + // todo: break out the following logic into a separate strategy class |
|
597 | + // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
598 | + // todo: which would apply payments using the capitalist "first come first paid" approach |
|
599 | + // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
600 | + // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
601 | + // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
602 | + $refund = $payment->is_a_refund(); |
|
603 | + // how much is available to apply to registrations? |
|
604 | + $available_payment_amount = abs($payment->amount()); |
|
605 | + foreach ($registrations as $registration) { |
|
606 | + if ($registration instanceof EE_Registration) { |
|
607 | + // nothing left? |
|
608 | + if ($available_payment_amount <= 0) { |
|
609 | + break; |
|
610 | + } |
|
611 | + if ($refund) { |
|
612 | + $available_payment_amount = $this->process_registration_refund( |
|
613 | + $registration, |
|
614 | + $payment, |
|
615 | + $available_payment_amount |
|
616 | + ); |
|
617 | + } else { |
|
618 | + $available_payment_amount = $this->process_registration_payment( |
|
619 | + $registration, |
|
620 | + $payment, |
|
621 | + $available_payment_amount |
|
622 | + ); |
|
623 | + } |
|
624 | + } |
|
625 | + } |
|
626 | + if ($available_payment_amount > 0 |
|
627 | + && apply_filters( |
|
628 | + 'FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', |
|
629 | + false |
|
630 | + )) { |
|
631 | + EE_Error::add_attention( |
|
632 | + sprintf( |
|
633 | + __( |
|
634 | + 'A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
635 | + 'event_espresso' |
|
636 | + ), |
|
637 | + EEH_Template::format_currency($available_payment_amount), |
|
638 | + implode(', ', array_keys($registrations)), |
|
639 | + '<br/>', |
|
640 | + EEH_Template::format_currency($payment->amount()) |
|
641 | + ), |
|
642 | + __FILE__, |
|
643 | + __FUNCTION__, |
|
644 | + __LINE__ |
|
645 | + ); |
|
646 | + } |
|
647 | + } |
|
648 | + |
|
649 | + |
|
650 | + /** |
|
651 | + * update registration REG_paid field after successful payment and link registration with payment |
|
652 | + * |
|
653 | + * @param EE_Registration $registration |
|
654 | + * @param EE_Payment $payment |
|
655 | + * @param float $available_payment_amount |
|
656 | + * @return float |
|
657 | + * @throws EE_Error |
|
658 | + * @throws InvalidArgumentException |
|
659 | + * @throws RuntimeException |
|
660 | + * @throws InvalidDataTypeException |
|
661 | + * @throws InvalidInterfaceException |
|
662 | + */ |
|
663 | + public function process_registration_payment( |
|
664 | + EE_Registration $registration, |
|
665 | + EE_Payment $payment, |
|
666 | + $available_payment_amount = 0.00 |
|
667 | + ) { |
|
668 | + $owing = $registration->final_price() - $registration->paid(); |
|
669 | + if ($owing > 0) { |
|
670 | + // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
671 | + $payment_amount = min($available_payment_amount, $owing); |
|
672 | + // update $available_payment_amount |
|
673 | + $available_payment_amount -= $payment_amount; |
|
674 | + // calculate and set new REG_paid |
|
675 | + $registration->set_paid($registration->paid() + $payment_amount); |
|
676 | + // now save it |
|
677 | + $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
678 | + } |
|
679 | + return $available_payment_amount; |
|
680 | + } |
|
681 | + |
|
682 | + |
|
683 | + /** |
|
684 | + * update registration REG_paid field after successful payment and link registration with payment |
|
685 | + * |
|
686 | + * @param EE_Registration $registration |
|
687 | + * @param EE_Payment $payment |
|
688 | + * @param float $payment_amount |
|
689 | + * @return void |
|
690 | + * @throws EE_Error |
|
691 | + * @throws InvalidArgumentException |
|
692 | + * @throws InvalidDataTypeException |
|
693 | + * @throws InvalidInterfaceException |
|
694 | + */ |
|
695 | + protected function _apply_registration_payment( |
|
696 | + EE_Registration $registration, |
|
697 | + EE_Payment $payment, |
|
698 | + $payment_amount = 0.00 |
|
699 | + ) { |
|
700 | + // find any existing reg payment records for this registration and payment |
|
701 | + $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
702 | + array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
703 | + ); |
|
704 | + // if existing registration payment exists |
|
705 | + if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
706 | + // then update that record |
|
707 | + $existing_reg_payment->set_amount($payment_amount); |
|
708 | + $existing_reg_payment->save(); |
|
709 | + } else { |
|
710 | + // or add new relation between registration and payment and set amount |
|
711 | + $registration->_add_relation_to( |
|
712 | + $payment, |
|
713 | + 'Payment', |
|
714 | + array('RPY_amount' => $payment_amount) |
|
715 | + ); |
|
716 | + // make it stick |
|
717 | + $registration->save(); |
|
718 | + } |
|
719 | + } |
|
720 | + |
|
721 | + |
|
722 | + /** |
|
723 | + * update registration REG_paid field after refund and link registration with payment |
|
724 | + * |
|
725 | + * @param EE_Registration $registration |
|
726 | + * @param EE_Payment $payment |
|
727 | + * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
728 | + * @return float |
|
729 | + * @throws EE_Error |
|
730 | + * @throws InvalidArgumentException |
|
731 | + * @throws RuntimeException |
|
732 | + * @throws InvalidDataTypeException |
|
733 | + * @throws InvalidInterfaceException |
|
734 | + */ |
|
735 | + public function process_registration_refund( |
|
736 | + EE_Registration $registration, |
|
737 | + EE_Payment $payment, |
|
738 | + $available_refund_amount = 0.00 |
|
739 | + ) { |
|
740 | + // EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
741 | + if ($registration->paid() > 0) { |
|
742 | + // ensure $available_refund_amount is NOT negative |
|
743 | + $available_refund_amount = (float) abs($available_refund_amount); |
|
744 | + // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
745 | + $refund_amount = min($available_refund_amount, (float) $registration->paid()); |
|
746 | + // update $available_payment_amount |
|
747 | + $available_refund_amount -= $refund_amount; |
|
748 | + // calculate and set new REG_paid |
|
749 | + $registration->set_paid($registration->paid() - $refund_amount); |
|
750 | + // convert payment amount back to a negative value for storage in the db |
|
751 | + $refund_amount = (float) abs($refund_amount) * -1; |
|
752 | + // now save it |
|
753 | + $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
754 | + } |
|
755 | + return $available_refund_amount; |
|
756 | + } |
|
757 | + |
|
758 | + |
|
759 | + /** |
|
760 | + * Process payments and transaction after payment process completed. |
|
761 | + * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
762 | + * if this request happens to be processing an IPN, |
|
763 | + * then we will also set the Payment Options Reg Step to completed, |
|
764 | + * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
765 | + * |
|
766 | + * @param EE_Transaction $transaction |
|
767 | + * @param EE_Payment $payment |
|
768 | + * @param bool $IPN |
|
769 | + * @throws EE_Error |
|
770 | + * @throws InvalidArgumentException |
|
771 | + * @throws ReflectionException |
|
772 | + * @throws RuntimeException |
|
773 | + * @throws InvalidDataTypeException |
|
774 | + * @throws InvalidInterfaceException |
|
775 | + */ |
|
776 | + protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
777 | + { |
|
778 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
779 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
780 | + // is the Payment Options Reg Step completed ? |
|
781 | + $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
782 | + // if the Payment Options Reg Step is completed... |
|
783 | + $revisit = $payment_options_step_completed === true; |
|
784 | + // then this is kinda sorta a revisit with regards to payments at least |
|
785 | + $transaction_processor->set_revisit($revisit); |
|
786 | + // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
787 | + if ($IPN |
|
788 | + && $payment_options_step_completed !== true |
|
789 | + && ($payment->is_approved() || $payment->is_pending()) |
|
790 | + ) { |
|
791 | + $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
792 | + 'payment_options' |
|
793 | + ); |
|
794 | + } |
|
795 | + // maybe update status, but don't save transaction just yet |
|
796 | + $transaction->update_status_based_on_total_paid(false); |
|
797 | + // check if 'finalize_registration' step has been completed... |
|
798 | + $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
799 | + // if this is an IPN and the final step has not been initiated |
|
800 | + if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
801 | + // and if it hasn't already been set as being started... |
|
802 | + $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
803 | + } |
|
804 | + $transaction->save(); |
|
805 | + // because the above will return false if the final step was not fully completed, we need to check again... |
|
806 | + if ($IPN && $finalized !== false) { |
|
807 | + // and if we are all good to go, then send out notifications |
|
808 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
809 | + // ok, now process the transaction according to the payment |
|
810 | + $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
811 | + $transaction, |
|
812 | + $payment |
|
813 | + ); |
|
814 | + } |
|
815 | + // DEBUG LOG |
|
816 | + $payment_method = $payment->payment_method(); |
|
817 | + if ($payment_method instanceof EE_Payment_Method) { |
|
818 | + $payment_method_type_obj = $payment_method->type_obj(); |
|
819 | + if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
820 | + $gateway = $payment_method_type_obj->get_gateway(); |
|
821 | + if ($gateway instanceof EE_Gateway) { |
|
822 | + $gateway->log( |
|
823 | + array( |
|
824 | + 'message' => (string) __('Post Payment Transaction Details', 'event_espresso'), |
|
825 | + 'transaction' => $transaction->model_field_array(), |
|
826 | + 'finalized' => $finalized, |
|
827 | + 'IPN' => $IPN, |
|
828 | + 'deliver_notifications' => has_filter( |
|
829 | + 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
830 | + ), |
|
831 | + ), |
|
832 | + $payment |
|
833 | + ); |
|
834 | + } |
|
835 | + } |
|
836 | + } |
|
837 | + } |
|
838 | + |
|
839 | + |
|
840 | + /** |
|
841 | + * Force posts to PayPal to use TLS v1.2. See: |
|
842 | + * https://core.trac.wordpress.org/ticket/36320 |
|
843 | + * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
844 | + * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
845 | + * This will affect PayPal standard, pro, express, and Payflow. |
|
846 | + * |
|
847 | + * @param $handle |
|
848 | + * @param $r |
|
849 | + * @param $url |
|
850 | + */ |
|
851 | + public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
852 | + { |
|
853 | + if (strpos($url, 'https://') !== false && strpos($url, '.paypal.com') !== false) { |
|
854 | + // Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
855 | + // instead of the constant because it might not be defined |
|
856 | + curl_setopt($handle, CURLOPT_SSLVERSION, 6); |
|
857 | + } |
|
858 | + } |
|
859 | 859 | } |
@@ -12,562 +12,562 @@ |
||
12 | 12 | class EE_Event_Registrations_List_Table extends EE_Admin_List_Table |
13 | 13 | { |
14 | 14 | |
15 | - /** |
|
16 | - * This property will hold the related Datetimes on an event IF the event id is included in the request. |
|
17 | - * |
|
18 | - * @var EE_Datetime[] |
|
19 | - */ |
|
20 | - protected $_dtts_for_event = array(); |
|
21 | - |
|
22 | - |
|
23 | - /** |
|
24 | - * The event if one is specified in the request |
|
25 | - * |
|
26 | - * @var EE_Event |
|
27 | - */ |
|
28 | - protected $_evt = null; |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * The DTT_ID if the current view has a specified datetime. |
|
33 | - * |
|
34 | - * @var int $_cur_dtt_id |
|
35 | - */ |
|
36 | - protected $_cur_dtt_id = 0; |
|
37 | - |
|
38 | - |
|
39 | - /** |
|
40 | - * EE_Event_Registrations_List_Table constructor. |
|
41 | - * |
|
42 | - * @param \Registrations_Admin_Page $admin_page |
|
43 | - */ |
|
44 | - public function __construct($admin_page) |
|
45 | - { |
|
46 | - parent::__construct($admin_page); |
|
47 | - $this->_status = $this->_admin_page->get_registration_status_array(); |
|
48 | - } |
|
49 | - |
|
50 | - |
|
51 | - protected function _setup_data() |
|
52 | - { |
|
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 | - $this->_all_data_count = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees( |
|
56 | - $this->_per_page, |
|
57 | - true |
|
58 | - ) : $this->_admin_page->get_event_attendees($this->_per_page, true, true); |
|
59 | - } |
|
60 | - |
|
61 | - |
|
62 | - protected function _set_properties() |
|
63 | - { |
|
64 | - $evt_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
65 | - $this->_wp_list_args = array( |
|
66 | - 'singular' => __('registrant', 'event_espresso'), |
|
67 | - 'plural' => __('registrants', 'event_espresso'), |
|
68 | - 'ajax' => true, |
|
69 | - 'screen' => $this->_admin_page->get_current_screen()->id, |
|
70 | - ); |
|
71 | - $columns = array(); |
|
72 | - // $columns['_Reg_Status'] = ''; |
|
73 | - if (! empty($evt_id)) { |
|
74 | - $columns['cb'] = '<input type="checkbox" />'; // Render a checkbox instead of text |
|
75 | - $this->_has_checkbox_column = true; |
|
76 | - } |
|
77 | - $this->_columns = array( |
|
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'), |
|
86 | - ); |
|
87 | - $this->_columns = array_merge($columns, $this->_columns); |
|
88 | - $this->_primary_column = '_REG_att_checked_in'; |
|
89 | - if (! empty($evt_id) |
|
90 | - && EE_Registry::instance()->CAP->current_user_can( |
|
91 | - 'ee_read_registrations', |
|
92 | - 'espresso_registrations_registrations_reports', |
|
93 | - $evt_id |
|
94 | - ) |
|
95 | - ) { |
|
96 | - $this->_bottom_buttons = array( |
|
97 | - 'report' => array( |
|
98 | - 'route' => 'registrations_report', |
|
99 | - 'extra_request' => |
|
100 | - array( |
|
101 | - 'EVT_ID' => $evt_id, |
|
102 | - 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
103 | - ), |
|
104 | - ), |
|
105 | - ); |
|
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 | - ); |
|
129 | - $this->_sortable_columns = array( |
|
130 | - /** |
|
131 | - * Allows users to change the default sort if they wish. |
|
132 | - * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name. |
|
133 | - * |
|
134 | - * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to |
|
135 | - * change the sorts on any list table involving registration contacts. If you want to only change the filter |
|
136 | - * for a specific list table you can use the provided reference to this object instance. |
|
137 | - */ |
|
138 | - 'ATT_name' => array( |
|
139 | - 'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name', |
|
140 | - true, |
|
141 | - $this, |
|
142 | - ) |
|
143 | - ? array('ATT_lname' => true) |
|
144 | - : array('ATT_fname' => true), |
|
145 | - 'Event' => array('Event.EVT_name' => false), |
|
146 | - ); |
|
147 | - $this->_hidden_columns = array(); |
|
148 | - $this->_evt = EEM_Event::instance()->get_one_by_ID($evt_id); |
|
149 | - $this->_dtts_for_event = $this->_evt instanceof EE_Event ? $this->_evt->datetimes_ordered() : array(); |
|
150 | - } |
|
151 | - |
|
152 | - |
|
153 | - /** |
|
154 | - * @param \EE_Registration $item |
|
155 | - * @return string |
|
156 | - */ |
|
157 | - protected function _get_row_class($item) |
|
158 | - { |
|
159 | - $class = parent::_get_row_class($item); |
|
160 | - // add status class |
|
161 | - $class .= ' ee-status-strip reg-status-' . $item->status_ID(); |
|
162 | - if ($this->_has_checkbox_column) { |
|
163 | - $class .= ' has-checkbox-column'; |
|
164 | - } |
|
165 | - return $class; |
|
166 | - } |
|
167 | - |
|
168 | - |
|
169 | - /** |
|
170 | - * @return array |
|
171 | - * @throws \EE_Error |
|
172 | - */ |
|
173 | - protected function _get_table_filters() |
|
174 | - { |
|
175 | - $filters = $where = array(); |
|
176 | - $current_EVT_ID = isset($this->_req_data['event_id']) ? (int) $this->_req_data['event_id'] : 0; |
|
177 | - if (empty($this->_dtts_for_event) || count($this->_dtts_for_event) === 1) { |
|
178 | - // this means we don't have an event so let's setup a filter dropdown for all the events to select |
|
179 | - // note possible capability restrictions |
|
180 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) { |
|
181 | - $where['status**'] = array('!=', 'private'); |
|
182 | - } |
|
183 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) { |
|
184 | - $where['EVT_wp_user'] = get_current_user_id(); |
|
185 | - } |
|
186 | - $events = EEM_Event::instance()->get_all( |
|
187 | - array( |
|
188 | - $where, |
|
189 | - 'order_by' => array('Datetime.DTT_EVT_start' => 'DESC'), |
|
190 | - ) |
|
191 | - ); |
|
192 | - $evts[] = array( |
|
193 | - 'id' => 0, |
|
194 | - 'text' => __('To toggle Check-in status, select an event', 'event_espresso'), |
|
195 | - ); |
|
196 | - $checked = 'checked'; |
|
197 | - /** @var EE_Event $evt */ |
|
198 | - foreach ($events as $evt) { |
|
199 | - // any registrations for this event? |
|
200 | - if (! $evt->get_count_of_all_registrations()) { |
|
201 | - continue; |
|
202 | - } |
|
203 | - $evts[] = array( |
|
204 | - 'id' => $evt->ID(), |
|
205 | - 'text' => apply_filters( |
|
206 | - 'FHEE__EE_Event_Registrations___get_table_filters__event_name', |
|
207 | - $evt->get('EVT_name'), |
|
208 | - $evt |
|
209 | - ), |
|
210 | - 'class' => $evt->is_expired() ? 'ee-expired-event' : '', |
|
211 | - ); |
|
212 | - if ($evt->ID() === $current_EVT_ID && $evt->is_expired()) { |
|
213 | - $checked = ''; |
|
214 | - } |
|
215 | - } |
|
216 | - $event_filter = '<div class="ee-event-filter">'; |
|
217 | - $event_filter .= EEH_Form_Fields::select_input('event_id', $evts, $current_EVT_ID); |
|
218 | - $event_filter .= '<span class="ee-event-filter-toggle">'; |
|
219 | - $event_filter .= '<input type="checkbox" id="js-ee-hide-expired-events" ' . $checked . '> '; |
|
220 | - $event_filter .= __('Hide Expired Events', 'event_espresso'); |
|
221 | - $event_filter .= '</span>'; |
|
222 | - $event_filter .= '</div>'; |
|
223 | - $filters[] = $event_filter; |
|
224 | - } |
|
225 | - if (! empty($this->_dtts_for_event)) { |
|
226 | - // DTT datetimes filter |
|
227 | - $this->_cur_dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0; |
|
228 | - if (count($this->_dtts_for_event) > 1) { |
|
229 | - $dtts[0] = __('To toggle check-in status, select a datetime.', 'event_espresso'); |
|
230 | - foreach ($this->_dtts_for_event as $dtt) { |
|
231 | - $datetime_string = $dtt->name(); |
|
232 | - $datetime_string = ! empty($datetime_string) ? ' (' . $datetime_string . ')' : ''; |
|
233 | - $datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time() . $datetime_string; |
|
234 | - $dtts[ $dtt->ID() ] = $datetime_string; |
|
235 | - } |
|
236 | - $input = new EE_Select_Input( |
|
237 | - $dtts, |
|
238 | - array( |
|
239 | - 'html_name' => 'DTT_ID', |
|
240 | - 'html_id' => 'DTT_ID', |
|
241 | - 'default' => $this->_cur_dtt_id, |
|
242 | - ) |
|
243 | - ); |
|
244 | - $filters[] = $input->get_html_for_input(); |
|
245 | - $filters[] = '<input type="hidden" name="event_id" value="' . $current_EVT_ID . '">'; |
|
246 | - } |
|
247 | - } |
|
248 | - return $filters; |
|
249 | - } |
|
250 | - |
|
251 | - |
|
252 | - protected function _add_view_counts() |
|
253 | - { |
|
254 | - $this->_views['all']['count'] = $this->_get_total_event_attendees(); |
|
255 | - } |
|
256 | - |
|
257 | - |
|
258 | - /** |
|
259 | - * @return int |
|
260 | - * @throws \EE_Error |
|
261 | - */ |
|
262 | - protected function _get_total_event_attendees() |
|
263 | - { |
|
264 | - $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
265 | - $DTT_ID = $this->_cur_dtt_id; |
|
266 | - $query_params = array(); |
|
267 | - if ($EVT_ID) { |
|
268 | - $query_params[0]['EVT_ID'] = $EVT_ID; |
|
269 | - } |
|
270 | - // if DTT is included we only show for that datetime. Otherwise we're showing for all datetimes (the event). |
|
271 | - if ($DTT_ID) { |
|
272 | - $query_params[0]['Ticket.Datetime.DTT_ID'] = $DTT_ID; |
|
273 | - } |
|
274 | - $status_ids_array = apply_filters( |
|
275 | - 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
276 | - array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
277 | - ); |
|
278 | - $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
279 | - return EEM_Registration::instance()->count($query_params); |
|
280 | - } |
|
281 | - |
|
282 | - |
|
283 | - /** |
|
284 | - * @param \EE_Registration $item |
|
285 | - * @return string |
|
286 | - */ |
|
287 | - public function column__Reg_Status(EE_Registration $item) |
|
288 | - { |
|
289 | - return '<span class="ee-status-strip ee-status-strip-td reg-status-' . $item->status_ID() . '"></span>'; |
|
290 | - } |
|
291 | - |
|
292 | - |
|
293 | - /** |
|
294 | - * @param \EE_Registration $item |
|
295 | - * @return string |
|
296 | - * @throws \EE_Error |
|
297 | - */ |
|
298 | - public function column_cb($item) |
|
299 | - { |
|
300 | - return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID()); |
|
301 | - } |
|
302 | - |
|
303 | - |
|
304 | - /** |
|
305 | - * column_REG_att_checked_in |
|
306 | - * |
|
307 | - * @param EE_Registration $item |
|
308 | - * @return string |
|
309 | - * @throws EE_Error |
|
310 | - * @throws InvalidArgumentException |
|
311 | - * @throws InvalidDataTypeException |
|
312 | - * @throws InvalidInterfaceException |
|
313 | - */ |
|
314 | - public function column__REG_att_checked_in(EE_Registration $item) |
|
315 | - { |
|
316 | - $attendee = $item->attendee(); |
|
317 | - $attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : ''; |
|
318 | - |
|
319 | - if ($this->_cur_dtt_id === 0 && count($this->_dtts_for_event) === 1) { |
|
320 | - $latest_related_datetime = $item->get_latest_related_datetime(); |
|
321 | - if ($latest_related_datetime instanceof EE_Datetime) { |
|
322 | - $this->_cur_dtt_id = $latest_related_datetime->ID(); |
|
323 | - } |
|
324 | - } |
|
325 | - $checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId( |
|
326 | - $item, |
|
327 | - $this->_cur_dtt_id |
|
328 | - ); |
|
329 | - $nonce = wp_create_nonce('checkin_nonce'); |
|
330 | - $toggle_active = ! empty($this->_cur_dtt_id) |
|
331 | - && EE_Registry::instance()->CAP->current_user_can( |
|
332 | - 'ee_edit_checkin', |
|
333 | - 'espresso_registrations_toggle_checkin_status', |
|
334 | - $item->ID() |
|
335 | - ) |
|
336 | - ? ' clickable trigger-checkin' |
|
337 | - : ''; |
|
338 | - $mobile_view_content = ' <span class="show-on-mobile-view-only">' . $attendee_name . '</span>'; |
|
339 | - return '<span class="' . $checkin_status_dashicon->cssClasses() . $toggle_active . '"' |
|
340 | - . ' data-_regid="' . $item->ID() . '"' |
|
341 | - . ' data-dttid="' . $this->_cur_dtt_id . '"' |
|
342 | - . ' data-nonce="' . $nonce . '">' |
|
343 | - . '</span>' |
|
344 | - . $mobile_view_content; |
|
345 | - } |
|
346 | - |
|
347 | - |
|
348 | - /** |
|
349 | - * @param \EE_Registration $item |
|
350 | - * @return mixed|string|void |
|
351 | - * @throws \EE_Error |
|
352 | - */ |
|
353 | - public function column_ATT_name(EE_Registration $item) |
|
354 | - { |
|
355 | - $attendee = $item->attendee(); |
|
356 | - if (! $attendee instanceof EE_Attendee) { |
|
357 | - return __('No contact record for this registration.', 'event_espresso'); |
|
358 | - } |
|
359 | - // edit attendee link |
|
360 | - $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
361 | - array('action' => 'view_registration', '_REG_ID' => $item->ID()), |
|
362 | - REG_ADMIN_URL |
|
363 | - ); |
|
364 | - $name_link = EE_Registry::instance()->CAP->current_user_can( |
|
365 | - 'ee_edit_contacts', |
|
366 | - 'espresso_registrations_edit_attendee' |
|
367 | - ) |
|
368 | - ? '<a href="' . $edit_lnk_url . '" title="' . esc_attr__('View Registration Details', 'event_espresso') . '">' |
|
369 | - . $item->attendee()->full_name() |
|
370 | - . '</a>' |
|
371 | - : $item->attendee()->full_name(); |
|
372 | - $name_link .= $item->count() === 1 |
|
373 | - ? ' <sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup> ' |
|
374 | - : ''; |
|
375 | - // add group details |
|
376 | - $name_link .= ' ' . sprintf(__('(%s of %s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
377 | - // add regcode |
|
378 | - $link = EE_Admin_Page::add_query_args_and_nonce( |
|
379 | - array('action' => 'view_registration', '_REG_ID' => $item->ID()), |
|
380 | - REG_ADMIN_URL |
|
381 | - ); |
|
382 | - $name_link .= '<br>'; |
|
383 | - $name_link .= EE_Registry::instance()->instance()->CAP->current_user_can( |
|
384 | - 'ee_read_registration', |
|
385 | - 'view_registration', |
|
386 | - $item->ID() |
|
387 | - ) |
|
388 | - ? '<a href="' . $link . '" title="' . esc_attr__('View Registration Details', 'event_espresso') . '">' |
|
389 | - . $item->reg_code() |
|
390 | - . '</a>' |
|
391 | - : $item->reg_code(); |
|
392 | - // status |
|
393 | - $name_link .= '<br><span class="ee-status-text-small">'; |
|
394 | - $name_link .= EEH_Template::pretty_status($item->status_ID(), false, 'sentence'); |
|
395 | - $name_link .= '</span>'; |
|
396 | - $actions = array(); |
|
397 | - $DTT_ID = $this->_cur_dtt_id; |
|
398 | - $latest_related_datetime = empty($DTT_ID) && ! empty($this->_req_data['event_id']) && $item instanceof EE_Registration |
|
399 | - ? $item->get_latest_related_datetime() |
|
400 | - : null; |
|
401 | - $DTT_ID = $latest_related_datetime instanceof EE_Datetime |
|
402 | - ? $latest_related_datetime->ID() |
|
403 | - : $DTT_ID; |
|
404 | - if (! empty($DTT_ID) |
|
405 | - && EE_Registry::instance()->CAP->current_user_can( |
|
406 | - 'ee_read_checkins', |
|
407 | - 'espresso_registrations_registration_checkins' |
|
408 | - ) |
|
409 | - ) { |
|
410 | - $checkin_list_url = EE_Admin_Page::add_query_args_and_nonce( |
|
411 | - array('action' => 'registration_checkins', '_REG_ID' => $item->ID(), 'DTT_ID' => $DTT_ID), |
|
412 | - REG_ADMIN_URL |
|
413 | - ); |
|
414 | - // get the timestamps for this registration's checkins, related to the selected datetime |
|
415 | - $timestamps = $item->get_many_related('Checkin', array(array('DTT_ID' => $DTT_ID))); |
|
416 | - if (! empty($timestamps)) { |
|
417 | - // get the last timestamp |
|
418 | - $last_timestamp = end($timestamps); |
|
419 | - // checked in or checked out? |
|
420 | - $checkin_status = $last_timestamp->get('CHK_in') |
|
421 | - ? esc_html__('Checked In', 'event_espresso') |
|
422 | - : esc_html__('Checked Out', 'event_espresso'); |
|
423 | - // get timestamp string |
|
424 | - $timestamp_string = $last_timestamp->get_datetime('CHK_timestamp'); |
|
425 | - $actions['checkin'] = '<a href="' . $checkin_list_url . '" title="' |
|
426 | - . esc_attr__( |
|
427 | - 'View this registrant\'s check-ins/checkouts for the datetime', |
|
428 | - 'event_espresso' |
|
429 | - ) . '">' . $checkin_status . ': ' . $timestamp_string . '</a>'; |
|
430 | - } |
|
431 | - } |
|
432 | - return (! empty($DTT_ID) && ! empty($timestamps)) |
|
433 | - ? sprintf('%1$s %2$s', $name_link, $this->row_actions($actions, true)) |
|
434 | - : $name_link; |
|
435 | - } |
|
436 | - |
|
437 | - |
|
438 | - /** |
|
439 | - * @param \EE_Registration $item |
|
440 | - * @return string |
|
441 | - */ |
|
442 | - public function column_ATT_email(EE_Registration $item) |
|
443 | - { |
|
444 | - $attendee = $item->attendee(); |
|
445 | - return $attendee instanceof EE_Attendee ? $attendee->email() : ''; |
|
446 | - } |
|
447 | - |
|
448 | - |
|
449 | - /** |
|
450 | - * @param \EE_Registration $item |
|
451 | - * @return bool|string |
|
452 | - * @throws \EE_Error |
|
453 | - */ |
|
454 | - public function column_Event(EE_Registration $item) |
|
455 | - { |
|
456 | - try { |
|
457 | - $event = $this->_evt instanceof EE_Event ? $this->_evt : $item->event(); |
|
458 | - $chkin_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
459 | - array('action' => 'event_registrations', 'event_id' => $event->ID()), |
|
460 | - REG_ADMIN_URL |
|
461 | - ); |
|
462 | - $event_label = EE_Registry::instance()->CAP->current_user_can( |
|
463 | - 'ee_read_checkins', |
|
464 | - 'espresso_registrations_registration_checkins' |
|
465 | - ) ? '<a href="' . $chkin_lnk_url . '" title="' |
|
466 | - . esc_attr__( |
|
467 | - 'View Checkins for this Event', |
|
468 | - 'event_espresso' |
|
469 | - ) . '">' . $event->name() . '</a>' : $event->name(); |
|
470 | - } catch (\EventEspresso\core\exceptions\EntityNotFoundException $e) { |
|
471 | - $event_label = esc_html__('Unknown', 'event_espresso'); |
|
472 | - } |
|
473 | - return $event_label; |
|
474 | - } |
|
475 | - |
|
476 | - |
|
477 | - /** |
|
478 | - * @param \EE_Registration $item |
|
479 | - * @return mixed|string|void |
|
480 | - */ |
|
481 | - public function column_PRC_name(EE_Registration $item) |
|
482 | - { |
|
483 | - return $item->ticket() instanceof EE_Ticket ? $item->ticket()->name() : __("Unknown", "event_espresso"); |
|
484 | - } |
|
485 | - |
|
486 | - |
|
487 | - /** |
|
488 | - * column_REG_final_price |
|
489 | - * |
|
490 | - * @param \EE_Registration $item |
|
491 | - * @return string |
|
492 | - */ |
|
493 | - public function column__REG_final_price(EE_Registration $item) |
|
494 | - { |
|
495 | - return '<span class="reg-pad-rght">' . ' ' . $item->pretty_final_price() . '</span>'; |
|
496 | - } |
|
497 | - |
|
498 | - |
|
499 | - /** |
|
500 | - * column_TXN_paid |
|
501 | - * |
|
502 | - * @param \EE_Registration $item |
|
503 | - * @return string |
|
504 | - * @throws \EE_Error |
|
505 | - */ |
|
506 | - public function column_TXN_paid(EE_Registration $item) |
|
507 | - { |
|
508 | - if ($item->count() === 1) { |
|
509 | - if ($item->transaction()->paid() >= $item->transaction()->total()) { |
|
510 | - return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>'; |
|
511 | - } else { |
|
512 | - $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
513 | - array('action' => 'view_transaction', 'TXN_ID' => $item->transaction_ID()), |
|
514 | - TXN_ADMIN_URL |
|
515 | - ); |
|
516 | - return EE_Registry::instance()->CAP->current_user_can( |
|
517 | - 'ee_read_transaction', |
|
518 | - 'espresso_transactions_view_transaction' |
|
519 | - ) ? ' |
|
15 | + /** |
|
16 | + * This property will hold the related Datetimes on an event IF the event id is included in the request. |
|
17 | + * |
|
18 | + * @var EE_Datetime[] |
|
19 | + */ |
|
20 | + protected $_dtts_for_event = array(); |
|
21 | + |
|
22 | + |
|
23 | + /** |
|
24 | + * The event if one is specified in the request |
|
25 | + * |
|
26 | + * @var EE_Event |
|
27 | + */ |
|
28 | + protected $_evt = null; |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * The DTT_ID if the current view has a specified datetime. |
|
33 | + * |
|
34 | + * @var int $_cur_dtt_id |
|
35 | + */ |
|
36 | + protected $_cur_dtt_id = 0; |
|
37 | + |
|
38 | + |
|
39 | + /** |
|
40 | + * EE_Event_Registrations_List_Table constructor. |
|
41 | + * |
|
42 | + * @param \Registrations_Admin_Page $admin_page |
|
43 | + */ |
|
44 | + public function __construct($admin_page) |
|
45 | + { |
|
46 | + parent::__construct($admin_page); |
|
47 | + $this->_status = $this->_admin_page->get_registration_status_array(); |
|
48 | + } |
|
49 | + |
|
50 | + |
|
51 | + protected function _setup_data() |
|
52 | + { |
|
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 | + $this->_all_data_count = $this->_view !== 'trash' ? $this->_admin_page->get_event_attendees( |
|
56 | + $this->_per_page, |
|
57 | + true |
|
58 | + ) : $this->_admin_page->get_event_attendees($this->_per_page, true, true); |
|
59 | + } |
|
60 | + |
|
61 | + |
|
62 | + protected function _set_properties() |
|
63 | + { |
|
64 | + $evt_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
65 | + $this->_wp_list_args = array( |
|
66 | + 'singular' => __('registrant', 'event_espresso'), |
|
67 | + 'plural' => __('registrants', 'event_espresso'), |
|
68 | + 'ajax' => true, |
|
69 | + 'screen' => $this->_admin_page->get_current_screen()->id, |
|
70 | + ); |
|
71 | + $columns = array(); |
|
72 | + // $columns['_Reg_Status'] = ''; |
|
73 | + if (! empty($evt_id)) { |
|
74 | + $columns['cb'] = '<input type="checkbox" />'; // Render a checkbox instead of text |
|
75 | + $this->_has_checkbox_column = true; |
|
76 | + } |
|
77 | + $this->_columns = array( |
|
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'), |
|
86 | + ); |
|
87 | + $this->_columns = array_merge($columns, $this->_columns); |
|
88 | + $this->_primary_column = '_REG_att_checked_in'; |
|
89 | + if (! empty($evt_id) |
|
90 | + && EE_Registry::instance()->CAP->current_user_can( |
|
91 | + 'ee_read_registrations', |
|
92 | + 'espresso_registrations_registrations_reports', |
|
93 | + $evt_id |
|
94 | + ) |
|
95 | + ) { |
|
96 | + $this->_bottom_buttons = array( |
|
97 | + 'report' => array( |
|
98 | + 'route' => 'registrations_report', |
|
99 | + 'extra_request' => |
|
100 | + array( |
|
101 | + 'EVT_ID' => $evt_id, |
|
102 | + 'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"), |
|
103 | + ), |
|
104 | + ), |
|
105 | + ); |
|
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 | + ); |
|
129 | + $this->_sortable_columns = array( |
|
130 | + /** |
|
131 | + * Allows users to change the default sort if they wish. |
|
132 | + * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name. |
|
133 | + * |
|
134 | + * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to |
|
135 | + * change the sorts on any list table involving registration contacts. If you want to only change the filter |
|
136 | + * for a specific list table you can use the provided reference to this object instance. |
|
137 | + */ |
|
138 | + 'ATT_name' => array( |
|
139 | + 'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name', |
|
140 | + true, |
|
141 | + $this, |
|
142 | + ) |
|
143 | + ? array('ATT_lname' => true) |
|
144 | + : array('ATT_fname' => true), |
|
145 | + 'Event' => array('Event.EVT_name' => false), |
|
146 | + ); |
|
147 | + $this->_hidden_columns = array(); |
|
148 | + $this->_evt = EEM_Event::instance()->get_one_by_ID($evt_id); |
|
149 | + $this->_dtts_for_event = $this->_evt instanceof EE_Event ? $this->_evt->datetimes_ordered() : array(); |
|
150 | + } |
|
151 | + |
|
152 | + |
|
153 | + /** |
|
154 | + * @param \EE_Registration $item |
|
155 | + * @return string |
|
156 | + */ |
|
157 | + protected function _get_row_class($item) |
|
158 | + { |
|
159 | + $class = parent::_get_row_class($item); |
|
160 | + // add status class |
|
161 | + $class .= ' ee-status-strip reg-status-' . $item->status_ID(); |
|
162 | + if ($this->_has_checkbox_column) { |
|
163 | + $class .= ' has-checkbox-column'; |
|
164 | + } |
|
165 | + return $class; |
|
166 | + } |
|
167 | + |
|
168 | + |
|
169 | + /** |
|
170 | + * @return array |
|
171 | + * @throws \EE_Error |
|
172 | + */ |
|
173 | + protected function _get_table_filters() |
|
174 | + { |
|
175 | + $filters = $where = array(); |
|
176 | + $current_EVT_ID = isset($this->_req_data['event_id']) ? (int) $this->_req_data['event_id'] : 0; |
|
177 | + if (empty($this->_dtts_for_event) || count($this->_dtts_for_event) === 1) { |
|
178 | + // this means we don't have an event so let's setup a filter dropdown for all the events to select |
|
179 | + // note possible capability restrictions |
|
180 | + if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) { |
|
181 | + $where['status**'] = array('!=', 'private'); |
|
182 | + } |
|
183 | + if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) { |
|
184 | + $where['EVT_wp_user'] = get_current_user_id(); |
|
185 | + } |
|
186 | + $events = EEM_Event::instance()->get_all( |
|
187 | + array( |
|
188 | + $where, |
|
189 | + 'order_by' => array('Datetime.DTT_EVT_start' => 'DESC'), |
|
190 | + ) |
|
191 | + ); |
|
192 | + $evts[] = array( |
|
193 | + 'id' => 0, |
|
194 | + 'text' => __('To toggle Check-in status, select an event', 'event_espresso'), |
|
195 | + ); |
|
196 | + $checked = 'checked'; |
|
197 | + /** @var EE_Event $evt */ |
|
198 | + foreach ($events as $evt) { |
|
199 | + // any registrations for this event? |
|
200 | + if (! $evt->get_count_of_all_registrations()) { |
|
201 | + continue; |
|
202 | + } |
|
203 | + $evts[] = array( |
|
204 | + 'id' => $evt->ID(), |
|
205 | + 'text' => apply_filters( |
|
206 | + 'FHEE__EE_Event_Registrations___get_table_filters__event_name', |
|
207 | + $evt->get('EVT_name'), |
|
208 | + $evt |
|
209 | + ), |
|
210 | + 'class' => $evt->is_expired() ? 'ee-expired-event' : '', |
|
211 | + ); |
|
212 | + if ($evt->ID() === $current_EVT_ID && $evt->is_expired()) { |
|
213 | + $checked = ''; |
|
214 | + } |
|
215 | + } |
|
216 | + $event_filter = '<div class="ee-event-filter">'; |
|
217 | + $event_filter .= EEH_Form_Fields::select_input('event_id', $evts, $current_EVT_ID); |
|
218 | + $event_filter .= '<span class="ee-event-filter-toggle">'; |
|
219 | + $event_filter .= '<input type="checkbox" id="js-ee-hide-expired-events" ' . $checked . '> '; |
|
220 | + $event_filter .= __('Hide Expired Events', 'event_espresso'); |
|
221 | + $event_filter .= '</span>'; |
|
222 | + $event_filter .= '</div>'; |
|
223 | + $filters[] = $event_filter; |
|
224 | + } |
|
225 | + if (! empty($this->_dtts_for_event)) { |
|
226 | + // DTT datetimes filter |
|
227 | + $this->_cur_dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0; |
|
228 | + if (count($this->_dtts_for_event) > 1) { |
|
229 | + $dtts[0] = __('To toggle check-in status, select a datetime.', 'event_espresso'); |
|
230 | + foreach ($this->_dtts_for_event as $dtt) { |
|
231 | + $datetime_string = $dtt->name(); |
|
232 | + $datetime_string = ! empty($datetime_string) ? ' (' . $datetime_string . ')' : ''; |
|
233 | + $datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time() . $datetime_string; |
|
234 | + $dtts[ $dtt->ID() ] = $datetime_string; |
|
235 | + } |
|
236 | + $input = new EE_Select_Input( |
|
237 | + $dtts, |
|
238 | + array( |
|
239 | + 'html_name' => 'DTT_ID', |
|
240 | + 'html_id' => 'DTT_ID', |
|
241 | + 'default' => $this->_cur_dtt_id, |
|
242 | + ) |
|
243 | + ); |
|
244 | + $filters[] = $input->get_html_for_input(); |
|
245 | + $filters[] = '<input type="hidden" name="event_id" value="' . $current_EVT_ID . '">'; |
|
246 | + } |
|
247 | + } |
|
248 | + return $filters; |
|
249 | + } |
|
250 | + |
|
251 | + |
|
252 | + protected function _add_view_counts() |
|
253 | + { |
|
254 | + $this->_views['all']['count'] = $this->_get_total_event_attendees(); |
|
255 | + } |
|
256 | + |
|
257 | + |
|
258 | + /** |
|
259 | + * @return int |
|
260 | + * @throws \EE_Error |
|
261 | + */ |
|
262 | + protected function _get_total_event_attendees() |
|
263 | + { |
|
264 | + $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false; |
|
265 | + $DTT_ID = $this->_cur_dtt_id; |
|
266 | + $query_params = array(); |
|
267 | + if ($EVT_ID) { |
|
268 | + $query_params[0]['EVT_ID'] = $EVT_ID; |
|
269 | + } |
|
270 | + // if DTT is included we only show for that datetime. Otherwise we're showing for all datetimes (the event). |
|
271 | + if ($DTT_ID) { |
|
272 | + $query_params[0]['Ticket.Datetime.DTT_ID'] = $DTT_ID; |
|
273 | + } |
|
274 | + $status_ids_array = apply_filters( |
|
275 | + 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
276 | + array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
277 | + ); |
|
278 | + $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
279 | + return EEM_Registration::instance()->count($query_params); |
|
280 | + } |
|
281 | + |
|
282 | + |
|
283 | + /** |
|
284 | + * @param \EE_Registration $item |
|
285 | + * @return string |
|
286 | + */ |
|
287 | + public function column__Reg_Status(EE_Registration $item) |
|
288 | + { |
|
289 | + return '<span class="ee-status-strip ee-status-strip-td reg-status-' . $item->status_ID() . '"></span>'; |
|
290 | + } |
|
291 | + |
|
292 | + |
|
293 | + /** |
|
294 | + * @param \EE_Registration $item |
|
295 | + * @return string |
|
296 | + * @throws \EE_Error |
|
297 | + */ |
|
298 | + public function column_cb($item) |
|
299 | + { |
|
300 | + return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID()); |
|
301 | + } |
|
302 | + |
|
303 | + |
|
304 | + /** |
|
305 | + * column_REG_att_checked_in |
|
306 | + * |
|
307 | + * @param EE_Registration $item |
|
308 | + * @return string |
|
309 | + * @throws EE_Error |
|
310 | + * @throws InvalidArgumentException |
|
311 | + * @throws InvalidDataTypeException |
|
312 | + * @throws InvalidInterfaceException |
|
313 | + */ |
|
314 | + public function column__REG_att_checked_in(EE_Registration $item) |
|
315 | + { |
|
316 | + $attendee = $item->attendee(); |
|
317 | + $attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : ''; |
|
318 | + |
|
319 | + if ($this->_cur_dtt_id === 0 && count($this->_dtts_for_event) === 1) { |
|
320 | + $latest_related_datetime = $item->get_latest_related_datetime(); |
|
321 | + if ($latest_related_datetime instanceof EE_Datetime) { |
|
322 | + $this->_cur_dtt_id = $latest_related_datetime->ID(); |
|
323 | + } |
|
324 | + } |
|
325 | + $checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId( |
|
326 | + $item, |
|
327 | + $this->_cur_dtt_id |
|
328 | + ); |
|
329 | + $nonce = wp_create_nonce('checkin_nonce'); |
|
330 | + $toggle_active = ! empty($this->_cur_dtt_id) |
|
331 | + && EE_Registry::instance()->CAP->current_user_can( |
|
332 | + 'ee_edit_checkin', |
|
333 | + 'espresso_registrations_toggle_checkin_status', |
|
334 | + $item->ID() |
|
335 | + ) |
|
336 | + ? ' clickable trigger-checkin' |
|
337 | + : ''; |
|
338 | + $mobile_view_content = ' <span class="show-on-mobile-view-only">' . $attendee_name . '</span>'; |
|
339 | + return '<span class="' . $checkin_status_dashicon->cssClasses() . $toggle_active . '"' |
|
340 | + . ' data-_regid="' . $item->ID() . '"' |
|
341 | + . ' data-dttid="' . $this->_cur_dtt_id . '"' |
|
342 | + . ' data-nonce="' . $nonce . '">' |
|
343 | + . '</span>' |
|
344 | + . $mobile_view_content; |
|
345 | + } |
|
346 | + |
|
347 | + |
|
348 | + /** |
|
349 | + * @param \EE_Registration $item |
|
350 | + * @return mixed|string|void |
|
351 | + * @throws \EE_Error |
|
352 | + */ |
|
353 | + public function column_ATT_name(EE_Registration $item) |
|
354 | + { |
|
355 | + $attendee = $item->attendee(); |
|
356 | + if (! $attendee instanceof EE_Attendee) { |
|
357 | + return __('No contact record for this registration.', 'event_espresso'); |
|
358 | + } |
|
359 | + // edit attendee link |
|
360 | + $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
361 | + array('action' => 'view_registration', '_REG_ID' => $item->ID()), |
|
362 | + REG_ADMIN_URL |
|
363 | + ); |
|
364 | + $name_link = EE_Registry::instance()->CAP->current_user_can( |
|
365 | + 'ee_edit_contacts', |
|
366 | + 'espresso_registrations_edit_attendee' |
|
367 | + ) |
|
368 | + ? '<a href="' . $edit_lnk_url . '" title="' . esc_attr__('View Registration Details', 'event_espresso') . '">' |
|
369 | + . $item->attendee()->full_name() |
|
370 | + . '</a>' |
|
371 | + : $item->attendee()->full_name(); |
|
372 | + $name_link .= $item->count() === 1 |
|
373 | + ? ' <sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup> ' |
|
374 | + : ''; |
|
375 | + // add group details |
|
376 | + $name_link .= ' ' . sprintf(__('(%s of %s)', 'event_espresso'), $item->count(), $item->group_size()); |
|
377 | + // add regcode |
|
378 | + $link = EE_Admin_Page::add_query_args_and_nonce( |
|
379 | + array('action' => 'view_registration', '_REG_ID' => $item->ID()), |
|
380 | + REG_ADMIN_URL |
|
381 | + ); |
|
382 | + $name_link .= '<br>'; |
|
383 | + $name_link .= EE_Registry::instance()->instance()->CAP->current_user_can( |
|
384 | + 'ee_read_registration', |
|
385 | + 'view_registration', |
|
386 | + $item->ID() |
|
387 | + ) |
|
388 | + ? '<a href="' . $link . '" title="' . esc_attr__('View Registration Details', 'event_espresso') . '">' |
|
389 | + . $item->reg_code() |
|
390 | + . '</a>' |
|
391 | + : $item->reg_code(); |
|
392 | + // status |
|
393 | + $name_link .= '<br><span class="ee-status-text-small">'; |
|
394 | + $name_link .= EEH_Template::pretty_status($item->status_ID(), false, 'sentence'); |
|
395 | + $name_link .= '</span>'; |
|
396 | + $actions = array(); |
|
397 | + $DTT_ID = $this->_cur_dtt_id; |
|
398 | + $latest_related_datetime = empty($DTT_ID) && ! empty($this->_req_data['event_id']) && $item instanceof EE_Registration |
|
399 | + ? $item->get_latest_related_datetime() |
|
400 | + : null; |
|
401 | + $DTT_ID = $latest_related_datetime instanceof EE_Datetime |
|
402 | + ? $latest_related_datetime->ID() |
|
403 | + : $DTT_ID; |
|
404 | + if (! empty($DTT_ID) |
|
405 | + && EE_Registry::instance()->CAP->current_user_can( |
|
406 | + 'ee_read_checkins', |
|
407 | + 'espresso_registrations_registration_checkins' |
|
408 | + ) |
|
409 | + ) { |
|
410 | + $checkin_list_url = EE_Admin_Page::add_query_args_and_nonce( |
|
411 | + array('action' => 'registration_checkins', '_REG_ID' => $item->ID(), 'DTT_ID' => $DTT_ID), |
|
412 | + REG_ADMIN_URL |
|
413 | + ); |
|
414 | + // get the timestamps for this registration's checkins, related to the selected datetime |
|
415 | + $timestamps = $item->get_many_related('Checkin', array(array('DTT_ID' => $DTT_ID))); |
|
416 | + if (! empty($timestamps)) { |
|
417 | + // get the last timestamp |
|
418 | + $last_timestamp = end($timestamps); |
|
419 | + // checked in or checked out? |
|
420 | + $checkin_status = $last_timestamp->get('CHK_in') |
|
421 | + ? esc_html__('Checked In', 'event_espresso') |
|
422 | + : esc_html__('Checked Out', 'event_espresso'); |
|
423 | + // get timestamp string |
|
424 | + $timestamp_string = $last_timestamp->get_datetime('CHK_timestamp'); |
|
425 | + $actions['checkin'] = '<a href="' . $checkin_list_url . '" title="' |
|
426 | + . esc_attr__( |
|
427 | + 'View this registrant\'s check-ins/checkouts for the datetime', |
|
428 | + 'event_espresso' |
|
429 | + ) . '">' . $checkin_status . ': ' . $timestamp_string . '</a>'; |
|
430 | + } |
|
431 | + } |
|
432 | + return (! empty($DTT_ID) && ! empty($timestamps)) |
|
433 | + ? sprintf('%1$s %2$s', $name_link, $this->row_actions($actions, true)) |
|
434 | + : $name_link; |
|
435 | + } |
|
436 | + |
|
437 | + |
|
438 | + /** |
|
439 | + * @param \EE_Registration $item |
|
440 | + * @return string |
|
441 | + */ |
|
442 | + public function column_ATT_email(EE_Registration $item) |
|
443 | + { |
|
444 | + $attendee = $item->attendee(); |
|
445 | + return $attendee instanceof EE_Attendee ? $attendee->email() : ''; |
|
446 | + } |
|
447 | + |
|
448 | + |
|
449 | + /** |
|
450 | + * @param \EE_Registration $item |
|
451 | + * @return bool|string |
|
452 | + * @throws \EE_Error |
|
453 | + */ |
|
454 | + public function column_Event(EE_Registration $item) |
|
455 | + { |
|
456 | + try { |
|
457 | + $event = $this->_evt instanceof EE_Event ? $this->_evt : $item->event(); |
|
458 | + $chkin_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
459 | + array('action' => 'event_registrations', 'event_id' => $event->ID()), |
|
460 | + REG_ADMIN_URL |
|
461 | + ); |
|
462 | + $event_label = EE_Registry::instance()->CAP->current_user_can( |
|
463 | + 'ee_read_checkins', |
|
464 | + 'espresso_registrations_registration_checkins' |
|
465 | + ) ? '<a href="' . $chkin_lnk_url . '" title="' |
|
466 | + . esc_attr__( |
|
467 | + 'View Checkins for this Event', |
|
468 | + 'event_espresso' |
|
469 | + ) . '">' . $event->name() . '</a>' : $event->name(); |
|
470 | + } catch (\EventEspresso\core\exceptions\EntityNotFoundException $e) { |
|
471 | + $event_label = esc_html__('Unknown', 'event_espresso'); |
|
472 | + } |
|
473 | + return $event_label; |
|
474 | + } |
|
475 | + |
|
476 | + |
|
477 | + /** |
|
478 | + * @param \EE_Registration $item |
|
479 | + * @return mixed|string|void |
|
480 | + */ |
|
481 | + public function column_PRC_name(EE_Registration $item) |
|
482 | + { |
|
483 | + return $item->ticket() instanceof EE_Ticket ? $item->ticket()->name() : __("Unknown", "event_espresso"); |
|
484 | + } |
|
485 | + |
|
486 | + |
|
487 | + /** |
|
488 | + * column_REG_final_price |
|
489 | + * |
|
490 | + * @param \EE_Registration $item |
|
491 | + * @return string |
|
492 | + */ |
|
493 | + public function column__REG_final_price(EE_Registration $item) |
|
494 | + { |
|
495 | + return '<span class="reg-pad-rght">' . ' ' . $item->pretty_final_price() . '</span>'; |
|
496 | + } |
|
497 | + |
|
498 | + |
|
499 | + /** |
|
500 | + * column_TXN_paid |
|
501 | + * |
|
502 | + * @param \EE_Registration $item |
|
503 | + * @return string |
|
504 | + * @throws \EE_Error |
|
505 | + */ |
|
506 | + public function column_TXN_paid(EE_Registration $item) |
|
507 | + { |
|
508 | + if ($item->count() === 1) { |
|
509 | + if ($item->transaction()->paid() >= $item->transaction()->total()) { |
|
510 | + return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>'; |
|
511 | + } else { |
|
512 | + $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce( |
|
513 | + array('action' => 'view_transaction', 'TXN_ID' => $item->transaction_ID()), |
|
514 | + TXN_ADMIN_URL |
|
515 | + ); |
|
516 | + return EE_Registry::instance()->CAP->current_user_can( |
|
517 | + 'ee_read_transaction', |
|
518 | + 'espresso_transactions_view_transaction' |
|
519 | + ) ? ' |
|
520 | 520 | <span class="reg-pad-rght"> |
521 | 521 | <a class="status-' |
522 | - . $item->transaction()->status_ID() |
|
523 | - . '" href="' |
|
524 | - . $view_txn_lnk_url |
|
525 | - . '" title="' |
|
526 | - . esc_attr__('View Transaction', 'event_espresso') |
|
527 | - . '"> |
|
522 | + . $item->transaction()->status_ID() |
|
523 | + . '" href="' |
|
524 | + . $view_txn_lnk_url |
|
525 | + . '" title="' |
|
526 | + . esc_attr__('View Transaction', 'event_espresso') |
|
527 | + . '"> |
|
528 | 528 | ' |
529 | - . $item->transaction()->pretty_paid() |
|
530 | - . ' |
|
529 | + . $item->transaction()->pretty_paid() |
|
530 | + . ' |
|
531 | 531 | </a> |
532 | 532 | <span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>'; |
533 | - } |
|
534 | - } else { |
|
535 | - return '<span class="reg-pad-rght"></span>'; |
|
536 | - } |
|
537 | - } |
|
538 | - |
|
539 | - |
|
540 | - /** |
|
541 | - * column_TXN_total |
|
542 | - * |
|
543 | - * @param \EE_Registration $item |
|
544 | - * @return string |
|
545 | - * @throws \EE_Error |
|
546 | - */ |
|
547 | - public function column_TXN_total(EE_Registration $item) |
|
548 | - { |
|
549 | - $txn = $item->transaction(); |
|
550 | - $view_txn_url = add_query_arg(array('action' => 'view_transaction', 'TXN_ID' => $txn->ID()), TXN_ADMIN_URL); |
|
551 | - if ($item->get('REG_count') === 1) { |
|
552 | - $line_total_obj = $txn->total_line_item(); |
|
553 | - $txn_total = $line_total_obj instanceof EE_Line_Item |
|
554 | - ? $line_total_obj->get_pretty('LIN_total') |
|
555 | - : __( |
|
556 | - 'View Transaction', |
|
557 | - 'event_espresso' |
|
558 | - ); |
|
559 | - return EE_Registry::instance()->CAP->current_user_can( |
|
560 | - 'ee_read_transaction', |
|
561 | - 'espresso_transactions_view_transaction' |
|
562 | - ) ? '<a href="' |
|
563 | - . $view_txn_url |
|
564 | - . '" title="' |
|
565 | - . esc_attr__('View Transaction', 'event_espresso') |
|
566 | - . '"><span class="reg-pad-rght">' |
|
567 | - . $txn_total |
|
568 | - . '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>'; |
|
569 | - } else { |
|
570 | - return '<span class="reg-pad-rght"></span>'; |
|
571 | - } |
|
572 | - } |
|
533 | + } |
|
534 | + } else { |
|
535 | + return '<span class="reg-pad-rght"></span>'; |
|
536 | + } |
|
537 | + } |
|
538 | + |
|
539 | + |
|
540 | + /** |
|
541 | + * column_TXN_total |
|
542 | + * |
|
543 | + * @param \EE_Registration $item |
|
544 | + * @return string |
|
545 | + * @throws \EE_Error |
|
546 | + */ |
|
547 | + public function column_TXN_total(EE_Registration $item) |
|
548 | + { |
|
549 | + $txn = $item->transaction(); |
|
550 | + $view_txn_url = add_query_arg(array('action' => 'view_transaction', 'TXN_ID' => $txn->ID()), TXN_ADMIN_URL); |
|
551 | + if ($item->get('REG_count') === 1) { |
|
552 | + $line_total_obj = $txn->total_line_item(); |
|
553 | + $txn_total = $line_total_obj instanceof EE_Line_Item |
|
554 | + ? $line_total_obj->get_pretty('LIN_total') |
|
555 | + : __( |
|
556 | + 'View Transaction', |
|
557 | + 'event_espresso' |
|
558 | + ); |
|
559 | + return EE_Registry::instance()->CAP->current_user_can( |
|
560 | + 'ee_read_transaction', |
|
561 | + 'espresso_transactions_view_transaction' |
|
562 | + ) ? '<a href="' |
|
563 | + . $view_txn_url |
|
564 | + . '" title="' |
|
565 | + . esc_attr__('View Transaction', 'event_espresso') |
|
566 | + . '"><span class="reg-pad-rght">' |
|
567 | + . $txn_total |
|
568 | + . '</span></a>' : '<span class="reg-pad-rght">' . $txn_total . '</span>'; |
|
569 | + } else { |
|
570 | + return '<span class="reg-pad-rght"></span>'; |
|
571 | + } |
|
572 | + } |
|
573 | 573 | } |
@@ -39,573 +39,573 @@ |
||
39 | 39 | { |
40 | 40 | |
41 | 41 | |
42 | - public function __construct() |
|
43 | - { |
|
44 | - parent::__construct(); |
|
45 | - EE_Registry::instance()->load_helper('Inflector'); |
|
46 | - } |
|
42 | + public function __construct() |
|
43 | + { |
|
44 | + parent::__construct(); |
|
45 | + EE_Registry::instance()->load_helper('Inflector'); |
|
46 | + } |
|
47 | 47 | |
48 | 48 | |
49 | - /** |
|
50 | - * Handles requests to get all (or a filtered subset) of entities for a particular model |
|
51 | - * |
|
52 | - * @param WP_REST_Request $request |
|
53 | - * @param string $version |
|
54 | - * @param string $model_name |
|
55 | - * @return WP_REST_Response|\WP_Error |
|
56 | - */ |
|
57 | - public static function handleRequestInsert(WP_REST_Request $request, $version, $model_name) |
|
58 | - { |
|
59 | - $controller = new Write(); |
|
60 | - try { |
|
61 | - $controller->setRequestedVersion($version); |
|
62 | - return $controller->sendResponse( |
|
63 | - $controller->insert( |
|
64 | - $controller->getModelVersionInfo()->loadModel($model_name), |
|
65 | - $request |
|
66 | - ) |
|
67 | - ); |
|
68 | - } catch (Exception $e) { |
|
69 | - return $controller->sendResponse($e); |
|
70 | - } |
|
71 | - } |
|
49 | + /** |
|
50 | + * Handles requests to get all (or a filtered subset) of entities for a particular model |
|
51 | + * |
|
52 | + * @param WP_REST_Request $request |
|
53 | + * @param string $version |
|
54 | + * @param string $model_name |
|
55 | + * @return WP_REST_Response|\WP_Error |
|
56 | + */ |
|
57 | + public static function handleRequestInsert(WP_REST_Request $request, $version, $model_name) |
|
58 | + { |
|
59 | + $controller = new Write(); |
|
60 | + try { |
|
61 | + $controller->setRequestedVersion($version); |
|
62 | + return $controller->sendResponse( |
|
63 | + $controller->insert( |
|
64 | + $controller->getModelVersionInfo()->loadModel($model_name), |
|
65 | + $request |
|
66 | + ) |
|
67 | + ); |
|
68 | + } catch (Exception $e) { |
|
69 | + return $controller->sendResponse($e); |
|
70 | + } |
|
71 | + } |
|
72 | 72 | |
73 | 73 | |
74 | - /** |
|
75 | - * Handles a request from \WP_REST_Server to update an EE model |
|
76 | - * |
|
77 | - * @param WP_REST_Request $request |
|
78 | - * @param string $version |
|
79 | - * @param string $model_name |
|
80 | - * @return WP_REST_Response|\WP_Error |
|
81 | - */ |
|
82 | - public static function handleRequestUpdate(WP_REST_Request $request, $version, $model_name) |
|
83 | - { |
|
84 | - $controller = new Write(); |
|
85 | - try { |
|
86 | - $controller->setRequestedVersion($version); |
|
87 | - return $controller->sendResponse( |
|
88 | - $controller->update( |
|
89 | - $controller->getModelVersionInfo()->loadModel($model_name), |
|
90 | - $request |
|
91 | - ) |
|
92 | - ); |
|
93 | - } catch (Exception $e) { |
|
94 | - return $controller->sendResponse($e); |
|
95 | - } |
|
96 | - } |
|
74 | + /** |
|
75 | + * Handles a request from \WP_REST_Server to update an EE model |
|
76 | + * |
|
77 | + * @param WP_REST_Request $request |
|
78 | + * @param string $version |
|
79 | + * @param string $model_name |
|
80 | + * @return WP_REST_Response|\WP_Error |
|
81 | + */ |
|
82 | + public static function handleRequestUpdate(WP_REST_Request $request, $version, $model_name) |
|
83 | + { |
|
84 | + $controller = new Write(); |
|
85 | + try { |
|
86 | + $controller->setRequestedVersion($version); |
|
87 | + return $controller->sendResponse( |
|
88 | + $controller->update( |
|
89 | + $controller->getModelVersionInfo()->loadModel($model_name), |
|
90 | + $request |
|
91 | + ) |
|
92 | + ); |
|
93 | + } catch (Exception $e) { |
|
94 | + return $controller->sendResponse($e); |
|
95 | + } |
|
96 | + } |
|
97 | 97 | |
98 | 98 | |
99 | - /** |
|
100 | - * Deletes a single model object and returns it. Unless |
|
101 | - * |
|
102 | - * @param WP_REST_Request $request |
|
103 | - * @param string $version |
|
104 | - * @param string $model_name |
|
105 | - * @return WP_REST_Response|\WP_Error |
|
106 | - */ |
|
107 | - public static function handleRequestDelete(WP_REST_Request $request, $version, $model_name) |
|
108 | - { |
|
109 | - $controller = new Write(); |
|
110 | - try { |
|
111 | - $controller->setRequestedVersion($version); |
|
112 | - return $controller->sendResponse( |
|
113 | - $controller->delete( |
|
114 | - $controller->getModelVersionInfo()->loadModel($model_name), |
|
115 | - $request |
|
116 | - ) |
|
117 | - ); |
|
118 | - } catch (Exception $e) { |
|
119 | - return $controller->sendResponse($e); |
|
120 | - } |
|
121 | - } |
|
99 | + /** |
|
100 | + * Deletes a single model object and returns it. Unless |
|
101 | + * |
|
102 | + * @param WP_REST_Request $request |
|
103 | + * @param string $version |
|
104 | + * @param string $model_name |
|
105 | + * @return WP_REST_Response|\WP_Error |
|
106 | + */ |
|
107 | + public static function handleRequestDelete(WP_REST_Request $request, $version, $model_name) |
|
108 | + { |
|
109 | + $controller = new Write(); |
|
110 | + try { |
|
111 | + $controller->setRequestedVersion($version); |
|
112 | + return $controller->sendResponse( |
|
113 | + $controller->delete( |
|
114 | + $controller->getModelVersionInfo()->loadModel($model_name), |
|
115 | + $request |
|
116 | + ) |
|
117 | + ); |
|
118 | + } catch (Exception $e) { |
|
119 | + return $controller->sendResponse($e); |
|
120 | + } |
|
121 | + } |
|
122 | 122 | |
123 | 123 | |
124 | - /** |
|
125 | - * Inserts a new model object according to the $request |
|
126 | - * |
|
127 | - * @param EEM_Base $model |
|
128 | - * @param WP_REST_Request $request |
|
129 | - * @return array |
|
130 | - * @throws EE_Error |
|
131 | - * @throws RestException |
|
132 | - */ |
|
133 | - public function insert(EEM_Base $model, WP_REST_Request $request) |
|
134 | - { |
|
135 | - Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create'); |
|
136 | - $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
137 | - if (! current_user_can($default_cap_to_check_for)) { |
|
138 | - throw new RestException( |
|
139 | - 'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
140 | - sprintf( |
|
141 | - esc_html__( |
|
142 | - // @codingStandardsIgnoreStart |
|
143 | - 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to insert data into Event Espresso.', |
|
144 | - // @codingStandardsIgnoreEnd |
|
145 | - 'event_espresso' |
|
146 | - ), |
|
147 | - $default_cap_to_check_for |
|
148 | - ), |
|
149 | - array('status' => 403) |
|
150 | - ); |
|
151 | - } |
|
152 | - $submitted_json_data = array_merge((array) $request->get_body_params(), (array) $request->get_json_params()); |
|
153 | - $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
154 | - $submitted_json_data, |
|
155 | - $model, |
|
156 | - $this->getModelVersionInfo()->requestedVersion(), |
|
157 | - true |
|
158 | - ); |
|
159 | - $model_obj = EE_Registry::instance()->load_class( |
|
160 | - $model->get_this_model_name(), |
|
161 | - array($model_data, $model->get_timezone()), |
|
162 | - false, |
|
163 | - false |
|
164 | - ); |
|
165 | - $model_obj->save(); |
|
166 | - $new_id = $model_obj->ID(); |
|
167 | - if (! $new_id) { |
|
168 | - throw new RestException( |
|
169 | - 'rest_insertion_failed', |
|
170 | - sprintf(__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name()) |
|
171 | - ); |
|
172 | - } |
|
173 | - return $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
174 | - } |
|
124 | + /** |
|
125 | + * Inserts a new model object according to the $request |
|
126 | + * |
|
127 | + * @param EEM_Base $model |
|
128 | + * @param WP_REST_Request $request |
|
129 | + * @return array |
|
130 | + * @throws EE_Error |
|
131 | + * @throws RestException |
|
132 | + */ |
|
133 | + public function insert(EEM_Base $model, WP_REST_Request $request) |
|
134 | + { |
|
135 | + Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create'); |
|
136 | + $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
137 | + if (! current_user_can($default_cap_to_check_for)) { |
|
138 | + throw new RestException( |
|
139 | + 'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
140 | + sprintf( |
|
141 | + esc_html__( |
|
142 | + // @codingStandardsIgnoreStart |
|
143 | + 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to insert data into Event Espresso.', |
|
144 | + // @codingStandardsIgnoreEnd |
|
145 | + 'event_espresso' |
|
146 | + ), |
|
147 | + $default_cap_to_check_for |
|
148 | + ), |
|
149 | + array('status' => 403) |
|
150 | + ); |
|
151 | + } |
|
152 | + $submitted_json_data = array_merge((array) $request->get_body_params(), (array) $request->get_json_params()); |
|
153 | + $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
154 | + $submitted_json_data, |
|
155 | + $model, |
|
156 | + $this->getModelVersionInfo()->requestedVersion(), |
|
157 | + true |
|
158 | + ); |
|
159 | + $model_obj = EE_Registry::instance()->load_class( |
|
160 | + $model->get_this_model_name(), |
|
161 | + array($model_data, $model->get_timezone()), |
|
162 | + false, |
|
163 | + false |
|
164 | + ); |
|
165 | + $model_obj->save(); |
|
166 | + $new_id = $model_obj->ID(); |
|
167 | + if (! $new_id) { |
|
168 | + throw new RestException( |
|
169 | + 'rest_insertion_failed', |
|
170 | + sprintf(__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name()) |
|
171 | + ); |
|
172 | + } |
|
173 | + return $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
174 | + } |
|
175 | 175 | |
176 | 176 | |
177 | - /** |
|
178 | - * Updates an existing model object according to the $request |
|
179 | - * |
|
180 | - * @param EEM_Base $model |
|
181 | - * @param WP_REST_Request $request |
|
182 | - * @return array |
|
183 | - * @throws EE_Error |
|
184 | - */ |
|
185 | - public function update(EEM_Base $model, WP_REST_Request $request) |
|
186 | - { |
|
187 | - Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit'); |
|
188 | - $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
189 | - if (! current_user_can($default_cap_to_check_for)) { |
|
190 | - throw new RestException( |
|
191 | - 'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
192 | - sprintf( |
|
193 | - esc_html__( |
|
194 | - // @codingStandardsIgnoreStart |
|
195 | - 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to update data into Event Espresso.', |
|
196 | - // @codingStandardsIgnoreEnd |
|
197 | - 'event_espresso' |
|
198 | - ), |
|
199 | - $default_cap_to_check_for |
|
200 | - ), |
|
201 | - array('status' => 403) |
|
202 | - ); |
|
203 | - } |
|
204 | - $obj_id = $request->get_param('id'); |
|
205 | - if (! $obj_id) { |
|
206 | - throw new RestException( |
|
207 | - 'rest_edit_failed', |
|
208 | - sprintf(__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name()) |
|
209 | - ); |
|
210 | - } |
|
211 | - $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
212 | - $this->getBodyParams($request), |
|
213 | - $model, |
|
214 | - $this->getModelVersionInfo()->requestedVersion(), |
|
215 | - true |
|
216 | - ); |
|
217 | - $model_obj = $model->get_one_by_ID($obj_id); |
|
218 | - if (! $model_obj instanceof EE_Base_Class) { |
|
219 | - $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
220 | - throw new RestException( |
|
221 | - sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
222 | - sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
223 | - array('status' => 404) |
|
224 | - ); |
|
225 | - } |
|
226 | - $model_obj->save($model_data); |
|
227 | - return $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
228 | - } |
|
177 | + /** |
|
178 | + * Updates an existing model object according to the $request |
|
179 | + * |
|
180 | + * @param EEM_Base $model |
|
181 | + * @param WP_REST_Request $request |
|
182 | + * @return array |
|
183 | + * @throws EE_Error |
|
184 | + */ |
|
185 | + public function update(EEM_Base $model, WP_REST_Request $request) |
|
186 | + { |
|
187 | + Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit'); |
|
188 | + $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
189 | + if (! current_user_can($default_cap_to_check_for)) { |
|
190 | + throw new RestException( |
|
191 | + 'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
192 | + sprintf( |
|
193 | + esc_html__( |
|
194 | + // @codingStandardsIgnoreStart |
|
195 | + 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to update data into Event Espresso.', |
|
196 | + // @codingStandardsIgnoreEnd |
|
197 | + 'event_espresso' |
|
198 | + ), |
|
199 | + $default_cap_to_check_for |
|
200 | + ), |
|
201 | + array('status' => 403) |
|
202 | + ); |
|
203 | + } |
|
204 | + $obj_id = $request->get_param('id'); |
|
205 | + if (! $obj_id) { |
|
206 | + throw new RestException( |
|
207 | + 'rest_edit_failed', |
|
208 | + sprintf(__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name()) |
|
209 | + ); |
|
210 | + } |
|
211 | + $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
212 | + $this->getBodyParams($request), |
|
213 | + $model, |
|
214 | + $this->getModelVersionInfo()->requestedVersion(), |
|
215 | + true |
|
216 | + ); |
|
217 | + $model_obj = $model->get_one_by_ID($obj_id); |
|
218 | + if (! $model_obj instanceof EE_Base_Class) { |
|
219 | + $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
220 | + throw new RestException( |
|
221 | + sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
222 | + sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
223 | + array('status' => 404) |
|
224 | + ); |
|
225 | + } |
|
226 | + $model_obj->save($model_data); |
|
227 | + return $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
228 | + } |
|
229 | 229 | |
230 | 230 | |
231 | - /** |
|
232 | - * Updates an existing model object according to the $request |
|
233 | - * |
|
234 | - * @param EEM_Base $model |
|
235 | - * @param WP_REST_Request $request |
|
236 | - * @return array of either the soft-deleted item, or |
|
237 | - * @throws EE_Error |
|
238 | - */ |
|
239 | - public function delete(EEM_Base $model, WP_REST_Request $request) |
|
240 | - { |
|
241 | - Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete'); |
|
242 | - $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
243 | - if (! current_user_can($default_cap_to_check_for)) { |
|
244 | - throw new RestException( |
|
245 | - 'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
246 | - sprintf( |
|
247 | - esc_html__( |
|
248 | - // @codingStandardsIgnoreStart |
|
249 | - 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to delete data into Event Espresso.', |
|
250 | - // @codingStandardsIgnoreEnd |
|
251 | - 'event_espresso' |
|
252 | - ), |
|
253 | - $default_cap_to_check_for |
|
254 | - ), |
|
255 | - array('status' => 403) |
|
256 | - ); |
|
257 | - } |
|
258 | - $obj_id = $request->get_param('id'); |
|
259 | - // this is where we would apply more fine-grained caps |
|
260 | - $model_obj = $model->get_one_by_ID($obj_id); |
|
261 | - if (! $model_obj instanceof EE_Base_Class) { |
|
262 | - $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
263 | - throw new RestException( |
|
264 | - sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
265 | - sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
266 | - array('status' => 404) |
|
267 | - ); |
|
268 | - } |
|
269 | - $requested_permanent_delete = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN); |
|
270 | - $requested_allow_blocking = filter_var($request->get_param('allow_blocking'), FILTER_VALIDATE_BOOLEAN); |
|
271 | - if ($requested_permanent_delete) { |
|
272 | - $previous = $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
273 | - $deleted = (bool) $model->delete_permanently_by_ID($obj_id, $requested_allow_blocking); |
|
274 | - return array( |
|
275 | - 'deleted' => $deleted, |
|
276 | - 'previous' => $previous, |
|
277 | - ); |
|
278 | - } else { |
|
279 | - if ($model instanceof EEM_Soft_Delete_Base) { |
|
280 | - $model->delete_by_ID($obj_id, $requested_allow_blocking); |
|
281 | - return $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
282 | - } else { |
|
283 | - throw new RestException( |
|
284 | - 'rest_trash_not_supported', |
|
285 | - 501, |
|
286 | - sprintf( |
|
287 | - esc_html__('%1$s do not support trashing. Set force=1 to delete.', 'event_espresso'), |
|
288 | - EEH_Inflector::pluralize($model->get_this_model_name()) |
|
289 | - ) |
|
290 | - ); |
|
291 | - } |
|
292 | - } |
|
293 | - } |
|
231 | + /** |
|
232 | + * Updates an existing model object according to the $request |
|
233 | + * |
|
234 | + * @param EEM_Base $model |
|
235 | + * @param WP_REST_Request $request |
|
236 | + * @return array of either the soft-deleted item, or |
|
237 | + * @throws EE_Error |
|
238 | + */ |
|
239 | + public function delete(EEM_Base $model, WP_REST_Request $request) |
|
240 | + { |
|
241 | + Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete'); |
|
242 | + $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
243 | + if (! current_user_can($default_cap_to_check_for)) { |
|
244 | + throw new RestException( |
|
245 | + 'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
246 | + sprintf( |
|
247 | + esc_html__( |
|
248 | + // @codingStandardsIgnoreStart |
|
249 | + 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to delete data into Event Espresso.', |
|
250 | + // @codingStandardsIgnoreEnd |
|
251 | + 'event_espresso' |
|
252 | + ), |
|
253 | + $default_cap_to_check_for |
|
254 | + ), |
|
255 | + array('status' => 403) |
|
256 | + ); |
|
257 | + } |
|
258 | + $obj_id = $request->get_param('id'); |
|
259 | + // this is where we would apply more fine-grained caps |
|
260 | + $model_obj = $model->get_one_by_ID($obj_id); |
|
261 | + if (! $model_obj instanceof EE_Base_Class) { |
|
262 | + $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
263 | + throw new RestException( |
|
264 | + sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
265 | + sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
266 | + array('status' => 404) |
|
267 | + ); |
|
268 | + } |
|
269 | + $requested_permanent_delete = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN); |
|
270 | + $requested_allow_blocking = filter_var($request->get_param('allow_blocking'), FILTER_VALIDATE_BOOLEAN); |
|
271 | + if ($requested_permanent_delete) { |
|
272 | + $previous = $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
273 | + $deleted = (bool) $model->delete_permanently_by_ID($obj_id, $requested_allow_blocking); |
|
274 | + return array( |
|
275 | + 'deleted' => $deleted, |
|
276 | + 'previous' => $previous, |
|
277 | + ); |
|
278 | + } else { |
|
279 | + if ($model instanceof EEM_Soft_Delete_Base) { |
|
280 | + $model->delete_by_ID($obj_id, $requested_allow_blocking); |
|
281 | + return $this->returnModelObjAsJsonResponse($model_obj, $request); |
|
282 | + } else { |
|
283 | + throw new RestException( |
|
284 | + 'rest_trash_not_supported', |
|
285 | + 501, |
|
286 | + sprintf( |
|
287 | + esc_html__('%1$s do not support trashing. Set force=1 to delete.', 'event_espresso'), |
|
288 | + EEH_Inflector::pluralize($model->get_this_model_name()) |
|
289 | + ) |
|
290 | + ); |
|
291 | + } |
|
292 | + } |
|
293 | + } |
|
294 | 294 | |
295 | 295 | |
296 | - /** |
|
297 | - * Returns an array ready to be converted into a JSON response, based solely on the model object |
|
298 | - * |
|
299 | - * @param EE_Base_Class $model_obj |
|
300 | - * @param WP_REST_Request $request |
|
301 | - * @return array ready for a response |
|
302 | - */ |
|
303 | - protected function returnModelObjAsJsonResponse(EE_Base_Class $model_obj, WP_REST_Request $request) |
|
304 | - { |
|
305 | - $model = $model_obj->get_model(); |
|
306 | - // create an array exactly like the wpdb results row, |
|
307 | - // so we can pass it to controllers/model/Read::create_entity_from_wpdb_result() |
|
308 | - $simulated_db_row = array(); |
|
309 | - foreach ($model->field_settings(true) as $field_name => $field_obj) { |
|
310 | - // we need to reconstruct the normal wpdb results, including the db-only fields |
|
311 | - // like a secondary table's primary key. The models expect those (but don't care what value they have) |
|
312 | - if ($field_obj instanceof EE_DB_Only_Field_Base) { |
|
313 | - $raw_value = true; |
|
314 | - } elseif ($field_obj instanceof EE_Datetime_Field) { |
|
315 | - $raw_value = $model_obj->get_DateTime_object($field_name); |
|
316 | - } else { |
|
317 | - $raw_value = $model_obj->get_raw($field_name); |
|
318 | - } |
|
319 | - $simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value); |
|
320 | - } |
|
321 | - $read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read'); |
|
322 | - $read_controller->setRequestedVersion($this->getRequestedVersion()); |
|
323 | - // the simulates request really doesn't need any info downstream |
|
324 | - $simulated_request = new WP_REST_Request('GET'); |
|
325 | - // set the caps context on the simulated according to the original request. |
|
326 | - switch ($request->get_method()) { |
|
327 | - case 'POST': |
|
328 | - case 'PUT': |
|
329 | - $caps_context = EEM_Base::caps_edit; |
|
330 | - break; |
|
331 | - case 'DELETE': |
|
332 | - $caps_context = EEM_Base::caps_delete; |
|
333 | - break; |
|
334 | - default: |
|
335 | - $caps_context = EEM_Base::caps_read_admin; |
|
336 | - } |
|
337 | - $simulated_request->set_param('caps', $caps_context); |
|
338 | - return $read_controller->createEntityFromWpdbResult( |
|
339 | - $model_obj->get_model(), |
|
340 | - $simulated_db_row, |
|
341 | - $simulated_request |
|
342 | - ); |
|
343 | - } |
|
296 | + /** |
|
297 | + * Returns an array ready to be converted into a JSON response, based solely on the model object |
|
298 | + * |
|
299 | + * @param EE_Base_Class $model_obj |
|
300 | + * @param WP_REST_Request $request |
|
301 | + * @return array ready for a response |
|
302 | + */ |
|
303 | + protected function returnModelObjAsJsonResponse(EE_Base_Class $model_obj, WP_REST_Request $request) |
|
304 | + { |
|
305 | + $model = $model_obj->get_model(); |
|
306 | + // create an array exactly like the wpdb results row, |
|
307 | + // so we can pass it to controllers/model/Read::create_entity_from_wpdb_result() |
|
308 | + $simulated_db_row = array(); |
|
309 | + foreach ($model->field_settings(true) as $field_name => $field_obj) { |
|
310 | + // we need to reconstruct the normal wpdb results, including the db-only fields |
|
311 | + // like a secondary table's primary key. The models expect those (but don't care what value they have) |
|
312 | + if ($field_obj instanceof EE_DB_Only_Field_Base) { |
|
313 | + $raw_value = true; |
|
314 | + } elseif ($field_obj instanceof EE_Datetime_Field) { |
|
315 | + $raw_value = $model_obj->get_DateTime_object($field_name); |
|
316 | + } else { |
|
317 | + $raw_value = $model_obj->get_raw($field_name); |
|
318 | + } |
|
319 | + $simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value); |
|
320 | + } |
|
321 | + $read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read'); |
|
322 | + $read_controller->setRequestedVersion($this->getRequestedVersion()); |
|
323 | + // the simulates request really doesn't need any info downstream |
|
324 | + $simulated_request = new WP_REST_Request('GET'); |
|
325 | + // set the caps context on the simulated according to the original request. |
|
326 | + switch ($request->get_method()) { |
|
327 | + case 'POST': |
|
328 | + case 'PUT': |
|
329 | + $caps_context = EEM_Base::caps_edit; |
|
330 | + break; |
|
331 | + case 'DELETE': |
|
332 | + $caps_context = EEM_Base::caps_delete; |
|
333 | + break; |
|
334 | + default: |
|
335 | + $caps_context = EEM_Base::caps_read_admin; |
|
336 | + } |
|
337 | + $simulated_request->set_param('caps', $caps_context); |
|
338 | + return $read_controller->createEntityFromWpdbResult( |
|
339 | + $model_obj->get_model(), |
|
340 | + $simulated_db_row, |
|
341 | + $simulated_request |
|
342 | + ); |
|
343 | + } |
|
344 | 344 | |
345 | 345 | |
346 | - /** |
|
347 | - * Gets the item affected by this request |
|
348 | - * |
|
349 | - * @param EEM_Base $model |
|
350 | - * @param WP_REST_Request $request |
|
351 | - * @param int|string $obj_id |
|
352 | - * @return \WP_Error|array |
|
353 | - */ |
|
354 | - protected function getOneBasedOnRequest(EEM_Base $model, WP_REST_Request $request, $obj_id) |
|
355 | - { |
|
356 | - $requested_version = $this->getRequestedVersion($request->get_route()); |
|
357 | - $get_request = new WP_REST_Request( |
|
358 | - 'GET', |
|
359 | - EED_Core_Rest_Api::ee_api_namespace |
|
360 | - . $requested_version |
|
361 | - . '/' |
|
362 | - . EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
363 | - . '/' |
|
364 | - . $obj_id |
|
365 | - ); |
|
366 | - $get_request->set_url_params( |
|
367 | - array( |
|
368 | - 'id' => $obj_id, |
|
369 | - 'include' => $request->get_param('include'), |
|
370 | - ) |
|
371 | - ); |
|
372 | - $read_controller = new Read(); |
|
373 | - $read_controller->setRequestedVersion($this->getRequestedVersion()); |
|
374 | - return $read_controller->getEntityFromModel($model, $get_request); |
|
375 | - } |
|
346 | + /** |
|
347 | + * Gets the item affected by this request |
|
348 | + * |
|
349 | + * @param EEM_Base $model |
|
350 | + * @param WP_REST_Request $request |
|
351 | + * @param int|string $obj_id |
|
352 | + * @return \WP_Error|array |
|
353 | + */ |
|
354 | + protected function getOneBasedOnRequest(EEM_Base $model, WP_REST_Request $request, $obj_id) |
|
355 | + { |
|
356 | + $requested_version = $this->getRequestedVersion($request->get_route()); |
|
357 | + $get_request = new WP_REST_Request( |
|
358 | + 'GET', |
|
359 | + EED_Core_Rest_Api::ee_api_namespace |
|
360 | + . $requested_version |
|
361 | + . '/' |
|
362 | + . EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
363 | + . '/' |
|
364 | + . $obj_id |
|
365 | + ); |
|
366 | + $get_request->set_url_params( |
|
367 | + array( |
|
368 | + 'id' => $obj_id, |
|
369 | + 'include' => $request->get_param('include'), |
|
370 | + ) |
|
371 | + ); |
|
372 | + $read_controller = new Read(); |
|
373 | + $read_controller->setRequestedVersion($this->getRequestedVersion()); |
|
374 | + return $read_controller->getEntityFromModel($model, $get_request); |
|
375 | + } |
|
376 | 376 | |
377 | - /** |
|
378 | - * Adds a relation between the specified models (if it doesn't already exist.) |
|
379 | - * @since 4.9.76.p |
|
380 | - * @param WP_REST_Request $request |
|
381 | - * @return WP_REST_Response |
|
382 | - */ |
|
383 | - public static function handleRequestAddRelation(WP_REST_Request $request, $version, $model_name, $related_model_name) |
|
384 | - { |
|
385 | - $controller = new Write(); |
|
386 | - try { |
|
387 | - $controller->setRequestedVersion($version); |
|
388 | - $main_model = $controller->validateModel($model_name); |
|
389 | - $controller->validateModel($related_model_name); |
|
390 | - return $controller->sendResponse( |
|
391 | - $controller->addRelation( |
|
392 | - $main_model, |
|
393 | - $main_model->related_settings_for($related_model_name), |
|
394 | - $request |
|
395 | - ) |
|
396 | - ); |
|
397 | - } catch (Exception $e) { |
|
398 | - return $controller->sendResponse($e); |
|
399 | - } |
|
400 | - } |
|
377 | + /** |
|
378 | + * Adds a relation between the specified models (if it doesn't already exist.) |
|
379 | + * @since 4.9.76.p |
|
380 | + * @param WP_REST_Request $request |
|
381 | + * @return WP_REST_Response |
|
382 | + */ |
|
383 | + public static function handleRequestAddRelation(WP_REST_Request $request, $version, $model_name, $related_model_name) |
|
384 | + { |
|
385 | + $controller = new Write(); |
|
386 | + try { |
|
387 | + $controller->setRequestedVersion($version); |
|
388 | + $main_model = $controller->validateModel($model_name); |
|
389 | + $controller->validateModel($related_model_name); |
|
390 | + return $controller->sendResponse( |
|
391 | + $controller->addRelation( |
|
392 | + $main_model, |
|
393 | + $main_model->related_settings_for($related_model_name), |
|
394 | + $request |
|
395 | + ) |
|
396 | + ); |
|
397 | + } catch (Exception $e) { |
|
398 | + return $controller->sendResponse($e); |
|
399 | + } |
|
400 | + } |
|
401 | 401 | |
402 | - /** |
|
403 | - * Adds a relation between the two model specified model objects. |
|
404 | - * @since 4.9.76.p |
|
405 | - * @param EEM_Base $model |
|
406 | - * @param EE_Model_Relation_Base $relation |
|
407 | - * @param WP_REST_Request $request |
|
408 | - * @return array |
|
409 | - * @throws EE_Error |
|
410 | - * @throws InvalidArgumentException |
|
411 | - * @throws InvalidDataTypeException |
|
412 | - * @throws InvalidInterfaceException |
|
413 | - * @throws RestException |
|
414 | - * @throws DomainException |
|
415 | - */ |
|
416 | - public function addRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request) |
|
417 | - { |
|
418 | - list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request); |
|
419 | - $extra_params = array(); |
|
420 | - if ($relation instanceof EE_HABTM_Relation) { |
|
421 | - $extra_params = array_intersect_key( |
|
422 | - ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
423 | - $request->get_body_params(), |
|
424 | - $relation->get_join_model(), |
|
425 | - $this->getModelVersionInfo()->requestedVersion(), |
|
426 | - true |
|
427 | - ), |
|
428 | - $relation->getNonKeyFields() |
|
429 | - ); |
|
430 | - } |
|
431 | - // Add a relation. |
|
432 | - $related_obj = $model_obj->_add_relation_to( |
|
433 | - $other_obj, |
|
434 | - $relation->get_other_model()->get_this_model_name(), |
|
435 | - $extra_params |
|
436 | - ); |
|
437 | - $response = array( |
|
438 | - strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request), |
|
439 | - strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request), |
|
440 | - ); |
|
441 | - if ($relation instanceof EE_HABTM_Relation) { |
|
442 | - $join_model_obj = $relation->get_join_model()->get_one( |
|
443 | - array( |
|
444 | - array( |
|
445 | - $relation->get_join_model()->get_foreign_key_to($model->get_this_model_name())->get_name() => $model_obj->ID(), |
|
446 | - $relation->get_join_model()->get_foreign_key_to($relation->get_other_model()->get_this_model_name())->get_name() => $related_obj->ID() |
|
447 | - ) |
|
448 | - ) |
|
449 | - ); |
|
450 | - $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request); |
|
451 | - } |
|
452 | - return $response; |
|
453 | - } |
|
402 | + /** |
|
403 | + * Adds a relation between the two model specified model objects. |
|
404 | + * @since 4.9.76.p |
|
405 | + * @param EEM_Base $model |
|
406 | + * @param EE_Model_Relation_Base $relation |
|
407 | + * @param WP_REST_Request $request |
|
408 | + * @return array |
|
409 | + * @throws EE_Error |
|
410 | + * @throws InvalidArgumentException |
|
411 | + * @throws InvalidDataTypeException |
|
412 | + * @throws InvalidInterfaceException |
|
413 | + * @throws RestException |
|
414 | + * @throws DomainException |
|
415 | + */ |
|
416 | + public function addRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request) |
|
417 | + { |
|
418 | + list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request); |
|
419 | + $extra_params = array(); |
|
420 | + if ($relation instanceof EE_HABTM_Relation) { |
|
421 | + $extra_params = array_intersect_key( |
|
422 | + ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
423 | + $request->get_body_params(), |
|
424 | + $relation->get_join_model(), |
|
425 | + $this->getModelVersionInfo()->requestedVersion(), |
|
426 | + true |
|
427 | + ), |
|
428 | + $relation->getNonKeyFields() |
|
429 | + ); |
|
430 | + } |
|
431 | + // Add a relation. |
|
432 | + $related_obj = $model_obj->_add_relation_to( |
|
433 | + $other_obj, |
|
434 | + $relation->get_other_model()->get_this_model_name(), |
|
435 | + $extra_params |
|
436 | + ); |
|
437 | + $response = array( |
|
438 | + strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request), |
|
439 | + strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request), |
|
440 | + ); |
|
441 | + if ($relation instanceof EE_HABTM_Relation) { |
|
442 | + $join_model_obj = $relation->get_join_model()->get_one( |
|
443 | + array( |
|
444 | + array( |
|
445 | + $relation->get_join_model()->get_foreign_key_to($model->get_this_model_name())->get_name() => $model_obj->ID(), |
|
446 | + $relation->get_join_model()->get_foreign_key_to($relation->get_other_model()->get_this_model_name())->get_name() => $related_obj->ID() |
|
447 | + ) |
|
448 | + ) |
|
449 | + ); |
|
450 | + $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request); |
|
451 | + } |
|
452 | + return $response; |
|
453 | + } |
|
454 | 454 | |
455 | 455 | |
456 | - /** |
|
457 | - * Removes the relation between the specified models (if it exists). |
|
458 | - * @since 4.9.76.p |
|
459 | - * @param WP_REST_Request $request |
|
460 | - * @return WP_REST_Response |
|
461 | - */ |
|
462 | - public static function handleRequestRemoveRelation(WP_REST_Request $request, $version, $model_name, $related_model_name) |
|
463 | - { |
|
464 | - $controller = new Write(); |
|
465 | - try { |
|
466 | - $controller->setRequestedVersion($version); |
|
467 | - $main_model = $controller->getModelVersionInfo()->loadModel($model_name); |
|
468 | - return $controller->sendResponse( |
|
469 | - $controller->removeRelation( |
|
470 | - $main_model, |
|
471 | - $main_model->related_settings_for($related_model_name), |
|
472 | - $request |
|
473 | - ) |
|
474 | - ); |
|
475 | - } catch (Exception $e) { |
|
476 | - return $controller->sendResponse($e); |
|
477 | - } |
|
478 | - } |
|
456 | + /** |
|
457 | + * Removes the relation between the specified models (if it exists). |
|
458 | + * @since 4.9.76.p |
|
459 | + * @param WP_REST_Request $request |
|
460 | + * @return WP_REST_Response |
|
461 | + */ |
|
462 | + public static function handleRequestRemoveRelation(WP_REST_Request $request, $version, $model_name, $related_model_name) |
|
463 | + { |
|
464 | + $controller = new Write(); |
|
465 | + try { |
|
466 | + $controller->setRequestedVersion($version); |
|
467 | + $main_model = $controller->getModelVersionInfo()->loadModel($model_name); |
|
468 | + return $controller->sendResponse( |
|
469 | + $controller->removeRelation( |
|
470 | + $main_model, |
|
471 | + $main_model->related_settings_for($related_model_name), |
|
472 | + $request |
|
473 | + ) |
|
474 | + ); |
|
475 | + } catch (Exception $e) { |
|
476 | + return $controller->sendResponse($e); |
|
477 | + } |
|
478 | + } |
|
479 | 479 | |
480 | - /** |
|
481 | - * Adds a relation between the two model specified model objects. |
|
482 | - * @since 4.9.76.p |
|
483 | - * @param EEM_Base $model |
|
484 | - * @param EE_Model_Relation_Base $relation |
|
485 | - * @param WP_REST_Request $request |
|
486 | - * @return array |
|
487 | - * @throws DomainException |
|
488 | - * @throws EE_Error |
|
489 | - * @throws InvalidArgumentException |
|
490 | - * @throws InvalidDataTypeException |
|
491 | - * @throws InvalidInterfaceException |
|
492 | - * @throws RestException |
|
493 | - */ |
|
494 | - public function removeRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request) |
|
495 | - { |
|
496 | - // This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know |
|
497 | - // up-front that it doesn't.) |
|
498 | - if (!empty($request->get_body_params())) { |
|
499 | - $body_params = $request->get_body_params(); |
|
500 | - throw new RestException( |
|
501 | - 'invalid_field', |
|
502 | - sprintf( |
|
503 | - esc_html__('This endpoint doesn\'t accept post body arguments, you sent in %1$s', 'event_espresso'), |
|
504 | - implode(array_keys($body_params)) |
|
505 | - ) |
|
506 | - ); |
|
507 | - } |
|
508 | - list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request); |
|
509 | - // Remember the old relation, if it used a join entry. |
|
510 | - $join_model_obj = null; |
|
511 | - if ($relation instanceof EE_HABTM_Relation) { |
|
512 | - $join_model_obj = $relation->get_join_model()->get_one( |
|
513 | - array( |
|
514 | - array( |
|
515 | - $model->primary_key_name() => $model_obj->ID(), |
|
516 | - $relation->get_other_model()->primary_key_name() => $other_obj->ID() |
|
517 | - ) |
|
518 | - ) |
|
519 | - ); |
|
520 | - } |
|
521 | - // Remove the relation. |
|
522 | - $related_obj = $model_obj->_remove_relation_to( |
|
523 | - $other_obj, |
|
524 | - $relation->get_other_model()->get_this_model_name() |
|
525 | - ); |
|
526 | - $response = array( |
|
527 | - strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request), |
|
528 | - strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request), |
|
529 | - ); |
|
530 | - if ($relation instanceof EE_HABTM_Relation) { |
|
531 | - $join_model_obj_after_removal = $relation->get_join_model()->get_one( |
|
532 | - array( |
|
533 | - array( |
|
534 | - $model->primary_key_name() => $model_obj->ID(), |
|
535 | - $relation->get_other_model()->primary_key_name() => $other_obj->ID() |
|
536 | - ) |
|
537 | - ) |
|
538 | - ); |
|
539 | - if ($join_model_obj instanceof EE_Base_Class) { |
|
540 | - $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request); |
|
541 | - } else { |
|
542 | - $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null; |
|
543 | - } |
|
544 | - } |
|
545 | - return $response; |
|
546 | - } |
|
480 | + /** |
|
481 | + * Adds a relation between the two model specified model objects. |
|
482 | + * @since 4.9.76.p |
|
483 | + * @param EEM_Base $model |
|
484 | + * @param EE_Model_Relation_Base $relation |
|
485 | + * @param WP_REST_Request $request |
|
486 | + * @return array |
|
487 | + * @throws DomainException |
|
488 | + * @throws EE_Error |
|
489 | + * @throws InvalidArgumentException |
|
490 | + * @throws InvalidDataTypeException |
|
491 | + * @throws InvalidInterfaceException |
|
492 | + * @throws RestException |
|
493 | + */ |
|
494 | + public function removeRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request) |
|
495 | + { |
|
496 | + // This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know |
|
497 | + // up-front that it doesn't.) |
|
498 | + if (!empty($request->get_body_params())) { |
|
499 | + $body_params = $request->get_body_params(); |
|
500 | + throw new RestException( |
|
501 | + 'invalid_field', |
|
502 | + sprintf( |
|
503 | + esc_html__('This endpoint doesn\'t accept post body arguments, you sent in %1$s', 'event_espresso'), |
|
504 | + implode(array_keys($body_params)) |
|
505 | + ) |
|
506 | + ); |
|
507 | + } |
|
508 | + list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request); |
|
509 | + // Remember the old relation, if it used a join entry. |
|
510 | + $join_model_obj = null; |
|
511 | + if ($relation instanceof EE_HABTM_Relation) { |
|
512 | + $join_model_obj = $relation->get_join_model()->get_one( |
|
513 | + array( |
|
514 | + array( |
|
515 | + $model->primary_key_name() => $model_obj->ID(), |
|
516 | + $relation->get_other_model()->primary_key_name() => $other_obj->ID() |
|
517 | + ) |
|
518 | + ) |
|
519 | + ); |
|
520 | + } |
|
521 | + // Remove the relation. |
|
522 | + $related_obj = $model_obj->_remove_relation_to( |
|
523 | + $other_obj, |
|
524 | + $relation->get_other_model()->get_this_model_name() |
|
525 | + ); |
|
526 | + $response = array( |
|
527 | + strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request), |
|
528 | + strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request), |
|
529 | + ); |
|
530 | + if ($relation instanceof EE_HABTM_Relation) { |
|
531 | + $join_model_obj_after_removal = $relation->get_join_model()->get_one( |
|
532 | + array( |
|
533 | + array( |
|
534 | + $model->primary_key_name() => $model_obj->ID(), |
|
535 | + $relation->get_other_model()->primary_key_name() => $other_obj->ID() |
|
536 | + ) |
|
537 | + ) |
|
538 | + ); |
|
539 | + if ($join_model_obj instanceof EE_Base_Class) { |
|
540 | + $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request); |
|
541 | + } else { |
|
542 | + $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null; |
|
543 | + } |
|
544 | + } |
|
545 | + return $response; |
|
546 | + } |
|
547 | 547 | |
548 | - /** |
|
549 | - * Gets the model objects indicated by the model, relation object, and request. |
|
550 | - * Throws an exception if the first object doesn't exist, and currently if the related object also doesn't exist. |
|
551 | - * However, this behaviour may change, as we may add support for simultaneously creating and relating data. |
|
552 | - * @since 4.9.76.p |
|
553 | - * @param EEM_Base $model |
|
554 | - * @param EE_Model_Relation_Base $relation |
|
555 | - * @param WP_REST_Request $request |
|
556 | - * @return array { |
|
557 | - * @type EE_Base_Class $model_obj |
|
558 | - * @type EE_Base_Class|null $other_model_obj |
|
559 | - * } |
|
560 | - * @throws RestException |
|
561 | - */ |
|
562 | - protected function getBothModelObjects(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request) |
|
563 | - { |
|
564 | - // Check generic caps. For now, we're only allowing access to this endpoint to full admins. |
|
565 | - Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit'); |
|
566 | - $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
567 | - if (! current_user_can($default_cap_to_check_for)) { |
|
568 | - throw new RestException( |
|
569 | - 'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
570 | - sprintf( |
|
571 | - esc_html__( |
|
572 | - // @codingStandardsIgnoreStart |
|
573 | - 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to add relations in Event Espresso.', |
|
574 | - // @codingStandardsIgnoreEnd |
|
575 | - 'event_espresso' |
|
576 | - ), |
|
577 | - $default_cap_to_check_for |
|
578 | - ), |
|
579 | - array('status' => 403) |
|
580 | - ); |
|
581 | - } |
|
582 | - // Get the main model object. |
|
583 | - $model_obj = $this->getOneOrThrowException($model, $request->get_param('id')); |
|
584 | - // For now, we require the other model object to exist too. This might be relaxed later. |
|
585 | - $other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id')); |
|
586 | - return array($model_obj,$other_obj); |
|
587 | - } |
|
548 | + /** |
|
549 | + * Gets the model objects indicated by the model, relation object, and request. |
|
550 | + * Throws an exception if the first object doesn't exist, and currently if the related object also doesn't exist. |
|
551 | + * However, this behaviour may change, as we may add support for simultaneously creating and relating data. |
|
552 | + * @since 4.9.76.p |
|
553 | + * @param EEM_Base $model |
|
554 | + * @param EE_Model_Relation_Base $relation |
|
555 | + * @param WP_REST_Request $request |
|
556 | + * @return array { |
|
557 | + * @type EE_Base_Class $model_obj |
|
558 | + * @type EE_Base_Class|null $other_model_obj |
|
559 | + * } |
|
560 | + * @throws RestException |
|
561 | + */ |
|
562 | + protected function getBothModelObjects(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request) |
|
563 | + { |
|
564 | + // Check generic caps. For now, we're only allowing access to this endpoint to full admins. |
|
565 | + Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit'); |
|
566 | + $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap(); |
|
567 | + if (! current_user_can($default_cap_to_check_for)) { |
|
568 | + throw new RestException( |
|
569 | + 'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())), |
|
570 | + sprintf( |
|
571 | + esc_html__( |
|
572 | + // @codingStandardsIgnoreStart |
|
573 | + 'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to add relations in Event Espresso.', |
|
574 | + // @codingStandardsIgnoreEnd |
|
575 | + 'event_espresso' |
|
576 | + ), |
|
577 | + $default_cap_to_check_for |
|
578 | + ), |
|
579 | + array('status' => 403) |
|
580 | + ); |
|
581 | + } |
|
582 | + // Get the main model object. |
|
583 | + $model_obj = $this->getOneOrThrowException($model, $request->get_param('id')); |
|
584 | + // For now, we require the other model object to exist too. This might be relaxed later. |
|
585 | + $other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id')); |
|
586 | + return array($model_obj,$other_obj); |
|
587 | + } |
|
588 | 588 | |
589 | - /** |
|
590 | - * Gets the model with that ID or throws a REST exception. |
|
591 | - * @since 4.9.76.p |
|
592 | - * @param EEM_Base $model |
|
593 | - * @param $id |
|
594 | - * @return EE_Base_Class |
|
595 | - * @throws RestException |
|
596 | - */ |
|
597 | - protected function getOneOrThrowException(EEM_Base $model, $id) |
|
598 | - { |
|
599 | - $model_obj = $model->get_one_by_ID($id); |
|
600 | - // @todo: check they can permission for it. For now unnecessary because only full admins can use this endpoint. |
|
601 | - if ($model_obj instanceof EE_Base_Class) { |
|
602 | - return $model_obj; |
|
603 | - } |
|
604 | - $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
605 | - throw new RestException( |
|
606 | - sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
607 | - sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
608 | - array('status' => 404) |
|
609 | - ); |
|
610 | - } |
|
589 | + /** |
|
590 | + * Gets the model with that ID or throws a REST exception. |
|
591 | + * @since 4.9.76.p |
|
592 | + * @param EEM_Base $model |
|
593 | + * @param $id |
|
594 | + * @return EE_Base_Class |
|
595 | + * @throws RestException |
|
596 | + */ |
|
597 | + protected function getOneOrThrowException(EEM_Base $model, $id) |
|
598 | + { |
|
599 | + $model_obj = $model->get_one_by_ID($id); |
|
600 | + // @todo: check they can permission for it. For now unnecessary because only full admins can use this endpoint. |
|
601 | + if ($model_obj instanceof EE_Base_Class) { |
|
602 | + return $model_obj; |
|
603 | + } |
|
604 | + $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
605 | + throw new RestException( |
|
606 | + sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
607 | + sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
608 | + array('status' => 404) |
|
609 | + ); |
|
610 | + } |
|
611 | 611 | } |
@@ -38,103 +38,103 @@ |
||
38 | 38 | * @since 4.0 |
39 | 39 | */ |
40 | 40 | if (function_exists('espresso_version')) { |
41 | - if (! function_exists('espresso_duplicate_plugin_error')) { |
|
42 | - /** |
|
43 | - * espresso_duplicate_plugin_error |
|
44 | - * displays if more than one version of EE is activated at the same time |
|
45 | - */ |
|
46 | - function espresso_duplicate_plugin_error() |
|
47 | - { |
|
48 | - ?> |
|
41 | + if (! function_exists('espresso_duplicate_plugin_error')) { |
|
42 | + /** |
|
43 | + * espresso_duplicate_plugin_error |
|
44 | + * displays if more than one version of EE is activated at the same time |
|
45 | + */ |
|
46 | + function espresso_duplicate_plugin_error() |
|
47 | + { |
|
48 | + ?> |
|
49 | 49 | <div class="error"> |
50 | 50 | <p> |
51 | 51 | <?php |
52 | - echo esc_html__( |
|
53 | - 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
54 | - 'event_espresso' |
|
55 | - ); ?> |
|
52 | + echo esc_html__( |
|
53 | + 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
54 | + 'event_espresso' |
|
55 | + ); ?> |
|
56 | 56 | </p> |
57 | 57 | </div> |
58 | 58 | <?php |
59 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
60 | - } |
|
61 | - } |
|
62 | - add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
59 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
60 | + } |
|
61 | + } |
|
62 | + add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
63 | 63 | } else { |
64 | - define('EE_MIN_PHP_VER_REQUIRED', '5.4.0'); |
|
65 | - if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
66 | - /** |
|
67 | - * espresso_minimum_php_version_error |
|
68 | - * |
|
69 | - * @return void |
|
70 | - */ |
|
71 | - function espresso_minimum_php_version_error() |
|
72 | - { |
|
73 | - ?> |
|
64 | + define('EE_MIN_PHP_VER_REQUIRED', '5.4.0'); |
|
65 | + if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
66 | + /** |
|
67 | + * espresso_minimum_php_version_error |
|
68 | + * |
|
69 | + * @return void |
|
70 | + */ |
|
71 | + function espresso_minimum_php_version_error() |
|
72 | + { |
|
73 | + ?> |
|
74 | 74 | <div class="error"> |
75 | 75 | <p> |
76 | 76 | <?php |
77 | - printf( |
|
78 | - esc_html__( |
|
79 | - 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
80 | - 'event_espresso' |
|
81 | - ), |
|
82 | - EE_MIN_PHP_VER_REQUIRED, |
|
83 | - PHP_VERSION, |
|
84 | - '<br/>', |
|
85 | - '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>' |
|
86 | - ); |
|
87 | - ?> |
|
77 | + printf( |
|
78 | + esc_html__( |
|
79 | + 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
80 | + 'event_espresso' |
|
81 | + ), |
|
82 | + EE_MIN_PHP_VER_REQUIRED, |
|
83 | + PHP_VERSION, |
|
84 | + '<br/>', |
|
85 | + '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>' |
|
86 | + ); |
|
87 | + ?> |
|
88 | 88 | </p> |
89 | 89 | </div> |
90 | 90 | <?php |
91 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
92 | - } |
|
91 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
92 | + } |
|
93 | 93 | |
94 | - add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
95 | - } else { |
|
96 | - define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
97 | - /** |
|
98 | - * espresso_version |
|
99 | - * Returns the plugin version |
|
100 | - * |
|
101 | - * @return string |
|
102 | - */ |
|
103 | - function espresso_version() |
|
104 | - { |
|
105 | - return apply_filters('FHEE__espresso__espresso_version', '4.10.3.rc.002'); |
|
106 | - } |
|
94 | + add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
95 | + } else { |
|
96 | + define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
97 | + /** |
|
98 | + * espresso_version |
|
99 | + * Returns the plugin version |
|
100 | + * |
|
101 | + * @return string |
|
102 | + */ |
|
103 | + function espresso_version() |
|
104 | + { |
|
105 | + return apply_filters('FHEE__espresso__espresso_version', '4.10.3.rc.002'); |
|
106 | + } |
|
107 | 107 | |
108 | - /** |
|
109 | - * espresso_plugin_activation |
|
110 | - * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
111 | - */ |
|
112 | - function espresso_plugin_activation() |
|
113 | - { |
|
114 | - update_option('ee_espresso_activation', true); |
|
115 | - } |
|
108 | + /** |
|
109 | + * espresso_plugin_activation |
|
110 | + * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
111 | + */ |
|
112 | + function espresso_plugin_activation() |
|
113 | + { |
|
114 | + update_option('ee_espresso_activation', true); |
|
115 | + } |
|
116 | 116 | |
117 | - register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
117 | + register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
118 | 118 | |
119 | - require_once __DIR__ . '/core/bootstrap_espresso.php'; |
|
120 | - bootstrap_espresso(); |
|
121 | - } |
|
119 | + require_once __DIR__ . '/core/bootstrap_espresso.php'; |
|
120 | + bootstrap_espresso(); |
|
121 | + } |
|
122 | 122 | } |
123 | 123 | if (! function_exists('espresso_deactivate_plugin')) { |
124 | - /** |
|
125 | - * deactivate_plugin |
|
126 | - * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
127 | - * |
|
128 | - * @access public |
|
129 | - * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
130 | - * @return void |
|
131 | - */ |
|
132 | - function espresso_deactivate_plugin($plugin_basename = '') |
|
133 | - { |
|
134 | - if (! function_exists('deactivate_plugins')) { |
|
135 | - require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
136 | - } |
|
137 | - unset($_GET['activate'], $_REQUEST['activate']); |
|
138 | - deactivate_plugins($plugin_basename); |
|
139 | - } |
|
124 | + /** |
|
125 | + * deactivate_plugin |
|
126 | + * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
127 | + * |
|
128 | + * @access public |
|
129 | + * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
130 | + * @return void |
|
131 | + */ |
|
132 | + function espresso_deactivate_plugin($plugin_basename = '') |
|
133 | + { |
|
134 | + if (! function_exists('deactivate_plugins')) { |
|
135 | + require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
136 | + } |
|
137 | + unset($_GET['activate'], $_REQUEST['activate']); |
|
138 | + deactivate_plugins($plugin_basename); |
|
139 | + } |
|
140 | 140 | } |
@@ -43,6 +43,10 @@ discard block |
||
43 | 43 | |
44 | 44 | protected $model_obj_nodes; |
45 | 45 | |
46 | + /** |
|
47 | + * @param EE_Base_Class $main_model_obj |
|
48 | + * @param EEM_Base|null $related_model |
|
49 | + */ |
|
46 | 50 | public function __construct($main_model_obj, $related_model) |
47 | 51 | { |
48 | 52 | $this->main_model_obj = $main_model_obj; |
@@ -119,7 +123,7 @@ discard block |
||
119 | 123 | * Visits the provided nodes and keeps track of how much work was done, making sure to not go over budget. |
120 | 124 | * @since $VID:$ |
121 | 125 | * @param ModelObjNode[] $model_obj_nodes |
122 | - * @param $work_budget |
|
126 | + * @param integer $work_budget |
|
123 | 127 | * @return int |
124 | 128 | */ |
125 | 129 | protected function visitAlreadyDiscoveredNodes($model_obj_nodes, $work_budget) |
@@ -4,11 +4,9 @@ |
||
4 | 4 | |
5 | 5 | use EE_Base_Class; |
6 | 6 | use EE_Error; |
7 | -use EE_Model_Relation_Base; |
|
8 | 7 | use EEM_Base; |
9 | 8 | use EventEspresso\core\exceptions\InvalidDataTypeException; |
10 | 9 | use EventEspresso\core\exceptions\InvalidInterfaceException; |
11 | -use EventEspresso\core\services\payment_methods\forms\PayPalSettingsForm; |
|
12 | 10 | use InvalidArgumentException; |
13 | 11 | use ReflectionException; |
14 | 12 |
@@ -25,190 +25,190 @@ |
||
25 | 25 | */ |
26 | 26 | class RelationNode extends BaseNode |
27 | 27 | { |
28 | - /** |
|
29 | - * @var EE_Base_Class |
|
30 | - */ |
|
31 | - protected $main_model_obj; |
|
32 | - |
|
33 | - /** |
|
34 | - * @var int |
|
35 | - */ |
|
36 | - protected $count; |
|
37 | - |
|
38 | - /** |
|
39 | - * @var EEM_Base |
|
40 | - */ |
|
41 | - protected $related_model; |
|
42 | - |
|
43 | - |
|
44 | - protected $model_obj_nodes; |
|
45 | - |
|
46 | - public function __construct($main_model_obj, $related_model) |
|
47 | - { |
|
48 | - $this->main_model_obj = $main_model_obj; |
|
49 | - $this->related_model = $related_model; |
|
50 | - $this->model_obj_nodes = []; |
|
51 | - } |
|
52 | - |
|
53 | - |
|
54 | - /** |
|
55 | - * Here is where most of the work happens. We've counted how many related model objects exist, here we identify |
|
56 | - * them (ie, learn their IDs). But its recursive, so we'll also find their related dependent model objects etc. |
|
57 | - * @since $VID:$ |
|
58 | - * @param int $model_objects_to_identify |
|
59 | - * @return int |
|
60 | - * @throws EE_Error |
|
61 | - * @throws InvalidArgumentException |
|
62 | - * @throws InvalidDataTypeException |
|
63 | - * @throws InvalidInterfaceException |
|
64 | - * @throws ReflectionException |
|
65 | - */ |
|
66 | - protected function work($model_objects_to_identify) |
|
67 | - { |
|
68 | - $num_identified = $this->visitAlreadyDiscoveredNodes($this->model_obj_nodes, $model_objects_to_identify); |
|
69 | - if ($num_identified < $model_objects_to_identify) { |
|
70 | - $related_model_objs = $this->related_model->get_all( |
|
71 | - [ |
|
72 | - $this->whereQueryParams(), |
|
73 | - 'limit' => [ |
|
74 | - count($this->model_obj_nodes), |
|
75 | - $model_objects_to_identify |
|
76 | - ] |
|
77 | - ] |
|
78 | - ); |
|
79 | - $new_item_nodes = []; |
|
80 | - |
|
81 | - // Add entity nodes for each of the model objects we fetched. |
|
82 | - foreach ($related_model_objs as $related_model_obj) { |
|
83 | - $entity_node = new ModelObjNode($related_model_obj); |
|
84 | - $this->model_obj_nodes[ $related_model_obj->ID() ] = $entity_node; |
|
85 | - $new_item_nodes[ $related_model_obj->ID() ] = $entity_node; |
|
86 | - } |
|
87 | - $num_identified += count($new_item_nodes); |
|
88 | - if ($num_identified < $model_objects_to_identify) { |
|
89 | - // And lastly do the work. |
|
90 | - $num_identified += $this->visitAlreadyDiscoveredNodes( |
|
91 | - $new_item_nodes, |
|
92 | - $model_objects_to_identify - $num_identified |
|
93 | - ); |
|
94 | - } |
|
95 | - } |
|
96 | - |
|
97 | - if (count($this->model_obj_nodes) >= $this->count && $this->allChildrenComplete()) { |
|
98 | - $this->complete = true; |
|
99 | - } |
|
100 | - return $num_identified; |
|
101 | - } |
|
102 | - |
|
103 | - /** |
|
104 | - * Checks if all the identified child nodes are complete or not. |
|
105 | - * @since $VID:$ |
|
106 | - * @return bool |
|
107 | - */ |
|
108 | - protected function allChildrenComplete() |
|
109 | - { |
|
110 | - foreach ($this->model_obj_nodes as $model_obj_node) { |
|
111 | - if (! $model_obj_node->isComplete()) { |
|
112 | - return false; |
|
113 | - } |
|
114 | - } |
|
115 | - return true; |
|
116 | - } |
|
117 | - |
|
118 | - /** |
|
119 | - * Visits the provided nodes and keeps track of how much work was done, making sure to not go over budget. |
|
120 | - * @since $VID:$ |
|
121 | - * @param ModelObjNode[] $model_obj_nodes |
|
122 | - * @param $work_budget |
|
123 | - * @return int |
|
124 | - */ |
|
125 | - protected function visitAlreadyDiscoveredNodes($model_obj_nodes, $work_budget) |
|
126 | - { |
|
127 | - $work_done = 0; |
|
128 | - if (! $model_obj_nodes) { |
|
129 | - return 0; |
|
130 | - } |
|
131 | - foreach ($model_obj_nodes as $model_obj_node) { |
|
132 | - if ($work_done >= $work_budget) { |
|
133 | - break; |
|
134 | - } |
|
135 | - $work_done += $model_obj_node->visit($work_budget - $work_done); |
|
136 | - } |
|
137 | - return $work_done; |
|
138 | - } |
|
139 | - |
|
140 | - /** |
|
141 | - * Whether this item has already been initialized |
|
142 | - */ |
|
143 | - protected function isDiscovered() |
|
144 | - { |
|
145 | - return $this->count !== null; |
|
146 | - } |
|
147 | - |
|
148 | - /** |
|
149 | - * @since $VID:$ |
|
150 | - * @return boolean |
|
151 | - */ |
|
152 | - public function isComplete() |
|
153 | - { |
|
154 | - if ($this->complete === null) { |
|
155 | - if (count($this->model_obj_nodes) === $this->count) { |
|
156 | - $this->complete = true; |
|
157 | - } else { |
|
158 | - $this->complete = false; |
|
159 | - } |
|
160 | - } |
|
161 | - return $this->complete; |
|
162 | - } |
|
163 | - |
|
164 | - /** |
|
165 | - * Discovers how many related model objects exist. |
|
166 | - * @since $VID:$ |
|
167 | - * @return mixed|void |
|
168 | - * @throws EE_Error |
|
169 | - * @throws InvalidArgumentException |
|
170 | - * @throws InvalidDataTypeException |
|
171 | - * @throws InvalidInterfaceException |
|
172 | - * @throws ReflectionException |
|
173 | - */ |
|
174 | - protected function discover() |
|
175 | - { |
|
176 | - $this->count = $this->related_model->count([$this->whereQueryParams()]); |
|
177 | - } |
|
178 | - |
|
179 | - /** |
|
180 | - * @since $VID:$ |
|
181 | - * @return array |
|
182 | - * @throws EE_Error |
|
183 | - * @throws InvalidDataTypeException |
|
184 | - * @throws InvalidInterfaceException |
|
185 | - * @throws InvalidArgumentException |
|
186 | - * @throws ReflectionException |
|
187 | - */ |
|
188 | - protected function whereQueryParams() |
|
189 | - { |
|
190 | - return [ |
|
191 | - $this->related_model->get_foreign_key_to( |
|
192 | - $this->main_model_obj->get_model()->get_this_model_name() |
|
193 | - )->get_name() => $this->main_model_obj->ID() |
|
194 | - ]; |
|
195 | - } |
|
196 | - /** |
|
197 | - * @since $VID:$ |
|
198 | - * @return array |
|
199 | - */ |
|
200 | - public function toArray() |
|
201 | - { |
|
202 | - $tree = [ |
|
203 | - 'count' => $this->count, |
|
204 | - 'complete' => $this->isComplete(), |
|
205 | - 'objs' => [] |
|
206 | - ]; |
|
207 | - foreach ($this->model_obj_nodes as $id => $model_obj_node) { |
|
208 | - $tree['objs'][ $id ] = $model_obj_node->toArray(); |
|
209 | - } |
|
210 | - return $tree; |
|
211 | - } |
|
28 | + /** |
|
29 | + * @var EE_Base_Class |
|
30 | + */ |
|
31 | + protected $main_model_obj; |
|
32 | + |
|
33 | + /** |
|
34 | + * @var int |
|
35 | + */ |
|
36 | + protected $count; |
|
37 | + |
|
38 | + /** |
|
39 | + * @var EEM_Base |
|
40 | + */ |
|
41 | + protected $related_model; |
|
42 | + |
|
43 | + |
|
44 | + protected $model_obj_nodes; |
|
45 | + |
|
46 | + public function __construct($main_model_obj, $related_model) |
|
47 | + { |
|
48 | + $this->main_model_obj = $main_model_obj; |
|
49 | + $this->related_model = $related_model; |
|
50 | + $this->model_obj_nodes = []; |
|
51 | + } |
|
52 | + |
|
53 | + |
|
54 | + /** |
|
55 | + * Here is where most of the work happens. We've counted how many related model objects exist, here we identify |
|
56 | + * them (ie, learn their IDs). But its recursive, so we'll also find their related dependent model objects etc. |
|
57 | + * @since $VID:$ |
|
58 | + * @param int $model_objects_to_identify |
|
59 | + * @return int |
|
60 | + * @throws EE_Error |
|
61 | + * @throws InvalidArgumentException |
|
62 | + * @throws InvalidDataTypeException |
|
63 | + * @throws InvalidInterfaceException |
|
64 | + * @throws ReflectionException |
|
65 | + */ |
|
66 | + protected function work($model_objects_to_identify) |
|
67 | + { |
|
68 | + $num_identified = $this->visitAlreadyDiscoveredNodes($this->model_obj_nodes, $model_objects_to_identify); |
|
69 | + if ($num_identified < $model_objects_to_identify) { |
|
70 | + $related_model_objs = $this->related_model->get_all( |
|
71 | + [ |
|
72 | + $this->whereQueryParams(), |
|
73 | + 'limit' => [ |
|
74 | + count($this->model_obj_nodes), |
|
75 | + $model_objects_to_identify |
|
76 | + ] |
|
77 | + ] |
|
78 | + ); |
|
79 | + $new_item_nodes = []; |
|
80 | + |
|
81 | + // Add entity nodes for each of the model objects we fetched. |
|
82 | + foreach ($related_model_objs as $related_model_obj) { |
|
83 | + $entity_node = new ModelObjNode($related_model_obj); |
|
84 | + $this->model_obj_nodes[ $related_model_obj->ID() ] = $entity_node; |
|
85 | + $new_item_nodes[ $related_model_obj->ID() ] = $entity_node; |
|
86 | + } |
|
87 | + $num_identified += count($new_item_nodes); |
|
88 | + if ($num_identified < $model_objects_to_identify) { |
|
89 | + // And lastly do the work. |
|
90 | + $num_identified += $this->visitAlreadyDiscoveredNodes( |
|
91 | + $new_item_nodes, |
|
92 | + $model_objects_to_identify - $num_identified |
|
93 | + ); |
|
94 | + } |
|
95 | + } |
|
96 | + |
|
97 | + if (count($this->model_obj_nodes) >= $this->count && $this->allChildrenComplete()) { |
|
98 | + $this->complete = true; |
|
99 | + } |
|
100 | + return $num_identified; |
|
101 | + } |
|
102 | + |
|
103 | + /** |
|
104 | + * Checks if all the identified child nodes are complete or not. |
|
105 | + * @since $VID:$ |
|
106 | + * @return bool |
|
107 | + */ |
|
108 | + protected function allChildrenComplete() |
|
109 | + { |
|
110 | + foreach ($this->model_obj_nodes as $model_obj_node) { |
|
111 | + if (! $model_obj_node->isComplete()) { |
|
112 | + return false; |
|
113 | + } |
|
114 | + } |
|
115 | + return true; |
|
116 | + } |
|
117 | + |
|
118 | + /** |
|
119 | + * Visits the provided nodes and keeps track of how much work was done, making sure to not go over budget. |
|
120 | + * @since $VID:$ |
|
121 | + * @param ModelObjNode[] $model_obj_nodes |
|
122 | + * @param $work_budget |
|
123 | + * @return int |
|
124 | + */ |
|
125 | + protected function visitAlreadyDiscoveredNodes($model_obj_nodes, $work_budget) |
|
126 | + { |
|
127 | + $work_done = 0; |
|
128 | + if (! $model_obj_nodes) { |
|
129 | + return 0; |
|
130 | + } |
|
131 | + foreach ($model_obj_nodes as $model_obj_node) { |
|
132 | + if ($work_done >= $work_budget) { |
|
133 | + break; |
|
134 | + } |
|
135 | + $work_done += $model_obj_node->visit($work_budget - $work_done); |
|
136 | + } |
|
137 | + return $work_done; |
|
138 | + } |
|
139 | + |
|
140 | + /** |
|
141 | + * Whether this item has already been initialized |
|
142 | + */ |
|
143 | + protected function isDiscovered() |
|
144 | + { |
|
145 | + return $this->count !== null; |
|
146 | + } |
|
147 | + |
|
148 | + /** |
|
149 | + * @since $VID:$ |
|
150 | + * @return boolean |
|
151 | + */ |
|
152 | + public function isComplete() |
|
153 | + { |
|
154 | + if ($this->complete === null) { |
|
155 | + if (count($this->model_obj_nodes) === $this->count) { |
|
156 | + $this->complete = true; |
|
157 | + } else { |
|
158 | + $this->complete = false; |
|
159 | + } |
|
160 | + } |
|
161 | + return $this->complete; |
|
162 | + } |
|
163 | + |
|
164 | + /** |
|
165 | + * Discovers how many related model objects exist. |
|
166 | + * @since $VID:$ |
|
167 | + * @return mixed|void |
|
168 | + * @throws EE_Error |
|
169 | + * @throws InvalidArgumentException |
|
170 | + * @throws InvalidDataTypeException |
|
171 | + * @throws InvalidInterfaceException |
|
172 | + * @throws ReflectionException |
|
173 | + */ |
|
174 | + protected function discover() |
|
175 | + { |
|
176 | + $this->count = $this->related_model->count([$this->whereQueryParams()]); |
|
177 | + } |
|
178 | + |
|
179 | + /** |
|
180 | + * @since $VID:$ |
|
181 | + * @return array |
|
182 | + * @throws EE_Error |
|
183 | + * @throws InvalidDataTypeException |
|
184 | + * @throws InvalidInterfaceException |
|
185 | + * @throws InvalidArgumentException |
|
186 | + * @throws ReflectionException |
|
187 | + */ |
|
188 | + protected function whereQueryParams() |
|
189 | + { |
|
190 | + return [ |
|
191 | + $this->related_model->get_foreign_key_to( |
|
192 | + $this->main_model_obj->get_model()->get_this_model_name() |
|
193 | + )->get_name() => $this->main_model_obj->ID() |
|
194 | + ]; |
|
195 | + } |
|
196 | + /** |
|
197 | + * @since $VID:$ |
|
198 | + * @return array |
|
199 | + */ |
|
200 | + public function toArray() |
|
201 | + { |
|
202 | + $tree = [ |
|
203 | + 'count' => $this->count, |
|
204 | + 'complete' => $this->isComplete(), |
|
205 | + 'objs' => [] |
|
206 | + ]; |
|
207 | + foreach ($this->model_obj_nodes as $id => $model_obj_node) { |
|
208 | + $tree['objs'][ $id ] = $model_obj_node->toArray(); |
|
209 | + } |
|
210 | + return $tree; |
|
211 | + } |
|
212 | 212 | } |
213 | 213 | // End of file RelationNode.php |
214 | 214 | // Location: EventEspresso\core\services\orm\tree_traversal/RelationNode.php |
@@ -81,8 +81,8 @@ discard block |
||
81 | 81 | // Add entity nodes for each of the model objects we fetched. |
82 | 82 | foreach ($related_model_objs as $related_model_obj) { |
83 | 83 | $entity_node = new ModelObjNode($related_model_obj); |
84 | - $this->model_obj_nodes[ $related_model_obj->ID() ] = $entity_node; |
|
85 | - $new_item_nodes[ $related_model_obj->ID() ] = $entity_node; |
|
84 | + $this->model_obj_nodes[$related_model_obj->ID()] = $entity_node; |
|
85 | + $new_item_nodes[$related_model_obj->ID()] = $entity_node; |
|
86 | 86 | } |
87 | 87 | $num_identified += count($new_item_nodes); |
88 | 88 | if ($num_identified < $model_objects_to_identify) { |
@@ -108,7 +108,7 @@ discard block |
||
108 | 108 | protected function allChildrenComplete() |
109 | 109 | { |
110 | 110 | foreach ($this->model_obj_nodes as $model_obj_node) { |
111 | - if (! $model_obj_node->isComplete()) { |
|
111 | + if ( ! $model_obj_node->isComplete()) { |
|
112 | 112 | return false; |
113 | 113 | } |
114 | 114 | } |
@@ -125,7 +125,7 @@ discard block |
||
125 | 125 | protected function visitAlreadyDiscoveredNodes($model_obj_nodes, $work_budget) |
126 | 126 | { |
127 | 127 | $work_done = 0; |
128 | - if (! $model_obj_nodes) { |
|
128 | + if ( ! $model_obj_nodes) { |
|
129 | 129 | return 0; |
130 | 130 | } |
131 | 131 | foreach ($model_obj_nodes as $model_obj_node) { |
@@ -205,7 +205,7 @@ discard block |
||
205 | 205 | 'objs' => [] |
206 | 206 | ]; |
207 | 207 | foreach ($this->model_obj_nodes as $id => $model_obj_node) { |
208 | - $tree['objs'][ $id ] = $model_obj_node->toArray(); |
|
208 | + $tree['objs'][$id] = $model_obj_node->toArray(); |
|
209 | 209 | } |
210 | 210 | return $tree; |
211 | 211 | } |
@@ -31,66 +31,66 @@ |
||
31 | 31 | */ |
32 | 32 | abstract class BaseNode |
33 | 33 | { |
34 | - /** |
|
35 | - * @var boolean |
|
36 | - */ |
|
37 | - protected $complete; |
|
38 | - /** |
|
39 | - * Whether this item has already been initialized |
|
40 | - */ |
|
41 | - abstract protected function isDiscovered(); |
|
34 | + /** |
|
35 | + * @var boolean |
|
36 | + */ |
|
37 | + protected $complete; |
|
38 | + /** |
|
39 | + * Whether this item has already been initialized |
|
40 | + */ |
|
41 | + abstract protected function isDiscovered(); |
|
42 | 42 | |
43 | - /** |
|
44 | - * Determines if the work is done yet or not. Requires you to have first discovered what work exists by calling |
|
45 | - * discover(). |
|
46 | - * @since $VID:$ |
|
47 | - * @return boolean |
|
48 | - */ |
|
49 | - abstract public function isComplete(); |
|
43 | + /** |
|
44 | + * Determines if the work is done yet or not. Requires you to have first discovered what work exists by calling |
|
45 | + * discover(). |
|
46 | + * @since $VID:$ |
|
47 | + * @return boolean |
|
48 | + */ |
|
49 | + abstract public function isComplete(); |
|
50 | 50 | |
51 | - /** |
|
52 | - * Discovers what work needs to be done to complete traversing this node and its children. |
|
53 | - * Note that this is separate from the constructor, so we can create child nodes without |
|
54 | - * discovering them immediately. |
|
55 | - * @since $VID:$ |
|
56 | - * @return mixed |
|
57 | - */ |
|
58 | - abstract protected function discover(); |
|
51 | + /** |
|
52 | + * Discovers what work needs to be done to complete traversing this node and its children. |
|
53 | + * Note that this is separate from the constructor, so we can create child nodes without |
|
54 | + * discovering them immediately. |
|
55 | + * @since $VID:$ |
|
56 | + * @return mixed |
|
57 | + */ |
|
58 | + abstract protected function discover(); |
|
59 | 59 | |
60 | - /** |
|
61 | - * Discovers how much work there is to do, double-checks the work isn't already finished, and then does the work. |
|
62 | - * Note: do not call when site is in maintenance mode level 2. |
|
63 | - * |
|
64 | - * @since $VID:$ |
|
65 | - * @param $model_objects_to_identify |
|
66 | - * @return int number of model objects we want to identify during this call. On subsequent calls we'll continue |
|
67 | - * where we left off. |
|
68 | - */ |
|
69 | - public function visit($model_objects_to_identify) |
|
70 | - { |
|
71 | - if (! $this->isDiscovered()) { |
|
72 | - $this->discover(); |
|
73 | - } |
|
74 | - if ($this->isComplete()) { |
|
75 | - return 0; |
|
76 | - } |
|
77 | - return $this->work($model_objects_to_identify); |
|
78 | - } |
|
60 | + /** |
|
61 | + * Discovers how much work there is to do, double-checks the work isn't already finished, and then does the work. |
|
62 | + * Note: do not call when site is in maintenance mode level 2. |
|
63 | + * |
|
64 | + * @since $VID:$ |
|
65 | + * @param $model_objects_to_identify |
|
66 | + * @return int number of model objects we want to identify during this call. On subsequent calls we'll continue |
|
67 | + * where we left off. |
|
68 | + */ |
|
69 | + public function visit($model_objects_to_identify) |
|
70 | + { |
|
71 | + if (! $this->isDiscovered()) { |
|
72 | + $this->discover(); |
|
73 | + } |
|
74 | + if ($this->isComplete()) { |
|
75 | + return 0; |
|
76 | + } |
|
77 | + return $this->work($model_objects_to_identify); |
|
78 | + } |
|
79 | 79 | |
80 | - /** |
|
81 | - * Identifies model objects, up to the limit $model_objects_to_identify. |
|
82 | - * @since $VID:$ |
|
83 | - * @param int $model_objects_to_identify |
|
84 | - * @return int units of work done |
|
85 | - */ |
|
86 | - abstract protected function work($model_objects_to_identify); |
|
80 | + /** |
|
81 | + * Identifies model objects, up to the limit $model_objects_to_identify. |
|
82 | + * @since $VID:$ |
|
83 | + * @param int $model_objects_to_identify |
|
84 | + * @return int units of work done |
|
85 | + */ |
|
86 | + abstract protected function work($model_objects_to_identify); |
|
87 | 87 | |
88 | - /** |
|
89 | - * Shows the entity/relation node as an array. |
|
90 | - * @since $VID:$ |
|
91 | - * @return array |
|
92 | - */ |
|
93 | - abstract public function toArray(); |
|
88 | + /** |
|
89 | + * Shows the entity/relation node as an array. |
|
90 | + * @since $VID:$ |
|
91 | + * @return array |
|
92 | + */ |
|
93 | + abstract public function toArray(); |
|
94 | 94 | } |
95 | 95 | // End of file BaseNode.php |
96 | 96 | // Location: EventEspresso\core\services\orm\tree_traversal/BaseNode.php |
@@ -68,7 +68,7 @@ |
||
68 | 68 | */ |
69 | 69 | public function visit($model_objects_to_identify) |
70 | 70 | { |
71 | - if (! $this->isDiscovered()) { |
|
71 | + if ( ! $this->isDiscovered()) { |
|
72 | 72 | $this->discover(); |
73 | 73 | } |
74 | 74 | if ($this->isComplete()) { |
@@ -21,112 +21,112 @@ |
||
21 | 21 | */ |
22 | 22 | class ModelObjNode extends BaseNode |
23 | 23 | { |
24 | - /** |
|
25 | - * @var EE_Base_Class |
|
26 | - */ |
|
27 | - protected $model_obj; |
|
24 | + /** |
|
25 | + * @var EE_Base_Class |
|
26 | + */ |
|
27 | + protected $model_obj; |
|
28 | 28 | |
29 | - /** |
|
30 | - * @var RelationNode[] |
|
31 | - */ |
|
32 | - protected $relation_nodes; |
|
29 | + /** |
|
30 | + * @var RelationNode[] |
|
31 | + */ |
|
32 | + protected $relation_nodes; |
|
33 | 33 | |
34 | - public function __construct($instance) |
|
35 | - { |
|
36 | - $this->model_obj = $instance; |
|
37 | - } |
|
34 | + public function __construct($instance) |
|
35 | + { |
|
36 | + $this->model_obj = $instance; |
|
37 | + } |
|
38 | 38 | |
39 | - /** |
|
40 | - * Creates a relation node for each relation of this model's relations. |
|
41 | - * Does NOT call `discover` on them yet though. |
|
42 | - * @since $VID:$ |
|
43 | - * @throws \EE_Error |
|
44 | - * @throws InvalidDataTypeException |
|
45 | - * @throws InvalidInterfaceException |
|
46 | - * @throws InvalidArgumentException |
|
47 | - * @throws ReflectionException |
|
48 | - */ |
|
49 | - protected function discover() |
|
50 | - { |
|
51 | - $this->relation_nodes = []; |
|
52 | - foreach ($this->model_obj->get_model()->relation_settings() as $relationName => $relation) { |
|
53 | - if ($relation instanceof EE_Has_Many_Relation) { |
|
54 | - $this->relation_nodes[ $relationName ] = new RelationNode($this->model_obj, $relation->get_other_model()); |
|
55 | - } elseif ($relation instanceof EE_HABTM_Relation) { |
|
56 | - $this->relation_nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode($this->model_obj, $relation->get_join_model()); |
|
57 | - } |
|
58 | - } |
|
59 | - ksort($this->relation_nodes); |
|
60 | - } |
|
39 | + /** |
|
40 | + * Creates a relation node for each relation of this model's relations. |
|
41 | + * Does NOT call `discover` on them yet though. |
|
42 | + * @since $VID:$ |
|
43 | + * @throws \EE_Error |
|
44 | + * @throws InvalidDataTypeException |
|
45 | + * @throws InvalidInterfaceException |
|
46 | + * @throws InvalidArgumentException |
|
47 | + * @throws ReflectionException |
|
48 | + */ |
|
49 | + protected function discover() |
|
50 | + { |
|
51 | + $this->relation_nodes = []; |
|
52 | + foreach ($this->model_obj->get_model()->relation_settings() as $relationName => $relation) { |
|
53 | + if ($relation instanceof EE_Has_Many_Relation) { |
|
54 | + $this->relation_nodes[ $relationName ] = new RelationNode($this->model_obj, $relation->get_other_model()); |
|
55 | + } elseif ($relation instanceof EE_HABTM_Relation) { |
|
56 | + $this->relation_nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode($this->model_obj, $relation->get_join_model()); |
|
57 | + } |
|
58 | + } |
|
59 | + ksort($this->relation_nodes); |
|
60 | + } |
|
61 | 61 | |
62 | 62 | |
63 | - /** |
|
64 | - * Whether this item has already been initialized |
|
65 | - */ |
|
66 | - protected function isDiscovered() |
|
67 | - { |
|
68 | - return $this->relation_nodes !== null && is_array($this->relation_nodes); |
|
69 | - } |
|
63 | + /** |
|
64 | + * Whether this item has already been initialized |
|
65 | + */ |
|
66 | + protected function isDiscovered() |
|
67 | + { |
|
68 | + return $this->relation_nodes !== null && is_array($this->relation_nodes); |
|
69 | + } |
|
70 | 70 | |
71 | - /** |
|
72 | - * @since $VID:$ |
|
73 | - * @return boolean |
|
74 | - */ |
|
75 | - public function isComplete() |
|
76 | - { |
|
77 | - if ($this->complete === null) { |
|
78 | - $this->complete = false; |
|
79 | - } |
|
80 | - return $this->complete; |
|
81 | - } |
|
71 | + /** |
|
72 | + * @since $VID:$ |
|
73 | + * @return boolean |
|
74 | + */ |
|
75 | + public function isComplete() |
|
76 | + { |
|
77 | + if ($this->complete === null) { |
|
78 | + $this->complete = false; |
|
79 | + } |
|
80 | + return $this->complete; |
|
81 | + } |
|
82 | 82 | |
83 | - /** |
|
84 | - * Triggers working on each child relation node that has work to do. |
|
85 | - * @since $VID:$ |
|
86 | - * @param $model_objects_to_identify |
|
87 | - * @return int units of work done |
|
88 | - */ |
|
89 | - protected function work($model_objects_to_identify) |
|
90 | - { |
|
91 | - $num_identified = 0; |
|
92 | - // Begin assuming we'll finish all the work on this node and its children... |
|
93 | - $this->complete = true; |
|
94 | - foreach ($this->relation_nodes as $relation_node) { |
|
95 | - $num_identified += $relation_node->visit($model_objects_to_identify); |
|
96 | - if ($num_identified >= $model_objects_to_identify) { |
|
97 | - // ...but admit we're wrong if the work exceeded the budget. |
|
98 | - $this->complete = false; |
|
99 | - break; |
|
100 | - } |
|
101 | - } |
|
102 | - return $num_identified; |
|
103 | - } |
|
83 | + /** |
|
84 | + * Triggers working on each child relation node that has work to do. |
|
85 | + * @since $VID:$ |
|
86 | + * @param $model_objects_to_identify |
|
87 | + * @return int units of work done |
|
88 | + */ |
|
89 | + protected function work($model_objects_to_identify) |
|
90 | + { |
|
91 | + $num_identified = 0; |
|
92 | + // Begin assuming we'll finish all the work on this node and its children... |
|
93 | + $this->complete = true; |
|
94 | + foreach ($this->relation_nodes as $relation_node) { |
|
95 | + $num_identified += $relation_node->visit($model_objects_to_identify); |
|
96 | + if ($num_identified >= $model_objects_to_identify) { |
|
97 | + // ...but admit we're wrong if the work exceeded the budget. |
|
98 | + $this->complete = false; |
|
99 | + break; |
|
100 | + } |
|
101 | + } |
|
102 | + return $num_identified; |
|
103 | + } |
|
104 | 104 | |
105 | - /** |
|
106 | - * @since $VID:$ |
|
107 | - * @return array |
|
108 | - * @throws \EE_Error |
|
109 | - * @throws InvalidDataTypeException |
|
110 | - * @throws InvalidInterfaceException |
|
111 | - * @throws InvalidArgumentException |
|
112 | - * @throws ReflectionException |
|
113 | - */ |
|
114 | - public function toArray() |
|
115 | - { |
|
116 | - $tree = [ |
|
117 | - 'id' => $this->model_obj->ID(), |
|
118 | - 'complete' => $this->isComplete(), |
|
119 | - 'rels' => [] |
|
120 | - ]; |
|
121 | - if ($this->relation_nodes === null) { |
|
122 | - $tree['rels'] = null; |
|
123 | - } else { |
|
124 | - foreach ($this->relation_nodes as $relation_name => $relation_node) { |
|
125 | - $tree['rels'][ $relation_name ] = $relation_node->toArray(); |
|
126 | - } |
|
127 | - } |
|
128 | - return $tree; |
|
129 | - } |
|
105 | + /** |
|
106 | + * @since $VID:$ |
|
107 | + * @return array |
|
108 | + * @throws \EE_Error |
|
109 | + * @throws InvalidDataTypeException |
|
110 | + * @throws InvalidInterfaceException |
|
111 | + * @throws InvalidArgumentException |
|
112 | + * @throws ReflectionException |
|
113 | + */ |
|
114 | + public function toArray() |
|
115 | + { |
|
116 | + $tree = [ |
|
117 | + 'id' => $this->model_obj->ID(), |
|
118 | + 'complete' => $this->isComplete(), |
|
119 | + 'rels' => [] |
|
120 | + ]; |
|
121 | + if ($this->relation_nodes === null) { |
|
122 | + $tree['rels'] = null; |
|
123 | + } else { |
|
124 | + foreach ($this->relation_nodes as $relation_name => $relation_node) { |
|
125 | + $tree['rels'][ $relation_name ] = $relation_node->toArray(); |
|
126 | + } |
|
127 | + } |
|
128 | + return $tree; |
|
129 | + } |
|
130 | 130 | } |
131 | 131 | // End of file Visitor.php |
132 | 132 | // Location: EventEspresso\core\services\orm\tree_traversal/Visitor.php |
@@ -51,9 +51,9 @@ discard block |
||
51 | 51 | $this->relation_nodes = []; |
52 | 52 | foreach ($this->model_obj->get_model()->relation_settings() as $relationName => $relation) { |
53 | 53 | if ($relation instanceof EE_Has_Many_Relation) { |
54 | - $this->relation_nodes[ $relationName ] = new RelationNode($this->model_obj, $relation->get_other_model()); |
|
54 | + $this->relation_nodes[$relationName] = new RelationNode($this->model_obj, $relation->get_other_model()); |
|
55 | 55 | } elseif ($relation instanceof EE_HABTM_Relation) { |
56 | - $this->relation_nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode($this->model_obj, $relation->get_join_model()); |
|
56 | + $this->relation_nodes[$relation->get_join_model()->get_this_model_name()] = new RelationNode($this->model_obj, $relation->get_join_model()); |
|
57 | 57 | } |
58 | 58 | } |
59 | 59 | ksort($this->relation_nodes); |
@@ -122,7 +122,7 @@ discard block |
||
122 | 122 | $tree['rels'] = null; |
123 | 123 | } else { |
124 | 124 | foreach ($this->relation_nodes as $relation_name => $relation_node) { |
125 | - $tree['rels'][ $relation_name ] = $relation_node->toArray(); |
|
125 | + $tree['rels'][$relation_name] = $relation_node->toArray(); |
|
126 | 126 | } |
127 | 127 | } |
128 | 128 | return $tree; |