@@ -36,16 +36,16 @@ discard block |
||
36 | 36 | */ |
37 | 37 | protected function __construct($fieldValues = null, $bydb = false, $timezone = null, $date_formats = array()) |
38 | 38 | { |
39 | - if (! isset($fieldValues['ATT_full_name'])) { |
|
40 | - $fname = isset($fieldValues['ATT_fname']) ? $fieldValues['ATT_fname'] . ' ' : ''; |
|
39 | + if ( ! isset($fieldValues['ATT_full_name'])) { |
|
40 | + $fname = isset($fieldValues['ATT_fname']) ? $fieldValues['ATT_fname'].' ' : ''; |
|
41 | 41 | $lname = isset($fieldValues['ATT_lname']) ? $fieldValues['ATT_lname'] : ''; |
42 | - $fieldValues['ATT_full_name'] = $fname . $lname; |
|
42 | + $fieldValues['ATT_full_name'] = $fname.$lname; |
|
43 | 43 | } |
44 | - if (! isset($fieldValues['ATT_slug'])) { |
|
44 | + if ( ! isset($fieldValues['ATT_slug'])) { |
|
45 | 45 | // $fieldValues['ATT_slug'] = sanitize_key(wp_generate_password(20)); |
46 | 46 | $fieldValues['ATT_slug'] = sanitize_title($fieldValues['ATT_full_name']); |
47 | 47 | } |
48 | - if (! isset($fieldValues['ATT_short_bio']) && isset($fieldValues['ATT_bio'])) { |
|
48 | + if ( ! isset($fieldValues['ATT_short_bio']) && isset($fieldValues['ATT_bio'])) { |
|
49 | 49 | $fieldValues['ATT_short_bio'] = substr($fieldValues['ATT_bio'], 0, 50); |
50 | 50 | } |
51 | 51 | parent::__construct($fieldValues, $bydb, $timezone, $date_formats); |
@@ -325,7 +325,7 @@ discard block |
||
325 | 325 | $initial_address_fields = array('ATT_address', 'ATT_address2', 'ATT_city',); |
326 | 326 | foreach ($initial_address_fields as $address_field_name) { |
327 | 327 | $address_fields_value = $this->get($address_field_name); |
328 | - if (! empty($address_fields_value)) { |
|
328 | + if ( ! empty($address_fields_value)) { |
|
329 | 329 | $full_address_array[] = $address_fields_value; |
330 | 330 | } |
331 | 331 | } |
@@ -340,7 +340,7 @@ discard block |
||
340 | 340 | } |
341 | 341 | // lastly get the xip |
342 | 342 | $zip_value = $this->zip(); |
343 | - if (! empty($zip_value)) { |
|
343 | + if ( ! empty($zip_value)) { |
|
344 | 344 | $full_address_array[] = $zip_value; |
345 | 345 | } |
346 | 346 | return $full_address_array; |
@@ -622,18 +622,18 @@ discard block |
||
622 | 622 | public function billing_info_for_payment_method($payment_method) |
623 | 623 | { |
624 | 624 | $pm_type = $payment_method->type_obj(); |
625 | - if (! $pm_type instanceof EE_PMT_Base) { |
|
625 | + if ( ! $pm_type instanceof EE_PMT_Base) { |
|
626 | 626 | return null; |
627 | 627 | } |
628 | 628 | $billing_info = $this->get_post_meta($this->get_billing_info_postmeta_name($payment_method), true); |
629 | - if (! $billing_info) { |
|
629 | + if ( ! $billing_info) { |
|
630 | 630 | return null; |
631 | 631 | } |
632 | 632 | $billing_form = $pm_type->billing_form(); |
633 | 633 | // double-check the form isn't totally hidden, in which case pretend there is no form |
634 | 634 | $form_totally_hidden = true; |
635 | 635 | foreach ($billing_form->inputs_in_subsections() as $input) { |
636 | - if (! $input->get_display_strategy() instanceof EE_Hidden_Display_Strategy) { |
|
636 | + if ( ! $input->get_display_strategy() instanceof EE_Hidden_Display_Strategy) { |
|
637 | 637 | $form_totally_hidden = false; |
638 | 638 | break; |
639 | 639 | } |
@@ -660,7 +660,7 @@ discard block |
||
660 | 660 | public function get_billing_info_postmeta_name($payment_method) |
661 | 661 | { |
662 | 662 | if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
663 | - return 'billing_info_' . $payment_method->type_obj()->system_name(); |
|
663 | + return 'billing_info_'.$payment_method->type_obj()->system_name(); |
|
664 | 664 | } |
665 | 665 | return null; |
666 | 666 | } |
@@ -677,7 +677,7 @@ discard block |
||
677 | 677 | */ |
678 | 678 | public function save_and_clean_billing_info_for_payment_method($billing_form, $payment_method) |
679 | 679 | { |
680 | - if (! $billing_form instanceof EE_Billing_Attendee_Info_Form) { |
|
680 | + if ( ! $billing_form instanceof EE_Billing_Attendee_Info_Form) { |
|
681 | 681 | EE_Error::add_error(esc_html__('Cannot save billing info because there is none.', 'event_espresso')); |
682 | 682 | return false; |
683 | 683 | } |
@@ -25,746 +25,746 @@ |
||
25 | 25 | class EE_Attendee extends EE_CPT_Base implements EEI_Contact, EEI_Address, EEI_Admin_Links, EEI_Attendee |
26 | 26 | { |
27 | 27 | |
28 | - /** |
|
29 | - * Sets some dynamic defaults |
|
30 | - * |
|
31 | - * @param array $fieldValues |
|
32 | - * @param bool $bydb |
|
33 | - * @param string $timezone |
|
34 | - * @param array $date_formats |
|
35 | - * @throws EE_Error |
|
36 | - */ |
|
37 | - protected function __construct($fieldValues = null, $bydb = false, $timezone = null, $date_formats = array()) |
|
38 | - { |
|
39 | - if (! isset($fieldValues['ATT_full_name'])) { |
|
40 | - $fname = isset($fieldValues['ATT_fname']) ? $fieldValues['ATT_fname'] . ' ' : ''; |
|
41 | - $lname = isset($fieldValues['ATT_lname']) ? $fieldValues['ATT_lname'] : ''; |
|
42 | - $fieldValues['ATT_full_name'] = $fname . $lname; |
|
43 | - } |
|
44 | - if (! isset($fieldValues['ATT_slug'])) { |
|
45 | - // $fieldValues['ATT_slug'] = sanitize_key(wp_generate_password(20)); |
|
46 | - $fieldValues['ATT_slug'] = sanitize_title($fieldValues['ATT_full_name']); |
|
47 | - } |
|
48 | - if (! isset($fieldValues['ATT_short_bio']) && isset($fieldValues['ATT_bio'])) { |
|
49 | - $fieldValues['ATT_short_bio'] = substr($fieldValues['ATT_bio'], 0, 50); |
|
50 | - } |
|
51 | - parent::__construct($fieldValues, $bydb, $timezone, $date_formats); |
|
52 | - } |
|
53 | - |
|
54 | - |
|
55 | - /** |
|
56 | - * @param array $props_n_values incoming values |
|
57 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
58 | - * used.) |
|
59 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
60 | - * date_format and the second value is the time format |
|
61 | - * @return EE_Attendee |
|
62 | - * @throws EE_Error |
|
63 | - */ |
|
64 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
65 | - { |
|
66 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
67 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
68 | - } |
|
69 | - |
|
70 | - |
|
71 | - /** |
|
72 | - * @param array $props_n_values incoming values from the database |
|
73 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
74 | - * the website will be used. |
|
75 | - * @return EE_Attendee |
|
76 | - */ |
|
77 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
78 | - { |
|
79 | - return new self($props_n_values, true, $timezone); |
|
80 | - } |
|
81 | - |
|
82 | - |
|
83 | - /** |
|
84 | - * Set Attendee First Name |
|
85 | - * |
|
86 | - * @access public |
|
87 | - * @param string $fname |
|
88 | - * @throws EE_Error |
|
89 | - */ |
|
90 | - public function set_fname($fname = '') |
|
91 | - { |
|
92 | - $this->set('ATT_fname', $fname); |
|
93 | - } |
|
94 | - |
|
95 | - |
|
96 | - /** |
|
97 | - * Set Attendee Last Name |
|
98 | - * |
|
99 | - * @access public |
|
100 | - * @param string $lname |
|
101 | - * @throws EE_Error |
|
102 | - */ |
|
103 | - public function set_lname($lname = '') |
|
104 | - { |
|
105 | - $this->set('ATT_lname', $lname); |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * Set Attendee Address |
|
111 | - * |
|
112 | - * @access public |
|
113 | - * @param string $address |
|
114 | - * @throws EE_Error |
|
115 | - */ |
|
116 | - public function set_address($address = '') |
|
117 | - { |
|
118 | - $this->set('ATT_address', $address); |
|
119 | - } |
|
120 | - |
|
121 | - |
|
122 | - /** |
|
123 | - * Set Attendee Address2 |
|
124 | - * |
|
125 | - * @access public |
|
126 | - * @param string $address2 |
|
127 | - * @throws EE_Error |
|
128 | - */ |
|
129 | - public function set_address2($address2 = '') |
|
130 | - { |
|
131 | - $this->set('ATT_address2', $address2); |
|
132 | - } |
|
133 | - |
|
134 | - |
|
135 | - /** |
|
136 | - * Set Attendee City |
|
137 | - * |
|
138 | - * @access public |
|
139 | - * @param string $city |
|
140 | - * @throws EE_Error |
|
141 | - */ |
|
142 | - public function set_city($city = '') |
|
143 | - { |
|
144 | - $this->set('ATT_city', $city); |
|
145 | - } |
|
146 | - |
|
147 | - |
|
148 | - /** |
|
149 | - * Set Attendee State ID |
|
150 | - * |
|
151 | - * @access public |
|
152 | - * @param int $STA_ID |
|
153 | - * @throws EE_Error |
|
154 | - */ |
|
155 | - public function set_state($STA_ID = 0) |
|
156 | - { |
|
157 | - $this->set('STA_ID', $STA_ID); |
|
158 | - } |
|
159 | - |
|
160 | - |
|
161 | - /** |
|
162 | - * Set Attendee Country ISO Code |
|
163 | - * |
|
164 | - * @access public |
|
165 | - * @param string $CNT_ISO |
|
166 | - * @throws EE_Error |
|
167 | - */ |
|
168 | - public function set_country($CNT_ISO = '') |
|
169 | - { |
|
170 | - $this->set('CNT_ISO', $CNT_ISO); |
|
171 | - } |
|
172 | - |
|
173 | - |
|
174 | - /** |
|
175 | - * Set Attendee Zip/Postal Code |
|
176 | - * |
|
177 | - * @access public |
|
178 | - * @param string $zip |
|
179 | - * @throws EE_Error |
|
180 | - */ |
|
181 | - public function set_zip($zip = '') |
|
182 | - { |
|
183 | - $this->set('ATT_zip', $zip); |
|
184 | - } |
|
185 | - |
|
186 | - |
|
187 | - /** |
|
188 | - * Set Attendee Email Address |
|
189 | - * |
|
190 | - * @access public |
|
191 | - * @param string $email |
|
192 | - * @throws EE_Error |
|
193 | - */ |
|
194 | - public function set_email($email = '') |
|
195 | - { |
|
196 | - $this->set('ATT_email', $email); |
|
197 | - } |
|
198 | - |
|
199 | - |
|
200 | - /** |
|
201 | - * Set Attendee Phone |
|
202 | - * |
|
203 | - * @access public |
|
204 | - * @param string $phone |
|
205 | - * @throws EE_Error |
|
206 | - */ |
|
207 | - public function set_phone($phone = '') |
|
208 | - { |
|
209 | - $this->set('ATT_phone', $phone); |
|
210 | - } |
|
211 | - |
|
212 | - |
|
213 | - /** |
|
214 | - * set deleted |
|
215 | - * |
|
216 | - * @access public |
|
217 | - * @param bool $ATT_deleted |
|
218 | - * @throws EE_Error |
|
219 | - */ |
|
220 | - public function set_deleted($ATT_deleted = false) |
|
221 | - { |
|
222 | - $this->set('ATT_deleted', $ATT_deleted); |
|
223 | - } |
|
224 | - |
|
225 | - |
|
226 | - /** |
|
227 | - * Returns the value for the post_author id saved with the cpt |
|
228 | - * |
|
229 | - * @since 4.5.0 |
|
230 | - * @return int |
|
231 | - * @throws EE_Error |
|
232 | - */ |
|
233 | - public function wp_user() |
|
234 | - { |
|
235 | - return $this->get('ATT_author'); |
|
236 | - } |
|
237 | - |
|
238 | - |
|
239 | - /** |
|
240 | - * get Attendee First Name |
|
241 | - * |
|
242 | - * @access public |
|
243 | - * @return string |
|
244 | - * @throws EE_Error |
|
245 | - */ |
|
246 | - public function fname() |
|
247 | - { |
|
248 | - return $this->get('ATT_fname'); |
|
249 | - } |
|
250 | - |
|
251 | - |
|
252 | - /** |
|
253 | - * echoes out the attendee's first name |
|
254 | - * |
|
255 | - * @return void |
|
256 | - * @throws EE_Error |
|
257 | - */ |
|
258 | - public function e_full_name() |
|
259 | - { |
|
260 | - echo $this->full_name(); // sanitized |
|
261 | - } |
|
262 | - |
|
263 | - |
|
264 | - /** |
|
265 | - * Returns the first and last name concatenated together with a space. |
|
266 | - * |
|
267 | - * @param bool $apply_html_entities |
|
268 | - * @return string |
|
269 | - * @throws EE_Error |
|
270 | - */ |
|
271 | - public function full_name($apply_html_entities = false) |
|
272 | - { |
|
273 | - $full_name = array( |
|
274 | - $this->fname(), |
|
275 | - $this->lname(), |
|
276 | - ); |
|
277 | - $full_name = array_filter($full_name); |
|
278 | - $full_name = implode(' ', $full_name); |
|
279 | - return $apply_html_entities ? htmlentities($full_name, ENT_QUOTES, 'UTF-8') : $full_name; |
|
280 | - } |
|
281 | - |
|
282 | - |
|
283 | - /** |
|
284 | - * This returns the value of the `ATT_full_name` field which is usually equivalent to calling `full_name()` unless |
|
285 | - * the post_title field has been directly modified in the db for the post (espresso_attendees post type) for this |
|
286 | - * attendee. |
|
287 | - * |
|
288 | - * @param bool $apply_html_entities |
|
289 | - * @return string |
|
290 | - * @throws EE_Error |
|
291 | - */ |
|
292 | - public function ATT_full_name($apply_html_entities = false) |
|
293 | - { |
|
294 | - return $apply_html_entities |
|
295 | - ? htmlentities($this->get('ATT_full_name'), ENT_QUOTES, 'UTF-8') |
|
296 | - : $this->get('ATT_full_name'); |
|
297 | - } |
|
298 | - |
|
299 | - |
|
300 | - /** |
|
301 | - * get Attendee Last Name |
|
302 | - * |
|
303 | - * @access public |
|
304 | - * @return string |
|
305 | - * @throws EE_Error |
|
306 | - */ |
|
307 | - public function lname() |
|
308 | - { |
|
309 | - return $this->get('ATT_lname'); |
|
310 | - } |
|
311 | - |
|
312 | - |
|
313 | - /** |
|
314 | - * Gets the attendee's full address as an array so client code can decide hwo to display it |
|
315 | - * |
|
316 | - * @return array numerically indexed, with each part of the address that is known. |
|
317 | - * Eg, if the user only responded to state and country, |
|
318 | - * it would be array(0=>'Alabama',1=>'USA') |
|
319 | - * @return array |
|
320 | - * @throws EE_Error |
|
321 | - */ |
|
322 | - public function full_address_as_array() |
|
323 | - { |
|
324 | - $full_address_array = array(); |
|
325 | - $initial_address_fields = array('ATT_address', 'ATT_address2', 'ATT_city',); |
|
326 | - foreach ($initial_address_fields as $address_field_name) { |
|
327 | - $address_fields_value = $this->get($address_field_name); |
|
328 | - if (! empty($address_fields_value)) { |
|
329 | - $full_address_array[] = $address_fields_value; |
|
330 | - } |
|
331 | - } |
|
332 | - // now handle state and country |
|
333 | - $state_obj = $this->state_obj(); |
|
334 | - if ($state_obj instanceof EE_State) { |
|
335 | - $full_address_array[] = $state_obj->name(); |
|
336 | - } |
|
337 | - $country_obj = $this->country_obj(); |
|
338 | - if ($country_obj instanceof EE_Country) { |
|
339 | - $full_address_array[] = $country_obj->name(); |
|
340 | - } |
|
341 | - // lastly get the xip |
|
342 | - $zip_value = $this->zip(); |
|
343 | - if (! empty($zip_value)) { |
|
344 | - $full_address_array[] = $zip_value; |
|
345 | - } |
|
346 | - return $full_address_array; |
|
347 | - } |
|
348 | - |
|
349 | - |
|
350 | - /** |
|
351 | - * get Attendee Address |
|
352 | - * |
|
353 | - * @return string |
|
354 | - * @throws EE_Error |
|
355 | - */ |
|
356 | - public function address() |
|
357 | - { |
|
358 | - return $this->get('ATT_address'); |
|
359 | - } |
|
360 | - |
|
361 | - |
|
362 | - /** |
|
363 | - * get Attendee Address2 |
|
364 | - * |
|
365 | - * @return string |
|
366 | - * @throws EE_Error |
|
367 | - */ |
|
368 | - public function address2() |
|
369 | - { |
|
370 | - return $this->get('ATT_address2'); |
|
371 | - } |
|
372 | - |
|
373 | - |
|
374 | - /** |
|
375 | - * get Attendee City |
|
376 | - * |
|
377 | - * @return string |
|
378 | - * @throws EE_Error |
|
379 | - */ |
|
380 | - public function city() |
|
381 | - { |
|
382 | - return $this->get('ATT_city'); |
|
383 | - } |
|
384 | - |
|
385 | - |
|
386 | - /** |
|
387 | - * get Attendee State ID |
|
388 | - * |
|
389 | - * @return string |
|
390 | - * @throws EE_Error |
|
391 | - */ |
|
392 | - public function state_ID() |
|
393 | - { |
|
394 | - return $this->get('STA_ID'); |
|
395 | - } |
|
396 | - |
|
397 | - |
|
398 | - /** |
|
399 | - * @return string |
|
400 | - * @throws EE_Error |
|
401 | - */ |
|
402 | - public function state_abbrev() |
|
403 | - { |
|
404 | - return $this->state_obj() instanceof EE_State ? $this->state_obj()->abbrev() : ''; |
|
405 | - } |
|
406 | - |
|
407 | - |
|
408 | - /** |
|
409 | - * Gets the state set to this attendee |
|
410 | - * |
|
411 | - * @return EE_State |
|
412 | - * @throws EE_Error |
|
413 | - */ |
|
414 | - public function state_obj() |
|
415 | - { |
|
416 | - return $this->get_first_related('State'); |
|
417 | - } |
|
418 | - |
|
419 | - |
|
420 | - /** |
|
421 | - * Returns the state's name, otherwise 'Unknown' |
|
422 | - * |
|
423 | - * @return string |
|
424 | - * @throws EE_Error |
|
425 | - */ |
|
426 | - public function state_name() |
|
427 | - { |
|
428 | - if ($this->state_obj()) { |
|
429 | - return $this->state_obj()->name(); |
|
430 | - } else { |
|
431 | - return ''; |
|
432 | - } |
|
433 | - } |
|
434 | - |
|
435 | - |
|
436 | - /** |
|
437 | - * either displays the state abbreviation or the state name, as determined |
|
438 | - * by the "FHEE__EEI_Address__state__use_abbreviation" filter. |
|
439 | - * defaults to abbreviation |
|
440 | - * |
|
441 | - * @return string |
|
442 | - * @throws EE_Error |
|
443 | - */ |
|
444 | - public function state() |
|
445 | - { |
|
446 | - if (apply_filters('FHEE__EEI_Address__state__use_abbreviation', true, $this->state_obj())) { |
|
447 | - return $this->state_abbrev(); |
|
448 | - } |
|
449 | - return $this->state_name(); |
|
450 | - } |
|
451 | - |
|
452 | - |
|
453 | - /** |
|
454 | - * get Attendee Country ISO Code |
|
455 | - * |
|
456 | - * @return string |
|
457 | - * @throws EE_Error |
|
458 | - */ |
|
459 | - public function country_ID() |
|
460 | - { |
|
461 | - return $this->get('CNT_ISO'); |
|
462 | - } |
|
463 | - |
|
464 | - |
|
465 | - /** |
|
466 | - * Gets country set for this attendee |
|
467 | - * |
|
468 | - * @return EE_Country |
|
469 | - * @throws EE_Error |
|
470 | - */ |
|
471 | - public function country_obj() |
|
472 | - { |
|
473 | - return $this->get_first_related('Country'); |
|
474 | - } |
|
475 | - |
|
476 | - |
|
477 | - /** |
|
478 | - * Returns the country's name if known, otherwise 'Unknown' |
|
479 | - * |
|
480 | - * @return string |
|
481 | - * @throws EE_Error |
|
482 | - */ |
|
483 | - public function country_name() |
|
484 | - { |
|
485 | - if ($this->country_obj()) { |
|
486 | - return $this->country_obj()->name(); |
|
487 | - } |
|
488 | - return ''; |
|
489 | - } |
|
490 | - |
|
491 | - |
|
492 | - /** |
|
493 | - * either displays the country ISO2 code or the country name, as determined |
|
494 | - * by the "FHEE__EEI_Address__country__use_abbreviation" filter. |
|
495 | - * defaults to abbreviation |
|
496 | - * |
|
497 | - * @return string |
|
498 | - * @throws EE_Error |
|
499 | - */ |
|
500 | - public function country() |
|
501 | - { |
|
502 | - if (apply_filters('FHEE__EEI_Address__country__use_abbreviation', true, $this->country_obj())) { |
|
503 | - return $this->country_ID(); |
|
504 | - } |
|
505 | - return $this->country_name(); |
|
506 | - } |
|
507 | - |
|
508 | - |
|
509 | - /** |
|
510 | - * get Attendee Zip/Postal Code |
|
511 | - * |
|
512 | - * @return string |
|
513 | - * @throws EE_Error |
|
514 | - */ |
|
515 | - public function zip() |
|
516 | - { |
|
517 | - return $this->get('ATT_zip'); |
|
518 | - } |
|
519 | - |
|
520 | - |
|
521 | - /** |
|
522 | - * get Attendee Email Address |
|
523 | - * |
|
524 | - * @return string |
|
525 | - * @throws EE_Error |
|
526 | - */ |
|
527 | - public function email() |
|
528 | - { |
|
529 | - return $this->get('ATT_email'); |
|
530 | - } |
|
531 | - |
|
532 | - |
|
533 | - /** |
|
534 | - * get Attendee Phone # |
|
535 | - * |
|
536 | - * @return string |
|
537 | - * @throws EE_Error |
|
538 | - */ |
|
539 | - public function phone() |
|
540 | - { |
|
541 | - return $this->get('ATT_phone'); |
|
542 | - } |
|
543 | - |
|
544 | - |
|
545 | - /** |
|
546 | - * get deleted |
|
547 | - * |
|
548 | - * @return bool |
|
549 | - * @throws EE_Error |
|
550 | - */ |
|
551 | - public function deleted() |
|
552 | - { |
|
553 | - return $this->get('ATT_deleted'); |
|
554 | - } |
|
555 | - |
|
556 | - |
|
557 | - /** |
|
558 | - * Gets registrations of this attendee |
|
559 | - * |
|
560 | - * @param array $query_params |
|
561 | - * @return EE_Registration[] |
|
562 | - * @throws EE_Error |
|
563 | - */ |
|
564 | - public function get_registrations($query_params = array()) |
|
565 | - { |
|
566 | - return $this->get_many_related('Registration', $query_params); |
|
567 | - } |
|
568 | - |
|
569 | - |
|
570 | - /** |
|
571 | - * Gets the most recent registration of this attendee |
|
572 | - * |
|
573 | - * @return EE_Registration |
|
574 | - * @throws EE_Error |
|
575 | - */ |
|
576 | - public function get_most_recent_registration() |
|
577 | - { |
|
578 | - return $this->get_first_related( |
|
579 | - 'Registration', |
|
580 | - array('order_by' => array('REG_date' => 'DESC')) |
|
581 | - ); // null, 'REG_date', 'DESC', '=', 'OBJECT_K'); |
|
582 | - } |
|
583 | - |
|
584 | - |
|
585 | - /** |
|
586 | - * Gets the most recent registration for this attend at this event |
|
587 | - * |
|
588 | - * @param int $event_id |
|
589 | - * @return EE_Registration |
|
590 | - * @throws EE_Error |
|
591 | - */ |
|
592 | - public function get_most_recent_registration_for_event($event_id) |
|
593 | - { |
|
594 | - return $this->get_first_related( |
|
595 | - 'Registration', |
|
596 | - array(array('EVT_ID' => $event_id), 'order_by' => array('REG_date' => 'DESC')) |
|
597 | - ); |
|
598 | - } |
|
599 | - |
|
600 | - |
|
601 | - /** |
|
602 | - * returns any events attached to this attendee ($_Event property); |
|
603 | - * |
|
604 | - * @return array |
|
605 | - * @throws EE_Error |
|
606 | - */ |
|
607 | - public function events() |
|
608 | - { |
|
609 | - return $this->get_many_related('Event'); |
|
610 | - } |
|
611 | - |
|
612 | - |
|
613 | - /** |
|
614 | - * Gets the billing info array where keys match espresso_reg_page_billing_inputs(), |
|
615 | - * and keys are their cleaned values. @see EE_Attendee::save_and_clean_billing_info_for_payment_method() which was |
|
616 | - * used to save the billing info |
|
617 | - * |
|
618 | - * @param EE_Payment_Method $payment_method the _gateway_name property on the gateway class |
|
619 | - * @return EE_Form_Section_Proper|null |
|
620 | - * @throws EE_Error |
|
621 | - */ |
|
622 | - public function billing_info_for_payment_method($payment_method) |
|
623 | - { |
|
624 | - $pm_type = $payment_method->type_obj(); |
|
625 | - if (! $pm_type instanceof EE_PMT_Base) { |
|
626 | - return null; |
|
627 | - } |
|
628 | - $billing_info = $this->get_post_meta($this->get_billing_info_postmeta_name($payment_method), true); |
|
629 | - if (! $billing_info) { |
|
630 | - return null; |
|
631 | - } |
|
632 | - $billing_form = $pm_type->billing_form(); |
|
633 | - // double-check the form isn't totally hidden, in which case pretend there is no form |
|
634 | - $form_totally_hidden = true; |
|
635 | - foreach ($billing_form->inputs_in_subsections() as $input) { |
|
636 | - if (! $input->get_display_strategy() instanceof EE_Hidden_Display_Strategy) { |
|
637 | - $form_totally_hidden = false; |
|
638 | - break; |
|
639 | - } |
|
640 | - } |
|
641 | - if ($form_totally_hidden) { |
|
642 | - return null; |
|
643 | - } |
|
644 | - if ($billing_form instanceof EE_Form_Section_Proper) { |
|
645 | - $billing_form->receive_form_submission(array($billing_form->name() => $billing_info), false); |
|
646 | - } |
|
647 | - |
|
648 | - return $billing_form; |
|
649 | - } |
|
650 | - |
|
651 | - |
|
652 | - /** |
|
653 | - * Gets the postmeta key that holds this attendee's billing info for the |
|
654 | - * specified payment method |
|
655 | - * |
|
656 | - * @param EE_Payment_Method $payment_method |
|
657 | - * @return string |
|
658 | - * @throws EE_Error |
|
659 | - */ |
|
660 | - public function get_billing_info_postmeta_name($payment_method) |
|
661 | - { |
|
662 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
663 | - return 'billing_info_' . $payment_method->type_obj()->system_name(); |
|
664 | - } |
|
665 | - return null; |
|
666 | - } |
|
667 | - |
|
668 | - |
|
669 | - /** |
|
670 | - * Saves the billing info to the attendee. @see EE_Attendee::billing_info_for_payment_method() which is used to |
|
671 | - * retrieve it |
|
672 | - * |
|
673 | - * @param EE_Billing_Attendee_Info_Form $billing_form |
|
674 | - * @param EE_Payment_Method $payment_method |
|
675 | - * @return boolean |
|
676 | - * @throws EE_Error |
|
677 | - */ |
|
678 | - public function save_and_clean_billing_info_for_payment_method($billing_form, $payment_method) |
|
679 | - { |
|
680 | - if (! $billing_form instanceof EE_Billing_Attendee_Info_Form) { |
|
681 | - EE_Error::add_error(esc_html__('Cannot save billing info because there is none.', 'event_espresso')); |
|
682 | - return false; |
|
683 | - } |
|
684 | - $billing_form->clean_sensitive_data(); |
|
685 | - return update_post_meta( |
|
686 | - $this->ID(), |
|
687 | - $this->get_billing_info_postmeta_name($payment_method), |
|
688 | - $billing_form->input_values(true) |
|
689 | - ); |
|
690 | - } |
|
691 | - |
|
692 | - |
|
693 | - /** |
|
694 | - * Return the link to the admin details for the object. |
|
695 | - * |
|
696 | - * @return string |
|
697 | - * @throws EE_Error |
|
698 | - * @throws InvalidArgumentException |
|
699 | - * @throws InvalidDataTypeException |
|
700 | - * @throws InvalidInterfaceException |
|
701 | - * @throws ReflectionException |
|
702 | - */ |
|
703 | - public function get_admin_details_link() |
|
704 | - { |
|
705 | - return $this->get_admin_edit_link(); |
|
706 | - } |
|
707 | - |
|
708 | - |
|
709 | - /** |
|
710 | - * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
711 | - * |
|
712 | - * @return string |
|
713 | - * @throws EE_Error |
|
714 | - * @throws InvalidArgumentException |
|
715 | - * @throws ReflectionException |
|
716 | - * @throws InvalidDataTypeException |
|
717 | - * @throws InvalidInterfaceException |
|
718 | - */ |
|
719 | - public function get_admin_edit_link() |
|
720 | - { |
|
721 | - EE_Registry::instance()->load_helper('URL'); |
|
722 | - return EEH_URL::add_query_args_and_nonce( |
|
723 | - array( |
|
724 | - 'page' => 'espresso_registrations', |
|
725 | - 'action' => 'edit_attendee', |
|
726 | - 'post' => $this->ID(), |
|
727 | - ), |
|
728 | - admin_url('admin.php') |
|
729 | - ); |
|
730 | - } |
|
731 | - |
|
732 | - |
|
733 | - /** |
|
734 | - * Returns the link to a settings page for the object. |
|
735 | - * |
|
736 | - * @return string |
|
737 | - * @throws EE_Error |
|
738 | - * @throws InvalidArgumentException |
|
739 | - * @throws InvalidDataTypeException |
|
740 | - * @throws InvalidInterfaceException |
|
741 | - * @throws ReflectionException |
|
742 | - */ |
|
743 | - public function get_admin_settings_link() |
|
744 | - { |
|
745 | - return $this->get_admin_edit_link(); |
|
746 | - } |
|
747 | - |
|
748 | - |
|
749 | - /** |
|
750 | - * Returns the link to the "overview" for the object (typically the "list table" view). |
|
751 | - * |
|
752 | - * @return string |
|
753 | - * @throws EE_Error |
|
754 | - * @throws InvalidArgumentException |
|
755 | - * @throws ReflectionException |
|
756 | - * @throws InvalidDataTypeException |
|
757 | - * @throws InvalidInterfaceException |
|
758 | - */ |
|
759 | - public function get_admin_overview_link() |
|
760 | - { |
|
761 | - EE_Registry::instance()->load_helper('URL'); |
|
762 | - return EEH_URL::add_query_args_and_nonce( |
|
763 | - array( |
|
764 | - 'page' => 'espresso_registrations', |
|
765 | - 'action' => 'contact_list', |
|
766 | - ), |
|
767 | - admin_url('admin.php') |
|
768 | - ); |
|
769 | - } |
|
28 | + /** |
|
29 | + * Sets some dynamic defaults |
|
30 | + * |
|
31 | + * @param array $fieldValues |
|
32 | + * @param bool $bydb |
|
33 | + * @param string $timezone |
|
34 | + * @param array $date_formats |
|
35 | + * @throws EE_Error |
|
36 | + */ |
|
37 | + protected function __construct($fieldValues = null, $bydb = false, $timezone = null, $date_formats = array()) |
|
38 | + { |
|
39 | + if (! isset($fieldValues['ATT_full_name'])) { |
|
40 | + $fname = isset($fieldValues['ATT_fname']) ? $fieldValues['ATT_fname'] . ' ' : ''; |
|
41 | + $lname = isset($fieldValues['ATT_lname']) ? $fieldValues['ATT_lname'] : ''; |
|
42 | + $fieldValues['ATT_full_name'] = $fname . $lname; |
|
43 | + } |
|
44 | + if (! isset($fieldValues['ATT_slug'])) { |
|
45 | + // $fieldValues['ATT_slug'] = sanitize_key(wp_generate_password(20)); |
|
46 | + $fieldValues['ATT_slug'] = sanitize_title($fieldValues['ATT_full_name']); |
|
47 | + } |
|
48 | + if (! isset($fieldValues['ATT_short_bio']) && isset($fieldValues['ATT_bio'])) { |
|
49 | + $fieldValues['ATT_short_bio'] = substr($fieldValues['ATT_bio'], 0, 50); |
|
50 | + } |
|
51 | + parent::__construct($fieldValues, $bydb, $timezone, $date_formats); |
|
52 | + } |
|
53 | + |
|
54 | + |
|
55 | + /** |
|
56 | + * @param array $props_n_values incoming values |
|
57 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
58 | + * used.) |
|
59 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
60 | + * date_format and the second value is the time format |
|
61 | + * @return EE_Attendee |
|
62 | + * @throws EE_Error |
|
63 | + */ |
|
64 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
65 | + { |
|
66 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
67 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
68 | + } |
|
69 | + |
|
70 | + |
|
71 | + /** |
|
72 | + * @param array $props_n_values incoming values from the database |
|
73 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
74 | + * the website will be used. |
|
75 | + * @return EE_Attendee |
|
76 | + */ |
|
77 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
78 | + { |
|
79 | + return new self($props_n_values, true, $timezone); |
|
80 | + } |
|
81 | + |
|
82 | + |
|
83 | + /** |
|
84 | + * Set Attendee First Name |
|
85 | + * |
|
86 | + * @access public |
|
87 | + * @param string $fname |
|
88 | + * @throws EE_Error |
|
89 | + */ |
|
90 | + public function set_fname($fname = '') |
|
91 | + { |
|
92 | + $this->set('ATT_fname', $fname); |
|
93 | + } |
|
94 | + |
|
95 | + |
|
96 | + /** |
|
97 | + * Set Attendee Last Name |
|
98 | + * |
|
99 | + * @access public |
|
100 | + * @param string $lname |
|
101 | + * @throws EE_Error |
|
102 | + */ |
|
103 | + public function set_lname($lname = '') |
|
104 | + { |
|
105 | + $this->set('ATT_lname', $lname); |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * Set Attendee Address |
|
111 | + * |
|
112 | + * @access public |
|
113 | + * @param string $address |
|
114 | + * @throws EE_Error |
|
115 | + */ |
|
116 | + public function set_address($address = '') |
|
117 | + { |
|
118 | + $this->set('ATT_address', $address); |
|
119 | + } |
|
120 | + |
|
121 | + |
|
122 | + /** |
|
123 | + * Set Attendee Address2 |
|
124 | + * |
|
125 | + * @access public |
|
126 | + * @param string $address2 |
|
127 | + * @throws EE_Error |
|
128 | + */ |
|
129 | + public function set_address2($address2 = '') |
|
130 | + { |
|
131 | + $this->set('ATT_address2', $address2); |
|
132 | + } |
|
133 | + |
|
134 | + |
|
135 | + /** |
|
136 | + * Set Attendee City |
|
137 | + * |
|
138 | + * @access public |
|
139 | + * @param string $city |
|
140 | + * @throws EE_Error |
|
141 | + */ |
|
142 | + public function set_city($city = '') |
|
143 | + { |
|
144 | + $this->set('ATT_city', $city); |
|
145 | + } |
|
146 | + |
|
147 | + |
|
148 | + /** |
|
149 | + * Set Attendee State ID |
|
150 | + * |
|
151 | + * @access public |
|
152 | + * @param int $STA_ID |
|
153 | + * @throws EE_Error |
|
154 | + */ |
|
155 | + public function set_state($STA_ID = 0) |
|
156 | + { |
|
157 | + $this->set('STA_ID', $STA_ID); |
|
158 | + } |
|
159 | + |
|
160 | + |
|
161 | + /** |
|
162 | + * Set Attendee Country ISO Code |
|
163 | + * |
|
164 | + * @access public |
|
165 | + * @param string $CNT_ISO |
|
166 | + * @throws EE_Error |
|
167 | + */ |
|
168 | + public function set_country($CNT_ISO = '') |
|
169 | + { |
|
170 | + $this->set('CNT_ISO', $CNT_ISO); |
|
171 | + } |
|
172 | + |
|
173 | + |
|
174 | + /** |
|
175 | + * Set Attendee Zip/Postal Code |
|
176 | + * |
|
177 | + * @access public |
|
178 | + * @param string $zip |
|
179 | + * @throws EE_Error |
|
180 | + */ |
|
181 | + public function set_zip($zip = '') |
|
182 | + { |
|
183 | + $this->set('ATT_zip', $zip); |
|
184 | + } |
|
185 | + |
|
186 | + |
|
187 | + /** |
|
188 | + * Set Attendee Email Address |
|
189 | + * |
|
190 | + * @access public |
|
191 | + * @param string $email |
|
192 | + * @throws EE_Error |
|
193 | + */ |
|
194 | + public function set_email($email = '') |
|
195 | + { |
|
196 | + $this->set('ATT_email', $email); |
|
197 | + } |
|
198 | + |
|
199 | + |
|
200 | + /** |
|
201 | + * Set Attendee Phone |
|
202 | + * |
|
203 | + * @access public |
|
204 | + * @param string $phone |
|
205 | + * @throws EE_Error |
|
206 | + */ |
|
207 | + public function set_phone($phone = '') |
|
208 | + { |
|
209 | + $this->set('ATT_phone', $phone); |
|
210 | + } |
|
211 | + |
|
212 | + |
|
213 | + /** |
|
214 | + * set deleted |
|
215 | + * |
|
216 | + * @access public |
|
217 | + * @param bool $ATT_deleted |
|
218 | + * @throws EE_Error |
|
219 | + */ |
|
220 | + public function set_deleted($ATT_deleted = false) |
|
221 | + { |
|
222 | + $this->set('ATT_deleted', $ATT_deleted); |
|
223 | + } |
|
224 | + |
|
225 | + |
|
226 | + /** |
|
227 | + * Returns the value for the post_author id saved with the cpt |
|
228 | + * |
|
229 | + * @since 4.5.0 |
|
230 | + * @return int |
|
231 | + * @throws EE_Error |
|
232 | + */ |
|
233 | + public function wp_user() |
|
234 | + { |
|
235 | + return $this->get('ATT_author'); |
|
236 | + } |
|
237 | + |
|
238 | + |
|
239 | + /** |
|
240 | + * get Attendee First Name |
|
241 | + * |
|
242 | + * @access public |
|
243 | + * @return string |
|
244 | + * @throws EE_Error |
|
245 | + */ |
|
246 | + public function fname() |
|
247 | + { |
|
248 | + return $this->get('ATT_fname'); |
|
249 | + } |
|
250 | + |
|
251 | + |
|
252 | + /** |
|
253 | + * echoes out the attendee's first name |
|
254 | + * |
|
255 | + * @return void |
|
256 | + * @throws EE_Error |
|
257 | + */ |
|
258 | + public function e_full_name() |
|
259 | + { |
|
260 | + echo $this->full_name(); // sanitized |
|
261 | + } |
|
262 | + |
|
263 | + |
|
264 | + /** |
|
265 | + * Returns the first and last name concatenated together with a space. |
|
266 | + * |
|
267 | + * @param bool $apply_html_entities |
|
268 | + * @return string |
|
269 | + * @throws EE_Error |
|
270 | + */ |
|
271 | + public function full_name($apply_html_entities = false) |
|
272 | + { |
|
273 | + $full_name = array( |
|
274 | + $this->fname(), |
|
275 | + $this->lname(), |
|
276 | + ); |
|
277 | + $full_name = array_filter($full_name); |
|
278 | + $full_name = implode(' ', $full_name); |
|
279 | + return $apply_html_entities ? htmlentities($full_name, ENT_QUOTES, 'UTF-8') : $full_name; |
|
280 | + } |
|
281 | + |
|
282 | + |
|
283 | + /** |
|
284 | + * This returns the value of the `ATT_full_name` field which is usually equivalent to calling `full_name()` unless |
|
285 | + * the post_title field has been directly modified in the db for the post (espresso_attendees post type) for this |
|
286 | + * attendee. |
|
287 | + * |
|
288 | + * @param bool $apply_html_entities |
|
289 | + * @return string |
|
290 | + * @throws EE_Error |
|
291 | + */ |
|
292 | + public function ATT_full_name($apply_html_entities = false) |
|
293 | + { |
|
294 | + return $apply_html_entities |
|
295 | + ? htmlentities($this->get('ATT_full_name'), ENT_QUOTES, 'UTF-8') |
|
296 | + : $this->get('ATT_full_name'); |
|
297 | + } |
|
298 | + |
|
299 | + |
|
300 | + /** |
|
301 | + * get Attendee Last Name |
|
302 | + * |
|
303 | + * @access public |
|
304 | + * @return string |
|
305 | + * @throws EE_Error |
|
306 | + */ |
|
307 | + public function lname() |
|
308 | + { |
|
309 | + return $this->get('ATT_lname'); |
|
310 | + } |
|
311 | + |
|
312 | + |
|
313 | + /** |
|
314 | + * Gets the attendee's full address as an array so client code can decide hwo to display it |
|
315 | + * |
|
316 | + * @return array numerically indexed, with each part of the address that is known. |
|
317 | + * Eg, if the user only responded to state and country, |
|
318 | + * it would be array(0=>'Alabama',1=>'USA') |
|
319 | + * @return array |
|
320 | + * @throws EE_Error |
|
321 | + */ |
|
322 | + public function full_address_as_array() |
|
323 | + { |
|
324 | + $full_address_array = array(); |
|
325 | + $initial_address_fields = array('ATT_address', 'ATT_address2', 'ATT_city',); |
|
326 | + foreach ($initial_address_fields as $address_field_name) { |
|
327 | + $address_fields_value = $this->get($address_field_name); |
|
328 | + if (! empty($address_fields_value)) { |
|
329 | + $full_address_array[] = $address_fields_value; |
|
330 | + } |
|
331 | + } |
|
332 | + // now handle state and country |
|
333 | + $state_obj = $this->state_obj(); |
|
334 | + if ($state_obj instanceof EE_State) { |
|
335 | + $full_address_array[] = $state_obj->name(); |
|
336 | + } |
|
337 | + $country_obj = $this->country_obj(); |
|
338 | + if ($country_obj instanceof EE_Country) { |
|
339 | + $full_address_array[] = $country_obj->name(); |
|
340 | + } |
|
341 | + // lastly get the xip |
|
342 | + $zip_value = $this->zip(); |
|
343 | + if (! empty($zip_value)) { |
|
344 | + $full_address_array[] = $zip_value; |
|
345 | + } |
|
346 | + return $full_address_array; |
|
347 | + } |
|
348 | + |
|
349 | + |
|
350 | + /** |
|
351 | + * get Attendee Address |
|
352 | + * |
|
353 | + * @return string |
|
354 | + * @throws EE_Error |
|
355 | + */ |
|
356 | + public function address() |
|
357 | + { |
|
358 | + return $this->get('ATT_address'); |
|
359 | + } |
|
360 | + |
|
361 | + |
|
362 | + /** |
|
363 | + * get Attendee Address2 |
|
364 | + * |
|
365 | + * @return string |
|
366 | + * @throws EE_Error |
|
367 | + */ |
|
368 | + public function address2() |
|
369 | + { |
|
370 | + return $this->get('ATT_address2'); |
|
371 | + } |
|
372 | + |
|
373 | + |
|
374 | + /** |
|
375 | + * get Attendee City |
|
376 | + * |
|
377 | + * @return string |
|
378 | + * @throws EE_Error |
|
379 | + */ |
|
380 | + public function city() |
|
381 | + { |
|
382 | + return $this->get('ATT_city'); |
|
383 | + } |
|
384 | + |
|
385 | + |
|
386 | + /** |
|
387 | + * get Attendee State ID |
|
388 | + * |
|
389 | + * @return string |
|
390 | + * @throws EE_Error |
|
391 | + */ |
|
392 | + public function state_ID() |
|
393 | + { |
|
394 | + return $this->get('STA_ID'); |
|
395 | + } |
|
396 | + |
|
397 | + |
|
398 | + /** |
|
399 | + * @return string |
|
400 | + * @throws EE_Error |
|
401 | + */ |
|
402 | + public function state_abbrev() |
|
403 | + { |
|
404 | + return $this->state_obj() instanceof EE_State ? $this->state_obj()->abbrev() : ''; |
|
405 | + } |
|
406 | + |
|
407 | + |
|
408 | + /** |
|
409 | + * Gets the state set to this attendee |
|
410 | + * |
|
411 | + * @return EE_State |
|
412 | + * @throws EE_Error |
|
413 | + */ |
|
414 | + public function state_obj() |
|
415 | + { |
|
416 | + return $this->get_first_related('State'); |
|
417 | + } |
|
418 | + |
|
419 | + |
|
420 | + /** |
|
421 | + * Returns the state's name, otherwise 'Unknown' |
|
422 | + * |
|
423 | + * @return string |
|
424 | + * @throws EE_Error |
|
425 | + */ |
|
426 | + public function state_name() |
|
427 | + { |
|
428 | + if ($this->state_obj()) { |
|
429 | + return $this->state_obj()->name(); |
|
430 | + } else { |
|
431 | + return ''; |
|
432 | + } |
|
433 | + } |
|
434 | + |
|
435 | + |
|
436 | + /** |
|
437 | + * either displays the state abbreviation or the state name, as determined |
|
438 | + * by the "FHEE__EEI_Address__state__use_abbreviation" filter. |
|
439 | + * defaults to abbreviation |
|
440 | + * |
|
441 | + * @return string |
|
442 | + * @throws EE_Error |
|
443 | + */ |
|
444 | + public function state() |
|
445 | + { |
|
446 | + if (apply_filters('FHEE__EEI_Address__state__use_abbreviation', true, $this->state_obj())) { |
|
447 | + return $this->state_abbrev(); |
|
448 | + } |
|
449 | + return $this->state_name(); |
|
450 | + } |
|
451 | + |
|
452 | + |
|
453 | + /** |
|
454 | + * get Attendee Country ISO Code |
|
455 | + * |
|
456 | + * @return string |
|
457 | + * @throws EE_Error |
|
458 | + */ |
|
459 | + public function country_ID() |
|
460 | + { |
|
461 | + return $this->get('CNT_ISO'); |
|
462 | + } |
|
463 | + |
|
464 | + |
|
465 | + /** |
|
466 | + * Gets country set for this attendee |
|
467 | + * |
|
468 | + * @return EE_Country |
|
469 | + * @throws EE_Error |
|
470 | + */ |
|
471 | + public function country_obj() |
|
472 | + { |
|
473 | + return $this->get_first_related('Country'); |
|
474 | + } |
|
475 | + |
|
476 | + |
|
477 | + /** |
|
478 | + * Returns the country's name if known, otherwise 'Unknown' |
|
479 | + * |
|
480 | + * @return string |
|
481 | + * @throws EE_Error |
|
482 | + */ |
|
483 | + public function country_name() |
|
484 | + { |
|
485 | + if ($this->country_obj()) { |
|
486 | + return $this->country_obj()->name(); |
|
487 | + } |
|
488 | + return ''; |
|
489 | + } |
|
490 | + |
|
491 | + |
|
492 | + /** |
|
493 | + * either displays the country ISO2 code or the country name, as determined |
|
494 | + * by the "FHEE__EEI_Address__country__use_abbreviation" filter. |
|
495 | + * defaults to abbreviation |
|
496 | + * |
|
497 | + * @return string |
|
498 | + * @throws EE_Error |
|
499 | + */ |
|
500 | + public function country() |
|
501 | + { |
|
502 | + if (apply_filters('FHEE__EEI_Address__country__use_abbreviation', true, $this->country_obj())) { |
|
503 | + return $this->country_ID(); |
|
504 | + } |
|
505 | + return $this->country_name(); |
|
506 | + } |
|
507 | + |
|
508 | + |
|
509 | + /** |
|
510 | + * get Attendee Zip/Postal Code |
|
511 | + * |
|
512 | + * @return string |
|
513 | + * @throws EE_Error |
|
514 | + */ |
|
515 | + public function zip() |
|
516 | + { |
|
517 | + return $this->get('ATT_zip'); |
|
518 | + } |
|
519 | + |
|
520 | + |
|
521 | + /** |
|
522 | + * get Attendee Email Address |
|
523 | + * |
|
524 | + * @return string |
|
525 | + * @throws EE_Error |
|
526 | + */ |
|
527 | + public function email() |
|
528 | + { |
|
529 | + return $this->get('ATT_email'); |
|
530 | + } |
|
531 | + |
|
532 | + |
|
533 | + /** |
|
534 | + * get Attendee Phone # |
|
535 | + * |
|
536 | + * @return string |
|
537 | + * @throws EE_Error |
|
538 | + */ |
|
539 | + public function phone() |
|
540 | + { |
|
541 | + return $this->get('ATT_phone'); |
|
542 | + } |
|
543 | + |
|
544 | + |
|
545 | + /** |
|
546 | + * get deleted |
|
547 | + * |
|
548 | + * @return bool |
|
549 | + * @throws EE_Error |
|
550 | + */ |
|
551 | + public function deleted() |
|
552 | + { |
|
553 | + return $this->get('ATT_deleted'); |
|
554 | + } |
|
555 | + |
|
556 | + |
|
557 | + /** |
|
558 | + * Gets registrations of this attendee |
|
559 | + * |
|
560 | + * @param array $query_params |
|
561 | + * @return EE_Registration[] |
|
562 | + * @throws EE_Error |
|
563 | + */ |
|
564 | + public function get_registrations($query_params = array()) |
|
565 | + { |
|
566 | + return $this->get_many_related('Registration', $query_params); |
|
567 | + } |
|
568 | + |
|
569 | + |
|
570 | + /** |
|
571 | + * Gets the most recent registration of this attendee |
|
572 | + * |
|
573 | + * @return EE_Registration |
|
574 | + * @throws EE_Error |
|
575 | + */ |
|
576 | + public function get_most_recent_registration() |
|
577 | + { |
|
578 | + return $this->get_first_related( |
|
579 | + 'Registration', |
|
580 | + array('order_by' => array('REG_date' => 'DESC')) |
|
581 | + ); // null, 'REG_date', 'DESC', '=', 'OBJECT_K'); |
|
582 | + } |
|
583 | + |
|
584 | + |
|
585 | + /** |
|
586 | + * Gets the most recent registration for this attend at this event |
|
587 | + * |
|
588 | + * @param int $event_id |
|
589 | + * @return EE_Registration |
|
590 | + * @throws EE_Error |
|
591 | + */ |
|
592 | + public function get_most_recent_registration_for_event($event_id) |
|
593 | + { |
|
594 | + return $this->get_first_related( |
|
595 | + 'Registration', |
|
596 | + array(array('EVT_ID' => $event_id), 'order_by' => array('REG_date' => 'DESC')) |
|
597 | + ); |
|
598 | + } |
|
599 | + |
|
600 | + |
|
601 | + /** |
|
602 | + * returns any events attached to this attendee ($_Event property); |
|
603 | + * |
|
604 | + * @return array |
|
605 | + * @throws EE_Error |
|
606 | + */ |
|
607 | + public function events() |
|
608 | + { |
|
609 | + return $this->get_many_related('Event'); |
|
610 | + } |
|
611 | + |
|
612 | + |
|
613 | + /** |
|
614 | + * Gets the billing info array where keys match espresso_reg_page_billing_inputs(), |
|
615 | + * and keys are their cleaned values. @see EE_Attendee::save_and_clean_billing_info_for_payment_method() which was |
|
616 | + * used to save the billing info |
|
617 | + * |
|
618 | + * @param EE_Payment_Method $payment_method the _gateway_name property on the gateway class |
|
619 | + * @return EE_Form_Section_Proper|null |
|
620 | + * @throws EE_Error |
|
621 | + */ |
|
622 | + public function billing_info_for_payment_method($payment_method) |
|
623 | + { |
|
624 | + $pm_type = $payment_method->type_obj(); |
|
625 | + if (! $pm_type instanceof EE_PMT_Base) { |
|
626 | + return null; |
|
627 | + } |
|
628 | + $billing_info = $this->get_post_meta($this->get_billing_info_postmeta_name($payment_method), true); |
|
629 | + if (! $billing_info) { |
|
630 | + return null; |
|
631 | + } |
|
632 | + $billing_form = $pm_type->billing_form(); |
|
633 | + // double-check the form isn't totally hidden, in which case pretend there is no form |
|
634 | + $form_totally_hidden = true; |
|
635 | + foreach ($billing_form->inputs_in_subsections() as $input) { |
|
636 | + if (! $input->get_display_strategy() instanceof EE_Hidden_Display_Strategy) { |
|
637 | + $form_totally_hidden = false; |
|
638 | + break; |
|
639 | + } |
|
640 | + } |
|
641 | + if ($form_totally_hidden) { |
|
642 | + return null; |
|
643 | + } |
|
644 | + if ($billing_form instanceof EE_Form_Section_Proper) { |
|
645 | + $billing_form->receive_form_submission(array($billing_form->name() => $billing_info), false); |
|
646 | + } |
|
647 | + |
|
648 | + return $billing_form; |
|
649 | + } |
|
650 | + |
|
651 | + |
|
652 | + /** |
|
653 | + * Gets the postmeta key that holds this attendee's billing info for the |
|
654 | + * specified payment method |
|
655 | + * |
|
656 | + * @param EE_Payment_Method $payment_method |
|
657 | + * @return string |
|
658 | + * @throws EE_Error |
|
659 | + */ |
|
660 | + public function get_billing_info_postmeta_name($payment_method) |
|
661 | + { |
|
662 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
663 | + return 'billing_info_' . $payment_method->type_obj()->system_name(); |
|
664 | + } |
|
665 | + return null; |
|
666 | + } |
|
667 | + |
|
668 | + |
|
669 | + /** |
|
670 | + * Saves the billing info to the attendee. @see EE_Attendee::billing_info_for_payment_method() which is used to |
|
671 | + * retrieve it |
|
672 | + * |
|
673 | + * @param EE_Billing_Attendee_Info_Form $billing_form |
|
674 | + * @param EE_Payment_Method $payment_method |
|
675 | + * @return boolean |
|
676 | + * @throws EE_Error |
|
677 | + */ |
|
678 | + public function save_and_clean_billing_info_for_payment_method($billing_form, $payment_method) |
|
679 | + { |
|
680 | + if (! $billing_form instanceof EE_Billing_Attendee_Info_Form) { |
|
681 | + EE_Error::add_error(esc_html__('Cannot save billing info because there is none.', 'event_espresso')); |
|
682 | + return false; |
|
683 | + } |
|
684 | + $billing_form->clean_sensitive_data(); |
|
685 | + return update_post_meta( |
|
686 | + $this->ID(), |
|
687 | + $this->get_billing_info_postmeta_name($payment_method), |
|
688 | + $billing_form->input_values(true) |
|
689 | + ); |
|
690 | + } |
|
691 | + |
|
692 | + |
|
693 | + /** |
|
694 | + * Return the link to the admin details for the object. |
|
695 | + * |
|
696 | + * @return string |
|
697 | + * @throws EE_Error |
|
698 | + * @throws InvalidArgumentException |
|
699 | + * @throws InvalidDataTypeException |
|
700 | + * @throws InvalidInterfaceException |
|
701 | + * @throws ReflectionException |
|
702 | + */ |
|
703 | + public function get_admin_details_link() |
|
704 | + { |
|
705 | + return $this->get_admin_edit_link(); |
|
706 | + } |
|
707 | + |
|
708 | + |
|
709 | + /** |
|
710 | + * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
711 | + * |
|
712 | + * @return string |
|
713 | + * @throws EE_Error |
|
714 | + * @throws InvalidArgumentException |
|
715 | + * @throws ReflectionException |
|
716 | + * @throws InvalidDataTypeException |
|
717 | + * @throws InvalidInterfaceException |
|
718 | + */ |
|
719 | + public function get_admin_edit_link() |
|
720 | + { |
|
721 | + EE_Registry::instance()->load_helper('URL'); |
|
722 | + return EEH_URL::add_query_args_and_nonce( |
|
723 | + array( |
|
724 | + 'page' => 'espresso_registrations', |
|
725 | + 'action' => 'edit_attendee', |
|
726 | + 'post' => $this->ID(), |
|
727 | + ), |
|
728 | + admin_url('admin.php') |
|
729 | + ); |
|
730 | + } |
|
731 | + |
|
732 | + |
|
733 | + /** |
|
734 | + * Returns the link to a settings page for the object. |
|
735 | + * |
|
736 | + * @return string |
|
737 | + * @throws EE_Error |
|
738 | + * @throws InvalidArgumentException |
|
739 | + * @throws InvalidDataTypeException |
|
740 | + * @throws InvalidInterfaceException |
|
741 | + * @throws ReflectionException |
|
742 | + */ |
|
743 | + public function get_admin_settings_link() |
|
744 | + { |
|
745 | + return $this->get_admin_edit_link(); |
|
746 | + } |
|
747 | + |
|
748 | + |
|
749 | + /** |
|
750 | + * Returns the link to the "overview" for the object (typically the "list table" view). |
|
751 | + * |
|
752 | + * @return string |
|
753 | + * @throws EE_Error |
|
754 | + * @throws InvalidArgumentException |
|
755 | + * @throws ReflectionException |
|
756 | + * @throws InvalidDataTypeException |
|
757 | + * @throws InvalidInterfaceException |
|
758 | + */ |
|
759 | + public function get_admin_overview_link() |
|
760 | + { |
|
761 | + EE_Registry::instance()->load_helper('URL'); |
|
762 | + return EEH_URL::add_query_args_and_nonce( |
|
763 | + array( |
|
764 | + 'page' => 'espresso_registrations', |
|
765 | + 'action' => 'contact_list', |
|
766 | + ), |
|
767 | + admin_url('admin.php') |
|
768 | + ); |
|
769 | + } |
|
770 | 770 | } |
@@ -14,1732 +14,1732 @@ |
||
14 | 14 | class EE_Ticket extends EE_Soft_Delete_Base_Class implements EEI_Line_Item_Object, EEI_Event_Relation, EEI_Has_Icon |
15 | 15 | { |
16 | 16 | |
17 | - /** |
|
18 | - * The following constants are used by the ticket_status() method to indicate whether a ticket is on sale or not. |
|
19 | - */ |
|
20 | - const sold_out = 'TKS'; |
|
21 | - |
|
22 | - /** |
|
23 | - * |
|
24 | - */ |
|
25 | - const expired = 'TKE'; |
|
26 | - |
|
27 | - /** |
|
28 | - * |
|
29 | - */ |
|
30 | - const archived = 'TKA'; |
|
31 | - |
|
32 | - /** |
|
33 | - * |
|
34 | - */ |
|
35 | - const pending = 'TKP'; |
|
36 | - |
|
37 | - /** |
|
38 | - * |
|
39 | - */ |
|
40 | - const onsale = 'TKO'; |
|
41 | - |
|
42 | - /** |
|
43 | - * extra meta key for tracking ticket reservations |
|
44 | - * |
|
45 | - * @type string |
|
46 | - */ |
|
47 | - const META_KEY_TICKET_RESERVATIONS = 'ticket_reservations'; |
|
48 | - |
|
49 | - /** |
|
50 | - * cached result from method of the same name |
|
51 | - * |
|
52 | - * @var float $_ticket_total_with_taxes |
|
53 | - */ |
|
54 | - private $_ticket_total_with_taxes; |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * @param array $props_n_values incoming values |
|
59 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
60 | - * used.) |
|
61 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
62 | - * date_format and the second value is the time format |
|
63 | - * @return EE_Ticket |
|
64 | - * @throws EE_Error |
|
65 | - */ |
|
66 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
67 | - { |
|
68 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
69 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
70 | - } |
|
71 | - |
|
72 | - |
|
73 | - /** |
|
74 | - * @param array $props_n_values incoming values from the database |
|
75 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
76 | - * the website will be used. |
|
77 | - * @return EE_Ticket |
|
78 | - * @throws EE_Error |
|
79 | - */ |
|
80 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
81 | - { |
|
82 | - return new self($props_n_values, true, $timezone); |
|
83 | - } |
|
84 | - |
|
85 | - |
|
86 | - /** |
|
87 | - * @return bool |
|
88 | - * @throws EE_Error |
|
89 | - */ |
|
90 | - public function parent() |
|
91 | - { |
|
92 | - return $this->get('TKT_parent'); |
|
93 | - } |
|
94 | - |
|
95 | - |
|
96 | - /** |
|
97 | - * return if a ticket has quantities available for purchase |
|
98 | - * |
|
99 | - * @param int $DTT_ID the primary key for a particular datetime |
|
100 | - * @return boolean |
|
101 | - * @throws EE_Error |
|
102 | - */ |
|
103 | - public function available($DTT_ID = 0) |
|
104 | - { |
|
105 | - // are we checking availability for a particular datetime ? |
|
106 | - if ($DTT_ID) { |
|
107 | - // get that datetime object |
|
108 | - $datetime = $this->get_first_related('Datetime', array(array('DTT_ID' => $DTT_ID))); |
|
109 | - // if ticket sales for this datetime have exceeded the reg limit... |
|
110 | - if ($datetime instanceof EE_Datetime && $datetime->sold_out()) { |
|
111 | - return false; |
|
112 | - } |
|
113 | - } |
|
114 | - // datetime is still open for registration, but is this ticket sold out ? |
|
115 | - return $this->qty() < 1 || $this->qty() > $this->sold() ? true : false; |
|
116 | - } |
|
117 | - |
|
118 | - |
|
119 | - /** |
|
120 | - * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired |
|
121 | - * |
|
122 | - * @param bool $display true = we'll return a localized string, otherwise we just return the value of the |
|
123 | - * relevant status const |
|
124 | - * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save |
|
125 | - * further processing |
|
126 | - * @return mixed status int if the display string isn't requested |
|
127 | - * @throws EE_Error |
|
128 | - */ |
|
129 | - public function ticket_status($display = false, $remaining = null) |
|
130 | - { |
|
131 | - $remaining = is_bool($remaining) ? $remaining : $this->is_remaining(); |
|
132 | - if (! $remaining) { |
|
133 | - return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, false, 'sentence') : EE_Ticket::sold_out; |
|
134 | - } |
|
135 | - if ($this->get('TKT_deleted')) { |
|
136 | - return $display ? EEH_Template::pretty_status(EE_Ticket::archived, false, 'sentence') : EE_Ticket::archived; |
|
137 | - } |
|
138 | - if ($this->is_expired()) { |
|
139 | - return $display ? EEH_Template::pretty_status(EE_Ticket::expired, false, 'sentence') : EE_Ticket::expired; |
|
140 | - } |
|
141 | - if ($this->is_pending()) { |
|
142 | - return $display ? EEH_Template::pretty_status(EE_Ticket::pending, false, 'sentence') : EE_Ticket::pending; |
|
143 | - } |
|
144 | - if ($this->is_on_sale()) { |
|
145 | - return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence') : EE_Ticket::onsale; |
|
146 | - } |
|
147 | - return ''; |
|
148 | - } |
|
149 | - |
|
150 | - |
|
151 | - /** |
|
152 | - * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale |
|
153 | - * considering ALL the factors used for figuring that out. |
|
154 | - * |
|
155 | - * @access public |
|
156 | - * @param int $DTT_ID if an int above 0 is included here then we get a specific dtt. |
|
157 | - * @return boolean true = tickets remaining, false not. |
|
158 | - * @throws EE_Error |
|
159 | - */ |
|
160 | - public function is_remaining($DTT_ID = 0) |
|
161 | - { |
|
162 | - $num_remaining = $this->remaining($DTT_ID); |
|
163 | - if ($num_remaining === 0) { |
|
164 | - return false; |
|
165 | - } |
|
166 | - if ($num_remaining > 0 && $num_remaining < $this->min()) { |
|
167 | - return false; |
|
168 | - } |
|
169 | - return true; |
|
170 | - } |
|
171 | - |
|
172 | - |
|
173 | - /** |
|
174 | - * return the total number of tickets available for purchase |
|
175 | - * |
|
176 | - * @param int $DTT_ID the primary key for a particular datetime. |
|
177 | - * set to 0 for all related datetimes |
|
178 | - * @return int |
|
179 | - * @throws EE_Error |
|
180 | - */ |
|
181 | - public function remaining($DTT_ID = 0) |
|
182 | - { |
|
183 | - return $this->real_quantity_on_ticket('saleable', $DTT_ID); |
|
184 | - } |
|
185 | - |
|
186 | - |
|
187 | - /** |
|
188 | - * Gets min |
|
189 | - * |
|
190 | - * @return int |
|
191 | - * @throws EE_Error |
|
192 | - */ |
|
193 | - public function min() |
|
194 | - { |
|
195 | - return $this->get('TKT_min'); |
|
196 | - } |
|
197 | - |
|
198 | - |
|
199 | - /** |
|
200 | - * return if a ticket is no longer available cause its available dates have expired. |
|
201 | - * |
|
202 | - * @return boolean |
|
203 | - * @throws EE_Error |
|
204 | - */ |
|
205 | - public function is_expired() |
|
206 | - { |
|
207 | - return ($this->get_raw('TKT_end_date') < time()); |
|
208 | - } |
|
209 | - |
|
210 | - |
|
211 | - /** |
|
212 | - * Return if a ticket is yet to go on sale or not |
|
213 | - * |
|
214 | - * @return boolean |
|
215 | - * @throws EE_Error |
|
216 | - */ |
|
217 | - public function is_pending() |
|
218 | - { |
|
219 | - return ($this->get_raw('TKT_start_date') > time()); |
|
220 | - } |
|
221 | - |
|
222 | - |
|
223 | - /** |
|
224 | - * Return if a ticket is on sale or not |
|
225 | - * |
|
226 | - * @return boolean |
|
227 | - * @throws EE_Error |
|
228 | - */ |
|
229 | - public function is_on_sale() |
|
230 | - { |
|
231 | - return ($this->get_raw('TKT_start_date') < time() && $this->get_raw('TKT_end_date') > time()); |
|
232 | - } |
|
233 | - |
|
234 | - |
|
235 | - /** |
|
236 | - * This returns the chronologically last datetime that this ticket is associated with |
|
237 | - * |
|
238 | - * @param string $dt_frmt |
|
239 | - * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with |
|
240 | - * the end date ie: Jan 01 "to" Dec 31 |
|
241 | - * @return string |
|
242 | - * @throws EE_Error |
|
243 | - */ |
|
244 | - public function date_range($dt_frmt = '', $conjunction = ' - ') |
|
245 | - { |
|
246 | - $dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt; |
|
247 | - $first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->get_i18n_datetime('DTT_EVT_start', $dt_frmt) |
|
248 | - : ''; |
|
249 | - $last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->get_i18n_datetime('DTT_EVT_end', $dt_frmt) : ''; |
|
250 | - |
|
251 | - return $first_date && $last_date ? $first_date . $conjunction . $last_date : ''; |
|
252 | - } |
|
253 | - |
|
254 | - |
|
255 | - /** |
|
256 | - * This returns the chronologically first datetime that this ticket is associated with |
|
257 | - * |
|
258 | - * @return EE_Datetime |
|
259 | - * @throws EE_Error |
|
260 | - */ |
|
261 | - public function first_datetime() |
|
262 | - { |
|
263 | - $datetimes = $this->datetimes(array('limit' => 1)); |
|
264 | - return reset($datetimes); |
|
265 | - } |
|
266 | - |
|
267 | - |
|
268 | - /** |
|
269 | - * Gets all the datetimes this ticket can be used for attending. |
|
270 | - * Unless otherwise specified, orders datetimes by start date. |
|
271 | - * |
|
272 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
273 | - * @return EE_Datetime[]|EE_Base_Class[] |
|
274 | - * @throws EE_Error |
|
275 | - */ |
|
276 | - public function datetimes($query_params = array()) |
|
277 | - { |
|
278 | - if (! isset($query_params['order_by'])) { |
|
279 | - $query_params['order_by']['DTT_order'] = 'ASC'; |
|
280 | - } |
|
281 | - return $this->get_many_related('Datetime', $query_params); |
|
282 | - } |
|
283 | - |
|
284 | - |
|
285 | - /** |
|
286 | - * This returns the chronologically last datetime that this ticket is associated with |
|
287 | - * |
|
288 | - * @return EE_Datetime |
|
289 | - * @throws EE_Error |
|
290 | - */ |
|
291 | - public function last_datetime() |
|
292 | - { |
|
293 | - $datetimes = $this->datetimes(array('limit' => 1, 'order_by' => array('DTT_EVT_start' => 'DESC'))); |
|
294 | - return end($datetimes); |
|
295 | - } |
|
296 | - |
|
297 | - |
|
298 | - /** |
|
299 | - * This returns the total tickets sold depending on the given parameters. |
|
300 | - * |
|
301 | - * @param string $what Can be one of two options: 'ticket', 'datetime'. |
|
302 | - * 'ticket' = total ticket sales for all datetimes this ticket is related to |
|
303 | - * 'datetime' = total ticket sales for a specified datetime (required $dtt_id) |
|
304 | - * 'datetime' = total ticket sales in the datetime_ticket table. |
|
305 | - * If $dtt_id is not given then we return an array of sales indexed by datetime. |
|
306 | - * If $dtt_id IS given then we return the tickets sold for that given datetime. |
|
307 | - * @param int $dtt_id [optional] include the dtt_id with $what = 'datetime'. |
|
308 | - * @return mixed (array|int) how many tickets have sold |
|
309 | - * @throws EE_Error |
|
310 | - */ |
|
311 | - public function tickets_sold($what = 'ticket', $dtt_id = null) |
|
312 | - { |
|
313 | - $total = 0; |
|
314 | - $tickets_sold = $this->_all_tickets_sold(); |
|
315 | - switch ($what) { |
|
316 | - case 'ticket': |
|
317 | - return $tickets_sold['ticket']; |
|
318 | - break; |
|
319 | - case 'datetime': |
|
320 | - if (empty($tickets_sold['datetime'])) { |
|
321 | - return $total; |
|
322 | - } |
|
323 | - if (! empty($dtt_id) && ! isset($tickets_sold['datetime'][ $dtt_id ])) { |
|
324 | - EE_Error::add_error( |
|
325 | - esc_html__( |
|
326 | - 'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included. Are you SURE that is a datetime related to this ticket?', |
|
327 | - 'event_espresso' |
|
328 | - ), |
|
329 | - __FILE__, |
|
330 | - __FUNCTION__, |
|
331 | - __LINE__ |
|
332 | - ); |
|
333 | - return $total; |
|
334 | - } |
|
335 | - return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][ $dtt_id ]; |
|
336 | - break; |
|
337 | - default: |
|
338 | - return $total; |
|
339 | - } |
|
340 | - } |
|
341 | - |
|
342 | - |
|
343 | - /** |
|
344 | - * This returns an array indexed by datetime_id for tickets sold with this ticket. |
|
345 | - * |
|
346 | - * @return EE_Ticket[] |
|
347 | - * @throws EE_Error |
|
348 | - */ |
|
349 | - protected function _all_tickets_sold() |
|
350 | - { |
|
351 | - $datetimes = $this->get_many_related('Datetime'); |
|
352 | - $tickets_sold = array(); |
|
353 | - if (! empty($datetimes)) { |
|
354 | - foreach ($datetimes as $datetime) { |
|
355 | - $tickets_sold['datetime'][ $datetime->ID() ] = $datetime->get('DTT_sold'); |
|
356 | - } |
|
357 | - } |
|
358 | - // Tickets sold |
|
359 | - $tickets_sold['ticket'] = $this->sold(); |
|
360 | - return $tickets_sold; |
|
361 | - } |
|
362 | - |
|
363 | - |
|
364 | - /** |
|
365 | - * This returns the base price object for the ticket. |
|
366 | - * |
|
367 | - * @param bool $return_array whether to return as an array indexed by price id or just the object. |
|
368 | - * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[] |
|
369 | - * @throws EE_Error |
|
370 | - */ |
|
371 | - public function base_price($return_array = false) |
|
372 | - { |
|
373 | - $_where = array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price); |
|
374 | - return $return_array |
|
375 | - ? $this->get_many_related('Price', array($_where)) |
|
376 | - : $this->get_first_related('Price', array($_where)); |
|
377 | - } |
|
378 | - |
|
379 | - |
|
380 | - /** |
|
381 | - * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price) |
|
382 | - * |
|
383 | - * @access public |
|
384 | - * @return EE_Price[] |
|
385 | - * @throws EE_Error |
|
386 | - */ |
|
387 | - public function price_modifiers() |
|
388 | - { |
|
389 | - $query_params = array( |
|
390 | - 0 => array( |
|
391 | - 'Price_Type.PBT_ID' => array( |
|
392 | - 'NOT IN', |
|
393 | - array(EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax), |
|
394 | - ), |
|
395 | - ), |
|
396 | - ); |
|
397 | - return $this->prices($query_params); |
|
398 | - } |
|
399 | - |
|
400 | - |
|
401 | - /** |
|
402 | - * Gets all the prices that combine to form the final price of this ticket |
|
403 | - * |
|
404 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
405 | - * @return EE_Price[]|EE_Base_Class[] |
|
406 | - * @throws EE_Error |
|
407 | - */ |
|
408 | - public function prices($query_params = array()) |
|
409 | - { |
|
410 | - return $this->get_many_related('Price', $query_params); |
|
411 | - } |
|
412 | - |
|
413 | - |
|
414 | - /** |
|
415 | - * Gets all the ticket applicabilities (ie, relations between datetimes and tickets) |
|
416 | - * |
|
417 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
418 | - * @return EE_Datetime_Ticket|EE_Base_Class[] |
|
419 | - * @throws EE_Error |
|
420 | - */ |
|
421 | - public function datetime_tickets($query_params = array()) |
|
422 | - { |
|
423 | - return $this->get_many_related('Datetime_Ticket', $query_params); |
|
424 | - } |
|
425 | - |
|
426 | - |
|
427 | - /** |
|
428 | - * Gets all the datetimes from the db ordered by DTT_order |
|
429 | - * |
|
430 | - * @param boolean $show_expired |
|
431 | - * @param boolean $show_deleted |
|
432 | - * @return EE_Datetime[] |
|
433 | - * @throws EE_Error |
|
434 | - */ |
|
435 | - public function datetimes_ordered($show_expired = true, $show_deleted = false) |
|
436 | - { |
|
437 | - return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order( |
|
438 | - $this->ID(), |
|
439 | - $show_expired, |
|
440 | - $show_deleted |
|
441 | - ); |
|
442 | - } |
|
443 | - |
|
444 | - |
|
445 | - /** |
|
446 | - * Gets ID |
|
447 | - * |
|
448 | - * @return string |
|
449 | - * @throws EE_Error |
|
450 | - */ |
|
451 | - public function ID() |
|
452 | - { |
|
453 | - return $this->get('TKT_ID'); |
|
454 | - } |
|
455 | - |
|
456 | - |
|
457 | - /** |
|
458 | - * get the author of the ticket. |
|
459 | - * |
|
460 | - * @since 4.5.0 |
|
461 | - * @return int |
|
462 | - * @throws EE_Error |
|
463 | - */ |
|
464 | - public function wp_user() |
|
465 | - { |
|
466 | - return $this->get('TKT_wp_user'); |
|
467 | - } |
|
468 | - |
|
469 | - |
|
470 | - /** |
|
471 | - * Gets the template for the ticket |
|
472 | - * |
|
473 | - * @return EE_Ticket_Template|EE_Base_Class |
|
474 | - * @throws EE_Error |
|
475 | - */ |
|
476 | - public function template() |
|
477 | - { |
|
478 | - return $this->get_first_related('Ticket_Template'); |
|
479 | - } |
|
480 | - |
|
481 | - |
|
482 | - /** |
|
483 | - * Simply returns an array of EE_Price objects that are taxes. |
|
484 | - * |
|
485 | - * @return EE_Price[] |
|
486 | - * @throws EE_Error |
|
487 | - */ |
|
488 | - public function get_ticket_taxes_for_admin() |
|
489 | - { |
|
490 | - return EE_Taxes::get_taxes_for_admin(); |
|
491 | - } |
|
492 | - |
|
493 | - |
|
494 | - /** |
|
495 | - * @return float |
|
496 | - * @throws EE_Error |
|
497 | - */ |
|
498 | - public function ticket_price() |
|
499 | - { |
|
500 | - return $this->get('TKT_price'); |
|
501 | - } |
|
502 | - |
|
503 | - |
|
504 | - /** |
|
505 | - * @return mixed |
|
506 | - * @throws EE_Error |
|
507 | - */ |
|
508 | - public function pretty_price() |
|
509 | - { |
|
510 | - return $this->get_pretty('TKT_price'); |
|
511 | - } |
|
512 | - |
|
513 | - |
|
514 | - /** |
|
515 | - * @return bool |
|
516 | - * @throws EE_Error |
|
517 | - */ |
|
518 | - public function is_free() |
|
519 | - { |
|
520 | - return $this->get_ticket_total_with_taxes() === (float) 0; |
|
521 | - } |
|
522 | - |
|
523 | - |
|
524 | - /** |
|
525 | - * get_ticket_total_with_taxes |
|
526 | - * |
|
527 | - * @param bool $no_cache |
|
528 | - * @return float |
|
529 | - * @throws EE_Error |
|
530 | - */ |
|
531 | - public function get_ticket_total_with_taxes($no_cache = false) |
|
532 | - { |
|
533 | - if ($this->_ticket_total_with_taxes === null || $no_cache) { |
|
534 | - $this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin(); |
|
535 | - } |
|
536 | - return (float) $this->_ticket_total_with_taxes; |
|
537 | - } |
|
538 | - |
|
539 | - |
|
540 | - public function ensure_TKT_Price_correct() |
|
541 | - { |
|
542 | - $this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this)); |
|
543 | - $this->save(); |
|
544 | - } |
|
545 | - |
|
546 | - |
|
547 | - /** |
|
548 | - * @return float |
|
549 | - * @throws EE_Error |
|
550 | - */ |
|
551 | - public function get_ticket_subtotal() |
|
552 | - { |
|
553 | - return EE_Taxes::get_subtotal_for_admin($this); |
|
554 | - } |
|
555 | - |
|
556 | - |
|
557 | - /** |
|
558 | - * Returns the total taxes applied to this ticket |
|
559 | - * |
|
560 | - * @return float |
|
561 | - * @throws EE_Error |
|
562 | - */ |
|
563 | - public function get_ticket_taxes_total_for_admin() |
|
564 | - { |
|
565 | - return EE_Taxes::get_total_taxes_for_admin($this); |
|
566 | - } |
|
567 | - |
|
568 | - |
|
569 | - /** |
|
570 | - * Sets name |
|
571 | - * |
|
572 | - * @param string $name |
|
573 | - * @throws EE_Error |
|
574 | - */ |
|
575 | - public function set_name($name) |
|
576 | - { |
|
577 | - $this->set('TKT_name', $name); |
|
578 | - } |
|
579 | - |
|
580 | - |
|
581 | - /** |
|
582 | - * Gets description |
|
583 | - * |
|
584 | - * @return string |
|
585 | - * @throws EE_Error |
|
586 | - */ |
|
587 | - public function description() |
|
588 | - { |
|
589 | - return $this->get('TKT_description'); |
|
590 | - } |
|
591 | - |
|
592 | - |
|
593 | - /** |
|
594 | - * Sets description |
|
595 | - * |
|
596 | - * @param string $description |
|
597 | - * @throws EE_Error |
|
598 | - */ |
|
599 | - public function set_description($description) |
|
600 | - { |
|
601 | - $this->set('TKT_description', $description); |
|
602 | - } |
|
603 | - |
|
604 | - |
|
605 | - /** |
|
606 | - * Gets start_date |
|
607 | - * |
|
608 | - * @param string $dt_frmt |
|
609 | - * @param string $tm_frmt |
|
610 | - * @return string |
|
611 | - * @throws EE_Error |
|
612 | - */ |
|
613 | - public function start_date($dt_frmt = '', $tm_frmt = '') |
|
614 | - { |
|
615 | - return $this->_get_datetime('TKT_start_date', $dt_frmt, $tm_frmt); |
|
616 | - } |
|
617 | - |
|
618 | - |
|
619 | - /** |
|
620 | - * Sets start_date |
|
621 | - * |
|
622 | - * @param string $start_date |
|
623 | - * @return void |
|
624 | - * @throws EE_Error |
|
625 | - */ |
|
626 | - public function set_start_date($start_date) |
|
627 | - { |
|
628 | - $this->_set_date_time('B', $start_date, 'TKT_start_date'); |
|
629 | - } |
|
630 | - |
|
631 | - |
|
632 | - /** |
|
633 | - * Gets end_date |
|
634 | - * |
|
635 | - * @param string $dt_frmt |
|
636 | - * @param string $tm_frmt |
|
637 | - * @return string |
|
638 | - * @throws EE_Error |
|
639 | - */ |
|
640 | - public function end_date($dt_frmt = '', $tm_frmt = '') |
|
641 | - { |
|
642 | - return $this->_get_datetime('TKT_end_date', $dt_frmt, $tm_frmt); |
|
643 | - } |
|
644 | - |
|
645 | - |
|
646 | - /** |
|
647 | - * Sets end_date |
|
648 | - * |
|
649 | - * @param string $end_date |
|
650 | - * @return void |
|
651 | - * @throws EE_Error |
|
652 | - */ |
|
653 | - public function set_end_date($end_date) |
|
654 | - { |
|
655 | - $this->_set_date_time('B', $end_date, 'TKT_end_date'); |
|
656 | - } |
|
657 | - |
|
658 | - |
|
659 | - /** |
|
660 | - * Sets sell until time |
|
661 | - * |
|
662 | - * @since 4.5.0 |
|
663 | - * @param string $time a string representation of the sell until time (ex 9am or 7:30pm) |
|
664 | - * @throws EE_Error |
|
665 | - */ |
|
666 | - public function set_end_time($time) |
|
667 | - { |
|
668 | - $this->_set_time_for($time, 'TKT_end_date'); |
|
669 | - } |
|
670 | - |
|
671 | - |
|
672 | - /** |
|
673 | - * Sets min |
|
674 | - * |
|
675 | - * @param int $min |
|
676 | - * @return void |
|
677 | - * @throws EE_Error |
|
678 | - */ |
|
679 | - public function set_min($min) |
|
680 | - { |
|
681 | - $this->set('TKT_min', $min); |
|
682 | - } |
|
683 | - |
|
684 | - |
|
685 | - /** |
|
686 | - * Gets max |
|
687 | - * |
|
688 | - * @return int |
|
689 | - * @throws EE_Error |
|
690 | - */ |
|
691 | - public function max() |
|
692 | - { |
|
693 | - return $this->get('TKT_max'); |
|
694 | - } |
|
695 | - |
|
696 | - |
|
697 | - /** |
|
698 | - * Sets max |
|
699 | - * |
|
700 | - * @param int $max |
|
701 | - * @return void |
|
702 | - * @throws EE_Error |
|
703 | - */ |
|
704 | - public function set_max($max) |
|
705 | - { |
|
706 | - $this->set('TKT_max', $max); |
|
707 | - } |
|
708 | - |
|
709 | - |
|
710 | - /** |
|
711 | - * Sets price |
|
712 | - * |
|
713 | - * @param float $price |
|
714 | - * @return void |
|
715 | - * @throws EE_Error |
|
716 | - */ |
|
717 | - public function set_price($price) |
|
718 | - { |
|
719 | - $this->set('TKT_price', $price); |
|
720 | - } |
|
721 | - |
|
722 | - |
|
723 | - /** |
|
724 | - * Gets sold |
|
725 | - * |
|
726 | - * @return int |
|
727 | - * @throws EE_Error |
|
728 | - */ |
|
729 | - public function sold() |
|
730 | - { |
|
731 | - return $this->get_raw('TKT_sold'); |
|
732 | - } |
|
733 | - |
|
734 | - |
|
735 | - /** |
|
736 | - * Sets sold |
|
737 | - * |
|
738 | - * @param int $sold |
|
739 | - * @return void |
|
740 | - * @throws EE_Error |
|
741 | - */ |
|
742 | - public function set_sold($sold) |
|
743 | - { |
|
744 | - // sold can not go below zero |
|
745 | - $sold = max(0, $sold); |
|
746 | - $this->set('TKT_sold', $sold); |
|
747 | - } |
|
748 | - |
|
749 | - |
|
750 | - /** |
|
751 | - * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its |
|
752 | - * associated datetimes. |
|
753 | - * |
|
754 | - * @since 4.9.80.p |
|
755 | - * @param int $qty |
|
756 | - * @return boolean |
|
757 | - * @throws EE_Error |
|
758 | - * @throws InvalidArgumentException |
|
759 | - * @throws InvalidDataTypeException |
|
760 | - * @throws InvalidInterfaceException |
|
761 | - * @throws ReflectionException |
|
762 | - */ |
|
763 | - public function increaseSold($qty = 1) |
|
764 | - { |
|
765 | - $qty = absint($qty); |
|
766 | - // increment sold and decrement reserved datetime quantities simultaneously |
|
767 | - // don't worry about failures, because they must have already had a spot reserved |
|
768 | - $this->increaseSoldForDatetimes($qty); |
|
769 | - // Increment and decrement ticket quantities simultaneously |
|
770 | - $success = $this->adjustNumericFieldsInDb( |
|
771 | - [ |
|
772 | - 'TKT_reserved' => $qty * -1, |
|
773 | - 'TKT_sold' => $qty |
|
774 | - ] |
|
775 | - ); |
|
776 | - do_action( |
|
777 | - 'AHEE__EE_Ticket__increase_sold', |
|
778 | - $this, |
|
779 | - $qty, |
|
780 | - $this->sold(), |
|
781 | - $success |
|
782 | - ); |
|
783 | - return $success; |
|
784 | - } |
|
785 | - |
|
786 | - /** |
|
787 | - * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty. |
|
788 | - * |
|
789 | - * @since 4.9.80.p |
|
790 | - * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts), |
|
791 | - * Negative means to decreases old counts (and increase reserved counts). |
|
792 | - * @param EE_Datetime[] $datetimes |
|
793 | - * @throws EE_Error |
|
794 | - * @throws InvalidArgumentException |
|
795 | - * @throws InvalidDataTypeException |
|
796 | - * @throws InvalidInterfaceException |
|
797 | - * @throws ReflectionException |
|
798 | - */ |
|
799 | - protected function increaseSoldForDatetimes($qty, array $datetimes = []) |
|
800 | - { |
|
801 | - $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
802 | - foreach ($datetimes as $datetime) { |
|
803 | - $datetime->increaseSold($qty); |
|
804 | - } |
|
805 | - } |
|
806 | - |
|
807 | - |
|
808 | - |
|
809 | - /** |
|
810 | - * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the |
|
811 | - * DB and then updates the model objects. |
|
812 | - * Does not affect the reserved counts. |
|
813 | - * |
|
814 | - * @since 4.9.80.p |
|
815 | - * @param int $qty |
|
816 | - * @return boolean |
|
817 | - * @throws EE_Error |
|
818 | - * @throws InvalidArgumentException |
|
819 | - * @throws InvalidDataTypeException |
|
820 | - * @throws InvalidInterfaceException |
|
821 | - * @throws ReflectionException |
|
822 | - */ |
|
823 | - public function decreaseSold($qty = 1) |
|
824 | - { |
|
825 | - $qty = absint($qty); |
|
826 | - $this->decreaseSoldForDatetimes($qty); |
|
827 | - $success = $this->adjustNumericFieldsInDb( |
|
828 | - [ |
|
829 | - 'TKT_sold' => $qty * -1 |
|
830 | - ] |
|
831 | - ); |
|
832 | - do_action( |
|
833 | - 'AHEE__EE_Ticket__decrease_sold', |
|
834 | - $this, |
|
835 | - $qty, |
|
836 | - $this->sold(), |
|
837 | - $success |
|
838 | - ); |
|
839 | - return $success; |
|
840 | - } |
|
841 | - |
|
842 | - |
|
843 | - /** |
|
844 | - * Decreases sold on related datetimes |
|
845 | - * |
|
846 | - * @since 4.9.80.p |
|
847 | - * @param int $qty |
|
848 | - * @param EE_Datetime[] $datetimes |
|
849 | - * @return void |
|
850 | - * @throws EE_Error |
|
851 | - * @throws InvalidArgumentException |
|
852 | - * @throws InvalidDataTypeException |
|
853 | - * @throws InvalidInterfaceException |
|
854 | - * @throws ReflectionException |
|
855 | - */ |
|
856 | - protected function decreaseSoldForDatetimes($qty = 1, array $datetimes = []) |
|
857 | - { |
|
858 | - $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
859 | - if (is_array($datetimes)) { |
|
860 | - foreach ($datetimes as $datetime) { |
|
861 | - if ($datetime instanceof EE_Datetime) { |
|
862 | - $datetime->decreaseSold($qty); |
|
863 | - } |
|
864 | - } |
|
865 | - } |
|
866 | - } |
|
867 | - |
|
868 | - |
|
869 | - /** |
|
870 | - * Gets qty of reserved tickets |
|
871 | - * |
|
872 | - * @return int |
|
873 | - * @throws EE_Error |
|
874 | - */ |
|
875 | - public function reserved() |
|
876 | - { |
|
877 | - return $this->get_raw('TKT_reserved'); |
|
878 | - } |
|
879 | - |
|
880 | - |
|
881 | - /** |
|
882 | - * Sets reserved |
|
883 | - * |
|
884 | - * @param int $reserved |
|
885 | - * @return void |
|
886 | - * @throws EE_Error |
|
887 | - */ |
|
888 | - public function set_reserved($reserved) |
|
889 | - { |
|
890 | - // reserved can not go below zero |
|
891 | - $reserved = max(0, (int) $reserved); |
|
892 | - $this->set('TKT_reserved', $reserved); |
|
893 | - } |
|
894 | - |
|
895 | - |
|
896 | - /** |
|
897 | - * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
898 | - * |
|
899 | - * @since 4.9.80.p |
|
900 | - * @param int $qty |
|
901 | - * @param string $source |
|
902 | - * @return bool whether we successfully reserved the ticket or not. |
|
903 | - * @throws EE_Error |
|
904 | - * @throws InvalidArgumentException |
|
905 | - * @throws ReflectionException |
|
906 | - * @throws InvalidDataTypeException |
|
907 | - * @throws InvalidInterfaceException |
|
908 | - */ |
|
909 | - public function increaseReserved($qty = 1, $source = 'unknown') |
|
910 | - { |
|
911 | - $qty = absint($qty); |
|
912 | - do_action( |
|
913 | - 'AHEE__EE_Ticket__increase_reserved__begin', |
|
914 | - $this, |
|
915 | - $qty, |
|
916 | - $source |
|
917 | - ); |
|
918 | - $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "{$qty} from {$source}"); |
|
919 | - $success = false; |
|
920 | - $datetimes_adjusted_successfully = $this->increaseReservedForDatetimes($qty); |
|
921 | - if ($datetimes_adjusted_successfully) { |
|
922 | - $success = $this->incrementFieldConditionallyInDb( |
|
923 | - 'TKT_reserved', |
|
924 | - 'TKT_sold', |
|
925 | - 'TKT_qty', |
|
926 | - $qty |
|
927 | - ); |
|
928 | - if (! $success) { |
|
929 | - // The datetimes were successfully bumped, but not the |
|
930 | - // ticket. So we need to manually rollback the datetimes. |
|
931 | - $this->decreaseReservedForDatetimes($qty); |
|
932 | - } |
|
933 | - } |
|
934 | - do_action( |
|
935 | - 'AHEE__EE_Ticket__increase_reserved', |
|
936 | - $this, |
|
937 | - $qty, |
|
938 | - $this->reserved(), |
|
939 | - $success |
|
940 | - ); |
|
941 | - return $success; |
|
942 | - } |
|
943 | - |
|
944 | - |
|
945 | - /** |
|
946 | - * Increases reserved counts on related datetimes |
|
947 | - * |
|
948 | - * @since 4.9.80.p |
|
949 | - * @param int $qty |
|
950 | - * @param EE_Datetime[] $datetimes |
|
951 | - * @return boolean indicating success |
|
952 | - * @throws EE_Error |
|
953 | - * @throws InvalidArgumentException |
|
954 | - * @throws InvalidDataTypeException |
|
955 | - * @throws InvalidInterfaceException |
|
956 | - * @throws ReflectionException |
|
957 | - */ |
|
958 | - protected function increaseReservedForDatetimes($qty = 1, array $datetimes = []) |
|
959 | - { |
|
960 | - $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
961 | - $datetimes_updated = []; |
|
962 | - $limit_exceeded = false; |
|
963 | - if (is_array($datetimes)) { |
|
964 | - foreach ($datetimes as $datetime) { |
|
965 | - if ($datetime instanceof EE_Datetime) { |
|
966 | - if ($datetime->increaseReserved($qty)) { |
|
967 | - $datetimes_updated[] = $datetime; |
|
968 | - } else { |
|
969 | - $limit_exceeded = true; |
|
970 | - break; |
|
971 | - } |
|
972 | - } |
|
973 | - } |
|
974 | - // If somewhere along the way we detected a datetime whose |
|
975 | - // limit was exceeded, do a manual rollback. |
|
976 | - if ($limit_exceeded) { |
|
977 | - $this->decreaseReservedForDatetimes($qty, $datetimes_updated); |
|
978 | - return false; |
|
979 | - } |
|
980 | - } |
|
981 | - return true; |
|
982 | - } |
|
983 | - |
|
984 | - |
|
985 | - /** |
|
986 | - * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
987 | - * |
|
988 | - * @since 4.9.80.p |
|
989 | - * @param int $qty |
|
990 | - * @param bool $adjust_datetimes |
|
991 | - * @param string $source |
|
992 | - * @return boolean |
|
993 | - * @throws EE_Error |
|
994 | - * @throws InvalidArgumentException |
|
995 | - * @throws ReflectionException |
|
996 | - * @throws InvalidDataTypeException |
|
997 | - * @throws InvalidInterfaceException |
|
998 | - */ |
|
999 | - public function decreaseReserved($qty = 1, $adjust_datetimes = true, $source = 'unknown') |
|
1000 | - { |
|
1001 | - $qty = absint($qty); |
|
1002 | - $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "-{$qty} from {$source}"); |
|
1003 | - if ($adjust_datetimes) { |
|
1004 | - $this->decreaseReservedForDatetimes($qty); |
|
1005 | - } |
|
1006 | - $success = $this->adjustNumericFieldsInDb( |
|
1007 | - [ |
|
1008 | - 'TKT_reserved' => $qty * -1 |
|
1009 | - ] |
|
1010 | - ); |
|
1011 | - do_action( |
|
1012 | - 'AHEE__EE_Ticket__decrease_reserved', |
|
1013 | - $this, |
|
1014 | - $qty, |
|
1015 | - $this->reserved(), |
|
1016 | - $success |
|
1017 | - ); |
|
1018 | - return $success; |
|
1019 | - } |
|
1020 | - |
|
1021 | - |
|
1022 | - /** |
|
1023 | - * Decreases the reserved count on the specified datetimes. |
|
1024 | - * |
|
1025 | - * @since 4.9.80.p |
|
1026 | - * @param int $qty |
|
1027 | - * @param EE_Datetime[] $datetimes |
|
1028 | - * @throws EE_Error |
|
1029 | - * @throws InvalidArgumentException |
|
1030 | - * @throws ReflectionException |
|
1031 | - * @throws InvalidDataTypeException |
|
1032 | - * @throws InvalidInterfaceException |
|
1033 | - */ |
|
1034 | - protected function decreaseReservedForDatetimes($qty = 1, array $datetimes = []) |
|
1035 | - { |
|
1036 | - $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
1037 | - foreach ($datetimes as $datetime) { |
|
1038 | - if ($datetime instanceof EE_Datetime) { |
|
1039 | - $datetime->decreaseReserved($qty); |
|
1040 | - } |
|
1041 | - } |
|
1042 | - } |
|
1043 | - |
|
1044 | - |
|
1045 | - /** |
|
1046 | - * Gets ticket quantity |
|
1047 | - * |
|
1048 | - * @param string $context ticket quantity is somewhat subjective depending on the exact information sought |
|
1049 | - * therefore $context can be one of three values: '', 'reg_limit', or 'saleable' |
|
1050 | - * '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects |
|
1051 | - * REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes |
|
1052 | - * SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and |
|
1053 | - * is therefore the truest measure of tickets that can be purchased at the moment |
|
1054 | - * @return int |
|
1055 | - * @throws EE_Error |
|
1056 | - */ |
|
1057 | - public function qty($context = '') |
|
1058 | - { |
|
1059 | - switch ($context) { |
|
1060 | - case 'reg_limit': |
|
1061 | - return $this->real_quantity_on_ticket(); |
|
1062 | - case 'saleable': |
|
1063 | - return $this->real_quantity_on_ticket('saleable'); |
|
1064 | - default: |
|
1065 | - return $this->get_raw('TKT_qty'); |
|
1066 | - } |
|
1067 | - } |
|
1068 | - |
|
1069 | - |
|
1070 | - /** |
|
1071 | - * Gets ticket quantity |
|
1072 | - * |
|
1073 | - * @param string $context ticket quantity is somewhat subjective depending on the exact information sought |
|
1074 | - * therefore $context can be one of two values: 'reg_limit', or 'saleable' |
|
1075 | - * REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes |
|
1076 | - * SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and |
|
1077 | - * is therefore the truest measure of tickets that can be purchased at the moment |
|
1078 | - * @param int $DTT_ID the primary key for a particular datetime. |
|
1079 | - * set to 0 for all related datetimes |
|
1080 | - * @return int |
|
1081 | - * @throws EE_Error |
|
1082 | - */ |
|
1083 | - public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0) |
|
1084 | - { |
|
1085 | - $raw = $this->get_raw('TKT_qty'); |
|
1086 | - // return immediately if it's zero |
|
1087 | - if ($raw === 0) { |
|
1088 | - return $raw; |
|
1089 | - } |
|
1090 | - // echo "\n\n<br />Ticket: " . $this->name() . '<br />'; |
|
1091 | - // ensure qty doesn't exceed raw value for THIS ticket |
|
1092 | - $qty = min(EE_INF, $raw); |
|
1093 | - // echo "\n . qty: " . $qty . '<br />'; |
|
1094 | - // calculate this ticket's total sales and reservations |
|
1095 | - $sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved(); |
|
1096 | - // echo "\n . sold: " . $this->sold() . '<br />'; |
|
1097 | - // echo "\n . reserved: " . $this->reserved() . '<br />'; |
|
1098 | - // echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />'; |
|
1099 | - // first we need to calculate the maximum number of tickets available for the datetime |
|
1100 | - // do we want data for one datetime or all of them ? |
|
1101 | - $query_params = $DTT_ID ? array(array('DTT_ID' => $DTT_ID)) : array(); |
|
1102 | - $datetimes = $this->datetimes($query_params); |
|
1103 | - if (is_array($datetimes) && ! empty($datetimes)) { |
|
1104 | - foreach ($datetimes as $datetime) { |
|
1105 | - if ($datetime instanceof EE_Datetime) { |
|
1106 | - $datetime->refresh_from_db(); |
|
1107 | - // echo "\n . . datetime name: " . $datetime->name() . '<br />'; |
|
1108 | - // echo "\n . . datetime ID: " . $datetime->ID() . '<br />'; |
|
1109 | - // initialize with no restrictions for each datetime |
|
1110 | - // but adjust datetime qty based on datetime reg limit |
|
1111 | - $datetime_qty = min(EE_INF, $datetime->reg_limit()); |
|
1112 | - // echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />'; |
|
1113 | - // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />'; |
|
1114 | - // if we want the actual saleable amount, then we need to consider OTHER ticket sales |
|
1115 | - // and reservations for this datetime, that do NOT include sales and reservations |
|
1116 | - // for this ticket (so we add $this->sold() and $this->reserved() back in) |
|
1117 | - if ($context === 'saleable') { |
|
1118 | - $datetime_qty = max( |
|
1119 | - $datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket, |
|
1120 | - 0 |
|
1121 | - ); |
|
1122 | - // echo "\n . . . datetime sold: " . $datetime->sold() . '<br />'; |
|
1123 | - // echo "\n . . . datetime reserved: " . $datetime->reserved() . '<br />'; |
|
1124 | - // echo "\n . . . datetime sold_and_reserved: " . $datetime->sold_and_reserved() . '<br />'; |
|
1125 | - // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />'; |
|
1126 | - $datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0; |
|
1127 | - // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />'; |
|
1128 | - } |
|
1129 | - $qty = min($datetime_qty, $qty); |
|
1130 | - // echo "\n . . qty: " . $qty . '<br />'; |
|
1131 | - } |
|
1132 | - } |
|
1133 | - } |
|
1134 | - // NOW that we know the maximum number of tickets available for the datetime |
|
1135 | - // we can finally factor in the details for this specific ticket |
|
1136 | - if ($qty > 0 && $context === 'saleable') { |
|
1137 | - // and subtract the sales for THIS ticket |
|
1138 | - $qty = max($qty - $sold_and_reserved_for_this_ticket, 0); |
|
1139 | - // echo "\n . qty: " . $qty . '<br />'; |
|
1140 | - } |
|
1141 | - // echo "\nFINAL QTY: " . $qty . "<br /><br />"; |
|
1142 | - return $qty; |
|
1143 | - } |
|
1144 | - |
|
1145 | - |
|
1146 | - /** |
|
1147 | - * Sets qty - IMPORTANT!!! Does NOT allow QTY to be set higher than the lowest reg limit of any related datetimes |
|
1148 | - * |
|
1149 | - * @param int $qty |
|
1150 | - * @return void |
|
1151 | - * @throws EE_Error |
|
1152 | - */ |
|
1153 | - public function set_qty($qty) |
|
1154 | - { |
|
1155 | - $datetimes = $this->datetimes(); |
|
1156 | - foreach ($datetimes as $datetime) { |
|
1157 | - if ($datetime instanceof EE_Datetime) { |
|
1158 | - $qty = min($qty, $datetime->reg_limit()); |
|
1159 | - } |
|
1160 | - } |
|
1161 | - $this->set('TKT_qty', $qty); |
|
1162 | - } |
|
1163 | - |
|
1164 | - |
|
1165 | - /** |
|
1166 | - * Gets uses |
|
1167 | - * |
|
1168 | - * @return int |
|
1169 | - * @throws EE_Error |
|
1170 | - */ |
|
1171 | - public function uses() |
|
1172 | - { |
|
1173 | - return $this->get('TKT_uses'); |
|
1174 | - } |
|
1175 | - |
|
1176 | - |
|
1177 | - /** |
|
1178 | - * Sets uses |
|
1179 | - * |
|
1180 | - * @param int $uses |
|
1181 | - * @return void |
|
1182 | - * @throws EE_Error |
|
1183 | - */ |
|
1184 | - public function set_uses($uses) |
|
1185 | - { |
|
1186 | - $this->set('TKT_uses', $uses); |
|
1187 | - } |
|
1188 | - |
|
1189 | - |
|
1190 | - /** |
|
1191 | - * returns whether ticket is required or not. |
|
1192 | - * |
|
1193 | - * @return boolean |
|
1194 | - * @throws EE_Error |
|
1195 | - */ |
|
1196 | - public function required() |
|
1197 | - { |
|
1198 | - return $this->get('TKT_required'); |
|
1199 | - } |
|
1200 | - |
|
1201 | - |
|
1202 | - /** |
|
1203 | - * sets the TKT_required property |
|
1204 | - * |
|
1205 | - * @param boolean $required |
|
1206 | - * @return void |
|
1207 | - * @throws EE_Error |
|
1208 | - */ |
|
1209 | - public function set_required($required) |
|
1210 | - { |
|
1211 | - $this->set('TKT_required', $required); |
|
1212 | - } |
|
1213 | - |
|
1214 | - |
|
1215 | - /** |
|
1216 | - * Gets taxable |
|
1217 | - * |
|
1218 | - * @return boolean |
|
1219 | - * @throws EE_Error |
|
1220 | - */ |
|
1221 | - public function taxable() |
|
1222 | - { |
|
1223 | - return $this->get('TKT_taxable'); |
|
1224 | - } |
|
1225 | - |
|
1226 | - |
|
1227 | - /** |
|
1228 | - * Sets taxable |
|
1229 | - * |
|
1230 | - * @param boolean $taxable |
|
1231 | - * @return void |
|
1232 | - * @throws EE_Error |
|
1233 | - */ |
|
1234 | - public function set_taxable($taxable) |
|
1235 | - { |
|
1236 | - $this->set('TKT_taxable', $taxable); |
|
1237 | - } |
|
1238 | - |
|
1239 | - |
|
1240 | - /** |
|
1241 | - * Gets is_default |
|
1242 | - * |
|
1243 | - * @return boolean |
|
1244 | - * @throws EE_Error |
|
1245 | - */ |
|
1246 | - public function is_default() |
|
1247 | - { |
|
1248 | - return $this->get('TKT_is_default'); |
|
1249 | - } |
|
1250 | - |
|
1251 | - |
|
1252 | - /** |
|
1253 | - * Sets is_default |
|
1254 | - * |
|
1255 | - * @param boolean $is_default |
|
1256 | - * @return void |
|
1257 | - * @throws EE_Error |
|
1258 | - */ |
|
1259 | - public function set_is_default($is_default) |
|
1260 | - { |
|
1261 | - $this->set('TKT_is_default', $is_default); |
|
1262 | - } |
|
1263 | - |
|
1264 | - |
|
1265 | - /** |
|
1266 | - * Gets order |
|
1267 | - * |
|
1268 | - * @return int |
|
1269 | - * @throws EE_Error |
|
1270 | - */ |
|
1271 | - public function order() |
|
1272 | - { |
|
1273 | - return $this->get('TKT_order'); |
|
1274 | - } |
|
1275 | - |
|
1276 | - |
|
1277 | - /** |
|
1278 | - * Sets order |
|
1279 | - * |
|
1280 | - * @param int $order |
|
1281 | - * @return void |
|
1282 | - * @throws EE_Error |
|
1283 | - */ |
|
1284 | - public function set_order($order) |
|
1285 | - { |
|
1286 | - $this->set('TKT_order', $order); |
|
1287 | - } |
|
1288 | - |
|
1289 | - |
|
1290 | - /** |
|
1291 | - * Gets row |
|
1292 | - * |
|
1293 | - * @return int |
|
1294 | - * @throws EE_Error |
|
1295 | - */ |
|
1296 | - public function row() |
|
1297 | - { |
|
1298 | - return $this->get('TKT_row'); |
|
1299 | - } |
|
1300 | - |
|
1301 | - |
|
1302 | - /** |
|
1303 | - * Sets row |
|
1304 | - * |
|
1305 | - * @param int $row |
|
1306 | - * @return void |
|
1307 | - * @throws EE_Error |
|
1308 | - */ |
|
1309 | - public function set_row($row) |
|
1310 | - { |
|
1311 | - $this->set('TKT_row', $row); |
|
1312 | - } |
|
1313 | - |
|
1314 | - |
|
1315 | - /** |
|
1316 | - * Gets deleted |
|
1317 | - * |
|
1318 | - * @return boolean |
|
1319 | - * @throws EE_Error |
|
1320 | - */ |
|
1321 | - public function deleted() |
|
1322 | - { |
|
1323 | - return $this->get('TKT_deleted'); |
|
1324 | - } |
|
1325 | - |
|
1326 | - |
|
1327 | - /** |
|
1328 | - * Sets deleted |
|
1329 | - * |
|
1330 | - * @param boolean $deleted |
|
1331 | - * @return void |
|
1332 | - * @throws EE_Error |
|
1333 | - */ |
|
1334 | - public function set_deleted($deleted) |
|
1335 | - { |
|
1336 | - $this->set('TKT_deleted', $deleted); |
|
1337 | - } |
|
1338 | - |
|
1339 | - |
|
1340 | - /** |
|
1341 | - * Gets parent |
|
1342 | - * |
|
1343 | - * @return int |
|
1344 | - * @throws EE_Error |
|
1345 | - */ |
|
1346 | - public function parent_ID() |
|
1347 | - { |
|
1348 | - return $this->get('TKT_parent'); |
|
1349 | - } |
|
1350 | - |
|
1351 | - |
|
1352 | - /** |
|
1353 | - * Sets parent |
|
1354 | - * |
|
1355 | - * @param int $parent |
|
1356 | - * @return void |
|
1357 | - * @throws EE_Error |
|
1358 | - */ |
|
1359 | - public function set_parent_ID($parent) |
|
1360 | - { |
|
1361 | - $this->set('TKT_parent', $parent); |
|
1362 | - } |
|
1363 | - |
|
1364 | - |
|
1365 | - /** |
|
1366 | - * Gets a string which is handy for showing in gateways etc that describes the ticket. |
|
1367 | - * |
|
1368 | - * @return string |
|
1369 | - * @throws EE_Error |
|
1370 | - */ |
|
1371 | - public function name_and_info() |
|
1372 | - { |
|
1373 | - $times = array(); |
|
1374 | - foreach ($this->datetimes() as $datetime) { |
|
1375 | - $times[] = $datetime->start_date_and_time(); |
|
1376 | - } |
|
1377 | - return $this->name() . ' @ ' . implode(', ', $times) . ' for ' . $this->pretty_price(); |
|
1378 | - } |
|
1379 | - |
|
1380 | - |
|
1381 | - /** |
|
1382 | - * Gets name |
|
1383 | - * |
|
1384 | - * @return string |
|
1385 | - * @throws EE_Error |
|
1386 | - */ |
|
1387 | - public function name() |
|
1388 | - { |
|
1389 | - return $this->get('TKT_name'); |
|
1390 | - } |
|
1391 | - |
|
1392 | - |
|
1393 | - /** |
|
1394 | - * Gets price |
|
1395 | - * |
|
1396 | - * @return float |
|
1397 | - * @throws EE_Error |
|
1398 | - */ |
|
1399 | - public function price() |
|
1400 | - { |
|
1401 | - return $this->get('TKT_price'); |
|
1402 | - } |
|
1403 | - |
|
1404 | - |
|
1405 | - /** |
|
1406 | - * Gets all the registrations for this ticket |
|
1407 | - * |
|
1408 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1409 | - * @return EE_Registration[]|EE_Base_Class[] |
|
1410 | - * @throws EE_Error |
|
1411 | - */ |
|
1412 | - public function registrations($query_params = array()) |
|
1413 | - { |
|
1414 | - return $this->get_many_related('Registration', $query_params); |
|
1415 | - } |
|
1416 | - |
|
1417 | - |
|
1418 | - /** |
|
1419 | - * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket. |
|
1420 | - * |
|
1421 | - * @return int |
|
1422 | - * @throws EE_Error |
|
1423 | - */ |
|
1424 | - public function update_tickets_sold() |
|
1425 | - { |
|
1426 | - $count_regs_for_this_ticket = $this->count_registrations( |
|
1427 | - array( |
|
1428 | - array( |
|
1429 | - 'STS_ID' => EEM_Registration::status_id_approved, |
|
1430 | - 'REG_deleted' => 0, |
|
1431 | - ), |
|
1432 | - ) |
|
1433 | - ); |
|
1434 | - $this->set_sold($count_regs_for_this_ticket); |
|
1435 | - $this->save(); |
|
1436 | - return $count_regs_for_this_ticket; |
|
1437 | - } |
|
1438 | - |
|
1439 | - |
|
1440 | - /** |
|
1441 | - * Counts the registrations for this ticket |
|
1442 | - * |
|
1443 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1444 | - * @return int |
|
1445 | - */ |
|
1446 | - public function count_registrations($query_params = array()) |
|
1447 | - { |
|
1448 | - return $this->count_related('Registration', $query_params); |
|
1449 | - } |
|
1450 | - |
|
1451 | - |
|
1452 | - /** |
|
1453 | - * Implementation for EEI_Has_Icon interface method. |
|
1454 | - * |
|
1455 | - * @see EEI_Visual_Representation for comments |
|
1456 | - * @return string |
|
1457 | - */ |
|
1458 | - public function get_icon() |
|
1459 | - { |
|
1460 | - return '<span class="dashicons dashicons-tickets-alt"></span>'; |
|
1461 | - } |
|
1462 | - |
|
1463 | - |
|
1464 | - /** |
|
1465 | - * Implementation of the EEI_Event_Relation interface method |
|
1466 | - * |
|
1467 | - * @see EEI_Event_Relation for comments |
|
1468 | - * @return EE_Event |
|
1469 | - * @throws EE_Error |
|
1470 | - * @throws UnexpectedEntityException |
|
1471 | - */ |
|
1472 | - public function get_related_event() |
|
1473 | - { |
|
1474 | - // get one datetime to use for getting the event |
|
1475 | - $datetime = $this->first_datetime(); |
|
1476 | - if (! $datetime instanceof \EE_Datetime) { |
|
1477 | - throw new UnexpectedEntityException( |
|
1478 | - $datetime, |
|
1479 | - 'EE_Datetime', |
|
1480 | - sprintf( |
|
1481 | - esc_html__('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'), |
|
1482 | - $this->name() |
|
1483 | - ) |
|
1484 | - ); |
|
1485 | - } |
|
1486 | - $event = $datetime->event(); |
|
1487 | - if (! $event instanceof \EE_Event) { |
|
1488 | - throw new UnexpectedEntityException( |
|
1489 | - $event, |
|
1490 | - 'EE_Event', |
|
1491 | - sprintf( |
|
1492 | - esc_html__('The ticket (%s) is not associated with a valid event.', 'event_espresso'), |
|
1493 | - $this->name() |
|
1494 | - ) |
|
1495 | - ); |
|
1496 | - } |
|
1497 | - return $event; |
|
1498 | - } |
|
1499 | - |
|
1500 | - |
|
1501 | - /** |
|
1502 | - * Implementation of the EEI_Event_Relation interface method |
|
1503 | - * |
|
1504 | - * @see EEI_Event_Relation for comments |
|
1505 | - * @return string |
|
1506 | - * @throws UnexpectedEntityException |
|
1507 | - * @throws EE_Error |
|
1508 | - */ |
|
1509 | - public function get_event_name() |
|
1510 | - { |
|
1511 | - $event = $this->get_related_event(); |
|
1512 | - return $event instanceof EE_Event ? $event->name() : ''; |
|
1513 | - } |
|
1514 | - |
|
1515 | - |
|
1516 | - /** |
|
1517 | - * Implementation of the EEI_Event_Relation interface method |
|
1518 | - * |
|
1519 | - * @see EEI_Event_Relation for comments |
|
1520 | - * @return int |
|
1521 | - * @throws UnexpectedEntityException |
|
1522 | - * @throws EE_Error |
|
1523 | - */ |
|
1524 | - public function get_event_ID() |
|
1525 | - { |
|
1526 | - $event = $this->get_related_event(); |
|
1527 | - return $event instanceof EE_Event ? $event->ID() : 0; |
|
1528 | - } |
|
1529 | - |
|
1530 | - |
|
1531 | - /** |
|
1532 | - * This simply returns whether a ticket can be permanently deleted or not. |
|
1533 | - * The criteria for determining this is whether the ticket has any related registrations. |
|
1534 | - * If there are none then it can be permanently deleted. |
|
1535 | - * |
|
1536 | - * @return bool |
|
1537 | - */ |
|
1538 | - public function is_permanently_deleteable() |
|
1539 | - { |
|
1540 | - return $this->count_registrations() === 0; |
|
1541 | - } |
|
1542 | - |
|
1543 | - |
|
1544 | - /******************************************************************* |
|
17 | + /** |
|
18 | + * The following constants are used by the ticket_status() method to indicate whether a ticket is on sale or not. |
|
19 | + */ |
|
20 | + const sold_out = 'TKS'; |
|
21 | + |
|
22 | + /** |
|
23 | + * |
|
24 | + */ |
|
25 | + const expired = 'TKE'; |
|
26 | + |
|
27 | + /** |
|
28 | + * |
|
29 | + */ |
|
30 | + const archived = 'TKA'; |
|
31 | + |
|
32 | + /** |
|
33 | + * |
|
34 | + */ |
|
35 | + const pending = 'TKP'; |
|
36 | + |
|
37 | + /** |
|
38 | + * |
|
39 | + */ |
|
40 | + const onsale = 'TKO'; |
|
41 | + |
|
42 | + /** |
|
43 | + * extra meta key for tracking ticket reservations |
|
44 | + * |
|
45 | + * @type string |
|
46 | + */ |
|
47 | + const META_KEY_TICKET_RESERVATIONS = 'ticket_reservations'; |
|
48 | + |
|
49 | + /** |
|
50 | + * cached result from method of the same name |
|
51 | + * |
|
52 | + * @var float $_ticket_total_with_taxes |
|
53 | + */ |
|
54 | + private $_ticket_total_with_taxes; |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * @param array $props_n_values incoming values |
|
59 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
60 | + * used.) |
|
61 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
62 | + * date_format and the second value is the time format |
|
63 | + * @return EE_Ticket |
|
64 | + * @throws EE_Error |
|
65 | + */ |
|
66 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
67 | + { |
|
68 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
69 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
70 | + } |
|
71 | + |
|
72 | + |
|
73 | + /** |
|
74 | + * @param array $props_n_values incoming values from the database |
|
75 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
76 | + * the website will be used. |
|
77 | + * @return EE_Ticket |
|
78 | + * @throws EE_Error |
|
79 | + */ |
|
80 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
81 | + { |
|
82 | + return new self($props_n_values, true, $timezone); |
|
83 | + } |
|
84 | + |
|
85 | + |
|
86 | + /** |
|
87 | + * @return bool |
|
88 | + * @throws EE_Error |
|
89 | + */ |
|
90 | + public function parent() |
|
91 | + { |
|
92 | + return $this->get('TKT_parent'); |
|
93 | + } |
|
94 | + |
|
95 | + |
|
96 | + /** |
|
97 | + * return if a ticket has quantities available for purchase |
|
98 | + * |
|
99 | + * @param int $DTT_ID the primary key for a particular datetime |
|
100 | + * @return boolean |
|
101 | + * @throws EE_Error |
|
102 | + */ |
|
103 | + public function available($DTT_ID = 0) |
|
104 | + { |
|
105 | + // are we checking availability for a particular datetime ? |
|
106 | + if ($DTT_ID) { |
|
107 | + // get that datetime object |
|
108 | + $datetime = $this->get_first_related('Datetime', array(array('DTT_ID' => $DTT_ID))); |
|
109 | + // if ticket sales for this datetime have exceeded the reg limit... |
|
110 | + if ($datetime instanceof EE_Datetime && $datetime->sold_out()) { |
|
111 | + return false; |
|
112 | + } |
|
113 | + } |
|
114 | + // datetime is still open for registration, but is this ticket sold out ? |
|
115 | + return $this->qty() < 1 || $this->qty() > $this->sold() ? true : false; |
|
116 | + } |
|
117 | + |
|
118 | + |
|
119 | + /** |
|
120 | + * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired |
|
121 | + * |
|
122 | + * @param bool $display true = we'll return a localized string, otherwise we just return the value of the |
|
123 | + * relevant status const |
|
124 | + * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save |
|
125 | + * further processing |
|
126 | + * @return mixed status int if the display string isn't requested |
|
127 | + * @throws EE_Error |
|
128 | + */ |
|
129 | + public function ticket_status($display = false, $remaining = null) |
|
130 | + { |
|
131 | + $remaining = is_bool($remaining) ? $remaining : $this->is_remaining(); |
|
132 | + if (! $remaining) { |
|
133 | + return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, false, 'sentence') : EE_Ticket::sold_out; |
|
134 | + } |
|
135 | + if ($this->get('TKT_deleted')) { |
|
136 | + return $display ? EEH_Template::pretty_status(EE_Ticket::archived, false, 'sentence') : EE_Ticket::archived; |
|
137 | + } |
|
138 | + if ($this->is_expired()) { |
|
139 | + return $display ? EEH_Template::pretty_status(EE_Ticket::expired, false, 'sentence') : EE_Ticket::expired; |
|
140 | + } |
|
141 | + if ($this->is_pending()) { |
|
142 | + return $display ? EEH_Template::pretty_status(EE_Ticket::pending, false, 'sentence') : EE_Ticket::pending; |
|
143 | + } |
|
144 | + if ($this->is_on_sale()) { |
|
145 | + return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence') : EE_Ticket::onsale; |
|
146 | + } |
|
147 | + return ''; |
|
148 | + } |
|
149 | + |
|
150 | + |
|
151 | + /** |
|
152 | + * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale |
|
153 | + * considering ALL the factors used for figuring that out. |
|
154 | + * |
|
155 | + * @access public |
|
156 | + * @param int $DTT_ID if an int above 0 is included here then we get a specific dtt. |
|
157 | + * @return boolean true = tickets remaining, false not. |
|
158 | + * @throws EE_Error |
|
159 | + */ |
|
160 | + public function is_remaining($DTT_ID = 0) |
|
161 | + { |
|
162 | + $num_remaining = $this->remaining($DTT_ID); |
|
163 | + if ($num_remaining === 0) { |
|
164 | + return false; |
|
165 | + } |
|
166 | + if ($num_remaining > 0 && $num_remaining < $this->min()) { |
|
167 | + return false; |
|
168 | + } |
|
169 | + return true; |
|
170 | + } |
|
171 | + |
|
172 | + |
|
173 | + /** |
|
174 | + * return the total number of tickets available for purchase |
|
175 | + * |
|
176 | + * @param int $DTT_ID the primary key for a particular datetime. |
|
177 | + * set to 0 for all related datetimes |
|
178 | + * @return int |
|
179 | + * @throws EE_Error |
|
180 | + */ |
|
181 | + public function remaining($DTT_ID = 0) |
|
182 | + { |
|
183 | + return $this->real_quantity_on_ticket('saleable', $DTT_ID); |
|
184 | + } |
|
185 | + |
|
186 | + |
|
187 | + /** |
|
188 | + * Gets min |
|
189 | + * |
|
190 | + * @return int |
|
191 | + * @throws EE_Error |
|
192 | + */ |
|
193 | + public function min() |
|
194 | + { |
|
195 | + return $this->get('TKT_min'); |
|
196 | + } |
|
197 | + |
|
198 | + |
|
199 | + /** |
|
200 | + * return if a ticket is no longer available cause its available dates have expired. |
|
201 | + * |
|
202 | + * @return boolean |
|
203 | + * @throws EE_Error |
|
204 | + */ |
|
205 | + public function is_expired() |
|
206 | + { |
|
207 | + return ($this->get_raw('TKT_end_date') < time()); |
|
208 | + } |
|
209 | + |
|
210 | + |
|
211 | + /** |
|
212 | + * Return if a ticket is yet to go on sale or not |
|
213 | + * |
|
214 | + * @return boolean |
|
215 | + * @throws EE_Error |
|
216 | + */ |
|
217 | + public function is_pending() |
|
218 | + { |
|
219 | + return ($this->get_raw('TKT_start_date') > time()); |
|
220 | + } |
|
221 | + |
|
222 | + |
|
223 | + /** |
|
224 | + * Return if a ticket is on sale or not |
|
225 | + * |
|
226 | + * @return boolean |
|
227 | + * @throws EE_Error |
|
228 | + */ |
|
229 | + public function is_on_sale() |
|
230 | + { |
|
231 | + return ($this->get_raw('TKT_start_date') < time() && $this->get_raw('TKT_end_date') > time()); |
|
232 | + } |
|
233 | + |
|
234 | + |
|
235 | + /** |
|
236 | + * This returns the chronologically last datetime that this ticket is associated with |
|
237 | + * |
|
238 | + * @param string $dt_frmt |
|
239 | + * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with |
|
240 | + * the end date ie: Jan 01 "to" Dec 31 |
|
241 | + * @return string |
|
242 | + * @throws EE_Error |
|
243 | + */ |
|
244 | + public function date_range($dt_frmt = '', $conjunction = ' - ') |
|
245 | + { |
|
246 | + $dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt; |
|
247 | + $first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->get_i18n_datetime('DTT_EVT_start', $dt_frmt) |
|
248 | + : ''; |
|
249 | + $last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->get_i18n_datetime('DTT_EVT_end', $dt_frmt) : ''; |
|
250 | + |
|
251 | + return $first_date && $last_date ? $first_date . $conjunction . $last_date : ''; |
|
252 | + } |
|
253 | + |
|
254 | + |
|
255 | + /** |
|
256 | + * This returns the chronologically first datetime that this ticket is associated with |
|
257 | + * |
|
258 | + * @return EE_Datetime |
|
259 | + * @throws EE_Error |
|
260 | + */ |
|
261 | + public function first_datetime() |
|
262 | + { |
|
263 | + $datetimes = $this->datetimes(array('limit' => 1)); |
|
264 | + return reset($datetimes); |
|
265 | + } |
|
266 | + |
|
267 | + |
|
268 | + /** |
|
269 | + * Gets all the datetimes this ticket can be used for attending. |
|
270 | + * Unless otherwise specified, orders datetimes by start date. |
|
271 | + * |
|
272 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
273 | + * @return EE_Datetime[]|EE_Base_Class[] |
|
274 | + * @throws EE_Error |
|
275 | + */ |
|
276 | + public function datetimes($query_params = array()) |
|
277 | + { |
|
278 | + if (! isset($query_params['order_by'])) { |
|
279 | + $query_params['order_by']['DTT_order'] = 'ASC'; |
|
280 | + } |
|
281 | + return $this->get_many_related('Datetime', $query_params); |
|
282 | + } |
|
283 | + |
|
284 | + |
|
285 | + /** |
|
286 | + * This returns the chronologically last datetime that this ticket is associated with |
|
287 | + * |
|
288 | + * @return EE_Datetime |
|
289 | + * @throws EE_Error |
|
290 | + */ |
|
291 | + public function last_datetime() |
|
292 | + { |
|
293 | + $datetimes = $this->datetimes(array('limit' => 1, 'order_by' => array('DTT_EVT_start' => 'DESC'))); |
|
294 | + return end($datetimes); |
|
295 | + } |
|
296 | + |
|
297 | + |
|
298 | + /** |
|
299 | + * This returns the total tickets sold depending on the given parameters. |
|
300 | + * |
|
301 | + * @param string $what Can be one of two options: 'ticket', 'datetime'. |
|
302 | + * 'ticket' = total ticket sales for all datetimes this ticket is related to |
|
303 | + * 'datetime' = total ticket sales for a specified datetime (required $dtt_id) |
|
304 | + * 'datetime' = total ticket sales in the datetime_ticket table. |
|
305 | + * If $dtt_id is not given then we return an array of sales indexed by datetime. |
|
306 | + * If $dtt_id IS given then we return the tickets sold for that given datetime. |
|
307 | + * @param int $dtt_id [optional] include the dtt_id with $what = 'datetime'. |
|
308 | + * @return mixed (array|int) how many tickets have sold |
|
309 | + * @throws EE_Error |
|
310 | + */ |
|
311 | + public function tickets_sold($what = 'ticket', $dtt_id = null) |
|
312 | + { |
|
313 | + $total = 0; |
|
314 | + $tickets_sold = $this->_all_tickets_sold(); |
|
315 | + switch ($what) { |
|
316 | + case 'ticket': |
|
317 | + return $tickets_sold['ticket']; |
|
318 | + break; |
|
319 | + case 'datetime': |
|
320 | + if (empty($tickets_sold['datetime'])) { |
|
321 | + return $total; |
|
322 | + } |
|
323 | + if (! empty($dtt_id) && ! isset($tickets_sold['datetime'][ $dtt_id ])) { |
|
324 | + EE_Error::add_error( |
|
325 | + esc_html__( |
|
326 | + 'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included. Are you SURE that is a datetime related to this ticket?', |
|
327 | + 'event_espresso' |
|
328 | + ), |
|
329 | + __FILE__, |
|
330 | + __FUNCTION__, |
|
331 | + __LINE__ |
|
332 | + ); |
|
333 | + return $total; |
|
334 | + } |
|
335 | + return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][ $dtt_id ]; |
|
336 | + break; |
|
337 | + default: |
|
338 | + return $total; |
|
339 | + } |
|
340 | + } |
|
341 | + |
|
342 | + |
|
343 | + /** |
|
344 | + * This returns an array indexed by datetime_id for tickets sold with this ticket. |
|
345 | + * |
|
346 | + * @return EE_Ticket[] |
|
347 | + * @throws EE_Error |
|
348 | + */ |
|
349 | + protected function _all_tickets_sold() |
|
350 | + { |
|
351 | + $datetimes = $this->get_many_related('Datetime'); |
|
352 | + $tickets_sold = array(); |
|
353 | + if (! empty($datetimes)) { |
|
354 | + foreach ($datetimes as $datetime) { |
|
355 | + $tickets_sold['datetime'][ $datetime->ID() ] = $datetime->get('DTT_sold'); |
|
356 | + } |
|
357 | + } |
|
358 | + // Tickets sold |
|
359 | + $tickets_sold['ticket'] = $this->sold(); |
|
360 | + return $tickets_sold; |
|
361 | + } |
|
362 | + |
|
363 | + |
|
364 | + /** |
|
365 | + * This returns the base price object for the ticket. |
|
366 | + * |
|
367 | + * @param bool $return_array whether to return as an array indexed by price id or just the object. |
|
368 | + * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[] |
|
369 | + * @throws EE_Error |
|
370 | + */ |
|
371 | + public function base_price($return_array = false) |
|
372 | + { |
|
373 | + $_where = array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price); |
|
374 | + return $return_array |
|
375 | + ? $this->get_many_related('Price', array($_where)) |
|
376 | + : $this->get_first_related('Price', array($_where)); |
|
377 | + } |
|
378 | + |
|
379 | + |
|
380 | + /** |
|
381 | + * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price) |
|
382 | + * |
|
383 | + * @access public |
|
384 | + * @return EE_Price[] |
|
385 | + * @throws EE_Error |
|
386 | + */ |
|
387 | + public function price_modifiers() |
|
388 | + { |
|
389 | + $query_params = array( |
|
390 | + 0 => array( |
|
391 | + 'Price_Type.PBT_ID' => array( |
|
392 | + 'NOT IN', |
|
393 | + array(EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax), |
|
394 | + ), |
|
395 | + ), |
|
396 | + ); |
|
397 | + return $this->prices($query_params); |
|
398 | + } |
|
399 | + |
|
400 | + |
|
401 | + /** |
|
402 | + * Gets all the prices that combine to form the final price of this ticket |
|
403 | + * |
|
404 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
405 | + * @return EE_Price[]|EE_Base_Class[] |
|
406 | + * @throws EE_Error |
|
407 | + */ |
|
408 | + public function prices($query_params = array()) |
|
409 | + { |
|
410 | + return $this->get_many_related('Price', $query_params); |
|
411 | + } |
|
412 | + |
|
413 | + |
|
414 | + /** |
|
415 | + * Gets all the ticket applicabilities (ie, relations between datetimes and tickets) |
|
416 | + * |
|
417 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
418 | + * @return EE_Datetime_Ticket|EE_Base_Class[] |
|
419 | + * @throws EE_Error |
|
420 | + */ |
|
421 | + public function datetime_tickets($query_params = array()) |
|
422 | + { |
|
423 | + return $this->get_many_related('Datetime_Ticket', $query_params); |
|
424 | + } |
|
425 | + |
|
426 | + |
|
427 | + /** |
|
428 | + * Gets all the datetimes from the db ordered by DTT_order |
|
429 | + * |
|
430 | + * @param boolean $show_expired |
|
431 | + * @param boolean $show_deleted |
|
432 | + * @return EE_Datetime[] |
|
433 | + * @throws EE_Error |
|
434 | + */ |
|
435 | + public function datetimes_ordered($show_expired = true, $show_deleted = false) |
|
436 | + { |
|
437 | + return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order( |
|
438 | + $this->ID(), |
|
439 | + $show_expired, |
|
440 | + $show_deleted |
|
441 | + ); |
|
442 | + } |
|
443 | + |
|
444 | + |
|
445 | + /** |
|
446 | + * Gets ID |
|
447 | + * |
|
448 | + * @return string |
|
449 | + * @throws EE_Error |
|
450 | + */ |
|
451 | + public function ID() |
|
452 | + { |
|
453 | + return $this->get('TKT_ID'); |
|
454 | + } |
|
455 | + |
|
456 | + |
|
457 | + /** |
|
458 | + * get the author of the ticket. |
|
459 | + * |
|
460 | + * @since 4.5.0 |
|
461 | + * @return int |
|
462 | + * @throws EE_Error |
|
463 | + */ |
|
464 | + public function wp_user() |
|
465 | + { |
|
466 | + return $this->get('TKT_wp_user'); |
|
467 | + } |
|
468 | + |
|
469 | + |
|
470 | + /** |
|
471 | + * Gets the template for the ticket |
|
472 | + * |
|
473 | + * @return EE_Ticket_Template|EE_Base_Class |
|
474 | + * @throws EE_Error |
|
475 | + */ |
|
476 | + public function template() |
|
477 | + { |
|
478 | + return $this->get_first_related('Ticket_Template'); |
|
479 | + } |
|
480 | + |
|
481 | + |
|
482 | + /** |
|
483 | + * Simply returns an array of EE_Price objects that are taxes. |
|
484 | + * |
|
485 | + * @return EE_Price[] |
|
486 | + * @throws EE_Error |
|
487 | + */ |
|
488 | + public function get_ticket_taxes_for_admin() |
|
489 | + { |
|
490 | + return EE_Taxes::get_taxes_for_admin(); |
|
491 | + } |
|
492 | + |
|
493 | + |
|
494 | + /** |
|
495 | + * @return float |
|
496 | + * @throws EE_Error |
|
497 | + */ |
|
498 | + public function ticket_price() |
|
499 | + { |
|
500 | + return $this->get('TKT_price'); |
|
501 | + } |
|
502 | + |
|
503 | + |
|
504 | + /** |
|
505 | + * @return mixed |
|
506 | + * @throws EE_Error |
|
507 | + */ |
|
508 | + public function pretty_price() |
|
509 | + { |
|
510 | + return $this->get_pretty('TKT_price'); |
|
511 | + } |
|
512 | + |
|
513 | + |
|
514 | + /** |
|
515 | + * @return bool |
|
516 | + * @throws EE_Error |
|
517 | + */ |
|
518 | + public function is_free() |
|
519 | + { |
|
520 | + return $this->get_ticket_total_with_taxes() === (float) 0; |
|
521 | + } |
|
522 | + |
|
523 | + |
|
524 | + /** |
|
525 | + * get_ticket_total_with_taxes |
|
526 | + * |
|
527 | + * @param bool $no_cache |
|
528 | + * @return float |
|
529 | + * @throws EE_Error |
|
530 | + */ |
|
531 | + public function get_ticket_total_with_taxes($no_cache = false) |
|
532 | + { |
|
533 | + if ($this->_ticket_total_with_taxes === null || $no_cache) { |
|
534 | + $this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin(); |
|
535 | + } |
|
536 | + return (float) $this->_ticket_total_with_taxes; |
|
537 | + } |
|
538 | + |
|
539 | + |
|
540 | + public function ensure_TKT_Price_correct() |
|
541 | + { |
|
542 | + $this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this)); |
|
543 | + $this->save(); |
|
544 | + } |
|
545 | + |
|
546 | + |
|
547 | + /** |
|
548 | + * @return float |
|
549 | + * @throws EE_Error |
|
550 | + */ |
|
551 | + public function get_ticket_subtotal() |
|
552 | + { |
|
553 | + return EE_Taxes::get_subtotal_for_admin($this); |
|
554 | + } |
|
555 | + |
|
556 | + |
|
557 | + /** |
|
558 | + * Returns the total taxes applied to this ticket |
|
559 | + * |
|
560 | + * @return float |
|
561 | + * @throws EE_Error |
|
562 | + */ |
|
563 | + public function get_ticket_taxes_total_for_admin() |
|
564 | + { |
|
565 | + return EE_Taxes::get_total_taxes_for_admin($this); |
|
566 | + } |
|
567 | + |
|
568 | + |
|
569 | + /** |
|
570 | + * Sets name |
|
571 | + * |
|
572 | + * @param string $name |
|
573 | + * @throws EE_Error |
|
574 | + */ |
|
575 | + public function set_name($name) |
|
576 | + { |
|
577 | + $this->set('TKT_name', $name); |
|
578 | + } |
|
579 | + |
|
580 | + |
|
581 | + /** |
|
582 | + * Gets description |
|
583 | + * |
|
584 | + * @return string |
|
585 | + * @throws EE_Error |
|
586 | + */ |
|
587 | + public function description() |
|
588 | + { |
|
589 | + return $this->get('TKT_description'); |
|
590 | + } |
|
591 | + |
|
592 | + |
|
593 | + /** |
|
594 | + * Sets description |
|
595 | + * |
|
596 | + * @param string $description |
|
597 | + * @throws EE_Error |
|
598 | + */ |
|
599 | + public function set_description($description) |
|
600 | + { |
|
601 | + $this->set('TKT_description', $description); |
|
602 | + } |
|
603 | + |
|
604 | + |
|
605 | + /** |
|
606 | + * Gets start_date |
|
607 | + * |
|
608 | + * @param string $dt_frmt |
|
609 | + * @param string $tm_frmt |
|
610 | + * @return string |
|
611 | + * @throws EE_Error |
|
612 | + */ |
|
613 | + public function start_date($dt_frmt = '', $tm_frmt = '') |
|
614 | + { |
|
615 | + return $this->_get_datetime('TKT_start_date', $dt_frmt, $tm_frmt); |
|
616 | + } |
|
617 | + |
|
618 | + |
|
619 | + /** |
|
620 | + * Sets start_date |
|
621 | + * |
|
622 | + * @param string $start_date |
|
623 | + * @return void |
|
624 | + * @throws EE_Error |
|
625 | + */ |
|
626 | + public function set_start_date($start_date) |
|
627 | + { |
|
628 | + $this->_set_date_time('B', $start_date, 'TKT_start_date'); |
|
629 | + } |
|
630 | + |
|
631 | + |
|
632 | + /** |
|
633 | + * Gets end_date |
|
634 | + * |
|
635 | + * @param string $dt_frmt |
|
636 | + * @param string $tm_frmt |
|
637 | + * @return string |
|
638 | + * @throws EE_Error |
|
639 | + */ |
|
640 | + public function end_date($dt_frmt = '', $tm_frmt = '') |
|
641 | + { |
|
642 | + return $this->_get_datetime('TKT_end_date', $dt_frmt, $tm_frmt); |
|
643 | + } |
|
644 | + |
|
645 | + |
|
646 | + /** |
|
647 | + * Sets end_date |
|
648 | + * |
|
649 | + * @param string $end_date |
|
650 | + * @return void |
|
651 | + * @throws EE_Error |
|
652 | + */ |
|
653 | + public function set_end_date($end_date) |
|
654 | + { |
|
655 | + $this->_set_date_time('B', $end_date, 'TKT_end_date'); |
|
656 | + } |
|
657 | + |
|
658 | + |
|
659 | + /** |
|
660 | + * Sets sell until time |
|
661 | + * |
|
662 | + * @since 4.5.0 |
|
663 | + * @param string $time a string representation of the sell until time (ex 9am or 7:30pm) |
|
664 | + * @throws EE_Error |
|
665 | + */ |
|
666 | + public function set_end_time($time) |
|
667 | + { |
|
668 | + $this->_set_time_for($time, 'TKT_end_date'); |
|
669 | + } |
|
670 | + |
|
671 | + |
|
672 | + /** |
|
673 | + * Sets min |
|
674 | + * |
|
675 | + * @param int $min |
|
676 | + * @return void |
|
677 | + * @throws EE_Error |
|
678 | + */ |
|
679 | + public function set_min($min) |
|
680 | + { |
|
681 | + $this->set('TKT_min', $min); |
|
682 | + } |
|
683 | + |
|
684 | + |
|
685 | + /** |
|
686 | + * Gets max |
|
687 | + * |
|
688 | + * @return int |
|
689 | + * @throws EE_Error |
|
690 | + */ |
|
691 | + public function max() |
|
692 | + { |
|
693 | + return $this->get('TKT_max'); |
|
694 | + } |
|
695 | + |
|
696 | + |
|
697 | + /** |
|
698 | + * Sets max |
|
699 | + * |
|
700 | + * @param int $max |
|
701 | + * @return void |
|
702 | + * @throws EE_Error |
|
703 | + */ |
|
704 | + public function set_max($max) |
|
705 | + { |
|
706 | + $this->set('TKT_max', $max); |
|
707 | + } |
|
708 | + |
|
709 | + |
|
710 | + /** |
|
711 | + * Sets price |
|
712 | + * |
|
713 | + * @param float $price |
|
714 | + * @return void |
|
715 | + * @throws EE_Error |
|
716 | + */ |
|
717 | + public function set_price($price) |
|
718 | + { |
|
719 | + $this->set('TKT_price', $price); |
|
720 | + } |
|
721 | + |
|
722 | + |
|
723 | + /** |
|
724 | + * Gets sold |
|
725 | + * |
|
726 | + * @return int |
|
727 | + * @throws EE_Error |
|
728 | + */ |
|
729 | + public function sold() |
|
730 | + { |
|
731 | + return $this->get_raw('TKT_sold'); |
|
732 | + } |
|
733 | + |
|
734 | + |
|
735 | + /** |
|
736 | + * Sets sold |
|
737 | + * |
|
738 | + * @param int $sold |
|
739 | + * @return void |
|
740 | + * @throws EE_Error |
|
741 | + */ |
|
742 | + public function set_sold($sold) |
|
743 | + { |
|
744 | + // sold can not go below zero |
|
745 | + $sold = max(0, $sold); |
|
746 | + $this->set('TKT_sold', $sold); |
|
747 | + } |
|
748 | + |
|
749 | + |
|
750 | + /** |
|
751 | + * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its |
|
752 | + * associated datetimes. |
|
753 | + * |
|
754 | + * @since 4.9.80.p |
|
755 | + * @param int $qty |
|
756 | + * @return boolean |
|
757 | + * @throws EE_Error |
|
758 | + * @throws InvalidArgumentException |
|
759 | + * @throws InvalidDataTypeException |
|
760 | + * @throws InvalidInterfaceException |
|
761 | + * @throws ReflectionException |
|
762 | + */ |
|
763 | + public function increaseSold($qty = 1) |
|
764 | + { |
|
765 | + $qty = absint($qty); |
|
766 | + // increment sold and decrement reserved datetime quantities simultaneously |
|
767 | + // don't worry about failures, because they must have already had a spot reserved |
|
768 | + $this->increaseSoldForDatetimes($qty); |
|
769 | + // Increment and decrement ticket quantities simultaneously |
|
770 | + $success = $this->adjustNumericFieldsInDb( |
|
771 | + [ |
|
772 | + 'TKT_reserved' => $qty * -1, |
|
773 | + 'TKT_sold' => $qty |
|
774 | + ] |
|
775 | + ); |
|
776 | + do_action( |
|
777 | + 'AHEE__EE_Ticket__increase_sold', |
|
778 | + $this, |
|
779 | + $qty, |
|
780 | + $this->sold(), |
|
781 | + $success |
|
782 | + ); |
|
783 | + return $success; |
|
784 | + } |
|
785 | + |
|
786 | + /** |
|
787 | + * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty. |
|
788 | + * |
|
789 | + * @since 4.9.80.p |
|
790 | + * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts), |
|
791 | + * Negative means to decreases old counts (and increase reserved counts). |
|
792 | + * @param EE_Datetime[] $datetimes |
|
793 | + * @throws EE_Error |
|
794 | + * @throws InvalidArgumentException |
|
795 | + * @throws InvalidDataTypeException |
|
796 | + * @throws InvalidInterfaceException |
|
797 | + * @throws ReflectionException |
|
798 | + */ |
|
799 | + protected function increaseSoldForDatetimes($qty, array $datetimes = []) |
|
800 | + { |
|
801 | + $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
802 | + foreach ($datetimes as $datetime) { |
|
803 | + $datetime->increaseSold($qty); |
|
804 | + } |
|
805 | + } |
|
806 | + |
|
807 | + |
|
808 | + |
|
809 | + /** |
|
810 | + * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the |
|
811 | + * DB and then updates the model objects. |
|
812 | + * Does not affect the reserved counts. |
|
813 | + * |
|
814 | + * @since 4.9.80.p |
|
815 | + * @param int $qty |
|
816 | + * @return boolean |
|
817 | + * @throws EE_Error |
|
818 | + * @throws InvalidArgumentException |
|
819 | + * @throws InvalidDataTypeException |
|
820 | + * @throws InvalidInterfaceException |
|
821 | + * @throws ReflectionException |
|
822 | + */ |
|
823 | + public function decreaseSold($qty = 1) |
|
824 | + { |
|
825 | + $qty = absint($qty); |
|
826 | + $this->decreaseSoldForDatetimes($qty); |
|
827 | + $success = $this->adjustNumericFieldsInDb( |
|
828 | + [ |
|
829 | + 'TKT_sold' => $qty * -1 |
|
830 | + ] |
|
831 | + ); |
|
832 | + do_action( |
|
833 | + 'AHEE__EE_Ticket__decrease_sold', |
|
834 | + $this, |
|
835 | + $qty, |
|
836 | + $this->sold(), |
|
837 | + $success |
|
838 | + ); |
|
839 | + return $success; |
|
840 | + } |
|
841 | + |
|
842 | + |
|
843 | + /** |
|
844 | + * Decreases sold on related datetimes |
|
845 | + * |
|
846 | + * @since 4.9.80.p |
|
847 | + * @param int $qty |
|
848 | + * @param EE_Datetime[] $datetimes |
|
849 | + * @return void |
|
850 | + * @throws EE_Error |
|
851 | + * @throws InvalidArgumentException |
|
852 | + * @throws InvalidDataTypeException |
|
853 | + * @throws InvalidInterfaceException |
|
854 | + * @throws ReflectionException |
|
855 | + */ |
|
856 | + protected function decreaseSoldForDatetimes($qty = 1, array $datetimes = []) |
|
857 | + { |
|
858 | + $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
859 | + if (is_array($datetimes)) { |
|
860 | + foreach ($datetimes as $datetime) { |
|
861 | + if ($datetime instanceof EE_Datetime) { |
|
862 | + $datetime->decreaseSold($qty); |
|
863 | + } |
|
864 | + } |
|
865 | + } |
|
866 | + } |
|
867 | + |
|
868 | + |
|
869 | + /** |
|
870 | + * Gets qty of reserved tickets |
|
871 | + * |
|
872 | + * @return int |
|
873 | + * @throws EE_Error |
|
874 | + */ |
|
875 | + public function reserved() |
|
876 | + { |
|
877 | + return $this->get_raw('TKT_reserved'); |
|
878 | + } |
|
879 | + |
|
880 | + |
|
881 | + /** |
|
882 | + * Sets reserved |
|
883 | + * |
|
884 | + * @param int $reserved |
|
885 | + * @return void |
|
886 | + * @throws EE_Error |
|
887 | + */ |
|
888 | + public function set_reserved($reserved) |
|
889 | + { |
|
890 | + // reserved can not go below zero |
|
891 | + $reserved = max(0, (int) $reserved); |
|
892 | + $this->set('TKT_reserved', $reserved); |
|
893 | + } |
|
894 | + |
|
895 | + |
|
896 | + /** |
|
897 | + * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
898 | + * |
|
899 | + * @since 4.9.80.p |
|
900 | + * @param int $qty |
|
901 | + * @param string $source |
|
902 | + * @return bool whether we successfully reserved the ticket or not. |
|
903 | + * @throws EE_Error |
|
904 | + * @throws InvalidArgumentException |
|
905 | + * @throws ReflectionException |
|
906 | + * @throws InvalidDataTypeException |
|
907 | + * @throws InvalidInterfaceException |
|
908 | + */ |
|
909 | + public function increaseReserved($qty = 1, $source = 'unknown') |
|
910 | + { |
|
911 | + $qty = absint($qty); |
|
912 | + do_action( |
|
913 | + 'AHEE__EE_Ticket__increase_reserved__begin', |
|
914 | + $this, |
|
915 | + $qty, |
|
916 | + $source |
|
917 | + ); |
|
918 | + $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "{$qty} from {$source}"); |
|
919 | + $success = false; |
|
920 | + $datetimes_adjusted_successfully = $this->increaseReservedForDatetimes($qty); |
|
921 | + if ($datetimes_adjusted_successfully) { |
|
922 | + $success = $this->incrementFieldConditionallyInDb( |
|
923 | + 'TKT_reserved', |
|
924 | + 'TKT_sold', |
|
925 | + 'TKT_qty', |
|
926 | + $qty |
|
927 | + ); |
|
928 | + if (! $success) { |
|
929 | + // The datetimes were successfully bumped, but not the |
|
930 | + // ticket. So we need to manually rollback the datetimes. |
|
931 | + $this->decreaseReservedForDatetimes($qty); |
|
932 | + } |
|
933 | + } |
|
934 | + do_action( |
|
935 | + 'AHEE__EE_Ticket__increase_reserved', |
|
936 | + $this, |
|
937 | + $qty, |
|
938 | + $this->reserved(), |
|
939 | + $success |
|
940 | + ); |
|
941 | + return $success; |
|
942 | + } |
|
943 | + |
|
944 | + |
|
945 | + /** |
|
946 | + * Increases reserved counts on related datetimes |
|
947 | + * |
|
948 | + * @since 4.9.80.p |
|
949 | + * @param int $qty |
|
950 | + * @param EE_Datetime[] $datetimes |
|
951 | + * @return boolean indicating success |
|
952 | + * @throws EE_Error |
|
953 | + * @throws InvalidArgumentException |
|
954 | + * @throws InvalidDataTypeException |
|
955 | + * @throws InvalidInterfaceException |
|
956 | + * @throws ReflectionException |
|
957 | + */ |
|
958 | + protected function increaseReservedForDatetimes($qty = 1, array $datetimes = []) |
|
959 | + { |
|
960 | + $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
961 | + $datetimes_updated = []; |
|
962 | + $limit_exceeded = false; |
|
963 | + if (is_array($datetimes)) { |
|
964 | + foreach ($datetimes as $datetime) { |
|
965 | + if ($datetime instanceof EE_Datetime) { |
|
966 | + if ($datetime->increaseReserved($qty)) { |
|
967 | + $datetimes_updated[] = $datetime; |
|
968 | + } else { |
|
969 | + $limit_exceeded = true; |
|
970 | + break; |
|
971 | + } |
|
972 | + } |
|
973 | + } |
|
974 | + // If somewhere along the way we detected a datetime whose |
|
975 | + // limit was exceeded, do a manual rollback. |
|
976 | + if ($limit_exceeded) { |
|
977 | + $this->decreaseReservedForDatetimes($qty, $datetimes_updated); |
|
978 | + return false; |
|
979 | + } |
|
980 | + } |
|
981 | + return true; |
|
982 | + } |
|
983 | + |
|
984 | + |
|
985 | + /** |
|
986 | + * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
987 | + * |
|
988 | + * @since 4.9.80.p |
|
989 | + * @param int $qty |
|
990 | + * @param bool $adjust_datetimes |
|
991 | + * @param string $source |
|
992 | + * @return boolean |
|
993 | + * @throws EE_Error |
|
994 | + * @throws InvalidArgumentException |
|
995 | + * @throws ReflectionException |
|
996 | + * @throws InvalidDataTypeException |
|
997 | + * @throws InvalidInterfaceException |
|
998 | + */ |
|
999 | + public function decreaseReserved($qty = 1, $adjust_datetimes = true, $source = 'unknown') |
|
1000 | + { |
|
1001 | + $qty = absint($qty); |
|
1002 | + $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "-{$qty} from {$source}"); |
|
1003 | + if ($adjust_datetimes) { |
|
1004 | + $this->decreaseReservedForDatetimes($qty); |
|
1005 | + } |
|
1006 | + $success = $this->adjustNumericFieldsInDb( |
|
1007 | + [ |
|
1008 | + 'TKT_reserved' => $qty * -1 |
|
1009 | + ] |
|
1010 | + ); |
|
1011 | + do_action( |
|
1012 | + 'AHEE__EE_Ticket__decrease_reserved', |
|
1013 | + $this, |
|
1014 | + $qty, |
|
1015 | + $this->reserved(), |
|
1016 | + $success |
|
1017 | + ); |
|
1018 | + return $success; |
|
1019 | + } |
|
1020 | + |
|
1021 | + |
|
1022 | + /** |
|
1023 | + * Decreases the reserved count on the specified datetimes. |
|
1024 | + * |
|
1025 | + * @since 4.9.80.p |
|
1026 | + * @param int $qty |
|
1027 | + * @param EE_Datetime[] $datetimes |
|
1028 | + * @throws EE_Error |
|
1029 | + * @throws InvalidArgumentException |
|
1030 | + * @throws ReflectionException |
|
1031 | + * @throws InvalidDataTypeException |
|
1032 | + * @throws InvalidInterfaceException |
|
1033 | + */ |
|
1034 | + protected function decreaseReservedForDatetimes($qty = 1, array $datetimes = []) |
|
1035 | + { |
|
1036 | + $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes(); |
|
1037 | + foreach ($datetimes as $datetime) { |
|
1038 | + if ($datetime instanceof EE_Datetime) { |
|
1039 | + $datetime->decreaseReserved($qty); |
|
1040 | + } |
|
1041 | + } |
|
1042 | + } |
|
1043 | + |
|
1044 | + |
|
1045 | + /** |
|
1046 | + * Gets ticket quantity |
|
1047 | + * |
|
1048 | + * @param string $context ticket quantity is somewhat subjective depending on the exact information sought |
|
1049 | + * therefore $context can be one of three values: '', 'reg_limit', or 'saleable' |
|
1050 | + * '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects |
|
1051 | + * REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes |
|
1052 | + * SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and |
|
1053 | + * is therefore the truest measure of tickets that can be purchased at the moment |
|
1054 | + * @return int |
|
1055 | + * @throws EE_Error |
|
1056 | + */ |
|
1057 | + public function qty($context = '') |
|
1058 | + { |
|
1059 | + switch ($context) { |
|
1060 | + case 'reg_limit': |
|
1061 | + return $this->real_quantity_on_ticket(); |
|
1062 | + case 'saleable': |
|
1063 | + return $this->real_quantity_on_ticket('saleable'); |
|
1064 | + default: |
|
1065 | + return $this->get_raw('TKT_qty'); |
|
1066 | + } |
|
1067 | + } |
|
1068 | + |
|
1069 | + |
|
1070 | + /** |
|
1071 | + * Gets ticket quantity |
|
1072 | + * |
|
1073 | + * @param string $context ticket quantity is somewhat subjective depending on the exact information sought |
|
1074 | + * therefore $context can be one of two values: 'reg_limit', or 'saleable' |
|
1075 | + * REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes |
|
1076 | + * SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and |
|
1077 | + * is therefore the truest measure of tickets that can be purchased at the moment |
|
1078 | + * @param int $DTT_ID the primary key for a particular datetime. |
|
1079 | + * set to 0 for all related datetimes |
|
1080 | + * @return int |
|
1081 | + * @throws EE_Error |
|
1082 | + */ |
|
1083 | + public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0) |
|
1084 | + { |
|
1085 | + $raw = $this->get_raw('TKT_qty'); |
|
1086 | + // return immediately if it's zero |
|
1087 | + if ($raw === 0) { |
|
1088 | + return $raw; |
|
1089 | + } |
|
1090 | + // echo "\n\n<br />Ticket: " . $this->name() . '<br />'; |
|
1091 | + // ensure qty doesn't exceed raw value for THIS ticket |
|
1092 | + $qty = min(EE_INF, $raw); |
|
1093 | + // echo "\n . qty: " . $qty . '<br />'; |
|
1094 | + // calculate this ticket's total sales and reservations |
|
1095 | + $sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved(); |
|
1096 | + // echo "\n . sold: " . $this->sold() . '<br />'; |
|
1097 | + // echo "\n . reserved: " . $this->reserved() . '<br />'; |
|
1098 | + // echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />'; |
|
1099 | + // first we need to calculate the maximum number of tickets available for the datetime |
|
1100 | + // do we want data for one datetime or all of them ? |
|
1101 | + $query_params = $DTT_ID ? array(array('DTT_ID' => $DTT_ID)) : array(); |
|
1102 | + $datetimes = $this->datetimes($query_params); |
|
1103 | + if (is_array($datetimes) && ! empty($datetimes)) { |
|
1104 | + foreach ($datetimes as $datetime) { |
|
1105 | + if ($datetime instanceof EE_Datetime) { |
|
1106 | + $datetime->refresh_from_db(); |
|
1107 | + // echo "\n . . datetime name: " . $datetime->name() . '<br />'; |
|
1108 | + // echo "\n . . datetime ID: " . $datetime->ID() . '<br />'; |
|
1109 | + // initialize with no restrictions for each datetime |
|
1110 | + // but adjust datetime qty based on datetime reg limit |
|
1111 | + $datetime_qty = min(EE_INF, $datetime->reg_limit()); |
|
1112 | + // echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />'; |
|
1113 | + // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />'; |
|
1114 | + // if we want the actual saleable amount, then we need to consider OTHER ticket sales |
|
1115 | + // and reservations for this datetime, that do NOT include sales and reservations |
|
1116 | + // for this ticket (so we add $this->sold() and $this->reserved() back in) |
|
1117 | + if ($context === 'saleable') { |
|
1118 | + $datetime_qty = max( |
|
1119 | + $datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket, |
|
1120 | + 0 |
|
1121 | + ); |
|
1122 | + // echo "\n . . . datetime sold: " . $datetime->sold() . '<br />'; |
|
1123 | + // echo "\n . . . datetime reserved: " . $datetime->reserved() . '<br />'; |
|
1124 | + // echo "\n . . . datetime sold_and_reserved: " . $datetime->sold_and_reserved() . '<br />'; |
|
1125 | + // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />'; |
|
1126 | + $datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0; |
|
1127 | + // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />'; |
|
1128 | + } |
|
1129 | + $qty = min($datetime_qty, $qty); |
|
1130 | + // echo "\n . . qty: " . $qty . '<br />'; |
|
1131 | + } |
|
1132 | + } |
|
1133 | + } |
|
1134 | + // NOW that we know the maximum number of tickets available for the datetime |
|
1135 | + // we can finally factor in the details for this specific ticket |
|
1136 | + if ($qty > 0 && $context === 'saleable') { |
|
1137 | + // and subtract the sales for THIS ticket |
|
1138 | + $qty = max($qty - $sold_and_reserved_for_this_ticket, 0); |
|
1139 | + // echo "\n . qty: " . $qty . '<br />'; |
|
1140 | + } |
|
1141 | + // echo "\nFINAL QTY: " . $qty . "<br /><br />"; |
|
1142 | + return $qty; |
|
1143 | + } |
|
1144 | + |
|
1145 | + |
|
1146 | + /** |
|
1147 | + * Sets qty - IMPORTANT!!! Does NOT allow QTY to be set higher than the lowest reg limit of any related datetimes |
|
1148 | + * |
|
1149 | + * @param int $qty |
|
1150 | + * @return void |
|
1151 | + * @throws EE_Error |
|
1152 | + */ |
|
1153 | + public function set_qty($qty) |
|
1154 | + { |
|
1155 | + $datetimes = $this->datetimes(); |
|
1156 | + foreach ($datetimes as $datetime) { |
|
1157 | + if ($datetime instanceof EE_Datetime) { |
|
1158 | + $qty = min($qty, $datetime->reg_limit()); |
|
1159 | + } |
|
1160 | + } |
|
1161 | + $this->set('TKT_qty', $qty); |
|
1162 | + } |
|
1163 | + |
|
1164 | + |
|
1165 | + /** |
|
1166 | + * Gets uses |
|
1167 | + * |
|
1168 | + * @return int |
|
1169 | + * @throws EE_Error |
|
1170 | + */ |
|
1171 | + public function uses() |
|
1172 | + { |
|
1173 | + return $this->get('TKT_uses'); |
|
1174 | + } |
|
1175 | + |
|
1176 | + |
|
1177 | + /** |
|
1178 | + * Sets uses |
|
1179 | + * |
|
1180 | + * @param int $uses |
|
1181 | + * @return void |
|
1182 | + * @throws EE_Error |
|
1183 | + */ |
|
1184 | + public function set_uses($uses) |
|
1185 | + { |
|
1186 | + $this->set('TKT_uses', $uses); |
|
1187 | + } |
|
1188 | + |
|
1189 | + |
|
1190 | + /** |
|
1191 | + * returns whether ticket is required or not. |
|
1192 | + * |
|
1193 | + * @return boolean |
|
1194 | + * @throws EE_Error |
|
1195 | + */ |
|
1196 | + public function required() |
|
1197 | + { |
|
1198 | + return $this->get('TKT_required'); |
|
1199 | + } |
|
1200 | + |
|
1201 | + |
|
1202 | + /** |
|
1203 | + * sets the TKT_required property |
|
1204 | + * |
|
1205 | + * @param boolean $required |
|
1206 | + * @return void |
|
1207 | + * @throws EE_Error |
|
1208 | + */ |
|
1209 | + public function set_required($required) |
|
1210 | + { |
|
1211 | + $this->set('TKT_required', $required); |
|
1212 | + } |
|
1213 | + |
|
1214 | + |
|
1215 | + /** |
|
1216 | + * Gets taxable |
|
1217 | + * |
|
1218 | + * @return boolean |
|
1219 | + * @throws EE_Error |
|
1220 | + */ |
|
1221 | + public function taxable() |
|
1222 | + { |
|
1223 | + return $this->get('TKT_taxable'); |
|
1224 | + } |
|
1225 | + |
|
1226 | + |
|
1227 | + /** |
|
1228 | + * Sets taxable |
|
1229 | + * |
|
1230 | + * @param boolean $taxable |
|
1231 | + * @return void |
|
1232 | + * @throws EE_Error |
|
1233 | + */ |
|
1234 | + public function set_taxable($taxable) |
|
1235 | + { |
|
1236 | + $this->set('TKT_taxable', $taxable); |
|
1237 | + } |
|
1238 | + |
|
1239 | + |
|
1240 | + /** |
|
1241 | + * Gets is_default |
|
1242 | + * |
|
1243 | + * @return boolean |
|
1244 | + * @throws EE_Error |
|
1245 | + */ |
|
1246 | + public function is_default() |
|
1247 | + { |
|
1248 | + return $this->get('TKT_is_default'); |
|
1249 | + } |
|
1250 | + |
|
1251 | + |
|
1252 | + /** |
|
1253 | + * Sets is_default |
|
1254 | + * |
|
1255 | + * @param boolean $is_default |
|
1256 | + * @return void |
|
1257 | + * @throws EE_Error |
|
1258 | + */ |
|
1259 | + public function set_is_default($is_default) |
|
1260 | + { |
|
1261 | + $this->set('TKT_is_default', $is_default); |
|
1262 | + } |
|
1263 | + |
|
1264 | + |
|
1265 | + /** |
|
1266 | + * Gets order |
|
1267 | + * |
|
1268 | + * @return int |
|
1269 | + * @throws EE_Error |
|
1270 | + */ |
|
1271 | + public function order() |
|
1272 | + { |
|
1273 | + return $this->get('TKT_order'); |
|
1274 | + } |
|
1275 | + |
|
1276 | + |
|
1277 | + /** |
|
1278 | + * Sets order |
|
1279 | + * |
|
1280 | + * @param int $order |
|
1281 | + * @return void |
|
1282 | + * @throws EE_Error |
|
1283 | + */ |
|
1284 | + public function set_order($order) |
|
1285 | + { |
|
1286 | + $this->set('TKT_order', $order); |
|
1287 | + } |
|
1288 | + |
|
1289 | + |
|
1290 | + /** |
|
1291 | + * Gets row |
|
1292 | + * |
|
1293 | + * @return int |
|
1294 | + * @throws EE_Error |
|
1295 | + */ |
|
1296 | + public function row() |
|
1297 | + { |
|
1298 | + return $this->get('TKT_row'); |
|
1299 | + } |
|
1300 | + |
|
1301 | + |
|
1302 | + /** |
|
1303 | + * Sets row |
|
1304 | + * |
|
1305 | + * @param int $row |
|
1306 | + * @return void |
|
1307 | + * @throws EE_Error |
|
1308 | + */ |
|
1309 | + public function set_row($row) |
|
1310 | + { |
|
1311 | + $this->set('TKT_row', $row); |
|
1312 | + } |
|
1313 | + |
|
1314 | + |
|
1315 | + /** |
|
1316 | + * Gets deleted |
|
1317 | + * |
|
1318 | + * @return boolean |
|
1319 | + * @throws EE_Error |
|
1320 | + */ |
|
1321 | + public function deleted() |
|
1322 | + { |
|
1323 | + return $this->get('TKT_deleted'); |
|
1324 | + } |
|
1325 | + |
|
1326 | + |
|
1327 | + /** |
|
1328 | + * Sets deleted |
|
1329 | + * |
|
1330 | + * @param boolean $deleted |
|
1331 | + * @return void |
|
1332 | + * @throws EE_Error |
|
1333 | + */ |
|
1334 | + public function set_deleted($deleted) |
|
1335 | + { |
|
1336 | + $this->set('TKT_deleted', $deleted); |
|
1337 | + } |
|
1338 | + |
|
1339 | + |
|
1340 | + /** |
|
1341 | + * Gets parent |
|
1342 | + * |
|
1343 | + * @return int |
|
1344 | + * @throws EE_Error |
|
1345 | + */ |
|
1346 | + public function parent_ID() |
|
1347 | + { |
|
1348 | + return $this->get('TKT_parent'); |
|
1349 | + } |
|
1350 | + |
|
1351 | + |
|
1352 | + /** |
|
1353 | + * Sets parent |
|
1354 | + * |
|
1355 | + * @param int $parent |
|
1356 | + * @return void |
|
1357 | + * @throws EE_Error |
|
1358 | + */ |
|
1359 | + public function set_parent_ID($parent) |
|
1360 | + { |
|
1361 | + $this->set('TKT_parent', $parent); |
|
1362 | + } |
|
1363 | + |
|
1364 | + |
|
1365 | + /** |
|
1366 | + * Gets a string which is handy for showing in gateways etc that describes the ticket. |
|
1367 | + * |
|
1368 | + * @return string |
|
1369 | + * @throws EE_Error |
|
1370 | + */ |
|
1371 | + public function name_and_info() |
|
1372 | + { |
|
1373 | + $times = array(); |
|
1374 | + foreach ($this->datetimes() as $datetime) { |
|
1375 | + $times[] = $datetime->start_date_and_time(); |
|
1376 | + } |
|
1377 | + return $this->name() . ' @ ' . implode(', ', $times) . ' for ' . $this->pretty_price(); |
|
1378 | + } |
|
1379 | + |
|
1380 | + |
|
1381 | + /** |
|
1382 | + * Gets name |
|
1383 | + * |
|
1384 | + * @return string |
|
1385 | + * @throws EE_Error |
|
1386 | + */ |
|
1387 | + public function name() |
|
1388 | + { |
|
1389 | + return $this->get('TKT_name'); |
|
1390 | + } |
|
1391 | + |
|
1392 | + |
|
1393 | + /** |
|
1394 | + * Gets price |
|
1395 | + * |
|
1396 | + * @return float |
|
1397 | + * @throws EE_Error |
|
1398 | + */ |
|
1399 | + public function price() |
|
1400 | + { |
|
1401 | + return $this->get('TKT_price'); |
|
1402 | + } |
|
1403 | + |
|
1404 | + |
|
1405 | + /** |
|
1406 | + * Gets all the registrations for this ticket |
|
1407 | + * |
|
1408 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1409 | + * @return EE_Registration[]|EE_Base_Class[] |
|
1410 | + * @throws EE_Error |
|
1411 | + */ |
|
1412 | + public function registrations($query_params = array()) |
|
1413 | + { |
|
1414 | + return $this->get_many_related('Registration', $query_params); |
|
1415 | + } |
|
1416 | + |
|
1417 | + |
|
1418 | + /** |
|
1419 | + * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket. |
|
1420 | + * |
|
1421 | + * @return int |
|
1422 | + * @throws EE_Error |
|
1423 | + */ |
|
1424 | + public function update_tickets_sold() |
|
1425 | + { |
|
1426 | + $count_regs_for_this_ticket = $this->count_registrations( |
|
1427 | + array( |
|
1428 | + array( |
|
1429 | + 'STS_ID' => EEM_Registration::status_id_approved, |
|
1430 | + 'REG_deleted' => 0, |
|
1431 | + ), |
|
1432 | + ) |
|
1433 | + ); |
|
1434 | + $this->set_sold($count_regs_for_this_ticket); |
|
1435 | + $this->save(); |
|
1436 | + return $count_regs_for_this_ticket; |
|
1437 | + } |
|
1438 | + |
|
1439 | + |
|
1440 | + /** |
|
1441 | + * Counts the registrations for this ticket |
|
1442 | + * |
|
1443 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1444 | + * @return int |
|
1445 | + */ |
|
1446 | + public function count_registrations($query_params = array()) |
|
1447 | + { |
|
1448 | + return $this->count_related('Registration', $query_params); |
|
1449 | + } |
|
1450 | + |
|
1451 | + |
|
1452 | + /** |
|
1453 | + * Implementation for EEI_Has_Icon interface method. |
|
1454 | + * |
|
1455 | + * @see EEI_Visual_Representation for comments |
|
1456 | + * @return string |
|
1457 | + */ |
|
1458 | + public function get_icon() |
|
1459 | + { |
|
1460 | + return '<span class="dashicons dashicons-tickets-alt"></span>'; |
|
1461 | + } |
|
1462 | + |
|
1463 | + |
|
1464 | + /** |
|
1465 | + * Implementation of the EEI_Event_Relation interface method |
|
1466 | + * |
|
1467 | + * @see EEI_Event_Relation for comments |
|
1468 | + * @return EE_Event |
|
1469 | + * @throws EE_Error |
|
1470 | + * @throws UnexpectedEntityException |
|
1471 | + */ |
|
1472 | + public function get_related_event() |
|
1473 | + { |
|
1474 | + // get one datetime to use for getting the event |
|
1475 | + $datetime = $this->first_datetime(); |
|
1476 | + if (! $datetime instanceof \EE_Datetime) { |
|
1477 | + throw new UnexpectedEntityException( |
|
1478 | + $datetime, |
|
1479 | + 'EE_Datetime', |
|
1480 | + sprintf( |
|
1481 | + esc_html__('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'), |
|
1482 | + $this->name() |
|
1483 | + ) |
|
1484 | + ); |
|
1485 | + } |
|
1486 | + $event = $datetime->event(); |
|
1487 | + if (! $event instanceof \EE_Event) { |
|
1488 | + throw new UnexpectedEntityException( |
|
1489 | + $event, |
|
1490 | + 'EE_Event', |
|
1491 | + sprintf( |
|
1492 | + esc_html__('The ticket (%s) is not associated with a valid event.', 'event_espresso'), |
|
1493 | + $this->name() |
|
1494 | + ) |
|
1495 | + ); |
|
1496 | + } |
|
1497 | + return $event; |
|
1498 | + } |
|
1499 | + |
|
1500 | + |
|
1501 | + /** |
|
1502 | + * Implementation of the EEI_Event_Relation interface method |
|
1503 | + * |
|
1504 | + * @see EEI_Event_Relation for comments |
|
1505 | + * @return string |
|
1506 | + * @throws UnexpectedEntityException |
|
1507 | + * @throws EE_Error |
|
1508 | + */ |
|
1509 | + public function get_event_name() |
|
1510 | + { |
|
1511 | + $event = $this->get_related_event(); |
|
1512 | + return $event instanceof EE_Event ? $event->name() : ''; |
|
1513 | + } |
|
1514 | + |
|
1515 | + |
|
1516 | + /** |
|
1517 | + * Implementation of the EEI_Event_Relation interface method |
|
1518 | + * |
|
1519 | + * @see EEI_Event_Relation for comments |
|
1520 | + * @return int |
|
1521 | + * @throws UnexpectedEntityException |
|
1522 | + * @throws EE_Error |
|
1523 | + */ |
|
1524 | + public function get_event_ID() |
|
1525 | + { |
|
1526 | + $event = $this->get_related_event(); |
|
1527 | + return $event instanceof EE_Event ? $event->ID() : 0; |
|
1528 | + } |
|
1529 | + |
|
1530 | + |
|
1531 | + /** |
|
1532 | + * This simply returns whether a ticket can be permanently deleted or not. |
|
1533 | + * The criteria for determining this is whether the ticket has any related registrations. |
|
1534 | + * If there are none then it can be permanently deleted. |
|
1535 | + * |
|
1536 | + * @return bool |
|
1537 | + */ |
|
1538 | + public function is_permanently_deleteable() |
|
1539 | + { |
|
1540 | + return $this->count_registrations() === 0; |
|
1541 | + } |
|
1542 | + |
|
1543 | + |
|
1544 | + /******************************************************************* |
|
1545 | 1545 | *********************** DEPRECATED METHODS ********************** |
1546 | 1546 | *******************************************************************/ |
1547 | 1547 | |
1548 | 1548 | |
1549 | - /** |
|
1550 | - * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its |
|
1551 | - * associated datetimes. |
|
1552 | - * |
|
1553 | - * @deprecated 4.9.80.p |
|
1554 | - * @param int $qty |
|
1555 | - * @return void |
|
1556 | - * @throws EE_Error |
|
1557 | - * @throws InvalidArgumentException |
|
1558 | - * @throws InvalidDataTypeException |
|
1559 | - * @throws InvalidInterfaceException |
|
1560 | - * @throws ReflectionException |
|
1561 | - */ |
|
1562 | - public function increase_sold($qty = 1) |
|
1563 | - { |
|
1564 | - EE_Error::doing_it_wrong( |
|
1565 | - __FUNCTION__, |
|
1566 | - esc_html__('Please use EE_Ticket::increaseSold() instead', 'event_espresso'), |
|
1567 | - '4.9.80.p', |
|
1568 | - '5.0.0.p' |
|
1569 | - ); |
|
1570 | - $this->increaseSold($qty); |
|
1571 | - } |
|
1572 | - |
|
1573 | - |
|
1574 | - /** |
|
1575 | - * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty. |
|
1576 | - * |
|
1577 | - * @deprecated 4.9.80.p |
|
1578 | - * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts), |
|
1579 | - * Negative means to decreases old counts (and increase reserved counts). |
|
1580 | - * @throws EE_Error |
|
1581 | - * @throws InvalidArgumentException |
|
1582 | - * @throws InvalidDataTypeException |
|
1583 | - * @throws InvalidInterfaceException |
|
1584 | - * @throws ReflectionException |
|
1585 | - */ |
|
1586 | - protected function _increase_sold_for_datetimes($qty) |
|
1587 | - { |
|
1588 | - EE_Error::doing_it_wrong( |
|
1589 | - __FUNCTION__, |
|
1590 | - esc_html__('Please use EE_Ticket::increaseSoldForDatetimes() instead', 'event_espresso'), |
|
1591 | - '4.9.80.p', |
|
1592 | - '5.0.0.p' |
|
1593 | - ); |
|
1594 | - $this->increaseSoldForDatetimes($qty); |
|
1595 | - } |
|
1596 | - |
|
1597 | - |
|
1598 | - /** |
|
1599 | - * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the |
|
1600 | - * DB and then updates the model objects. |
|
1601 | - * Does not affect the reserved counts. |
|
1602 | - * |
|
1603 | - * @deprecated 4.9.80.p |
|
1604 | - * @param int $qty |
|
1605 | - * @return void |
|
1606 | - * @throws EE_Error |
|
1607 | - * @throws InvalidArgumentException |
|
1608 | - * @throws InvalidDataTypeException |
|
1609 | - * @throws InvalidInterfaceException |
|
1610 | - * @throws ReflectionException |
|
1611 | - */ |
|
1612 | - public function decrease_sold($qty = 1) |
|
1613 | - { |
|
1614 | - EE_Error::doing_it_wrong( |
|
1615 | - __FUNCTION__, |
|
1616 | - esc_html__('Please use EE_Ticket::decreaseSold() instead', 'event_espresso'), |
|
1617 | - '4.9.80.p', |
|
1618 | - '5.0.0.p' |
|
1619 | - ); |
|
1620 | - $this->decreaseSold($qty); |
|
1621 | - } |
|
1622 | - |
|
1623 | - |
|
1624 | - /** |
|
1625 | - * Decreases sold on related datetimes |
|
1626 | - * |
|
1627 | - * @deprecated 4.9.80.p |
|
1628 | - * @param int $qty |
|
1629 | - * @return void |
|
1630 | - * @throws EE_Error |
|
1631 | - * @throws InvalidArgumentException |
|
1632 | - * @throws InvalidDataTypeException |
|
1633 | - * @throws InvalidInterfaceException |
|
1634 | - * @throws ReflectionException |
|
1635 | - */ |
|
1636 | - protected function _decrease_sold_for_datetimes($qty = 1) |
|
1637 | - { |
|
1638 | - EE_Error::doing_it_wrong( |
|
1639 | - __FUNCTION__, |
|
1640 | - esc_html__('Please use EE_Ticket::decreaseSoldForDatetimes() instead', 'event_espresso'), |
|
1641 | - '4.9.80.p', |
|
1642 | - '5.0.0.p' |
|
1643 | - ); |
|
1644 | - $this->decreaseSoldForDatetimes($qty); |
|
1645 | - } |
|
1646 | - |
|
1647 | - |
|
1648 | - /** |
|
1649 | - * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
1650 | - * |
|
1651 | - * @deprecated 4.9.80.p |
|
1652 | - * @param int $qty |
|
1653 | - * @param string $source |
|
1654 | - * @return bool whether we successfully reserved the ticket or not. |
|
1655 | - * @throws EE_Error |
|
1656 | - * @throws InvalidArgumentException |
|
1657 | - * @throws ReflectionException |
|
1658 | - * @throws InvalidDataTypeException |
|
1659 | - * @throws InvalidInterfaceException |
|
1660 | - */ |
|
1661 | - public function increase_reserved($qty = 1, $source = 'unknown') |
|
1662 | - { |
|
1663 | - EE_Error::doing_it_wrong( |
|
1664 | - __FUNCTION__, |
|
1665 | - esc_html__('Please use EE_Ticket::increaseReserved() instead', 'event_espresso'), |
|
1666 | - '4.9.80.p', |
|
1667 | - '5.0.0.p' |
|
1668 | - ); |
|
1669 | - return $this->increaseReserved($qty); |
|
1670 | - } |
|
1671 | - |
|
1672 | - |
|
1673 | - /** |
|
1674 | - * Increases sold on related datetimes |
|
1675 | - * |
|
1676 | - * @deprecated 4.9.80.p |
|
1677 | - * @param int $qty |
|
1678 | - * @return boolean indicating success |
|
1679 | - * @throws EE_Error |
|
1680 | - * @throws InvalidArgumentException |
|
1681 | - * @throws InvalidDataTypeException |
|
1682 | - * @throws InvalidInterfaceException |
|
1683 | - * @throws ReflectionException |
|
1684 | - */ |
|
1685 | - protected function _increase_reserved_for_datetimes($qty = 1) |
|
1686 | - { |
|
1687 | - EE_Error::doing_it_wrong( |
|
1688 | - __FUNCTION__, |
|
1689 | - esc_html__('Please use EE_Ticket::increaseReservedForDatetimes() instead', 'event_espresso'), |
|
1690 | - '4.9.80.p', |
|
1691 | - '5.0.0.p' |
|
1692 | - ); |
|
1693 | - return $this->increaseReservedForDatetimes($qty); |
|
1694 | - } |
|
1695 | - |
|
1696 | - |
|
1697 | - /** |
|
1698 | - * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
1699 | - * |
|
1700 | - * @deprecated 4.9.80.p |
|
1701 | - * @param int $qty |
|
1702 | - * @param bool $adjust_datetimes |
|
1703 | - * @param string $source |
|
1704 | - * @return void |
|
1705 | - * @throws EE_Error |
|
1706 | - * @throws InvalidArgumentException |
|
1707 | - * @throws ReflectionException |
|
1708 | - * @throws InvalidDataTypeException |
|
1709 | - * @throws InvalidInterfaceException |
|
1710 | - */ |
|
1711 | - public function decrease_reserved($qty = 1, $adjust_datetimes = true, $source = 'unknown') |
|
1712 | - { |
|
1713 | - EE_Error::doing_it_wrong( |
|
1714 | - __FUNCTION__, |
|
1715 | - esc_html__('Please use EE_Ticket::decreaseReserved() instead', 'event_espresso'), |
|
1716 | - '4.9.80.p', |
|
1717 | - '5.0.0.p' |
|
1718 | - ); |
|
1719 | - $this->decreaseReserved($qty); |
|
1720 | - } |
|
1721 | - |
|
1722 | - |
|
1723 | - /** |
|
1724 | - * Decreases reserved on related datetimes |
|
1725 | - * |
|
1726 | - * @deprecated 4.9.80.p |
|
1727 | - * @param int $qty |
|
1728 | - * @return void |
|
1729 | - * @throws EE_Error |
|
1730 | - * @throws InvalidArgumentException |
|
1731 | - * @throws ReflectionException |
|
1732 | - * @throws InvalidDataTypeException |
|
1733 | - * @throws InvalidInterfaceException |
|
1734 | - */ |
|
1735 | - protected function _decrease_reserved_for_datetimes($qty = 1) |
|
1736 | - { |
|
1737 | - EE_Error::doing_it_wrong( |
|
1738 | - __FUNCTION__, |
|
1739 | - esc_html__('Please use EE_Ticket::decreaseReservedForDatetimes() instead', 'event_espresso'), |
|
1740 | - '4.9.80.p', |
|
1741 | - '5.0.0.p' |
|
1742 | - ); |
|
1743 | - $this->decreaseReservedForDatetimes($qty); |
|
1744 | - } |
|
1549 | + /** |
|
1550 | + * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its |
|
1551 | + * associated datetimes. |
|
1552 | + * |
|
1553 | + * @deprecated 4.9.80.p |
|
1554 | + * @param int $qty |
|
1555 | + * @return void |
|
1556 | + * @throws EE_Error |
|
1557 | + * @throws InvalidArgumentException |
|
1558 | + * @throws InvalidDataTypeException |
|
1559 | + * @throws InvalidInterfaceException |
|
1560 | + * @throws ReflectionException |
|
1561 | + */ |
|
1562 | + public function increase_sold($qty = 1) |
|
1563 | + { |
|
1564 | + EE_Error::doing_it_wrong( |
|
1565 | + __FUNCTION__, |
|
1566 | + esc_html__('Please use EE_Ticket::increaseSold() instead', 'event_espresso'), |
|
1567 | + '4.9.80.p', |
|
1568 | + '5.0.0.p' |
|
1569 | + ); |
|
1570 | + $this->increaseSold($qty); |
|
1571 | + } |
|
1572 | + |
|
1573 | + |
|
1574 | + /** |
|
1575 | + * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty. |
|
1576 | + * |
|
1577 | + * @deprecated 4.9.80.p |
|
1578 | + * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts), |
|
1579 | + * Negative means to decreases old counts (and increase reserved counts). |
|
1580 | + * @throws EE_Error |
|
1581 | + * @throws InvalidArgumentException |
|
1582 | + * @throws InvalidDataTypeException |
|
1583 | + * @throws InvalidInterfaceException |
|
1584 | + * @throws ReflectionException |
|
1585 | + */ |
|
1586 | + protected function _increase_sold_for_datetimes($qty) |
|
1587 | + { |
|
1588 | + EE_Error::doing_it_wrong( |
|
1589 | + __FUNCTION__, |
|
1590 | + esc_html__('Please use EE_Ticket::increaseSoldForDatetimes() instead', 'event_espresso'), |
|
1591 | + '4.9.80.p', |
|
1592 | + '5.0.0.p' |
|
1593 | + ); |
|
1594 | + $this->increaseSoldForDatetimes($qty); |
|
1595 | + } |
|
1596 | + |
|
1597 | + |
|
1598 | + /** |
|
1599 | + * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the |
|
1600 | + * DB and then updates the model objects. |
|
1601 | + * Does not affect the reserved counts. |
|
1602 | + * |
|
1603 | + * @deprecated 4.9.80.p |
|
1604 | + * @param int $qty |
|
1605 | + * @return void |
|
1606 | + * @throws EE_Error |
|
1607 | + * @throws InvalidArgumentException |
|
1608 | + * @throws InvalidDataTypeException |
|
1609 | + * @throws InvalidInterfaceException |
|
1610 | + * @throws ReflectionException |
|
1611 | + */ |
|
1612 | + public function decrease_sold($qty = 1) |
|
1613 | + { |
|
1614 | + EE_Error::doing_it_wrong( |
|
1615 | + __FUNCTION__, |
|
1616 | + esc_html__('Please use EE_Ticket::decreaseSold() instead', 'event_espresso'), |
|
1617 | + '4.9.80.p', |
|
1618 | + '5.0.0.p' |
|
1619 | + ); |
|
1620 | + $this->decreaseSold($qty); |
|
1621 | + } |
|
1622 | + |
|
1623 | + |
|
1624 | + /** |
|
1625 | + * Decreases sold on related datetimes |
|
1626 | + * |
|
1627 | + * @deprecated 4.9.80.p |
|
1628 | + * @param int $qty |
|
1629 | + * @return void |
|
1630 | + * @throws EE_Error |
|
1631 | + * @throws InvalidArgumentException |
|
1632 | + * @throws InvalidDataTypeException |
|
1633 | + * @throws InvalidInterfaceException |
|
1634 | + * @throws ReflectionException |
|
1635 | + */ |
|
1636 | + protected function _decrease_sold_for_datetimes($qty = 1) |
|
1637 | + { |
|
1638 | + EE_Error::doing_it_wrong( |
|
1639 | + __FUNCTION__, |
|
1640 | + esc_html__('Please use EE_Ticket::decreaseSoldForDatetimes() instead', 'event_espresso'), |
|
1641 | + '4.9.80.p', |
|
1642 | + '5.0.0.p' |
|
1643 | + ); |
|
1644 | + $this->decreaseSoldForDatetimes($qty); |
|
1645 | + } |
|
1646 | + |
|
1647 | + |
|
1648 | + /** |
|
1649 | + * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
1650 | + * |
|
1651 | + * @deprecated 4.9.80.p |
|
1652 | + * @param int $qty |
|
1653 | + * @param string $source |
|
1654 | + * @return bool whether we successfully reserved the ticket or not. |
|
1655 | + * @throws EE_Error |
|
1656 | + * @throws InvalidArgumentException |
|
1657 | + * @throws ReflectionException |
|
1658 | + * @throws InvalidDataTypeException |
|
1659 | + * @throws InvalidInterfaceException |
|
1660 | + */ |
|
1661 | + public function increase_reserved($qty = 1, $source = 'unknown') |
|
1662 | + { |
|
1663 | + EE_Error::doing_it_wrong( |
|
1664 | + __FUNCTION__, |
|
1665 | + esc_html__('Please use EE_Ticket::increaseReserved() instead', 'event_espresso'), |
|
1666 | + '4.9.80.p', |
|
1667 | + '5.0.0.p' |
|
1668 | + ); |
|
1669 | + return $this->increaseReserved($qty); |
|
1670 | + } |
|
1671 | + |
|
1672 | + |
|
1673 | + /** |
|
1674 | + * Increases sold on related datetimes |
|
1675 | + * |
|
1676 | + * @deprecated 4.9.80.p |
|
1677 | + * @param int $qty |
|
1678 | + * @return boolean indicating success |
|
1679 | + * @throws EE_Error |
|
1680 | + * @throws InvalidArgumentException |
|
1681 | + * @throws InvalidDataTypeException |
|
1682 | + * @throws InvalidInterfaceException |
|
1683 | + * @throws ReflectionException |
|
1684 | + */ |
|
1685 | + protected function _increase_reserved_for_datetimes($qty = 1) |
|
1686 | + { |
|
1687 | + EE_Error::doing_it_wrong( |
|
1688 | + __FUNCTION__, |
|
1689 | + esc_html__('Please use EE_Ticket::increaseReservedForDatetimes() instead', 'event_espresso'), |
|
1690 | + '4.9.80.p', |
|
1691 | + '5.0.0.p' |
|
1692 | + ); |
|
1693 | + return $this->increaseReservedForDatetimes($qty); |
|
1694 | + } |
|
1695 | + |
|
1696 | + |
|
1697 | + /** |
|
1698 | + * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
1699 | + * |
|
1700 | + * @deprecated 4.9.80.p |
|
1701 | + * @param int $qty |
|
1702 | + * @param bool $adjust_datetimes |
|
1703 | + * @param string $source |
|
1704 | + * @return void |
|
1705 | + * @throws EE_Error |
|
1706 | + * @throws InvalidArgumentException |
|
1707 | + * @throws ReflectionException |
|
1708 | + * @throws InvalidDataTypeException |
|
1709 | + * @throws InvalidInterfaceException |
|
1710 | + */ |
|
1711 | + public function decrease_reserved($qty = 1, $adjust_datetimes = true, $source = 'unknown') |
|
1712 | + { |
|
1713 | + EE_Error::doing_it_wrong( |
|
1714 | + __FUNCTION__, |
|
1715 | + esc_html__('Please use EE_Ticket::decreaseReserved() instead', 'event_espresso'), |
|
1716 | + '4.9.80.p', |
|
1717 | + '5.0.0.p' |
|
1718 | + ); |
|
1719 | + $this->decreaseReserved($qty); |
|
1720 | + } |
|
1721 | + |
|
1722 | + |
|
1723 | + /** |
|
1724 | + * Decreases reserved on related datetimes |
|
1725 | + * |
|
1726 | + * @deprecated 4.9.80.p |
|
1727 | + * @param int $qty |
|
1728 | + * @return void |
|
1729 | + * @throws EE_Error |
|
1730 | + * @throws InvalidArgumentException |
|
1731 | + * @throws ReflectionException |
|
1732 | + * @throws InvalidDataTypeException |
|
1733 | + * @throws InvalidInterfaceException |
|
1734 | + */ |
|
1735 | + protected function _decrease_reserved_for_datetimes($qty = 1) |
|
1736 | + { |
|
1737 | + EE_Error::doing_it_wrong( |
|
1738 | + __FUNCTION__, |
|
1739 | + esc_html__('Please use EE_Ticket::decreaseReservedForDatetimes() instead', 'event_espresso'), |
|
1740 | + '4.9.80.p', |
|
1741 | + '5.0.0.p' |
|
1742 | + ); |
|
1743 | + $this->decreaseReservedForDatetimes($qty); |
|
1744 | + } |
|
1745 | 1745 | } |
@@ -129,7 +129,7 @@ discard block |
||
129 | 129 | public function ticket_status($display = false, $remaining = null) |
130 | 130 | { |
131 | 131 | $remaining = is_bool($remaining) ? $remaining : $this->is_remaining(); |
132 | - if (! $remaining) { |
|
132 | + if ( ! $remaining) { |
|
133 | 133 | return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, false, 'sentence') : EE_Ticket::sold_out; |
134 | 134 | } |
135 | 135 | if ($this->get('TKT_deleted')) { |
@@ -248,7 +248,7 @@ discard block |
||
248 | 248 | : ''; |
249 | 249 | $last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->get_i18n_datetime('DTT_EVT_end', $dt_frmt) : ''; |
250 | 250 | |
251 | - return $first_date && $last_date ? $first_date . $conjunction . $last_date : ''; |
|
251 | + return $first_date && $last_date ? $first_date.$conjunction.$last_date : ''; |
|
252 | 252 | } |
253 | 253 | |
254 | 254 | |
@@ -275,7 +275,7 @@ discard block |
||
275 | 275 | */ |
276 | 276 | public function datetimes($query_params = array()) |
277 | 277 | { |
278 | - if (! isset($query_params['order_by'])) { |
|
278 | + if ( ! isset($query_params['order_by'])) { |
|
279 | 279 | $query_params['order_by']['DTT_order'] = 'ASC'; |
280 | 280 | } |
281 | 281 | return $this->get_many_related('Datetime', $query_params); |
@@ -320,7 +320,7 @@ discard block |
||
320 | 320 | if (empty($tickets_sold['datetime'])) { |
321 | 321 | return $total; |
322 | 322 | } |
323 | - if (! empty($dtt_id) && ! isset($tickets_sold['datetime'][ $dtt_id ])) { |
|
323 | + if ( ! empty($dtt_id) && ! isset($tickets_sold['datetime'][$dtt_id])) { |
|
324 | 324 | EE_Error::add_error( |
325 | 325 | esc_html__( |
326 | 326 | 'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included. Are you SURE that is a datetime related to this ticket?', |
@@ -332,7 +332,7 @@ discard block |
||
332 | 332 | ); |
333 | 333 | return $total; |
334 | 334 | } |
335 | - return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][ $dtt_id ]; |
|
335 | + return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][$dtt_id]; |
|
336 | 336 | break; |
337 | 337 | default: |
338 | 338 | return $total; |
@@ -350,9 +350,9 @@ discard block |
||
350 | 350 | { |
351 | 351 | $datetimes = $this->get_many_related('Datetime'); |
352 | 352 | $tickets_sold = array(); |
353 | - if (! empty($datetimes)) { |
|
353 | + if ( ! empty($datetimes)) { |
|
354 | 354 | foreach ($datetimes as $datetime) { |
355 | - $tickets_sold['datetime'][ $datetime->ID() ] = $datetime->get('DTT_sold'); |
|
355 | + $tickets_sold['datetime'][$datetime->ID()] = $datetime->get('DTT_sold'); |
|
356 | 356 | } |
357 | 357 | } |
358 | 358 | // Tickets sold |
@@ -925,7 +925,7 @@ discard block |
||
925 | 925 | 'TKT_qty', |
926 | 926 | $qty |
927 | 927 | ); |
928 | - if (! $success) { |
|
928 | + if ( ! $success) { |
|
929 | 929 | // The datetimes were successfully bumped, but not the |
930 | 930 | // ticket. So we need to manually rollback the datetimes. |
931 | 931 | $this->decreaseReservedForDatetimes($qty); |
@@ -1374,7 +1374,7 @@ discard block |
||
1374 | 1374 | foreach ($this->datetimes() as $datetime) { |
1375 | 1375 | $times[] = $datetime->start_date_and_time(); |
1376 | 1376 | } |
1377 | - return $this->name() . ' @ ' . implode(', ', $times) . ' for ' . $this->pretty_price(); |
|
1377 | + return $this->name().' @ '.implode(', ', $times).' for '.$this->pretty_price(); |
|
1378 | 1378 | } |
1379 | 1379 | |
1380 | 1380 | |
@@ -1473,7 +1473,7 @@ discard block |
||
1473 | 1473 | { |
1474 | 1474 | // get one datetime to use for getting the event |
1475 | 1475 | $datetime = $this->first_datetime(); |
1476 | - if (! $datetime instanceof \EE_Datetime) { |
|
1476 | + if ( ! $datetime instanceof \EE_Datetime) { |
|
1477 | 1477 | throw new UnexpectedEntityException( |
1478 | 1478 | $datetime, |
1479 | 1479 | 'EE_Datetime', |
@@ -1484,7 +1484,7 @@ discard block |
||
1484 | 1484 | ); |
1485 | 1485 | } |
1486 | 1486 | $event = $datetime->event(); |
1487 | - if (! $event instanceof \EE_Event) { |
|
1487 | + if ( ! $event instanceof \EE_Event) { |
|
1488 | 1488 | throw new UnexpectedEntityException( |
1489 | 1489 | $event, |
1490 | 1490 | 'EE_Event', |
@@ -18,846 +18,846 @@ |
||
18 | 18 | class EE_Payment_Processor extends EE_Processor_Base implements ResettableInterface |
19 | 19 | { |
20 | 20 | |
21 | - /** |
|
22 | - * @var EE_Payment_Processor $_instance |
|
23 | - * @access private |
|
24 | - */ |
|
25 | - private static $_instance; |
|
26 | - |
|
27 | - |
|
28 | - /** |
|
29 | - * @singleton method used to instantiate class object |
|
30 | - * @access public |
|
31 | - * @return EE_Payment_Processor instance |
|
32 | - */ |
|
33 | - public static function instance() |
|
34 | - { |
|
35 | - // check if class object is instantiated |
|
36 | - if (! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | - self::$_instance = new self(); |
|
38 | - } |
|
39 | - return self::$_instance; |
|
40 | - } |
|
41 | - |
|
42 | - |
|
43 | - /** |
|
44 | - * @return EE_Payment_Processor |
|
45 | - */ |
|
46 | - public static function reset() |
|
47 | - { |
|
48 | - self::$_instance = null; |
|
49 | - return self::instance(); |
|
50 | - } |
|
51 | - |
|
52 | - |
|
53 | - /** |
|
54 | - *private constructor to prevent direct creation |
|
55 | - * |
|
56 | - * @Constructor |
|
57 | - * @access private |
|
58 | - */ |
|
59 | - private function __construct() |
|
60 | - { |
|
61 | - do_action('AHEE__EE_Payment_Processor__construct'); |
|
62 | - add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
63 | - } |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
68 | - * appropriately. Saves the payment that is generated |
|
69 | - * |
|
70 | - * @param EE_Payment_Method $payment_method |
|
71 | - * @param EE_Transaction $transaction |
|
72 | - * @param float $amount if only part of the transaction is to be paid for, how much. |
|
73 | - * Leave null if payment is for the full amount owing |
|
74 | - * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
75 | - * Receive_form_submission() should have |
|
76 | - * already been called on the billing form |
|
77 | - * (ie, its inputs should have their normalized values set). |
|
78 | - * @param string $return_url string used mostly by offsite gateways to specify |
|
79 | - * where to go AFTER the offsite gateway |
|
80 | - * @param string $method like 'CART', indicates who the client who called this was |
|
81 | - * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
82 | - * @param boolean $update_txn whether or not to call |
|
83 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
84 | - * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
85 | - * @return EE_Payment |
|
86 | - * @throws EE_Error |
|
87 | - * @throws InvalidArgumentException |
|
88 | - * @throws ReflectionException |
|
89 | - * @throws RuntimeException |
|
90 | - * @throws InvalidDataTypeException |
|
91 | - * @throws InvalidInterfaceException |
|
92 | - */ |
|
93 | - public function process_payment( |
|
94 | - EE_Payment_Method $payment_method, |
|
95 | - EE_Transaction $transaction, |
|
96 | - $amount = null, |
|
97 | - $billing_form = null, |
|
98 | - $return_url = null, |
|
99 | - $method = 'CART', |
|
100 | - $by_admin = false, |
|
101 | - $update_txn = true, |
|
102 | - $cancel_url = '' |
|
103 | - ) { |
|
104 | - if ((float) $amount < 0) { |
|
105 | - throw new EE_Error( |
|
106 | - sprintf( |
|
107 | - esc_html__( |
|
108 | - 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
109 | - 'event_espresso' |
|
110 | - ), |
|
111 | - $amount, |
|
112 | - $transaction->ID() |
|
113 | - ) |
|
114 | - ); |
|
115 | - } |
|
116 | - // verify payment method |
|
117 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
118 | - $payment_method, |
|
119 | - true |
|
120 | - ); |
|
121 | - // verify transaction |
|
122 | - EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
123 | - $transaction->set_payment_method_ID($payment_method->ID()); |
|
124 | - // verify payment method type |
|
125 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
126 | - $payment = $payment_method->type_obj()->process_payment( |
|
127 | - $transaction, |
|
128 | - min($amount, $transaction->remaining()), // make sure we don't overcharge |
|
129 | - $billing_form, |
|
130 | - $return_url, |
|
131 | - add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
132 | - $method, |
|
133 | - $by_admin |
|
134 | - ); |
|
135 | - // check if payment method uses an off-site gateway |
|
136 | - if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
137 | - // don't process payments for off-site gateways yet because no payment has occurred yet |
|
138 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
139 | - } |
|
140 | - return $payment; |
|
141 | - } |
|
142 | - EE_Error::add_error( |
|
143 | - sprintf( |
|
144 | - esc_html__( |
|
145 | - 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
146 | - 'event_espresso' |
|
147 | - ), |
|
148 | - '<br/>', |
|
149 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
150 | - ), |
|
151 | - __FILE__, |
|
152 | - __FUNCTION__, |
|
153 | - __LINE__ |
|
154 | - ); |
|
155 | - return null; |
|
156 | - } |
|
157 | - |
|
158 | - |
|
159 | - /** |
|
160 | - * @param EE_Transaction|int $transaction |
|
161 | - * @param EE_Payment_Method $payment_method |
|
162 | - * @return string |
|
163 | - * @throws EE_Error |
|
164 | - * @throws InvalidArgumentException |
|
165 | - * @throws InvalidDataTypeException |
|
166 | - * @throws InvalidInterfaceException |
|
167 | - */ |
|
168 | - public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
169 | - { |
|
170 | - /** @type \EE_Transaction $transaction */ |
|
171 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
172 | - $primary_reg = $transaction->primary_registration(); |
|
173 | - if (! $primary_reg instanceof EE_Registration) { |
|
174 | - throw new EE_Error( |
|
175 | - sprintf( |
|
176 | - esc_html__( |
|
177 | - 'Cannot get IPN URL for transaction with ID %d because it has no primary registration', |
|
178 | - 'event_espresso' |
|
179 | - ), |
|
180 | - $transaction->ID() |
|
181 | - ) |
|
182 | - ); |
|
183 | - } |
|
184 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
185 | - $payment_method, |
|
186 | - true |
|
187 | - ); |
|
188 | - $url = add_query_arg( |
|
189 | - array( |
|
190 | - 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
191 | - 'ee_payment_method' => $payment_method->slug(), |
|
192 | - ), |
|
193 | - EE_Registry::instance()->CFG->core->txn_page_url() |
|
194 | - ); |
|
195 | - return $url; |
|
196 | - } |
|
197 | - |
|
198 | - |
|
199 | - /** |
|
200 | - * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
201 | - * we can easily find what registration the IPN is for and what payment method. |
|
202 | - * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
203 | - * If a payment is found for the IPN info, it is saved. |
|
204 | - * |
|
205 | - * @param array $_req_data form post data |
|
206 | - * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
207 | - * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
208 | - * @param boolean $update_txn whether or not to call |
|
209 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
210 | - * @param bool $separate_IPN_request whether the IPN uses a separate request (true, like PayPal) |
|
211 | - * or is processed manually (false, like Authorize.net) |
|
212 | - * @throws EE_Error |
|
213 | - * @throws Exception |
|
214 | - * @return EE_Payment |
|
215 | - * @throws \RuntimeException |
|
216 | - * @throws \ReflectionException |
|
217 | - * @throws \InvalidArgumentException |
|
218 | - * @throws InvalidInterfaceException |
|
219 | - * @throws InvalidDataTypeException |
|
220 | - */ |
|
221 | - public function process_ipn( |
|
222 | - $_req_data, |
|
223 | - $transaction = null, |
|
224 | - $payment_method = null, |
|
225 | - $update_txn = true, |
|
226 | - $separate_IPN_request = true |
|
227 | - ) { |
|
228 | - EE_Registry::instance()->load_model('Change_Log'); |
|
229 | - $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data); |
|
230 | - EE_Processor_Base::set_IPN($separate_IPN_request); |
|
231 | - $obj_for_log = null; |
|
232 | - if ($transaction instanceof EE_Transaction) { |
|
233 | - $obj_for_log = $transaction; |
|
234 | - if ($payment_method instanceof EE_Payment_Method) { |
|
235 | - $obj_for_log = EEM_Payment::instance()->get_one( |
|
236 | - array( |
|
237 | - array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
238 | - 'order_by' => array('PAY_timestamp' => 'desc'), |
|
239 | - ) |
|
240 | - ); |
|
241 | - } |
|
242 | - } elseif ($payment_method instanceof EE_Payment) { |
|
243 | - $obj_for_log = $payment_method; |
|
244 | - } |
|
245 | - $log = EEM_Change_Log::instance()->log( |
|
246 | - EEM_Change_Log::type_gateway, |
|
247 | - array('IPN data received' => $_req_data), |
|
248 | - $obj_for_log |
|
249 | - ); |
|
250 | - try { |
|
251 | - /** |
|
252 | - * @var EE_Payment $payment |
|
253 | - */ |
|
254 | - $payment = null; |
|
255 | - if ($transaction && $payment_method) { |
|
256 | - /** @type EE_Transaction $transaction */ |
|
257 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
258 | - /** @type EE_Payment_Method $payment_method */ |
|
259 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
260 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
261 | - try { |
|
262 | - $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
263 | - $log->set_object($payment); |
|
264 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
265 | - EEM_Change_Log::instance()->log( |
|
266 | - EEM_Change_Log::type_gateway, |
|
267 | - array( |
|
268 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
269 | - 'current_url' => EEH_URL::current_url(), |
|
270 | - 'payment' => $e->getPaymentProperties(), |
|
271 | - 'IPN_data' => $e->getIpnData(), |
|
272 | - ), |
|
273 | - $obj_for_log |
|
274 | - ); |
|
275 | - return $e->getPayment(); |
|
276 | - } |
|
277 | - } else { |
|
278 | - // not a payment |
|
279 | - EE_Error::add_error( |
|
280 | - sprintf( |
|
281 | - esc_html__( |
|
282 | - 'A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', |
|
283 | - 'event_espresso' |
|
284 | - ), |
|
285 | - '<br/>', |
|
286 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
287 | - ), |
|
288 | - __FILE__, |
|
289 | - __FUNCTION__, |
|
290 | - __LINE__ |
|
291 | - ); |
|
292 | - } |
|
293 | - } else { |
|
294 | - // that's actually pretty ok. The IPN just wasn't able |
|
295 | - // to identify which transaction or payment method this was for |
|
296 | - // give all active payment methods a chance to claim it |
|
297 | - $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
298 | - foreach ($active_payment_methods as $active_payment_method) { |
|
299 | - try { |
|
300 | - $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
301 | - $payment_method = $active_payment_method; |
|
302 | - EEM_Change_Log::instance()->log( |
|
303 | - EEM_Change_Log::type_gateway, |
|
304 | - array('IPN data' => $_req_data), |
|
305 | - $payment |
|
306 | - ); |
|
307 | - break; |
|
308 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
309 | - EEM_Change_Log::instance()->log( |
|
310 | - EEM_Change_Log::type_gateway, |
|
311 | - array( |
|
312 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
313 | - 'current_url' => EEH_URL::current_url(), |
|
314 | - 'payment' => $e->getPaymentProperties(), |
|
315 | - 'IPN_data' => $e->getIpnData(), |
|
316 | - ), |
|
317 | - $obj_for_log |
|
318 | - ); |
|
319 | - return $e->getPayment(); |
|
320 | - } catch (EE_Error $e) { |
|
321 | - // that's fine- it apparently couldn't handle the IPN |
|
322 | - } |
|
323 | - } |
|
324 | - } |
|
325 | - // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
326 | - if ($payment instanceof EE_Payment) { |
|
327 | - $payment->save(); |
|
328 | - // update the TXN |
|
329 | - $this->update_txn_based_on_payment( |
|
330 | - $transaction, |
|
331 | - $payment, |
|
332 | - $update_txn, |
|
333 | - $separate_IPN_request |
|
334 | - ); |
|
335 | - } else { |
|
336 | - // we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
337 | - if ($payment_method) { |
|
338 | - EEM_Change_Log::instance()->log( |
|
339 | - EEM_Change_Log::type_gateway, |
|
340 | - array('IPN data' => $_req_data), |
|
341 | - $payment_method |
|
342 | - ); |
|
343 | - } elseif ($transaction) { |
|
344 | - EEM_Change_Log::instance()->log( |
|
345 | - EEM_Change_Log::type_gateway, |
|
346 | - array('IPN data' => $_req_data), |
|
347 | - $transaction |
|
348 | - ); |
|
349 | - } |
|
350 | - } |
|
351 | - return $payment; |
|
352 | - } catch (EE_Error $e) { |
|
353 | - do_action( |
|
354 | - 'AHEE__log', |
|
355 | - __FILE__, |
|
356 | - __FUNCTION__, |
|
357 | - sprintf( |
|
358 | - esc_html__( |
|
359 | - 'Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', |
|
360 | - 'event_espresso' |
|
361 | - ), |
|
362 | - print_r($transaction, true), |
|
363 | - print_r($_req_data, true), |
|
364 | - $e->getMessage() |
|
365 | - ) |
|
366 | - ); |
|
367 | - throw $e; |
|
368 | - } |
|
369 | - } |
|
370 | - |
|
371 | - |
|
372 | - /** |
|
373 | - * Removes any non-printable illegal characters from the input, |
|
374 | - * which might cause a raucous when trying to insert into the database |
|
375 | - * |
|
376 | - * @param array $request_data |
|
377 | - * @return array |
|
378 | - */ |
|
379 | - protected function _remove_unusable_characters_from_array(array $request_data) |
|
380 | - { |
|
381 | - $return_data = array(); |
|
382 | - foreach ($request_data as $key => $value) { |
|
383 | - $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
384 | - $value |
|
385 | - ); |
|
386 | - } |
|
387 | - return $return_data; |
|
388 | - } |
|
389 | - |
|
390 | - |
|
391 | - /** |
|
392 | - * Removes any non-printable illegal characters from the input, |
|
393 | - * which might cause a raucous when trying to insert into the database |
|
394 | - * |
|
395 | - * @param string $request_data |
|
396 | - * @return string |
|
397 | - */ |
|
398 | - protected function _remove_unusable_characters($request_data) |
|
399 | - { |
|
400 | - return preg_replace('/[^[:print:]]/', '', $request_data); |
|
401 | - } |
|
402 | - |
|
403 | - |
|
404 | - /** |
|
405 | - * Should be called just before displaying the payment attempt results to the user, |
|
406 | - * when the payment attempt has finished. Some payment methods may have special |
|
407 | - * logic to perform here. For example, if process_payment() happens on a special request |
|
408 | - * and then the user is redirected to a page that displays the payment's status, this |
|
409 | - * should be called while loading the page that displays the payment's status. If the user is |
|
410 | - * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
411 | - * provider. |
|
412 | - * |
|
413 | - * @param EE_Transaction|int $transaction |
|
414 | - * @param bool $update_txn whether or not to call |
|
415 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
416 | - * @return EE_Payment |
|
417 | - * @throws EE_Error |
|
418 | - * @throws InvalidArgumentException |
|
419 | - * @throws ReflectionException |
|
420 | - * @throws RuntimeException |
|
421 | - * @throws InvalidDataTypeException |
|
422 | - * @throws InvalidInterfaceException |
|
423 | - * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
424 | - * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
425 | - */ |
|
426 | - public function finalize_payment_for($transaction, $update_txn = true) |
|
427 | - { |
|
428 | - /** @var $transaction EE_Transaction */ |
|
429 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
430 | - $last_payment_method = $transaction->payment_method(); |
|
431 | - if ($last_payment_method instanceof EE_Payment_Method) { |
|
432 | - $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
433 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
434 | - return $payment; |
|
435 | - } |
|
436 | - return null; |
|
437 | - } |
|
438 | - |
|
439 | - |
|
440 | - /** |
|
441 | - * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
442 | - * |
|
443 | - * @param EE_Payment_Method $payment_method |
|
444 | - * @param EE_Payment $payment_to_refund |
|
445 | - * @param array $refund_info |
|
446 | - * @return EE_Payment |
|
447 | - * @throws EE_Error |
|
448 | - * @throws InvalidArgumentException |
|
449 | - * @throws ReflectionException |
|
450 | - * @throws RuntimeException |
|
451 | - * @throws InvalidDataTypeException |
|
452 | - * @throws InvalidInterfaceException |
|
453 | - */ |
|
454 | - public function process_refund( |
|
455 | - EE_Payment_Method $payment_method, |
|
456 | - EE_Payment $payment_to_refund, |
|
457 | - array $refund_info = array() |
|
458 | - ) { |
|
459 | - if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
460 | - $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
461 | - $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
462 | - } |
|
463 | - return $payment_to_refund; |
|
464 | - } |
|
465 | - |
|
466 | - |
|
467 | - /** |
|
468 | - * This should be called each time there may have been an update to a |
|
469 | - * payment on a transaction (ie, we asked for a payment to process a |
|
470 | - * payment for a transaction, or we told a payment method about an IPN, or |
|
471 | - * we told a payment method to |
|
472 | - * "finalize_payment_for" (a transaction), or we told a payment method to |
|
473 | - * process a refund. This should handle firing the correct hooks to |
|
474 | - * indicate |
|
475 | - * what exactly happened and updating the transaction appropriately). This |
|
476 | - * could be integrated directly into EE_Transaction upon save, but we want |
|
477 | - * this logic to be separate from 'normal' plain-jane saving and updating |
|
478 | - * of transactions and payments, and to be tied to payment processing. |
|
479 | - * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
480 | - * of previous code to decide whether or not to save (because the payment passed into |
|
481 | - * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
482 | - * in which case we only want that payment object for some temporary usage during this request, |
|
483 | - * but we don't want it to be saved). |
|
484 | - * |
|
485 | - * @param EE_Transaction|int $transaction |
|
486 | - * @param EE_Payment $payment |
|
487 | - * @param boolean $update_txn |
|
488 | - * whether or not to call |
|
489 | - * EE_Transaction_Processor:: |
|
490 | - * update_transaction_and_registrations_after_checkout_or_payment() |
|
491 | - * (you can save 1 DB query if you know you're going |
|
492 | - * to save it later instead) |
|
493 | - * @param bool $IPN |
|
494 | - * if processing IPNs or other similar payment |
|
495 | - * related activities that occur in alternate |
|
496 | - * requests than the main one that is processing the |
|
497 | - * TXN, then set this to true to check whether the |
|
498 | - * TXN is locked before updating |
|
499 | - * @throws EE_Error |
|
500 | - * @throws InvalidArgumentException |
|
501 | - * @throws ReflectionException |
|
502 | - * @throws RuntimeException |
|
503 | - * @throws InvalidDataTypeException |
|
504 | - * @throws InvalidInterfaceException |
|
505 | - */ |
|
506 | - public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
507 | - { |
|
508 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
509 | - /** @type EE_Transaction $transaction */ |
|
510 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
511 | - // can we freely update the TXN at this moment? |
|
512 | - if ($IPN && $transaction->is_locked()) { |
|
513 | - // don't update the transaction at this exact moment |
|
514 | - // because the TXN is active in another request |
|
515 | - EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
516 | - time(), |
|
517 | - $transaction->ID(), |
|
518 | - $payment->ID() |
|
519 | - ); |
|
520 | - } else { |
|
521 | - // verify payment and that it has been saved |
|
522 | - if ($payment instanceof EE_Payment && $payment->ID()) { |
|
523 | - if ( |
|
524 | - $payment->payment_method() instanceof EE_Payment_Method |
|
525 | - && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
526 | - ) { |
|
527 | - $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
528 | - // update TXN registrations with payment info |
|
529 | - $this->process_registration_payments($transaction, $payment); |
|
530 | - } |
|
531 | - $do_action = $payment->just_approved() |
|
532 | - ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
533 | - : $do_action; |
|
534 | - } else { |
|
535 | - // send out notifications |
|
536 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
537 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
538 | - } |
|
539 | - if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
540 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
541 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
542 | - // set new value for total paid |
|
543 | - $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
544 | - // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
545 | - if ($update_txn) { |
|
546 | - $this->_post_payment_processing($transaction, $payment, $IPN); |
|
547 | - } |
|
548 | - } |
|
549 | - // granular hook for others to use. |
|
550 | - do_action($do_action, $transaction, $payment); |
|
551 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
552 | - // global hook for others to use. |
|
553 | - do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
554 | - } |
|
555 | - } |
|
556 | - |
|
557 | - |
|
558 | - /** |
|
559 | - * update registrations REG_paid field after successful payment and link registrations with payment |
|
560 | - * |
|
561 | - * @param EE_Transaction $transaction |
|
562 | - * @param EE_Payment $payment |
|
563 | - * @param EE_Registration[] $registrations |
|
564 | - * @throws EE_Error |
|
565 | - * @throws InvalidArgumentException |
|
566 | - * @throws RuntimeException |
|
567 | - * @throws InvalidDataTypeException |
|
568 | - * @throws InvalidInterfaceException |
|
569 | - */ |
|
570 | - public function process_registration_payments( |
|
571 | - EE_Transaction $transaction, |
|
572 | - EE_Payment $payment, |
|
573 | - array $registrations = array() |
|
574 | - ) { |
|
575 | - // only process if payment was successful |
|
576 | - if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
577 | - return; |
|
578 | - } |
|
579 | - // EEM_Registration::instance()->show_next_x_db_queries(); |
|
580 | - if (empty($registrations)) { |
|
581 | - // find registrations with monies owing that can receive a payment |
|
582 | - $registrations = $transaction->registrations( |
|
583 | - array( |
|
584 | - array( |
|
585 | - // only these reg statuses can receive payments |
|
586 | - 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
587 | - 'REG_final_price' => array('!=', 0), |
|
588 | - 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
589 | - ), |
|
590 | - ) |
|
591 | - ); |
|
592 | - } |
|
593 | - // still nothing ??!?? |
|
594 | - if (empty($registrations)) { |
|
595 | - return; |
|
596 | - } |
|
597 | - // todo: break out the following logic into a separate strategy class |
|
598 | - // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
599 | - // todo: which would apply payments using the capitalist "first come first paid" approach |
|
600 | - // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
601 | - // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
602 | - // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
603 | - $refund = $payment->is_a_refund(); |
|
604 | - // how much is available to apply to registrations? |
|
605 | - $available_payment_amount = abs($payment->amount()); |
|
606 | - foreach ($registrations as $registration) { |
|
607 | - if ($registration instanceof EE_Registration) { |
|
608 | - // nothing left? |
|
609 | - if ($available_payment_amount <= 0) { |
|
610 | - break; |
|
611 | - } |
|
612 | - if ($refund) { |
|
613 | - $available_payment_amount = $this->process_registration_refund( |
|
614 | - $registration, |
|
615 | - $payment, |
|
616 | - $available_payment_amount |
|
617 | - ); |
|
618 | - } else { |
|
619 | - $available_payment_amount = $this->process_registration_payment( |
|
620 | - $registration, |
|
621 | - $payment, |
|
622 | - $available_payment_amount |
|
623 | - ); |
|
624 | - } |
|
625 | - } |
|
626 | - } |
|
627 | - if ( |
|
628 | - $available_payment_amount > 0 |
|
629 | - && apply_filters( |
|
630 | - 'FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', |
|
631 | - false |
|
632 | - ) |
|
633 | - ) { |
|
634 | - EE_Error::add_attention( |
|
635 | - sprintf( |
|
636 | - esc_html__( |
|
637 | - 'A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
638 | - 'event_espresso' |
|
639 | - ), |
|
640 | - EEH_Template::format_currency($available_payment_amount), |
|
641 | - implode(', ', array_keys($registrations)), |
|
642 | - '<br/>', |
|
643 | - EEH_Template::format_currency($payment->amount()) |
|
644 | - ), |
|
645 | - __FILE__, |
|
646 | - __FUNCTION__, |
|
647 | - __LINE__ |
|
648 | - ); |
|
649 | - } |
|
650 | - } |
|
651 | - |
|
652 | - |
|
653 | - /** |
|
654 | - * update registration REG_paid field after successful payment and link registration with payment |
|
655 | - * |
|
656 | - * @param EE_Registration $registration |
|
657 | - * @param EE_Payment $payment |
|
658 | - * @param float $available_payment_amount |
|
659 | - * @return float |
|
660 | - * @throws EE_Error |
|
661 | - * @throws InvalidArgumentException |
|
662 | - * @throws RuntimeException |
|
663 | - * @throws InvalidDataTypeException |
|
664 | - * @throws InvalidInterfaceException |
|
665 | - */ |
|
666 | - public function process_registration_payment( |
|
667 | - EE_Registration $registration, |
|
668 | - EE_Payment $payment, |
|
669 | - $available_payment_amount = 0.00 |
|
670 | - ) { |
|
671 | - $owing = $registration->final_price() - $registration->paid(); |
|
672 | - if ($owing > 0) { |
|
673 | - // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
674 | - $payment_amount = min($available_payment_amount, $owing); |
|
675 | - // update $available_payment_amount |
|
676 | - $available_payment_amount -= $payment_amount; |
|
677 | - // calculate and set new REG_paid |
|
678 | - $registration->set_paid($registration->paid() + $payment_amount); |
|
679 | - // now save it |
|
680 | - $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
681 | - } |
|
682 | - return $available_payment_amount; |
|
683 | - } |
|
684 | - |
|
685 | - |
|
686 | - /** |
|
687 | - * update registration REG_paid field after successful payment and link registration with payment |
|
688 | - * |
|
689 | - * @param EE_Registration $registration |
|
690 | - * @param EE_Payment $payment |
|
691 | - * @param float $payment_amount |
|
692 | - * @return void |
|
693 | - * @throws EE_Error |
|
694 | - * @throws InvalidArgumentException |
|
695 | - * @throws InvalidDataTypeException |
|
696 | - * @throws InvalidInterfaceException |
|
697 | - */ |
|
698 | - protected function _apply_registration_payment( |
|
699 | - EE_Registration $registration, |
|
700 | - EE_Payment $payment, |
|
701 | - $payment_amount = 0.00 |
|
702 | - ) { |
|
703 | - // find any existing reg payment records for this registration and payment |
|
704 | - $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
705 | - array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
706 | - ); |
|
707 | - // if existing registration payment exists |
|
708 | - if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
709 | - // then update that record |
|
710 | - $existing_reg_payment->set_amount($payment_amount); |
|
711 | - $existing_reg_payment->save(); |
|
712 | - } else { |
|
713 | - // or add new relation between registration and payment and set amount |
|
714 | - $registration->_add_relation_to( |
|
715 | - $payment, |
|
716 | - 'Payment', |
|
717 | - array('RPY_amount' => $payment_amount) |
|
718 | - ); |
|
719 | - // make it stick |
|
720 | - $registration->save(); |
|
721 | - } |
|
722 | - } |
|
723 | - |
|
724 | - |
|
725 | - /** |
|
726 | - * update registration REG_paid field after refund and link registration with payment |
|
727 | - * |
|
728 | - * @param EE_Registration $registration |
|
729 | - * @param EE_Payment $payment |
|
730 | - * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
731 | - * @return float |
|
732 | - * @throws EE_Error |
|
733 | - * @throws InvalidArgumentException |
|
734 | - * @throws RuntimeException |
|
735 | - * @throws InvalidDataTypeException |
|
736 | - * @throws InvalidInterfaceException |
|
737 | - */ |
|
738 | - public function process_registration_refund( |
|
739 | - EE_Registration $registration, |
|
740 | - EE_Payment $payment, |
|
741 | - $available_refund_amount = 0.00 |
|
742 | - ) { |
|
743 | - // EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
744 | - if ($registration->paid() > 0) { |
|
745 | - // ensure $available_refund_amount is NOT negative |
|
746 | - $available_refund_amount = (float) abs($available_refund_amount); |
|
747 | - // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
748 | - $refund_amount = min($available_refund_amount, (float) $registration->paid()); |
|
749 | - // update $available_payment_amount |
|
750 | - $available_refund_amount -= $refund_amount; |
|
751 | - // calculate and set new REG_paid |
|
752 | - $registration->set_paid($registration->paid() - $refund_amount); |
|
753 | - // convert payment amount back to a negative value for storage in the db |
|
754 | - $refund_amount = (float) abs($refund_amount) * -1; |
|
755 | - // now save it |
|
756 | - $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
757 | - } |
|
758 | - return $available_refund_amount; |
|
759 | - } |
|
760 | - |
|
761 | - |
|
762 | - /** |
|
763 | - * Process payments and transaction after payment process completed. |
|
764 | - * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
765 | - * if this request happens to be processing an IPN, |
|
766 | - * then we will also set the Payment Options Reg Step to completed, |
|
767 | - * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
768 | - * |
|
769 | - * @param EE_Transaction $transaction |
|
770 | - * @param EE_Payment $payment |
|
771 | - * @param bool $IPN |
|
772 | - * @throws EE_Error |
|
773 | - * @throws InvalidArgumentException |
|
774 | - * @throws ReflectionException |
|
775 | - * @throws RuntimeException |
|
776 | - * @throws InvalidDataTypeException |
|
777 | - * @throws InvalidInterfaceException |
|
778 | - */ |
|
779 | - protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
780 | - { |
|
781 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
782 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
783 | - // is the Payment Options Reg Step completed ? |
|
784 | - $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
785 | - // if the Payment Options Reg Step is completed... |
|
786 | - $revisit = $payment_options_step_completed === true; |
|
787 | - // then this is kinda sorta a revisit with regards to payments at least |
|
788 | - $transaction_processor->set_revisit($revisit); |
|
789 | - // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
790 | - if ( |
|
791 | - $IPN |
|
792 | - && $payment_options_step_completed !== true |
|
793 | - && ($payment->is_approved() || $payment->is_pending()) |
|
794 | - ) { |
|
795 | - $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
796 | - 'payment_options' |
|
797 | - ); |
|
798 | - } |
|
799 | - // maybe update status, but don't save transaction just yet |
|
800 | - $transaction->update_status_based_on_total_paid(false); |
|
801 | - // check if 'finalize_registration' step has been completed... |
|
802 | - $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
803 | - // if this is an IPN and the final step has not been initiated |
|
804 | - if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
805 | - // and if it hasn't already been set as being started... |
|
806 | - $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
807 | - } |
|
808 | - $transaction->save(); |
|
809 | - // because the above will return false if the final step was not fully completed, we need to check again... |
|
810 | - if ($IPN && $finalized !== false) { |
|
811 | - // and if we are all good to go, then send out notifications |
|
812 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
813 | - // ok, now process the transaction according to the payment |
|
814 | - $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
815 | - $transaction, |
|
816 | - $payment |
|
817 | - ); |
|
818 | - } |
|
819 | - // DEBUG LOG |
|
820 | - $payment_method = $payment->payment_method(); |
|
821 | - if ($payment_method instanceof EE_Payment_Method) { |
|
822 | - $payment_method_type_obj = $payment_method->type_obj(); |
|
823 | - if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
824 | - $gateway = $payment_method_type_obj->get_gateway(); |
|
825 | - if ($gateway instanceof EE_Gateway) { |
|
826 | - $gateway->log( |
|
827 | - array( |
|
828 | - 'message' => (string) esc_html__('Post Payment Transaction Details', 'event_espresso'), |
|
829 | - 'transaction' => $transaction->model_field_array(), |
|
830 | - 'finalized' => $finalized, |
|
831 | - 'IPN' => $IPN, |
|
832 | - 'deliver_notifications' => has_filter( |
|
833 | - 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
834 | - ), |
|
835 | - ), |
|
836 | - $payment |
|
837 | - ); |
|
838 | - } |
|
839 | - } |
|
840 | - } |
|
841 | - } |
|
842 | - |
|
843 | - |
|
844 | - /** |
|
845 | - * Force posts to PayPal to use TLS v1.2. See: |
|
846 | - * https://core.trac.wordpress.org/ticket/36320 |
|
847 | - * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
848 | - * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
849 | - * This will affect PayPal standard, pro, express, and Payflow. |
|
850 | - * |
|
851 | - * @param $handle |
|
852 | - * @param $r |
|
853 | - * @param $url |
|
854 | - */ |
|
855 | - public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
856 | - { |
|
857 | - if (strpos($url, 'https://') !== false && strpos($url, '.paypal.com') !== false) { |
|
858 | - // Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
859 | - // instead of the constant because it might not be defined |
|
860 | - curl_setopt($handle, CURLOPT_SSLVERSION, 6); |
|
861 | - } |
|
862 | - } |
|
21 | + /** |
|
22 | + * @var EE_Payment_Processor $_instance |
|
23 | + * @access private |
|
24 | + */ |
|
25 | + private static $_instance; |
|
26 | + |
|
27 | + |
|
28 | + /** |
|
29 | + * @singleton method used to instantiate class object |
|
30 | + * @access public |
|
31 | + * @return EE_Payment_Processor instance |
|
32 | + */ |
|
33 | + public static function instance() |
|
34 | + { |
|
35 | + // check if class object is instantiated |
|
36 | + if (! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | + self::$_instance = new self(); |
|
38 | + } |
|
39 | + return self::$_instance; |
|
40 | + } |
|
41 | + |
|
42 | + |
|
43 | + /** |
|
44 | + * @return EE_Payment_Processor |
|
45 | + */ |
|
46 | + public static function reset() |
|
47 | + { |
|
48 | + self::$_instance = null; |
|
49 | + return self::instance(); |
|
50 | + } |
|
51 | + |
|
52 | + |
|
53 | + /** |
|
54 | + *private constructor to prevent direct creation |
|
55 | + * |
|
56 | + * @Constructor |
|
57 | + * @access private |
|
58 | + */ |
|
59 | + private function __construct() |
|
60 | + { |
|
61 | + do_action('AHEE__EE_Payment_Processor__construct'); |
|
62 | + add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
63 | + } |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
68 | + * appropriately. Saves the payment that is generated |
|
69 | + * |
|
70 | + * @param EE_Payment_Method $payment_method |
|
71 | + * @param EE_Transaction $transaction |
|
72 | + * @param float $amount if only part of the transaction is to be paid for, how much. |
|
73 | + * Leave null if payment is for the full amount owing |
|
74 | + * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
75 | + * Receive_form_submission() should have |
|
76 | + * already been called on the billing form |
|
77 | + * (ie, its inputs should have their normalized values set). |
|
78 | + * @param string $return_url string used mostly by offsite gateways to specify |
|
79 | + * where to go AFTER the offsite gateway |
|
80 | + * @param string $method like 'CART', indicates who the client who called this was |
|
81 | + * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
82 | + * @param boolean $update_txn whether or not to call |
|
83 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
84 | + * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
85 | + * @return EE_Payment |
|
86 | + * @throws EE_Error |
|
87 | + * @throws InvalidArgumentException |
|
88 | + * @throws ReflectionException |
|
89 | + * @throws RuntimeException |
|
90 | + * @throws InvalidDataTypeException |
|
91 | + * @throws InvalidInterfaceException |
|
92 | + */ |
|
93 | + public function process_payment( |
|
94 | + EE_Payment_Method $payment_method, |
|
95 | + EE_Transaction $transaction, |
|
96 | + $amount = null, |
|
97 | + $billing_form = null, |
|
98 | + $return_url = null, |
|
99 | + $method = 'CART', |
|
100 | + $by_admin = false, |
|
101 | + $update_txn = true, |
|
102 | + $cancel_url = '' |
|
103 | + ) { |
|
104 | + if ((float) $amount < 0) { |
|
105 | + throw new EE_Error( |
|
106 | + sprintf( |
|
107 | + esc_html__( |
|
108 | + 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
109 | + 'event_espresso' |
|
110 | + ), |
|
111 | + $amount, |
|
112 | + $transaction->ID() |
|
113 | + ) |
|
114 | + ); |
|
115 | + } |
|
116 | + // verify payment method |
|
117 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
118 | + $payment_method, |
|
119 | + true |
|
120 | + ); |
|
121 | + // verify transaction |
|
122 | + EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
123 | + $transaction->set_payment_method_ID($payment_method->ID()); |
|
124 | + // verify payment method type |
|
125 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
126 | + $payment = $payment_method->type_obj()->process_payment( |
|
127 | + $transaction, |
|
128 | + min($amount, $transaction->remaining()), // make sure we don't overcharge |
|
129 | + $billing_form, |
|
130 | + $return_url, |
|
131 | + add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
132 | + $method, |
|
133 | + $by_admin |
|
134 | + ); |
|
135 | + // check if payment method uses an off-site gateway |
|
136 | + if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
137 | + // don't process payments for off-site gateways yet because no payment has occurred yet |
|
138 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
139 | + } |
|
140 | + return $payment; |
|
141 | + } |
|
142 | + EE_Error::add_error( |
|
143 | + sprintf( |
|
144 | + esc_html__( |
|
145 | + 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
146 | + 'event_espresso' |
|
147 | + ), |
|
148 | + '<br/>', |
|
149 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
150 | + ), |
|
151 | + __FILE__, |
|
152 | + __FUNCTION__, |
|
153 | + __LINE__ |
|
154 | + ); |
|
155 | + return null; |
|
156 | + } |
|
157 | + |
|
158 | + |
|
159 | + /** |
|
160 | + * @param EE_Transaction|int $transaction |
|
161 | + * @param EE_Payment_Method $payment_method |
|
162 | + * @return string |
|
163 | + * @throws EE_Error |
|
164 | + * @throws InvalidArgumentException |
|
165 | + * @throws InvalidDataTypeException |
|
166 | + * @throws InvalidInterfaceException |
|
167 | + */ |
|
168 | + public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
169 | + { |
|
170 | + /** @type \EE_Transaction $transaction */ |
|
171 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
172 | + $primary_reg = $transaction->primary_registration(); |
|
173 | + if (! $primary_reg instanceof EE_Registration) { |
|
174 | + throw new EE_Error( |
|
175 | + sprintf( |
|
176 | + esc_html__( |
|
177 | + 'Cannot get IPN URL for transaction with ID %d because it has no primary registration', |
|
178 | + 'event_espresso' |
|
179 | + ), |
|
180 | + $transaction->ID() |
|
181 | + ) |
|
182 | + ); |
|
183 | + } |
|
184 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
185 | + $payment_method, |
|
186 | + true |
|
187 | + ); |
|
188 | + $url = add_query_arg( |
|
189 | + array( |
|
190 | + 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
191 | + 'ee_payment_method' => $payment_method->slug(), |
|
192 | + ), |
|
193 | + EE_Registry::instance()->CFG->core->txn_page_url() |
|
194 | + ); |
|
195 | + return $url; |
|
196 | + } |
|
197 | + |
|
198 | + |
|
199 | + /** |
|
200 | + * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
201 | + * we can easily find what registration the IPN is for and what payment method. |
|
202 | + * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
203 | + * If a payment is found for the IPN info, it is saved. |
|
204 | + * |
|
205 | + * @param array $_req_data form post data |
|
206 | + * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
207 | + * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
208 | + * @param boolean $update_txn whether or not to call |
|
209 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
210 | + * @param bool $separate_IPN_request whether the IPN uses a separate request (true, like PayPal) |
|
211 | + * or is processed manually (false, like Authorize.net) |
|
212 | + * @throws EE_Error |
|
213 | + * @throws Exception |
|
214 | + * @return EE_Payment |
|
215 | + * @throws \RuntimeException |
|
216 | + * @throws \ReflectionException |
|
217 | + * @throws \InvalidArgumentException |
|
218 | + * @throws InvalidInterfaceException |
|
219 | + * @throws InvalidDataTypeException |
|
220 | + */ |
|
221 | + public function process_ipn( |
|
222 | + $_req_data, |
|
223 | + $transaction = null, |
|
224 | + $payment_method = null, |
|
225 | + $update_txn = true, |
|
226 | + $separate_IPN_request = true |
|
227 | + ) { |
|
228 | + EE_Registry::instance()->load_model('Change_Log'); |
|
229 | + $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data); |
|
230 | + EE_Processor_Base::set_IPN($separate_IPN_request); |
|
231 | + $obj_for_log = null; |
|
232 | + if ($transaction instanceof EE_Transaction) { |
|
233 | + $obj_for_log = $transaction; |
|
234 | + if ($payment_method instanceof EE_Payment_Method) { |
|
235 | + $obj_for_log = EEM_Payment::instance()->get_one( |
|
236 | + array( |
|
237 | + array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
238 | + 'order_by' => array('PAY_timestamp' => 'desc'), |
|
239 | + ) |
|
240 | + ); |
|
241 | + } |
|
242 | + } elseif ($payment_method instanceof EE_Payment) { |
|
243 | + $obj_for_log = $payment_method; |
|
244 | + } |
|
245 | + $log = EEM_Change_Log::instance()->log( |
|
246 | + EEM_Change_Log::type_gateway, |
|
247 | + array('IPN data received' => $_req_data), |
|
248 | + $obj_for_log |
|
249 | + ); |
|
250 | + try { |
|
251 | + /** |
|
252 | + * @var EE_Payment $payment |
|
253 | + */ |
|
254 | + $payment = null; |
|
255 | + if ($transaction && $payment_method) { |
|
256 | + /** @type EE_Transaction $transaction */ |
|
257 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
258 | + /** @type EE_Payment_Method $payment_method */ |
|
259 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
260 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
261 | + try { |
|
262 | + $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
263 | + $log->set_object($payment); |
|
264 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
265 | + EEM_Change_Log::instance()->log( |
|
266 | + EEM_Change_Log::type_gateway, |
|
267 | + array( |
|
268 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
269 | + 'current_url' => EEH_URL::current_url(), |
|
270 | + 'payment' => $e->getPaymentProperties(), |
|
271 | + 'IPN_data' => $e->getIpnData(), |
|
272 | + ), |
|
273 | + $obj_for_log |
|
274 | + ); |
|
275 | + return $e->getPayment(); |
|
276 | + } |
|
277 | + } else { |
|
278 | + // not a payment |
|
279 | + EE_Error::add_error( |
|
280 | + sprintf( |
|
281 | + esc_html__( |
|
282 | + 'A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', |
|
283 | + 'event_espresso' |
|
284 | + ), |
|
285 | + '<br/>', |
|
286 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
287 | + ), |
|
288 | + __FILE__, |
|
289 | + __FUNCTION__, |
|
290 | + __LINE__ |
|
291 | + ); |
|
292 | + } |
|
293 | + } else { |
|
294 | + // that's actually pretty ok. The IPN just wasn't able |
|
295 | + // to identify which transaction or payment method this was for |
|
296 | + // give all active payment methods a chance to claim it |
|
297 | + $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
298 | + foreach ($active_payment_methods as $active_payment_method) { |
|
299 | + try { |
|
300 | + $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
301 | + $payment_method = $active_payment_method; |
|
302 | + EEM_Change_Log::instance()->log( |
|
303 | + EEM_Change_Log::type_gateway, |
|
304 | + array('IPN data' => $_req_data), |
|
305 | + $payment |
|
306 | + ); |
|
307 | + break; |
|
308 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
309 | + EEM_Change_Log::instance()->log( |
|
310 | + EEM_Change_Log::type_gateway, |
|
311 | + array( |
|
312 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
313 | + 'current_url' => EEH_URL::current_url(), |
|
314 | + 'payment' => $e->getPaymentProperties(), |
|
315 | + 'IPN_data' => $e->getIpnData(), |
|
316 | + ), |
|
317 | + $obj_for_log |
|
318 | + ); |
|
319 | + return $e->getPayment(); |
|
320 | + } catch (EE_Error $e) { |
|
321 | + // that's fine- it apparently couldn't handle the IPN |
|
322 | + } |
|
323 | + } |
|
324 | + } |
|
325 | + // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
326 | + if ($payment instanceof EE_Payment) { |
|
327 | + $payment->save(); |
|
328 | + // update the TXN |
|
329 | + $this->update_txn_based_on_payment( |
|
330 | + $transaction, |
|
331 | + $payment, |
|
332 | + $update_txn, |
|
333 | + $separate_IPN_request |
|
334 | + ); |
|
335 | + } else { |
|
336 | + // we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
337 | + if ($payment_method) { |
|
338 | + EEM_Change_Log::instance()->log( |
|
339 | + EEM_Change_Log::type_gateway, |
|
340 | + array('IPN data' => $_req_data), |
|
341 | + $payment_method |
|
342 | + ); |
|
343 | + } elseif ($transaction) { |
|
344 | + EEM_Change_Log::instance()->log( |
|
345 | + EEM_Change_Log::type_gateway, |
|
346 | + array('IPN data' => $_req_data), |
|
347 | + $transaction |
|
348 | + ); |
|
349 | + } |
|
350 | + } |
|
351 | + return $payment; |
|
352 | + } catch (EE_Error $e) { |
|
353 | + do_action( |
|
354 | + 'AHEE__log', |
|
355 | + __FILE__, |
|
356 | + __FUNCTION__, |
|
357 | + sprintf( |
|
358 | + esc_html__( |
|
359 | + 'Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', |
|
360 | + 'event_espresso' |
|
361 | + ), |
|
362 | + print_r($transaction, true), |
|
363 | + print_r($_req_data, true), |
|
364 | + $e->getMessage() |
|
365 | + ) |
|
366 | + ); |
|
367 | + throw $e; |
|
368 | + } |
|
369 | + } |
|
370 | + |
|
371 | + |
|
372 | + /** |
|
373 | + * Removes any non-printable illegal characters from the input, |
|
374 | + * which might cause a raucous when trying to insert into the database |
|
375 | + * |
|
376 | + * @param array $request_data |
|
377 | + * @return array |
|
378 | + */ |
|
379 | + protected function _remove_unusable_characters_from_array(array $request_data) |
|
380 | + { |
|
381 | + $return_data = array(); |
|
382 | + foreach ($request_data as $key => $value) { |
|
383 | + $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
384 | + $value |
|
385 | + ); |
|
386 | + } |
|
387 | + return $return_data; |
|
388 | + } |
|
389 | + |
|
390 | + |
|
391 | + /** |
|
392 | + * Removes any non-printable illegal characters from the input, |
|
393 | + * which might cause a raucous when trying to insert into the database |
|
394 | + * |
|
395 | + * @param string $request_data |
|
396 | + * @return string |
|
397 | + */ |
|
398 | + protected function _remove_unusable_characters($request_data) |
|
399 | + { |
|
400 | + return preg_replace('/[^[:print:]]/', '', $request_data); |
|
401 | + } |
|
402 | + |
|
403 | + |
|
404 | + /** |
|
405 | + * Should be called just before displaying the payment attempt results to the user, |
|
406 | + * when the payment attempt has finished. Some payment methods may have special |
|
407 | + * logic to perform here. For example, if process_payment() happens on a special request |
|
408 | + * and then the user is redirected to a page that displays the payment's status, this |
|
409 | + * should be called while loading the page that displays the payment's status. If the user is |
|
410 | + * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
411 | + * provider. |
|
412 | + * |
|
413 | + * @param EE_Transaction|int $transaction |
|
414 | + * @param bool $update_txn whether or not to call |
|
415 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
416 | + * @return EE_Payment |
|
417 | + * @throws EE_Error |
|
418 | + * @throws InvalidArgumentException |
|
419 | + * @throws ReflectionException |
|
420 | + * @throws RuntimeException |
|
421 | + * @throws InvalidDataTypeException |
|
422 | + * @throws InvalidInterfaceException |
|
423 | + * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
424 | + * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
425 | + */ |
|
426 | + public function finalize_payment_for($transaction, $update_txn = true) |
|
427 | + { |
|
428 | + /** @var $transaction EE_Transaction */ |
|
429 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
430 | + $last_payment_method = $transaction->payment_method(); |
|
431 | + if ($last_payment_method instanceof EE_Payment_Method) { |
|
432 | + $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
433 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
434 | + return $payment; |
|
435 | + } |
|
436 | + return null; |
|
437 | + } |
|
438 | + |
|
439 | + |
|
440 | + /** |
|
441 | + * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
442 | + * |
|
443 | + * @param EE_Payment_Method $payment_method |
|
444 | + * @param EE_Payment $payment_to_refund |
|
445 | + * @param array $refund_info |
|
446 | + * @return EE_Payment |
|
447 | + * @throws EE_Error |
|
448 | + * @throws InvalidArgumentException |
|
449 | + * @throws ReflectionException |
|
450 | + * @throws RuntimeException |
|
451 | + * @throws InvalidDataTypeException |
|
452 | + * @throws InvalidInterfaceException |
|
453 | + */ |
|
454 | + public function process_refund( |
|
455 | + EE_Payment_Method $payment_method, |
|
456 | + EE_Payment $payment_to_refund, |
|
457 | + array $refund_info = array() |
|
458 | + ) { |
|
459 | + if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
460 | + $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
461 | + $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
462 | + } |
|
463 | + return $payment_to_refund; |
|
464 | + } |
|
465 | + |
|
466 | + |
|
467 | + /** |
|
468 | + * This should be called each time there may have been an update to a |
|
469 | + * payment on a transaction (ie, we asked for a payment to process a |
|
470 | + * payment for a transaction, or we told a payment method about an IPN, or |
|
471 | + * we told a payment method to |
|
472 | + * "finalize_payment_for" (a transaction), or we told a payment method to |
|
473 | + * process a refund. This should handle firing the correct hooks to |
|
474 | + * indicate |
|
475 | + * what exactly happened and updating the transaction appropriately). This |
|
476 | + * could be integrated directly into EE_Transaction upon save, but we want |
|
477 | + * this logic to be separate from 'normal' plain-jane saving and updating |
|
478 | + * of transactions and payments, and to be tied to payment processing. |
|
479 | + * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
480 | + * of previous code to decide whether or not to save (because the payment passed into |
|
481 | + * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
482 | + * in which case we only want that payment object for some temporary usage during this request, |
|
483 | + * but we don't want it to be saved). |
|
484 | + * |
|
485 | + * @param EE_Transaction|int $transaction |
|
486 | + * @param EE_Payment $payment |
|
487 | + * @param boolean $update_txn |
|
488 | + * whether or not to call |
|
489 | + * EE_Transaction_Processor:: |
|
490 | + * update_transaction_and_registrations_after_checkout_or_payment() |
|
491 | + * (you can save 1 DB query if you know you're going |
|
492 | + * to save it later instead) |
|
493 | + * @param bool $IPN |
|
494 | + * if processing IPNs or other similar payment |
|
495 | + * related activities that occur in alternate |
|
496 | + * requests than the main one that is processing the |
|
497 | + * TXN, then set this to true to check whether the |
|
498 | + * TXN is locked before updating |
|
499 | + * @throws EE_Error |
|
500 | + * @throws InvalidArgumentException |
|
501 | + * @throws ReflectionException |
|
502 | + * @throws RuntimeException |
|
503 | + * @throws InvalidDataTypeException |
|
504 | + * @throws InvalidInterfaceException |
|
505 | + */ |
|
506 | + public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
507 | + { |
|
508 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
509 | + /** @type EE_Transaction $transaction */ |
|
510 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
511 | + // can we freely update the TXN at this moment? |
|
512 | + if ($IPN && $transaction->is_locked()) { |
|
513 | + // don't update the transaction at this exact moment |
|
514 | + // because the TXN is active in another request |
|
515 | + EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
516 | + time(), |
|
517 | + $transaction->ID(), |
|
518 | + $payment->ID() |
|
519 | + ); |
|
520 | + } else { |
|
521 | + // verify payment and that it has been saved |
|
522 | + if ($payment instanceof EE_Payment && $payment->ID()) { |
|
523 | + if ( |
|
524 | + $payment->payment_method() instanceof EE_Payment_Method |
|
525 | + && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
526 | + ) { |
|
527 | + $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
528 | + // update TXN registrations with payment info |
|
529 | + $this->process_registration_payments($transaction, $payment); |
|
530 | + } |
|
531 | + $do_action = $payment->just_approved() |
|
532 | + ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
533 | + : $do_action; |
|
534 | + } else { |
|
535 | + // send out notifications |
|
536 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
537 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
538 | + } |
|
539 | + if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
540 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
541 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
542 | + // set new value for total paid |
|
543 | + $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
544 | + // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
545 | + if ($update_txn) { |
|
546 | + $this->_post_payment_processing($transaction, $payment, $IPN); |
|
547 | + } |
|
548 | + } |
|
549 | + // granular hook for others to use. |
|
550 | + do_action($do_action, $transaction, $payment); |
|
551 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
552 | + // global hook for others to use. |
|
553 | + do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
554 | + } |
|
555 | + } |
|
556 | + |
|
557 | + |
|
558 | + /** |
|
559 | + * update registrations REG_paid field after successful payment and link registrations with payment |
|
560 | + * |
|
561 | + * @param EE_Transaction $transaction |
|
562 | + * @param EE_Payment $payment |
|
563 | + * @param EE_Registration[] $registrations |
|
564 | + * @throws EE_Error |
|
565 | + * @throws InvalidArgumentException |
|
566 | + * @throws RuntimeException |
|
567 | + * @throws InvalidDataTypeException |
|
568 | + * @throws InvalidInterfaceException |
|
569 | + */ |
|
570 | + public function process_registration_payments( |
|
571 | + EE_Transaction $transaction, |
|
572 | + EE_Payment $payment, |
|
573 | + array $registrations = array() |
|
574 | + ) { |
|
575 | + // only process if payment was successful |
|
576 | + if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
577 | + return; |
|
578 | + } |
|
579 | + // EEM_Registration::instance()->show_next_x_db_queries(); |
|
580 | + if (empty($registrations)) { |
|
581 | + // find registrations with monies owing that can receive a payment |
|
582 | + $registrations = $transaction->registrations( |
|
583 | + array( |
|
584 | + array( |
|
585 | + // only these reg statuses can receive payments |
|
586 | + 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
587 | + 'REG_final_price' => array('!=', 0), |
|
588 | + 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
589 | + ), |
|
590 | + ) |
|
591 | + ); |
|
592 | + } |
|
593 | + // still nothing ??!?? |
|
594 | + if (empty($registrations)) { |
|
595 | + return; |
|
596 | + } |
|
597 | + // todo: break out the following logic into a separate strategy class |
|
598 | + // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
599 | + // todo: which would apply payments using the capitalist "first come first paid" approach |
|
600 | + // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
601 | + // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
602 | + // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
603 | + $refund = $payment->is_a_refund(); |
|
604 | + // how much is available to apply to registrations? |
|
605 | + $available_payment_amount = abs($payment->amount()); |
|
606 | + foreach ($registrations as $registration) { |
|
607 | + if ($registration instanceof EE_Registration) { |
|
608 | + // nothing left? |
|
609 | + if ($available_payment_amount <= 0) { |
|
610 | + break; |
|
611 | + } |
|
612 | + if ($refund) { |
|
613 | + $available_payment_amount = $this->process_registration_refund( |
|
614 | + $registration, |
|
615 | + $payment, |
|
616 | + $available_payment_amount |
|
617 | + ); |
|
618 | + } else { |
|
619 | + $available_payment_amount = $this->process_registration_payment( |
|
620 | + $registration, |
|
621 | + $payment, |
|
622 | + $available_payment_amount |
|
623 | + ); |
|
624 | + } |
|
625 | + } |
|
626 | + } |
|
627 | + if ( |
|
628 | + $available_payment_amount > 0 |
|
629 | + && apply_filters( |
|
630 | + 'FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', |
|
631 | + false |
|
632 | + ) |
|
633 | + ) { |
|
634 | + EE_Error::add_attention( |
|
635 | + sprintf( |
|
636 | + esc_html__( |
|
637 | + 'A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
638 | + 'event_espresso' |
|
639 | + ), |
|
640 | + EEH_Template::format_currency($available_payment_amount), |
|
641 | + implode(', ', array_keys($registrations)), |
|
642 | + '<br/>', |
|
643 | + EEH_Template::format_currency($payment->amount()) |
|
644 | + ), |
|
645 | + __FILE__, |
|
646 | + __FUNCTION__, |
|
647 | + __LINE__ |
|
648 | + ); |
|
649 | + } |
|
650 | + } |
|
651 | + |
|
652 | + |
|
653 | + /** |
|
654 | + * update registration REG_paid field after successful payment and link registration with payment |
|
655 | + * |
|
656 | + * @param EE_Registration $registration |
|
657 | + * @param EE_Payment $payment |
|
658 | + * @param float $available_payment_amount |
|
659 | + * @return float |
|
660 | + * @throws EE_Error |
|
661 | + * @throws InvalidArgumentException |
|
662 | + * @throws RuntimeException |
|
663 | + * @throws InvalidDataTypeException |
|
664 | + * @throws InvalidInterfaceException |
|
665 | + */ |
|
666 | + public function process_registration_payment( |
|
667 | + EE_Registration $registration, |
|
668 | + EE_Payment $payment, |
|
669 | + $available_payment_amount = 0.00 |
|
670 | + ) { |
|
671 | + $owing = $registration->final_price() - $registration->paid(); |
|
672 | + if ($owing > 0) { |
|
673 | + // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
674 | + $payment_amount = min($available_payment_amount, $owing); |
|
675 | + // update $available_payment_amount |
|
676 | + $available_payment_amount -= $payment_amount; |
|
677 | + // calculate and set new REG_paid |
|
678 | + $registration->set_paid($registration->paid() + $payment_amount); |
|
679 | + // now save it |
|
680 | + $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
681 | + } |
|
682 | + return $available_payment_amount; |
|
683 | + } |
|
684 | + |
|
685 | + |
|
686 | + /** |
|
687 | + * update registration REG_paid field after successful payment and link registration with payment |
|
688 | + * |
|
689 | + * @param EE_Registration $registration |
|
690 | + * @param EE_Payment $payment |
|
691 | + * @param float $payment_amount |
|
692 | + * @return void |
|
693 | + * @throws EE_Error |
|
694 | + * @throws InvalidArgumentException |
|
695 | + * @throws InvalidDataTypeException |
|
696 | + * @throws InvalidInterfaceException |
|
697 | + */ |
|
698 | + protected function _apply_registration_payment( |
|
699 | + EE_Registration $registration, |
|
700 | + EE_Payment $payment, |
|
701 | + $payment_amount = 0.00 |
|
702 | + ) { |
|
703 | + // find any existing reg payment records for this registration and payment |
|
704 | + $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
705 | + array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
706 | + ); |
|
707 | + // if existing registration payment exists |
|
708 | + if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
709 | + // then update that record |
|
710 | + $existing_reg_payment->set_amount($payment_amount); |
|
711 | + $existing_reg_payment->save(); |
|
712 | + } else { |
|
713 | + // or add new relation between registration and payment and set amount |
|
714 | + $registration->_add_relation_to( |
|
715 | + $payment, |
|
716 | + 'Payment', |
|
717 | + array('RPY_amount' => $payment_amount) |
|
718 | + ); |
|
719 | + // make it stick |
|
720 | + $registration->save(); |
|
721 | + } |
|
722 | + } |
|
723 | + |
|
724 | + |
|
725 | + /** |
|
726 | + * update registration REG_paid field after refund and link registration with payment |
|
727 | + * |
|
728 | + * @param EE_Registration $registration |
|
729 | + * @param EE_Payment $payment |
|
730 | + * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
731 | + * @return float |
|
732 | + * @throws EE_Error |
|
733 | + * @throws InvalidArgumentException |
|
734 | + * @throws RuntimeException |
|
735 | + * @throws InvalidDataTypeException |
|
736 | + * @throws InvalidInterfaceException |
|
737 | + */ |
|
738 | + public function process_registration_refund( |
|
739 | + EE_Registration $registration, |
|
740 | + EE_Payment $payment, |
|
741 | + $available_refund_amount = 0.00 |
|
742 | + ) { |
|
743 | + // EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
744 | + if ($registration->paid() > 0) { |
|
745 | + // ensure $available_refund_amount is NOT negative |
|
746 | + $available_refund_amount = (float) abs($available_refund_amount); |
|
747 | + // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
748 | + $refund_amount = min($available_refund_amount, (float) $registration->paid()); |
|
749 | + // update $available_payment_amount |
|
750 | + $available_refund_amount -= $refund_amount; |
|
751 | + // calculate and set new REG_paid |
|
752 | + $registration->set_paid($registration->paid() - $refund_amount); |
|
753 | + // convert payment amount back to a negative value for storage in the db |
|
754 | + $refund_amount = (float) abs($refund_amount) * -1; |
|
755 | + // now save it |
|
756 | + $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
757 | + } |
|
758 | + return $available_refund_amount; |
|
759 | + } |
|
760 | + |
|
761 | + |
|
762 | + /** |
|
763 | + * Process payments and transaction after payment process completed. |
|
764 | + * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
765 | + * if this request happens to be processing an IPN, |
|
766 | + * then we will also set the Payment Options Reg Step to completed, |
|
767 | + * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
768 | + * |
|
769 | + * @param EE_Transaction $transaction |
|
770 | + * @param EE_Payment $payment |
|
771 | + * @param bool $IPN |
|
772 | + * @throws EE_Error |
|
773 | + * @throws InvalidArgumentException |
|
774 | + * @throws ReflectionException |
|
775 | + * @throws RuntimeException |
|
776 | + * @throws InvalidDataTypeException |
|
777 | + * @throws InvalidInterfaceException |
|
778 | + */ |
|
779 | + protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
780 | + { |
|
781 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
782 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
783 | + // is the Payment Options Reg Step completed ? |
|
784 | + $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
785 | + // if the Payment Options Reg Step is completed... |
|
786 | + $revisit = $payment_options_step_completed === true; |
|
787 | + // then this is kinda sorta a revisit with regards to payments at least |
|
788 | + $transaction_processor->set_revisit($revisit); |
|
789 | + // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
790 | + if ( |
|
791 | + $IPN |
|
792 | + && $payment_options_step_completed !== true |
|
793 | + && ($payment->is_approved() || $payment->is_pending()) |
|
794 | + ) { |
|
795 | + $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
796 | + 'payment_options' |
|
797 | + ); |
|
798 | + } |
|
799 | + // maybe update status, but don't save transaction just yet |
|
800 | + $transaction->update_status_based_on_total_paid(false); |
|
801 | + // check if 'finalize_registration' step has been completed... |
|
802 | + $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
803 | + // if this is an IPN and the final step has not been initiated |
|
804 | + if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
805 | + // and if it hasn't already been set as being started... |
|
806 | + $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
807 | + } |
|
808 | + $transaction->save(); |
|
809 | + // because the above will return false if the final step was not fully completed, we need to check again... |
|
810 | + if ($IPN && $finalized !== false) { |
|
811 | + // and if we are all good to go, then send out notifications |
|
812 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
813 | + // ok, now process the transaction according to the payment |
|
814 | + $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
815 | + $transaction, |
|
816 | + $payment |
|
817 | + ); |
|
818 | + } |
|
819 | + // DEBUG LOG |
|
820 | + $payment_method = $payment->payment_method(); |
|
821 | + if ($payment_method instanceof EE_Payment_Method) { |
|
822 | + $payment_method_type_obj = $payment_method->type_obj(); |
|
823 | + if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
824 | + $gateway = $payment_method_type_obj->get_gateway(); |
|
825 | + if ($gateway instanceof EE_Gateway) { |
|
826 | + $gateway->log( |
|
827 | + array( |
|
828 | + 'message' => (string) esc_html__('Post Payment Transaction Details', 'event_espresso'), |
|
829 | + 'transaction' => $transaction->model_field_array(), |
|
830 | + 'finalized' => $finalized, |
|
831 | + 'IPN' => $IPN, |
|
832 | + 'deliver_notifications' => has_filter( |
|
833 | + 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
834 | + ), |
|
835 | + ), |
|
836 | + $payment |
|
837 | + ); |
|
838 | + } |
|
839 | + } |
|
840 | + } |
|
841 | + } |
|
842 | + |
|
843 | + |
|
844 | + /** |
|
845 | + * Force posts to PayPal to use TLS v1.2. See: |
|
846 | + * https://core.trac.wordpress.org/ticket/36320 |
|
847 | + * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
848 | + * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
849 | + * This will affect PayPal standard, pro, express, and Payflow. |
|
850 | + * |
|
851 | + * @param $handle |
|
852 | + * @param $r |
|
853 | + * @param $url |
|
854 | + */ |
|
855 | + public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
856 | + { |
|
857 | + if (strpos($url, 'https://') !== false && strpos($url, '.paypal.com') !== false) { |
|
858 | + // Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
859 | + // instead of the constant because it might not be defined |
|
860 | + curl_setopt($handle, CURLOPT_SSLVERSION, 6); |
|
861 | + } |
|
862 | + } |
|
863 | 863 | } |
@@ -33,7 +33,7 @@ discard block |
||
33 | 33 | public static function instance() |
34 | 34 | { |
35 | 35 | // check if class object is instantiated |
36 | - if (! self::$_instance instanceof EE_Payment_Processor) { |
|
36 | + if ( ! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | 37 | self::$_instance = new self(); |
38 | 38 | } |
39 | 39 | return self::$_instance; |
@@ -170,7 +170,7 @@ discard block |
||
170 | 170 | /** @type \EE_Transaction $transaction */ |
171 | 171 | $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
172 | 172 | $primary_reg = $transaction->primary_registration(); |
173 | - if (! $primary_reg instanceof EE_Registration) { |
|
173 | + if ( ! $primary_reg instanceof EE_Registration) { |
|
174 | 174 | throw new EE_Error( |
175 | 175 | sprintf( |
176 | 176 | esc_html__( |
@@ -265,7 +265,7 @@ discard block |
||
265 | 265 | EEM_Change_Log::instance()->log( |
266 | 266 | EEM_Change_Log::type_gateway, |
267 | 267 | array( |
268 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
268 | + 'message' => 'IPN Exception: '.$e->getMessage(), |
|
269 | 269 | 'current_url' => EEH_URL::current_url(), |
270 | 270 | 'payment' => $e->getPaymentProperties(), |
271 | 271 | 'IPN_data' => $e->getIpnData(), |
@@ -309,7 +309,7 @@ discard block |
||
309 | 309 | EEM_Change_Log::instance()->log( |
310 | 310 | EEM_Change_Log::type_gateway, |
311 | 311 | array( |
312 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
312 | + 'message' => 'IPN Exception: '.$e->getMessage(), |
|
313 | 313 | 'current_url' => EEH_URL::current_url(), |
314 | 314 | 'payment' => $e->getPaymentProperties(), |
315 | 315 | 'IPN_data' => $e->getIpnData(), |
@@ -380,7 +380,7 @@ discard block |
||
380 | 380 | { |
381 | 381 | $return_data = array(); |
382 | 382 | foreach ($request_data as $key => $value) { |
383 | - $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
383 | + $return_data[$this->_remove_unusable_characters($key)] = $this->_remove_unusable_characters( |
|
384 | 384 | $value |
385 | 385 | ); |
386 | 386 | } |
@@ -26,784 +26,784 @@ |
||
26 | 26 | class Registry |
27 | 27 | { |
28 | 28 | |
29 | - const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json'; |
|
30 | - |
|
31 | - /** |
|
32 | - * @var AssetCollection $assets |
|
33 | - */ |
|
34 | - protected $assets; |
|
35 | - |
|
36 | - /** |
|
37 | - * @var I18nRegistry |
|
38 | - */ |
|
39 | - private $i18n_registry; |
|
40 | - |
|
41 | - /** |
|
42 | - * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script. |
|
43 | - * |
|
44 | - * @var array |
|
45 | - */ |
|
46 | - protected $jsdata = array(); |
|
47 | - |
|
48 | - /** |
|
49 | - * This keeps track of all scripts with registered data. It is used to prevent duplicate data objects setup in the |
|
50 | - * page source. |
|
51 | - * |
|
52 | - * @var array |
|
53 | - */ |
|
54 | - private $script_handles_with_data = array(); |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * Holds the manifest data obtained from registered manifest files. |
|
59 | - * Manifests are maps of asset chunk name to actual built asset file names. |
|
60 | - * Shape of this array is: |
|
61 | - * array( |
|
62 | - * 'some_namespace_slug' => array( |
|
63 | - * 'some_chunk_name' => array( |
|
64 | - * 'js' => 'filename.js' |
|
65 | - * 'css' => 'filename.js' |
|
66 | - * ), |
|
67 | - * 'url_base' => 'https://baseurl.com/to/assets |
|
68 | - * ) |
|
69 | - * ) |
|
70 | - * |
|
71 | - * @var array |
|
72 | - */ |
|
73 | - private $manifest_data = array(); |
|
74 | - |
|
75 | - |
|
76 | - /** |
|
77 | - * Holds any dependency data obtained from registered dependency map json. |
|
78 | - * Dependency map json is generated via the @wordpress/dependency-extraction-webpack-plugin via the webpack config. |
|
79 | - * @see https://github.com/WordPress/gutenberg/tree/master/packages/dependency-extraction-webpack-plugin |
|
80 | - * |
|
81 | - * @var array |
|
82 | - */ |
|
83 | - private $dependencies_data = []; |
|
84 | - |
|
85 | - |
|
86 | - /** |
|
87 | - * This is a known array of possible wp css handles that correspond to what may be exposed as dependencies in our |
|
88 | - * build process. Currently the dependency export process in webpack does not consider css imports, so we derive |
|
89 | - * them via the js dependencies (WP uses the same handle for both js and css). This is a list of known handles that |
|
90 | - * are used for both js and css. |
|
91 | - * @var array |
|
92 | - */ |
|
93 | - private $wp_css_handle_dependencies = [ |
|
94 | - 'wp-components', |
|
95 | - 'wp-block-editor', |
|
96 | - 'wp-block-library', |
|
97 | - 'wp-edit-post', |
|
98 | - 'wp-edit-widgets', |
|
99 | - 'wp-editor', |
|
100 | - 'wp-format-library', |
|
101 | - 'wp-list-reusable-blocks', |
|
102 | - 'wp-nux', |
|
103 | - ]; |
|
104 | - |
|
105 | - |
|
106 | - /** |
|
107 | - * Registry constructor. |
|
108 | - * Hooking into WP actions for script registry. |
|
109 | - * |
|
110 | - * @param AssetCollection $assets |
|
111 | - * @param I18nRegistry $i18n_registry |
|
112 | - * @throws InvalidArgumentException |
|
113 | - * @throws InvalidDataTypeException |
|
114 | - * @throws InvalidInterfaceException |
|
115 | - */ |
|
116 | - public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry) |
|
117 | - { |
|
118 | - $this->assets = $assets; |
|
119 | - $this->i18n_registry = $i18n_registry; |
|
120 | - add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
121 | - add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
122 | - add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
123 | - add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
124 | - add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
125 | - add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
126 | - add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
127 | - add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
128 | - } |
|
129 | - |
|
130 | - |
|
131 | - /** |
|
132 | - * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n |
|
133 | - * translation handling. |
|
134 | - * |
|
135 | - * @return I18nRegistry |
|
136 | - */ |
|
137 | - public function getI18nRegistry() |
|
138 | - { |
|
139 | - return $this->i18n_registry; |
|
140 | - } |
|
141 | - |
|
142 | - |
|
143 | - /** |
|
144 | - * Callback for the wp_enqueue_scripts actions used to register assets. |
|
145 | - * |
|
146 | - * @since 4.9.62.p |
|
147 | - * @throws Exception |
|
148 | - */ |
|
149 | - public function registerScriptsAndStyles() |
|
150 | - { |
|
151 | - try { |
|
152 | - $this->registerScripts($this->assets->getJavascriptAssets()); |
|
153 | - $this->registerStyles($this->assets->getStylesheetAssets()); |
|
154 | - } catch (Exception $exception) { |
|
155 | - new ExceptionStackTraceDisplay($exception); |
|
156 | - } |
|
157 | - } |
|
158 | - |
|
159 | - |
|
160 | - /** |
|
161 | - * Registers JS assets with WP core |
|
162 | - * |
|
163 | - * @param JavascriptAsset[] $scripts |
|
164 | - * @throws AssetRegistrationException |
|
165 | - * @throws InvalidDataTypeException |
|
166 | - * @throws DomainException |
|
167 | - * @since 4.9.62.p |
|
168 | - */ |
|
169 | - public function registerScripts(array $scripts) |
|
170 | - { |
|
171 | - foreach ($scripts as $script) { |
|
172 | - // skip to next script if this has already been done |
|
173 | - if ($script->isRegistered()) { |
|
174 | - continue; |
|
175 | - } |
|
176 | - do_action( |
|
177 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script', |
|
178 | - $script |
|
179 | - ); |
|
180 | - $registered = wp_register_script( |
|
181 | - $script->handle(), |
|
182 | - $script->source(), |
|
183 | - $script->dependencies(), |
|
184 | - $script->version(), |
|
185 | - $script->loadInFooter() |
|
186 | - ); |
|
187 | - if (! $registered && $this->debug()) { |
|
188 | - throw new AssetRegistrationException($script->handle()); |
|
189 | - } |
|
190 | - $script->setRegistered($registered); |
|
191 | - if ($script->requiresTranslation()) { |
|
192 | - $this->registerTranslation($script->handle()); |
|
193 | - } |
|
194 | - do_action( |
|
195 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script', |
|
196 | - $script |
|
197 | - ); |
|
198 | - } |
|
199 | - } |
|
200 | - |
|
201 | - |
|
202 | - /** |
|
203 | - * Registers CSS assets with WP core |
|
204 | - * |
|
205 | - * @param StylesheetAsset[] $styles |
|
206 | - * @throws InvalidDataTypeException |
|
207 | - * @throws DomainException |
|
208 | - * @since 4.9.62.p |
|
209 | - */ |
|
210 | - public function registerStyles(array $styles) |
|
211 | - { |
|
212 | - foreach ($styles as $style) { |
|
213 | - // skip to next style if this has already been done |
|
214 | - if ($style->isRegistered()) { |
|
215 | - continue; |
|
216 | - } |
|
217 | - do_action( |
|
218 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style', |
|
219 | - $style |
|
220 | - ); |
|
221 | - wp_register_style( |
|
222 | - $style->handle(), |
|
223 | - $style->source(), |
|
224 | - $style->dependencies(), |
|
225 | - $style->version(), |
|
226 | - $style->media() |
|
227 | - ); |
|
228 | - $style->setRegistered(); |
|
229 | - do_action( |
|
230 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style', |
|
231 | - $style |
|
232 | - ); |
|
233 | - } |
|
234 | - } |
|
235 | - |
|
236 | - |
|
237 | - /** |
|
238 | - * Call back for the script print in frontend and backend. |
|
239 | - * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point. |
|
240 | - * |
|
241 | - * @since 4.9.31.rc.015 |
|
242 | - */ |
|
243 | - public function enqueueData() |
|
244 | - { |
|
245 | - $this->removeAlreadyRegisteredDataForScriptHandles(); |
|
246 | - wp_add_inline_script( |
|
247 | - 'eejs-core', |
|
248 | - 'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)), |
|
249 | - 'before' |
|
250 | - ); |
|
251 | - $scripts = $this->assets->getJavascriptAssetsWithData(); |
|
252 | - foreach ($scripts as $script) { |
|
253 | - $this->addRegisteredScriptHandlesWithData($script->handle()); |
|
254 | - if ($script->hasInlineDataCallback()) { |
|
255 | - $localize = $script->inlineDataCallback(); |
|
256 | - $localize(); |
|
257 | - } |
|
258 | - } |
|
259 | - } |
|
260 | - |
|
261 | - |
|
262 | - /** |
|
263 | - * Used to add data to eejs.data object. |
|
264 | - * Note: Overriding existing data is not allowed. |
|
265 | - * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript. |
|
266 | - * If the data you add is something like this: |
|
267 | - * $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) ); |
|
268 | - * It will be exposed in the page source as: |
|
269 | - * eejs.data.my_plugin_data.foo == gar |
|
270 | - * |
|
271 | - * @param string $key Key used to access your data |
|
272 | - * @param string|array $value Value to attach to key |
|
273 | - * @throws InvalidArgumentException |
|
274 | - */ |
|
275 | - public function addData($key, $value) |
|
276 | - { |
|
277 | - if ($this->verifyDataNotExisting($key)) { |
|
278 | - $this->jsdata[ $key ] = $value; |
|
279 | - } |
|
280 | - } |
|
281 | - |
|
282 | - |
|
283 | - /** |
|
284 | - * Similar to addData except this allows for users to push values to an existing key where the values on key are |
|
285 | - * elements in an array. |
|
286 | - * |
|
287 | - * When you use this method, the value you include will be merged with the array on $key. |
|
288 | - * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript |
|
289 | - * object like this, eejs.data.test = [ my_data, |
|
290 | - * ] |
|
291 | - * If there has already been a scalar value attached to the data object given key (via addData for instance), then |
|
292 | - * this will throw an exception. |
|
293 | - * |
|
294 | - * Caution: Only add data using this method if you are okay with the potential for additional data added on the same |
|
295 | - * key potentially overriding the existing data on merge (specifically with associative arrays). |
|
296 | - * |
|
297 | - * @param string $key Key to attach data to. |
|
298 | - * @param string|array $value Value being registered. |
|
299 | - * @throws InvalidArgumentException |
|
300 | - */ |
|
301 | - public function pushData($key, $value) |
|
302 | - { |
|
303 | - if (isset($this->jsdata[ $key ]) |
|
304 | - && ! is_array($this->jsdata[ $key ]) |
|
305 | - ) { |
|
306 | - if (! $this->debug()) { |
|
307 | - return; |
|
308 | - } |
|
309 | - throw new InvalidArgumentException( |
|
310 | - sprintf( |
|
311 | - esc_html__( |
|
312 | - 'The value for %1$s is already set and it is not an array. The %2$s method can only be used to |
|
29 | + const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json'; |
|
30 | + |
|
31 | + /** |
|
32 | + * @var AssetCollection $assets |
|
33 | + */ |
|
34 | + protected $assets; |
|
35 | + |
|
36 | + /** |
|
37 | + * @var I18nRegistry |
|
38 | + */ |
|
39 | + private $i18n_registry; |
|
40 | + |
|
41 | + /** |
|
42 | + * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script. |
|
43 | + * |
|
44 | + * @var array |
|
45 | + */ |
|
46 | + protected $jsdata = array(); |
|
47 | + |
|
48 | + /** |
|
49 | + * This keeps track of all scripts with registered data. It is used to prevent duplicate data objects setup in the |
|
50 | + * page source. |
|
51 | + * |
|
52 | + * @var array |
|
53 | + */ |
|
54 | + private $script_handles_with_data = array(); |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * Holds the manifest data obtained from registered manifest files. |
|
59 | + * Manifests are maps of asset chunk name to actual built asset file names. |
|
60 | + * Shape of this array is: |
|
61 | + * array( |
|
62 | + * 'some_namespace_slug' => array( |
|
63 | + * 'some_chunk_name' => array( |
|
64 | + * 'js' => 'filename.js' |
|
65 | + * 'css' => 'filename.js' |
|
66 | + * ), |
|
67 | + * 'url_base' => 'https://baseurl.com/to/assets |
|
68 | + * ) |
|
69 | + * ) |
|
70 | + * |
|
71 | + * @var array |
|
72 | + */ |
|
73 | + private $manifest_data = array(); |
|
74 | + |
|
75 | + |
|
76 | + /** |
|
77 | + * Holds any dependency data obtained from registered dependency map json. |
|
78 | + * Dependency map json is generated via the @wordpress/dependency-extraction-webpack-plugin via the webpack config. |
|
79 | + * @see https://github.com/WordPress/gutenberg/tree/master/packages/dependency-extraction-webpack-plugin |
|
80 | + * |
|
81 | + * @var array |
|
82 | + */ |
|
83 | + private $dependencies_data = []; |
|
84 | + |
|
85 | + |
|
86 | + /** |
|
87 | + * This is a known array of possible wp css handles that correspond to what may be exposed as dependencies in our |
|
88 | + * build process. Currently the dependency export process in webpack does not consider css imports, so we derive |
|
89 | + * them via the js dependencies (WP uses the same handle for both js and css). This is a list of known handles that |
|
90 | + * are used for both js and css. |
|
91 | + * @var array |
|
92 | + */ |
|
93 | + private $wp_css_handle_dependencies = [ |
|
94 | + 'wp-components', |
|
95 | + 'wp-block-editor', |
|
96 | + 'wp-block-library', |
|
97 | + 'wp-edit-post', |
|
98 | + 'wp-edit-widgets', |
|
99 | + 'wp-editor', |
|
100 | + 'wp-format-library', |
|
101 | + 'wp-list-reusable-blocks', |
|
102 | + 'wp-nux', |
|
103 | + ]; |
|
104 | + |
|
105 | + |
|
106 | + /** |
|
107 | + * Registry constructor. |
|
108 | + * Hooking into WP actions for script registry. |
|
109 | + * |
|
110 | + * @param AssetCollection $assets |
|
111 | + * @param I18nRegistry $i18n_registry |
|
112 | + * @throws InvalidArgumentException |
|
113 | + * @throws InvalidDataTypeException |
|
114 | + * @throws InvalidInterfaceException |
|
115 | + */ |
|
116 | + public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry) |
|
117 | + { |
|
118 | + $this->assets = $assets; |
|
119 | + $this->i18n_registry = $i18n_registry; |
|
120 | + add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
121 | + add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1); |
|
122 | + add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
123 | + add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3); |
|
124 | + add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
125 | + add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4); |
|
126 | + add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
127 | + add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
128 | + } |
|
129 | + |
|
130 | + |
|
131 | + /** |
|
132 | + * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n |
|
133 | + * translation handling. |
|
134 | + * |
|
135 | + * @return I18nRegistry |
|
136 | + */ |
|
137 | + public function getI18nRegistry() |
|
138 | + { |
|
139 | + return $this->i18n_registry; |
|
140 | + } |
|
141 | + |
|
142 | + |
|
143 | + /** |
|
144 | + * Callback for the wp_enqueue_scripts actions used to register assets. |
|
145 | + * |
|
146 | + * @since 4.9.62.p |
|
147 | + * @throws Exception |
|
148 | + */ |
|
149 | + public function registerScriptsAndStyles() |
|
150 | + { |
|
151 | + try { |
|
152 | + $this->registerScripts($this->assets->getJavascriptAssets()); |
|
153 | + $this->registerStyles($this->assets->getStylesheetAssets()); |
|
154 | + } catch (Exception $exception) { |
|
155 | + new ExceptionStackTraceDisplay($exception); |
|
156 | + } |
|
157 | + } |
|
158 | + |
|
159 | + |
|
160 | + /** |
|
161 | + * Registers JS assets with WP core |
|
162 | + * |
|
163 | + * @param JavascriptAsset[] $scripts |
|
164 | + * @throws AssetRegistrationException |
|
165 | + * @throws InvalidDataTypeException |
|
166 | + * @throws DomainException |
|
167 | + * @since 4.9.62.p |
|
168 | + */ |
|
169 | + public function registerScripts(array $scripts) |
|
170 | + { |
|
171 | + foreach ($scripts as $script) { |
|
172 | + // skip to next script if this has already been done |
|
173 | + if ($script->isRegistered()) { |
|
174 | + continue; |
|
175 | + } |
|
176 | + do_action( |
|
177 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script', |
|
178 | + $script |
|
179 | + ); |
|
180 | + $registered = wp_register_script( |
|
181 | + $script->handle(), |
|
182 | + $script->source(), |
|
183 | + $script->dependencies(), |
|
184 | + $script->version(), |
|
185 | + $script->loadInFooter() |
|
186 | + ); |
|
187 | + if (! $registered && $this->debug()) { |
|
188 | + throw new AssetRegistrationException($script->handle()); |
|
189 | + } |
|
190 | + $script->setRegistered($registered); |
|
191 | + if ($script->requiresTranslation()) { |
|
192 | + $this->registerTranslation($script->handle()); |
|
193 | + } |
|
194 | + do_action( |
|
195 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script', |
|
196 | + $script |
|
197 | + ); |
|
198 | + } |
|
199 | + } |
|
200 | + |
|
201 | + |
|
202 | + /** |
|
203 | + * Registers CSS assets with WP core |
|
204 | + * |
|
205 | + * @param StylesheetAsset[] $styles |
|
206 | + * @throws InvalidDataTypeException |
|
207 | + * @throws DomainException |
|
208 | + * @since 4.9.62.p |
|
209 | + */ |
|
210 | + public function registerStyles(array $styles) |
|
211 | + { |
|
212 | + foreach ($styles as $style) { |
|
213 | + // skip to next style if this has already been done |
|
214 | + if ($style->isRegistered()) { |
|
215 | + continue; |
|
216 | + } |
|
217 | + do_action( |
|
218 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style', |
|
219 | + $style |
|
220 | + ); |
|
221 | + wp_register_style( |
|
222 | + $style->handle(), |
|
223 | + $style->source(), |
|
224 | + $style->dependencies(), |
|
225 | + $style->version(), |
|
226 | + $style->media() |
|
227 | + ); |
|
228 | + $style->setRegistered(); |
|
229 | + do_action( |
|
230 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style', |
|
231 | + $style |
|
232 | + ); |
|
233 | + } |
|
234 | + } |
|
235 | + |
|
236 | + |
|
237 | + /** |
|
238 | + * Call back for the script print in frontend and backend. |
|
239 | + * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point. |
|
240 | + * |
|
241 | + * @since 4.9.31.rc.015 |
|
242 | + */ |
|
243 | + public function enqueueData() |
|
244 | + { |
|
245 | + $this->removeAlreadyRegisteredDataForScriptHandles(); |
|
246 | + wp_add_inline_script( |
|
247 | + 'eejs-core', |
|
248 | + 'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)), |
|
249 | + 'before' |
|
250 | + ); |
|
251 | + $scripts = $this->assets->getJavascriptAssetsWithData(); |
|
252 | + foreach ($scripts as $script) { |
|
253 | + $this->addRegisteredScriptHandlesWithData($script->handle()); |
|
254 | + if ($script->hasInlineDataCallback()) { |
|
255 | + $localize = $script->inlineDataCallback(); |
|
256 | + $localize(); |
|
257 | + } |
|
258 | + } |
|
259 | + } |
|
260 | + |
|
261 | + |
|
262 | + /** |
|
263 | + * Used to add data to eejs.data object. |
|
264 | + * Note: Overriding existing data is not allowed. |
|
265 | + * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript. |
|
266 | + * If the data you add is something like this: |
|
267 | + * $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) ); |
|
268 | + * It will be exposed in the page source as: |
|
269 | + * eejs.data.my_plugin_data.foo == gar |
|
270 | + * |
|
271 | + * @param string $key Key used to access your data |
|
272 | + * @param string|array $value Value to attach to key |
|
273 | + * @throws InvalidArgumentException |
|
274 | + */ |
|
275 | + public function addData($key, $value) |
|
276 | + { |
|
277 | + if ($this->verifyDataNotExisting($key)) { |
|
278 | + $this->jsdata[ $key ] = $value; |
|
279 | + } |
|
280 | + } |
|
281 | + |
|
282 | + |
|
283 | + /** |
|
284 | + * Similar to addData except this allows for users to push values to an existing key where the values on key are |
|
285 | + * elements in an array. |
|
286 | + * |
|
287 | + * When you use this method, the value you include will be merged with the array on $key. |
|
288 | + * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript |
|
289 | + * object like this, eejs.data.test = [ my_data, |
|
290 | + * ] |
|
291 | + * If there has already been a scalar value attached to the data object given key (via addData for instance), then |
|
292 | + * this will throw an exception. |
|
293 | + * |
|
294 | + * Caution: Only add data using this method if you are okay with the potential for additional data added on the same |
|
295 | + * key potentially overriding the existing data on merge (specifically with associative arrays). |
|
296 | + * |
|
297 | + * @param string $key Key to attach data to. |
|
298 | + * @param string|array $value Value being registered. |
|
299 | + * @throws InvalidArgumentException |
|
300 | + */ |
|
301 | + public function pushData($key, $value) |
|
302 | + { |
|
303 | + if (isset($this->jsdata[ $key ]) |
|
304 | + && ! is_array($this->jsdata[ $key ]) |
|
305 | + ) { |
|
306 | + if (! $this->debug()) { |
|
307 | + return; |
|
308 | + } |
|
309 | + throw new InvalidArgumentException( |
|
310 | + sprintf( |
|
311 | + esc_html__( |
|
312 | + 'The value for %1$s is already set and it is not an array. The %2$s method can only be used to |
|
313 | 313 | push values to this data element when it is an array.', |
314 | - 'event_espresso' |
|
315 | - ), |
|
316 | - $key, |
|
317 | - __METHOD__ |
|
318 | - ) |
|
319 | - ); |
|
320 | - } |
|
321 | - if ( ! isset( $this->jsdata[ $key ] ) ) { |
|
322 | - $this->jsdata[ $key ] = is_array($value) ? $value : [$value]; |
|
323 | - } else { |
|
324 | - $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value); |
|
325 | - } |
|
326 | - } |
|
327 | - |
|
328 | - |
|
329 | - /** |
|
330 | - * Used to set content used by javascript for a template. |
|
331 | - * Note: Overrides of existing registered templates are not allowed. |
|
332 | - * |
|
333 | - * @param string $template_reference |
|
334 | - * @param string $template_content |
|
335 | - * @throws InvalidArgumentException |
|
336 | - */ |
|
337 | - public function addTemplate($template_reference, $template_content) |
|
338 | - { |
|
339 | - if (! isset($this->jsdata['templates'])) { |
|
340 | - $this->jsdata['templates'] = array(); |
|
341 | - } |
|
342 | - //no overrides allowed. |
|
343 | - if (isset($this->jsdata['templates'][ $template_reference ])) { |
|
344 | - if (! $this->debug()) { |
|
345 | - return; |
|
346 | - } |
|
347 | - throw new InvalidArgumentException( |
|
348 | - sprintf( |
|
349 | - esc_html__( |
|
350 | - 'The %1$s key already exists for the templates array in the js data array. No overrides are allowed.', |
|
351 | - 'event_espresso' |
|
352 | - ), |
|
353 | - $template_reference |
|
354 | - ) |
|
355 | - ); |
|
356 | - } |
|
357 | - $this->jsdata['templates'][ $template_reference ] = $template_content; |
|
358 | - } |
|
359 | - |
|
360 | - |
|
361 | - /** |
|
362 | - * Retrieve the template content already registered for the given reference. |
|
363 | - * |
|
364 | - * @param string $template_reference |
|
365 | - * @return string |
|
366 | - */ |
|
367 | - public function getTemplate($template_reference) |
|
368 | - { |
|
369 | - return isset($this->jsdata['templates'][ $template_reference ]) |
|
370 | - ? $this->jsdata['templates'][ $template_reference ] |
|
371 | - : ''; |
|
372 | - } |
|
373 | - |
|
374 | - |
|
375 | - /** |
|
376 | - * Retrieve registered data. |
|
377 | - * |
|
378 | - * @param string $key Name of key to attach data to. |
|
379 | - * @return mixed If there is no for the given key, then false is returned. |
|
380 | - */ |
|
381 | - public function getData($key) |
|
382 | - { |
|
383 | - return isset($this->jsdata[ $key ]) |
|
384 | - ? $this->jsdata[ $key ] |
|
385 | - : false; |
|
386 | - } |
|
387 | - |
|
388 | - |
|
389 | - /** |
|
390 | - * Verifies whether the given data exists already on the jsdata array. |
|
391 | - * Overriding data is not allowed. |
|
392 | - * |
|
393 | - * @param string $key Index for data. |
|
394 | - * @return bool If valid then return true. |
|
395 | - * @throws InvalidArgumentException if data already exists. |
|
396 | - */ |
|
397 | - protected function verifyDataNotExisting($key) |
|
398 | - { |
|
399 | - if (isset($this->jsdata[ $key ])) { |
|
400 | - if (! $this->debug()) { |
|
401 | - return false; |
|
402 | - } |
|
403 | - if (is_array($this->jsdata[ $key ])) { |
|
404 | - throw new InvalidArgumentException( |
|
405 | - sprintf( |
|
406 | - esc_html__( |
|
407 | - 'The value for %1$s already exists in the Registry::eejs object. |
|
314 | + 'event_espresso' |
|
315 | + ), |
|
316 | + $key, |
|
317 | + __METHOD__ |
|
318 | + ) |
|
319 | + ); |
|
320 | + } |
|
321 | + if ( ! isset( $this->jsdata[ $key ] ) ) { |
|
322 | + $this->jsdata[ $key ] = is_array($value) ? $value : [$value]; |
|
323 | + } else { |
|
324 | + $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value); |
|
325 | + } |
|
326 | + } |
|
327 | + |
|
328 | + |
|
329 | + /** |
|
330 | + * Used to set content used by javascript for a template. |
|
331 | + * Note: Overrides of existing registered templates are not allowed. |
|
332 | + * |
|
333 | + * @param string $template_reference |
|
334 | + * @param string $template_content |
|
335 | + * @throws InvalidArgumentException |
|
336 | + */ |
|
337 | + public function addTemplate($template_reference, $template_content) |
|
338 | + { |
|
339 | + if (! isset($this->jsdata['templates'])) { |
|
340 | + $this->jsdata['templates'] = array(); |
|
341 | + } |
|
342 | + //no overrides allowed. |
|
343 | + if (isset($this->jsdata['templates'][ $template_reference ])) { |
|
344 | + if (! $this->debug()) { |
|
345 | + return; |
|
346 | + } |
|
347 | + throw new InvalidArgumentException( |
|
348 | + sprintf( |
|
349 | + esc_html__( |
|
350 | + 'The %1$s key already exists for the templates array in the js data array. No overrides are allowed.', |
|
351 | + 'event_espresso' |
|
352 | + ), |
|
353 | + $template_reference |
|
354 | + ) |
|
355 | + ); |
|
356 | + } |
|
357 | + $this->jsdata['templates'][ $template_reference ] = $template_content; |
|
358 | + } |
|
359 | + |
|
360 | + |
|
361 | + /** |
|
362 | + * Retrieve the template content already registered for the given reference. |
|
363 | + * |
|
364 | + * @param string $template_reference |
|
365 | + * @return string |
|
366 | + */ |
|
367 | + public function getTemplate($template_reference) |
|
368 | + { |
|
369 | + return isset($this->jsdata['templates'][ $template_reference ]) |
|
370 | + ? $this->jsdata['templates'][ $template_reference ] |
|
371 | + : ''; |
|
372 | + } |
|
373 | + |
|
374 | + |
|
375 | + /** |
|
376 | + * Retrieve registered data. |
|
377 | + * |
|
378 | + * @param string $key Name of key to attach data to. |
|
379 | + * @return mixed If there is no for the given key, then false is returned. |
|
380 | + */ |
|
381 | + public function getData($key) |
|
382 | + { |
|
383 | + return isset($this->jsdata[ $key ]) |
|
384 | + ? $this->jsdata[ $key ] |
|
385 | + : false; |
|
386 | + } |
|
387 | + |
|
388 | + |
|
389 | + /** |
|
390 | + * Verifies whether the given data exists already on the jsdata array. |
|
391 | + * Overriding data is not allowed. |
|
392 | + * |
|
393 | + * @param string $key Index for data. |
|
394 | + * @return bool If valid then return true. |
|
395 | + * @throws InvalidArgumentException if data already exists. |
|
396 | + */ |
|
397 | + protected function verifyDataNotExisting($key) |
|
398 | + { |
|
399 | + if (isset($this->jsdata[ $key ])) { |
|
400 | + if (! $this->debug()) { |
|
401 | + return false; |
|
402 | + } |
|
403 | + if (is_array($this->jsdata[ $key ])) { |
|
404 | + throw new InvalidArgumentException( |
|
405 | + sprintf( |
|
406 | + esc_html__( |
|
407 | + 'The value for %1$s already exists in the Registry::eejs object. |
|
408 | 408 | Overrides are not allowed. Since the value of this data is an array, you may want to use the |
409 | 409 | %2$s method to push your value to the array.', |
410 | - 'event_espresso' |
|
411 | - ), |
|
412 | - $key, |
|
413 | - 'pushData()' |
|
414 | - ) |
|
415 | - ); |
|
416 | - } |
|
417 | - throw new InvalidArgumentException( |
|
418 | - sprintf( |
|
419 | - esc_html__( |
|
420 | - 'The value for %1$s already exists in the Registry::eejs object. Overrides are not |
|
410 | + 'event_espresso' |
|
411 | + ), |
|
412 | + $key, |
|
413 | + 'pushData()' |
|
414 | + ) |
|
415 | + ); |
|
416 | + } |
|
417 | + throw new InvalidArgumentException( |
|
418 | + sprintf( |
|
419 | + esc_html__( |
|
420 | + 'The value for %1$s already exists in the Registry::eejs object. Overrides are not |
|
421 | 421 | allowed. Consider attaching your value to a different key', |
422 | - 'event_espresso' |
|
423 | - ), |
|
424 | - $key |
|
425 | - ) |
|
426 | - ); |
|
427 | - } |
|
428 | - return true; |
|
429 | - } |
|
430 | - |
|
431 | - |
|
432 | - /** |
|
433 | - * Get the actual asset path for asset manifests. |
|
434 | - * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned. |
|
435 | - * |
|
436 | - * @param string $namespace The namespace associated with the manifest file hosting the map of chunk_name to actual |
|
437 | - * asset file location. |
|
438 | - * @param string $chunk_name |
|
439 | - * @param string $asset_type |
|
440 | - * @return string |
|
441 | - * @since 4.9.59.p |
|
442 | - */ |
|
443 | - public function getAssetUrl($namespace, $chunk_name, $asset_type) |
|
444 | - { |
|
445 | - $url = isset( |
|
446 | - $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ], |
|
447 | - $this->manifest_data[ $namespace ]['url_base'] |
|
448 | - ) |
|
449 | - ? $this->manifest_data[ $namespace ]['url_base'] |
|
450 | - . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ] |
|
451 | - : $chunk_name; |
|
452 | - |
|
453 | - return apply_filters( |
|
454 | - 'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl', |
|
455 | - $url, |
|
456 | - $namespace, |
|
457 | - $chunk_name, |
|
458 | - $asset_type |
|
459 | - ); |
|
460 | - } |
|
461 | - |
|
462 | - |
|
463 | - |
|
464 | - /** |
|
465 | - * Return the url to a js file for the given namespace and chunk name. |
|
466 | - * |
|
467 | - * @param string $namespace |
|
468 | - * @param string $chunk_name |
|
469 | - * @return string |
|
470 | - */ |
|
471 | - public function getJsUrl($namespace, $chunk_name) |
|
472 | - { |
|
473 | - return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS); |
|
474 | - } |
|
475 | - |
|
476 | - |
|
477 | - /** |
|
478 | - * Return the url to a css file for the given namespace and chunk name. |
|
479 | - * |
|
480 | - * @param string $namespace |
|
481 | - * @param string $chunk_name |
|
482 | - * @return string |
|
483 | - */ |
|
484 | - public function getCssUrl($namespace, $chunk_name) |
|
485 | - { |
|
486 | - return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS); |
|
487 | - } |
|
488 | - |
|
489 | - |
|
490 | - /** |
|
491 | - * Return the dependencies array and version string for a given asset $chunk_name |
|
492 | - * |
|
493 | - * @param string $namespace |
|
494 | - * @param string $chunk_name |
|
495 | - * @param string $asset_type |
|
496 | - * @return array |
|
497 | - * @since 4.9.82.p |
|
498 | - */ |
|
499 | - private function getDetailsForAsset($namespace, $chunk_name, $asset_type) |
|
500 | - { |
|
501 | - $asset_index = $chunk_name . '.' . $asset_type; |
|
502 | - if (! isset( $this->dependencies_data[ $namespace ][ $asset_index ])) { |
|
503 | - $path = isset($this->manifest_data[ $namespace ]['path']) |
|
504 | - ? $this->manifest_data[ $namespace ]['path'] |
|
505 | - : ''; |
|
506 | - $dependencies_index = $chunk_name . '.' . Asset::TYPE_PHP; |
|
507 | - $file_path = isset($this->manifest_data[ $namespace ][ $dependencies_index ]) |
|
508 | - ? $path . $this->manifest_data[ $namespace ][ $dependencies_index ] |
|
509 | - : |
|
510 | - ''; |
|
511 | - $this->dependencies_data[ $namespace ][ $asset_index ] = $file_path !== '' && file_exists($file_path) |
|
512 | - ? $this->getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name) |
|
513 | - : []; |
|
514 | - } |
|
515 | - $details = $this->dependencies_data[ $namespace ][ $asset_index ]; |
|
516 | - return $details; |
|
517 | - } |
|
518 | - |
|
519 | - |
|
520 | - /** |
|
521 | - * Return dependencies array and version string according to asset type. |
|
522 | - * For css assets, this filters the auto generated dependencies by css type. |
|
523 | - * |
|
524 | - * @param string $namespace |
|
525 | - * @param string $asset_type |
|
526 | - * @param string $file_path |
|
527 | - * @param string $chunk_name |
|
528 | - * @return array |
|
529 | - * @since 4.9.82.p |
|
530 | - */ |
|
531 | - private function getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name) |
|
532 | - { |
|
533 | - // $asset_dependencies = json_decode(file_get_contents($file_path), true); |
|
534 | - $asset_details = require($file_path); |
|
535 | - $asset_details['dependencies'] = isset($asset_details['dependencies']) |
|
536 | - ? $asset_details['dependencies'] |
|
537 | - : []; |
|
538 | - $asset_details['version'] = isset($asset_details['version']) |
|
539 | - ? $asset_details['version'] |
|
540 | - : ''; |
|
541 | - if ($asset_type === Asset::TYPE_JS) { |
|
542 | - $asset_details['dependencies'] = $chunk_name === 'eejs-core' |
|
543 | - ? $asset_details['dependencies'] |
|
544 | - : $asset_details['dependencies'] + [ CoreAssetManager::JS_HANDLE_JS_CORE ]; |
|
545 | - return $asset_details; |
|
546 | - } |
|
547 | - // for css we need to make sure there is actually a css file related to this chunk. |
|
548 | - if (isset($this->manifest_data[ $namespace ])) { |
|
549 | - // array of css chunk files for ee. |
|
550 | - $css_chunks = array_map( |
|
551 | - static function ($value) { |
|
552 | - return str_replace('.css', '', $value); |
|
553 | - }, |
|
554 | - array_filter( |
|
555 | - array_keys($this->manifest_data[ $namespace ]), |
|
556 | - static function ($value) { |
|
557 | - return strpos($value, '.css') !== false; |
|
558 | - } |
|
559 | - ) |
|
560 | - ); |
|
561 | - // add known wp chunks with css |
|
562 | - $css_chunks = array_merge( $css_chunks, $this->wp_css_handle_dependencies); |
|
563 | - // flip for easier search |
|
564 | - $css_chunks = array_flip($css_chunks); |
|
565 | - // now let's filter the dependencies for the incoming chunk to actual chunks that have styles |
|
566 | - $asset_details['dependencies'] = array_filter( |
|
567 | - $asset_details['dependencies'], |
|
568 | - static function ($chunk_name) use ($css_chunks) { |
|
569 | - return isset($css_chunks[ $chunk_name ]); |
|
570 | - } |
|
571 | - ); |
|
572 | - return $asset_details; |
|
573 | - } |
|
574 | - return ['dependencies' => [], 'version' => '']; |
|
575 | - } |
|
576 | - |
|
577 | - |
|
578 | - /** |
|
579 | - * Get the dependencies array and version string for the given js asset chunk name |
|
580 | - * |
|
581 | - * @param string $namespace |
|
582 | - * @param string $chunk_name |
|
583 | - * @return array |
|
584 | - * @since 4.10.2.p |
|
585 | - */ |
|
586 | - public function getJsAssetDetails($namespace, $chunk_name) |
|
587 | - { |
|
588 | - return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_JS); |
|
589 | - } |
|
590 | - |
|
591 | - |
|
592 | - /** |
|
593 | - * Get the dependencies array and version string for the given css asset chunk name |
|
594 | - * |
|
595 | - * @param string $namespace |
|
596 | - * @param string $chunk_name |
|
597 | - * @return array |
|
598 | - * @since 4.10.2.p |
|
599 | - */ |
|
600 | - public function getCssAssetDetails($namespace, $chunk_name) |
|
601 | - { |
|
602 | - return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_CSS); |
|
603 | - } |
|
604 | - |
|
605 | - |
|
606 | - /** |
|
607 | - * @since 4.9.62.p |
|
608 | - * @throws InvalidArgumentException |
|
609 | - * @throws InvalidFilePathException |
|
610 | - */ |
|
611 | - public function registerManifestFiles() |
|
612 | - { |
|
613 | - $manifest_files = $this->assets->getManifestFiles(); |
|
614 | - foreach ($manifest_files as $manifest_file) { |
|
615 | - $this->registerManifestFile( |
|
616 | - $manifest_file->assetNamespace(), |
|
617 | - $manifest_file->urlBase(), |
|
618 | - $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST, |
|
619 | - $manifest_file->filepath() |
|
620 | - ); |
|
621 | - } |
|
622 | - } |
|
623 | - |
|
624 | - |
|
625 | - /** |
|
626 | - * Used to register a js/css manifest file with the registered_manifest_files property. |
|
627 | - * |
|
628 | - * @param string $namespace Provided to associate the manifest file with a specific namespace. |
|
629 | - * @param string $url_base The url base for the manifest file location. |
|
630 | - * @param string $manifest_file The absolute path to the manifest file. |
|
631 | - * @param string $manifest_file_path The path to the folder containing the manifest file. If not provided will be |
|
632 | - * default to `plugin_root/assets/dist`. |
|
633 | - * @throws InvalidArgumentException |
|
634 | - * @throws InvalidFilePathException |
|
635 | - * @since 4.9.59.p |
|
636 | - */ |
|
637 | - public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '') |
|
638 | - { |
|
639 | - if (isset($this->manifest_data[ $namespace ])) { |
|
640 | - if (! $this->debug()) { |
|
641 | - return; |
|
642 | - } |
|
643 | - throw new InvalidArgumentException( |
|
644 | - sprintf( |
|
645 | - esc_html__( |
|
646 | - 'The namespace for this manifest file has already been registered, choose a namespace other than %s', |
|
647 | - 'event_espresso' |
|
648 | - ), |
|
649 | - $namespace |
|
650 | - ) |
|
651 | - ); |
|
652 | - } |
|
653 | - if (filter_var($url_base, FILTER_VALIDATE_URL) === false) { |
|
654 | - if (is_admin()) { |
|
655 | - EE_Error::add_error( |
|
656 | - sprintf( |
|
657 | - esc_html__( |
|
658 | - 'The url given for %1$s assets is invalid. The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant', |
|
659 | - 'event_espresso' |
|
660 | - ), |
|
661 | - 'Event Espresso', |
|
662 | - $url_base, |
|
663 | - 'plugins_url', |
|
664 | - 'WP_PLUGIN_URL' |
|
665 | - ), |
|
666 | - __FILE__, |
|
667 | - __FUNCTION__, |
|
668 | - __LINE__ |
|
669 | - ); |
|
670 | - } |
|
671 | - return; |
|
672 | - } |
|
673 | - $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file); |
|
674 | - if (! isset($this->manifest_data[ $namespace ]['url_base'])) { |
|
675 | - $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base); |
|
676 | - } |
|
677 | - if (! isset($this->manifest_data[ $namespace ]['path'])) { |
|
678 | - $this->manifest_data[ $namespace ]['path'] = $manifest_file_path; |
|
679 | - } |
|
680 | - } |
|
681 | - |
|
682 | - |
|
683 | - /** |
|
684 | - * Decodes json from the provided manifest file. |
|
685 | - * |
|
686 | - * @since 4.9.59.p |
|
687 | - * @param string $manifest_file Path to manifest file. |
|
688 | - * @return array |
|
689 | - * @throws InvalidFilePathException |
|
690 | - */ |
|
691 | - private function decodeManifestFile($manifest_file) |
|
692 | - { |
|
693 | - if (! file_exists($manifest_file)) { |
|
694 | - throw new InvalidFilePathException($manifest_file); |
|
695 | - } |
|
696 | - return json_decode(file_get_contents($manifest_file), true); |
|
697 | - } |
|
698 | - |
|
699 | - |
|
700 | - /** |
|
701 | - * This is used to set registered script handles that have data. |
|
702 | - * |
|
703 | - * @param string $script_handle |
|
704 | - */ |
|
705 | - private function addRegisteredScriptHandlesWithData($script_handle) |
|
706 | - { |
|
707 | - $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
708 | - } |
|
709 | - |
|
710 | - |
|
711 | - /**i |
|
422 | + 'event_espresso' |
|
423 | + ), |
|
424 | + $key |
|
425 | + ) |
|
426 | + ); |
|
427 | + } |
|
428 | + return true; |
|
429 | + } |
|
430 | + |
|
431 | + |
|
432 | + /** |
|
433 | + * Get the actual asset path for asset manifests. |
|
434 | + * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned. |
|
435 | + * |
|
436 | + * @param string $namespace The namespace associated with the manifest file hosting the map of chunk_name to actual |
|
437 | + * asset file location. |
|
438 | + * @param string $chunk_name |
|
439 | + * @param string $asset_type |
|
440 | + * @return string |
|
441 | + * @since 4.9.59.p |
|
442 | + */ |
|
443 | + public function getAssetUrl($namespace, $chunk_name, $asset_type) |
|
444 | + { |
|
445 | + $url = isset( |
|
446 | + $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ], |
|
447 | + $this->manifest_data[ $namespace ]['url_base'] |
|
448 | + ) |
|
449 | + ? $this->manifest_data[ $namespace ]['url_base'] |
|
450 | + . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ] |
|
451 | + : $chunk_name; |
|
452 | + |
|
453 | + return apply_filters( |
|
454 | + 'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl', |
|
455 | + $url, |
|
456 | + $namespace, |
|
457 | + $chunk_name, |
|
458 | + $asset_type |
|
459 | + ); |
|
460 | + } |
|
461 | + |
|
462 | + |
|
463 | + |
|
464 | + /** |
|
465 | + * Return the url to a js file for the given namespace and chunk name. |
|
466 | + * |
|
467 | + * @param string $namespace |
|
468 | + * @param string $chunk_name |
|
469 | + * @return string |
|
470 | + */ |
|
471 | + public function getJsUrl($namespace, $chunk_name) |
|
472 | + { |
|
473 | + return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS); |
|
474 | + } |
|
475 | + |
|
476 | + |
|
477 | + /** |
|
478 | + * Return the url to a css file for the given namespace and chunk name. |
|
479 | + * |
|
480 | + * @param string $namespace |
|
481 | + * @param string $chunk_name |
|
482 | + * @return string |
|
483 | + */ |
|
484 | + public function getCssUrl($namespace, $chunk_name) |
|
485 | + { |
|
486 | + return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS); |
|
487 | + } |
|
488 | + |
|
489 | + |
|
490 | + /** |
|
491 | + * Return the dependencies array and version string for a given asset $chunk_name |
|
492 | + * |
|
493 | + * @param string $namespace |
|
494 | + * @param string $chunk_name |
|
495 | + * @param string $asset_type |
|
496 | + * @return array |
|
497 | + * @since 4.9.82.p |
|
498 | + */ |
|
499 | + private function getDetailsForAsset($namespace, $chunk_name, $asset_type) |
|
500 | + { |
|
501 | + $asset_index = $chunk_name . '.' . $asset_type; |
|
502 | + if (! isset( $this->dependencies_data[ $namespace ][ $asset_index ])) { |
|
503 | + $path = isset($this->manifest_data[ $namespace ]['path']) |
|
504 | + ? $this->manifest_data[ $namespace ]['path'] |
|
505 | + : ''; |
|
506 | + $dependencies_index = $chunk_name . '.' . Asset::TYPE_PHP; |
|
507 | + $file_path = isset($this->manifest_data[ $namespace ][ $dependencies_index ]) |
|
508 | + ? $path . $this->manifest_data[ $namespace ][ $dependencies_index ] |
|
509 | + : |
|
510 | + ''; |
|
511 | + $this->dependencies_data[ $namespace ][ $asset_index ] = $file_path !== '' && file_exists($file_path) |
|
512 | + ? $this->getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name) |
|
513 | + : []; |
|
514 | + } |
|
515 | + $details = $this->dependencies_data[ $namespace ][ $asset_index ]; |
|
516 | + return $details; |
|
517 | + } |
|
518 | + |
|
519 | + |
|
520 | + /** |
|
521 | + * Return dependencies array and version string according to asset type. |
|
522 | + * For css assets, this filters the auto generated dependencies by css type. |
|
523 | + * |
|
524 | + * @param string $namespace |
|
525 | + * @param string $asset_type |
|
526 | + * @param string $file_path |
|
527 | + * @param string $chunk_name |
|
528 | + * @return array |
|
529 | + * @since 4.9.82.p |
|
530 | + */ |
|
531 | + private function getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name) |
|
532 | + { |
|
533 | + // $asset_dependencies = json_decode(file_get_contents($file_path), true); |
|
534 | + $asset_details = require($file_path); |
|
535 | + $asset_details['dependencies'] = isset($asset_details['dependencies']) |
|
536 | + ? $asset_details['dependencies'] |
|
537 | + : []; |
|
538 | + $asset_details['version'] = isset($asset_details['version']) |
|
539 | + ? $asset_details['version'] |
|
540 | + : ''; |
|
541 | + if ($asset_type === Asset::TYPE_JS) { |
|
542 | + $asset_details['dependencies'] = $chunk_name === 'eejs-core' |
|
543 | + ? $asset_details['dependencies'] |
|
544 | + : $asset_details['dependencies'] + [ CoreAssetManager::JS_HANDLE_JS_CORE ]; |
|
545 | + return $asset_details; |
|
546 | + } |
|
547 | + // for css we need to make sure there is actually a css file related to this chunk. |
|
548 | + if (isset($this->manifest_data[ $namespace ])) { |
|
549 | + // array of css chunk files for ee. |
|
550 | + $css_chunks = array_map( |
|
551 | + static function ($value) { |
|
552 | + return str_replace('.css', '', $value); |
|
553 | + }, |
|
554 | + array_filter( |
|
555 | + array_keys($this->manifest_data[ $namespace ]), |
|
556 | + static function ($value) { |
|
557 | + return strpos($value, '.css') !== false; |
|
558 | + } |
|
559 | + ) |
|
560 | + ); |
|
561 | + // add known wp chunks with css |
|
562 | + $css_chunks = array_merge( $css_chunks, $this->wp_css_handle_dependencies); |
|
563 | + // flip for easier search |
|
564 | + $css_chunks = array_flip($css_chunks); |
|
565 | + // now let's filter the dependencies for the incoming chunk to actual chunks that have styles |
|
566 | + $asset_details['dependencies'] = array_filter( |
|
567 | + $asset_details['dependencies'], |
|
568 | + static function ($chunk_name) use ($css_chunks) { |
|
569 | + return isset($css_chunks[ $chunk_name ]); |
|
570 | + } |
|
571 | + ); |
|
572 | + return $asset_details; |
|
573 | + } |
|
574 | + return ['dependencies' => [], 'version' => '']; |
|
575 | + } |
|
576 | + |
|
577 | + |
|
578 | + /** |
|
579 | + * Get the dependencies array and version string for the given js asset chunk name |
|
580 | + * |
|
581 | + * @param string $namespace |
|
582 | + * @param string $chunk_name |
|
583 | + * @return array |
|
584 | + * @since 4.10.2.p |
|
585 | + */ |
|
586 | + public function getJsAssetDetails($namespace, $chunk_name) |
|
587 | + { |
|
588 | + return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_JS); |
|
589 | + } |
|
590 | + |
|
591 | + |
|
592 | + /** |
|
593 | + * Get the dependencies array and version string for the given css asset chunk name |
|
594 | + * |
|
595 | + * @param string $namespace |
|
596 | + * @param string $chunk_name |
|
597 | + * @return array |
|
598 | + * @since 4.10.2.p |
|
599 | + */ |
|
600 | + public function getCssAssetDetails($namespace, $chunk_name) |
|
601 | + { |
|
602 | + return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_CSS); |
|
603 | + } |
|
604 | + |
|
605 | + |
|
606 | + /** |
|
607 | + * @since 4.9.62.p |
|
608 | + * @throws InvalidArgumentException |
|
609 | + * @throws InvalidFilePathException |
|
610 | + */ |
|
611 | + public function registerManifestFiles() |
|
612 | + { |
|
613 | + $manifest_files = $this->assets->getManifestFiles(); |
|
614 | + foreach ($manifest_files as $manifest_file) { |
|
615 | + $this->registerManifestFile( |
|
616 | + $manifest_file->assetNamespace(), |
|
617 | + $manifest_file->urlBase(), |
|
618 | + $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST, |
|
619 | + $manifest_file->filepath() |
|
620 | + ); |
|
621 | + } |
|
622 | + } |
|
623 | + |
|
624 | + |
|
625 | + /** |
|
626 | + * Used to register a js/css manifest file with the registered_manifest_files property. |
|
627 | + * |
|
628 | + * @param string $namespace Provided to associate the manifest file with a specific namespace. |
|
629 | + * @param string $url_base The url base for the manifest file location. |
|
630 | + * @param string $manifest_file The absolute path to the manifest file. |
|
631 | + * @param string $manifest_file_path The path to the folder containing the manifest file. If not provided will be |
|
632 | + * default to `plugin_root/assets/dist`. |
|
633 | + * @throws InvalidArgumentException |
|
634 | + * @throws InvalidFilePathException |
|
635 | + * @since 4.9.59.p |
|
636 | + */ |
|
637 | + public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '') |
|
638 | + { |
|
639 | + if (isset($this->manifest_data[ $namespace ])) { |
|
640 | + if (! $this->debug()) { |
|
641 | + return; |
|
642 | + } |
|
643 | + throw new InvalidArgumentException( |
|
644 | + sprintf( |
|
645 | + esc_html__( |
|
646 | + 'The namespace for this manifest file has already been registered, choose a namespace other than %s', |
|
647 | + 'event_espresso' |
|
648 | + ), |
|
649 | + $namespace |
|
650 | + ) |
|
651 | + ); |
|
652 | + } |
|
653 | + if (filter_var($url_base, FILTER_VALIDATE_URL) === false) { |
|
654 | + if (is_admin()) { |
|
655 | + EE_Error::add_error( |
|
656 | + sprintf( |
|
657 | + esc_html__( |
|
658 | + 'The url given for %1$s assets is invalid. The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant', |
|
659 | + 'event_espresso' |
|
660 | + ), |
|
661 | + 'Event Espresso', |
|
662 | + $url_base, |
|
663 | + 'plugins_url', |
|
664 | + 'WP_PLUGIN_URL' |
|
665 | + ), |
|
666 | + __FILE__, |
|
667 | + __FUNCTION__, |
|
668 | + __LINE__ |
|
669 | + ); |
|
670 | + } |
|
671 | + return; |
|
672 | + } |
|
673 | + $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file); |
|
674 | + if (! isset($this->manifest_data[ $namespace ]['url_base'])) { |
|
675 | + $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base); |
|
676 | + } |
|
677 | + if (! isset($this->manifest_data[ $namespace ]['path'])) { |
|
678 | + $this->manifest_data[ $namespace ]['path'] = $manifest_file_path; |
|
679 | + } |
|
680 | + } |
|
681 | + |
|
682 | + |
|
683 | + /** |
|
684 | + * Decodes json from the provided manifest file. |
|
685 | + * |
|
686 | + * @since 4.9.59.p |
|
687 | + * @param string $manifest_file Path to manifest file. |
|
688 | + * @return array |
|
689 | + * @throws InvalidFilePathException |
|
690 | + */ |
|
691 | + private function decodeManifestFile($manifest_file) |
|
692 | + { |
|
693 | + if (! file_exists($manifest_file)) { |
|
694 | + throw new InvalidFilePathException($manifest_file); |
|
695 | + } |
|
696 | + return json_decode(file_get_contents($manifest_file), true); |
|
697 | + } |
|
698 | + |
|
699 | + |
|
700 | + /** |
|
701 | + * This is used to set registered script handles that have data. |
|
702 | + * |
|
703 | + * @param string $script_handle |
|
704 | + */ |
|
705 | + private function addRegisteredScriptHandlesWithData($script_handle) |
|
706 | + { |
|
707 | + $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
708 | + } |
|
709 | + |
|
710 | + |
|
711 | + /**i |
|
712 | 712 | * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the |
713 | 713 | * Dependency stored in WP_Scripts if its set. |
714 | 714 | */ |
715 | - private function removeAlreadyRegisteredDataForScriptHandles() |
|
716 | - { |
|
717 | - if (empty($this->script_handles_with_data)) { |
|
718 | - return; |
|
719 | - } |
|
720 | - foreach ($this->script_handles_with_data as $script_handle) { |
|
721 | - $this->removeAlreadyRegisteredDataForScriptHandle($script_handle); |
|
722 | - } |
|
723 | - } |
|
724 | - |
|
725 | - |
|
726 | - /** |
|
727 | - * Removes any data dependency registered in WP_Scripts if its set. |
|
728 | - * |
|
729 | - * @param string $script_handle |
|
730 | - */ |
|
731 | - private function removeAlreadyRegisteredDataForScriptHandle($script_handle) |
|
732 | - { |
|
733 | - if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
734 | - global $wp_scripts; |
|
735 | - $unset_handle = false; |
|
736 | - if ($wp_scripts->get_data($script_handle, 'data')) { |
|
737 | - unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
738 | - $unset_handle = true; |
|
739 | - } |
|
740 | - //deal with inline_scripts |
|
741 | - if ($wp_scripts->get_data($script_handle, 'before')) { |
|
742 | - unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
743 | - $unset_handle = true; |
|
744 | - } |
|
745 | - if ($wp_scripts->get_data($script_handle, 'after')) { |
|
746 | - unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
747 | - } |
|
748 | - if ($unset_handle) { |
|
749 | - unset($this->script_handles_with_data[ $script_handle ]); |
|
750 | - } |
|
751 | - } |
|
752 | - } |
|
753 | - |
|
754 | - |
|
755 | - /** |
|
756 | - * register translations for a registered script |
|
757 | - * |
|
758 | - * @param string $handle |
|
759 | - */ |
|
760 | - public function registerTranslation($handle) |
|
761 | - { |
|
762 | - $this->i18n_registry->registerScriptI18n($handle); |
|
763 | - } |
|
764 | - |
|
765 | - |
|
766 | - /** |
|
767 | - * @since 4.9.63.p |
|
768 | - * @return bool |
|
769 | - */ |
|
770 | - private function debug() |
|
771 | - { |
|
772 | - return apply_filters( |
|
773 | - 'FHEE__EventEspresso_core_services_assets_Registry__debug', |
|
774 | - defined('EE_DEBUG') && EE_DEBUG |
|
775 | - ); |
|
776 | - } |
|
777 | - |
|
778 | - |
|
779 | - /** |
|
780 | - * Get the dependencies array for the given js asset chunk name |
|
781 | - * |
|
782 | - * @param string $namespace |
|
783 | - * @param string $chunk_name |
|
784 | - * @return array |
|
785 | - * @deprecated 4.10.2.p |
|
786 | - * @since 4.9.82.p |
|
787 | - */ |
|
788 | - public function getJsDependencies($namespace, $chunk_name) |
|
789 | - { |
|
790 | - $details = $this->getJsAssetDetails($namespace, $chunk_name); |
|
791 | - return isset($details['dependencies']) ? $details['dependencies'] : []; |
|
792 | - } |
|
793 | - |
|
794 | - |
|
795 | - /** |
|
796 | - * Get the dependencies array for the given css asset chunk name |
|
797 | - * |
|
798 | - * @param string $namespace |
|
799 | - * @param string $chunk_name |
|
800 | - * @return array |
|
801 | - * @deprecated 4.10.2.p |
|
802 | - * @since 4.9.82.p |
|
803 | - */ |
|
804 | - public function getCssDependencies($namespace, $chunk_name) |
|
805 | - { |
|
806 | - $details = $this->getCssAssetDetails($namespace, $chunk_name); |
|
807 | - return isset($details['dependencies']) ? $details['dependencies'] : []; |
|
808 | - } |
|
715 | + private function removeAlreadyRegisteredDataForScriptHandles() |
|
716 | + { |
|
717 | + if (empty($this->script_handles_with_data)) { |
|
718 | + return; |
|
719 | + } |
|
720 | + foreach ($this->script_handles_with_data as $script_handle) { |
|
721 | + $this->removeAlreadyRegisteredDataForScriptHandle($script_handle); |
|
722 | + } |
|
723 | + } |
|
724 | + |
|
725 | + |
|
726 | + /** |
|
727 | + * Removes any data dependency registered in WP_Scripts if its set. |
|
728 | + * |
|
729 | + * @param string $script_handle |
|
730 | + */ |
|
731 | + private function removeAlreadyRegisteredDataForScriptHandle($script_handle) |
|
732 | + { |
|
733 | + if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
734 | + global $wp_scripts; |
|
735 | + $unset_handle = false; |
|
736 | + if ($wp_scripts->get_data($script_handle, 'data')) { |
|
737 | + unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
738 | + $unset_handle = true; |
|
739 | + } |
|
740 | + //deal with inline_scripts |
|
741 | + if ($wp_scripts->get_data($script_handle, 'before')) { |
|
742 | + unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
743 | + $unset_handle = true; |
|
744 | + } |
|
745 | + if ($wp_scripts->get_data($script_handle, 'after')) { |
|
746 | + unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
747 | + } |
|
748 | + if ($unset_handle) { |
|
749 | + unset($this->script_handles_with_data[ $script_handle ]); |
|
750 | + } |
|
751 | + } |
|
752 | + } |
|
753 | + |
|
754 | + |
|
755 | + /** |
|
756 | + * register translations for a registered script |
|
757 | + * |
|
758 | + * @param string $handle |
|
759 | + */ |
|
760 | + public function registerTranslation($handle) |
|
761 | + { |
|
762 | + $this->i18n_registry->registerScriptI18n($handle); |
|
763 | + } |
|
764 | + |
|
765 | + |
|
766 | + /** |
|
767 | + * @since 4.9.63.p |
|
768 | + * @return bool |
|
769 | + */ |
|
770 | + private function debug() |
|
771 | + { |
|
772 | + return apply_filters( |
|
773 | + 'FHEE__EventEspresso_core_services_assets_Registry__debug', |
|
774 | + defined('EE_DEBUG') && EE_DEBUG |
|
775 | + ); |
|
776 | + } |
|
777 | + |
|
778 | + |
|
779 | + /** |
|
780 | + * Get the dependencies array for the given js asset chunk name |
|
781 | + * |
|
782 | + * @param string $namespace |
|
783 | + * @param string $chunk_name |
|
784 | + * @return array |
|
785 | + * @deprecated 4.10.2.p |
|
786 | + * @since 4.9.82.p |
|
787 | + */ |
|
788 | + public function getJsDependencies($namespace, $chunk_name) |
|
789 | + { |
|
790 | + $details = $this->getJsAssetDetails($namespace, $chunk_name); |
|
791 | + return isset($details['dependencies']) ? $details['dependencies'] : []; |
|
792 | + } |
|
793 | + |
|
794 | + |
|
795 | + /** |
|
796 | + * Get the dependencies array for the given css asset chunk name |
|
797 | + * |
|
798 | + * @param string $namespace |
|
799 | + * @param string $chunk_name |
|
800 | + * @return array |
|
801 | + * @deprecated 4.10.2.p |
|
802 | + * @since 4.9.82.p |
|
803 | + */ |
|
804 | + public function getCssDependencies($namespace, $chunk_name) |
|
805 | + { |
|
806 | + $details = $this->getCssAssetDetails($namespace, $chunk_name); |
|
807 | + return isset($details['dependencies']) ? $details['dependencies'] : []; |
|
808 | + } |
|
809 | 809 | } |
@@ -184,7 +184,7 @@ discard block |
||
184 | 184 | $script->version(), |
185 | 185 | $script->loadInFooter() |
186 | 186 | ); |
187 | - if (! $registered && $this->debug()) { |
|
187 | + if ( ! $registered && $this->debug()) { |
|
188 | 188 | throw new AssetRegistrationException($script->handle()); |
189 | 189 | } |
190 | 190 | $script->setRegistered($registered); |
@@ -245,7 +245,7 @@ discard block |
||
245 | 245 | $this->removeAlreadyRegisteredDataForScriptHandles(); |
246 | 246 | wp_add_inline_script( |
247 | 247 | 'eejs-core', |
248 | - 'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)), |
|
248 | + 'var eejsdata='.wp_json_encode(array('data' => $this->jsdata)), |
|
249 | 249 | 'before' |
250 | 250 | ); |
251 | 251 | $scripts = $this->assets->getJavascriptAssetsWithData(); |
@@ -275,7 +275,7 @@ discard block |
||
275 | 275 | public function addData($key, $value) |
276 | 276 | { |
277 | 277 | if ($this->verifyDataNotExisting($key)) { |
278 | - $this->jsdata[ $key ] = $value; |
|
278 | + $this->jsdata[$key] = $value; |
|
279 | 279 | } |
280 | 280 | } |
281 | 281 | |
@@ -300,10 +300,10 @@ discard block |
||
300 | 300 | */ |
301 | 301 | public function pushData($key, $value) |
302 | 302 | { |
303 | - if (isset($this->jsdata[ $key ]) |
|
304 | - && ! is_array($this->jsdata[ $key ]) |
|
303 | + if (isset($this->jsdata[$key]) |
|
304 | + && ! is_array($this->jsdata[$key]) |
|
305 | 305 | ) { |
306 | - if (! $this->debug()) { |
|
306 | + if ( ! $this->debug()) { |
|
307 | 307 | return; |
308 | 308 | } |
309 | 309 | throw new InvalidArgumentException( |
@@ -318,10 +318,10 @@ discard block |
||
318 | 318 | ) |
319 | 319 | ); |
320 | 320 | } |
321 | - if ( ! isset( $this->jsdata[ $key ] ) ) { |
|
322 | - $this->jsdata[ $key ] = is_array($value) ? $value : [$value]; |
|
321 | + if ( ! isset($this->jsdata[$key])) { |
|
322 | + $this->jsdata[$key] = is_array($value) ? $value : [$value]; |
|
323 | 323 | } else { |
324 | - $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value); |
|
324 | + $this->jsdata[$key] = array_merge($this->jsdata[$key], (array) $value); |
|
325 | 325 | } |
326 | 326 | } |
327 | 327 | |
@@ -336,12 +336,12 @@ discard block |
||
336 | 336 | */ |
337 | 337 | public function addTemplate($template_reference, $template_content) |
338 | 338 | { |
339 | - if (! isset($this->jsdata['templates'])) { |
|
339 | + if ( ! isset($this->jsdata['templates'])) { |
|
340 | 340 | $this->jsdata['templates'] = array(); |
341 | 341 | } |
342 | 342 | //no overrides allowed. |
343 | - if (isset($this->jsdata['templates'][ $template_reference ])) { |
|
344 | - if (! $this->debug()) { |
|
343 | + if (isset($this->jsdata['templates'][$template_reference])) { |
|
344 | + if ( ! $this->debug()) { |
|
345 | 345 | return; |
346 | 346 | } |
347 | 347 | throw new InvalidArgumentException( |
@@ -354,7 +354,7 @@ discard block |
||
354 | 354 | ) |
355 | 355 | ); |
356 | 356 | } |
357 | - $this->jsdata['templates'][ $template_reference ] = $template_content; |
|
357 | + $this->jsdata['templates'][$template_reference] = $template_content; |
|
358 | 358 | } |
359 | 359 | |
360 | 360 | |
@@ -366,8 +366,8 @@ discard block |
||
366 | 366 | */ |
367 | 367 | public function getTemplate($template_reference) |
368 | 368 | { |
369 | - return isset($this->jsdata['templates'][ $template_reference ]) |
|
370 | - ? $this->jsdata['templates'][ $template_reference ] |
|
369 | + return isset($this->jsdata['templates'][$template_reference]) |
|
370 | + ? $this->jsdata['templates'][$template_reference] |
|
371 | 371 | : ''; |
372 | 372 | } |
373 | 373 | |
@@ -380,8 +380,8 @@ discard block |
||
380 | 380 | */ |
381 | 381 | public function getData($key) |
382 | 382 | { |
383 | - return isset($this->jsdata[ $key ]) |
|
384 | - ? $this->jsdata[ $key ] |
|
383 | + return isset($this->jsdata[$key]) |
|
384 | + ? $this->jsdata[$key] |
|
385 | 385 | : false; |
386 | 386 | } |
387 | 387 | |
@@ -396,11 +396,11 @@ discard block |
||
396 | 396 | */ |
397 | 397 | protected function verifyDataNotExisting($key) |
398 | 398 | { |
399 | - if (isset($this->jsdata[ $key ])) { |
|
400 | - if (! $this->debug()) { |
|
399 | + if (isset($this->jsdata[$key])) { |
|
400 | + if ( ! $this->debug()) { |
|
401 | 401 | return false; |
402 | 402 | } |
403 | - if (is_array($this->jsdata[ $key ])) { |
|
403 | + if (is_array($this->jsdata[$key])) { |
|
404 | 404 | throw new InvalidArgumentException( |
405 | 405 | sprintf( |
406 | 406 | esc_html__( |
@@ -443,11 +443,11 @@ discard block |
||
443 | 443 | public function getAssetUrl($namespace, $chunk_name, $asset_type) |
444 | 444 | { |
445 | 445 | $url = isset( |
446 | - $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ], |
|
447 | - $this->manifest_data[ $namespace ]['url_base'] |
|
446 | + $this->manifest_data[$namespace][$chunk_name.'.'.$asset_type], |
|
447 | + $this->manifest_data[$namespace]['url_base'] |
|
448 | 448 | ) |
449 | - ? $this->manifest_data[ $namespace ]['url_base'] |
|
450 | - . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ] |
|
449 | + ? $this->manifest_data[$namespace]['url_base'] |
|
450 | + . $this->manifest_data[$namespace][$chunk_name.'.'.$asset_type] |
|
451 | 451 | : $chunk_name; |
452 | 452 | |
453 | 453 | return apply_filters( |
@@ -498,21 +498,21 @@ discard block |
||
498 | 498 | */ |
499 | 499 | private function getDetailsForAsset($namespace, $chunk_name, $asset_type) |
500 | 500 | { |
501 | - $asset_index = $chunk_name . '.' . $asset_type; |
|
502 | - if (! isset( $this->dependencies_data[ $namespace ][ $asset_index ])) { |
|
503 | - $path = isset($this->manifest_data[ $namespace ]['path']) |
|
504 | - ? $this->manifest_data[ $namespace ]['path'] |
|
501 | + $asset_index = $chunk_name.'.'.$asset_type; |
|
502 | + if ( ! isset($this->dependencies_data[$namespace][$asset_index])) { |
|
503 | + $path = isset($this->manifest_data[$namespace]['path']) |
|
504 | + ? $this->manifest_data[$namespace]['path'] |
|
505 | 505 | : ''; |
506 | - $dependencies_index = $chunk_name . '.' . Asset::TYPE_PHP; |
|
507 | - $file_path = isset($this->manifest_data[ $namespace ][ $dependencies_index ]) |
|
508 | - ? $path . $this->manifest_data[ $namespace ][ $dependencies_index ] |
|
506 | + $dependencies_index = $chunk_name.'.'.Asset::TYPE_PHP; |
|
507 | + $file_path = isset($this->manifest_data[$namespace][$dependencies_index]) |
|
508 | + ? $path.$this->manifest_data[$namespace][$dependencies_index] |
|
509 | 509 | : |
510 | 510 | ''; |
511 | - $this->dependencies_data[ $namespace ][ $asset_index ] = $file_path !== '' && file_exists($file_path) |
|
511 | + $this->dependencies_data[$namespace][$asset_index] = $file_path !== '' && file_exists($file_path) |
|
512 | 512 | ? $this->getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name) |
513 | 513 | : []; |
514 | 514 | } |
515 | - $details = $this->dependencies_data[ $namespace ][ $asset_index ]; |
|
515 | + $details = $this->dependencies_data[$namespace][$asset_index]; |
|
516 | 516 | return $details; |
517 | 517 | } |
518 | 518 | |
@@ -539,34 +539,34 @@ discard block |
||
539 | 539 | ? $asset_details['version'] |
540 | 540 | : ''; |
541 | 541 | if ($asset_type === Asset::TYPE_JS) { |
542 | - $asset_details['dependencies'] = $chunk_name === 'eejs-core' |
|
542 | + $asset_details['dependencies'] = $chunk_name === 'eejs-core' |
|
543 | 543 | ? $asset_details['dependencies'] |
544 | - : $asset_details['dependencies'] + [ CoreAssetManager::JS_HANDLE_JS_CORE ]; |
|
544 | + : $asset_details['dependencies'] + [CoreAssetManager::JS_HANDLE_JS_CORE]; |
|
545 | 545 | return $asset_details; |
546 | 546 | } |
547 | 547 | // for css we need to make sure there is actually a css file related to this chunk. |
548 | - if (isset($this->manifest_data[ $namespace ])) { |
|
548 | + if (isset($this->manifest_data[$namespace])) { |
|
549 | 549 | // array of css chunk files for ee. |
550 | 550 | $css_chunks = array_map( |
551 | - static function ($value) { |
|
551 | + static function($value) { |
|
552 | 552 | return str_replace('.css', '', $value); |
553 | 553 | }, |
554 | 554 | array_filter( |
555 | - array_keys($this->manifest_data[ $namespace ]), |
|
556 | - static function ($value) { |
|
555 | + array_keys($this->manifest_data[$namespace]), |
|
556 | + static function($value) { |
|
557 | 557 | return strpos($value, '.css') !== false; |
558 | 558 | } |
559 | 559 | ) |
560 | 560 | ); |
561 | 561 | // add known wp chunks with css |
562 | - $css_chunks = array_merge( $css_chunks, $this->wp_css_handle_dependencies); |
|
562 | + $css_chunks = array_merge($css_chunks, $this->wp_css_handle_dependencies); |
|
563 | 563 | // flip for easier search |
564 | 564 | $css_chunks = array_flip($css_chunks); |
565 | 565 | // now let's filter the dependencies for the incoming chunk to actual chunks that have styles |
566 | 566 | $asset_details['dependencies'] = array_filter( |
567 | 567 | $asset_details['dependencies'], |
568 | - static function ($chunk_name) use ($css_chunks) { |
|
569 | - return isset($css_chunks[ $chunk_name ]); |
|
568 | + static function($chunk_name) use ($css_chunks) { |
|
569 | + return isset($css_chunks[$chunk_name]); |
|
570 | 570 | } |
571 | 571 | ); |
572 | 572 | return $asset_details; |
@@ -615,7 +615,7 @@ discard block |
||
615 | 615 | $this->registerManifestFile( |
616 | 616 | $manifest_file->assetNamespace(), |
617 | 617 | $manifest_file->urlBase(), |
618 | - $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST, |
|
618 | + $manifest_file->filepath().Registry::FILE_NAME_BUILD_MANIFEST, |
|
619 | 619 | $manifest_file->filepath() |
620 | 620 | ); |
621 | 621 | } |
@@ -636,8 +636,8 @@ discard block |
||
636 | 636 | */ |
637 | 637 | public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '') |
638 | 638 | { |
639 | - if (isset($this->manifest_data[ $namespace ])) { |
|
640 | - if (! $this->debug()) { |
|
639 | + if (isset($this->manifest_data[$namespace])) { |
|
640 | + if ( ! $this->debug()) { |
|
641 | 641 | return; |
642 | 642 | } |
643 | 643 | throw new InvalidArgumentException( |
@@ -670,12 +670,12 @@ discard block |
||
670 | 670 | } |
671 | 671 | return; |
672 | 672 | } |
673 | - $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file); |
|
674 | - if (! isset($this->manifest_data[ $namespace ]['url_base'])) { |
|
675 | - $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base); |
|
673 | + $this->manifest_data[$namespace] = $this->decodeManifestFile($manifest_file); |
|
674 | + if ( ! isset($this->manifest_data[$namespace]['url_base'])) { |
|
675 | + $this->manifest_data[$namespace]['url_base'] = trailingslashit($url_base); |
|
676 | 676 | } |
677 | - if (! isset($this->manifest_data[ $namespace ]['path'])) { |
|
678 | - $this->manifest_data[ $namespace ]['path'] = $manifest_file_path; |
|
677 | + if ( ! isset($this->manifest_data[$namespace]['path'])) { |
|
678 | + $this->manifest_data[$namespace]['path'] = $manifest_file_path; |
|
679 | 679 | } |
680 | 680 | } |
681 | 681 | |
@@ -690,7 +690,7 @@ discard block |
||
690 | 690 | */ |
691 | 691 | private function decodeManifestFile($manifest_file) |
692 | 692 | { |
693 | - if (! file_exists($manifest_file)) { |
|
693 | + if ( ! file_exists($manifest_file)) { |
|
694 | 694 | throw new InvalidFilePathException($manifest_file); |
695 | 695 | } |
696 | 696 | return json_decode(file_get_contents($manifest_file), true); |
@@ -704,7 +704,7 @@ discard block |
||
704 | 704 | */ |
705 | 705 | private function addRegisteredScriptHandlesWithData($script_handle) |
706 | 706 | { |
707 | - $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
707 | + $this->script_handles_with_data[$script_handle] = $script_handle; |
|
708 | 708 | } |
709 | 709 | |
710 | 710 | |
@@ -730,23 +730,23 @@ discard block |
||
730 | 730 | */ |
731 | 731 | private function removeAlreadyRegisteredDataForScriptHandle($script_handle) |
732 | 732 | { |
733 | - if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
733 | + if (isset($this->script_handles_with_data[$script_handle])) { |
|
734 | 734 | global $wp_scripts; |
735 | 735 | $unset_handle = false; |
736 | 736 | if ($wp_scripts->get_data($script_handle, 'data')) { |
737 | - unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
737 | + unset($wp_scripts->registered[$script_handle]->extra['data']); |
|
738 | 738 | $unset_handle = true; |
739 | 739 | } |
740 | 740 | //deal with inline_scripts |
741 | 741 | if ($wp_scripts->get_data($script_handle, 'before')) { |
742 | - unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
742 | + unset($wp_scripts->registered[$script_handle]->extra['before']); |
|
743 | 743 | $unset_handle = true; |
744 | 744 | } |
745 | 745 | if ($wp_scripts->get_data($script_handle, 'after')) { |
746 | - unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
746 | + unset($wp_scripts->registered[$script_handle]->extra['after']); |
|
747 | 747 | } |
748 | 748 | if ($unset_handle) { |
749 | - unset($this->script_handles_with_data[ $script_handle ]); |
|
749 | + unset($this->script_handles_with_data[$script_handle]); |
|
750 | 750 | } |
751 | 751 | } |
752 | 752 | } |
@@ -16,25 +16,25 @@ |
||
16 | 16 | class CollectionLoaderException extends RuntimeException |
17 | 17 | { |
18 | 18 | |
19 | - /** |
|
20 | - * DuplicateCollectionIdentifierException constructor. |
|
21 | - * |
|
22 | - * @param Exception $previous |
|
23 | - * @param string $message |
|
24 | - * @param int $code |
|
25 | - */ |
|
26 | - public function __construct(Exception $previous, $message = '', $code = 0) |
|
27 | - { |
|
28 | - if (empty($message)) { |
|
29 | - $message = sprintf( |
|
30 | - esc_html__( |
|
31 | - 'The following error occurred during the creation and/or loading of this collection: %1$s %2$s', |
|
32 | - 'event_espresso' |
|
33 | - ), |
|
34 | - '<br />', |
|
35 | - $previous->getMessage() |
|
36 | - ); |
|
37 | - } |
|
38 | - parent::__construct($message, $code, $previous); |
|
39 | - } |
|
19 | + /** |
|
20 | + * DuplicateCollectionIdentifierException constructor. |
|
21 | + * |
|
22 | + * @param Exception $previous |
|
23 | + * @param string $message |
|
24 | + * @param int $code |
|
25 | + */ |
|
26 | + public function __construct(Exception $previous, $message = '', $code = 0) |
|
27 | + { |
|
28 | + if (empty($message)) { |
|
29 | + $message = sprintf( |
|
30 | + esc_html__( |
|
31 | + 'The following error occurred during the creation and/or loading of this collection: %1$s %2$s', |
|
32 | + 'event_espresso' |
|
33 | + ), |
|
34 | + '<br />', |
|
35 | + $previous->getMessage() |
|
36 | + ); |
|
37 | + } |
|
38 | + parent::__construct($message, $code, $previous); |
|
39 | + } |
|
40 | 40 | } |
@@ -16,26 +16,26 @@ |
||
16 | 16 | class InvalidCollectionIdentifierException extends OutOfBoundsException |
17 | 17 | { |
18 | 18 | |
19 | - /** |
|
20 | - * InvalidCollectionIdentifierException constructor. |
|
21 | - * |
|
22 | - * @param $identifier |
|
23 | - * @param string $message |
|
24 | - * @param int $code |
|
25 | - * @param Exception|null $previous |
|
26 | - */ |
|
27 | - public function __construct($identifier, $message = '', $code = 0, Exception $previous = null) |
|
28 | - { |
|
29 | - if (empty($message)) { |
|
30 | - $message = sprintf( |
|
31 | - esc_html__( |
|
32 | - 'The supplied identifier "%1$s" does not exist within this collection. |
|
19 | + /** |
|
20 | + * InvalidCollectionIdentifierException constructor. |
|
21 | + * |
|
22 | + * @param $identifier |
|
23 | + * @param string $message |
|
24 | + * @param int $code |
|
25 | + * @param Exception|null $previous |
|
26 | + */ |
|
27 | + public function __construct($identifier, $message = '', $code = 0, Exception $previous = null) |
|
28 | + { |
|
29 | + if (empty($message)) { |
|
30 | + $message = sprintf( |
|
31 | + esc_html__( |
|
32 | + 'The supplied identifier "%1$s" does not exist within this collection. |
|
33 | 33 | You may need to delay adding this asset until the required dependency has been added.', |
34 | - 'event_espresso' |
|
35 | - ), |
|
36 | - $identifier |
|
37 | - ); |
|
38 | - } |
|
39 | - parent::__construct($message, $code, $previous); |
|
40 | - } |
|
34 | + 'event_espresso' |
|
35 | + ), |
|
36 | + $identifier |
|
37 | + ); |
|
38 | + } |
|
39 | + parent::__construct($message, $code, $previous); |
|
40 | + } |
|
41 | 41 | } |
@@ -16,25 +16,25 @@ |
||
16 | 16 | class CollectionDetailsException extends RuntimeException |
17 | 17 | { |
18 | 18 | |
19 | - /** |
|
20 | - * DuplicateCollectionIdentifierException constructor. |
|
21 | - * |
|
22 | - * @param Exception $previous |
|
23 | - * @param string $message |
|
24 | - * @param int $code |
|
25 | - */ |
|
26 | - public function __construct(Exception $previous, $message = '', $code = 0) |
|
27 | - { |
|
28 | - if (empty($message)) { |
|
29 | - $message = sprintf( |
|
30 | - esc_html__( |
|
31 | - 'The following error occurred during the collection details generation: %1$s %2$s', |
|
32 | - 'event_espresso' |
|
33 | - ), |
|
34 | - '<br />', |
|
35 | - $previous->getMessage() |
|
36 | - ); |
|
37 | - } |
|
38 | - parent::__construct($message, $code, $previous); |
|
39 | - } |
|
19 | + /** |
|
20 | + * DuplicateCollectionIdentifierException constructor. |
|
21 | + * |
|
22 | + * @param Exception $previous |
|
23 | + * @param string $message |
|
24 | + * @param int $code |
|
25 | + */ |
|
26 | + public function __construct(Exception $previous, $message = '', $code = 0) |
|
27 | + { |
|
28 | + if (empty($message)) { |
|
29 | + $message = sprintf( |
|
30 | + esc_html__( |
|
31 | + 'The following error occurred during the collection details generation: %1$s %2$s', |
|
32 | + 'event_espresso' |
|
33 | + ), |
|
34 | + '<br />', |
|
35 | + $previous->getMessage() |
|
36 | + ); |
|
37 | + } |
|
38 | + parent::__construct($message, $code, $previous); |
|
39 | + } |
|
40 | 40 | } |
@@ -16,25 +16,25 @@ |
||
16 | 16 | class DuplicateCollectionIdentifierException extends OutOfRangeException |
17 | 17 | { |
18 | 18 | |
19 | - /** |
|
20 | - * DuplicateCollectionIdentifierException constructor. |
|
21 | - * |
|
22 | - * @param $identifier |
|
23 | - * @param string $message |
|
24 | - * @param int $code |
|
25 | - * @param Exception|null $previous |
|
26 | - */ |
|
27 | - public function __construct($identifier, $message = '', $code = 0, Exception $previous = null) |
|
28 | - { |
|
29 | - if (empty($message)) { |
|
30 | - $message = sprintf( |
|
31 | - esc_html__( |
|
32 | - 'The supplied identifier "%1$s" already exists within this collection.', |
|
33 | - 'event_espresso' |
|
34 | - ), |
|
35 | - $identifier |
|
36 | - ); |
|
37 | - } |
|
38 | - parent::__construct($message, $code, $previous); |
|
39 | - } |
|
19 | + /** |
|
20 | + * DuplicateCollectionIdentifierException constructor. |
|
21 | + * |
|
22 | + * @param $identifier |
|
23 | + * @param string $message |
|
24 | + * @param int $code |
|
25 | + * @param Exception|null $previous |
|
26 | + */ |
|
27 | + public function __construct($identifier, $message = '', $code = 0, Exception $previous = null) |
|
28 | + { |
|
29 | + if (empty($message)) { |
|
30 | + $message = sprintf( |
|
31 | + esc_html__( |
|
32 | + 'The supplied identifier "%1$s" already exists within this collection.', |
|
33 | + 'event_espresso' |
|
34 | + ), |
|
35 | + $identifier |
|
36 | + ); |
|
37 | + } |
|
38 | + parent::__construct($message, $code, $previous); |
|
39 | + } |
|
40 | 40 | } |
@@ -18,156 +18,156 @@ |
||
18 | 18 | abstract class CoffeeMaker implements CoffeeMakerInterface |
19 | 19 | { |
20 | 20 | |
21 | - /** |
|
22 | - * Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given) |
|
23 | - */ |
|
24 | - const BREW_NEW = 'new'; |
|
25 | - |
|
26 | - /** |
|
27 | - * Indicates that CoffeeMaker should always return a SHARED instance |
|
28 | - */ |
|
29 | - const BREW_SHARED = 'shared'; |
|
30 | - |
|
31 | - /** |
|
32 | - * Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate |
|
33 | - */ |
|
34 | - const BREW_LOAD_ONLY = 'load_only'; |
|
35 | - |
|
36 | - |
|
37 | - /** |
|
38 | - * @var CoffeePotInterface $coffee_pot |
|
39 | - */ |
|
40 | - private $coffee_pot; |
|
41 | - |
|
42 | - /** |
|
43 | - * @var DependencyInjector $injector |
|
44 | - */ |
|
45 | - private $injector; |
|
46 | - |
|
47 | - |
|
48 | - /** |
|
49 | - * @return array |
|
50 | - */ |
|
51 | - public static function getTypes() |
|
52 | - { |
|
53 | - return (array) apply_filters( |
|
54 | - 'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes', |
|
55 | - array( |
|
56 | - CoffeeMaker::BREW_NEW, |
|
57 | - CoffeeMaker::BREW_SHARED, |
|
58 | - CoffeeMaker::BREW_LOAD_ONLY, |
|
59 | - ) |
|
60 | - ); |
|
61 | - } |
|
62 | - |
|
63 | - |
|
64 | - /** |
|
65 | - * @param $type |
|
66 | - * @throws \EventEspresso\core\exceptions\InvalidIdentifierException |
|
67 | - */ |
|
68 | - public static function validateType($type) |
|
69 | - { |
|
70 | - $types = CoffeeMaker::getTypes(); |
|
71 | - if (! in_array($type, $types, true)) { |
|
72 | - throw new InvalidIdentifierException( |
|
73 | - is_object($type) ? get_class($type) : gettype($type), |
|
74 | - esc_html__( |
|
75 | - 'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)', |
|
76 | - 'event_espresso' |
|
77 | - ) |
|
78 | - ); |
|
79 | - } |
|
80 | - return $type; |
|
81 | - } |
|
82 | - |
|
83 | - |
|
84 | - /** |
|
85 | - * CoffeeMaker constructor. |
|
86 | - * |
|
87 | - * @param CoffeePotInterface $coffee_pot |
|
88 | - * @param InjectorInterface $injector |
|
89 | - */ |
|
90 | - public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector) |
|
91 | - { |
|
92 | - $this->coffee_pot = $coffee_pot; |
|
93 | - $this->injector = $injector; |
|
94 | - } |
|
95 | - |
|
96 | - |
|
97 | - /** |
|
98 | - * @return \EventEspresso\core\services\container\CoffeePotInterface |
|
99 | - */ |
|
100 | - protected function coffeePot() |
|
101 | - { |
|
102 | - return $this->coffee_pot; |
|
103 | - } |
|
104 | - |
|
105 | - |
|
106 | - /** |
|
107 | - * @return \EventEspresso\core\services\container\DependencyInjector |
|
108 | - */ |
|
109 | - protected function injector() |
|
110 | - { |
|
111 | - return $this->injector; |
|
112 | - } |
|
113 | - |
|
114 | - |
|
115 | - /** |
|
116 | - * Examines the constructor to determine which method should be used for instantiation |
|
117 | - * |
|
118 | - * @param \ReflectionClass $reflector |
|
119 | - * @return mixed |
|
120 | - * @throws InstantiationException |
|
121 | - */ |
|
122 | - protected function resolveInstantiationMethod(\ReflectionClass $reflector) |
|
123 | - { |
|
124 | - if ($reflector->getConstructor() === null) { |
|
125 | - return 'NewInstance'; |
|
126 | - } |
|
127 | - if ($reflector->isInstantiable()) { |
|
128 | - return 'NewInstanceArgs'; |
|
129 | - } |
|
130 | - if (method_exists($reflector->getName(), 'instance')) { |
|
131 | - return 'instance'; |
|
132 | - } |
|
133 | - if (method_exists($reflector->getName(), 'new_instance')) { |
|
134 | - return 'new_instance'; |
|
135 | - } |
|
136 | - if (method_exists($reflector->getName(), 'new_instance_from_db')) { |
|
137 | - return 'new_instance_from_db'; |
|
138 | - } |
|
139 | - throw new InstantiationException($reflector->getName()); |
|
140 | - } |
|
141 | - |
|
142 | - |
|
143 | - /** |
|
144 | - * Ensures files for classes that are not PSR-4 compatible are loaded |
|
145 | - * and then verifies that classes exist where applicable |
|
146 | - * |
|
147 | - * @param RecipeInterface $recipe |
|
148 | - * @return bool |
|
149 | - * @throws InvalidClassException |
|
150 | - */ |
|
151 | - protected function resolveClassAndFilepath(RecipeInterface $recipe) |
|
152 | - { |
|
153 | - $paths = $recipe->paths(); |
|
154 | - if (! empty($paths)) { |
|
155 | - foreach ($paths as $path) { |
|
156 | - if (strpos($path, '*') === false && is_readable($path)) { |
|
157 | - require_once($path); |
|
158 | - } |
|
159 | - } |
|
160 | - } |
|
161 | - // re: using "false" for class_exists() second param: |
|
162 | - // if a class name is not already known to PHP, then class_exists() will run through |
|
163 | - // all of the registered spl_autoload functions until it either finds the class, |
|
164 | - // or gets to the end of the registered spl_autoload functions. |
|
165 | - // When the second parameter is true, it will also attempt to load the class file, |
|
166 | - // but it will also trigger an error if the class can not be loaded. |
|
167 | - // We don't want that extra error in the mix, so we have set the second param to "false" |
|
168 | - if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) { |
|
169 | - throw new InvalidClassException($recipe->identifier()); |
|
170 | - } |
|
171 | - return true; |
|
172 | - } |
|
21 | + /** |
|
22 | + * Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given) |
|
23 | + */ |
|
24 | + const BREW_NEW = 'new'; |
|
25 | + |
|
26 | + /** |
|
27 | + * Indicates that CoffeeMaker should always return a SHARED instance |
|
28 | + */ |
|
29 | + const BREW_SHARED = 'shared'; |
|
30 | + |
|
31 | + /** |
|
32 | + * Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate |
|
33 | + */ |
|
34 | + const BREW_LOAD_ONLY = 'load_only'; |
|
35 | + |
|
36 | + |
|
37 | + /** |
|
38 | + * @var CoffeePotInterface $coffee_pot |
|
39 | + */ |
|
40 | + private $coffee_pot; |
|
41 | + |
|
42 | + /** |
|
43 | + * @var DependencyInjector $injector |
|
44 | + */ |
|
45 | + private $injector; |
|
46 | + |
|
47 | + |
|
48 | + /** |
|
49 | + * @return array |
|
50 | + */ |
|
51 | + public static function getTypes() |
|
52 | + { |
|
53 | + return (array) apply_filters( |
|
54 | + 'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes', |
|
55 | + array( |
|
56 | + CoffeeMaker::BREW_NEW, |
|
57 | + CoffeeMaker::BREW_SHARED, |
|
58 | + CoffeeMaker::BREW_LOAD_ONLY, |
|
59 | + ) |
|
60 | + ); |
|
61 | + } |
|
62 | + |
|
63 | + |
|
64 | + /** |
|
65 | + * @param $type |
|
66 | + * @throws \EventEspresso\core\exceptions\InvalidIdentifierException |
|
67 | + */ |
|
68 | + public static function validateType($type) |
|
69 | + { |
|
70 | + $types = CoffeeMaker::getTypes(); |
|
71 | + if (! in_array($type, $types, true)) { |
|
72 | + throw new InvalidIdentifierException( |
|
73 | + is_object($type) ? get_class($type) : gettype($type), |
|
74 | + esc_html__( |
|
75 | + 'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)', |
|
76 | + 'event_espresso' |
|
77 | + ) |
|
78 | + ); |
|
79 | + } |
|
80 | + return $type; |
|
81 | + } |
|
82 | + |
|
83 | + |
|
84 | + /** |
|
85 | + * CoffeeMaker constructor. |
|
86 | + * |
|
87 | + * @param CoffeePotInterface $coffee_pot |
|
88 | + * @param InjectorInterface $injector |
|
89 | + */ |
|
90 | + public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector) |
|
91 | + { |
|
92 | + $this->coffee_pot = $coffee_pot; |
|
93 | + $this->injector = $injector; |
|
94 | + } |
|
95 | + |
|
96 | + |
|
97 | + /** |
|
98 | + * @return \EventEspresso\core\services\container\CoffeePotInterface |
|
99 | + */ |
|
100 | + protected function coffeePot() |
|
101 | + { |
|
102 | + return $this->coffee_pot; |
|
103 | + } |
|
104 | + |
|
105 | + |
|
106 | + /** |
|
107 | + * @return \EventEspresso\core\services\container\DependencyInjector |
|
108 | + */ |
|
109 | + protected function injector() |
|
110 | + { |
|
111 | + return $this->injector; |
|
112 | + } |
|
113 | + |
|
114 | + |
|
115 | + /** |
|
116 | + * Examines the constructor to determine which method should be used for instantiation |
|
117 | + * |
|
118 | + * @param \ReflectionClass $reflector |
|
119 | + * @return mixed |
|
120 | + * @throws InstantiationException |
|
121 | + */ |
|
122 | + protected function resolveInstantiationMethod(\ReflectionClass $reflector) |
|
123 | + { |
|
124 | + if ($reflector->getConstructor() === null) { |
|
125 | + return 'NewInstance'; |
|
126 | + } |
|
127 | + if ($reflector->isInstantiable()) { |
|
128 | + return 'NewInstanceArgs'; |
|
129 | + } |
|
130 | + if (method_exists($reflector->getName(), 'instance')) { |
|
131 | + return 'instance'; |
|
132 | + } |
|
133 | + if (method_exists($reflector->getName(), 'new_instance')) { |
|
134 | + return 'new_instance'; |
|
135 | + } |
|
136 | + if (method_exists($reflector->getName(), 'new_instance_from_db')) { |
|
137 | + return 'new_instance_from_db'; |
|
138 | + } |
|
139 | + throw new InstantiationException($reflector->getName()); |
|
140 | + } |
|
141 | + |
|
142 | + |
|
143 | + /** |
|
144 | + * Ensures files for classes that are not PSR-4 compatible are loaded |
|
145 | + * and then verifies that classes exist where applicable |
|
146 | + * |
|
147 | + * @param RecipeInterface $recipe |
|
148 | + * @return bool |
|
149 | + * @throws InvalidClassException |
|
150 | + */ |
|
151 | + protected function resolveClassAndFilepath(RecipeInterface $recipe) |
|
152 | + { |
|
153 | + $paths = $recipe->paths(); |
|
154 | + if (! empty($paths)) { |
|
155 | + foreach ($paths as $path) { |
|
156 | + if (strpos($path, '*') === false && is_readable($path)) { |
|
157 | + require_once($path); |
|
158 | + } |
|
159 | + } |
|
160 | + } |
|
161 | + // re: using "false" for class_exists() second param: |
|
162 | + // if a class name is not already known to PHP, then class_exists() will run through |
|
163 | + // all of the registered spl_autoload functions until it either finds the class, |
|
164 | + // or gets to the end of the registered spl_autoload functions. |
|
165 | + // When the second parameter is true, it will also attempt to load the class file, |
|
166 | + // but it will also trigger an error if the class can not be loaded. |
|
167 | + // We don't want that extra error in the mix, so we have set the second param to "false" |
|
168 | + if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) { |
|
169 | + throw new InvalidClassException($recipe->identifier()); |
|
170 | + } |
|
171 | + return true; |
|
172 | + } |
|
173 | 173 | } |
@@ -68,7 +68,7 @@ discard block |
||
68 | 68 | public static function validateType($type) |
69 | 69 | { |
70 | 70 | $types = CoffeeMaker::getTypes(); |
71 | - if (! in_array($type, $types, true)) { |
|
71 | + if ( ! in_array($type, $types, true)) { |
|
72 | 72 | throw new InvalidIdentifierException( |
73 | 73 | is_object($type) ? get_class($type) : gettype($type), |
74 | 74 | esc_html__( |
@@ -151,7 +151,7 @@ discard block |
||
151 | 151 | protected function resolveClassAndFilepath(RecipeInterface $recipe) |
152 | 152 | { |
153 | 153 | $paths = $recipe->paths(); |
154 | - if (! empty($paths)) { |
|
154 | + if ( ! empty($paths)) { |
|
155 | 155 | foreach ($paths as $path) { |
156 | 156 | if (strpos($path, '*') === false && is_readable($path)) { |
157 | 157 | require_once($path); |