@@ -20,7 +20,7 @@ discard block |
||
20 | 20 | */ |
21 | 21 | public function __construct($pm_instance = null) |
22 | 22 | { |
23 | - require_once($this->file_folder() . 'EEG_Paypal_Pro.gateway.php'); |
|
23 | + require_once($this->file_folder().'EEG_Paypal_Pro.gateway.php'); |
|
24 | 24 | $this->_gateway = new EEG_Paypal_Pro(); |
25 | 25 | $this->_pretty_name = esc_html__("Paypal Pro", 'event_espresso'); |
26 | 26 | $this->_default_description = esc_html__('Please provide the following billing information.', 'event_espresso'); |
@@ -63,22 +63,22 @@ discard block |
||
63 | 63 | // 'html_id'=> 'ee-Paypal_Pro-billing-form', |
64 | 64 | 'subsections' => array( |
65 | 65 | 'credit_card' => new EE_Credit_Card_Input( |
66 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Number', 'event_espresso')) |
|
66 | + array('required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Number', 'event_espresso')) |
|
67 | 67 | ), |
68 | 68 | 'credit_card_type' => new EE_Select_Input( |
69 | 69 | // the options are set dynamically |
70 | 70 | array_intersect_key(EE_PMT_Paypal_Pro::card_types_supported(), array_flip($allowed_types)), |
71 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Type', 'event_espresso')) |
|
71 | + array('required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Type', 'event_espresso')) |
|
72 | 72 | ), |
73 | 73 | 'exp_month' => new EE_Credit_Card_Month_Input( |
74 | 74 | true, |
75 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Month', 'event_espresso') ) |
|
75 | + array('required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Month', 'event_espresso')) |
|
76 | 76 | ), |
77 | 77 | 'exp_year' => new EE_Credit_Card_Year_Input( |
78 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Year', 'event_espresso') ) |
|
78 | + array('required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Year', 'event_espresso')) |
|
79 | 79 | ), |
80 | 80 | 'cvv' => new EE_CVV_Input( |
81 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('CVV', 'event_espresso') ) |
|
81 | + array('required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('CVV', 'event_espresso')) |
|
82 | 82 | ), |
83 | 83 | ) |
84 | 84 | ) |
@@ -99,11 +99,11 @@ discard block |
||
99 | 99 | { |
100 | 100 | if ($this->_pm_instance->debug_mode()) { |
101 | 101 | $billing_form->add_subsections( |
102 | - array( 'fyi_about_autofill' => $billing_form->payment_fields_autofilled_notice_html() ), |
|
102 | + array('fyi_about_autofill' => $billing_form->payment_fields_autofilled_notice_html()), |
|
103 | 103 | 'credit_card' |
104 | 104 | ); |
105 | 105 | $billing_form->add_subsections( |
106 | - array( 'debug_content' => new EE_Form_Section_HTML_From_Template(dirname(__FILE__) . '/templates/paypal_pro_debug_info.template.php')), |
|
106 | + array('debug_content' => new EE_Form_Section_HTML_From_Template(dirname(__FILE__).'/templates/paypal_pro_debug_info.template.php')), |
|
107 | 107 | 'first_name' |
108 | 108 | ); |
109 | 109 | $billing_form->get_input('credit_card_type')->set_default('Visa'); |
@@ -184,9 +184,9 @@ discard block |
||
184 | 184 | ] |
185 | 185 | ); |
186 | 186 | // If they existed, set the new ones instead |
187 | - if (!empty($old_extra_metas)) { |
|
187 | + if ( ! empty($old_extra_metas)) { |
|
188 | 188 | foreach ($old_extra_metas as $old_extra_meta) { |
189 | - $old_extra_meta->set('EXM_key', 'api_' . $old_extra_meta->get('EXM_key')); |
|
189 | + $old_extra_meta->set('EXM_key', 'api_'.$old_extra_meta->get('EXM_key')); |
|
190 | 190 | $old_extra_meta->save(); |
191 | 191 | } |
192 | 192 | } |
@@ -13,186 +13,186 @@ |
||
13 | 13 | */ |
14 | 14 | class EE_PMT_Paypal_Pro extends EE_PMT_Base |
15 | 15 | { |
16 | - /** |
|
17 | - * @param EE_Payment_Method $pm_instance |
|
18 | - * @return EE_PMT_Paypal_Pro |
|
19 | - */ |
|
20 | - public function __construct($pm_instance = null) |
|
21 | - { |
|
22 | - require_once($this->file_folder() . 'EEG_Paypal_Pro.gateway.php'); |
|
23 | - $this->_gateway = new EEG_Paypal_Pro(); |
|
24 | - $this->_pretty_name = esc_html__("Paypal Pro", 'event_espresso'); |
|
25 | - $this->_default_description = esc_html__('Please provide the following billing information.', 'event_espresso'); |
|
26 | - $this->_requires_https = true; |
|
27 | - parent::__construct($pm_instance); |
|
28 | - } |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * Gets the form for all the settings related to this payment method type |
|
33 | - * @return EE_Payment_Method_Form |
|
34 | - * @throws InvalidArgumentException |
|
35 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
36 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
37 | - */ |
|
38 | - public function generate_new_settings_form() |
|
39 | - { |
|
40 | - return new PayPalProSettingsForm(array(), $this->get_help_tab_link()); |
|
41 | - } |
|
42 | - |
|
43 | - |
|
44 | - /** |
|
45 | - * Creates the billing form for this payment method type |
|
46 | - * @param \EE_Transaction $transaction |
|
47 | - * @throws \EE_Error |
|
48 | - * @return EE_Billing_Info_Form |
|
49 | - */ |
|
50 | - public function generate_new_billing_form(EE_Transaction $transaction = null) |
|
51 | - { |
|
52 | - $allowed_types = $this->_pm_instance->get_extra_meta('credit_card_types', true); |
|
53 | - // if allowed types is a string or empty array or null... |
|
54 | - if (empty($allowed_types)) { |
|
55 | - $allowed_types = array(); |
|
56 | - } |
|
57 | - |
|
58 | - $billing_form = new EE_Billing_Attendee_Info_Form( |
|
59 | - $this->_pm_instance, |
|
60 | - array( |
|
61 | - 'name' => 'Paypal_Pro_Billing_Form', |
|
62 | - // 'html_id'=> 'ee-Paypal_Pro-billing-form', |
|
63 | - 'subsections' => array( |
|
64 | - 'credit_card' => new EE_Credit_Card_Input( |
|
65 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Number', 'event_espresso')) |
|
66 | - ), |
|
67 | - 'credit_card_type' => new EE_Select_Input( |
|
68 | - // the options are set dynamically |
|
69 | - array_intersect_key(EE_PMT_Paypal_Pro::card_types_supported(), array_flip($allowed_types)), |
|
70 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Type', 'event_espresso')) |
|
71 | - ), |
|
72 | - 'exp_month' => new EE_Credit_Card_Month_Input( |
|
73 | - true, |
|
74 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Month', 'event_espresso') ) |
|
75 | - ), |
|
76 | - 'exp_year' => new EE_Credit_Card_Year_Input( |
|
77 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Year', 'event_espresso') ) |
|
78 | - ), |
|
79 | - 'cvv' => new EE_CVV_Input( |
|
80 | - array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('CVV', 'event_espresso') ) |
|
81 | - ), |
|
82 | - ) |
|
83 | - ) |
|
84 | - ); |
|
85 | - return $this->apply_billing_form_debug_settings($billing_form); |
|
86 | - } |
|
87 | - |
|
88 | - |
|
89 | - |
|
90 | - /** |
|
91 | - * apply_billing_form_debug_settings |
|
92 | - * applies debug data to the form |
|
93 | - * |
|
94 | - * @param \EE_Billing_Info_Form $billing_form |
|
95 | - * @return \EE_Billing_Info_Form |
|
96 | - */ |
|
97 | - public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form) |
|
98 | - { |
|
99 | - if ($this->_pm_instance->debug_mode()) { |
|
100 | - $billing_form->add_subsections( |
|
101 | - array( 'fyi_about_autofill' => $billing_form->payment_fields_autofilled_notice_html() ), |
|
102 | - 'credit_card' |
|
103 | - ); |
|
104 | - $billing_form->add_subsections( |
|
105 | - array( 'debug_content' => new EE_Form_Section_HTML_From_Template(dirname(__FILE__) . '/templates/paypal_pro_debug_info.template.php')), |
|
106 | - 'first_name' |
|
107 | - ); |
|
108 | - $billing_form->get_input('credit_card_type')->set_default('Visa'); |
|
109 | - $billing_form->get_input('exp_year')->set_default(2018); |
|
110 | - $billing_form->get_input('cvv')->set_default('115'); |
|
111 | - } |
|
112 | - return $billing_form; |
|
113 | - } |
|
114 | - |
|
115 | - |
|
116 | - |
|
117 | - /** |
|
118 | - * Returns an array of all the payment cards possibly supported by paypal pro. |
|
119 | - * Keys are their values, values are their pretty names. |
|
120 | - * @return array |
|
121 | - */ |
|
122 | - public static function card_types_supported() |
|
123 | - { |
|
124 | - return array( |
|
125 | - 'Visa' => esc_html__("Visa", 'event_espresso'), |
|
126 | - 'MasterCard' => esc_html__("MasterCard", 'event_espresso'), |
|
127 | - 'Amex' => esc_html__("American Express", 'event_espresso'), |
|
128 | - 'Discover' => esc_html__("Discover", 'event_espresso') |
|
129 | - ); |
|
130 | - } |
|
131 | - |
|
132 | - |
|
133 | - |
|
134 | - /** |
|
135 | - * Adds the help tab |
|
136 | - * @see EE_PMT_Base::help_tabs_config() |
|
137 | - * @return array |
|
138 | - */ |
|
139 | - public function help_tabs_config() |
|
140 | - { |
|
141 | - return array( |
|
142 | - $this->get_help_tab_name() => array( |
|
143 | - 'title' => esc_html__('PayPal Pro Settings', 'event_espresso'), |
|
144 | - 'filename' => 'payment_methods_overview_paypalpro' |
|
145 | - ), |
|
146 | - ); |
|
147 | - } |
|
148 | - |
|
149 | - |
|
150 | - /** |
|
151 | - * Overrides parent's _get_billing_values_from_form because we want to |
|
152 | - * get the country's 2-character ISO code, not the name like most gateways |
|
153 | - * |
|
154 | - * @param EE_Billing_Info_Form $billing_form |
|
155 | - * @return array |
|
156 | - * @throws EE_Error |
|
157 | - */ |
|
158 | - protected function _get_billing_values_from_form($billing_form) |
|
159 | - { |
|
160 | - $billing_values = parent::_get_billing_values_from_form($billing_form); |
|
161 | - $billing_values['country'] = $billing_form->get_input_value('country'); |
|
162 | - $billing_values['credit_card_type'] = $billing_form->get_input_value('credit_card_type'); |
|
163 | - return $billing_values; |
|
164 | - } |
|
165 | - |
|
166 | - /** |
|
167 | - * Override parent to account for a change in extra meta inputs in 4.9.75.p |
|
168 | - * |
|
169 | - * @param EE_Payment_Method $payment_method_instance |
|
170 | - * @throws EE_Error |
|
171 | - * @throws InvalidArgumentException |
|
172 | - * @throws ReflectionException |
|
173 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
174 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
175 | - *@since 4.9.79.p |
|
176 | - */ |
|
177 | - public function set_instance(EE_Payment_Method $payment_method_instance) |
|
178 | - { |
|
179 | - // Check for the old extra meta inputs |
|
180 | - $old_extra_metas = EEM_Extra_Meta::instance()->get_all( |
|
181 | - [ |
|
182 | - [ |
|
183 | - 'EXM_type' => 'Payment_Method', |
|
184 | - 'OBJ_ID' => $payment_method_instance->ID(), |
|
185 | - 'EXM_key' => ['IN', ['username', 'password', 'signature']], |
|
186 | - ] |
|
187 | - ] |
|
188 | - ); |
|
189 | - // If they existed, set the new ones instead |
|
190 | - if (!empty($old_extra_metas)) { |
|
191 | - foreach ($old_extra_metas as $old_extra_meta) { |
|
192 | - $old_extra_meta->set('EXM_key', 'api_' . $old_extra_meta->get('EXM_key')); |
|
193 | - $old_extra_meta->save(); |
|
194 | - } |
|
195 | - } |
|
196 | - return parent::set_instance($payment_method_instance); |
|
197 | - } |
|
16 | + /** |
|
17 | + * @param EE_Payment_Method $pm_instance |
|
18 | + * @return EE_PMT_Paypal_Pro |
|
19 | + */ |
|
20 | + public function __construct($pm_instance = null) |
|
21 | + { |
|
22 | + require_once($this->file_folder() . 'EEG_Paypal_Pro.gateway.php'); |
|
23 | + $this->_gateway = new EEG_Paypal_Pro(); |
|
24 | + $this->_pretty_name = esc_html__("Paypal Pro", 'event_espresso'); |
|
25 | + $this->_default_description = esc_html__('Please provide the following billing information.', 'event_espresso'); |
|
26 | + $this->_requires_https = true; |
|
27 | + parent::__construct($pm_instance); |
|
28 | + } |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * Gets the form for all the settings related to this payment method type |
|
33 | + * @return EE_Payment_Method_Form |
|
34 | + * @throws InvalidArgumentException |
|
35 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
36 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
37 | + */ |
|
38 | + public function generate_new_settings_form() |
|
39 | + { |
|
40 | + return new PayPalProSettingsForm(array(), $this->get_help_tab_link()); |
|
41 | + } |
|
42 | + |
|
43 | + |
|
44 | + /** |
|
45 | + * Creates the billing form for this payment method type |
|
46 | + * @param \EE_Transaction $transaction |
|
47 | + * @throws \EE_Error |
|
48 | + * @return EE_Billing_Info_Form |
|
49 | + */ |
|
50 | + public function generate_new_billing_form(EE_Transaction $transaction = null) |
|
51 | + { |
|
52 | + $allowed_types = $this->_pm_instance->get_extra_meta('credit_card_types', true); |
|
53 | + // if allowed types is a string or empty array or null... |
|
54 | + if (empty($allowed_types)) { |
|
55 | + $allowed_types = array(); |
|
56 | + } |
|
57 | + |
|
58 | + $billing_form = new EE_Billing_Attendee_Info_Form( |
|
59 | + $this->_pm_instance, |
|
60 | + array( |
|
61 | + 'name' => 'Paypal_Pro_Billing_Form', |
|
62 | + // 'html_id'=> 'ee-Paypal_Pro-billing-form', |
|
63 | + 'subsections' => array( |
|
64 | + 'credit_card' => new EE_Credit_Card_Input( |
|
65 | + array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Number', 'event_espresso')) |
|
66 | + ), |
|
67 | + 'credit_card_type' => new EE_Select_Input( |
|
68 | + // the options are set dynamically |
|
69 | + array_intersect_key(EE_PMT_Paypal_Pro::card_types_supported(), array_flip($allowed_types)), |
|
70 | + array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Card Type', 'event_espresso')) |
|
71 | + ), |
|
72 | + 'exp_month' => new EE_Credit_Card_Month_Input( |
|
73 | + true, |
|
74 | + array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Month', 'event_espresso') ) |
|
75 | + ), |
|
76 | + 'exp_year' => new EE_Credit_Card_Year_Input( |
|
77 | + array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('Expiry Year', 'event_espresso') ) |
|
78 | + ), |
|
79 | + 'cvv' => new EE_CVV_Input( |
|
80 | + array( 'required' => true, 'html_class' => 'ee-billing-qstn', 'html_label_text' => esc_html__('CVV', 'event_espresso') ) |
|
81 | + ), |
|
82 | + ) |
|
83 | + ) |
|
84 | + ); |
|
85 | + return $this->apply_billing_form_debug_settings($billing_form); |
|
86 | + } |
|
87 | + |
|
88 | + |
|
89 | + |
|
90 | + /** |
|
91 | + * apply_billing_form_debug_settings |
|
92 | + * applies debug data to the form |
|
93 | + * |
|
94 | + * @param \EE_Billing_Info_Form $billing_form |
|
95 | + * @return \EE_Billing_Info_Form |
|
96 | + */ |
|
97 | + public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form) |
|
98 | + { |
|
99 | + if ($this->_pm_instance->debug_mode()) { |
|
100 | + $billing_form->add_subsections( |
|
101 | + array( 'fyi_about_autofill' => $billing_form->payment_fields_autofilled_notice_html() ), |
|
102 | + 'credit_card' |
|
103 | + ); |
|
104 | + $billing_form->add_subsections( |
|
105 | + array( 'debug_content' => new EE_Form_Section_HTML_From_Template(dirname(__FILE__) . '/templates/paypal_pro_debug_info.template.php')), |
|
106 | + 'first_name' |
|
107 | + ); |
|
108 | + $billing_form->get_input('credit_card_type')->set_default('Visa'); |
|
109 | + $billing_form->get_input('exp_year')->set_default(2018); |
|
110 | + $billing_form->get_input('cvv')->set_default('115'); |
|
111 | + } |
|
112 | + return $billing_form; |
|
113 | + } |
|
114 | + |
|
115 | + |
|
116 | + |
|
117 | + /** |
|
118 | + * Returns an array of all the payment cards possibly supported by paypal pro. |
|
119 | + * Keys are their values, values are their pretty names. |
|
120 | + * @return array |
|
121 | + */ |
|
122 | + public static function card_types_supported() |
|
123 | + { |
|
124 | + return array( |
|
125 | + 'Visa' => esc_html__("Visa", 'event_espresso'), |
|
126 | + 'MasterCard' => esc_html__("MasterCard", 'event_espresso'), |
|
127 | + 'Amex' => esc_html__("American Express", 'event_espresso'), |
|
128 | + 'Discover' => esc_html__("Discover", 'event_espresso') |
|
129 | + ); |
|
130 | + } |
|
131 | + |
|
132 | + |
|
133 | + |
|
134 | + /** |
|
135 | + * Adds the help tab |
|
136 | + * @see EE_PMT_Base::help_tabs_config() |
|
137 | + * @return array |
|
138 | + */ |
|
139 | + public function help_tabs_config() |
|
140 | + { |
|
141 | + return array( |
|
142 | + $this->get_help_tab_name() => array( |
|
143 | + 'title' => esc_html__('PayPal Pro Settings', 'event_espresso'), |
|
144 | + 'filename' => 'payment_methods_overview_paypalpro' |
|
145 | + ), |
|
146 | + ); |
|
147 | + } |
|
148 | + |
|
149 | + |
|
150 | + /** |
|
151 | + * Overrides parent's _get_billing_values_from_form because we want to |
|
152 | + * get the country's 2-character ISO code, not the name like most gateways |
|
153 | + * |
|
154 | + * @param EE_Billing_Info_Form $billing_form |
|
155 | + * @return array |
|
156 | + * @throws EE_Error |
|
157 | + */ |
|
158 | + protected function _get_billing_values_from_form($billing_form) |
|
159 | + { |
|
160 | + $billing_values = parent::_get_billing_values_from_form($billing_form); |
|
161 | + $billing_values['country'] = $billing_form->get_input_value('country'); |
|
162 | + $billing_values['credit_card_type'] = $billing_form->get_input_value('credit_card_type'); |
|
163 | + return $billing_values; |
|
164 | + } |
|
165 | + |
|
166 | + /** |
|
167 | + * Override parent to account for a change in extra meta inputs in 4.9.75.p |
|
168 | + * |
|
169 | + * @param EE_Payment_Method $payment_method_instance |
|
170 | + * @throws EE_Error |
|
171 | + * @throws InvalidArgumentException |
|
172 | + * @throws ReflectionException |
|
173 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
174 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
175 | + *@since 4.9.79.p |
|
176 | + */ |
|
177 | + public function set_instance(EE_Payment_Method $payment_method_instance) |
|
178 | + { |
|
179 | + // Check for the old extra meta inputs |
|
180 | + $old_extra_metas = EEM_Extra_Meta::instance()->get_all( |
|
181 | + [ |
|
182 | + [ |
|
183 | + 'EXM_type' => 'Payment_Method', |
|
184 | + 'OBJ_ID' => $payment_method_instance->ID(), |
|
185 | + 'EXM_key' => ['IN', ['username', 'password', 'signature']], |
|
186 | + ] |
|
187 | + ] |
|
188 | + ); |
|
189 | + // If they existed, set the new ones instead |
|
190 | + if (!empty($old_extra_metas)) { |
|
191 | + foreach ($old_extra_metas as $old_extra_meta) { |
|
192 | + $old_extra_meta->set('EXM_key', 'api_' . $old_extra_meta->get('EXM_key')); |
|
193 | + $old_extra_meta->save(); |
|
194 | + } |
|
195 | + } |
|
196 | + return parent::set_instance($payment_method_instance); |
|
197 | + } |
|
198 | 198 | } |
@@ -191,7 +191,7 @@ discard block |
||
191 | 191 | $line_item->unit_price(), |
192 | 192 | 'N' |
193 | 193 | ); |
194 | - $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', '; |
|
194 | + $order_description .= $this->prepareStringForAuthnet($line_item->desc()).', '; |
|
195 | 195 | } |
196 | 196 | foreach ($total_line_item->tax_descendants() as $tax_line_item) { |
197 | 197 | $this->addLineItem( |
@@ -216,7 +216,7 @@ discard block |
||
216 | 216 | $this->setField('last_name', $billing_info['last_name']); |
217 | 217 | $this->setField('email', $billing_info['email']); |
218 | 218 | $this->setField('company', $billing_info['company']); |
219 | - $this->setField('address', $billing_info['address'] . ' ' . $billing_info['address2']); |
|
219 | + $this->setField('address', $billing_info['address'].' '.$billing_info['address2']); |
|
220 | 220 | $this->setField('city', $billing_info['city']); |
221 | 221 | $this->setField('state', $billing_info['state']); |
222 | 222 | $this->setField('country', $billing_info['country']); |
@@ -229,7 +229,7 @@ discard block |
||
229 | 229 | // invoice_num would be nice to have it be unique per SPCO page-load, that way if users |
230 | 230 | // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page |
231 | 231 | // in which case, we need to generate teh invoice num per request right here... |
232 | - $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
232 | + $this->setField('invoice_num', wp_generate_password(12, false)); // $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
233 | 233 | // tell AIM that any duplicates sent in the next 5 minutes are to be ignored |
234 | 234 | $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS); |
235 | 235 | |
@@ -240,7 +240,7 @@ discard block |
||
240 | 240 | // Capture response |
241 | 241 | $this->type = "AUTH_CAPTURE"; |
242 | 242 | $response = $this->_sendRequest($payment); |
243 | - if (! empty($response)) { |
|
243 | + if ( ! empty($response)) { |
|
244 | 244 | if ($response->error_message) { |
245 | 245 | $payment->set_status($this->_pay_model->failed_status()); |
246 | 246 | $payment->set_gateway_response($response->error_message); |
@@ -286,7 +286,7 @@ discard block |
||
286 | 286 | protected function _set_sensitive_billing_data($billing_info) |
287 | 287 | { |
288 | 288 | $this->setField('card_num', $billing_info['credit_card']); |
289 | - $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']); |
|
289 | + $this->setField('exp_date', $billing_info['exp_month'].$billing_info['exp_year']); |
|
290 | 290 | $this->setField('card_code', $billing_info['cvv']); |
291 | 291 | } |
292 | 292 | |
@@ -326,7 +326,7 @@ discard block |
||
326 | 326 | protected function setField($name, $value) |
327 | 327 | { |
328 | 328 | if (in_array($name, $this->_all_aim_fields)) { |
329 | - $this->_x_post_fields[ $name ] = $value; |
|
329 | + $this->_x_post_fields[$name] = $value; |
|
330 | 330 | } else { |
331 | 331 | throw new AuthorizeNetException("Error: no field $name exists in the AIM API. |
332 | 332 | To set a custom field use setCustomField('field','value') instead."); |
@@ -346,11 +346,11 @@ discard block |
||
346 | 346 | $this->_x_post_fields['tran_key'] = $this->_transaction_key; |
347 | 347 | $x_keys = array(); |
348 | 348 | foreach ($this->_x_post_fields as $key => $value) { |
349 | - $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
349 | + $x_keys[] = "x_$key=".urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
350 | 350 | } |
351 | 351 | // Add line items |
352 | 352 | foreach ($this->_additional_line_items as $key => $value) { |
353 | - $x_keys[] = "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
353 | + $x_keys[] = "x_line_item=".urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
354 | 354 | } |
355 | 355 | $this->_log_clean_request($x_keys, $payment); |
356 | 356 | $post_url = $this->_get_server_url(); |
@@ -362,7 +362,7 @@ discard block |
||
362 | 362 | curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); |
363 | 363 | curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2); |
364 | 364 | if ($this->VERIFY_PEER) { |
365 | - curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem'); |
|
365 | + curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__).'/ssl/cert.pem'); |
|
366 | 366 | } else { |
367 | 367 | curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false); |
368 | 368 | } |
@@ -374,7 +374,7 @@ discard block |
||
374 | 374 | $response = curl_exec($curl_request); |
375 | 375 | |
376 | 376 | curl_close($curl_request); |
377 | - $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
377 | + $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
378 | 378 | |
379 | 379 | return $this->_log_and_clean_response($response_obj, $payment); |
380 | 380 | } |
@@ -394,7 +394,7 @@ discard block |
||
394 | 394 | if (strpos($keyvaltogether, $key) === 0) { |
395 | 395 | // found it at the first character |
396 | 396 | // so its one of them |
397 | - unset($request_array[ $index ]); |
|
397 | + unset($request_array[$index]); |
|
398 | 398 | } |
399 | 399 | } |
400 | 400 | } |
@@ -535,7 +535,7 @@ discard block |
||
535 | 535 | // Split Array |
536 | 536 | $this->response = $response; |
537 | 537 | if ($encap_char) { |
538 | - $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1)); |
|
538 | + $this->_response_array = explode($encap_char.$delimiter.$encap_char, substr($response, 1, -1)); |
|
539 | 539 | } else { |
540 | 540 | $this->_response_array = explode($delimiter, $response); |
541 | 541 | } |
@@ -617,7 +617,7 @@ discard block |
||
617 | 617 | } |
618 | 618 | } |
619 | 619 | |
620 | -if (! class_exists('AuthorizeNetException')) { |
|
620 | +if ( ! class_exists('AuthorizeNetException')) { |
|
621 | 621 | /** |
622 | 622 | * Class AuthorizeNetException |
623 | 623 | * |
@@ -25,417 +25,417 @@ discard block |
||
25 | 25 | */ |
26 | 26 | class EEG_Aim extends EE_Onsite_Gateway |
27 | 27 | { |
28 | - const LIVE_URL = 'https://secure2.authorize.net/gateway/transact.dll'; // Authnet URL |
|
29 | - |
|
30 | - const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll'; |
|
31 | - |
|
32 | - protected $_login_id; |
|
33 | - |
|
34 | - protected $_transaction_key; |
|
35 | - |
|
36 | - protected $_currencies_supported = array( |
|
37 | - 'AUD', |
|
38 | - 'USD', |
|
39 | - 'CAD', |
|
40 | - 'EUR', |
|
41 | - 'GBP', |
|
42 | - 'NZD', |
|
43 | - ); |
|
44 | - |
|
45 | - /** |
|
46 | - * Whether to send test transactions (even to live site) |
|
47 | - * |
|
48 | - * @var boolean |
|
49 | - */ |
|
50 | - protected $_test_transactions; |
|
51 | - |
|
52 | - private $VERIFY_PEER = false; |
|
53 | - |
|
54 | - private $_x_post_fields = array( |
|
55 | - "version" => "3.1", |
|
56 | - "delim_char" => ",", |
|
57 | - "delim_data" => "TRUE", |
|
58 | - "relay_response" => "FALSE", |
|
59 | - "encap_char" => "|", |
|
60 | - ); |
|
61 | - |
|
62 | - private $_additional_line_items = array(); |
|
63 | - |
|
64 | - /** |
|
65 | - * A list of all fields in the AIM API. |
|
66 | - * Used to warn user if they try to set a field not offered in the API. |
|
67 | - */ |
|
68 | - private $_all_aim_fields = array( |
|
69 | - "address", |
|
70 | - "allow_partial_auth", |
|
71 | - "amount", |
|
72 | - "auth_code", |
|
73 | - "authentication_indicator", |
|
74 | - "bank_aba_code", |
|
75 | - "bank_acct_name", |
|
76 | - "bank_acct_num", |
|
77 | - "bank_acct_type", |
|
78 | - "bank_check_number", |
|
79 | - "bank_name", |
|
80 | - "card_code", |
|
81 | - "card_num", |
|
82 | - "cardholder_authentication_value", |
|
83 | - "city", |
|
84 | - "company", |
|
85 | - "country", |
|
86 | - "cust_id", |
|
87 | - "customer_ip", |
|
88 | - "delim_char", |
|
89 | - "delim_data", |
|
90 | - "description", |
|
91 | - "duplicate_window", |
|
92 | - "duty", |
|
93 | - "echeck_type", |
|
94 | - "email", |
|
95 | - "email_customer", |
|
96 | - "encap_char", |
|
97 | - "exp_date", |
|
98 | - "fax", |
|
99 | - "first_name", |
|
100 | - "footer_email_receipt", |
|
101 | - "freight", |
|
102 | - "header_email_receipt", |
|
103 | - "invoice_num", |
|
104 | - "last_name", |
|
105 | - "line_item", |
|
106 | - "login", |
|
107 | - "method", |
|
108 | - "phone", |
|
109 | - "po_num", |
|
110 | - "recurring_billing", |
|
111 | - "relay_response", |
|
112 | - "ship_to_address", |
|
113 | - "ship_to_city", |
|
114 | - "ship_to_company", |
|
115 | - "ship_to_country", |
|
116 | - "ship_to_first_name", |
|
117 | - "ship_to_last_name", |
|
118 | - "ship_to_state", |
|
119 | - "ship_to_zip", |
|
120 | - "split_tender_id", |
|
121 | - "state", |
|
122 | - "tax", |
|
123 | - "tax_exempt", |
|
124 | - "test_request", |
|
125 | - "tran_key", |
|
126 | - "trans_id", |
|
127 | - "type", |
|
128 | - "version", |
|
129 | - "zip", |
|
130 | - "solution_id", |
|
131 | - "currency_code" |
|
132 | - ); |
|
133 | - |
|
134 | - |
|
135 | - /** |
|
136 | - * Gets the URL where the request should go. This is filterable |
|
137 | - * |
|
138 | - * @return string |
|
139 | - */ |
|
140 | - protected function _get_server_url() |
|
141 | - { |
|
142 | - return apply_filters( |
|
143 | - 'FHEE__EEG_Aim___get_server_url', |
|
144 | - $this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL, |
|
145 | - $this |
|
146 | - ); |
|
147 | - } |
|
148 | - |
|
149 | - |
|
150 | - /** |
|
151 | - * Asks the gateway to do whatever it does to process the payment. Onsite gateways will |
|
152 | - * usually send a request directly to the payment provider and update the payment's status based on that; |
|
153 | - * whereas offsite gateways will usually just update the payment with the URL and query parameters to use |
|
154 | - * for sending the request via http_remote_request() |
|
155 | - * |
|
156 | - * @param EEI_Payment $payment |
|
157 | - * @param array $billing_info { |
|
158 | - * @type $credit_card string |
|
159 | - * @type $cvv string |
|
160 | - * @type $exp_month string |
|
161 | - * @type $exp_year string |
|
162 | - * @see parent::do_direct_payment |
|
163 | - * } |
|
164 | - * @return EEI_Payment updated |
|
165 | - */ |
|
166 | - public function do_direct_payment($payment, $billing_info = null) |
|
167 | - { |
|
168 | - // Enable test mode if needed |
|
169 | - // 4007000000027 <-- test successful visa |
|
170 | - // 4222222222222 <-- test failure card number |
|
171 | - |
|
172 | - $item_num = 1; |
|
173 | - $transaction = $payment->transaction(); |
|
174 | - $gateway_formatter = $this->_get_gateway_formatter(); |
|
175 | - $order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment)); |
|
176 | - $primary_registrant = $transaction->primary_registration(); |
|
177 | - // if we're are charging for the full amount, show the normal line items |
|
178 | - // and the itemized total adds up properly |
|
179 | - if ($this->_can_easily_itemize_transaction_for($payment)) { |
|
180 | - $total_line_item = $transaction->total_line_item(); |
|
181 | - foreach ($total_line_item->get_items() as $line_item) { |
|
182 | - if ($line_item->quantity() == 0) { |
|
183 | - continue; |
|
184 | - } |
|
185 | - $this->addLineItem( |
|
186 | - $item_num++, |
|
187 | - $gateway_formatter->formatLineItemName($line_item, $payment), |
|
188 | - $gateway_formatter->formatLineItemDesc($line_item, $payment), |
|
189 | - $line_item->quantity(), |
|
190 | - $line_item->unit_price(), |
|
191 | - 'N' |
|
192 | - ); |
|
193 | - $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', '; |
|
194 | - } |
|
195 | - foreach ($total_line_item->tax_descendants() as $tax_line_item) { |
|
196 | - $this->addLineItem( |
|
197 | - $item_num++, |
|
198 | - $tax_line_item->name(), |
|
199 | - $tax_line_item->desc(), |
|
200 | - 1, |
|
201 | - $tax_line_item->total(), |
|
202 | - 'N' |
|
203 | - ); |
|
204 | - } |
|
205 | - } |
|
206 | - |
|
207 | - // start transaction |
|
208 | - // if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id |
|
209 | - $partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363'; |
|
210 | - $this->setField('solution_id', $partner_id); |
|
211 | - $this->setField('amount', $gateway_formatter->formatCurrency($payment->amount())); |
|
212 | - $this->setField('description', substr(rtrim($order_description, ', '), 0, 255)); |
|
213 | - $this->_set_sensitive_billing_data($billing_info); |
|
214 | - $this->setField('first_name', $billing_info['first_name']); |
|
215 | - $this->setField('last_name', $billing_info['last_name']); |
|
216 | - $this->setField('email', $billing_info['email']); |
|
217 | - $this->setField('company', $billing_info['company']); |
|
218 | - $this->setField('address', $billing_info['address'] . ' ' . $billing_info['address2']); |
|
219 | - $this->setField('city', $billing_info['city']); |
|
220 | - $this->setField('state', $billing_info['state']); |
|
221 | - $this->setField('country', $billing_info['country']); |
|
222 | - $this->setField('zip', $billing_info['zip']); |
|
223 | - $this->setField('fax', $billing_info['fax']); |
|
224 | - $this->setField('cust_id', $primary_registrant->ID()); |
|
225 | - $this->setField('phone', $billing_info['phone']); |
|
226 | - $currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config'); |
|
227 | - $this->setField('currency_code', $currency_config->code); |
|
228 | - // invoice_num would be nice to have it be unique per SPCO page-load, that way if users |
|
229 | - // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page |
|
230 | - // in which case, we need to generate teh invoice num per request right here... |
|
231 | - $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
232 | - // tell AIM that any duplicates sent in the next 5 minutes are to be ignored |
|
233 | - $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS); |
|
234 | - |
|
235 | - if ($this->_test_transactions) { |
|
236 | - $this->test_request = "true"; |
|
237 | - } |
|
238 | - |
|
239 | - // Capture response |
|
240 | - $this->type = "AUTH_CAPTURE"; |
|
241 | - $response = $this->_sendRequest($payment); |
|
242 | - if (! empty($response)) { |
|
243 | - if ($response->error_message) { |
|
244 | - $payment->set_status($this->_pay_model->failed_status()); |
|
245 | - $payment->set_gateway_response($response->error_message); |
|
246 | - } else { |
|
247 | - $payment_status = $response->approved |
|
248 | - ? $this->_pay_model->approved_status() |
|
249 | - : $this->_pay_model->declined_status(); |
|
250 | - $payment->set_status($payment_status); |
|
251 | - // make sure we interpret the AMT as a float, not an international string (where periods are thousand separators) |
|
252 | - $payment->set_amount((float) $response->amount); |
|
253 | - $payment->set_gateway_response( |
|
254 | - sprintf( |
|
255 | - esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'), |
|
256 | - $response->response_reason_text, |
|
257 | - $response->response_reason_code |
|
258 | - ) |
|
259 | - ); |
|
260 | - if ($this->_debug_mode) { |
|
261 | - $txn_id = $response->invoice_number; |
|
262 | - } else { |
|
263 | - $txn_id = $response->transaction_id; |
|
264 | - } |
|
265 | - $payment->set_txn_id_chq_nmbr($txn_id); |
|
266 | - } |
|
267 | - $payment->set_extra_accntng($primary_registrant->reg_code()); |
|
268 | - $payment->set_details(print_r($response, true)); |
|
269 | - } else { |
|
270 | - $payment->set_status($this->_pay_model->failed_status()); |
|
271 | - $payment->set_gateway_response(esc_html__("There was no response from Authorize.net", 'event_espresso')); |
|
272 | - $payment->set_details(print_r($response, true)); |
|
273 | - } |
|
274 | - return $payment; |
|
275 | - } |
|
276 | - |
|
277 | - |
|
278 | - /** |
|
279 | - * Sets billing data for the upcoming request to AIM that is considered sensitive; |
|
280 | - * also this method can be overridden by children classes to easily change |
|
281 | - * what billing data gets sent |
|
282 | - * |
|
283 | - * @param array $billing_info |
|
284 | - */ |
|
285 | - protected function _set_sensitive_billing_data($billing_info) |
|
286 | - { |
|
287 | - $this->setField('card_num', $billing_info['credit_card']); |
|
288 | - $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']); |
|
289 | - $this->setField('card_code', $billing_info['cvv']); |
|
290 | - } |
|
291 | - |
|
292 | - |
|
293 | - /** |
|
294 | - * Add a line item. |
|
295 | - * |
|
296 | - * @param string $item_id |
|
297 | - * @param string $item_name |
|
298 | - * @param string $item_description |
|
299 | - * @param string $item_quantity |
|
300 | - * @param string $item_unit_price |
|
301 | - * @param string $item_taxable |
|
302 | - */ |
|
303 | - public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable) |
|
304 | - { |
|
305 | - $args = array( |
|
306 | - substr($item_id, 0, 31), |
|
307 | - substr($this->prepareStringForAuthnet($item_name), 0, 31), |
|
308 | - substr($this->prepareStringForAuthnet($item_description), 0, 255), |
|
309 | - number_format(abs($item_quantity), 2, '.', ''), |
|
310 | - number_format(abs($item_unit_price), 2, '.', ''), |
|
311 | - $item_taxable === 'N' ? 'N' : 'Y' |
|
312 | - ); |
|
313 | - $this->_additional_line_items[] = implode('<|>', $args); |
|
314 | - } |
|
315 | - |
|
316 | - |
|
317 | - /** |
|
318 | - * Set an individual name/value pair. This will append x_ to the name |
|
319 | - * before posting. |
|
320 | - * |
|
321 | - * @param string $name |
|
322 | - * @param string $value |
|
323 | - * @throws AuthorizeNetException |
|
324 | - */ |
|
325 | - protected function setField($name, $value) |
|
326 | - { |
|
327 | - if (in_array($name, $this->_all_aim_fields)) { |
|
328 | - $this->_x_post_fields[ $name ] = $value; |
|
329 | - } else { |
|
330 | - throw new AuthorizeNetException("Error: no field $name exists in the AIM API. |
|
28 | + const LIVE_URL = 'https://secure2.authorize.net/gateway/transact.dll'; // Authnet URL |
|
29 | + |
|
30 | + const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll'; |
|
31 | + |
|
32 | + protected $_login_id; |
|
33 | + |
|
34 | + protected $_transaction_key; |
|
35 | + |
|
36 | + protected $_currencies_supported = array( |
|
37 | + 'AUD', |
|
38 | + 'USD', |
|
39 | + 'CAD', |
|
40 | + 'EUR', |
|
41 | + 'GBP', |
|
42 | + 'NZD', |
|
43 | + ); |
|
44 | + |
|
45 | + /** |
|
46 | + * Whether to send test transactions (even to live site) |
|
47 | + * |
|
48 | + * @var boolean |
|
49 | + */ |
|
50 | + protected $_test_transactions; |
|
51 | + |
|
52 | + private $VERIFY_PEER = false; |
|
53 | + |
|
54 | + private $_x_post_fields = array( |
|
55 | + "version" => "3.1", |
|
56 | + "delim_char" => ",", |
|
57 | + "delim_data" => "TRUE", |
|
58 | + "relay_response" => "FALSE", |
|
59 | + "encap_char" => "|", |
|
60 | + ); |
|
61 | + |
|
62 | + private $_additional_line_items = array(); |
|
63 | + |
|
64 | + /** |
|
65 | + * A list of all fields in the AIM API. |
|
66 | + * Used to warn user if they try to set a field not offered in the API. |
|
67 | + */ |
|
68 | + private $_all_aim_fields = array( |
|
69 | + "address", |
|
70 | + "allow_partial_auth", |
|
71 | + "amount", |
|
72 | + "auth_code", |
|
73 | + "authentication_indicator", |
|
74 | + "bank_aba_code", |
|
75 | + "bank_acct_name", |
|
76 | + "bank_acct_num", |
|
77 | + "bank_acct_type", |
|
78 | + "bank_check_number", |
|
79 | + "bank_name", |
|
80 | + "card_code", |
|
81 | + "card_num", |
|
82 | + "cardholder_authentication_value", |
|
83 | + "city", |
|
84 | + "company", |
|
85 | + "country", |
|
86 | + "cust_id", |
|
87 | + "customer_ip", |
|
88 | + "delim_char", |
|
89 | + "delim_data", |
|
90 | + "description", |
|
91 | + "duplicate_window", |
|
92 | + "duty", |
|
93 | + "echeck_type", |
|
94 | + "email", |
|
95 | + "email_customer", |
|
96 | + "encap_char", |
|
97 | + "exp_date", |
|
98 | + "fax", |
|
99 | + "first_name", |
|
100 | + "footer_email_receipt", |
|
101 | + "freight", |
|
102 | + "header_email_receipt", |
|
103 | + "invoice_num", |
|
104 | + "last_name", |
|
105 | + "line_item", |
|
106 | + "login", |
|
107 | + "method", |
|
108 | + "phone", |
|
109 | + "po_num", |
|
110 | + "recurring_billing", |
|
111 | + "relay_response", |
|
112 | + "ship_to_address", |
|
113 | + "ship_to_city", |
|
114 | + "ship_to_company", |
|
115 | + "ship_to_country", |
|
116 | + "ship_to_first_name", |
|
117 | + "ship_to_last_name", |
|
118 | + "ship_to_state", |
|
119 | + "ship_to_zip", |
|
120 | + "split_tender_id", |
|
121 | + "state", |
|
122 | + "tax", |
|
123 | + "tax_exempt", |
|
124 | + "test_request", |
|
125 | + "tran_key", |
|
126 | + "trans_id", |
|
127 | + "type", |
|
128 | + "version", |
|
129 | + "zip", |
|
130 | + "solution_id", |
|
131 | + "currency_code" |
|
132 | + ); |
|
133 | + |
|
134 | + |
|
135 | + /** |
|
136 | + * Gets the URL where the request should go. This is filterable |
|
137 | + * |
|
138 | + * @return string |
|
139 | + */ |
|
140 | + protected function _get_server_url() |
|
141 | + { |
|
142 | + return apply_filters( |
|
143 | + 'FHEE__EEG_Aim___get_server_url', |
|
144 | + $this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL, |
|
145 | + $this |
|
146 | + ); |
|
147 | + } |
|
148 | + |
|
149 | + |
|
150 | + /** |
|
151 | + * Asks the gateway to do whatever it does to process the payment. Onsite gateways will |
|
152 | + * usually send a request directly to the payment provider and update the payment's status based on that; |
|
153 | + * whereas offsite gateways will usually just update the payment with the URL and query parameters to use |
|
154 | + * for sending the request via http_remote_request() |
|
155 | + * |
|
156 | + * @param EEI_Payment $payment |
|
157 | + * @param array $billing_info { |
|
158 | + * @type $credit_card string |
|
159 | + * @type $cvv string |
|
160 | + * @type $exp_month string |
|
161 | + * @type $exp_year string |
|
162 | + * @see parent::do_direct_payment |
|
163 | + * } |
|
164 | + * @return EEI_Payment updated |
|
165 | + */ |
|
166 | + public function do_direct_payment($payment, $billing_info = null) |
|
167 | + { |
|
168 | + // Enable test mode if needed |
|
169 | + // 4007000000027 <-- test successful visa |
|
170 | + // 4222222222222 <-- test failure card number |
|
171 | + |
|
172 | + $item_num = 1; |
|
173 | + $transaction = $payment->transaction(); |
|
174 | + $gateway_formatter = $this->_get_gateway_formatter(); |
|
175 | + $order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment)); |
|
176 | + $primary_registrant = $transaction->primary_registration(); |
|
177 | + // if we're are charging for the full amount, show the normal line items |
|
178 | + // and the itemized total adds up properly |
|
179 | + if ($this->_can_easily_itemize_transaction_for($payment)) { |
|
180 | + $total_line_item = $transaction->total_line_item(); |
|
181 | + foreach ($total_line_item->get_items() as $line_item) { |
|
182 | + if ($line_item->quantity() == 0) { |
|
183 | + continue; |
|
184 | + } |
|
185 | + $this->addLineItem( |
|
186 | + $item_num++, |
|
187 | + $gateway_formatter->formatLineItemName($line_item, $payment), |
|
188 | + $gateway_formatter->formatLineItemDesc($line_item, $payment), |
|
189 | + $line_item->quantity(), |
|
190 | + $line_item->unit_price(), |
|
191 | + 'N' |
|
192 | + ); |
|
193 | + $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', '; |
|
194 | + } |
|
195 | + foreach ($total_line_item->tax_descendants() as $tax_line_item) { |
|
196 | + $this->addLineItem( |
|
197 | + $item_num++, |
|
198 | + $tax_line_item->name(), |
|
199 | + $tax_line_item->desc(), |
|
200 | + 1, |
|
201 | + $tax_line_item->total(), |
|
202 | + 'N' |
|
203 | + ); |
|
204 | + } |
|
205 | + } |
|
206 | + |
|
207 | + // start transaction |
|
208 | + // if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id |
|
209 | + $partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363'; |
|
210 | + $this->setField('solution_id', $partner_id); |
|
211 | + $this->setField('amount', $gateway_formatter->formatCurrency($payment->amount())); |
|
212 | + $this->setField('description', substr(rtrim($order_description, ', '), 0, 255)); |
|
213 | + $this->_set_sensitive_billing_data($billing_info); |
|
214 | + $this->setField('first_name', $billing_info['first_name']); |
|
215 | + $this->setField('last_name', $billing_info['last_name']); |
|
216 | + $this->setField('email', $billing_info['email']); |
|
217 | + $this->setField('company', $billing_info['company']); |
|
218 | + $this->setField('address', $billing_info['address'] . ' ' . $billing_info['address2']); |
|
219 | + $this->setField('city', $billing_info['city']); |
|
220 | + $this->setField('state', $billing_info['state']); |
|
221 | + $this->setField('country', $billing_info['country']); |
|
222 | + $this->setField('zip', $billing_info['zip']); |
|
223 | + $this->setField('fax', $billing_info['fax']); |
|
224 | + $this->setField('cust_id', $primary_registrant->ID()); |
|
225 | + $this->setField('phone', $billing_info['phone']); |
|
226 | + $currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config'); |
|
227 | + $this->setField('currency_code', $currency_config->code); |
|
228 | + // invoice_num would be nice to have it be unique per SPCO page-load, that way if users |
|
229 | + // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page |
|
230 | + // in which case, we need to generate teh invoice num per request right here... |
|
231 | + $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
232 | + // tell AIM that any duplicates sent in the next 5 minutes are to be ignored |
|
233 | + $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS); |
|
234 | + |
|
235 | + if ($this->_test_transactions) { |
|
236 | + $this->test_request = "true"; |
|
237 | + } |
|
238 | + |
|
239 | + // Capture response |
|
240 | + $this->type = "AUTH_CAPTURE"; |
|
241 | + $response = $this->_sendRequest($payment); |
|
242 | + if (! empty($response)) { |
|
243 | + if ($response->error_message) { |
|
244 | + $payment->set_status($this->_pay_model->failed_status()); |
|
245 | + $payment->set_gateway_response($response->error_message); |
|
246 | + } else { |
|
247 | + $payment_status = $response->approved |
|
248 | + ? $this->_pay_model->approved_status() |
|
249 | + : $this->_pay_model->declined_status(); |
|
250 | + $payment->set_status($payment_status); |
|
251 | + // make sure we interpret the AMT as a float, not an international string (where periods are thousand separators) |
|
252 | + $payment->set_amount((float) $response->amount); |
|
253 | + $payment->set_gateway_response( |
|
254 | + sprintf( |
|
255 | + esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'), |
|
256 | + $response->response_reason_text, |
|
257 | + $response->response_reason_code |
|
258 | + ) |
|
259 | + ); |
|
260 | + if ($this->_debug_mode) { |
|
261 | + $txn_id = $response->invoice_number; |
|
262 | + } else { |
|
263 | + $txn_id = $response->transaction_id; |
|
264 | + } |
|
265 | + $payment->set_txn_id_chq_nmbr($txn_id); |
|
266 | + } |
|
267 | + $payment->set_extra_accntng($primary_registrant->reg_code()); |
|
268 | + $payment->set_details(print_r($response, true)); |
|
269 | + } else { |
|
270 | + $payment->set_status($this->_pay_model->failed_status()); |
|
271 | + $payment->set_gateway_response(esc_html__("There was no response from Authorize.net", 'event_espresso')); |
|
272 | + $payment->set_details(print_r($response, true)); |
|
273 | + } |
|
274 | + return $payment; |
|
275 | + } |
|
276 | + |
|
277 | + |
|
278 | + /** |
|
279 | + * Sets billing data for the upcoming request to AIM that is considered sensitive; |
|
280 | + * also this method can be overridden by children classes to easily change |
|
281 | + * what billing data gets sent |
|
282 | + * |
|
283 | + * @param array $billing_info |
|
284 | + */ |
|
285 | + protected function _set_sensitive_billing_data($billing_info) |
|
286 | + { |
|
287 | + $this->setField('card_num', $billing_info['credit_card']); |
|
288 | + $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']); |
|
289 | + $this->setField('card_code', $billing_info['cvv']); |
|
290 | + } |
|
291 | + |
|
292 | + |
|
293 | + /** |
|
294 | + * Add a line item. |
|
295 | + * |
|
296 | + * @param string $item_id |
|
297 | + * @param string $item_name |
|
298 | + * @param string $item_description |
|
299 | + * @param string $item_quantity |
|
300 | + * @param string $item_unit_price |
|
301 | + * @param string $item_taxable |
|
302 | + */ |
|
303 | + public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable) |
|
304 | + { |
|
305 | + $args = array( |
|
306 | + substr($item_id, 0, 31), |
|
307 | + substr($this->prepareStringForAuthnet($item_name), 0, 31), |
|
308 | + substr($this->prepareStringForAuthnet($item_description), 0, 255), |
|
309 | + number_format(abs($item_quantity), 2, '.', ''), |
|
310 | + number_format(abs($item_unit_price), 2, '.', ''), |
|
311 | + $item_taxable === 'N' ? 'N' : 'Y' |
|
312 | + ); |
|
313 | + $this->_additional_line_items[] = implode('<|>', $args); |
|
314 | + } |
|
315 | + |
|
316 | + |
|
317 | + /** |
|
318 | + * Set an individual name/value pair. This will append x_ to the name |
|
319 | + * before posting. |
|
320 | + * |
|
321 | + * @param string $name |
|
322 | + * @param string $value |
|
323 | + * @throws AuthorizeNetException |
|
324 | + */ |
|
325 | + protected function setField($name, $value) |
|
326 | + { |
|
327 | + if (in_array($name, $this->_all_aim_fields)) { |
|
328 | + $this->_x_post_fields[ $name ] = $value; |
|
329 | + } else { |
|
330 | + throw new AuthorizeNetException("Error: no field $name exists in the AIM API. |
|
331 | 331 | To set a custom field use setCustomField('field','value') instead."); |
332 | - } |
|
333 | - } |
|
334 | - |
|
335 | - |
|
336 | - /** |
|
337 | - * Posts the request to AuthorizeNet & returns response. |
|
338 | - * |
|
339 | - * @param $payment |
|
340 | - * @return \EE_AuthorizeNetAIM_Response |
|
341 | - */ |
|
342 | - private function _sendRequest($payment) |
|
343 | - { |
|
344 | - $this->_x_post_fields['login'] = $this->_login_id; |
|
345 | - $this->_x_post_fields['tran_key'] = $this->_transaction_key; |
|
346 | - $x_keys = array(); |
|
347 | - foreach ($this->_x_post_fields as $key => $value) { |
|
348 | - $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
349 | - } |
|
350 | - // Add line items |
|
351 | - foreach ($this->_additional_line_items as $key => $value) { |
|
352 | - $x_keys[] = "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
353 | - } |
|
354 | - $this->_log_clean_request($x_keys, $payment); |
|
355 | - $post_url = $this->_get_server_url(); |
|
356 | - $curl_request = curl_init($post_url); |
|
357 | - $post_body = implode("&", $x_keys); |
|
358 | - curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body); |
|
359 | - curl_setopt($curl_request, CURLOPT_HEADER, 0); |
|
360 | - curl_setopt($curl_request, CURLOPT_TIMEOUT, 45); |
|
361 | - curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); |
|
362 | - curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2); |
|
363 | - if ($this->VERIFY_PEER) { |
|
364 | - curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem'); |
|
365 | - } else { |
|
366 | - curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false); |
|
367 | - } |
|
368 | - |
|
369 | - if (preg_match('/xml/', $post_url)) { |
|
370 | - curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); |
|
371 | - } |
|
372 | - |
|
373 | - $response = curl_exec($curl_request); |
|
374 | - |
|
375 | - curl_close($curl_request); |
|
376 | - $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
377 | - |
|
378 | - return $this->_log_and_clean_response($response_obj, $payment); |
|
379 | - } |
|
380 | - |
|
381 | - |
|
382 | - /** |
|
383 | - * Logs the clean data only |
|
384 | - * |
|
385 | - * @param array $request_array |
|
386 | - * @param EEI_Payment $payment |
|
387 | - */ |
|
388 | - protected function _log_clean_request($request_array, $payment) |
|
389 | - { |
|
390 | - $keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date'); |
|
391 | - foreach ($request_array as $index => $keyvaltogether) { |
|
392 | - foreach ($keys_to_filter_out as $key) { |
|
393 | - if (strpos($keyvaltogether, $key) === 0) { |
|
394 | - // found it at the first character |
|
395 | - // so its one of them |
|
396 | - unset($request_array[ $index ]); |
|
397 | - } |
|
398 | - } |
|
399 | - } |
|
400 | - $this->log( |
|
401 | - array( |
|
402 | - 'AIM Request sent:' => $request_array, |
|
403 | - 'Server URL' => $this->_get_server_url() |
|
404 | - ), |
|
405 | - $payment |
|
406 | - ); |
|
407 | - } |
|
408 | - |
|
409 | - |
|
410 | - |
|
411 | - /** |
|
412 | - * Logs the response and cleans it |
|
413 | - * |
|
414 | - * @param EE_AuthorizeNetAIM_Response $response_obj |
|
415 | - * @param EE_Payment $payment |
|
416 | - * @return \EE_AuthorizeNetAIM_Response |
|
417 | - */ |
|
418 | - private function _log_and_clean_response($response_obj, $payment) |
|
419 | - { |
|
420 | - $response_obj->account_number = ''; |
|
421 | - $this->log(array('AIM Response received:' => (array) $response_obj), $payment); |
|
422 | - return $response_obj; |
|
423 | - } |
|
424 | - |
|
425 | - /** |
|
426 | - * Removes characters Authorize.net doesn't handle well. |
|
427 | - * @since 4.9.82.p |
|
428 | - * @param $text |
|
429 | - * @return string |
|
430 | - */ |
|
431 | - private function prepareStringForAuthnet($text) |
|
432 | - { |
|
433 | - return str_replace( |
|
434 | - '\'', |
|
435 | - '', |
|
436 | - $text |
|
437 | - ); |
|
438 | - } |
|
332 | + } |
|
333 | + } |
|
334 | + |
|
335 | + |
|
336 | + /** |
|
337 | + * Posts the request to AuthorizeNet & returns response. |
|
338 | + * |
|
339 | + * @param $payment |
|
340 | + * @return \EE_AuthorizeNetAIM_Response |
|
341 | + */ |
|
342 | + private function _sendRequest($payment) |
|
343 | + { |
|
344 | + $this->_x_post_fields['login'] = $this->_login_id; |
|
345 | + $this->_x_post_fields['tran_key'] = $this->_transaction_key; |
|
346 | + $x_keys = array(); |
|
347 | + foreach ($this->_x_post_fields as $key => $value) { |
|
348 | + $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
349 | + } |
|
350 | + // Add line items |
|
351 | + foreach ($this->_additional_line_items as $key => $value) { |
|
352 | + $x_keys[] = "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
353 | + } |
|
354 | + $this->_log_clean_request($x_keys, $payment); |
|
355 | + $post_url = $this->_get_server_url(); |
|
356 | + $curl_request = curl_init($post_url); |
|
357 | + $post_body = implode("&", $x_keys); |
|
358 | + curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body); |
|
359 | + curl_setopt($curl_request, CURLOPT_HEADER, 0); |
|
360 | + curl_setopt($curl_request, CURLOPT_TIMEOUT, 45); |
|
361 | + curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); |
|
362 | + curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2); |
|
363 | + if ($this->VERIFY_PEER) { |
|
364 | + curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem'); |
|
365 | + } else { |
|
366 | + curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false); |
|
367 | + } |
|
368 | + |
|
369 | + if (preg_match('/xml/', $post_url)) { |
|
370 | + curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); |
|
371 | + } |
|
372 | + |
|
373 | + $response = curl_exec($curl_request); |
|
374 | + |
|
375 | + curl_close($curl_request); |
|
376 | + $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
377 | + |
|
378 | + return $this->_log_and_clean_response($response_obj, $payment); |
|
379 | + } |
|
380 | + |
|
381 | + |
|
382 | + /** |
|
383 | + * Logs the clean data only |
|
384 | + * |
|
385 | + * @param array $request_array |
|
386 | + * @param EEI_Payment $payment |
|
387 | + */ |
|
388 | + protected function _log_clean_request($request_array, $payment) |
|
389 | + { |
|
390 | + $keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date'); |
|
391 | + foreach ($request_array as $index => $keyvaltogether) { |
|
392 | + foreach ($keys_to_filter_out as $key) { |
|
393 | + if (strpos($keyvaltogether, $key) === 0) { |
|
394 | + // found it at the first character |
|
395 | + // so its one of them |
|
396 | + unset($request_array[ $index ]); |
|
397 | + } |
|
398 | + } |
|
399 | + } |
|
400 | + $this->log( |
|
401 | + array( |
|
402 | + 'AIM Request sent:' => $request_array, |
|
403 | + 'Server URL' => $this->_get_server_url() |
|
404 | + ), |
|
405 | + $payment |
|
406 | + ); |
|
407 | + } |
|
408 | + |
|
409 | + |
|
410 | + |
|
411 | + /** |
|
412 | + * Logs the response and cleans it |
|
413 | + * |
|
414 | + * @param EE_AuthorizeNetAIM_Response $response_obj |
|
415 | + * @param EE_Payment $payment |
|
416 | + * @return \EE_AuthorizeNetAIM_Response |
|
417 | + */ |
|
418 | + private function _log_and_clean_response($response_obj, $payment) |
|
419 | + { |
|
420 | + $response_obj->account_number = ''; |
|
421 | + $this->log(array('AIM Response received:' => (array) $response_obj), $payment); |
|
422 | + return $response_obj; |
|
423 | + } |
|
424 | + |
|
425 | + /** |
|
426 | + * Removes characters Authorize.net doesn't handle well. |
|
427 | + * @since 4.9.82.p |
|
428 | + * @param $text |
|
429 | + * @return string |
|
430 | + */ |
|
431 | + private function prepareStringForAuthnet($text) |
|
432 | + { |
|
433 | + return str_replace( |
|
434 | + '\'', |
|
435 | + '', |
|
436 | + $text |
|
437 | + ); |
|
438 | + } |
|
439 | 439 | } |
440 | 440 | |
441 | 441 | |
@@ -450,191 +450,191 @@ discard block |
||
450 | 450 | */ |
451 | 451 | class EE_AuthorizeNetAIM_Response |
452 | 452 | { |
453 | - const APPROVED = '1'; |
|
454 | - const DECLINED = '2'; |
|
455 | - const ERROR = '3'; |
|
456 | - const HELD = '4'; |
|
457 | - |
|
458 | - protected $_x_post_fields = array( |
|
459 | - "version" => "3.1", |
|
460 | - "delim_char" => ",", |
|
461 | - "delim_data" => "TRUE", |
|
462 | - "relay_response" => "FALSE", |
|
463 | - "encap_char" => "|", |
|
464 | - ); |
|
465 | - public $approved; |
|
466 | - public $declined; |
|
467 | - public $error; |
|
468 | - public $held; |
|
469 | - public $response_code; |
|
470 | - public $response_subcode; |
|
471 | - public $response_reason_code; |
|
472 | - public $response_reason_text; |
|
473 | - public $authorization_code; |
|
474 | - public $avs_response; |
|
475 | - public $transaction_id; |
|
476 | - public $invoice_number; |
|
477 | - public $description; |
|
478 | - public $amount; |
|
479 | - public $method; |
|
480 | - public $transaction_type; |
|
481 | - public $customer_id; |
|
482 | - public $first_name; |
|
483 | - public $last_name; |
|
484 | - public $company; |
|
485 | - public $address; |
|
486 | - public $city; |
|
487 | - public $state; |
|
488 | - public $zip_code; |
|
489 | - public $country; |
|
490 | - public $phone; |
|
491 | - public $fax; |
|
492 | - public $email_address; |
|
493 | - public $ship_to_first_name; |
|
494 | - public $ship_to_last_name; |
|
495 | - public $ship_to_company; |
|
496 | - public $ship_to_address; |
|
497 | - public $ship_to_city; |
|
498 | - public $ship_to_state; |
|
499 | - public $ship_to_zip_code; |
|
500 | - public $ship_to_country; |
|
501 | - public $tax; |
|
502 | - public $duty; |
|
503 | - public $freight; |
|
504 | - public $tax_exempt; |
|
505 | - public $purchase_order_number; |
|
506 | - public $md5_hash; |
|
507 | - public $card_code_response; |
|
508 | - public $cavv_response; // cardholder_authentication_verification_response |
|
509 | - public $account_number; |
|
510 | - public $card_type; |
|
511 | - public $split_tender_id; |
|
512 | - public $requested_amount; |
|
513 | - public $balance_on_card; |
|
514 | - public $response; // The response string from AuthorizeNet. |
|
515 | - public $error_message; |
|
516 | - private $_response_array = array(); // An array with the split response. |
|
517 | - |
|
518 | - |
|
519 | - /** |
|
520 | - * Constructor. Parses the AuthorizeNet response string |
|
521 | - * |
|
522 | - * @param string $response The response from the AuthNet server. |
|
523 | - * @var string $delimiter The delimiter used (default is ",") |
|
524 | - * @var string $encap_char The encap_char used (default is "|") |
|
525 | - * @var array $custom_fields Any custom fields set in the request. |
|
526 | - */ |
|
527 | - |
|
528 | - public function __construct($response) |
|
529 | - { |
|
530 | - $encap_char = $this->_x_post_fields['encap_char']; |
|
531 | - $delimiter = $this->_x_post_fields['delim_char']; |
|
532 | - if ($response) { |
|
533 | - // Split Array |
|
534 | - $this->response = $response; |
|
535 | - if ($encap_char) { |
|
536 | - $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1)); |
|
537 | - } else { |
|
538 | - $this->_response_array = explode($delimiter, $response); |
|
539 | - } |
|
540 | - |
|
541 | - /** |
|
542 | - * If AuthorizeNet doesn't return a delimited response. |
|
543 | - */ |
|
544 | - if (count($this->_response_array) < 10) { |
|
545 | - $this->approved = false; |
|
546 | - $this->error = true; |
|
547 | - $this->error_message = sprintf( |
|
548 | - esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'), |
|
549 | - esc_html($response) |
|
550 | - ); |
|
551 | - return; |
|
552 | - } |
|
553 | - |
|
554 | - |
|
555 | - |
|
556 | - // Set all fields |
|
557 | - $this->response_code = $this->_response_array[0]; |
|
558 | - $this->response_subcode = $this->_response_array[1]; |
|
559 | - $this->response_reason_code = $this->_response_array[2]; |
|
560 | - $this->response_reason_text = $this->_response_array[3]; |
|
561 | - $this->authorization_code = $this->_response_array[4]; |
|
562 | - $this->avs_response = $this->_response_array[5]; |
|
563 | - $this->transaction_id = $this->_response_array[6]; |
|
564 | - $this->invoice_number = $this->_response_array[7]; |
|
565 | - $this->description = $this->_response_array[8]; |
|
566 | - $this->amount = $this->_response_array[9]; |
|
567 | - $this->method = $this->_response_array[10]; |
|
568 | - $this->transaction_type = $this->_response_array[11]; |
|
569 | - $this->customer_id = $this->_response_array[12]; |
|
570 | - $this->first_name = $this->_response_array[13]; |
|
571 | - $this->last_name = $this->_response_array[14]; |
|
572 | - $this->company = $this->_response_array[15]; |
|
573 | - $this->address = $this->_response_array[16]; |
|
574 | - $this->city = $this->_response_array[17]; |
|
575 | - $this->state = $this->_response_array[18]; |
|
576 | - $this->zip_code = $this->_response_array[19]; |
|
577 | - $this->country = $this->_response_array[20]; |
|
578 | - $this->phone = $this->_response_array[21]; |
|
579 | - $this->fax = $this->_response_array[22]; |
|
580 | - $this->email_address = $this->_response_array[23]; |
|
581 | - $this->ship_to_first_name = $this->_response_array[24]; |
|
582 | - $this->ship_to_last_name = $this->_response_array[25]; |
|
583 | - $this->ship_to_company = $this->_response_array[26]; |
|
584 | - $this->ship_to_address = $this->_response_array[27]; |
|
585 | - $this->ship_to_city = $this->_response_array[28]; |
|
586 | - $this->ship_to_state = $this->_response_array[29]; |
|
587 | - $this->ship_to_zip_code = $this->_response_array[30]; |
|
588 | - $this->ship_to_country = $this->_response_array[31]; |
|
589 | - $this->tax = $this->_response_array[32]; |
|
590 | - $this->duty = $this->_response_array[33]; |
|
591 | - $this->freight = $this->_response_array[34]; |
|
592 | - $this->tax_exempt = $this->_response_array[35]; |
|
593 | - $this->purchase_order_number = $this->_response_array[36]; |
|
594 | - $this->md5_hash = $this->_response_array[37]; |
|
595 | - $this->card_code_response = $this->_response_array[38]; |
|
596 | - $this->cavv_response = $this->_response_array[39]; |
|
597 | - $this->account_number = $this->_response_array[50]; |
|
598 | - $this->card_type = $this->_response_array[51]; |
|
599 | - $this->split_tender_id = $this->_response_array[52]; |
|
600 | - $this->requested_amount = $this->_response_array[53]; |
|
601 | - $this->balance_on_card = $this->_response_array[54]; |
|
602 | - |
|
603 | - $this->approved = ($this->response_code === self::APPROVED); |
|
604 | - $this->declined = ($this->response_code === self::DECLINED); |
|
605 | - $this->error = ($this->response_code === self::ERROR); |
|
606 | - $this->held = ($this->response_code === self::HELD); |
|
607 | - } else { |
|
608 | - $this->approved = false; |
|
609 | - $this->error = true; |
|
610 | - $this->error_message = esc_html__( |
|
611 | - 'Error connecting to Authorize.net', |
|
612 | - 'event_espresso' |
|
613 | - ); |
|
614 | - } |
|
615 | - } |
|
453 | + const APPROVED = '1'; |
|
454 | + const DECLINED = '2'; |
|
455 | + const ERROR = '3'; |
|
456 | + const HELD = '4'; |
|
457 | + |
|
458 | + protected $_x_post_fields = array( |
|
459 | + "version" => "3.1", |
|
460 | + "delim_char" => ",", |
|
461 | + "delim_data" => "TRUE", |
|
462 | + "relay_response" => "FALSE", |
|
463 | + "encap_char" => "|", |
|
464 | + ); |
|
465 | + public $approved; |
|
466 | + public $declined; |
|
467 | + public $error; |
|
468 | + public $held; |
|
469 | + public $response_code; |
|
470 | + public $response_subcode; |
|
471 | + public $response_reason_code; |
|
472 | + public $response_reason_text; |
|
473 | + public $authorization_code; |
|
474 | + public $avs_response; |
|
475 | + public $transaction_id; |
|
476 | + public $invoice_number; |
|
477 | + public $description; |
|
478 | + public $amount; |
|
479 | + public $method; |
|
480 | + public $transaction_type; |
|
481 | + public $customer_id; |
|
482 | + public $first_name; |
|
483 | + public $last_name; |
|
484 | + public $company; |
|
485 | + public $address; |
|
486 | + public $city; |
|
487 | + public $state; |
|
488 | + public $zip_code; |
|
489 | + public $country; |
|
490 | + public $phone; |
|
491 | + public $fax; |
|
492 | + public $email_address; |
|
493 | + public $ship_to_first_name; |
|
494 | + public $ship_to_last_name; |
|
495 | + public $ship_to_company; |
|
496 | + public $ship_to_address; |
|
497 | + public $ship_to_city; |
|
498 | + public $ship_to_state; |
|
499 | + public $ship_to_zip_code; |
|
500 | + public $ship_to_country; |
|
501 | + public $tax; |
|
502 | + public $duty; |
|
503 | + public $freight; |
|
504 | + public $tax_exempt; |
|
505 | + public $purchase_order_number; |
|
506 | + public $md5_hash; |
|
507 | + public $card_code_response; |
|
508 | + public $cavv_response; // cardholder_authentication_verification_response |
|
509 | + public $account_number; |
|
510 | + public $card_type; |
|
511 | + public $split_tender_id; |
|
512 | + public $requested_amount; |
|
513 | + public $balance_on_card; |
|
514 | + public $response; // The response string from AuthorizeNet. |
|
515 | + public $error_message; |
|
516 | + private $_response_array = array(); // An array with the split response. |
|
517 | + |
|
518 | + |
|
519 | + /** |
|
520 | + * Constructor. Parses the AuthorizeNet response string |
|
521 | + * |
|
522 | + * @param string $response The response from the AuthNet server. |
|
523 | + * @var string $delimiter The delimiter used (default is ",") |
|
524 | + * @var string $encap_char The encap_char used (default is "|") |
|
525 | + * @var array $custom_fields Any custom fields set in the request. |
|
526 | + */ |
|
527 | + |
|
528 | + public function __construct($response) |
|
529 | + { |
|
530 | + $encap_char = $this->_x_post_fields['encap_char']; |
|
531 | + $delimiter = $this->_x_post_fields['delim_char']; |
|
532 | + if ($response) { |
|
533 | + // Split Array |
|
534 | + $this->response = $response; |
|
535 | + if ($encap_char) { |
|
536 | + $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1)); |
|
537 | + } else { |
|
538 | + $this->_response_array = explode($delimiter, $response); |
|
539 | + } |
|
540 | + |
|
541 | + /** |
|
542 | + * If AuthorizeNet doesn't return a delimited response. |
|
543 | + */ |
|
544 | + if (count($this->_response_array) < 10) { |
|
545 | + $this->approved = false; |
|
546 | + $this->error = true; |
|
547 | + $this->error_message = sprintf( |
|
548 | + esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'), |
|
549 | + esc_html($response) |
|
550 | + ); |
|
551 | + return; |
|
552 | + } |
|
553 | + |
|
554 | + |
|
555 | + |
|
556 | + // Set all fields |
|
557 | + $this->response_code = $this->_response_array[0]; |
|
558 | + $this->response_subcode = $this->_response_array[1]; |
|
559 | + $this->response_reason_code = $this->_response_array[2]; |
|
560 | + $this->response_reason_text = $this->_response_array[3]; |
|
561 | + $this->authorization_code = $this->_response_array[4]; |
|
562 | + $this->avs_response = $this->_response_array[5]; |
|
563 | + $this->transaction_id = $this->_response_array[6]; |
|
564 | + $this->invoice_number = $this->_response_array[7]; |
|
565 | + $this->description = $this->_response_array[8]; |
|
566 | + $this->amount = $this->_response_array[9]; |
|
567 | + $this->method = $this->_response_array[10]; |
|
568 | + $this->transaction_type = $this->_response_array[11]; |
|
569 | + $this->customer_id = $this->_response_array[12]; |
|
570 | + $this->first_name = $this->_response_array[13]; |
|
571 | + $this->last_name = $this->_response_array[14]; |
|
572 | + $this->company = $this->_response_array[15]; |
|
573 | + $this->address = $this->_response_array[16]; |
|
574 | + $this->city = $this->_response_array[17]; |
|
575 | + $this->state = $this->_response_array[18]; |
|
576 | + $this->zip_code = $this->_response_array[19]; |
|
577 | + $this->country = $this->_response_array[20]; |
|
578 | + $this->phone = $this->_response_array[21]; |
|
579 | + $this->fax = $this->_response_array[22]; |
|
580 | + $this->email_address = $this->_response_array[23]; |
|
581 | + $this->ship_to_first_name = $this->_response_array[24]; |
|
582 | + $this->ship_to_last_name = $this->_response_array[25]; |
|
583 | + $this->ship_to_company = $this->_response_array[26]; |
|
584 | + $this->ship_to_address = $this->_response_array[27]; |
|
585 | + $this->ship_to_city = $this->_response_array[28]; |
|
586 | + $this->ship_to_state = $this->_response_array[29]; |
|
587 | + $this->ship_to_zip_code = $this->_response_array[30]; |
|
588 | + $this->ship_to_country = $this->_response_array[31]; |
|
589 | + $this->tax = $this->_response_array[32]; |
|
590 | + $this->duty = $this->_response_array[33]; |
|
591 | + $this->freight = $this->_response_array[34]; |
|
592 | + $this->tax_exempt = $this->_response_array[35]; |
|
593 | + $this->purchase_order_number = $this->_response_array[36]; |
|
594 | + $this->md5_hash = $this->_response_array[37]; |
|
595 | + $this->card_code_response = $this->_response_array[38]; |
|
596 | + $this->cavv_response = $this->_response_array[39]; |
|
597 | + $this->account_number = $this->_response_array[50]; |
|
598 | + $this->card_type = $this->_response_array[51]; |
|
599 | + $this->split_tender_id = $this->_response_array[52]; |
|
600 | + $this->requested_amount = $this->_response_array[53]; |
|
601 | + $this->balance_on_card = $this->_response_array[54]; |
|
602 | + |
|
603 | + $this->approved = ($this->response_code === self::APPROVED); |
|
604 | + $this->declined = ($this->response_code === self::DECLINED); |
|
605 | + $this->error = ($this->response_code === self::ERROR); |
|
606 | + $this->held = ($this->response_code === self::HELD); |
|
607 | + } else { |
|
608 | + $this->approved = false; |
|
609 | + $this->error = true; |
|
610 | + $this->error_message = esc_html__( |
|
611 | + 'Error connecting to Authorize.net', |
|
612 | + 'event_espresso' |
|
613 | + ); |
|
614 | + } |
|
615 | + } |
|
616 | 616 | } |
617 | 617 | |
618 | 618 | if (! class_exists('AuthorizeNetException')) { |
619 | - /** |
|
620 | - * Class AuthorizeNetException |
|
621 | - * |
|
622 | - * @package AuthorizeNet |
|
623 | - */ |
|
624 | - class AuthorizeNetException extends Exception |
|
625 | - { |
|
626 | - /** |
|
627 | - * Construct the exception. Note: The message is NOT binary safe. |
|
628 | - * |
|
629 | - * @link http://php.net/manual/en/exception.construct.php |
|
630 | - * @param string $message [optional] The Exception message to throw. |
|
631 | - * @param int $code [optional] The Exception code. |
|
632 | - * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0 |
|
633 | - * @since 5.1.0 |
|
634 | - */ |
|
635 | - public function __construct($message = "", $code = 0, Exception $previous = null) |
|
636 | - { |
|
637 | - parent::__construct($message, $code, $previous); |
|
638 | - } |
|
639 | - } |
|
619 | + /** |
|
620 | + * Class AuthorizeNetException |
|
621 | + * |
|
622 | + * @package AuthorizeNet |
|
623 | + */ |
|
624 | + class AuthorizeNetException extends Exception |
|
625 | + { |
|
626 | + /** |
|
627 | + * Construct the exception. Note: The message is NOT binary safe. |
|
628 | + * |
|
629 | + * @link http://php.net/manual/en/exception.construct.php |
|
630 | + * @param string $message [optional] The Exception message to throw. |
|
631 | + * @param int $code [optional] The Exception code. |
|
632 | + * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0 |
|
633 | + * @since 5.1.0 |
|
634 | + */ |
|
635 | + public function __construct($message = "", $code = 0, Exception $previous = null) |
|
636 | + { |
|
637 | + parent::__construct($message, $code, $previous); |
|
638 | + } |
|
639 | + } |
|
640 | 640 | } |
@@ -1,10 +1,10 @@ |
||
1 | 1 | <?php |
2 | 2 | |
3 | 3 | printf( |
4 | - esc_html__( |
|
5 | - 'Authorize.Net AIM is an on-site payment method for accepting credit and debit card payments and is available to event organizers in the United States, Canada, United Kingdom, and Australia. An account with Authorize.Net is required to accept payments. Need an Authorize.Net account? %1$sClick here to sign up for a merchant account%2$s.', |
|
6 | - 'event_espresso' |
|
7 | - ), |
|
8 | - '<a href="https://eventespresso.com/go/authorizenetaim/" target="_blank">', |
|
9 | - '</a>' |
|
4 | + esc_html__( |
|
5 | + 'Authorize.Net AIM is an on-site payment method for accepting credit and debit card payments and is available to event organizers in the United States, Canada, United Kingdom, and Australia. An account with Authorize.Net is required to accept payments. Need an Authorize.Net account? %1$sClick here to sign up for a merchant account%2$s.', |
|
6 | + 'event_espresso' |
|
7 | + ), |
|
8 | + '<a href="https://eventespresso.com/go/authorizenetaim/" target="_blank">', |
|
9 | + '</a>' |
|
10 | 10 | ); |
@@ -7,33 +7,33 @@ |
||
7 | 7 | */ |
8 | 8 | |
9 | 9 | spl_autoload_register(function ($class) { |
10 | - if (substr($class, 0, 10) !== 'ReCaptcha\\') { |
|
11 | - /* If the class does not lie under the "ReCaptcha" namespace, |
|
10 | + if (substr($class, 0, 10) !== 'ReCaptcha\\') { |
|
11 | + /* If the class does not lie under the "ReCaptcha" namespace, |
|
12 | 12 | * then we can exit immediately. |
13 | 13 | */ |
14 | - return; |
|
15 | - } |
|
14 | + return; |
|
15 | + } |
|
16 | 16 | |
17 | - /* All of the classes have names like "ReCaptcha\Foo", so we need |
|
17 | + /* All of the classes have names like "ReCaptcha\Foo", so we need |
|
18 | 18 | * to replace the backslashes with frontslashes if we want the |
19 | 19 | * name to map directly to a location in the filesystem. |
20 | 20 | */ |
21 | - $class = str_replace('\\', '/', $class); |
|
21 | + $class = str_replace('\\', '/', $class); |
|
22 | 22 | |
23 | - /* First, check under the current directory. It is important that |
|
23 | + /* First, check under the current directory. It is important that |
|
24 | 24 | * we look here first, so that we don't waste time searching for |
25 | 25 | * test classes in the common case. |
26 | 26 | */ |
27 | - $path = dirname(__FILE__) . '/' . $class . '.php'; |
|
28 | - if (is_readable($path)) { |
|
29 | - require_once $path; |
|
30 | - } |
|
27 | + $path = dirname(__FILE__) . '/' . $class . '.php'; |
|
28 | + if (is_readable($path)) { |
|
29 | + require_once $path; |
|
30 | + } |
|
31 | 31 | |
32 | - /* If we didn't find what we're looking for already, maybe it's |
|
32 | + /* If we didn't find what we're looking for already, maybe it's |
|
33 | 33 | * a test class? |
34 | 34 | */ |
35 | - $path = dirname(__FILE__) . '/../tests/' . $class . '.php'; |
|
36 | - if (is_readable($path)) { |
|
37 | - require_once $path; |
|
38 | - } |
|
35 | + $path = dirname(__FILE__) . '/../tests/' . $class . '.php'; |
|
36 | + if (is_readable($path)) { |
|
37 | + require_once $path; |
|
38 | + } |
|
39 | 39 | }); |
@@ -6,7 +6,7 @@ discard block |
||
6 | 6 | * classes. |
7 | 7 | */ |
8 | 8 | |
9 | -spl_autoload_register(function ($class) { |
|
9 | +spl_autoload_register(function($class) { |
|
10 | 10 | if (substr($class, 0, 10) !== 'ReCaptcha\\') { |
11 | 11 | /* If the class does not lie under the "ReCaptcha" namespace, |
12 | 12 | * then we can exit immediately. |
@@ -24,7 +24,7 @@ discard block |
||
24 | 24 | * we look here first, so that we don't waste time searching for |
25 | 25 | * test classes in the common case. |
26 | 26 | */ |
27 | - $path = dirname(__FILE__) . '/' . $class . '.php'; |
|
27 | + $path = dirname(__FILE__).'/'.$class.'.php'; |
|
28 | 28 | if (is_readable($path)) { |
29 | 29 | require_once $path; |
30 | 30 | } |
@@ -32,7 +32,7 @@ discard block |
||
32 | 32 | /* If we didn't find what we're looking for already, maybe it's |
33 | 33 | * a test class? |
34 | 34 | */ |
35 | - $path = dirname(__FILE__) . '/../tests/' . $class . '.php'; |
|
35 | + $path = dirname(__FILE__).'/../tests/'.$class.'.php'; |
|
36 | 36 | if (is_readable($path)) { |
37 | 37 | require_once $path; |
38 | 38 | } |
@@ -52,7 +52,7 @@ discard block |
||
52 | 52 | { |
53 | 53 | define( |
54 | 54 | 'TICKET_SELECTOR_CAFF_TEMPLATES_PATH', |
55 | - str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/' |
|
55 | + str_replace('\\', '/', plugin_dir_path(__FILE__)).'templates/' |
|
56 | 56 | ); |
57 | 57 | add_action( |
58 | 58 | 'AHEE__template_settings__template__before_settings_form', |
@@ -107,7 +107,7 @@ discard block |
||
107 | 107 | 'FHEE__EED_Ticket_Selector_Caff___ticket_selector_settings_form__form_subsections', |
108 | 108 | array( |
109 | 109 | 'appearance_settings_hdr' => new EE_Form_Section_HTML( |
110 | - EEH_HTML::br(2) . |
|
110 | + EEH_HTML::br(2). |
|
111 | 111 | EEH_HTML::h2(esc_html__('Ticket Selector Template Settings', 'event_espresso')) |
112 | 112 | ), |
113 | 113 | 'appearance_settings' => EED_Ticket_Selector_Caff::_ticket_selector_appearance_settings(), |
@@ -273,7 +273,7 @@ discard block |
||
273 | 273 | */ |
274 | 274 | public static function update_template_settings(EE_Template_Config $CFG, $REQ) |
275 | 275 | { |
276 | - if (! $CFG->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config) { |
|
276 | + if ( ! $CFG->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config) { |
|
277 | 277 | EED_Ticket_Selector::instance()->set_config(); |
278 | 278 | $CFG->EED_Ticket_Selector = EED_Ticket_Selector::instance()->config(); |
279 | 279 | } |
@@ -15,319 +15,319 @@ |
||
15 | 15 | */ |
16 | 16 | class EED_Ticket_Selector_Caff extends EED_Ticket_Selector |
17 | 17 | { |
18 | - /** |
|
19 | - * @return EED_Module|EED_Ticket_Selector_Caff |
|
20 | - */ |
|
21 | - public static function instance() |
|
22 | - { |
|
23 | - return parent::get_instance(__CLASS__); |
|
24 | - } |
|
18 | + /** |
|
19 | + * @return EED_Module|EED_Ticket_Selector_Caff |
|
20 | + */ |
|
21 | + public static function instance() |
|
22 | + { |
|
23 | + return parent::get_instance(__CLASS__); |
|
24 | + } |
|
25 | 25 | |
26 | 26 | |
27 | - /** |
|
28 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
29 | - * |
|
30 | - * @access public |
|
31 | - * @return void |
|
32 | - */ |
|
33 | - public static function set_hooks() |
|
34 | - { |
|
35 | - add_action( |
|
36 | - 'AHEE__ticket_selector_chart_template__ticket_details__after_description', |
|
37 | - array('EED_Ticket_Selector_Caff', 'ticket_price_details'), |
|
38 | - 10, |
|
39 | - 3 |
|
40 | - ); |
|
41 | - } |
|
27 | + /** |
|
28 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
29 | + * |
|
30 | + * @access public |
|
31 | + * @return void |
|
32 | + */ |
|
33 | + public static function set_hooks() |
|
34 | + { |
|
35 | + add_action( |
|
36 | + 'AHEE__ticket_selector_chart_template__ticket_details__after_description', |
|
37 | + array('EED_Ticket_Selector_Caff', 'ticket_price_details'), |
|
38 | + 10, |
|
39 | + 3 |
|
40 | + ); |
|
41 | + } |
|
42 | 42 | |
43 | - /** |
|
44 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
45 | - * |
|
46 | - * @access public |
|
47 | - * @return void |
|
48 | - */ |
|
49 | - public static function set_hooks_admin() |
|
50 | - { |
|
51 | - define( |
|
52 | - 'TICKET_SELECTOR_CAFF_TEMPLATES_PATH', |
|
53 | - str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/' |
|
54 | - ); |
|
55 | - add_action( |
|
56 | - 'AHEE__template_settings__template__before_settings_form', |
|
57 | - array('EED_Ticket_Selector_Caff', 'template_settings_form'), |
|
58 | - 10 |
|
59 | - ); |
|
60 | - add_filter( |
|
61 | - 'FHEE__General_Settings_Admin_Page__update_template_settings__data', |
|
62 | - array('EED_Ticket_Selector_Caff', 'update_template_settings'), |
|
63 | - 10, |
|
64 | - 2 |
|
65 | - ); |
|
66 | - } |
|
43 | + /** |
|
44 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
45 | + * |
|
46 | + * @access public |
|
47 | + * @return void |
|
48 | + */ |
|
49 | + public static function set_hooks_admin() |
|
50 | + { |
|
51 | + define( |
|
52 | + 'TICKET_SELECTOR_CAFF_TEMPLATES_PATH', |
|
53 | + str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/' |
|
54 | + ); |
|
55 | + add_action( |
|
56 | + 'AHEE__template_settings__template__before_settings_form', |
|
57 | + array('EED_Ticket_Selector_Caff', 'template_settings_form'), |
|
58 | + 10 |
|
59 | + ); |
|
60 | + add_filter( |
|
61 | + 'FHEE__General_Settings_Admin_Page__update_template_settings__data', |
|
62 | + array('EED_Ticket_Selector_Caff', 'update_template_settings'), |
|
63 | + 10, |
|
64 | + 2 |
|
65 | + ); |
|
66 | + } |
|
67 | 67 | |
68 | 68 | |
69 | - /** |
|
70 | - * @param \WP $WP |
|
71 | - */ |
|
72 | - public function run($WP) |
|
73 | - { |
|
74 | - $this->set_config(); |
|
75 | - } |
|
69 | + /** |
|
70 | + * @param \WP $WP |
|
71 | + */ |
|
72 | + public function run($WP) |
|
73 | + { |
|
74 | + $this->set_config(); |
|
75 | + } |
|
76 | 76 | |
77 | 77 | |
78 | - /** |
|
79 | - * @static |
|
80 | - * @return void |
|
81 | - * @throws EE_Error |
|
82 | - * @throws InvalidArgumentException |
|
83 | - * @throws InvalidDataTypeException |
|
84 | - * @throws InvalidInterfaceException |
|
85 | - */ |
|
86 | - public static function template_settings_form() |
|
87 | - { |
|
88 | - echo EED_Ticket_Selector_Caff::_ticket_selector_settings_form()->get_html(); |
|
89 | - } |
|
78 | + /** |
|
79 | + * @static |
|
80 | + * @return void |
|
81 | + * @throws EE_Error |
|
82 | + * @throws InvalidArgumentException |
|
83 | + * @throws InvalidDataTypeException |
|
84 | + * @throws InvalidInterfaceException |
|
85 | + */ |
|
86 | + public static function template_settings_form() |
|
87 | + { |
|
88 | + echo EED_Ticket_Selector_Caff::_ticket_selector_settings_form()->get_html(); |
|
89 | + } |
|
90 | 90 | |
91 | 91 | |
92 | - /** |
|
93 | - * @return \EE_Form_Section_Proper |
|
94 | - * @throws \EE_Error |
|
95 | - */ |
|
96 | - public static function _ticket_selector_settings_form() |
|
97 | - { |
|
92 | + /** |
|
93 | + * @return \EE_Form_Section_Proper |
|
94 | + * @throws \EE_Error |
|
95 | + */ |
|
96 | + public static function _ticket_selector_settings_form() |
|
97 | + { |
|
98 | 98 | |
99 | - return new EE_Form_Section_Proper( |
|
100 | - array( |
|
101 | - 'name' => 'ticket_selector_settings_form', |
|
102 | - 'html_id' => 'ticket_selector_settings_form', |
|
103 | - 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
104 | - 'subsections' => apply_filters( |
|
105 | - 'FHEE__EED_Ticket_Selector_Caff___ticket_selector_settings_form__form_subsections', |
|
106 | - array( |
|
107 | - 'appearance_settings_hdr' => new EE_Form_Section_HTML( |
|
108 | - EEH_HTML::br(2) . |
|
109 | - EEH_HTML::h2(esc_html__('Ticket Selector Template Settings', 'event_espresso')) |
|
110 | - ), |
|
111 | - 'appearance_settings' => EED_Ticket_Selector_Caff::_ticket_selector_appearance_settings(), |
|
112 | - ) |
|
113 | - ), |
|
114 | - ) |
|
115 | - ); |
|
116 | - } |
|
99 | + return new EE_Form_Section_Proper( |
|
100 | + array( |
|
101 | + 'name' => 'ticket_selector_settings_form', |
|
102 | + 'html_id' => 'ticket_selector_settings_form', |
|
103 | + 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
104 | + 'subsections' => apply_filters( |
|
105 | + 'FHEE__EED_Ticket_Selector_Caff___ticket_selector_settings_form__form_subsections', |
|
106 | + array( |
|
107 | + 'appearance_settings_hdr' => new EE_Form_Section_HTML( |
|
108 | + EEH_HTML::br(2) . |
|
109 | + EEH_HTML::h2(esc_html__('Ticket Selector Template Settings', 'event_espresso')) |
|
110 | + ), |
|
111 | + 'appearance_settings' => EED_Ticket_Selector_Caff::_ticket_selector_appearance_settings(), |
|
112 | + ) |
|
113 | + ), |
|
114 | + ) |
|
115 | + ); |
|
116 | + } |
|
117 | 117 | |
118 | 118 | |
119 | - /** |
|
120 | - * @return \EE_Form_Section_Proper |
|
121 | - * @throws \EE_Error |
|
122 | - */ |
|
123 | - public static function _ticket_selector_appearance_settings() |
|
124 | - { |
|
125 | - if ( |
|
126 | - ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
127 | - ) { |
|
128 | - EED_Ticket_Selector::instance()->set_config(); |
|
129 | - EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector = EED_Ticket_Selector::instance() |
|
130 | - ->config(); |
|
131 | - } |
|
132 | - $EE_Ticket_Selector_Config = EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector; |
|
133 | - // get option for whether to show datetime selector in TS |
|
134 | - $show_datetime_selector = $EE_Ticket_Selector_Config->getShowDatetimeSelector(); |
|
135 | - // and option for how may datetimes must exist if display is conditional |
|
136 | - $datetime_selector_threshold = $EE_Ticket_Selector_Config->getDatetimeSelectorThreshold(); |
|
119 | + /** |
|
120 | + * @return \EE_Form_Section_Proper |
|
121 | + * @throws \EE_Error |
|
122 | + */ |
|
123 | + public static function _ticket_selector_appearance_settings() |
|
124 | + { |
|
125 | + if ( |
|
126 | + ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
127 | + ) { |
|
128 | + EED_Ticket_Selector::instance()->set_config(); |
|
129 | + EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector = EED_Ticket_Selector::instance() |
|
130 | + ->config(); |
|
131 | + } |
|
132 | + $EE_Ticket_Selector_Config = EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector; |
|
133 | + // get option for whether to show datetime selector in TS |
|
134 | + $show_datetime_selector = $EE_Ticket_Selector_Config->getShowDatetimeSelector(); |
|
135 | + // and option for how may datetimes must exist if display is conditional |
|
136 | + $datetime_selector_threshold = $EE_Ticket_Selector_Config->getDatetimeSelectorThreshold(); |
|
137 | 137 | |
138 | - return new EE_Form_Section_Proper( |
|
139 | - array( |
|
140 | - 'name' => 'ticket_selector_settings_tbl', |
|
141 | - 'html_id' => 'ticket_selector_settings_tbl', |
|
142 | - 'html_class' => 'form-table', |
|
143 | - 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
144 | - 'subsections' => apply_filters( |
|
145 | - 'FHEE__EED_Ticket_Selector_Caff___ticket_selector_appearance_settings__form_subsections', |
|
146 | - array( |
|
147 | - 'show_ticket_details' => new EE_Yes_No_Input( |
|
148 | - array( |
|
149 | - 'html_label_text' => esc_html__( |
|
150 | - 'Show Ticket Details?', |
|
151 | - 'event_espresso' |
|
152 | - ), |
|
153 | - 'html_help_text' => esc_html__( |
|
154 | - 'This lets you choose whether the extra ticket details section is displayed with the ticket selector.', |
|
155 | - 'event_espresso' |
|
156 | - ), |
|
157 | - 'default' => isset($EE_Ticket_Selector_Config->show_ticket_details) |
|
158 | - ? $EE_Ticket_Selector_Config->show_ticket_details |
|
159 | - : true, |
|
160 | - 'display_html_label_text' => false, |
|
161 | - ) |
|
162 | - ), |
|
163 | - 'show_ticket_sale_columns' => new EE_Yes_No_Input( |
|
164 | - array( |
|
165 | - 'html_label_text' => esc_html__( |
|
166 | - 'Show Ticket Sale Info?', |
|
167 | - 'event_espresso' |
|
168 | - ), |
|
169 | - 'html_help_text' => esc_html__( |
|
170 | - 'This lets you indicate whether information about ticket sales is shown with ticket details in the ticket selector.', |
|
171 | - 'event_espresso' |
|
172 | - ), |
|
173 | - 'default' => isset($EE_Ticket_Selector_Config->show_ticket_sale_columns) |
|
174 | - ? $EE_Ticket_Selector_Config->show_ticket_sale_columns |
|
175 | - : true, |
|
176 | - 'display_html_label_text' => false, |
|
177 | - ) |
|
178 | - ), |
|
179 | - 'show_expired_tickets' => new EE_Yes_No_Input( |
|
180 | - array( |
|
181 | - 'html_label_text' => esc_html__( |
|
182 | - 'Show Expired Tickets?', |
|
183 | - 'event_espresso' |
|
184 | - ), |
|
185 | - 'html_help_text' => esc_html__( |
|
186 | - 'Indicate whether to show expired tickets in the ticket selector', |
|
187 | - 'event_espresso' |
|
188 | - ), |
|
189 | - 'default' => isset($EE_Ticket_Selector_Config->show_expired_tickets) |
|
190 | - ? $EE_Ticket_Selector_Config->show_expired_tickets |
|
191 | - : true, |
|
192 | - 'display_html_label_text' => false, |
|
193 | - ) |
|
194 | - ), |
|
195 | - 'show_datetime_selector' => new EE_Select_Input( |
|
196 | - $EE_Ticket_Selector_Config->getShowDatetimeSelectorOptions(false), |
|
197 | - array( |
|
198 | - 'html_label_text' => esc_html__( |
|
199 | - 'Show Date & Time Filter?', |
|
200 | - 'event_espresso' |
|
201 | - ), |
|
202 | - 'html_help_text' => sprintf( |
|
203 | - esc_html__( |
|
204 | - 'Indicates whether or not to display a dropdown select box above each ticket selector that displays dates and times for the available tickets. Ticket options can be unselected, which removes (hides) them from the list of tickets being displayed.%1$sOptions include:%1$s • %2$sdo not show date & time filter%3$s%1$s this option will NEVER display a date filter, regardless of how many dates exist.%1$s • %2$smaybe show date & time filter%3$s%1$s this option will conditionally display the date filter when the number of dates for the event matches the value set for "Date Filter Threshold".', |
|
205 | - 'event_espresso' |
|
206 | - ), |
|
207 | - '<br>', |
|
208 | - '<strong>', |
|
209 | - '</strong>' |
|
210 | - ), |
|
211 | - 'default' => ! empty($show_datetime_selector) |
|
212 | - ? $show_datetime_selector |
|
213 | - : EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR, |
|
214 | - 'display_html_label_text' => false, |
|
215 | - ) |
|
216 | - ), |
|
217 | - 'datetime_selector_threshold' => new EE_Select_Input( |
|
218 | - array_combine($r = range(1, 10), $r), |
|
219 | - array( |
|
220 | - 'html_label_text' => esc_html__( |
|
221 | - 'Date & Time Filter Threshold', |
|
222 | - 'event_espresso' |
|
223 | - ), |
|
224 | - 'html_help_text' => esc_html__( |
|
225 | - 'The number of unique dates an event has to have before conditionally displaying a date & time filter', |
|
226 | - 'event_espresso' |
|
227 | - ), |
|
228 | - 'default' => ! empty($datetime_selector_threshold) |
|
229 | - ? $datetime_selector_threshold |
|
230 | - : 3, |
|
231 | - 'display_html_label_text' => false, |
|
232 | - ) |
|
233 | - ), |
|
234 | - 'datetime_selector_max_checked' => new EE_Integer_Input( |
|
235 | - array( |
|
236 | - 'html_label_text' => esc_html__( |
|
237 | - 'Date & Time Filter Max Checked', |
|
238 | - 'event_espresso' |
|
239 | - ), |
|
240 | - 'html_help_text' => sprintf( |
|
241 | - esc_html__( |
|
242 | - 'Determines the maximum number of dates that will be checked upon initial loading for a Date and Time Filter.%1$sIf set to zero or left blank, then ALL dates will be checked upon initial loading.', |
|
243 | - 'event_espresso' |
|
244 | - ), |
|
245 | - '<br>' |
|
246 | - ), |
|
247 | - 'default' => $EE_Ticket_Selector_Config->getDatetimeSelectorMaxChecked(), |
|
248 | - 'display_html_label_text' => false, |
|
249 | - 'min_value' => 0, |
|
250 | - ) |
|
251 | - ), |
|
252 | - ) |
|
253 | - ), |
|
254 | - ) |
|
255 | - ); |
|
256 | - } |
|
138 | + return new EE_Form_Section_Proper( |
|
139 | + array( |
|
140 | + 'name' => 'ticket_selector_settings_tbl', |
|
141 | + 'html_id' => 'ticket_selector_settings_tbl', |
|
142 | + 'html_class' => 'form-table', |
|
143 | + 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
144 | + 'subsections' => apply_filters( |
|
145 | + 'FHEE__EED_Ticket_Selector_Caff___ticket_selector_appearance_settings__form_subsections', |
|
146 | + array( |
|
147 | + 'show_ticket_details' => new EE_Yes_No_Input( |
|
148 | + array( |
|
149 | + 'html_label_text' => esc_html__( |
|
150 | + 'Show Ticket Details?', |
|
151 | + 'event_espresso' |
|
152 | + ), |
|
153 | + 'html_help_text' => esc_html__( |
|
154 | + 'This lets you choose whether the extra ticket details section is displayed with the ticket selector.', |
|
155 | + 'event_espresso' |
|
156 | + ), |
|
157 | + 'default' => isset($EE_Ticket_Selector_Config->show_ticket_details) |
|
158 | + ? $EE_Ticket_Selector_Config->show_ticket_details |
|
159 | + : true, |
|
160 | + 'display_html_label_text' => false, |
|
161 | + ) |
|
162 | + ), |
|
163 | + 'show_ticket_sale_columns' => new EE_Yes_No_Input( |
|
164 | + array( |
|
165 | + 'html_label_text' => esc_html__( |
|
166 | + 'Show Ticket Sale Info?', |
|
167 | + 'event_espresso' |
|
168 | + ), |
|
169 | + 'html_help_text' => esc_html__( |
|
170 | + 'This lets you indicate whether information about ticket sales is shown with ticket details in the ticket selector.', |
|
171 | + 'event_espresso' |
|
172 | + ), |
|
173 | + 'default' => isset($EE_Ticket_Selector_Config->show_ticket_sale_columns) |
|
174 | + ? $EE_Ticket_Selector_Config->show_ticket_sale_columns |
|
175 | + : true, |
|
176 | + 'display_html_label_text' => false, |
|
177 | + ) |
|
178 | + ), |
|
179 | + 'show_expired_tickets' => new EE_Yes_No_Input( |
|
180 | + array( |
|
181 | + 'html_label_text' => esc_html__( |
|
182 | + 'Show Expired Tickets?', |
|
183 | + 'event_espresso' |
|
184 | + ), |
|
185 | + 'html_help_text' => esc_html__( |
|
186 | + 'Indicate whether to show expired tickets in the ticket selector', |
|
187 | + 'event_espresso' |
|
188 | + ), |
|
189 | + 'default' => isset($EE_Ticket_Selector_Config->show_expired_tickets) |
|
190 | + ? $EE_Ticket_Selector_Config->show_expired_tickets |
|
191 | + : true, |
|
192 | + 'display_html_label_text' => false, |
|
193 | + ) |
|
194 | + ), |
|
195 | + 'show_datetime_selector' => new EE_Select_Input( |
|
196 | + $EE_Ticket_Selector_Config->getShowDatetimeSelectorOptions(false), |
|
197 | + array( |
|
198 | + 'html_label_text' => esc_html__( |
|
199 | + 'Show Date & Time Filter?', |
|
200 | + 'event_espresso' |
|
201 | + ), |
|
202 | + 'html_help_text' => sprintf( |
|
203 | + esc_html__( |
|
204 | + 'Indicates whether or not to display a dropdown select box above each ticket selector that displays dates and times for the available tickets. Ticket options can be unselected, which removes (hides) them from the list of tickets being displayed.%1$sOptions include:%1$s • %2$sdo not show date & time filter%3$s%1$s this option will NEVER display a date filter, regardless of how many dates exist.%1$s • %2$smaybe show date & time filter%3$s%1$s this option will conditionally display the date filter when the number of dates for the event matches the value set for "Date Filter Threshold".', |
|
205 | + 'event_espresso' |
|
206 | + ), |
|
207 | + '<br>', |
|
208 | + '<strong>', |
|
209 | + '</strong>' |
|
210 | + ), |
|
211 | + 'default' => ! empty($show_datetime_selector) |
|
212 | + ? $show_datetime_selector |
|
213 | + : EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR, |
|
214 | + 'display_html_label_text' => false, |
|
215 | + ) |
|
216 | + ), |
|
217 | + 'datetime_selector_threshold' => new EE_Select_Input( |
|
218 | + array_combine($r = range(1, 10), $r), |
|
219 | + array( |
|
220 | + 'html_label_text' => esc_html__( |
|
221 | + 'Date & Time Filter Threshold', |
|
222 | + 'event_espresso' |
|
223 | + ), |
|
224 | + 'html_help_text' => esc_html__( |
|
225 | + 'The number of unique dates an event has to have before conditionally displaying a date & time filter', |
|
226 | + 'event_espresso' |
|
227 | + ), |
|
228 | + 'default' => ! empty($datetime_selector_threshold) |
|
229 | + ? $datetime_selector_threshold |
|
230 | + : 3, |
|
231 | + 'display_html_label_text' => false, |
|
232 | + ) |
|
233 | + ), |
|
234 | + 'datetime_selector_max_checked' => new EE_Integer_Input( |
|
235 | + array( |
|
236 | + 'html_label_text' => esc_html__( |
|
237 | + 'Date & Time Filter Max Checked', |
|
238 | + 'event_espresso' |
|
239 | + ), |
|
240 | + 'html_help_text' => sprintf( |
|
241 | + esc_html__( |
|
242 | + 'Determines the maximum number of dates that will be checked upon initial loading for a Date and Time Filter.%1$sIf set to zero or left blank, then ALL dates will be checked upon initial loading.', |
|
243 | + 'event_espresso' |
|
244 | + ), |
|
245 | + '<br>' |
|
246 | + ), |
|
247 | + 'default' => $EE_Ticket_Selector_Config->getDatetimeSelectorMaxChecked(), |
|
248 | + 'display_html_label_text' => false, |
|
249 | + 'min_value' => 0, |
|
250 | + ) |
|
251 | + ), |
|
252 | + ) |
|
253 | + ), |
|
254 | + ) |
|
255 | + ); |
|
256 | + } |
|
257 | 257 | |
258 | 258 | |
259 | - /** |
|
260 | - * callback for updating template settings |
|
261 | - * |
|
262 | - * @since 4.6.18.rc.006 |
|
263 | - * @param EE_Template_Config $CFG |
|
264 | - * @param array $REQ incoming request |
|
265 | - * @return EE_Template_Config |
|
266 | - * @throws EE_Error |
|
267 | - * @throws InvalidArgumentException |
|
268 | - * @throws ReflectionException |
|
269 | - * @throws InvalidDataTypeException |
|
270 | - * @throws InvalidInterfaceException |
|
271 | - */ |
|
272 | - public static function update_template_settings(EE_Template_Config $CFG, $REQ) |
|
273 | - { |
|
274 | - if (! $CFG->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config) { |
|
275 | - EED_Ticket_Selector::instance()->set_config(); |
|
276 | - $CFG->EED_Ticket_Selector = EED_Ticket_Selector::instance()->config(); |
|
277 | - } |
|
278 | - try { |
|
279 | - $ticket_selector_form = EED_Ticket_Selector_Caff::_ticket_selector_settings_form(); |
|
259 | + /** |
|
260 | + * callback for updating template settings |
|
261 | + * |
|
262 | + * @since 4.6.18.rc.006 |
|
263 | + * @param EE_Template_Config $CFG |
|
264 | + * @param array $REQ incoming request |
|
265 | + * @return EE_Template_Config |
|
266 | + * @throws EE_Error |
|
267 | + * @throws InvalidArgumentException |
|
268 | + * @throws ReflectionException |
|
269 | + * @throws InvalidDataTypeException |
|
270 | + * @throws InvalidInterfaceException |
|
271 | + */ |
|
272 | + public static function update_template_settings(EE_Template_Config $CFG, $REQ) |
|
273 | + { |
|
274 | + if (! $CFG->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config) { |
|
275 | + EED_Ticket_Selector::instance()->set_config(); |
|
276 | + $CFG->EED_Ticket_Selector = EED_Ticket_Selector::instance()->config(); |
|
277 | + } |
|
278 | + try { |
|
279 | + $ticket_selector_form = EED_Ticket_Selector_Caff::_ticket_selector_settings_form(); |
|
280 | 280 | |
281 | - // check for form submission |
|
282 | - if ($ticket_selector_form->was_submitted()) { |
|
283 | - // capture form data |
|
284 | - $ticket_selector_form->receive_form_submission(); |
|
281 | + // check for form submission |
|
282 | + if ($ticket_selector_form->was_submitted()) { |
|
283 | + // capture form data |
|
284 | + $ticket_selector_form->receive_form_submission(); |
|
285 | 285 | |
286 | - // validate form data |
|
287 | - if ($ticket_selector_form->is_valid()) { |
|
288 | - // grab validated data from form |
|
289 | - $valid_data = $ticket_selector_form->valid_data(); |
|
286 | + // validate form data |
|
287 | + if ($ticket_selector_form->is_valid()) { |
|
288 | + // grab validated data from form |
|
289 | + $valid_data = $ticket_selector_form->valid_data(); |
|
290 | 290 | |
291 | - // set data on config |
|
292 | - $CFG->EED_Ticket_Selector->show_ticket_sale_columns = $valid_data['appearance_settings']['show_ticket_sale_columns']; |
|
293 | - $CFG->EED_Ticket_Selector->show_ticket_details = $valid_data['appearance_settings']['show_ticket_details']; |
|
294 | - $CFG->EED_Ticket_Selector->show_expired_tickets = $valid_data['appearance_settings']['show_expired_tickets']; |
|
295 | - $CFG->EED_Ticket_Selector->setShowDatetimeSelector( |
|
296 | - $valid_data['appearance_settings']['show_datetime_selector'] |
|
297 | - ); |
|
298 | - $CFG->EED_Ticket_Selector->setDatetimeSelectorThreshold( |
|
299 | - $valid_data['appearance_settings']['datetime_selector_threshold'] |
|
300 | - ); |
|
301 | - $CFG->EED_Ticket_Selector->setDatetimeSelectorMaxChecked( |
|
302 | - $valid_data['appearance_settings']['datetime_selector_max_checked'] |
|
303 | - ); |
|
304 | - } else { |
|
305 | - if ($ticket_selector_form->submission_error_message() !== '') { |
|
306 | - EE_Error::add_error( |
|
307 | - $ticket_selector_form->submission_error_message(), |
|
308 | - __FILE__, |
|
309 | - __FUNCTION__, |
|
310 | - __LINE__ |
|
311 | - ); |
|
312 | - } |
|
313 | - } |
|
314 | - } |
|
315 | - } catch (EE_Error $e) { |
|
316 | - $e->get_error(); |
|
317 | - } |
|
291 | + // set data on config |
|
292 | + $CFG->EED_Ticket_Selector->show_ticket_sale_columns = $valid_data['appearance_settings']['show_ticket_sale_columns']; |
|
293 | + $CFG->EED_Ticket_Selector->show_ticket_details = $valid_data['appearance_settings']['show_ticket_details']; |
|
294 | + $CFG->EED_Ticket_Selector->show_expired_tickets = $valid_data['appearance_settings']['show_expired_tickets']; |
|
295 | + $CFG->EED_Ticket_Selector->setShowDatetimeSelector( |
|
296 | + $valid_data['appearance_settings']['show_datetime_selector'] |
|
297 | + ); |
|
298 | + $CFG->EED_Ticket_Selector->setDatetimeSelectorThreshold( |
|
299 | + $valid_data['appearance_settings']['datetime_selector_threshold'] |
|
300 | + ); |
|
301 | + $CFG->EED_Ticket_Selector->setDatetimeSelectorMaxChecked( |
|
302 | + $valid_data['appearance_settings']['datetime_selector_max_checked'] |
|
303 | + ); |
|
304 | + } else { |
|
305 | + if ($ticket_selector_form->submission_error_message() !== '') { |
|
306 | + EE_Error::add_error( |
|
307 | + $ticket_selector_form->submission_error_message(), |
|
308 | + __FILE__, |
|
309 | + __FUNCTION__, |
|
310 | + __LINE__ |
|
311 | + ); |
|
312 | + } |
|
313 | + } |
|
314 | + } |
|
315 | + } catch (EE_Error $e) { |
|
316 | + $e->get_error(); |
|
317 | + } |
|
318 | 318 | |
319 | - return $CFG; |
|
320 | - } |
|
319 | + return $CFG; |
|
320 | + } |
|
321 | 321 | |
322 | 322 | |
323 | - /** |
|
324 | - * @param \EE_Ticket $ticket |
|
325 | - * @param int $ticket_price |
|
326 | - * @param bool $display_ticket_price |
|
327 | - */ |
|
328 | - public static function ticket_price_details(EE_Ticket $ticket, $ticket_price = 0, $display_ticket_price = false) |
|
329 | - { |
|
330 | - require str_replace('\\', '/', plugin_dir_path(__FILE__)) |
|
331 | - . 'templates/ticket_selector_price_details.template.php'; |
|
332 | - } |
|
323 | + /** |
|
324 | + * @param \EE_Ticket $ticket |
|
325 | + * @param int $ticket_price |
|
326 | + * @param bool $display_ticket_price |
|
327 | + */ |
|
328 | + public static function ticket_price_details(EE_Ticket $ticket, $ticket_price = 0, $display_ticket_price = false) |
|
329 | + { |
|
330 | + require str_replace('\\', '/', plugin_dir_path(__FILE__)) |
|
331 | + . 'templates/ticket_selector_price_details.template.php'; |
|
332 | + } |
|
333 | 333 | } |
@@ -99,7 +99,7 @@ discard block |
||
99 | 99 | ) { |
100 | 100 | $has_password = $model->hasPassword(); |
101 | 101 | if ($has_password) { |
102 | - $entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson( |
|
102 | + $entity[$model->getPasswordField()->get_name()] = ModelDataTranslator::prepareFieldValueForJson( |
|
103 | 103 | $model->getPasswordField(), |
104 | 104 | $model->getPasswordField()->get_default_value(), |
105 | 105 | $model_version_info->requestedVersion() |
@@ -109,7 +109,7 @@ discard block |
||
109 | 109 | if ( |
110 | 110 | $has_password |
111 | 111 | && $model->getPasswordField()->fieldIsProtected($field_name) |
112 | - && $entity[ $field_name ] |
|
112 | + && $entity[$field_name] |
|
113 | 113 | ) { |
114 | 114 | $replacement_value = ModelDataTranslator::prepareFieldValueForJson( |
115 | 115 | $field_obj, |
@@ -117,10 +117,10 @@ discard block |
||
117 | 117 | $model_version_info->requestedVersion() |
118 | 118 | ); |
119 | 119 | if ($model_version_info->fieldHasRenderedFormat($field_obj)) { |
120 | - $entity[ $field_name ]['rendered'] = $replacement_value; |
|
120 | + $entity[$field_name]['rendered'] = $replacement_value; |
|
121 | 121 | } elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) { |
122 | - $entity[ $field_name ]['raw'] = $replacement_value; |
|
123 | - $entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson( |
|
122 | + $entity[$field_name]['raw'] = $replacement_value; |
|
123 | + $entity[$field_name]['pretty'] = ModelDataTranslator::prepareFieldValueForJson( |
|
124 | 124 | $field_obj, |
125 | 125 | $field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()), |
126 | 126 | $model_version_info->requestedVersion() |
@@ -131,7 +131,7 @@ discard block |
||
131 | 131 | // so just remove it (or rather, set its default) |
132 | 132 | // API clients will just need to look to fields with rendered formats to know if these have |
133 | 133 | // been redacted. Sorry. |
134 | - $entity[ $field_name ] = $replacement_value; |
|
134 | + $entity[$field_name] = $replacement_value; |
|
135 | 135 | } |
136 | 136 | } |
137 | 137 | } |
@@ -160,11 +160,11 @@ discard block |
||
160 | 160 | foreach ($model->field_settings() as $field_name => $field_obj) { |
161 | 161 | if ( |
162 | 162 | $model_version_info->fieldHasRenderedFormat($field_obj) |
163 | - && isset($entity[ $field_name ]) |
|
164 | - && is_array($entity[ $field_name ]) |
|
165 | - && isset($entity[ $field_name ]['raw']) |
|
163 | + && isset($entity[$field_name]) |
|
164 | + && is_array($entity[$field_name]) |
|
165 | + && isset($entity[$field_name]['raw']) |
|
166 | 166 | ) { |
167 | - unset($entity[ $field_name ]['raw']); |
|
167 | + unset($entity[$field_name]['raw']); |
|
168 | 168 | } |
169 | 169 | } |
170 | 170 | // theoretically we may want to filter out specific fields for specific models |
@@ -190,7 +190,7 @@ discard block |
||
190 | 190 | */ |
191 | 191 | public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list') |
192 | 192 | { |
193 | - if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) { |
|
193 | + if ( ! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) { |
|
194 | 194 | $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
195 | 195 | throw new RestException( |
196 | 196 | sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural), |
@@ -17,190 +17,190 @@ |
||
17 | 17 | */ |
18 | 18 | class Capabilities |
19 | 19 | { |
20 | - /** |
|
21 | - * The current user can see at least SOME of these entities. |
|
22 | - * |
|
23 | - * @param EEM_Base $model |
|
24 | - * @param string $model_context one of the return values from EEM_Base::valid_cap_contexts() |
|
25 | - * @return boolean |
|
26 | - */ |
|
27 | - public static function currentUserHasPartialAccessTo($model, $model_context = EEM_Base::caps_read) |
|
28 | - { |
|
29 | - if ( |
|
30 | - apply_filters( |
|
31 | - 'FHEE__Capabilities__current_user_has_partial_access_to__override_begin', |
|
32 | - false, |
|
33 | - $model, |
|
34 | - $model |
|
35 | - ) |
|
36 | - ) { |
|
37 | - return true; |
|
38 | - } |
|
39 | - foreach ($model->caps_missing($model_context) as $capability_name => $restriction_obj) { |
|
40 | - if ($restriction_obj instanceof \EE_Return_None_Where_Conditions) { |
|
41 | - return false; |
|
42 | - } |
|
43 | - } |
|
44 | - if ( |
|
45 | - apply_filters( |
|
46 | - 'FHEE__Capabilities__current_user_has_partial_access_to__override_end', |
|
47 | - false, |
|
48 | - $model, |
|
49 | - $model |
|
50 | - ) |
|
51 | - ) { |
|
52 | - return false; |
|
53 | - } |
|
54 | - return true; |
|
55 | - } |
|
20 | + /** |
|
21 | + * The current user can see at least SOME of these entities. |
|
22 | + * |
|
23 | + * @param EEM_Base $model |
|
24 | + * @param string $model_context one of the return values from EEM_Base::valid_cap_contexts() |
|
25 | + * @return boolean |
|
26 | + */ |
|
27 | + public static function currentUserHasPartialAccessTo($model, $model_context = EEM_Base::caps_read) |
|
28 | + { |
|
29 | + if ( |
|
30 | + apply_filters( |
|
31 | + 'FHEE__Capabilities__current_user_has_partial_access_to__override_begin', |
|
32 | + false, |
|
33 | + $model, |
|
34 | + $model |
|
35 | + ) |
|
36 | + ) { |
|
37 | + return true; |
|
38 | + } |
|
39 | + foreach ($model->caps_missing($model_context) as $capability_name => $restriction_obj) { |
|
40 | + if ($restriction_obj instanceof \EE_Return_None_Where_Conditions) { |
|
41 | + return false; |
|
42 | + } |
|
43 | + } |
|
44 | + if ( |
|
45 | + apply_filters( |
|
46 | + 'FHEE__Capabilities__current_user_has_partial_access_to__override_end', |
|
47 | + false, |
|
48 | + $model, |
|
49 | + $model |
|
50 | + ) |
|
51 | + ) { |
|
52 | + return false; |
|
53 | + } |
|
54 | + return true; |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | - /** |
|
59 | - * Gets an array of all the capabilities the current user is missing that affected |
|
60 | - * the query |
|
61 | - * |
|
62 | - * @param EEM_Base $model |
|
63 | - * @param string $request_type one of the constants on WP_JSON_Server |
|
64 | - * @return array |
|
65 | - */ |
|
66 | - public static function getMissingPermissions($model, $request_type = EEM_Base::caps_read) |
|
67 | - { |
|
68 | - return $model->caps_missing($request_type); |
|
69 | - } |
|
58 | + /** |
|
59 | + * Gets an array of all the capabilities the current user is missing that affected |
|
60 | + * the query |
|
61 | + * |
|
62 | + * @param EEM_Base $model |
|
63 | + * @param string $request_type one of the constants on WP_JSON_Server |
|
64 | + * @return array |
|
65 | + */ |
|
66 | + public static function getMissingPermissions($model, $request_type = EEM_Base::caps_read) |
|
67 | + { |
|
68 | + return $model->caps_missing($request_type); |
|
69 | + } |
|
70 | 70 | |
71 | 71 | |
72 | - /** |
|
73 | - * Gets a string of all the capabilities the current user is missing that affected |
|
74 | - * the query |
|
75 | - * |
|
76 | - * @param EEM_Base $model |
|
77 | - * @param string $model_context one of the return values from EEM_Base::valid_cap_contexts() |
|
78 | - * @return string |
|
79 | - */ |
|
80 | - public static function getMissingPermissionsString($model, $model_context = EEM_Base::caps_read) |
|
81 | - { |
|
82 | - return implode(',', array_keys(self::getMissingPermissions($model, $model_context))); |
|
83 | - } |
|
72 | + /** |
|
73 | + * Gets a string of all the capabilities the current user is missing that affected |
|
74 | + * the query |
|
75 | + * |
|
76 | + * @param EEM_Base $model |
|
77 | + * @param string $model_context one of the return values from EEM_Base::valid_cap_contexts() |
|
78 | + * @return string |
|
79 | + */ |
|
80 | + public static function getMissingPermissionsString($model, $model_context = EEM_Base::caps_read) |
|
81 | + { |
|
82 | + return implode(',', array_keys(self::getMissingPermissions($model, $model_context))); |
|
83 | + } |
|
84 | 84 | |
85 | - /** |
|
86 | - * "Removes" password-protected fields. Currently that means setting their values to their default. |
|
87 | - * @since 4.9.74.p |
|
88 | - * @param array $entity |
|
89 | - * @param EEM_Base $model |
|
90 | - * @param ModelVersionInfo $model_version_info |
|
91 | - * @return array |
|
92 | - * @throws EE_Error |
|
93 | - */ |
|
94 | - public static function filterOutPasswordProtectedFields( |
|
95 | - $entity, |
|
96 | - EEM_Base $model, |
|
97 | - ModelVersionInfo $model_version_info |
|
98 | - ) { |
|
99 | - $has_password = $model->hasPassword(); |
|
100 | - if ($has_password) { |
|
101 | - $entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson( |
|
102 | - $model->getPasswordField(), |
|
103 | - $model->getPasswordField()->get_default_value(), |
|
104 | - $model_version_info->requestedVersion() |
|
105 | - ); |
|
106 | - } |
|
107 | - foreach ($model->field_settings() as $field_name => $field_obj) { |
|
108 | - if ( |
|
109 | - $has_password |
|
110 | - && $model->getPasswordField()->fieldIsProtected($field_name) |
|
111 | - && $entity[ $field_name ] |
|
112 | - ) { |
|
113 | - $replacement_value = ModelDataTranslator::prepareFieldValueForJson( |
|
114 | - $field_obj, |
|
115 | - $field_obj->get_default_value(), |
|
116 | - $model_version_info->requestedVersion() |
|
117 | - ); |
|
118 | - if ($model_version_info->fieldHasRenderedFormat($field_obj)) { |
|
119 | - $entity[ $field_name ]['rendered'] = $replacement_value; |
|
120 | - } elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) { |
|
121 | - $entity[ $field_name ]['raw'] = $replacement_value; |
|
122 | - $entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson( |
|
123 | - $field_obj, |
|
124 | - $field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()), |
|
125 | - $model_version_info->requestedVersion() |
|
126 | - ); |
|
127 | - } else { |
|
128 | - // this is most likely an excerpt field. (These should have also had "rendered" and "raw" |
|
129 | - // versions, but we missed that, and can't change it without breaking backward compatibility) |
|
130 | - // so just remove it (or rather, set its default) |
|
131 | - // API clients will just need to look to fields with rendered formats to know if these have |
|
132 | - // been redacted. Sorry. |
|
133 | - $entity[ $field_name ] = $replacement_value; |
|
134 | - } |
|
135 | - } |
|
136 | - } |
|
137 | - return $entity; |
|
138 | - } |
|
85 | + /** |
|
86 | + * "Removes" password-protected fields. Currently that means setting their values to their default. |
|
87 | + * @since 4.9.74.p |
|
88 | + * @param array $entity |
|
89 | + * @param EEM_Base $model |
|
90 | + * @param ModelVersionInfo $model_version_info |
|
91 | + * @return array |
|
92 | + * @throws EE_Error |
|
93 | + */ |
|
94 | + public static function filterOutPasswordProtectedFields( |
|
95 | + $entity, |
|
96 | + EEM_Base $model, |
|
97 | + ModelVersionInfo $model_version_info |
|
98 | + ) { |
|
99 | + $has_password = $model->hasPassword(); |
|
100 | + if ($has_password) { |
|
101 | + $entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson( |
|
102 | + $model->getPasswordField(), |
|
103 | + $model->getPasswordField()->get_default_value(), |
|
104 | + $model_version_info->requestedVersion() |
|
105 | + ); |
|
106 | + } |
|
107 | + foreach ($model->field_settings() as $field_name => $field_obj) { |
|
108 | + if ( |
|
109 | + $has_password |
|
110 | + && $model->getPasswordField()->fieldIsProtected($field_name) |
|
111 | + && $entity[ $field_name ] |
|
112 | + ) { |
|
113 | + $replacement_value = ModelDataTranslator::prepareFieldValueForJson( |
|
114 | + $field_obj, |
|
115 | + $field_obj->get_default_value(), |
|
116 | + $model_version_info->requestedVersion() |
|
117 | + ); |
|
118 | + if ($model_version_info->fieldHasRenderedFormat($field_obj)) { |
|
119 | + $entity[ $field_name ]['rendered'] = $replacement_value; |
|
120 | + } elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) { |
|
121 | + $entity[ $field_name ]['raw'] = $replacement_value; |
|
122 | + $entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson( |
|
123 | + $field_obj, |
|
124 | + $field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()), |
|
125 | + $model_version_info->requestedVersion() |
|
126 | + ); |
|
127 | + } else { |
|
128 | + // this is most likely an excerpt field. (These should have also had "rendered" and "raw" |
|
129 | + // versions, but we missed that, and can't change it without breaking backward compatibility) |
|
130 | + // so just remove it (or rather, set its default) |
|
131 | + // API clients will just need to look to fields with rendered formats to know if these have |
|
132 | + // been redacted. Sorry. |
|
133 | + $entity[ $field_name ] = $replacement_value; |
|
134 | + } |
|
135 | + } |
|
136 | + } |
|
137 | + return $entity; |
|
138 | + } |
|
139 | 139 | |
140 | 140 | |
141 | - /** |
|
142 | - * Takes a entity that's ready to be returned and removes fields which the user shouldn't be able to access. |
|
143 | - * |
|
144 | - * @param array $entity |
|
145 | - * @param EEM_Base $model |
|
146 | - * @param string $request_type one of the return values from EEM_Base::valid_cap_contexts() |
|
147 | - * @param ModelVersionInfo $model_version_info |
|
148 | - * @param string $primary_key_string result of EEM_Base::get_index_primary_key_string(), so that we can |
|
149 | - * use this with models that have no primary key |
|
150 | - * @return array ready for converting into json |
|
151 | - */ |
|
152 | - public static function filterOutInaccessibleEntityFields( |
|
153 | - $entity, |
|
154 | - $model, |
|
155 | - $request_type, |
|
156 | - $model_version_info, |
|
157 | - $primary_key_string = null |
|
158 | - ) { |
|
159 | - foreach ($model->field_settings() as $field_name => $field_obj) { |
|
160 | - if ( |
|
161 | - $model_version_info->fieldHasRenderedFormat($field_obj) |
|
162 | - && isset($entity[ $field_name ]) |
|
163 | - && is_array($entity[ $field_name ]) |
|
164 | - && isset($entity[ $field_name ]['raw']) |
|
165 | - ) { |
|
166 | - unset($entity[ $field_name ]['raw']); |
|
167 | - } |
|
168 | - } |
|
169 | - // theoretically we may want to filter out specific fields for specific models |
|
170 | - return apply_filters( |
|
171 | - 'FHEE__Capabilities__filter_out_inaccessible_entity_fields', |
|
172 | - $entity, |
|
173 | - $model, |
|
174 | - $request_type |
|
175 | - ); |
|
176 | - } |
|
141 | + /** |
|
142 | + * Takes a entity that's ready to be returned and removes fields which the user shouldn't be able to access. |
|
143 | + * |
|
144 | + * @param array $entity |
|
145 | + * @param EEM_Base $model |
|
146 | + * @param string $request_type one of the return values from EEM_Base::valid_cap_contexts() |
|
147 | + * @param ModelVersionInfo $model_version_info |
|
148 | + * @param string $primary_key_string result of EEM_Base::get_index_primary_key_string(), so that we can |
|
149 | + * use this with models that have no primary key |
|
150 | + * @return array ready for converting into json |
|
151 | + */ |
|
152 | + public static function filterOutInaccessibleEntityFields( |
|
153 | + $entity, |
|
154 | + $model, |
|
155 | + $request_type, |
|
156 | + $model_version_info, |
|
157 | + $primary_key_string = null |
|
158 | + ) { |
|
159 | + foreach ($model->field_settings() as $field_name => $field_obj) { |
|
160 | + if ( |
|
161 | + $model_version_info->fieldHasRenderedFormat($field_obj) |
|
162 | + && isset($entity[ $field_name ]) |
|
163 | + && is_array($entity[ $field_name ]) |
|
164 | + && isset($entity[ $field_name ]['raw']) |
|
165 | + ) { |
|
166 | + unset($entity[ $field_name ]['raw']); |
|
167 | + } |
|
168 | + } |
|
169 | + // theoretically we may want to filter out specific fields for specific models |
|
170 | + return apply_filters( |
|
171 | + 'FHEE__Capabilities__filter_out_inaccessible_entity_fields', |
|
172 | + $entity, |
|
173 | + $model, |
|
174 | + $request_type |
|
175 | + ); |
|
176 | + } |
|
177 | 177 | |
178 | 178 | |
179 | - /** |
|
180 | - * Verifies the current user has at least partial access to do this action on this model. |
|
181 | - * If not, throws an exception (so we can define the code that sets up this error object |
|
182 | - * once) |
|
183 | - * |
|
184 | - * @param EEM_Base $model |
|
185 | - * @param string $model_action_context |
|
186 | - * @param string $action_name |
|
187 | - * @return void |
|
188 | - * @throws RestException |
|
189 | - */ |
|
190 | - public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list') |
|
191 | - { |
|
192 | - if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) { |
|
193 | - $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
194 | - throw new RestException( |
|
195 | - sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural), |
|
196 | - sprintf( |
|
197 | - esc_html__('Sorry, you are not allowed to %1$s %2$s. Missing permissions: %3$s', 'event_espresso'), |
|
198 | - $action_name, |
|
199 | - $model_name_plural, |
|
200 | - Capabilities::getMissingPermissionsString($model, $model_action_context) |
|
201 | - ), |
|
202 | - array('status' => 403) |
|
203 | - ); |
|
204 | - } |
|
205 | - } |
|
179 | + /** |
|
180 | + * Verifies the current user has at least partial access to do this action on this model. |
|
181 | + * If not, throws an exception (so we can define the code that sets up this error object |
|
182 | + * once) |
|
183 | + * |
|
184 | + * @param EEM_Base $model |
|
185 | + * @param string $model_action_context |
|
186 | + * @param string $action_name |
|
187 | + * @return void |
|
188 | + * @throws RestException |
|
189 | + */ |
|
190 | + public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list') |
|
191 | + { |
|
192 | + if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) { |
|
193 | + $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
194 | + throw new RestException( |
|
195 | + sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural), |
|
196 | + sprintf( |
|
197 | + esc_html__('Sorry, you are not allowed to %1$s %2$s. Missing permissions: %3$s', 'event_espresso'), |
|
198 | + $action_name, |
|
199 | + $model_name_plural, |
|
200 | + Capabilities::getMissingPermissionsString($model, $model_action_context) |
|
201 | + ), |
|
202 | + array('status' => 403) |
|
203 | + ); |
|
204 | + } |
|
205 | + } |
|
206 | 206 | } |
@@ -28,707 +28,707 @@ |
||
28 | 28 | */ |
29 | 29 | class RestIncomingQueryParamMetadata |
30 | 30 | { |
31 | - private $query_param_key; |
|
32 | - private $query_param_value; |
|
33 | - /** |
|
34 | - * @var RestIncomingQueryParamContext |
|
35 | - */ |
|
36 | - private $context; |
|
37 | - |
|
38 | - /** |
|
39 | - * @var EE_Model_Field_Base|null |
|
40 | - */ |
|
41 | - private $field; |
|
42 | - |
|
43 | - /** |
|
44 | - * @var string same as $query_param_key but has the * and anything after it removed |
|
45 | - */ |
|
46 | - private $query_param_key_sans_stars; |
|
47 | - |
|
48 | - /** |
|
49 | - * @var string for timezone or timezone offset |
|
50 | - */ |
|
51 | - private $timezone; |
|
52 | - |
|
53 | - /** |
|
54 | - * @var boolean if the field in $query_param_key is for a GMT field (eg `EVT_modified_gmt`) |
|
55 | - */ |
|
56 | - private $is_gmt_field = false; |
|
57 | - |
|
58 | - /** |
|
59 | - * RestIncomingQueryParamMetadata constructor. |
|
60 | - * You probably want to call |
|
61 | - * @param string $query_param_key |
|
62 | - * @param string $query_param_value |
|
63 | - * @param RestIncomingQueryParamContext $context |
|
64 | - */ |
|
65 | - public function __construct($query_param_key, $query_param_value, RestIncomingQueryParamContext $context) |
|
66 | - { |
|
67 | - $this->query_param_key = $query_param_key; |
|
68 | - $this->query_param_value = $query_param_value; |
|
69 | - $this->context = $context; |
|
70 | - $this->determineFieldAndTimezone(); |
|
71 | - } |
|
72 | - |
|
73 | - /** |
|
74 | - * Gets the query parameter key. This may have been modified (see setQueryParamValue()) |
|
75 | - * @return string |
|
76 | - */ |
|
77 | - public function getQueryParamKey() |
|
78 | - { |
|
79 | - return $this->query_param_key; |
|
80 | - } |
|
81 | - |
|
82 | - /** |
|
83 | - * Modifies the query parameter key passed in (Eg this is done when rewriting the simplified specified operator REST |
|
84 | - * query parameters into the legacy structure) |
|
85 | - * @param string|array|int|float $query_param_value |
|
86 | - */ |
|
87 | - private function setQueryParamValue($query_param_value) |
|
88 | - { |
|
89 | - $this->query_param_value = $query_param_value; |
|
90 | - } |
|
91 | - |
|
92 | - /** |
|
93 | - * Gets the original query parameter value passed in. |
|
94 | - * @return string |
|
95 | - */ |
|
96 | - public function getQueryParamValue() |
|
97 | - { |
|
98 | - return $this->query_param_value; |
|
99 | - } |
|
100 | - |
|
101 | - /** |
|
102 | - * Gets the context object. |
|
103 | - * @return RestIncomingQueryParamContext |
|
104 | - */ |
|
105 | - public function getContext() |
|
106 | - { |
|
107 | - return $this->context; |
|
108 | - } |
|
109 | - |
|
110 | - /** |
|
111 | - * Sets the query parameter key. This may be used to rewrite a key into its non-GMT alternative. |
|
112 | - * @param string $query_param_key |
|
113 | - */ |
|
114 | - private function setQueryParamKey($query_param_key) |
|
115 | - { |
|
116 | - $this->query_param_key = $query_param_key; |
|
117 | - } |
|
118 | - |
|
119 | - /** |
|
120 | - * Gets the field the query parameter key indicated. This may be null (in cases where the query parameter key |
|
121 | - * did not indicate a field, eg if it were `OR`). |
|
122 | - * @return EE_Model_Field_Base|null |
|
123 | - */ |
|
124 | - public function getField() |
|
125 | - { |
|
126 | - return $this->field; |
|
127 | - } |
|
128 | - |
|
129 | - /** |
|
130 | - * Gets the query parameter key (with the star and everything afterwards removed). |
|
131 | - * @return string |
|
132 | - */ |
|
133 | - public function getQueryParamKeySansStars() |
|
134 | - { |
|
135 | - return $this->query_param_key_sans_stars; |
|
136 | - } |
|
137 | - |
|
138 | - /** |
|
139 | - * Gets the timezone associated with this model (the site timezone, except for GMT datetime fields). |
|
140 | - * @return string |
|
141 | - */ |
|
142 | - public function getTimezone() |
|
143 | - { |
|
144 | - return $this->timezone; |
|
145 | - } |
|
146 | - |
|
147 | - /** |
|
148 | - * Returns whether or not this is a GMT field |
|
149 | - * @return boolean |
|
150 | - */ |
|
151 | - public function isGmtField() |
|
152 | - { |
|
153 | - return $this->is_gmt_field; |
|
154 | - } |
|
155 | - |
|
156 | - /** |
|
157 | - * Sets the field indicated by the query parameter key (might be null). |
|
158 | - * @param EE_Model_Field_Base|null $field |
|
159 | - */ |
|
160 | - private function setField(EE_Model_Field_Base $field = null) |
|
161 | - { |
|
162 | - $this->field = $field; |
|
163 | - } |
|
164 | - |
|
165 | - /** |
|
166 | - * Sets the query parameter key-with-stars-removed. |
|
167 | - * @param string $query_param_key_sans_stars |
|
168 | - */ |
|
169 | - private function setQueryParamKeySansStars($query_param_key_sans_stars) |
|
170 | - { |
|
171 | - $this->query_param_key_sans_stars = $query_param_key_sans_stars; |
|
172 | - } |
|
173 | - |
|
174 | - /** |
|
175 | - * Sets the timezone (this could be a timezeon offset string). |
|
176 | - * @param string $timezone |
|
177 | - */ |
|
178 | - private function setTimezone($timezone) |
|
179 | - { |
|
180 | - $this->timezone = $timezone; |
|
181 | - } |
|
182 | - |
|
183 | - /** |
|
184 | - * @param mixed $is_gmt_field |
|
185 | - */ |
|
186 | - private function setIsGmtField($is_gmt_field) |
|
187 | - { |
|
188 | - $this->is_gmt_field = $is_gmt_field; |
|
189 | - } |
|
190 | - |
|
191 | - /** |
|
192 | - * Determines what field, query param name, and query param name without stars, and timezone to use. |
|
193 | - * @since 4.9.72.p |
|
194 | - * @type EE_Model_Field_Base $field |
|
195 | - * @return void { |
|
196 | - * @throws EE_Error |
|
197 | - * @throws InvalidDataTypeException |
|
198 | - * @throws InvalidInterfaceException |
|
199 | - * @throws InvalidArgumentException |
|
200 | - */ |
|
201 | - private function determineFieldAndTimezone() |
|
202 | - { |
|
203 | - $this->setQueryParamKeySansStars(ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey( |
|
204 | - $this->getQueryParamKey() |
|
205 | - )); |
|
206 | - $this->setField(ModelDataTranslator::deduceFieldFromQueryParam( |
|
207 | - $this->getQueryParamKeySansStars(), |
|
208 | - $this->getContext()->getModel() |
|
209 | - )); |
|
210 | - // double-check is it a *_gmt field? |
|
211 | - if ( |
|
212 | - !$this->getField() instanceof EE_Model_Field_Base |
|
213 | - && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars()) |
|
214 | - ) { |
|
215 | - // yep, take off '_gmt', and find the field |
|
216 | - $this->setQueryParamKey(ModelDataTranslator::removeGmtFromFieldName($this->getQueryParamKeySansStars())); |
|
217 | - $this->setField(ModelDataTranslator::deduceFieldFromQueryParam( |
|
218 | - $this->getQueryParamKey(), |
|
219 | - $this->context->getModel() |
|
220 | - )); |
|
221 | - $this->setTimezone('UTC'); |
|
222 | - $this->setIsGmtField(true); |
|
223 | - } elseif ($this->getField() instanceof EE_Datetime_Field) { |
|
224 | - // so it's not a GMT field. Set the timezone on the model to the default |
|
225 | - $this->setTimezone(EEH_DTT_Helper::get_valid_timezone_string()); |
|
226 | - } else { |
|
227 | - // just keep using what's already set for the timezone |
|
228 | - $this->setTimezone($this->context->getModel()->get_timezone()); |
|
229 | - } |
|
230 | - $this->assertOnlyAdminCanReadPasswordFields(); |
|
231 | - } |
|
232 | - |
|
233 | - /** |
|
234 | - * Throws an exception if a non-admin is trying to query by password. |
|
235 | - * @since 4.9.74.p |
|
236 | - * @throws RestException |
|
237 | - */ |
|
238 | - private function assertOnlyAdminCanReadPasswordFields() |
|
239 | - { |
|
240 | - if ( |
|
241 | - $this->getField() instanceof EE_Password_Field |
|
242 | - && ! current_user_can(EE_Restriction_Generator_Base::get_default_restrictions_cap()) |
|
243 | - ) { |
|
244 | - // only full admins can query by password. sorry bub! |
|
245 | - throw new RestException( |
|
246 | - 'only_admins_can_query_by_password', |
|
247 | - // @codingStandardsIgnoreStart |
|
248 | - esc_html__('You attempted to filter by a password field without the needed privileges. Only a full admin is allowed to do that.', 'event_espresso'), |
|
249 | - // @codingStandardsIgnoreEnd |
|
250 | - array( |
|
251 | - 'status' => 403 |
|
252 | - ) |
|
253 | - ); |
|
254 | - } |
|
255 | - } |
|
256 | - |
|
257 | - /** |
|
258 | - * Given a ton of input, determines the value to use for the models. |
|
259 | - * @since 4.9.72.p |
|
260 | - * @return array|null |
|
261 | - * @throws DomainException |
|
262 | - * @throws EE_Error |
|
263 | - * @throws RestException |
|
264 | - * @throws DomainException |
|
265 | - */ |
|
266 | - public function determineConditionsQueryParameterValue() |
|
267 | - { |
|
268 | - if ($this->valueIsArrayDuringRead()) { |
|
269 | - return $this->determineModelValueGivenRestInputArray(); |
|
270 | - } |
|
271 | - return ModelDataTranslator::prepareFieldValueFromJson( |
|
272 | - $this->getField(), |
|
273 | - $this->getQueryParamValue(), |
|
274 | - $this->getContext()->getRequestedVersion(), |
|
275 | - $this->getTimezone() |
|
276 | - ); |
|
277 | - } |
|
278 | - |
|
279 | - /** |
|
280 | - * Given that the array value provided was itself an array, handles finding the correct value to pass to the model. |
|
281 | - * @since 4.9.72.p |
|
282 | - * @return array|null |
|
283 | - * @throws RestException |
|
284 | - */ |
|
285 | - private function determineModelValueGivenRestInputArray() |
|
286 | - { |
|
287 | - $this->transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax(); |
|
288 | - // did they specify an operator? |
|
289 | - if ($this->valueIsLegacySpecifiedOperator()) { |
|
290 | - $query_param_value = $this->getQueryParamValue(); |
|
291 | - $sub_array_key = $query_param_value[0]; |
|
292 | - $translated_value = array($sub_array_key); |
|
293 | - if ($this->operatorIsNAry($sub_array_key)) { |
|
294 | - $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]); |
|
295 | - } elseif ($this->operatorIsTernary($sub_array_key)) { |
|
296 | - $translated_value[] = array( |
|
297 | - $this->prepareValuesFromJson($query_param_value[1][0]), |
|
298 | - $this->prepareValuesFromJson($query_param_value[1][1]) |
|
299 | - ); |
|
300 | - } elseif ($this->operatorIsLike($sub_array_key)) { |
|
301 | - // we want to leave this value mostly-as-is (eg don't force it to be a float |
|
302 | - // or a boolean or an enum value. Leave it as-is with wildcards etc) |
|
303 | - // but do verify it at least doesn't have any serialized data |
|
304 | - ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]); |
|
305 | - $translated_value[] = $query_param_value[1]; |
|
306 | - } elseif ($this->operatorIsUnary($sub_array_key)) { |
|
307 | - // no arguments should have been provided, so don't look for any |
|
308 | - } elseif ($this->operatorisBinary($sub_array_key)) { |
|
309 | - // it's a valid operator, but none of the exceptions. Treat it normally. |
|
310 | - $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]); |
|
311 | - } else { |
|
312 | - // so they provided a valid operator, but wrong number of arguments |
|
313 | - $this->throwWrongNumberOfArgsExceptionIfDebugging($sub_array_key); |
|
314 | - $translated_value = null; |
|
315 | - } |
|
316 | - } else { |
|
317 | - // so they didn't provide a valid operator |
|
318 | - // if we aren't in debug mode, then just try our best to fulfill the user's request |
|
319 | - $this->throwInvalidOperatorExceptionIfDebugging(); |
|
320 | - $translated_value = null; |
|
321 | - } |
|
322 | - return $translated_value; |
|
323 | - } |
|
324 | - |
|
325 | - /** |
|
326 | - * Returns if this request is a "read" request and the value provided was an array. |
|
327 | - * This will indicate is such things as `array('<', 123)` and `array('IN', array(1,2,3))` are acceptable or not. |
|
328 | - * @since 4.9.72.p |
|
329 | - * @return boolean |
|
330 | - */ |
|
331 | - private function valueIsArrayDuringRead() |
|
332 | - { |
|
333 | - return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue()); |
|
334 | - } |
|
335 | - |
|
336 | - /** |
|
337 | - * Returns if the value provided was an associative array (we should have already verified it's an array of some |
|
338 | - * sort). If the value is an associative array, it had better be in the simplified specified operator structure. |
|
339 | - * @since 4.9.72.p |
|
340 | - * @return boolean |
|
341 | - */ |
|
342 | - private function valueIsAssociativeArray() |
|
343 | - { |
|
344 | - return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue()); |
|
345 | - } |
|
346 | - |
|
347 | - /** |
|
348 | - * Checks if the array value is itself an array that fits into the simplified specified operator structure |
|
349 | - * (eg `array('!=' => 123)`). |
|
350 | - * @since 4.9.72.p |
|
351 | - * @return boolean |
|
352 | - */ |
|
353 | - private function valueIsSimplifiedSpecifiedOperator() |
|
354 | - { |
|
355 | - return count($this->getQueryParamValue()) === 1 |
|
356 | - && array_key_exists( |
|
357 | - key($this->getQueryParamValue()), |
|
358 | - $this->getContext()->getModel()->valid_operators() |
|
359 | - ); |
|
360 | - } |
|
361 | - |
|
362 | - /** |
|
363 | - * Throws an exception if the sub-value is an array (eg `array('!=' => array())`). It needs to just be a string, |
|
364 | - * of either comma-separated-values, or a JSON array. |
|
365 | - * @since 4.9.72.p |
|
366 | - * @param $sub_array_key |
|
367 | - * @param $sub_array_value |
|
368 | - * @throws RestException |
|
369 | - */ |
|
370 | - private function assertSubValueIsntArray($sub_array_key, $sub_array_value) |
|
371 | - { |
|
372 | - if (is_array($sub_array_value) && EED_Core_Rest_Api::debugMode()) { |
|
373 | - throw new RestException( |
|
374 | - 'csv_or_json_string_only', |
|
375 | - sprintf( |
|
376 | - /* translators: 1: variable name*/ |
|
377 | - esc_html__( |
|
378 | - 'The value provided for the operator "%1$s" should be comma-separated value string or a JSON array.', |
|
379 | - 'event_espresso' |
|
380 | - ), |
|
381 | - $sub_array_key |
|
382 | - ), |
|
383 | - array( |
|
384 | - 'status' => 400, |
|
385 | - ) |
|
386 | - ); |
|
387 | - } |
|
388 | - } |
|
389 | - |
|
390 | - /** |
|
391 | - * Determines if the sub-array key is an operator taking 3 or more operators. |
|
392 | - * @since 4.9.72.p |
|
393 | - * @param $sub_array_key |
|
394 | - * @return boolean |
|
395 | - */ |
|
396 | - private function subArrayKeyIsNonBinaryOperator($sub_array_key) |
|
397 | - { |
|
398 | - return array_key_exists( |
|
399 | - $sub_array_key, |
|
400 | - array_merge( |
|
401 | - $this->getContext()->getModel()->valid_in_style_operators(), |
|
402 | - $this->getContext()->getModel()->valid_between_style_operators() |
|
403 | - ) |
|
404 | - ); |
|
405 | - } |
|
406 | - |
|
407 | - /** |
|
408 | - * Given that the $sub_array_key is a string, checks if it's an operator taking only 1 argument. |
|
409 | - * @since 4.9.72.p |
|
410 | - * @param string $sub_array_key |
|
411 | - * @return boolean |
|
412 | - */ |
|
413 | - private function subArrayKeyIsUnaryOperator($sub_array_key) |
|
414 | - { |
|
415 | - return array_key_exists( |
|
416 | - $sub_array_key, |
|
417 | - $this->getContext()->getModel()->valid_null_style_operators() |
|
418 | - ); |
|
419 | - } |
|
420 | - |
|
421 | - /** |
|
422 | - * Parses the $sub_array_value string into an array (given it could either be a comma-separated-list or a JSON |
|
423 | - * array). eg `"1,2,3"` or `"[1,2,3]"` into `array(1,2,3)`. |
|
424 | - * @since 4.9.72.p |
|
425 | - * @param $sub_array_value |
|
426 | - * @return array|mixed|object |
|
427 | - */ |
|
428 | - private function extractQuickStyleSpecifiedOperatorValue($sub_array_value) |
|
429 | - { |
|
430 | - // the value should be JSON or CSV |
|
431 | - $values = json_decode($sub_array_value); |
|
432 | - if (!is_array($values)) { |
|
433 | - $values = array_filter( |
|
434 | - array_map( |
|
435 | - 'trim', |
|
436 | - explode( |
|
437 | - ',', |
|
438 | - $sub_array_value |
|
439 | - ) |
|
440 | - ) |
|
441 | - ); |
|
442 | - } |
|
443 | - return $values; |
|
444 | - } |
|
445 | - |
|
446 | - /** |
|
447 | - * Throws an exception if the value isn't a simplified specified operator (only called when we expect that). |
|
448 | - * @since 4.9.72.p |
|
449 | - * @throws RestException |
|
450 | - */ |
|
451 | - private function assertSimplifiedSpecifiedOperator() |
|
452 | - { |
|
453 | - if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) { |
|
454 | - throw new RestException( |
|
455 | - 'numerically_indexed_array_of_values_only', |
|
456 | - sprintf( |
|
457 | - /* translators: 1: variable name*/ |
|
458 | - esc_html__( |
|
459 | - 'The array provided for the parameter "%1$s" should be numerically indexed.', |
|
460 | - 'event_espresso' |
|
461 | - ), |
|
462 | - $this->getQueryParamKey() |
|
463 | - ), |
|
464 | - array( |
|
465 | - 'status' => 400, |
|
466 | - ) |
|
467 | - ); |
|
468 | - } |
|
469 | - } |
|
470 | - |
|
471 | - /** |
|
472 | - * If query_param_value were in the simplified specific operator structure, change it into the legacy structure. |
|
473 | - * @since 4.9.72.p |
|
474 | - * @throws RestException |
|
475 | - */ |
|
476 | - private function transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax() |
|
477 | - { |
|
478 | - if ($this->valueIsAssociativeArray()) { |
|
479 | - $this->assertSimplifiedSpecifiedOperator(); |
|
480 | - $query_param_value = $this->getQueryParamValue(); |
|
481 | - $sub_array_value = reset($query_param_value); |
|
482 | - $sub_array_key = key($query_param_value); |
|
483 | - $this->assertSubValueIsntArray($sub_array_key, $sub_array_value); |
|
484 | - // they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5" |
|
485 | - if ($this->subArrayKeyIsNonBinaryOperator($sub_array_key)) { |
|
486 | - $this->setQueryParamValue(array( |
|
487 | - $sub_array_key, |
|
488 | - $this->extractQuickStyleSpecifiedOperatorValue($sub_array_value) |
|
489 | - )); |
|
490 | - } elseif ($this->subArrayKeyIsUnaryOperator($sub_array_key)) { |
|
491 | - $this->setQueryParamValue(array($sub_array_key)); |
|
492 | - } else { |
|
493 | - $this->setQueryParamValue(array($sub_array_key, $sub_array_value)); |
|
494 | - } |
|
495 | - } |
|
496 | - } |
|
497 | - |
|
498 | - /** |
|
499 | - * Returns true is the value is an array using the legacy structure to specify the operator. Eg `array('!=',123)`. |
|
500 | - * @since 4.9.72.p |
|
501 | - * @return boolean |
|
502 | - */ |
|
503 | - private function valueIsLegacySpecifiedOperator() |
|
504 | - { |
|
505 | - $valid_operators = $this->getContext()->getModel()->valid_operators(); |
|
506 | - $query_param_value = $this->getQueryParamValue(); |
|
507 | - return isset($query_param_value[0]) |
|
508 | - && isset($valid_operators[ $query_param_value[0] ]); |
|
509 | - } |
|
510 | - |
|
511 | - /** |
|
512 | - * Returns true if the value specified operator accepts arbitrary number of arguments, like "IN". |
|
513 | - * @since 4.9.72.p |
|
514 | - * @param $operator |
|
515 | - * @return boolean |
|
516 | - */ |
|
517 | - private function operatorIsNAry($operator) |
|
518 | - { |
|
519 | - $valueArray = $this->getQueryParamValue(); |
|
520 | - return array_key_exists( |
|
521 | - $operator, |
|
522 | - $this->getContext()->getModel()->valid_in_style_operators() |
|
523 | - ) |
|
524 | - && isset($valueArray[1]) |
|
525 | - && is_array($valueArray[1]) |
|
526 | - && !isset($valueArray[2]); |
|
527 | - } |
|
528 | - |
|
529 | - /** |
|
530 | - * Returns true if the operator accepts 3 arguments (eg "BETWEEN"). |
|
531 | - * So we're looking for a value that looks like |
|
532 | - * `array('BETWEEN', array('2015-01-01T00:00:00', '2016-01-01T00:00:00'))`. |
|
533 | - * @since 4.9.72.p |
|
534 | - * @param $operator |
|
535 | - * @return boolean |
|
536 | - */ |
|
537 | - private function operatorIsTernary($operator) |
|
538 | - { |
|
539 | - $query_param_value = $this->getQueryParamValue(); |
|
540 | - return array_key_exists($operator, $this->getContext()->getModel()->valid_between_style_operators()) |
|
541 | - && isset($query_param_value[1]) |
|
542 | - && is_array($query_param_value[1]) |
|
543 | - && isset($query_param_value[1][0], $query_param_value[1][1]) |
|
544 | - && !isset($query_param_value[1][2]) |
|
545 | - && !isset($query_param_value[2]); |
|
546 | - } |
|
547 | - |
|
548 | - /** |
|
549 | - * Returns true if the operator is a similar to LIKE, indicating the value may have wildcards we should leave alone. |
|
550 | - * @since 4.9.72.p |
|
551 | - * @param $operator |
|
552 | - * @return boolean |
|
553 | - */ |
|
554 | - private function operatorIsLike($operator) |
|
555 | - { |
|
556 | - $query_param_value = $this->getQueryParamValue(); |
|
557 | - return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators()) |
|
558 | - && isset($query_param_value[1]) |
|
559 | - && !isset($query_param_value[2]); |
|
560 | - } |
|
561 | - |
|
562 | - /** |
|
563 | - * Returns true if the operator only takes one argument (eg it's like `IS NULL`). |
|
564 | - * @since 4.9.72.p |
|
565 | - * @param $operator |
|
566 | - * @return boolean |
|
567 | - */ |
|
568 | - private function operatorIsUnary($operator) |
|
569 | - { |
|
570 | - $query_param_value = $this->getQueryParamValue(); |
|
571 | - return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators()) |
|
572 | - && !isset($query_param_value[1]); |
|
573 | - } |
|
574 | - |
|
575 | - /** |
|
576 | - * Returns true if the operator specified is a binary opeator (eg `=`, `!=`) |
|
577 | - * @since 4.9.72.p |
|
578 | - * @param $operator |
|
579 | - * @return boolean |
|
580 | - */ |
|
581 | - private function operatorisBinary($operator) |
|
582 | - { |
|
583 | - $query_param_value = $this->getQueryParamValue(); |
|
584 | - $model = $this->getContext()->getModel(); |
|
585 | - return isset($query_param_value[1]) |
|
586 | - && !isset($query_param_value[2]) |
|
587 | - && !array_key_exists( |
|
588 | - $operator, |
|
589 | - array_merge( |
|
590 | - $model->valid_in_style_operators(), |
|
591 | - $model->valid_null_style_operators(), |
|
592 | - $model->valid_like_style_operators(), |
|
593 | - $model->valid_between_style_operators() |
|
594 | - ) |
|
595 | - ); |
|
596 | - } |
|
597 | - |
|
598 | - /** |
|
599 | - * If we're debugging, throws an exception saying that the wrong number of arguments was provided. |
|
600 | - * @since 4.9.72.p |
|
601 | - * @param $operator |
|
602 | - * @throws RestException |
|
603 | - */ |
|
604 | - private function throwWrongNumberOfArgsExceptionIfDebugging($operator) |
|
605 | - { |
|
606 | - if (EED_Core_Rest_Api::debugMode()) { |
|
607 | - throw new RestException( |
|
608 | - 'wrong_number_of_arguments', |
|
609 | - sprintf( |
|
610 | - esc_html__( |
|
611 | - 'The operator you provided, "%1$s" had the wrong number of arguments', |
|
612 | - 'event_espresso' |
|
613 | - ), |
|
614 | - $operator |
|
615 | - ), |
|
616 | - array( |
|
617 | - 'status' => 400, |
|
618 | - ) |
|
619 | - ); |
|
620 | - } |
|
621 | - } |
|
622 | - |
|
623 | - /** |
|
624 | - * Wrapper for ModelDataTranslator::prepareFieldValuesFromJson(), just a tad more DRY. |
|
625 | - * @since 4.9.72.p |
|
626 | - * @param $value |
|
627 | - * @return mixed |
|
628 | - * @throws RestException |
|
629 | - */ |
|
630 | - private function prepareValuesFromJson($value) |
|
631 | - { |
|
632 | - return ModelDataTranslator::prepareFieldValuesFromJson( |
|
633 | - $this->getField(), |
|
634 | - $value, |
|
635 | - $this->getContext()->getRequestedVersion(), |
|
636 | - $this->getTimezone() |
|
637 | - ); |
|
638 | - } |
|
639 | - |
|
640 | - /** |
|
641 | - * Throws an exception if an invalid operator was specified and we're debugging. |
|
642 | - * @since 4.9.72.p |
|
643 | - * @throws RestException |
|
644 | - */ |
|
645 | - private function throwInvalidOperatorExceptionIfDebugging() |
|
646 | - { |
|
647 | - // so they didn't provide a valid operator |
|
648 | - if (EED_Core_Rest_Api::debugMode()) { |
|
649 | - throw new RestException( |
|
650 | - 'invalid_operator', |
|
651 | - sprintf( |
|
652 | - esc_html__( |
|
653 | - 'You provided an invalid parameter, with key "%1$s" and value "%2$s"', |
|
654 | - 'event_espresso' |
|
655 | - ), |
|
656 | - $this->getQueryParamKey(), |
|
657 | - $this->getQueryParamValue() |
|
658 | - ), |
|
659 | - array( |
|
660 | - 'status' => 400, |
|
661 | - ) |
|
662 | - ); |
|
663 | - } |
|
664 | - } |
|
665 | - |
|
666 | - /** |
|
667 | - * Returns true if the query_param_key was a logic query parameter, eg `OR`, `AND`, `NOT`, `OR*`, etc. |
|
668 | - * @since 4.9.72.p |
|
669 | - * @return boolean |
|
670 | - */ |
|
671 | - private function isLogicQueryParam() |
|
672 | - { |
|
673 | - return in_array($this->getQueryParamKeySansStars(), $this->getContext()->getModel()->logic_query_param_keys()); |
|
674 | - } |
|
675 | - |
|
676 | - |
|
677 | - /** |
|
678 | - * If the query param isn't for a field, it must be a nested query parameter which requires different logic. |
|
679 | - * @since 4.9.72.p |
|
680 | - * @return array |
|
681 | - * @throws DomainException |
|
682 | - * @throws EE_Error |
|
683 | - * @throws RestException |
|
684 | - * @throws InvalidDataTypeException |
|
685 | - * @throws InvalidInterfaceException |
|
686 | - * @throws InvalidArgumentException |
|
687 | - */ |
|
688 | - public function determineNestedConditionQueryParameters() |
|
689 | - { |
|
690 | - |
|
691 | - // so this param doesn't correspond to a field eh? |
|
692 | - if ($this->getContext()->isWriting()) { |
|
693 | - // always tell API clients about invalid parameters when they're creating data. Otherwise, |
|
694 | - // they are probably going to create invalid data |
|
695 | - throw new RestException( |
|
696 | - 'invalid_field', |
|
697 | - sprintf( |
|
698 | - /* translators: 1: variable name */ |
|
699 | - esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'), |
|
700 | - $this->getQueryParamKey() |
|
701 | - ) |
|
702 | - ); |
|
703 | - } |
|
704 | - // so it's not for a field, is it a logic query param key? |
|
705 | - if ($this->isLogicQueryParam()) { |
|
706 | - return ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
707 | - $this->getQueryParamValue(), |
|
708 | - $this->getContext()->getModel(), |
|
709 | - $this->getContext()->getRequestedVersion() |
|
710 | - ); |
|
711 | - } |
|
712 | - if (EED_Core_Rest_Api::debugMode()) { |
|
713 | - // only tell API clients they got it wrong if we're in debug mode |
|
714 | - // otherwise try our best ot fulfill their request by ignoring this invalid data |
|
715 | - throw new RestException( |
|
716 | - 'invalid_parameter', |
|
717 | - sprintf( |
|
718 | - /* translators: 1: variable name */ |
|
719 | - esc_html__( |
|
720 | - 'You provided an invalid parameter, with key "%1$s"', |
|
721 | - 'event_espresso' |
|
722 | - ), |
|
723 | - $this->getQueryParamKey() |
|
724 | - ), |
|
725 | - array( |
|
726 | - 'status' => 400, |
|
727 | - ) |
|
728 | - ); |
|
729 | - } |
|
730 | - return null; |
|
731 | - } |
|
31 | + private $query_param_key; |
|
32 | + private $query_param_value; |
|
33 | + /** |
|
34 | + * @var RestIncomingQueryParamContext |
|
35 | + */ |
|
36 | + private $context; |
|
37 | + |
|
38 | + /** |
|
39 | + * @var EE_Model_Field_Base|null |
|
40 | + */ |
|
41 | + private $field; |
|
42 | + |
|
43 | + /** |
|
44 | + * @var string same as $query_param_key but has the * and anything after it removed |
|
45 | + */ |
|
46 | + private $query_param_key_sans_stars; |
|
47 | + |
|
48 | + /** |
|
49 | + * @var string for timezone or timezone offset |
|
50 | + */ |
|
51 | + private $timezone; |
|
52 | + |
|
53 | + /** |
|
54 | + * @var boolean if the field in $query_param_key is for a GMT field (eg `EVT_modified_gmt`) |
|
55 | + */ |
|
56 | + private $is_gmt_field = false; |
|
57 | + |
|
58 | + /** |
|
59 | + * RestIncomingQueryParamMetadata constructor. |
|
60 | + * You probably want to call |
|
61 | + * @param string $query_param_key |
|
62 | + * @param string $query_param_value |
|
63 | + * @param RestIncomingQueryParamContext $context |
|
64 | + */ |
|
65 | + public function __construct($query_param_key, $query_param_value, RestIncomingQueryParamContext $context) |
|
66 | + { |
|
67 | + $this->query_param_key = $query_param_key; |
|
68 | + $this->query_param_value = $query_param_value; |
|
69 | + $this->context = $context; |
|
70 | + $this->determineFieldAndTimezone(); |
|
71 | + } |
|
72 | + |
|
73 | + /** |
|
74 | + * Gets the query parameter key. This may have been modified (see setQueryParamValue()) |
|
75 | + * @return string |
|
76 | + */ |
|
77 | + public function getQueryParamKey() |
|
78 | + { |
|
79 | + return $this->query_param_key; |
|
80 | + } |
|
81 | + |
|
82 | + /** |
|
83 | + * Modifies the query parameter key passed in (Eg this is done when rewriting the simplified specified operator REST |
|
84 | + * query parameters into the legacy structure) |
|
85 | + * @param string|array|int|float $query_param_value |
|
86 | + */ |
|
87 | + private function setQueryParamValue($query_param_value) |
|
88 | + { |
|
89 | + $this->query_param_value = $query_param_value; |
|
90 | + } |
|
91 | + |
|
92 | + /** |
|
93 | + * Gets the original query parameter value passed in. |
|
94 | + * @return string |
|
95 | + */ |
|
96 | + public function getQueryParamValue() |
|
97 | + { |
|
98 | + return $this->query_param_value; |
|
99 | + } |
|
100 | + |
|
101 | + /** |
|
102 | + * Gets the context object. |
|
103 | + * @return RestIncomingQueryParamContext |
|
104 | + */ |
|
105 | + public function getContext() |
|
106 | + { |
|
107 | + return $this->context; |
|
108 | + } |
|
109 | + |
|
110 | + /** |
|
111 | + * Sets the query parameter key. This may be used to rewrite a key into its non-GMT alternative. |
|
112 | + * @param string $query_param_key |
|
113 | + */ |
|
114 | + private function setQueryParamKey($query_param_key) |
|
115 | + { |
|
116 | + $this->query_param_key = $query_param_key; |
|
117 | + } |
|
118 | + |
|
119 | + /** |
|
120 | + * Gets the field the query parameter key indicated. This may be null (in cases where the query parameter key |
|
121 | + * did not indicate a field, eg if it were `OR`). |
|
122 | + * @return EE_Model_Field_Base|null |
|
123 | + */ |
|
124 | + public function getField() |
|
125 | + { |
|
126 | + return $this->field; |
|
127 | + } |
|
128 | + |
|
129 | + /** |
|
130 | + * Gets the query parameter key (with the star and everything afterwards removed). |
|
131 | + * @return string |
|
132 | + */ |
|
133 | + public function getQueryParamKeySansStars() |
|
134 | + { |
|
135 | + return $this->query_param_key_sans_stars; |
|
136 | + } |
|
137 | + |
|
138 | + /** |
|
139 | + * Gets the timezone associated with this model (the site timezone, except for GMT datetime fields). |
|
140 | + * @return string |
|
141 | + */ |
|
142 | + public function getTimezone() |
|
143 | + { |
|
144 | + return $this->timezone; |
|
145 | + } |
|
146 | + |
|
147 | + /** |
|
148 | + * Returns whether or not this is a GMT field |
|
149 | + * @return boolean |
|
150 | + */ |
|
151 | + public function isGmtField() |
|
152 | + { |
|
153 | + return $this->is_gmt_field; |
|
154 | + } |
|
155 | + |
|
156 | + /** |
|
157 | + * Sets the field indicated by the query parameter key (might be null). |
|
158 | + * @param EE_Model_Field_Base|null $field |
|
159 | + */ |
|
160 | + private function setField(EE_Model_Field_Base $field = null) |
|
161 | + { |
|
162 | + $this->field = $field; |
|
163 | + } |
|
164 | + |
|
165 | + /** |
|
166 | + * Sets the query parameter key-with-stars-removed. |
|
167 | + * @param string $query_param_key_sans_stars |
|
168 | + */ |
|
169 | + private function setQueryParamKeySansStars($query_param_key_sans_stars) |
|
170 | + { |
|
171 | + $this->query_param_key_sans_stars = $query_param_key_sans_stars; |
|
172 | + } |
|
173 | + |
|
174 | + /** |
|
175 | + * Sets the timezone (this could be a timezeon offset string). |
|
176 | + * @param string $timezone |
|
177 | + */ |
|
178 | + private function setTimezone($timezone) |
|
179 | + { |
|
180 | + $this->timezone = $timezone; |
|
181 | + } |
|
182 | + |
|
183 | + /** |
|
184 | + * @param mixed $is_gmt_field |
|
185 | + */ |
|
186 | + private function setIsGmtField($is_gmt_field) |
|
187 | + { |
|
188 | + $this->is_gmt_field = $is_gmt_field; |
|
189 | + } |
|
190 | + |
|
191 | + /** |
|
192 | + * Determines what field, query param name, and query param name without stars, and timezone to use. |
|
193 | + * @since 4.9.72.p |
|
194 | + * @type EE_Model_Field_Base $field |
|
195 | + * @return void { |
|
196 | + * @throws EE_Error |
|
197 | + * @throws InvalidDataTypeException |
|
198 | + * @throws InvalidInterfaceException |
|
199 | + * @throws InvalidArgumentException |
|
200 | + */ |
|
201 | + private function determineFieldAndTimezone() |
|
202 | + { |
|
203 | + $this->setQueryParamKeySansStars(ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey( |
|
204 | + $this->getQueryParamKey() |
|
205 | + )); |
|
206 | + $this->setField(ModelDataTranslator::deduceFieldFromQueryParam( |
|
207 | + $this->getQueryParamKeySansStars(), |
|
208 | + $this->getContext()->getModel() |
|
209 | + )); |
|
210 | + // double-check is it a *_gmt field? |
|
211 | + if ( |
|
212 | + !$this->getField() instanceof EE_Model_Field_Base |
|
213 | + && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars()) |
|
214 | + ) { |
|
215 | + // yep, take off '_gmt', and find the field |
|
216 | + $this->setQueryParamKey(ModelDataTranslator::removeGmtFromFieldName($this->getQueryParamKeySansStars())); |
|
217 | + $this->setField(ModelDataTranslator::deduceFieldFromQueryParam( |
|
218 | + $this->getQueryParamKey(), |
|
219 | + $this->context->getModel() |
|
220 | + )); |
|
221 | + $this->setTimezone('UTC'); |
|
222 | + $this->setIsGmtField(true); |
|
223 | + } elseif ($this->getField() instanceof EE_Datetime_Field) { |
|
224 | + // so it's not a GMT field. Set the timezone on the model to the default |
|
225 | + $this->setTimezone(EEH_DTT_Helper::get_valid_timezone_string()); |
|
226 | + } else { |
|
227 | + // just keep using what's already set for the timezone |
|
228 | + $this->setTimezone($this->context->getModel()->get_timezone()); |
|
229 | + } |
|
230 | + $this->assertOnlyAdminCanReadPasswordFields(); |
|
231 | + } |
|
232 | + |
|
233 | + /** |
|
234 | + * Throws an exception if a non-admin is trying to query by password. |
|
235 | + * @since 4.9.74.p |
|
236 | + * @throws RestException |
|
237 | + */ |
|
238 | + private function assertOnlyAdminCanReadPasswordFields() |
|
239 | + { |
|
240 | + if ( |
|
241 | + $this->getField() instanceof EE_Password_Field |
|
242 | + && ! current_user_can(EE_Restriction_Generator_Base::get_default_restrictions_cap()) |
|
243 | + ) { |
|
244 | + // only full admins can query by password. sorry bub! |
|
245 | + throw new RestException( |
|
246 | + 'only_admins_can_query_by_password', |
|
247 | + // @codingStandardsIgnoreStart |
|
248 | + esc_html__('You attempted to filter by a password field without the needed privileges. Only a full admin is allowed to do that.', 'event_espresso'), |
|
249 | + // @codingStandardsIgnoreEnd |
|
250 | + array( |
|
251 | + 'status' => 403 |
|
252 | + ) |
|
253 | + ); |
|
254 | + } |
|
255 | + } |
|
256 | + |
|
257 | + /** |
|
258 | + * Given a ton of input, determines the value to use for the models. |
|
259 | + * @since 4.9.72.p |
|
260 | + * @return array|null |
|
261 | + * @throws DomainException |
|
262 | + * @throws EE_Error |
|
263 | + * @throws RestException |
|
264 | + * @throws DomainException |
|
265 | + */ |
|
266 | + public function determineConditionsQueryParameterValue() |
|
267 | + { |
|
268 | + if ($this->valueIsArrayDuringRead()) { |
|
269 | + return $this->determineModelValueGivenRestInputArray(); |
|
270 | + } |
|
271 | + return ModelDataTranslator::prepareFieldValueFromJson( |
|
272 | + $this->getField(), |
|
273 | + $this->getQueryParamValue(), |
|
274 | + $this->getContext()->getRequestedVersion(), |
|
275 | + $this->getTimezone() |
|
276 | + ); |
|
277 | + } |
|
278 | + |
|
279 | + /** |
|
280 | + * Given that the array value provided was itself an array, handles finding the correct value to pass to the model. |
|
281 | + * @since 4.9.72.p |
|
282 | + * @return array|null |
|
283 | + * @throws RestException |
|
284 | + */ |
|
285 | + private function determineModelValueGivenRestInputArray() |
|
286 | + { |
|
287 | + $this->transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax(); |
|
288 | + // did they specify an operator? |
|
289 | + if ($this->valueIsLegacySpecifiedOperator()) { |
|
290 | + $query_param_value = $this->getQueryParamValue(); |
|
291 | + $sub_array_key = $query_param_value[0]; |
|
292 | + $translated_value = array($sub_array_key); |
|
293 | + if ($this->operatorIsNAry($sub_array_key)) { |
|
294 | + $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]); |
|
295 | + } elseif ($this->operatorIsTernary($sub_array_key)) { |
|
296 | + $translated_value[] = array( |
|
297 | + $this->prepareValuesFromJson($query_param_value[1][0]), |
|
298 | + $this->prepareValuesFromJson($query_param_value[1][1]) |
|
299 | + ); |
|
300 | + } elseif ($this->operatorIsLike($sub_array_key)) { |
|
301 | + // we want to leave this value mostly-as-is (eg don't force it to be a float |
|
302 | + // or a boolean or an enum value. Leave it as-is with wildcards etc) |
|
303 | + // but do verify it at least doesn't have any serialized data |
|
304 | + ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]); |
|
305 | + $translated_value[] = $query_param_value[1]; |
|
306 | + } elseif ($this->operatorIsUnary($sub_array_key)) { |
|
307 | + // no arguments should have been provided, so don't look for any |
|
308 | + } elseif ($this->operatorisBinary($sub_array_key)) { |
|
309 | + // it's a valid operator, but none of the exceptions. Treat it normally. |
|
310 | + $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]); |
|
311 | + } else { |
|
312 | + // so they provided a valid operator, but wrong number of arguments |
|
313 | + $this->throwWrongNumberOfArgsExceptionIfDebugging($sub_array_key); |
|
314 | + $translated_value = null; |
|
315 | + } |
|
316 | + } else { |
|
317 | + // so they didn't provide a valid operator |
|
318 | + // if we aren't in debug mode, then just try our best to fulfill the user's request |
|
319 | + $this->throwInvalidOperatorExceptionIfDebugging(); |
|
320 | + $translated_value = null; |
|
321 | + } |
|
322 | + return $translated_value; |
|
323 | + } |
|
324 | + |
|
325 | + /** |
|
326 | + * Returns if this request is a "read" request and the value provided was an array. |
|
327 | + * This will indicate is such things as `array('<', 123)` and `array('IN', array(1,2,3))` are acceptable or not. |
|
328 | + * @since 4.9.72.p |
|
329 | + * @return boolean |
|
330 | + */ |
|
331 | + private function valueIsArrayDuringRead() |
|
332 | + { |
|
333 | + return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue()); |
|
334 | + } |
|
335 | + |
|
336 | + /** |
|
337 | + * Returns if the value provided was an associative array (we should have already verified it's an array of some |
|
338 | + * sort). If the value is an associative array, it had better be in the simplified specified operator structure. |
|
339 | + * @since 4.9.72.p |
|
340 | + * @return boolean |
|
341 | + */ |
|
342 | + private function valueIsAssociativeArray() |
|
343 | + { |
|
344 | + return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue()); |
|
345 | + } |
|
346 | + |
|
347 | + /** |
|
348 | + * Checks if the array value is itself an array that fits into the simplified specified operator structure |
|
349 | + * (eg `array('!=' => 123)`). |
|
350 | + * @since 4.9.72.p |
|
351 | + * @return boolean |
|
352 | + */ |
|
353 | + private function valueIsSimplifiedSpecifiedOperator() |
|
354 | + { |
|
355 | + return count($this->getQueryParamValue()) === 1 |
|
356 | + && array_key_exists( |
|
357 | + key($this->getQueryParamValue()), |
|
358 | + $this->getContext()->getModel()->valid_operators() |
|
359 | + ); |
|
360 | + } |
|
361 | + |
|
362 | + /** |
|
363 | + * Throws an exception if the sub-value is an array (eg `array('!=' => array())`). It needs to just be a string, |
|
364 | + * of either comma-separated-values, or a JSON array. |
|
365 | + * @since 4.9.72.p |
|
366 | + * @param $sub_array_key |
|
367 | + * @param $sub_array_value |
|
368 | + * @throws RestException |
|
369 | + */ |
|
370 | + private function assertSubValueIsntArray($sub_array_key, $sub_array_value) |
|
371 | + { |
|
372 | + if (is_array($sub_array_value) && EED_Core_Rest_Api::debugMode()) { |
|
373 | + throw new RestException( |
|
374 | + 'csv_or_json_string_only', |
|
375 | + sprintf( |
|
376 | + /* translators: 1: variable name*/ |
|
377 | + esc_html__( |
|
378 | + 'The value provided for the operator "%1$s" should be comma-separated value string or a JSON array.', |
|
379 | + 'event_espresso' |
|
380 | + ), |
|
381 | + $sub_array_key |
|
382 | + ), |
|
383 | + array( |
|
384 | + 'status' => 400, |
|
385 | + ) |
|
386 | + ); |
|
387 | + } |
|
388 | + } |
|
389 | + |
|
390 | + /** |
|
391 | + * Determines if the sub-array key is an operator taking 3 or more operators. |
|
392 | + * @since 4.9.72.p |
|
393 | + * @param $sub_array_key |
|
394 | + * @return boolean |
|
395 | + */ |
|
396 | + private function subArrayKeyIsNonBinaryOperator($sub_array_key) |
|
397 | + { |
|
398 | + return array_key_exists( |
|
399 | + $sub_array_key, |
|
400 | + array_merge( |
|
401 | + $this->getContext()->getModel()->valid_in_style_operators(), |
|
402 | + $this->getContext()->getModel()->valid_between_style_operators() |
|
403 | + ) |
|
404 | + ); |
|
405 | + } |
|
406 | + |
|
407 | + /** |
|
408 | + * Given that the $sub_array_key is a string, checks if it's an operator taking only 1 argument. |
|
409 | + * @since 4.9.72.p |
|
410 | + * @param string $sub_array_key |
|
411 | + * @return boolean |
|
412 | + */ |
|
413 | + private function subArrayKeyIsUnaryOperator($sub_array_key) |
|
414 | + { |
|
415 | + return array_key_exists( |
|
416 | + $sub_array_key, |
|
417 | + $this->getContext()->getModel()->valid_null_style_operators() |
|
418 | + ); |
|
419 | + } |
|
420 | + |
|
421 | + /** |
|
422 | + * Parses the $sub_array_value string into an array (given it could either be a comma-separated-list or a JSON |
|
423 | + * array). eg `"1,2,3"` or `"[1,2,3]"` into `array(1,2,3)`. |
|
424 | + * @since 4.9.72.p |
|
425 | + * @param $sub_array_value |
|
426 | + * @return array|mixed|object |
|
427 | + */ |
|
428 | + private function extractQuickStyleSpecifiedOperatorValue($sub_array_value) |
|
429 | + { |
|
430 | + // the value should be JSON or CSV |
|
431 | + $values = json_decode($sub_array_value); |
|
432 | + if (!is_array($values)) { |
|
433 | + $values = array_filter( |
|
434 | + array_map( |
|
435 | + 'trim', |
|
436 | + explode( |
|
437 | + ',', |
|
438 | + $sub_array_value |
|
439 | + ) |
|
440 | + ) |
|
441 | + ); |
|
442 | + } |
|
443 | + return $values; |
|
444 | + } |
|
445 | + |
|
446 | + /** |
|
447 | + * Throws an exception if the value isn't a simplified specified operator (only called when we expect that). |
|
448 | + * @since 4.9.72.p |
|
449 | + * @throws RestException |
|
450 | + */ |
|
451 | + private function assertSimplifiedSpecifiedOperator() |
|
452 | + { |
|
453 | + if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) { |
|
454 | + throw new RestException( |
|
455 | + 'numerically_indexed_array_of_values_only', |
|
456 | + sprintf( |
|
457 | + /* translators: 1: variable name*/ |
|
458 | + esc_html__( |
|
459 | + 'The array provided for the parameter "%1$s" should be numerically indexed.', |
|
460 | + 'event_espresso' |
|
461 | + ), |
|
462 | + $this->getQueryParamKey() |
|
463 | + ), |
|
464 | + array( |
|
465 | + 'status' => 400, |
|
466 | + ) |
|
467 | + ); |
|
468 | + } |
|
469 | + } |
|
470 | + |
|
471 | + /** |
|
472 | + * If query_param_value were in the simplified specific operator structure, change it into the legacy structure. |
|
473 | + * @since 4.9.72.p |
|
474 | + * @throws RestException |
|
475 | + */ |
|
476 | + private function transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax() |
|
477 | + { |
|
478 | + if ($this->valueIsAssociativeArray()) { |
|
479 | + $this->assertSimplifiedSpecifiedOperator(); |
|
480 | + $query_param_value = $this->getQueryParamValue(); |
|
481 | + $sub_array_value = reset($query_param_value); |
|
482 | + $sub_array_key = key($query_param_value); |
|
483 | + $this->assertSubValueIsntArray($sub_array_key, $sub_array_value); |
|
484 | + // they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5" |
|
485 | + if ($this->subArrayKeyIsNonBinaryOperator($sub_array_key)) { |
|
486 | + $this->setQueryParamValue(array( |
|
487 | + $sub_array_key, |
|
488 | + $this->extractQuickStyleSpecifiedOperatorValue($sub_array_value) |
|
489 | + )); |
|
490 | + } elseif ($this->subArrayKeyIsUnaryOperator($sub_array_key)) { |
|
491 | + $this->setQueryParamValue(array($sub_array_key)); |
|
492 | + } else { |
|
493 | + $this->setQueryParamValue(array($sub_array_key, $sub_array_value)); |
|
494 | + } |
|
495 | + } |
|
496 | + } |
|
497 | + |
|
498 | + /** |
|
499 | + * Returns true is the value is an array using the legacy structure to specify the operator. Eg `array('!=',123)`. |
|
500 | + * @since 4.9.72.p |
|
501 | + * @return boolean |
|
502 | + */ |
|
503 | + private function valueIsLegacySpecifiedOperator() |
|
504 | + { |
|
505 | + $valid_operators = $this->getContext()->getModel()->valid_operators(); |
|
506 | + $query_param_value = $this->getQueryParamValue(); |
|
507 | + return isset($query_param_value[0]) |
|
508 | + && isset($valid_operators[ $query_param_value[0] ]); |
|
509 | + } |
|
510 | + |
|
511 | + /** |
|
512 | + * Returns true if the value specified operator accepts arbitrary number of arguments, like "IN". |
|
513 | + * @since 4.9.72.p |
|
514 | + * @param $operator |
|
515 | + * @return boolean |
|
516 | + */ |
|
517 | + private function operatorIsNAry($operator) |
|
518 | + { |
|
519 | + $valueArray = $this->getQueryParamValue(); |
|
520 | + return array_key_exists( |
|
521 | + $operator, |
|
522 | + $this->getContext()->getModel()->valid_in_style_operators() |
|
523 | + ) |
|
524 | + && isset($valueArray[1]) |
|
525 | + && is_array($valueArray[1]) |
|
526 | + && !isset($valueArray[2]); |
|
527 | + } |
|
528 | + |
|
529 | + /** |
|
530 | + * Returns true if the operator accepts 3 arguments (eg "BETWEEN"). |
|
531 | + * So we're looking for a value that looks like |
|
532 | + * `array('BETWEEN', array('2015-01-01T00:00:00', '2016-01-01T00:00:00'))`. |
|
533 | + * @since 4.9.72.p |
|
534 | + * @param $operator |
|
535 | + * @return boolean |
|
536 | + */ |
|
537 | + private function operatorIsTernary($operator) |
|
538 | + { |
|
539 | + $query_param_value = $this->getQueryParamValue(); |
|
540 | + return array_key_exists($operator, $this->getContext()->getModel()->valid_between_style_operators()) |
|
541 | + && isset($query_param_value[1]) |
|
542 | + && is_array($query_param_value[1]) |
|
543 | + && isset($query_param_value[1][0], $query_param_value[1][1]) |
|
544 | + && !isset($query_param_value[1][2]) |
|
545 | + && !isset($query_param_value[2]); |
|
546 | + } |
|
547 | + |
|
548 | + /** |
|
549 | + * Returns true if the operator is a similar to LIKE, indicating the value may have wildcards we should leave alone. |
|
550 | + * @since 4.9.72.p |
|
551 | + * @param $operator |
|
552 | + * @return boolean |
|
553 | + */ |
|
554 | + private function operatorIsLike($operator) |
|
555 | + { |
|
556 | + $query_param_value = $this->getQueryParamValue(); |
|
557 | + return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators()) |
|
558 | + && isset($query_param_value[1]) |
|
559 | + && !isset($query_param_value[2]); |
|
560 | + } |
|
561 | + |
|
562 | + /** |
|
563 | + * Returns true if the operator only takes one argument (eg it's like `IS NULL`). |
|
564 | + * @since 4.9.72.p |
|
565 | + * @param $operator |
|
566 | + * @return boolean |
|
567 | + */ |
|
568 | + private function operatorIsUnary($operator) |
|
569 | + { |
|
570 | + $query_param_value = $this->getQueryParamValue(); |
|
571 | + return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators()) |
|
572 | + && !isset($query_param_value[1]); |
|
573 | + } |
|
574 | + |
|
575 | + /** |
|
576 | + * Returns true if the operator specified is a binary opeator (eg `=`, `!=`) |
|
577 | + * @since 4.9.72.p |
|
578 | + * @param $operator |
|
579 | + * @return boolean |
|
580 | + */ |
|
581 | + private function operatorisBinary($operator) |
|
582 | + { |
|
583 | + $query_param_value = $this->getQueryParamValue(); |
|
584 | + $model = $this->getContext()->getModel(); |
|
585 | + return isset($query_param_value[1]) |
|
586 | + && !isset($query_param_value[2]) |
|
587 | + && !array_key_exists( |
|
588 | + $operator, |
|
589 | + array_merge( |
|
590 | + $model->valid_in_style_operators(), |
|
591 | + $model->valid_null_style_operators(), |
|
592 | + $model->valid_like_style_operators(), |
|
593 | + $model->valid_between_style_operators() |
|
594 | + ) |
|
595 | + ); |
|
596 | + } |
|
597 | + |
|
598 | + /** |
|
599 | + * If we're debugging, throws an exception saying that the wrong number of arguments was provided. |
|
600 | + * @since 4.9.72.p |
|
601 | + * @param $operator |
|
602 | + * @throws RestException |
|
603 | + */ |
|
604 | + private function throwWrongNumberOfArgsExceptionIfDebugging($operator) |
|
605 | + { |
|
606 | + if (EED_Core_Rest_Api::debugMode()) { |
|
607 | + throw new RestException( |
|
608 | + 'wrong_number_of_arguments', |
|
609 | + sprintf( |
|
610 | + esc_html__( |
|
611 | + 'The operator you provided, "%1$s" had the wrong number of arguments', |
|
612 | + 'event_espresso' |
|
613 | + ), |
|
614 | + $operator |
|
615 | + ), |
|
616 | + array( |
|
617 | + 'status' => 400, |
|
618 | + ) |
|
619 | + ); |
|
620 | + } |
|
621 | + } |
|
622 | + |
|
623 | + /** |
|
624 | + * Wrapper for ModelDataTranslator::prepareFieldValuesFromJson(), just a tad more DRY. |
|
625 | + * @since 4.9.72.p |
|
626 | + * @param $value |
|
627 | + * @return mixed |
|
628 | + * @throws RestException |
|
629 | + */ |
|
630 | + private function prepareValuesFromJson($value) |
|
631 | + { |
|
632 | + return ModelDataTranslator::prepareFieldValuesFromJson( |
|
633 | + $this->getField(), |
|
634 | + $value, |
|
635 | + $this->getContext()->getRequestedVersion(), |
|
636 | + $this->getTimezone() |
|
637 | + ); |
|
638 | + } |
|
639 | + |
|
640 | + /** |
|
641 | + * Throws an exception if an invalid operator was specified and we're debugging. |
|
642 | + * @since 4.9.72.p |
|
643 | + * @throws RestException |
|
644 | + */ |
|
645 | + private function throwInvalidOperatorExceptionIfDebugging() |
|
646 | + { |
|
647 | + // so they didn't provide a valid operator |
|
648 | + if (EED_Core_Rest_Api::debugMode()) { |
|
649 | + throw new RestException( |
|
650 | + 'invalid_operator', |
|
651 | + sprintf( |
|
652 | + esc_html__( |
|
653 | + 'You provided an invalid parameter, with key "%1$s" and value "%2$s"', |
|
654 | + 'event_espresso' |
|
655 | + ), |
|
656 | + $this->getQueryParamKey(), |
|
657 | + $this->getQueryParamValue() |
|
658 | + ), |
|
659 | + array( |
|
660 | + 'status' => 400, |
|
661 | + ) |
|
662 | + ); |
|
663 | + } |
|
664 | + } |
|
665 | + |
|
666 | + /** |
|
667 | + * Returns true if the query_param_key was a logic query parameter, eg `OR`, `AND`, `NOT`, `OR*`, etc. |
|
668 | + * @since 4.9.72.p |
|
669 | + * @return boolean |
|
670 | + */ |
|
671 | + private function isLogicQueryParam() |
|
672 | + { |
|
673 | + return in_array($this->getQueryParamKeySansStars(), $this->getContext()->getModel()->logic_query_param_keys()); |
|
674 | + } |
|
675 | + |
|
676 | + |
|
677 | + /** |
|
678 | + * If the query param isn't for a field, it must be a nested query parameter which requires different logic. |
|
679 | + * @since 4.9.72.p |
|
680 | + * @return array |
|
681 | + * @throws DomainException |
|
682 | + * @throws EE_Error |
|
683 | + * @throws RestException |
|
684 | + * @throws InvalidDataTypeException |
|
685 | + * @throws InvalidInterfaceException |
|
686 | + * @throws InvalidArgumentException |
|
687 | + */ |
|
688 | + public function determineNestedConditionQueryParameters() |
|
689 | + { |
|
690 | + |
|
691 | + // so this param doesn't correspond to a field eh? |
|
692 | + if ($this->getContext()->isWriting()) { |
|
693 | + // always tell API clients about invalid parameters when they're creating data. Otherwise, |
|
694 | + // they are probably going to create invalid data |
|
695 | + throw new RestException( |
|
696 | + 'invalid_field', |
|
697 | + sprintf( |
|
698 | + /* translators: 1: variable name */ |
|
699 | + esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'), |
|
700 | + $this->getQueryParamKey() |
|
701 | + ) |
|
702 | + ); |
|
703 | + } |
|
704 | + // so it's not for a field, is it a logic query param key? |
|
705 | + if ($this->isLogicQueryParam()) { |
|
706 | + return ModelDataTranslator::prepareConditionsQueryParamsForModels( |
|
707 | + $this->getQueryParamValue(), |
|
708 | + $this->getContext()->getModel(), |
|
709 | + $this->getContext()->getRequestedVersion() |
|
710 | + ); |
|
711 | + } |
|
712 | + if (EED_Core_Rest_Api::debugMode()) { |
|
713 | + // only tell API clients they got it wrong if we're in debug mode |
|
714 | + // otherwise try our best ot fulfill their request by ignoring this invalid data |
|
715 | + throw new RestException( |
|
716 | + 'invalid_parameter', |
|
717 | + sprintf( |
|
718 | + /* translators: 1: variable name */ |
|
719 | + esc_html__( |
|
720 | + 'You provided an invalid parameter, with key "%1$s"', |
|
721 | + 'event_espresso' |
|
722 | + ), |
|
723 | + $this->getQueryParamKey() |
|
724 | + ), |
|
725 | + array( |
|
726 | + 'status' => 400, |
|
727 | + ) |
|
728 | + ); |
|
729 | + } |
|
730 | + return null; |
|
731 | + } |
|
732 | 732 | } |
733 | 733 | // End of file RestQueryParamMetadata.php |
734 | 734 | // Location: EventEspresso\core\libraries\rest_api/RestQueryParamMetadata.php |
@@ -209,7 +209,7 @@ discard block |
||
209 | 209 | )); |
210 | 210 | // double-check is it a *_gmt field? |
211 | 211 | if ( |
212 | - !$this->getField() instanceof EE_Model_Field_Base |
|
212 | + ! $this->getField() instanceof EE_Model_Field_Base |
|
213 | 213 | && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars()) |
214 | 214 | ) { |
215 | 215 | // yep, take off '_gmt', and find the field |
@@ -330,7 +330,7 @@ discard block |
||
330 | 330 | */ |
331 | 331 | private function valueIsArrayDuringRead() |
332 | 332 | { |
333 | - return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue()); |
|
333 | + return ! $this->getContext()->isWriting() && is_array($this->getQueryParamValue()); |
|
334 | 334 | } |
335 | 335 | |
336 | 336 | /** |
@@ -341,7 +341,7 @@ discard block |
||
341 | 341 | */ |
342 | 342 | private function valueIsAssociativeArray() |
343 | 343 | { |
344 | - return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue()); |
|
344 | + return ! EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue()); |
|
345 | 345 | } |
346 | 346 | |
347 | 347 | /** |
@@ -429,7 +429,7 @@ discard block |
||
429 | 429 | { |
430 | 430 | // the value should be JSON or CSV |
431 | 431 | $values = json_decode($sub_array_value); |
432 | - if (!is_array($values)) { |
|
432 | + if ( ! is_array($values)) { |
|
433 | 433 | $values = array_filter( |
434 | 434 | array_map( |
435 | 435 | 'trim', |
@@ -450,7 +450,7 @@ discard block |
||
450 | 450 | */ |
451 | 451 | private function assertSimplifiedSpecifiedOperator() |
452 | 452 | { |
453 | - if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) { |
|
453 | + if ( ! $this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) { |
|
454 | 454 | throw new RestException( |
455 | 455 | 'numerically_indexed_array_of_values_only', |
456 | 456 | sprintf( |
@@ -505,7 +505,7 @@ discard block |
||
505 | 505 | $valid_operators = $this->getContext()->getModel()->valid_operators(); |
506 | 506 | $query_param_value = $this->getQueryParamValue(); |
507 | 507 | return isset($query_param_value[0]) |
508 | - && isset($valid_operators[ $query_param_value[0] ]); |
|
508 | + && isset($valid_operators[$query_param_value[0]]); |
|
509 | 509 | } |
510 | 510 | |
511 | 511 | /** |
@@ -523,7 +523,7 @@ discard block |
||
523 | 523 | ) |
524 | 524 | && isset($valueArray[1]) |
525 | 525 | && is_array($valueArray[1]) |
526 | - && !isset($valueArray[2]); |
|
526 | + && ! isset($valueArray[2]); |
|
527 | 527 | } |
528 | 528 | |
529 | 529 | /** |
@@ -541,8 +541,8 @@ discard block |
||
541 | 541 | && isset($query_param_value[1]) |
542 | 542 | && is_array($query_param_value[1]) |
543 | 543 | && isset($query_param_value[1][0], $query_param_value[1][1]) |
544 | - && !isset($query_param_value[1][2]) |
|
545 | - && !isset($query_param_value[2]); |
|
544 | + && ! isset($query_param_value[1][2]) |
|
545 | + && ! isset($query_param_value[2]); |
|
546 | 546 | } |
547 | 547 | |
548 | 548 | /** |
@@ -556,7 +556,7 @@ discard block |
||
556 | 556 | $query_param_value = $this->getQueryParamValue(); |
557 | 557 | return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators()) |
558 | 558 | && isset($query_param_value[1]) |
559 | - && !isset($query_param_value[2]); |
|
559 | + && ! isset($query_param_value[2]); |
|
560 | 560 | } |
561 | 561 | |
562 | 562 | /** |
@@ -569,7 +569,7 @@ discard block |
||
569 | 569 | { |
570 | 570 | $query_param_value = $this->getQueryParamValue(); |
571 | 571 | return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators()) |
572 | - && !isset($query_param_value[1]); |
|
572 | + && ! isset($query_param_value[1]); |
|
573 | 573 | } |
574 | 574 | |
575 | 575 | /** |
@@ -583,8 +583,8 @@ discard block |
||
583 | 583 | $query_param_value = $this->getQueryParamValue(); |
584 | 584 | $model = $this->getContext()->getModel(); |
585 | 585 | return isset($query_param_value[1]) |
586 | - && !isset($query_param_value[2]) |
|
587 | - && !array_key_exists( |
|
586 | + && ! isset($query_param_value[2]) |
|
587 | + && ! array_key_exists( |
|
588 | 588 | $operator, |
589 | 589 | array_merge( |
590 | 590 | $model->valid_in_style_operators(), |
@@ -12,39 +12,39 @@ |
||
12 | 12 | class ChangesIn40834 extends ChangesInBase |
13 | 13 | { |
14 | 14 | |
15 | - /** |
|
16 | - * Adds hooks so requests to 4.8.29 don't have the checkin endpoints |
|
17 | - */ |
|
18 | - public function setHooks() |
|
19 | - { |
|
20 | - // set a hook to remove the checkout/checkout endpoints if the request |
|
21 | - // is for lower than 4.8.33 |
|
22 | - add_filter( |
|
23 | - 'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers', |
|
24 | - array($this, 'removeResponseHeaders'), |
|
25 | - 10, |
|
26 | - 3 |
|
27 | - ); |
|
28 | - } |
|
15 | + /** |
|
16 | + * Adds hooks so requests to 4.8.29 don't have the checkin endpoints |
|
17 | + */ |
|
18 | + public function setHooks() |
|
19 | + { |
|
20 | + // set a hook to remove the checkout/checkout endpoints if the request |
|
21 | + // is for lower than 4.8.33 |
|
22 | + add_filter( |
|
23 | + 'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers', |
|
24 | + array($this, 'removeResponseHeaders'), |
|
25 | + 10, |
|
26 | + 3 |
|
27 | + ); |
|
28 | + } |
|
29 | 29 | |
30 | 30 | |
31 | - /** |
|
32 | - * Removes the checkin and checkout endpoints from the index for requests |
|
33 | - * to api versions lowers than 4.8.33 |
|
34 | - * |
|
35 | - * @param array $response_headers |
|
36 | - * @param Base $controller |
|
37 | - * @param string $requested_version |
|
38 | - * @return array like $routes_on_this_version |
|
39 | - */ |
|
40 | - public function removeResponseHeaders($response_headers, $controller, $requested_version) |
|
41 | - { |
|
42 | - if ( |
|
43 | - $controller instanceof Base |
|
44 | - && $this->appliesToVersion($requested_version) |
|
45 | - ) { |
|
46 | - return array(); |
|
47 | - } |
|
48 | - return $response_headers; |
|
49 | - } |
|
31 | + /** |
|
32 | + * Removes the checkin and checkout endpoints from the index for requests |
|
33 | + * to api versions lowers than 4.8.33 |
|
34 | + * |
|
35 | + * @param array $response_headers |
|
36 | + * @param Base $controller |
|
37 | + * @param string $requested_version |
|
38 | + * @return array like $routes_on_this_version |
|
39 | + */ |
|
40 | + public function removeResponseHeaders($response_headers, $controller, $requested_version) |
|
41 | + { |
|
42 | + if ( |
|
43 | + $controller instanceof Base |
|
44 | + && $this->appliesToVersion($requested_version) |
|
45 | + ) { |
|
46 | + return array(); |
|
47 | + } |
|
48 | + return $response_headers; |
|
49 | + } |
|
50 | 50 | } |
@@ -57,7 +57,7 @@ discard block |
||
57 | 57 | */ |
58 | 58 | public function mapping($refresh = false) |
59 | 59 | { |
60 | - if (! $this->mapping || $refresh) { |
|
60 | + if ( ! $this->mapping || $refresh) { |
|
61 | 61 | $this->mapping = $this->generateNewMapping(); |
62 | 62 | } |
63 | 63 | return $this->mapping; |
@@ -81,7 +81,7 @@ discard block |
||
81 | 81 | foreach ($models_with_calculated_fields as $model_name) { |
82 | 82 | $calculator = $this->factory->createFromModel($model_name); |
83 | 83 | foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) { |
84 | - $mapping[ $model_name ][ $field_name ] = get_class($calculator); |
|
84 | + $mapping[$model_name][$field_name] = get_class($calculator); |
|
85 | 85 | } |
86 | 86 | } |
87 | 87 | return apply_filters( |
@@ -108,8 +108,8 @@ discard block |
||
108 | 108 | foreach ($map_for_model as $calculation_index => $calculations_class) { |
109 | 109 | $calculator = $this->factory->createFromClassname($calculations_class); |
110 | 110 | $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index); |
111 | - if (! empty($schema)) { |
|
112 | - $schema_map[ $map_model ][ $calculation_index ] = $schema; |
|
111 | + if ( ! empty($schema)) { |
|
112 | + $schema_map[$map_model][$calculation_index] = $schema; |
|
113 | 113 | } |
114 | 114 | } |
115 | 115 | } |
@@ -126,8 +126,8 @@ discard block |
||
126 | 126 | public function retrieveCalculatedFieldsForModel(EEM_Base $model) |
127 | 127 | { |
128 | 128 | $mapping = $this->mapping(); |
129 | - if (isset($mapping[ $model->get_this_model_name() ])) { |
|
130 | - return array_keys($mapping[ $model->get_this_model_name() ]); |
|
129 | + if (isset($mapping[$model->get_this_model_name()])) { |
|
130 | + return array_keys($mapping[$model->get_this_model_name()]); |
|
131 | 131 | } |
132 | 132 | return array(); |
133 | 133 | } |
@@ -140,7 +140,7 @@ discard block |
||
140 | 140 | */ |
141 | 141 | public function getJsonSchemaForModel(EEM_Base $model) |
142 | 142 | { |
143 | - if (! $this->mapping_schema) { |
|
143 | + if ( ! $this->mapping_schema) { |
|
144 | 144 | $this->mapping_schema = $this->generateNewMappingSchema(); |
145 | 145 | } |
146 | 146 | return array( |
@@ -149,8 +149,8 @@ discard block |
||
149 | 149 | 'event_espresso' |
150 | 150 | ), |
151 | 151 | 'type' => 'object', |
152 | - 'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ]) |
|
153 | - ? $this->mapping_schema[ $model->get_this_model_name() ] |
|
152 | + 'properties' => isset($this->mapping_schema[$model->get_this_model_name()]) |
|
153 | + ? $this->mapping_schema[$model->get_this_model_name()] |
|
154 | 154 | : array(), |
155 | 155 | 'additionalProperties' => false, |
156 | 156 | 'readonly' => true, |
@@ -179,10 +179,10 @@ discard block |
||
179 | 179 | ) { |
180 | 180 | $mapping = $this->mapping(); |
181 | 181 | if ( |
182 | - isset($mapping[ $model->get_this_model_name() ]) |
|
183 | - && isset($mapping[ $model->get_this_model_name() ][ $field_name ]) |
|
182 | + isset($mapping[$model->get_this_model_name()]) |
|
183 | + && isset($mapping[$model->get_this_model_name()][$field_name]) |
|
184 | 184 | ) { |
185 | - $classname = $mapping[ $model->get_this_model_name() ][ $field_name ]; |
|
185 | + $classname = $mapping[$model->get_this_model_name()][$field_name]; |
|
186 | 186 | $calculator = $this->factory->createFromClassname($classname); |
187 | 187 | $class_method_name = EEH_Inflector::camelize_all_but_first($field_name); |
188 | 188 | return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller); |
@@ -21,178 +21,178 @@ |
||
21 | 21 | */ |
22 | 22 | class CalculatedModelFields |
23 | 23 | { |
24 | - /** |
|
25 | - * @var array |
|
26 | - */ |
|
27 | - protected $mapping; |
|
28 | - |
|
29 | - /** |
|
30 | - * @var array |
|
31 | - */ |
|
32 | - protected $mapping_schema; |
|
33 | - |
|
34 | - /** |
|
35 | - * @var CalculatedModelFieldsFactory |
|
36 | - */ |
|
37 | - private $factory; |
|
38 | - |
|
39 | - /** |
|
40 | - * CalculatedModelFields constructor. |
|
41 | - * @param CalculatedModelFieldsFactory $factory |
|
42 | - */ |
|
43 | - public function __construct(CalculatedModelFieldsFactory $factory) |
|
44 | - { |
|
45 | - $this->factory = $factory; |
|
46 | - } |
|
47 | - /** |
|
48 | - * @param bool $refresh |
|
49 | - * @return array top-level-keys are model names (eg "Event") |
|
50 | - * next-level are the calculated field names AND method names on classes |
|
51 | - * which perform calculations, values are the fully qualified classnames which do the calculations |
|
52 | - * These callbacks should accept as arguments: |
|
53 | - * the wpdb row results, |
|
54 | - * the WP_Request object, |
|
55 | - * the controller object |
|
56 | - */ |
|
57 | - public function mapping($refresh = false) |
|
58 | - { |
|
59 | - if (! $this->mapping || $refresh) { |
|
60 | - $this->mapping = $this->generateNewMapping(); |
|
61 | - } |
|
62 | - return $this->mapping; |
|
63 | - } |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * Generates a new mapping between model calculated fields and their callbacks |
|
68 | - * |
|
69 | - * @return array |
|
70 | - */ |
|
71 | - protected function generateNewMapping() |
|
72 | - { |
|
73 | - $mapping = array(); |
|
74 | - $models_with_calculated_fields = array( |
|
75 | - 'Attendee', |
|
76 | - 'Datetime', |
|
77 | - 'Event', |
|
78 | - 'Registration' |
|
79 | - ); |
|
80 | - foreach ($models_with_calculated_fields as $model_name) { |
|
81 | - $calculator = $this->factory->createFromModel($model_name); |
|
82 | - foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) { |
|
83 | - $mapping[ $model_name ][ $field_name ] = get_class($calculator); |
|
84 | - } |
|
85 | - } |
|
86 | - return apply_filters( |
|
87 | - 'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping', |
|
88 | - $mapping |
|
89 | - ); |
|
90 | - } |
|
91 | - |
|
92 | - |
|
93 | - /** |
|
94 | - * Generates the schema for each calculation index in the calculation map. |
|
95 | - * |
|
96 | - * @return array |
|
97 | - * @throws UnexpectedEntityException |
|
98 | - */ |
|
99 | - protected function generateNewMappingSchema() |
|
100 | - { |
|
101 | - $schema_map = array(); |
|
102 | - foreach ($this->mapping() as $map_model => $map_for_model) { |
|
103 | - /** |
|
104 | - * @var string $calculation_index |
|
105 | - * @var string $calculations_class |
|
106 | - */ |
|
107 | - foreach ($map_for_model as $calculation_index => $calculations_class) { |
|
108 | - $calculator = $this->factory->createFromClassname($calculations_class); |
|
109 | - $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index); |
|
110 | - if (! empty($schema)) { |
|
111 | - $schema_map[ $map_model ][ $calculation_index ] = $schema; |
|
112 | - } |
|
113 | - } |
|
114 | - } |
|
115 | - return $schema_map; |
|
116 | - } |
|
117 | - |
|
118 | - |
|
119 | - /** |
|
120 | - * Gets the known calculated fields for model |
|
121 | - * |
|
122 | - * @param EEM_Base $model |
|
123 | - * @return array allowable values for this field |
|
124 | - */ |
|
125 | - public function retrieveCalculatedFieldsForModel(EEM_Base $model) |
|
126 | - { |
|
127 | - $mapping = $this->mapping(); |
|
128 | - if (isset($mapping[ $model->get_this_model_name() ])) { |
|
129 | - return array_keys($mapping[ $model->get_this_model_name() ]); |
|
130 | - } |
|
131 | - return array(); |
|
132 | - } |
|
133 | - |
|
134 | - |
|
135 | - /** |
|
136 | - * Returns the JsonSchema for the calculated fields on the given model. |
|
137 | - * @param EEM_Base $model |
|
138 | - * @return array |
|
139 | - */ |
|
140 | - public function getJsonSchemaForModel(EEM_Base $model) |
|
141 | - { |
|
142 | - if (! $this->mapping_schema) { |
|
143 | - $this->mapping_schema = $this->generateNewMappingSchema(); |
|
144 | - } |
|
145 | - return array( |
|
146 | - 'description' => esc_html__( |
|
147 | - 'Available calculated fields for this model. Fields are only present in the response if explicitly requested', |
|
148 | - 'event_espresso' |
|
149 | - ), |
|
150 | - 'type' => 'object', |
|
151 | - 'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ]) |
|
152 | - ? $this->mapping_schema[ $model->get_this_model_name() ] |
|
153 | - : array(), |
|
154 | - 'additionalProperties' => false, |
|
155 | - 'readonly' => true, |
|
156 | - ); |
|
157 | - } |
|
158 | - |
|
159 | - |
|
160 | - /** |
|
161 | - * Retrieves the value for this calculation |
|
162 | - * |
|
163 | - * @param EEM_Base $model |
|
164 | - * @param string $field_name |
|
165 | - * @param array $wpdb_row |
|
166 | - * @param $rest_request |
|
167 | - * @param BaseController $controller |
|
168 | - * @return mixed|null |
|
169 | - * @throws RestException |
|
170 | - * @throws UnexpectedEntityException |
|
171 | - */ |
|
172 | - public function retrieveCalculatedFieldValue( |
|
173 | - EEM_Base $model, |
|
174 | - $field_name, |
|
175 | - $wpdb_row, |
|
176 | - $rest_request, |
|
177 | - Base $controller |
|
178 | - ) { |
|
179 | - $mapping = $this->mapping(); |
|
180 | - if ( |
|
181 | - isset($mapping[ $model->get_this_model_name() ]) |
|
182 | - && isset($mapping[ $model->get_this_model_name() ][ $field_name ]) |
|
183 | - ) { |
|
184 | - $classname = $mapping[ $model->get_this_model_name() ][ $field_name ]; |
|
185 | - $calculator = $this->factory->createFromClassname($classname); |
|
186 | - $class_method_name = EEH_Inflector::camelize_all_but_first($field_name); |
|
187 | - return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller); |
|
188 | - } |
|
189 | - throw new RestException( |
|
190 | - 'calculated_field_does_not_exist', |
|
191 | - sprintf( |
|
192 | - esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'), |
|
193 | - $field_name, |
|
194 | - $model->get_this_model_name() |
|
195 | - ) |
|
196 | - ); |
|
197 | - } |
|
24 | + /** |
|
25 | + * @var array |
|
26 | + */ |
|
27 | + protected $mapping; |
|
28 | + |
|
29 | + /** |
|
30 | + * @var array |
|
31 | + */ |
|
32 | + protected $mapping_schema; |
|
33 | + |
|
34 | + /** |
|
35 | + * @var CalculatedModelFieldsFactory |
|
36 | + */ |
|
37 | + private $factory; |
|
38 | + |
|
39 | + /** |
|
40 | + * CalculatedModelFields constructor. |
|
41 | + * @param CalculatedModelFieldsFactory $factory |
|
42 | + */ |
|
43 | + public function __construct(CalculatedModelFieldsFactory $factory) |
|
44 | + { |
|
45 | + $this->factory = $factory; |
|
46 | + } |
|
47 | + /** |
|
48 | + * @param bool $refresh |
|
49 | + * @return array top-level-keys are model names (eg "Event") |
|
50 | + * next-level are the calculated field names AND method names on classes |
|
51 | + * which perform calculations, values are the fully qualified classnames which do the calculations |
|
52 | + * These callbacks should accept as arguments: |
|
53 | + * the wpdb row results, |
|
54 | + * the WP_Request object, |
|
55 | + * the controller object |
|
56 | + */ |
|
57 | + public function mapping($refresh = false) |
|
58 | + { |
|
59 | + if (! $this->mapping || $refresh) { |
|
60 | + $this->mapping = $this->generateNewMapping(); |
|
61 | + } |
|
62 | + return $this->mapping; |
|
63 | + } |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * Generates a new mapping between model calculated fields and their callbacks |
|
68 | + * |
|
69 | + * @return array |
|
70 | + */ |
|
71 | + protected function generateNewMapping() |
|
72 | + { |
|
73 | + $mapping = array(); |
|
74 | + $models_with_calculated_fields = array( |
|
75 | + 'Attendee', |
|
76 | + 'Datetime', |
|
77 | + 'Event', |
|
78 | + 'Registration' |
|
79 | + ); |
|
80 | + foreach ($models_with_calculated_fields as $model_name) { |
|
81 | + $calculator = $this->factory->createFromModel($model_name); |
|
82 | + foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) { |
|
83 | + $mapping[ $model_name ][ $field_name ] = get_class($calculator); |
|
84 | + } |
|
85 | + } |
|
86 | + return apply_filters( |
|
87 | + 'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping', |
|
88 | + $mapping |
|
89 | + ); |
|
90 | + } |
|
91 | + |
|
92 | + |
|
93 | + /** |
|
94 | + * Generates the schema for each calculation index in the calculation map. |
|
95 | + * |
|
96 | + * @return array |
|
97 | + * @throws UnexpectedEntityException |
|
98 | + */ |
|
99 | + protected function generateNewMappingSchema() |
|
100 | + { |
|
101 | + $schema_map = array(); |
|
102 | + foreach ($this->mapping() as $map_model => $map_for_model) { |
|
103 | + /** |
|
104 | + * @var string $calculation_index |
|
105 | + * @var string $calculations_class |
|
106 | + */ |
|
107 | + foreach ($map_for_model as $calculation_index => $calculations_class) { |
|
108 | + $calculator = $this->factory->createFromClassname($calculations_class); |
|
109 | + $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index); |
|
110 | + if (! empty($schema)) { |
|
111 | + $schema_map[ $map_model ][ $calculation_index ] = $schema; |
|
112 | + } |
|
113 | + } |
|
114 | + } |
|
115 | + return $schema_map; |
|
116 | + } |
|
117 | + |
|
118 | + |
|
119 | + /** |
|
120 | + * Gets the known calculated fields for model |
|
121 | + * |
|
122 | + * @param EEM_Base $model |
|
123 | + * @return array allowable values for this field |
|
124 | + */ |
|
125 | + public function retrieveCalculatedFieldsForModel(EEM_Base $model) |
|
126 | + { |
|
127 | + $mapping = $this->mapping(); |
|
128 | + if (isset($mapping[ $model->get_this_model_name() ])) { |
|
129 | + return array_keys($mapping[ $model->get_this_model_name() ]); |
|
130 | + } |
|
131 | + return array(); |
|
132 | + } |
|
133 | + |
|
134 | + |
|
135 | + /** |
|
136 | + * Returns the JsonSchema for the calculated fields on the given model. |
|
137 | + * @param EEM_Base $model |
|
138 | + * @return array |
|
139 | + */ |
|
140 | + public function getJsonSchemaForModel(EEM_Base $model) |
|
141 | + { |
|
142 | + if (! $this->mapping_schema) { |
|
143 | + $this->mapping_schema = $this->generateNewMappingSchema(); |
|
144 | + } |
|
145 | + return array( |
|
146 | + 'description' => esc_html__( |
|
147 | + 'Available calculated fields for this model. Fields are only present in the response if explicitly requested', |
|
148 | + 'event_espresso' |
|
149 | + ), |
|
150 | + 'type' => 'object', |
|
151 | + 'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ]) |
|
152 | + ? $this->mapping_schema[ $model->get_this_model_name() ] |
|
153 | + : array(), |
|
154 | + 'additionalProperties' => false, |
|
155 | + 'readonly' => true, |
|
156 | + ); |
|
157 | + } |
|
158 | + |
|
159 | + |
|
160 | + /** |
|
161 | + * Retrieves the value for this calculation |
|
162 | + * |
|
163 | + * @param EEM_Base $model |
|
164 | + * @param string $field_name |
|
165 | + * @param array $wpdb_row |
|
166 | + * @param $rest_request |
|
167 | + * @param BaseController $controller |
|
168 | + * @return mixed|null |
|
169 | + * @throws RestException |
|
170 | + * @throws UnexpectedEntityException |
|
171 | + */ |
|
172 | + public function retrieveCalculatedFieldValue( |
|
173 | + EEM_Base $model, |
|
174 | + $field_name, |
|
175 | + $wpdb_row, |
|
176 | + $rest_request, |
|
177 | + Base $controller |
|
178 | + ) { |
|
179 | + $mapping = $this->mapping(); |
|
180 | + if ( |
|
181 | + isset($mapping[ $model->get_this_model_name() ]) |
|
182 | + && isset($mapping[ $model->get_this_model_name() ][ $field_name ]) |
|
183 | + ) { |
|
184 | + $classname = $mapping[ $model->get_this_model_name() ][ $field_name ]; |
|
185 | + $calculator = $this->factory->createFromClassname($classname); |
|
186 | + $class_method_name = EEH_Inflector::camelize_all_but_first($field_name); |
|
187 | + return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller); |
|
188 | + } |
|
189 | + throw new RestException( |
|
190 | + 'calculated_field_does_not_exist', |
|
191 | + sprintf( |
|
192 | + esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'), |
|
193 | + $field_name, |
|
194 | + $model->get_this_model_name() |
|
195 | + ) |
|
196 | + ); |
|
197 | + } |
|
198 | 198 | } |