Completed
Branch fix-dummy-related-question-qst... (e5efcf)
by
unknown
07:49 queued 03:45
created
core/admin/EE_Admin_Hooks.core.php 2 patches
Spacing   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
         $this->_set_defaults();
227 227
         $this->_set_hooks_properties();
228 228
         // first let's verify we're on the right page
229
-        if (! isset($this->_req_data['page']) || $this->_req_data['page'] !== $this->_adminpage_obj->page_slug) {
229
+        if ( ! isset($this->_req_data['page']) || $this->_req_data['page'] !== $this->_adminpage_obj->page_slug) {
230 230
             return;
231 231
         }
232 232
         // get out nothing more to be done here.
@@ -274,9 +274,9 @@  discard block
 block discarded – undo
274 274
     public function enqueue_scripts_styles()
275 275
     {
276 276
 
277
-        if (! empty($this->_scripts_styles)) {
277
+        if ( ! empty($this->_scripts_styles)) {
278 278
             // first let's do all the registrations
279
-            if (! isset($this->_scripts_styles['registers'])) {
279
+            if ( ! isset($this->_scripts_styles['registers'])) {
280 280
                 $msg[] = esc_html__(
281 281
                     'There is no "registers" index in the <code>$this->_scripts_styles</code> property.',
282 282
                     'event_espresso'
@@ -286,7 +286,7 @@  discard block
 block discarded – undo
286 286
                         'Make sure you read the phpdoc comments above the definition of the $_scripts_styles property in the <code>EE_Admin_Hooks</code> class and modify according in the %s child',
287 287
                         'event_espresso'
288 288
                     ),
289
-                    '<strong>' . $this->caller . '</strong>'
289
+                    '<strong>'.$this->caller.'</strong>'
290 290
                 );
291 291
                 throw new EE_Error(implode('||', $msg));
292 292
             }
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
                 $footer  = $details['footer'];
307 307
                 // let's make sure that we set the 'registers' type if it's not set!
308 308
                 // We need it later to determine which enqueue we do
309
-                $this->_scripts_styles['registers'][ $ref ]['type'] = $type;
309
+                $this->_scripts_styles['registers'][$ref]['type'] = $type;
310 310
                 // let's make sure we're not missing any REQUIRED parameters
311 311
                 if (empty($url)) {
312 312
                     $msg[] = sprintf(
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
                             'Doublecheck your <code>$this->_scripts_styles</code> array in %s and make sure that there is a "url" set for the %s ref',
319 319
                             'event_espresso'
320 320
                         ),
321
-                        '<strong>' . $this->caller . '</strong>',
321
+                        '<strong>'.$this->caller.'</strong>',
322 322
                         $ref
323 323
                     );
324 324
                     throw new EE_Error(implode('||', $msg));
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
                     );
335 335
             }
336 336
             // k now let's do the enqueues
337
-            if (! isset($this->_scripts_styles['enqueues'])) {
337
+            if ( ! isset($this->_scripts_styles['enqueues'])) {
338 338
                 return;
339 339
             }  //not sure if we should throw an error here or not.
340 340
 
@@ -342,22 +342,22 @@  discard block
 block discarded – undo
342 342
                 // make sure $routes is an array
343 343
                 $routes = (array) $routes;
344 344
                 if (in_array($this->_current_route, $routes)) {
345
-                    $this->_scripts_styles['registers'][ $ref ]['type'] == 'js' ? wp_enqueue_script($ref)
345
+                    $this->_scripts_styles['registers'][$ref]['type'] == 'js' ? wp_enqueue_script($ref)
346 346
                         : wp_enqueue_style($ref);
347 347
                     // if we have a localization for the script let's do that too.
348
-                    if (isset($this->_scripts_styles['localize'][ $ref ])) {
349
-                        foreach ($this->_scripts_styles['localize'][ $ref ] as $object_name => $indexes) {
348
+                    if (isset($this->_scripts_styles['localize'][$ref])) {
349
+                        foreach ($this->_scripts_styles['localize'][$ref] as $object_name => $indexes) {
350 350
                             wp_localize_script(
351 351
                                 $ref,
352 352
                                 $object_name,
353
-                                $this->_scripts_styles['localize'][ $ref ][ $object_name ]
353
+                                $this->_scripts_styles['localize'][$ref][$object_name]
354 354
                             );
355 355
                         }
356 356
                     }
357 357
                 }
358 358
             }
359 359
             // let's do the deregisters
360
-            if (! isset($this->_scripts_styles['deregisters'])) {
360
+            if ( ! isset($this->_scripts_styles['deregisters'])) {
361 361
                 return;
362 362
             }
363 363
             foreach ($this->_scripts_styles['deregisters'] as $ref => $details) {
@@ -424,20 +424,20 @@  discard block
 block discarded – undo
424 424
         // change "the_message" to "the message"
425 425
         $class_name = str_replace('_', ' ', $this->_name);
426 426
         // change "the message" to "The_Message_Admin_Page"
427
-        $class_name = str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
427
+        $class_name = str_replace(' ', '_', ucwords($class_name)).'_Admin_Page';
428 428
         // first default file (if exists)
429
-        $decaf_file = EE_ADMIN_PAGES . $this->_name . '/' . $class_name . '.core.php';
429
+        $decaf_file = EE_ADMIN_PAGES.$this->_name.'/'.$class_name.'.core.php';
430 430
         if (is_readable($decaf_file)) {
431 431
             require_once($decaf_file);
432 432
         }
433 433
         // now we have to do require for extended file (if needed)
434 434
         if ($this->_extend) {
435
-            require_once(EE_CORE_CAF_ADMIN_EXTEND . $this->_name . '/Extend_' . $class_name . '.core.php');
435
+            require_once(EE_CORE_CAF_ADMIN_EXTEND.$this->_name.'/Extend_'.$class_name.'.core.php');
436 436
             // and extend the class name as well
437
-            $class_name = 'Extend_' . $class_name;
437
+            $class_name = 'Extend_'.$class_name;
438 438
         }
439 439
         // let's make sure the class exists
440
-        if (! class_exists($class_name)) {
440
+        if ( ! class_exists($class_name)) {
441 441
             $msg[] = esc_html__('We can\'t load the page object', 'event_espresso');
442 442
             $msg[] = sprintf(
443 443
                 esc_html__(
@@ -477,28 +477,28 @@  discard block
 block discarded – undo
477 477
         // first the actions
478 478
         // note that these action hooks will have the $query_args value available.
479 479
         $admin_class_name = get_class($this->_adminpage_obj);
480
-        if (method_exists($this, '_redirect_action_early_' . $this->_current_route)) {
480
+        if (method_exists($this, '_redirect_action_early_'.$this->_current_route)) {
481 481
             add_action(
482 482
                 'AHEE__'
483 483
                 . $admin_class_name
484 484
                 . '___redirect_after_action__before_redirect_modification_'
485 485
                 . $this->_current_route,
486
-                [$this, '_redirect_action_early_' . $this->_current_route],
486
+                [$this, '_redirect_action_early_'.$this->_current_route],
487 487
                 10
488 488
             );
489 489
         }
490
-        if (method_exists($this, '_redirect_action_' . $this->_current_route)) {
490
+        if (method_exists($this, '_redirect_action_'.$this->_current_route)) {
491 491
             add_action(
492
-                'AHEE_redirect_' . $admin_class_name . $this->_current_route,
493
-                [$this, '_redirect_action_' . $this->_current_route],
492
+                'AHEE_redirect_'.$admin_class_name.$this->_current_route,
493
+                [$this, '_redirect_action_'.$this->_current_route],
494 494
                 10
495 495
             );
496 496
         }
497 497
         // let's hook into the _redirect itself and allow for changing where the user goes after redirect.  This will have $query_args and $redirect_url available.
498
-        if (method_exists($this, '_redirect_filter_' . $this->_current_route)) {
498
+        if (method_exists($this, '_redirect_filter_'.$this->_current_route)) {
499 499
             add_filter(
500
-                'FHEE_redirect_' . $admin_class_name . $this->_current_route,
501
-                [$this, '_redirect_filter_' . $this->_current_route],
500
+                'FHEE_redirect_'.$admin_class_name.$this->_current_route,
501
+                [$this, '_redirect_filter_'.$this->_current_route],
502 502
                 10,
503 503
                 2
504 504
             );
@@ -523,12 +523,12 @@  discard block
 block discarded – undo
523 523
                 'argnum'   => 1,
524 524
                 'priority' => 10,
525 525
             ],
526
-            'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug . '_' . $this->_current_route => [
526
+            'FHEE_list_table_views_'.$this->_adminpage_obj->page_slug.'_'.$this->_current_route => [
527 527
                 'type'     => 'filter',
528 528
                 'argnum'   => 1,
529 529
                 'priority' => 10,
530 530
             ],
531
-            'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug                               => [
531
+            'FHEE_list_table_views_'.$this->_adminpage_obj->page_slug                               => [
532 532
                 'type'     => 'filter',
533 533
                 'argnum'   => 1,
534 534
                 'priority' => 10,
@@ -545,21 +545,21 @@  discard block
 block discarded – undo
545 545
             ],
546 546
         ];
547 547
         foreach ($hook_filter_array as $hook => $args) {
548
-            if (method_exists($this, $this->_current_route . '_' . $hook)) {
549
-                if (isset($this->_wp_action_filters_priority[ $hook ])) {
550
-                    $args['priority'] = $this->_wp_action_filters_priority[ $hook ];
548
+            if (method_exists($this, $this->_current_route.'_'.$hook)) {
549
+                if (isset($this->_wp_action_filters_priority[$hook])) {
550
+                    $args['priority'] = $this->_wp_action_filters_priority[$hook];
551 551
                 }
552 552
                 if ($args['type'] == 'action') {
553 553
                     add_action(
554 554
                         $hook,
555
-                        [$this, $this->_current_route . '_' . $hook],
555
+                        [$this, $this->_current_route.'_'.$hook],
556 556
                         $args['priority'],
557 557
                         $args['argnum']
558 558
                     );
559 559
                 } else {
560 560
                     add_filter(
561 561
                         $hook,
562
-                        [$this, $this->_current_route . '_' . $hook],
562
+                        [$this, $this->_current_route.'_'.$hook],
563 563
                         $args['priority'],
564 564
                         $args['argnum']
565 565
                     );
@@ -583,11 +583,11 @@  discard block
 block discarded – undo
583 583
         } //get out there's nothing to take care of.
584 584
         foreach ($this->_ajax_func as $action => $method) {
585 585
             // make sure method exists
586
-            if (! method_exists($this, $method)) {
586
+            if ( ! method_exists($this, $method)) {
587 587
                 $msg[] = esc_html__(
588 588
                     'There is no corresponding method for the hook labeled in the _ajax_func array',
589 589
                     'event_espresso'
590
-                ) . '<br />';
590
+                ).'<br />';
591 591
                 $msg[] = sprintf(
592 592
                     esc_html__(
593 593
                         'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
@@ -598,7 +598,7 @@  discard block
 block discarded – undo
598 598
                 );
599 599
                 throw new EE_Error(implode('||', $msg));
600 600
             }
601
-            add_action('wp_ajax_' . $action, [$this, $method]);
601
+            add_action('wp_ajax_'.$action, [$this, $method]);
602 602
         }
603 603
     }
604 604
 
@@ -618,11 +618,11 @@  discard block
 block discarded – undo
618 618
         // We need to determine what page_route we are on!
619 619
         foreach ($this->_init_func as $route => $method) {
620 620
             // make sure method exists
621
-            if (! method_exists($this, $method)) {
621
+            if ( ! method_exists($this, $method)) {
622 622
                 $msg[] = esc_html__(
623 623
                     'There is no corresponding method for the hook labeled in the _init_func array',
624 624
                     'event_espresso'
625
-                ) . '<br />';
625
+                ).'<br />';
626 626
                 $msg[] = sprintf(
627 627
                     esc_html__(
628 628
                         'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
@@ -665,7 +665,7 @@  discard block
 block discarded – undo
665 665
     {
666 666
 
667 667
         foreach ($boxes as $box) {
668
-            if (! isset($box['page_route'])) {
668
+            if ( ! isset($box['page_route'])) {
669 669
                 continue;
670 670
             }
671 671
             // we don't have a valid array
@@ -713,11 +713,11 @@  discard block
 block discarded – undo
713 713
         $screen_id      = is_object($current_screen) ? $current_screen->id : null;
714 714
         $func           = isset($args['func']) ? $args['func'] : 'some_invalid_callback';
715 715
         // set defaults
716
-        $defaults      = [
716
+        $defaults = [
717 717
             'callback_args' => [],
718 718
             'context'       => 'advanced',
719 719
             'func'          => $func,
720
-            'id'            => $this->caller . '_' . $func . '_metabox',
720
+            'id'            => $this->caller.'_'.$func.'_metabox',
721 721
             'label'         => $this->caller,
722 722
             'page'          => isset($args['page']) ? $args['page'] : $screen_id,
723 723
             'priority'      => 'default',
@@ -731,7 +731,7 @@  discard block
 block discarded – undo
731 731
         $page          = $args['page'];
732 732
         $priority      = $args['priority'];
733 733
         // make sure method exists
734
-        if (! method_exists($this, $func)) {
734
+        if ( ! method_exists($this, $func)) {
735 735
             $msg[] =
736 736
                 esc_html__('There is no corresponding method to display the metabox content', 'event_espresso')
737 737
                 . '<br />';
@@ -760,7 +760,7 @@  discard block
 block discarded – undo
760 760
             'context' => 'default',
761 761
             'id'      => isset($args['id'])
762 762
                 ? $args['id']
763
-                : $this->_current_route . '_' . $this->caller . '_' . $func . '_metabox',
763
+                : $this->_current_route.'_'.$this->caller.'_'.$func.'_metabox',
764 764
             'screen'  => isset($args['screen']) ? $args['screen'] : $screen_id,
765 765
         ];
766 766
         $args     = wp_parse_args($args, $defaults);
Please login to merge, or discard this patch.
Indentation   +754 added lines, -754 removed lines patch added patch discarded remove patch
@@ -14,758 +14,758 @@
 block discarded – undo
14 14
  */
15 15
 abstract class EE_Admin_Hooks extends EE_Base
16 16
 {
17
-    /**
18
-     * we're just going to use this to hold the name of the caller class (child class name)
19
-     *
20
-     * @var string
21
-     */
22
-    public $caller;
23
-
24
-
25
-    /**
26
-     * this is just a flag set automatically to indicate whether we've got an extended hook class running (i.e.
27
-     * espresso_events_Registration_Form_Hooks_Extend extends espresso_events_Registration_Form_Hooks).  This flag is
28
-     * used later to make sure we require the needed files.
29
-     *
30
-     * @var bool
31
-     */
32
-    protected $_extend;
33
-
34
-
35
-    /**
36
-     * child classes MUST set this property so that the page object can be loaded correctly
37
-     *
38
-     * @var string
39
-     */
40
-    protected $_name;
41
-
42
-
43
-    /**
44
-     * This is set by child classes and is an associative array of ajax hooks in the format:
45
-     * array(
46
-     *    'ajax_action_ref' => 'executing_method'; //must be public
47
-     * )
48
-     *
49
-     * @var array
50
-     */
51
-    protected $_ajax_func;
52
-
53
-
54
-    /**
55
-     * This is an array of methods that get executed on a page routes admin_init hook. Use the following format:
56
-     * array(
57
-     *    'page_route' => 'executing_method' //must be public
58
-     * )
59
-     *
60
-     * @var array
61
-     */
62
-    protected $_init_func;
63
-
64
-
65
-    /**
66
-     * This is an array of methods that output metabox content for the given page route.  Use the following format:
67
-     * [
68
-     *      0 => [
69
-     *          'page_route' => 'string_for_page_route',    must correspond to a page route in the class being connected
70
-     *                                                      with (i.e. "edit_event") If this is in an array then the
71
-     *                                                      same params below will be used but the metabox will be
72
-     *                                                      added to each route.
73
-     *          'func' =>  'executing_method',              must be public (i.e. public function executing_method
74
-     *                                                      ($post, $callback_args){} ).
75
-     *                                                      Note if you include callback args in the array then you
76
-     *                                                      need to declare them in the method arguments.
77
-     *          'id' => 'identifier_for_metabox',           so it can be removed by addons
78
-     *                                                      (optional, class will set it automatically)
79
-     *          'priority' => 'default',                    default 'default' (optional)
80
-     *          'label' => esc_html__('Localized Title', 'event_espresso'),
81
-     *          'context' => 'advanced'                     advanced is default (optional),
82
-     *      ]
83
-     *      'callback_args' => array() //any callback args to include (optional)
84
-     * ]
85
-     * Why are we indexing numerically?  Because it's possible there may be more than one metabox per page_route.
86
-     *
87
-     * @var array
88
-     */
89
-    protected $_metaboxes;
90
-
91
-
92
-    /**
93
-     * This is an array of values that indicate any metaboxes we want removed from a given page route.  Usually this is
94
-     * used when caffeinated functionality is replacing decaffeinated functionality.  Use the following format for the
95
-     * array: array(
96
-     *    0 => array(
97
-     *        'page_route' => 'string_for_page_route' //can be string or array of strings that match a page_route(s)
98
-     *        that are in the class being connected with (i.e. 'edit', or 'create_new').
99
-     *        'id' => 'identifier_for_metabox', //what the id is of the metabox being removed
100
-     *        'context' => 'normal', //the context for the metabox being removed (has to match)
101
-     *        'screen' => 'screen_id', //(optional), if not included then this class will attempt to remove the metabox
102
-     *        using the currently loaded screen object->id  however, there may be cases where you have to specify the
103
-     *        id for the screen the metabox is on.
104
-     *    )
105
-     * )
106
-     *
107
-     * @var array
108
-     */
109
-    protected $_remove_metaboxes;
110
-
111
-
112
-    /**
113
-     * This parent class takes care of loading the scripts and styles if the child class has set the properties for
114
-     * them in the following format.  Note, the first array index ('register') is for defining all the registers.  The
115
-     * second array index is for indicating what routes each script/style loads on. array(
116
-     * 'registers' => array(
117
-     *        'script_ref' => array( // if more than one script is to be loaded its best to use the 'dependency'
118
-     *        argument to link scripts together.
119
-     *            'type' => 'js' // 'js' or 'css' (defaults to js).  This tells us what type of wp_function to use
120
-     *            'url' => 'http://urltoscript.css.js',
121
-     *            'depends' => array('jquery'), //an array of dependencies for the scripts. REMEMBER, if a script has
122
-     *            already been registered elsewhere in the system.  You can just use the depends array to make sure it
123
-     *            gets loaded before the one you are setting here.
124
-     *            'footer' => TRUE //defaults to true (styles don't use this parameter)
125
-     *        ),
126
-     *    'enqueues' => array( //this time each key corresponds to the script ref followed by an array of page routes
127
-     *    the script gets enqueued on.
128
-     *        'script_ref' => array('route_one', 'route_two')
129
-     *    ),
130
-     *    'localize' => array( //this allows you to set a localized object.  Indicate which script the object is being
131
-     *    attached to and then include an array indexed by the name of the object and the array of key/value pairs for
132
-     *    the object.
133
-     *        'scrip_ref' => array(
134
-     *            'NAME_OF_JS_OBJECT' => array(
135
-     *                'translate_ref' => esc_html__('localized_string', 'event_espresso'),
136
-     *                'some_data' => 5
137
-     *            )
138
-     *        )
139
-     *    )
140
-     * )
141
-     *
142
-     * @var array
143
-     */
144
-    protected $_scripts_styles;
145
-
146
-
147
-    /**
148
-     * This is a property that will contain the current route.
149
-     *
150
-     * @var string;
151
-     */
152
-    protected $_current_route;
153
-
154
-
155
-    /**
156
-     * this optional property can be set by child classes to override the priority for the automatic action/filter hook
157
-     * loading in the `_load_routed_hooks()` method.  Please follow this format: array(
158
-     *    'wp_hook_reference' => 1
159
-     *    )
160
-     * )
161
-     *
162
-     * @var array
163
-     */
164
-    protected $_wp_action_filters_priority;
165
-
166
-
167
-    /**
168
-     * This just holds a merged array of the request vars
169
-     *
170
-     * @var array
171
-     */
172
-    protected $_req_data;
173
-
174
-    /**
175
-     * @var array
176
-     */
177
-    protected $_scripts;
178
-
179
-    /**
180
-     * @var array
181
-     */
182
-    protected $_styles;
183
-
184
-    /**
185
-     * This just holds an instance of the page object for this hook
186
-     *
187
-     * @var EE_Admin_Page
188
-     */
189
-    protected $_page_object;
190
-
191
-
192
-    /**
193
-     * This holds the EE_Admin_Page object from the calling admin page that this object hooks into.
194
-     *
195
-     * @var EE_Admin_Page|EE_Admin_Page_CPT
196
-     */
197
-    protected $_adminpage_obj;
198
-
199
-
200
-    /**
201
-     * Holds EE_Registry object
202
-     *
203
-     * @var EE_Registry
204
-     */
205
-    protected $EE = null;
206
-
207
-    /**
208
-     * @var RequestInterface
209
-     */
210
-    protected $request;
211
-
212
-
213
-    /**
214
-     * constructor
215
-     *
216
-     * @param EE_Admin_Page $admin_page
217
-     * @throws EE_Error
218
-     */
219
-    public function __construct(EE_Admin_Page $admin_page)
220
-    {
221
-        $this->_adminpage_obj = $admin_page;
222
-        $this->request        = LoaderFactory::getLoader()->getShared(RequestInterface::class);
223
-        $this->_req_data      = $this->request->requestParams();
224
-        $this->_set_defaults();
225
-        $this->_set_hooks_properties();
226
-        // first let's verify we're on the right page
227
-        if (! isset($this->_req_data['page']) || $this->_req_data['page'] !== $this->_adminpage_obj->page_slug) {
228
-            return;
229
-        }
230
-        // get out nothing more to be done here.
231
-        // allow for extends to modify properties
232
-        if (method_exists($this, '_extend_properties')) {
233
-            $this->_extend_properties();
234
-        }
235
-        $this->_set_page_object();
236
-        $this->_init_hooks();
237
-        $this->_load_custom_methods();
238
-        $this->_load_routed_hooks();
239
-        add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts_styles']);
240
-        add_action('admin_enqueue_scripts', [$this, 'add_metaboxes'], 20);
241
-        add_action('admin_enqueue_scripts', [$this, 'remove_metaboxes'], 15);
242
-        $this->_ajax_hooks();
243
-    }
244
-
245
-
246
-    /**
247
-     * used by child classes to set the following properties:
248
-     * $_ajax_func (optional)
249
-     * $_init_func (optional)
250
-     * $_metaboxes (optional)
251
-     * $_scripts (optional)
252
-     * $_styles (optional)
253
-     * $_name (required)
254
-     * Also in this method will be registered any scripts or styles loaded on the targeted page (as indicated in the
255
-     * _scripts/_styles properties) Also children should place in this method any filters/actions that have to happen
256
-     * really early on page load (just after admin_init) if they want to have them registered for handling early.
257
-     *
258
-     * @abstract
259
-     * @return void
260
-     */
261
-    abstract protected function _set_hooks_properties();
262
-
263
-
264
-    /**
265
-     * The hooks for enqueue_scripts and enqueue_styles will be run in here.  Child classes need to define their
266
-     * scripts and styles in the relevant $_scripts and $_styles properties.  Child classes must have also already
267
-     * registered the scripts and styles using wp_register_script and wp_register_style functions.
268
-     *
269
-     * @return void
270
-     * @throws EE_Error
271
-     */
272
-    public function enqueue_scripts_styles()
273
-    {
274
-
275
-        if (! empty($this->_scripts_styles)) {
276
-            // first let's do all the registrations
277
-            if (! isset($this->_scripts_styles['registers'])) {
278
-                $msg[] = esc_html__(
279
-                    'There is no "registers" index in the <code>$this->_scripts_styles</code> property.',
280
-                    'event_espresso'
281
-                );
282
-                $msg[] = sprintf(
283
-                    esc_html__(
284
-                        'Make sure you read the phpdoc comments above the definition of the $_scripts_styles property in the <code>EE_Admin_Hooks</code> class and modify according in the %s child',
285
-                        'event_espresso'
286
-                    ),
287
-                    '<strong>' . $this->caller . '</strong>'
288
-                );
289
-                throw new EE_Error(implode('||', $msg));
290
-            }
291
-            $defaults = [
292
-                'type'    => 'js',
293
-                'url'     => '',
294
-                'depends' => [],
295
-                'version' => EVENT_ESPRESSO_VERSION,
296
-                'footer'  => true,
297
-            ];
298
-            foreach ($this->_scripts_styles['registers'] as $ref => $details) {
299
-                $details = wp_parse_args($details, $defaults);
300
-                $type    = $details['type'];
301
-                $url     = $details['url'];
302
-                $depends = $details['depends'];
303
-                $version = $details['version'];
304
-                $footer  = $details['footer'];
305
-                // let's make sure that we set the 'registers' type if it's not set!
306
-                // We need it later to determine which enqueue we do
307
-                $this->_scripts_styles['registers'][ $ref ]['type'] = $type;
308
-                // let's make sure we're not missing any REQUIRED parameters
309
-                if (empty($url)) {
310
-                    $msg[] = sprintf(
311
-                        esc_html__('Missing the url for the requested %s', 'event_espresso'),
312
-                        $type == 'js' ? 'script' : 'stylesheet'
313
-                    );
314
-                    $msg[] = sprintf(
315
-                        esc_html__(
316
-                            'Doublecheck your <code>$this->_scripts_styles</code> array in %s and make sure that there is a "url" set for the %s ref',
317
-                            'event_espresso'
318
-                        ),
319
-                        '<strong>' . $this->caller . '</strong>',
320
-                        $ref
321
-                    );
322
-                    throw new EE_Error(implode('||', $msg));
323
-                }
324
-                // made it here so let's do the appropriate registration
325
-                $type == 'js'
326
-                    ? wp_register_script($ref, $url, $depends, $version, $footer)
327
-                    : wp_register_style(
328
-                        $ref,
329
-                        $url,
330
-                        $depends,
331
-                        $version
332
-                    );
333
-            }
334
-            // k now let's do the enqueues
335
-            if (! isset($this->_scripts_styles['enqueues'])) {
336
-                return;
337
-            }  //not sure if we should throw an error here or not.
338
-
339
-            foreach ($this->_scripts_styles['enqueues'] as $ref => $routes) {
340
-                // make sure $routes is an array
341
-                $routes = (array) $routes;
342
-                if (in_array($this->_current_route, $routes)) {
343
-                    $this->_scripts_styles['registers'][ $ref ]['type'] == 'js' ? wp_enqueue_script($ref)
344
-                        : wp_enqueue_style($ref);
345
-                    // if we have a localization for the script let's do that too.
346
-                    if (isset($this->_scripts_styles['localize'][ $ref ])) {
347
-                        foreach ($this->_scripts_styles['localize'][ $ref ] as $object_name => $indexes) {
348
-                            wp_localize_script(
349
-                                $ref,
350
-                                $object_name,
351
-                                $this->_scripts_styles['localize'][ $ref ][ $object_name ]
352
-                            );
353
-                        }
354
-                    }
355
-                }
356
-            }
357
-            // let's do the deregisters
358
-            if (! isset($this->_scripts_styles['deregisters'])) {
359
-                return;
360
-            }
361
-            foreach ($this->_scripts_styles['deregisters'] as $ref => $details) {
362
-                $defaults = ['type' => 'js'];
363
-                $details  = wp_parse_args($details, $defaults);
364
-                $details['type'] === 'js' ? wp_deregister_script($ref) : wp_deregister_style($ref);
365
-            }
366
-        }
367
-    }
368
-
369
-
370
-    /**
371
-     * just set the defaults for the hooks properties.
372
-     *
373
-     * @return void
374
-     */
375
-    private function _set_defaults()
376
-    {
377
-        $this->_ajax_func                  = [];
378
-        $this->_init_func                  = [];
379
-        $this->_metaboxes                  = [];
380
-        $this->_scripts                    = [];
381
-        $this->_styles                     = [];
382
-        $this->_wp_action_filters_priority = [];
383
-        $this->_current_route              = $this->getCurrentRoute();
384
-        $this->caller                      = get_class($this);
385
-        $this->_extend                     = (bool) stripos($this->caller, 'Extend');
386
-    }
387
-
388
-
389
-    /**
390
-     * A helper for determining the current route.
391
-     *
392
-     * @return string
393
-     */
394
-    private function getCurrentRoute()
395
-    {
396
-        $action = $this->request->getRequestParam('action');
397
-        // list tables do something else with 'action' for bulk actions.
398
-        $action = $action !== '-1' && $action !== '' ? $action : 'default';
399
-        $route  = $this->request->getRequestParam('route');
400
-        // we set a 'route' variable in some cases where action is being used by something else.
401
-        return $action === 'default' && $route !== '' ? $route : $action;
402
-    }
403
-
404
-
405
-    /**
406
-     * this sets the _page_object property
407
-     *
408
-     * @return void
409
-     * @throws EE_Error
410
-     */
411
-    protected function _set_page_object()
412
-    {
413
-        // first make sure $this->_name is set
414
-        if (empty($this->_name)) {
415
-            $msg[] = esc_html__('We can\'t load the page object', 'event_espresso');
416
-            $msg[] = sprintf(
417
-                esc_html__("This is because the %s child class has not set the '_name' property", 'event_espresso'),
418
-                $this->caller
419
-            );
420
-            throw new EE_Error(implode('||', $msg));
421
-        }
422
-        // change "the_message" to "the message"
423
-        $class_name = str_replace('_', ' ', $this->_name);
424
-        // change "the message" to "The_Message_Admin_Page"
425
-        $class_name = str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
426
-        // first default file (if exists)
427
-        $decaf_file = EE_ADMIN_PAGES . $this->_name . '/' . $class_name . '.core.php';
428
-        if (is_readable($decaf_file)) {
429
-            require_once($decaf_file);
430
-        }
431
-        // now we have to do require for extended file (if needed)
432
-        if ($this->_extend) {
433
-            require_once(EE_CORE_CAF_ADMIN_EXTEND . $this->_name . '/Extend_' . $class_name . '.core.php');
434
-            // and extend the class name as well
435
-            $class_name = 'Extend_' . $class_name;
436
-        }
437
-        // let's make sure the class exists
438
-        if (! class_exists($class_name)) {
439
-            $msg[] = esc_html__('We can\'t load the page object', 'event_espresso');
440
-            $msg[] = sprintf(
441
-                esc_html__(
442
-                    'The class name that was given is %s. Check the spelling and make sure its correct, also there needs to be an autoloader setup for the class',
443
-                    'event_espresso'
444
-                ),
445
-                $class_name
446
-            );
447
-            throw new EE_Error(implode('||', $msg));
448
-        }
449
-        $this->_page_object = LoaderFactory::getLoader()->getShared($class_name, [false]);
450
-    }
451
-
452
-
453
-    /**
454
-     * Child "hook" classes can declare any methods that they want executed when a specific page route is loaded.  The
455
-     * advantage of this is when doing things like running our own db interactions on saves etc.  Remember that
456
-     * $this->_req_data (all the _POST and _GET data) is available to your methods.
457
-     *
458
-     * @return void
459
-     */
460
-    private function _load_custom_methods()
461
-    {
462
-        /**
463
-         * method cannot be named 'default' (@see http://us3.php
464
-         * .net/manual/en/reserved.keywords.php) so need to
465
-         * handle routes that are "default"
466
-         *
467
-         * @since 4.3.0
468
-         */
469
-        $method_callback = $this->_current_route == 'default' ? 'default_callback' : $this->_current_route;
470
-        // these run before the Admin_Page route executes.
471
-        if (method_exists($this, $method_callback)) {
472
-            call_user_func([$this, $method_callback]);
473
-        }
474
-        // these run via the _redirect_after_action method in EE_Admin_Page which usually happens after non_UI methods in EE_Admin_Page classes.  There are two redirect actions, the first fires before $query_args might be manipulated by "save and close" actions and the seond fires right before the actual redirect happens.
475
-        // first the actions
476
-        // note that these action hooks will have the $query_args value available.
477
-        $admin_class_name = get_class($this->_adminpage_obj);
478
-        if (method_exists($this, '_redirect_action_early_' . $this->_current_route)) {
479
-            add_action(
480
-                'AHEE__'
481
-                . $admin_class_name
482
-                . '___redirect_after_action__before_redirect_modification_'
483
-                . $this->_current_route,
484
-                [$this, '_redirect_action_early_' . $this->_current_route],
485
-                10
486
-            );
487
-        }
488
-        if (method_exists($this, '_redirect_action_' . $this->_current_route)) {
489
-            add_action(
490
-                'AHEE_redirect_' . $admin_class_name . $this->_current_route,
491
-                [$this, '_redirect_action_' . $this->_current_route],
492
-                10
493
-            );
494
-        }
495
-        // let's hook into the _redirect itself and allow for changing where the user goes after redirect.  This will have $query_args and $redirect_url available.
496
-        if (method_exists($this, '_redirect_filter_' . $this->_current_route)) {
497
-            add_filter(
498
-                'FHEE_redirect_' . $admin_class_name . $this->_current_route,
499
-                [$this, '_redirect_filter_' . $this->_current_route],
500
-                10,
501
-                2
502
-            );
503
-        }
504
-    }
505
-
506
-
507
-    /**
508
-     * This method will search for a corresponding method with a name matching the route and the wp_hook to run.  This
509
-     * allows child hook classes to target hooking into a specific wp action or filter hook ONLY on a certain route.
510
-     * just remember, methods MUST be public Future hooks should be added in here to be access by child classes.
511
-     *
512
-     * @return void
513
-     */
514
-    private function _load_routed_hooks()
515
-    {
516
-
517
-        // this array provides the hook action names that will be referenced.  Key is the action. Value is an array with the type (action or filter) and the number of parameters for the hook.  We'll default all priorities for automatic hooks to 10.
518
-        $hook_filter_array = [
519
-            'admin_footer'                                                                            => [
520
-                'type'     => 'action',
521
-                'argnum'   => 1,
522
-                'priority' => 10,
523
-            ],
524
-            'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug . '_' . $this->_current_route => [
525
-                'type'     => 'filter',
526
-                'argnum'   => 1,
527
-                'priority' => 10,
528
-            ],
529
-            'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug                               => [
530
-                'type'     => 'filter',
531
-                'argnum'   => 1,
532
-                'priority' => 10,
533
-            ],
534
-            'FHEE_list_table_views'                                                                   => [
535
-                'type'     => 'filter',
536
-                'argnum'   => 1,
537
-                'priority' => 10,
538
-            ],
539
-            'AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes'                              => [
540
-                'type'     => 'action',
541
-                'argnum'   => 1,
542
-                'priority' => 10,
543
-            ],
544
-        ];
545
-        foreach ($hook_filter_array as $hook => $args) {
546
-            if (method_exists($this, $this->_current_route . '_' . $hook)) {
547
-                if (isset($this->_wp_action_filters_priority[ $hook ])) {
548
-                    $args['priority'] = $this->_wp_action_filters_priority[ $hook ];
549
-                }
550
-                if ($args['type'] == 'action') {
551
-                    add_action(
552
-                        $hook,
553
-                        [$this, $this->_current_route . '_' . $hook],
554
-                        $args['priority'],
555
-                        $args['argnum']
556
-                    );
557
-                } else {
558
-                    add_filter(
559
-                        $hook,
560
-                        [$this, $this->_current_route . '_' . $hook],
561
-                        $args['priority'],
562
-                        $args['argnum']
563
-                    );
564
-                }
565
-            }
566
-        }
567
-    }
568
-
569
-
570
-    /**
571
-     * Loop throught the $_ajax_func array and add_actions for the array.
572
-     *
573
-     * @return void
574
-     * @throws EE_Error
575
-     */
576
-    private function _ajax_hooks()
577
-    {
578
-
579
-        if (empty($this->_ajax_func)) {
580
-            return;
581
-        } //get out there's nothing to take care of.
582
-        foreach ($this->_ajax_func as $action => $method) {
583
-            // make sure method exists
584
-            if (! method_exists($this, $method)) {
585
-                $msg[] = esc_html__(
586
-                    'There is no corresponding method for the hook labeled in the _ajax_func array',
587
-                    'event_espresso'
588
-                ) . '<br />';
589
-                $msg[] = sprintf(
590
-                    esc_html__(
591
-                        'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
592
-                        'event_espresso'
593
-                    ),
594
-                    $method,
595
-                    $this->caller
596
-                );
597
-                throw new EE_Error(implode('||', $msg));
598
-            }
599
-            add_action('wp_ajax_' . $action, [$this, $method]);
600
-        }
601
-    }
602
-
603
-
604
-    /**
605
-     * Loop throught the $_init_func array and add_actions for the array.
606
-     *
607
-     * @return void
608
-     * @throws EE_Error
609
-     */
610
-    protected function _init_hooks()
611
-    {
612
-        if (empty($this->_init_func)) {
613
-            return;
614
-        }
615
-        // get out there's nothing to take care of.
616
-        // We need to determine what page_route we are on!
617
-        foreach ($this->_init_func as $route => $method) {
618
-            // make sure method exists
619
-            if (! method_exists($this, $method)) {
620
-                $msg[] = esc_html__(
621
-                    'There is no corresponding method for the hook labeled in the _init_func array',
622
-                    'event_espresso'
623
-                ) . '<br />';
624
-                $msg[] = sprintf(
625
-                    esc_html__(
626
-                        'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
627
-                        'event_espresso'
628
-                    ),
629
-                    $method,
630
-                    $this->caller
631
-                );
632
-                throw new EE_Error(implode('||', $msg));
633
-            }
634
-            if ($route == $this->_current_route) {
635
-                add_action('admin_init', [$this, $method]);
636
-            }
637
-        }
638
-    }
639
-
640
-
641
-    /**
642
-     * Loop through the _metaboxes property and add_metaboxes accordingly
643
-     * //todo we could eventually make this a config component class (i.e. new EE_Metabox);
644
-     *
645
-     * @return void
646
-     * @throws EE_Error
647
-     */
648
-    public function add_metaboxes()
649
-    {
650
-        if (empty($this->_metaboxes)) {
651
-            return;
652
-        } //get out we don't have any metaboxes to set for this connection
653
-        $this->_handle_metabox_array($this->_metaboxes);
654
-    }
655
-
656
-
657
-    /**
658
-     * @param array $boxes
659
-     * @param bool  $add
660
-     * @throws EE_Error
661
-     */
662
-    private function _handle_metabox_array(array $boxes, $add = true)
663
-    {
664
-
665
-        foreach ($boxes as $box) {
666
-            if (! isset($box['page_route'])) {
667
-                continue;
668
-            }
669
-            // we don't have a valid array
670
-            // let's make sure $box['page_route'] is an array so the "foreach" will work.
671
-            $box['page_route'] = (array) $box['page_route'];
672
-            foreach ($box['page_route'] as $route) {
673
-                if ($route != $this->_current_route) {
674
-                    continue;
675
-                } //get out we only add metaboxes for set route.
676
-                if ($add) {
677
-                    $this->_add_metabox($box);
678
-                } else {
679
-                    $this->_remove_metabox($box);
680
-                }
681
-            }
682
-        }
683
-    }
684
-
685
-
686
-    /**
687
-     * Loop through the _remove_metaboxes property and remove metaboxes accordingly.
688
-     *
689
-     * @return void
690
-     * @throws EE_Error
691
-     */
692
-    public function remove_metaboxes()
693
-    {
694
-
695
-        if (empty($this->_remove_metaboxes)) {
696
-            return;
697
-        } //get out there are no metaboxes to remove
698
-        $this->_handle_metabox_array($this->_remove_metaboxes, false);
699
-    }
700
-
701
-
702
-    /**
703
-     * This just handles adding a metabox
704
-     *
705
-     * @param array $args an array of args that have been set for this metabox by the child class
706
-     * @throws EE_Error
707
-     */
708
-    private function _add_metabox($args)
709
-    {
710
-        $current_screen = get_current_screen();
711
-        $screen_id      = is_object($current_screen) ? $current_screen->id : null;
712
-        $func           = isset($args['func']) ? $args['func'] : 'some_invalid_callback';
713
-        // set defaults
714
-        $defaults      = [
715
-            'callback_args' => [],
716
-            'context'       => 'advanced',
717
-            'func'          => $func,
718
-            'id'            => $this->caller . '_' . $func . '_metabox',
719
-            'label'         => $this->caller,
720
-            'page'          => isset($args['page']) ? $args['page'] : $screen_id,
721
-            'priority'      => 'default',
722
-        ];
723
-        $args          = wp_parse_args($args, $defaults);
724
-        $callback_args = $args['callback_args'];
725
-        $context       = $args['context'];
726
-        $func          = $args['func'];
727
-        $id            = $args['id'];
728
-        $label         = $args['label'];
729
-        $page          = $args['page'];
730
-        $priority      = $args['priority'];
731
-        // make sure method exists
732
-        if (! method_exists($this, $func)) {
733
-            $msg[] =
734
-                esc_html__('There is no corresponding method to display the metabox content', 'event_espresso')
735
-                . '<br />';
736
-            $msg[] = sprintf(
737
-                esc_html__(
738
-                    'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
739
-                    'event_espresso'
740
-                ),
741
-                $func,
742
-                $this->caller
743
-            );
744
-            throw new EE_Error(implode('||', $msg));
745
-        }
746
-        // everything checks out so let's add the metabox
747
-        add_meta_box($id, $label, [$this, $func], $page, $context, $priority, $callback_args);
748
-    }
749
-
750
-
751
-    private function _remove_metabox($args)
752
-    {
753
-        $current_screen = get_current_screen();
754
-        $screen_id      = is_object($current_screen) ? $current_screen->id : null;
755
-        $func           = isset($args['func']) ? $args['func'] : 'some_invalid_callback';
756
-        // set defaults
757
-        $defaults = [
758
-            'context' => 'default',
759
-            'id'      => isset($args['id'])
760
-                ? $args['id']
761
-                : $this->_current_route . '_' . $this->caller . '_' . $func . '_metabox',
762
-            'screen'  => isset($args['screen']) ? $args['screen'] : $screen_id,
763
-        ];
764
-        $args     = wp_parse_args($args, $defaults);
765
-        $context  = $args['context'];
766
-        $id       = $args['id'];
767
-        $screen   = $args['screen'];
768
-        // everything checks out so lets remove the box!
769
-        remove_meta_box($id, $screen, $context);
770
-    }
17
+	/**
18
+	 * we're just going to use this to hold the name of the caller class (child class name)
19
+	 *
20
+	 * @var string
21
+	 */
22
+	public $caller;
23
+
24
+
25
+	/**
26
+	 * this is just a flag set automatically to indicate whether we've got an extended hook class running (i.e.
27
+	 * espresso_events_Registration_Form_Hooks_Extend extends espresso_events_Registration_Form_Hooks).  This flag is
28
+	 * used later to make sure we require the needed files.
29
+	 *
30
+	 * @var bool
31
+	 */
32
+	protected $_extend;
33
+
34
+
35
+	/**
36
+	 * child classes MUST set this property so that the page object can be loaded correctly
37
+	 *
38
+	 * @var string
39
+	 */
40
+	protected $_name;
41
+
42
+
43
+	/**
44
+	 * This is set by child classes and is an associative array of ajax hooks in the format:
45
+	 * array(
46
+	 *    'ajax_action_ref' => 'executing_method'; //must be public
47
+	 * )
48
+	 *
49
+	 * @var array
50
+	 */
51
+	protected $_ajax_func;
52
+
53
+
54
+	/**
55
+	 * This is an array of methods that get executed on a page routes admin_init hook. Use the following format:
56
+	 * array(
57
+	 *    'page_route' => 'executing_method' //must be public
58
+	 * )
59
+	 *
60
+	 * @var array
61
+	 */
62
+	protected $_init_func;
63
+
64
+
65
+	/**
66
+	 * This is an array of methods that output metabox content for the given page route.  Use the following format:
67
+	 * [
68
+	 *      0 => [
69
+	 *          'page_route' => 'string_for_page_route',    must correspond to a page route in the class being connected
70
+	 *                                                      with (i.e. "edit_event") If this is in an array then the
71
+	 *                                                      same params below will be used but the metabox will be
72
+	 *                                                      added to each route.
73
+	 *          'func' =>  'executing_method',              must be public (i.e. public function executing_method
74
+	 *                                                      ($post, $callback_args){} ).
75
+	 *                                                      Note if you include callback args in the array then you
76
+	 *                                                      need to declare them in the method arguments.
77
+	 *          'id' => 'identifier_for_metabox',           so it can be removed by addons
78
+	 *                                                      (optional, class will set it automatically)
79
+	 *          'priority' => 'default',                    default 'default' (optional)
80
+	 *          'label' => esc_html__('Localized Title', 'event_espresso'),
81
+	 *          'context' => 'advanced'                     advanced is default (optional),
82
+	 *      ]
83
+	 *      'callback_args' => array() //any callback args to include (optional)
84
+	 * ]
85
+	 * Why are we indexing numerically?  Because it's possible there may be more than one metabox per page_route.
86
+	 *
87
+	 * @var array
88
+	 */
89
+	protected $_metaboxes;
90
+
91
+
92
+	/**
93
+	 * This is an array of values that indicate any metaboxes we want removed from a given page route.  Usually this is
94
+	 * used when caffeinated functionality is replacing decaffeinated functionality.  Use the following format for the
95
+	 * array: array(
96
+	 *    0 => array(
97
+	 *        'page_route' => 'string_for_page_route' //can be string or array of strings that match a page_route(s)
98
+	 *        that are in the class being connected with (i.e. 'edit', or 'create_new').
99
+	 *        'id' => 'identifier_for_metabox', //what the id is of the metabox being removed
100
+	 *        'context' => 'normal', //the context for the metabox being removed (has to match)
101
+	 *        'screen' => 'screen_id', //(optional), if not included then this class will attempt to remove the metabox
102
+	 *        using the currently loaded screen object->id  however, there may be cases where you have to specify the
103
+	 *        id for the screen the metabox is on.
104
+	 *    )
105
+	 * )
106
+	 *
107
+	 * @var array
108
+	 */
109
+	protected $_remove_metaboxes;
110
+
111
+
112
+	/**
113
+	 * This parent class takes care of loading the scripts and styles if the child class has set the properties for
114
+	 * them in the following format.  Note, the first array index ('register') is for defining all the registers.  The
115
+	 * second array index is for indicating what routes each script/style loads on. array(
116
+	 * 'registers' => array(
117
+	 *        'script_ref' => array( // if more than one script is to be loaded its best to use the 'dependency'
118
+	 *        argument to link scripts together.
119
+	 *            'type' => 'js' // 'js' or 'css' (defaults to js).  This tells us what type of wp_function to use
120
+	 *            'url' => 'http://urltoscript.css.js',
121
+	 *            'depends' => array('jquery'), //an array of dependencies for the scripts. REMEMBER, if a script has
122
+	 *            already been registered elsewhere in the system.  You can just use the depends array to make sure it
123
+	 *            gets loaded before the one you are setting here.
124
+	 *            'footer' => TRUE //defaults to true (styles don't use this parameter)
125
+	 *        ),
126
+	 *    'enqueues' => array( //this time each key corresponds to the script ref followed by an array of page routes
127
+	 *    the script gets enqueued on.
128
+	 *        'script_ref' => array('route_one', 'route_two')
129
+	 *    ),
130
+	 *    'localize' => array( //this allows you to set a localized object.  Indicate which script the object is being
131
+	 *    attached to and then include an array indexed by the name of the object and the array of key/value pairs for
132
+	 *    the object.
133
+	 *        'scrip_ref' => array(
134
+	 *            'NAME_OF_JS_OBJECT' => array(
135
+	 *                'translate_ref' => esc_html__('localized_string', 'event_espresso'),
136
+	 *                'some_data' => 5
137
+	 *            )
138
+	 *        )
139
+	 *    )
140
+	 * )
141
+	 *
142
+	 * @var array
143
+	 */
144
+	protected $_scripts_styles;
145
+
146
+
147
+	/**
148
+	 * This is a property that will contain the current route.
149
+	 *
150
+	 * @var string;
151
+	 */
152
+	protected $_current_route;
153
+
154
+
155
+	/**
156
+	 * this optional property can be set by child classes to override the priority for the automatic action/filter hook
157
+	 * loading in the `_load_routed_hooks()` method.  Please follow this format: array(
158
+	 *    'wp_hook_reference' => 1
159
+	 *    )
160
+	 * )
161
+	 *
162
+	 * @var array
163
+	 */
164
+	protected $_wp_action_filters_priority;
165
+
166
+
167
+	/**
168
+	 * This just holds a merged array of the request vars
169
+	 *
170
+	 * @var array
171
+	 */
172
+	protected $_req_data;
173
+
174
+	/**
175
+	 * @var array
176
+	 */
177
+	protected $_scripts;
178
+
179
+	/**
180
+	 * @var array
181
+	 */
182
+	protected $_styles;
183
+
184
+	/**
185
+	 * This just holds an instance of the page object for this hook
186
+	 *
187
+	 * @var EE_Admin_Page
188
+	 */
189
+	protected $_page_object;
190
+
191
+
192
+	/**
193
+	 * This holds the EE_Admin_Page object from the calling admin page that this object hooks into.
194
+	 *
195
+	 * @var EE_Admin_Page|EE_Admin_Page_CPT
196
+	 */
197
+	protected $_adminpage_obj;
198
+
199
+
200
+	/**
201
+	 * Holds EE_Registry object
202
+	 *
203
+	 * @var EE_Registry
204
+	 */
205
+	protected $EE = null;
206
+
207
+	/**
208
+	 * @var RequestInterface
209
+	 */
210
+	protected $request;
211
+
212
+
213
+	/**
214
+	 * constructor
215
+	 *
216
+	 * @param EE_Admin_Page $admin_page
217
+	 * @throws EE_Error
218
+	 */
219
+	public function __construct(EE_Admin_Page $admin_page)
220
+	{
221
+		$this->_adminpage_obj = $admin_page;
222
+		$this->request        = LoaderFactory::getLoader()->getShared(RequestInterface::class);
223
+		$this->_req_data      = $this->request->requestParams();
224
+		$this->_set_defaults();
225
+		$this->_set_hooks_properties();
226
+		// first let's verify we're on the right page
227
+		if (! isset($this->_req_data['page']) || $this->_req_data['page'] !== $this->_adminpage_obj->page_slug) {
228
+			return;
229
+		}
230
+		// get out nothing more to be done here.
231
+		// allow for extends to modify properties
232
+		if (method_exists($this, '_extend_properties')) {
233
+			$this->_extend_properties();
234
+		}
235
+		$this->_set_page_object();
236
+		$this->_init_hooks();
237
+		$this->_load_custom_methods();
238
+		$this->_load_routed_hooks();
239
+		add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts_styles']);
240
+		add_action('admin_enqueue_scripts', [$this, 'add_metaboxes'], 20);
241
+		add_action('admin_enqueue_scripts', [$this, 'remove_metaboxes'], 15);
242
+		$this->_ajax_hooks();
243
+	}
244
+
245
+
246
+	/**
247
+	 * used by child classes to set the following properties:
248
+	 * $_ajax_func (optional)
249
+	 * $_init_func (optional)
250
+	 * $_metaboxes (optional)
251
+	 * $_scripts (optional)
252
+	 * $_styles (optional)
253
+	 * $_name (required)
254
+	 * Also in this method will be registered any scripts or styles loaded on the targeted page (as indicated in the
255
+	 * _scripts/_styles properties) Also children should place in this method any filters/actions that have to happen
256
+	 * really early on page load (just after admin_init) if they want to have them registered for handling early.
257
+	 *
258
+	 * @abstract
259
+	 * @return void
260
+	 */
261
+	abstract protected function _set_hooks_properties();
262
+
263
+
264
+	/**
265
+	 * The hooks for enqueue_scripts and enqueue_styles will be run in here.  Child classes need to define their
266
+	 * scripts and styles in the relevant $_scripts and $_styles properties.  Child classes must have also already
267
+	 * registered the scripts and styles using wp_register_script and wp_register_style functions.
268
+	 *
269
+	 * @return void
270
+	 * @throws EE_Error
271
+	 */
272
+	public function enqueue_scripts_styles()
273
+	{
274
+
275
+		if (! empty($this->_scripts_styles)) {
276
+			// first let's do all the registrations
277
+			if (! isset($this->_scripts_styles['registers'])) {
278
+				$msg[] = esc_html__(
279
+					'There is no "registers" index in the <code>$this->_scripts_styles</code> property.',
280
+					'event_espresso'
281
+				);
282
+				$msg[] = sprintf(
283
+					esc_html__(
284
+						'Make sure you read the phpdoc comments above the definition of the $_scripts_styles property in the <code>EE_Admin_Hooks</code> class and modify according in the %s child',
285
+						'event_espresso'
286
+					),
287
+					'<strong>' . $this->caller . '</strong>'
288
+				);
289
+				throw new EE_Error(implode('||', $msg));
290
+			}
291
+			$defaults = [
292
+				'type'    => 'js',
293
+				'url'     => '',
294
+				'depends' => [],
295
+				'version' => EVENT_ESPRESSO_VERSION,
296
+				'footer'  => true,
297
+			];
298
+			foreach ($this->_scripts_styles['registers'] as $ref => $details) {
299
+				$details = wp_parse_args($details, $defaults);
300
+				$type    = $details['type'];
301
+				$url     = $details['url'];
302
+				$depends = $details['depends'];
303
+				$version = $details['version'];
304
+				$footer  = $details['footer'];
305
+				// let's make sure that we set the 'registers' type if it's not set!
306
+				// We need it later to determine which enqueue we do
307
+				$this->_scripts_styles['registers'][ $ref ]['type'] = $type;
308
+				// let's make sure we're not missing any REQUIRED parameters
309
+				if (empty($url)) {
310
+					$msg[] = sprintf(
311
+						esc_html__('Missing the url for the requested %s', 'event_espresso'),
312
+						$type == 'js' ? 'script' : 'stylesheet'
313
+					);
314
+					$msg[] = sprintf(
315
+						esc_html__(
316
+							'Doublecheck your <code>$this->_scripts_styles</code> array in %s and make sure that there is a "url" set for the %s ref',
317
+							'event_espresso'
318
+						),
319
+						'<strong>' . $this->caller . '</strong>',
320
+						$ref
321
+					);
322
+					throw new EE_Error(implode('||', $msg));
323
+				}
324
+				// made it here so let's do the appropriate registration
325
+				$type == 'js'
326
+					? wp_register_script($ref, $url, $depends, $version, $footer)
327
+					: wp_register_style(
328
+						$ref,
329
+						$url,
330
+						$depends,
331
+						$version
332
+					);
333
+			}
334
+			// k now let's do the enqueues
335
+			if (! isset($this->_scripts_styles['enqueues'])) {
336
+				return;
337
+			}  //not sure if we should throw an error here or not.
338
+
339
+			foreach ($this->_scripts_styles['enqueues'] as $ref => $routes) {
340
+				// make sure $routes is an array
341
+				$routes = (array) $routes;
342
+				if (in_array($this->_current_route, $routes)) {
343
+					$this->_scripts_styles['registers'][ $ref ]['type'] == 'js' ? wp_enqueue_script($ref)
344
+						: wp_enqueue_style($ref);
345
+					// if we have a localization for the script let's do that too.
346
+					if (isset($this->_scripts_styles['localize'][ $ref ])) {
347
+						foreach ($this->_scripts_styles['localize'][ $ref ] as $object_name => $indexes) {
348
+							wp_localize_script(
349
+								$ref,
350
+								$object_name,
351
+								$this->_scripts_styles['localize'][ $ref ][ $object_name ]
352
+							);
353
+						}
354
+					}
355
+				}
356
+			}
357
+			// let's do the deregisters
358
+			if (! isset($this->_scripts_styles['deregisters'])) {
359
+				return;
360
+			}
361
+			foreach ($this->_scripts_styles['deregisters'] as $ref => $details) {
362
+				$defaults = ['type' => 'js'];
363
+				$details  = wp_parse_args($details, $defaults);
364
+				$details['type'] === 'js' ? wp_deregister_script($ref) : wp_deregister_style($ref);
365
+			}
366
+		}
367
+	}
368
+
369
+
370
+	/**
371
+	 * just set the defaults for the hooks properties.
372
+	 *
373
+	 * @return void
374
+	 */
375
+	private function _set_defaults()
376
+	{
377
+		$this->_ajax_func                  = [];
378
+		$this->_init_func                  = [];
379
+		$this->_metaboxes                  = [];
380
+		$this->_scripts                    = [];
381
+		$this->_styles                     = [];
382
+		$this->_wp_action_filters_priority = [];
383
+		$this->_current_route              = $this->getCurrentRoute();
384
+		$this->caller                      = get_class($this);
385
+		$this->_extend                     = (bool) stripos($this->caller, 'Extend');
386
+	}
387
+
388
+
389
+	/**
390
+	 * A helper for determining the current route.
391
+	 *
392
+	 * @return string
393
+	 */
394
+	private function getCurrentRoute()
395
+	{
396
+		$action = $this->request->getRequestParam('action');
397
+		// list tables do something else with 'action' for bulk actions.
398
+		$action = $action !== '-1' && $action !== '' ? $action : 'default';
399
+		$route  = $this->request->getRequestParam('route');
400
+		// we set a 'route' variable in some cases where action is being used by something else.
401
+		return $action === 'default' && $route !== '' ? $route : $action;
402
+	}
403
+
404
+
405
+	/**
406
+	 * this sets the _page_object property
407
+	 *
408
+	 * @return void
409
+	 * @throws EE_Error
410
+	 */
411
+	protected function _set_page_object()
412
+	{
413
+		// first make sure $this->_name is set
414
+		if (empty($this->_name)) {
415
+			$msg[] = esc_html__('We can\'t load the page object', 'event_espresso');
416
+			$msg[] = sprintf(
417
+				esc_html__("This is because the %s child class has not set the '_name' property", 'event_espresso'),
418
+				$this->caller
419
+			);
420
+			throw new EE_Error(implode('||', $msg));
421
+		}
422
+		// change "the_message" to "the message"
423
+		$class_name = str_replace('_', ' ', $this->_name);
424
+		// change "the message" to "The_Message_Admin_Page"
425
+		$class_name = str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
426
+		// first default file (if exists)
427
+		$decaf_file = EE_ADMIN_PAGES . $this->_name . '/' . $class_name . '.core.php';
428
+		if (is_readable($decaf_file)) {
429
+			require_once($decaf_file);
430
+		}
431
+		// now we have to do require for extended file (if needed)
432
+		if ($this->_extend) {
433
+			require_once(EE_CORE_CAF_ADMIN_EXTEND . $this->_name . '/Extend_' . $class_name . '.core.php');
434
+			// and extend the class name as well
435
+			$class_name = 'Extend_' . $class_name;
436
+		}
437
+		// let's make sure the class exists
438
+		if (! class_exists($class_name)) {
439
+			$msg[] = esc_html__('We can\'t load the page object', 'event_espresso');
440
+			$msg[] = sprintf(
441
+				esc_html__(
442
+					'The class name that was given is %s. Check the spelling and make sure its correct, also there needs to be an autoloader setup for the class',
443
+					'event_espresso'
444
+				),
445
+				$class_name
446
+			);
447
+			throw new EE_Error(implode('||', $msg));
448
+		}
449
+		$this->_page_object = LoaderFactory::getLoader()->getShared($class_name, [false]);
450
+	}
451
+
452
+
453
+	/**
454
+	 * Child "hook" classes can declare any methods that they want executed when a specific page route is loaded.  The
455
+	 * advantage of this is when doing things like running our own db interactions on saves etc.  Remember that
456
+	 * $this->_req_data (all the _POST and _GET data) is available to your methods.
457
+	 *
458
+	 * @return void
459
+	 */
460
+	private function _load_custom_methods()
461
+	{
462
+		/**
463
+		 * method cannot be named 'default' (@see http://us3.php
464
+		 * .net/manual/en/reserved.keywords.php) so need to
465
+		 * handle routes that are "default"
466
+		 *
467
+		 * @since 4.3.0
468
+		 */
469
+		$method_callback = $this->_current_route == 'default' ? 'default_callback' : $this->_current_route;
470
+		// these run before the Admin_Page route executes.
471
+		if (method_exists($this, $method_callback)) {
472
+			call_user_func([$this, $method_callback]);
473
+		}
474
+		// these run via the _redirect_after_action method in EE_Admin_Page which usually happens after non_UI methods in EE_Admin_Page classes.  There are two redirect actions, the first fires before $query_args might be manipulated by "save and close" actions and the seond fires right before the actual redirect happens.
475
+		// first the actions
476
+		// note that these action hooks will have the $query_args value available.
477
+		$admin_class_name = get_class($this->_adminpage_obj);
478
+		if (method_exists($this, '_redirect_action_early_' . $this->_current_route)) {
479
+			add_action(
480
+				'AHEE__'
481
+				. $admin_class_name
482
+				. '___redirect_after_action__before_redirect_modification_'
483
+				. $this->_current_route,
484
+				[$this, '_redirect_action_early_' . $this->_current_route],
485
+				10
486
+			);
487
+		}
488
+		if (method_exists($this, '_redirect_action_' . $this->_current_route)) {
489
+			add_action(
490
+				'AHEE_redirect_' . $admin_class_name . $this->_current_route,
491
+				[$this, '_redirect_action_' . $this->_current_route],
492
+				10
493
+			);
494
+		}
495
+		// let's hook into the _redirect itself and allow for changing where the user goes after redirect.  This will have $query_args and $redirect_url available.
496
+		if (method_exists($this, '_redirect_filter_' . $this->_current_route)) {
497
+			add_filter(
498
+				'FHEE_redirect_' . $admin_class_name . $this->_current_route,
499
+				[$this, '_redirect_filter_' . $this->_current_route],
500
+				10,
501
+				2
502
+			);
503
+		}
504
+	}
505
+
506
+
507
+	/**
508
+	 * This method will search for a corresponding method with a name matching the route and the wp_hook to run.  This
509
+	 * allows child hook classes to target hooking into a specific wp action or filter hook ONLY on a certain route.
510
+	 * just remember, methods MUST be public Future hooks should be added in here to be access by child classes.
511
+	 *
512
+	 * @return void
513
+	 */
514
+	private function _load_routed_hooks()
515
+	{
516
+
517
+		// this array provides the hook action names that will be referenced.  Key is the action. Value is an array with the type (action or filter) and the number of parameters for the hook.  We'll default all priorities for automatic hooks to 10.
518
+		$hook_filter_array = [
519
+			'admin_footer'                                                                            => [
520
+				'type'     => 'action',
521
+				'argnum'   => 1,
522
+				'priority' => 10,
523
+			],
524
+			'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug . '_' . $this->_current_route => [
525
+				'type'     => 'filter',
526
+				'argnum'   => 1,
527
+				'priority' => 10,
528
+			],
529
+			'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug                               => [
530
+				'type'     => 'filter',
531
+				'argnum'   => 1,
532
+				'priority' => 10,
533
+			],
534
+			'FHEE_list_table_views'                                                                   => [
535
+				'type'     => 'filter',
536
+				'argnum'   => 1,
537
+				'priority' => 10,
538
+			],
539
+			'AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes'                              => [
540
+				'type'     => 'action',
541
+				'argnum'   => 1,
542
+				'priority' => 10,
543
+			],
544
+		];
545
+		foreach ($hook_filter_array as $hook => $args) {
546
+			if (method_exists($this, $this->_current_route . '_' . $hook)) {
547
+				if (isset($this->_wp_action_filters_priority[ $hook ])) {
548
+					$args['priority'] = $this->_wp_action_filters_priority[ $hook ];
549
+				}
550
+				if ($args['type'] == 'action') {
551
+					add_action(
552
+						$hook,
553
+						[$this, $this->_current_route . '_' . $hook],
554
+						$args['priority'],
555
+						$args['argnum']
556
+					);
557
+				} else {
558
+					add_filter(
559
+						$hook,
560
+						[$this, $this->_current_route . '_' . $hook],
561
+						$args['priority'],
562
+						$args['argnum']
563
+					);
564
+				}
565
+			}
566
+		}
567
+	}
568
+
569
+
570
+	/**
571
+	 * Loop throught the $_ajax_func array and add_actions for the array.
572
+	 *
573
+	 * @return void
574
+	 * @throws EE_Error
575
+	 */
576
+	private function _ajax_hooks()
577
+	{
578
+
579
+		if (empty($this->_ajax_func)) {
580
+			return;
581
+		} //get out there's nothing to take care of.
582
+		foreach ($this->_ajax_func as $action => $method) {
583
+			// make sure method exists
584
+			if (! method_exists($this, $method)) {
585
+				$msg[] = esc_html__(
586
+					'There is no corresponding method for the hook labeled in the _ajax_func array',
587
+					'event_espresso'
588
+				) . '<br />';
589
+				$msg[] = sprintf(
590
+					esc_html__(
591
+						'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
592
+						'event_espresso'
593
+					),
594
+					$method,
595
+					$this->caller
596
+				);
597
+				throw new EE_Error(implode('||', $msg));
598
+			}
599
+			add_action('wp_ajax_' . $action, [$this, $method]);
600
+		}
601
+	}
602
+
603
+
604
+	/**
605
+	 * Loop throught the $_init_func array and add_actions for the array.
606
+	 *
607
+	 * @return void
608
+	 * @throws EE_Error
609
+	 */
610
+	protected function _init_hooks()
611
+	{
612
+		if (empty($this->_init_func)) {
613
+			return;
614
+		}
615
+		// get out there's nothing to take care of.
616
+		// We need to determine what page_route we are on!
617
+		foreach ($this->_init_func as $route => $method) {
618
+			// make sure method exists
619
+			if (! method_exists($this, $method)) {
620
+				$msg[] = esc_html__(
621
+					'There is no corresponding method for the hook labeled in the _init_func array',
622
+					'event_espresso'
623
+				) . '<br />';
624
+				$msg[] = sprintf(
625
+					esc_html__(
626
+						'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
627
+						'event_espresso'
628
+					),
629
+					$method,
630
+					$this->caller
631
+				);
632
+				throw new EE_Error(implode('||', $msg));
633
+			}
634
+			if ($route == $this->_current_route) {
635
+				add_action('admin_init', [$this, $method]);
636
+			}
637
+		}
638
+	}
639
+
640
+
641
+	/**
642
+	 * Loop through the _metaboxes property and add_metaboxes accordingly
643
+	 * //todo we could eventually make this a config component class (i.e. new EE_Metabox);
644
+	 *
645
+	 * @return void
646
+	 * @throws EE_Error
647
+	 */
648
+	public function add_metaboxes()
649
+	{
650
+		if (empty($this->_metaboxes)) {
651
+			return;
652
+		} //get out we don't have any metaboxes to set for this connection
653
+		$this->_handle_metabox_array($this->_metaboxes);
654
+	}
655
+
656
+
657
+	/**
658
+	 * @param array $boxes
659
+	 * @param bool  $add
660
+	 * @throws EE_Error
661
+	 */
662
+	private function _handle_metabox_array(array $boxes, $add = true)
663
+	{
664
+
665
+		foreach ($boxes as $box) {
666
+			if (! isset($box['page_route'])) {
667
+				continue;
668
+			}
669
+			// we don't have a valid array
670
+			// let's make sure $box['page_route'] is an array so the "foreach" will work.
671
+			$box['page_route'] = (array) $box['page_route'];
672
+			foreach ($box['page_route'] as $route) {
673
+				if ($route != $this->_current_route) {
674
+					continue;
675
+				} //get out we only add metaboxes for set route.
676
+				if ($add) {
677
+					$this->_add_metabox($box);
678
+				} else {
679
+					$this->_remove_metabox($box);
680
+				}
681
+			}
682
+		}
683
+	}
684
+
685
+
686
+	/**
687
+	 * Loop through the _remove_metaboxes property and remove metaboxes accordingly.
688
+	 *
689
+	 * @return void
690
+	 * @throws EE_Error
691
+	 */
692
+	public function remove_metaboxes()
693
+	{
694
+
695
+		if (empty($this->_remove_metaboxes)) {
696
+			return;
697
+		} //get out there are no metaboxes to remove
698
+		$this->_handle_metabox_array($this->_remove_metaboxes, false);
699
+	}
700
+
701
+
702
+	/**
703
+	 * This just handles adding a metabox
704
+	 *
705
+	 * @param array $args an array of args that have been set for this metabox by the child class
706
+	 * @throws EE_Error
707
+	 */
708
+	private function _add_metabox($args)
709
+	{
710
+		$current_screen = get_current_screen();
711
+		$screen_id      = is_object($current_screen) ? $current_screen->id : null;
712
+		$func           = isset($args['func']) ? $args['func'] : 'some_invalid_callback';
713
+		// set defaults
714
+		$defaults      = [
715
+			'callback_args' => [],
716
+			'context'       => 'advanced',
717
+			'func'          => $func,
718
+			'id'            => $this->caller . '_' . $func . '_metabox',
719
+			'label'         => $this->caller,
720
+			'page'          => isset($args['page']) ? $args['page'] : $screen_id,
721
+			'priority'      => 'default',
722
+		];
723
+		$args          = wp_parse_args($args, $defaults);
724
+		$callback_args = $args['callback_args'];
725
+		$context       = $args['context'];
726
+		$func          = $args['func'];
727
+		$id            = $args['id'];
728
+		$label         = $args['label'];
729
+		$page          = $args['page'];
730
+		$priority      = $args['priority'];
731
+		// make sure method exists
732
+		if (! method_exists($this, $func)) {
733
+			$msg[] =
734
+				esc_html__('There is no corresponding method to display the metabox content', 'event_espresso')
735
+				. '<br />';
736
+			$msg[] = sprintf(
737
+				esc_html__(
738
+					'The method name given in the array is %s, check the spelling and make sure it exists in the %s class',
739
+					'event_espresso'
740
+				),
741
+				$func,
742
+				$this->caller
743
+			);
744
+			throw new EE_Error(implode('||', $msg));
745
+		}
746
+		// everything checks out so let's add the metabox
747
+		add_meta_box($id, $label, [$this, $func], $page, $context, $priority, $callback_args);
748
+	}
749
+
750
+
751
+	private function _remove_metabox($args)
752
+	{
753
+		$current_screen = get_current_screen();
754
+		$screen_id      = is_object($current_screen) ? $current_screen->id : null;
755
+		$func           = isset($args['func']) ? $args['func'] : 'some_invalid_callback';
756
+		// set defaults
757
+		$defaults = [
758
+			'context' => 'default',
759
+			'id'      => isset($args['id'])
760
+				? $args['id']
761
+				: $this->_current_route . '_' . $this->caller . '_' . $func . '_metabox',
762
+			'screen'  => isset($args['screen']) ? $args['screen'] : $screen_id,
763
+		];
764
+		$args     = wp_parse_args($args, $defaults);
765
+		$context  = $args['context'];
766
+		$id       = $args['id'];
767
+		$screen   = $args['screen'];
768
+		// everything checks out so lets remove the box!
769
+		remove_meta_box($id, $screen, $context);
770
+	}
771 771
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Loader.core.php 2 patches
Spacing   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -100,13 +100,13 @@  discard block
 block discarded – undo
100 100
      */
101 101
     private function _define_caffeinated_constants()
102 102
     {
103
-        if (! defined('EE_CORE_CAF_ADMIN')) {
104
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
105
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
106
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
107
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
108
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
109
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
103
+        if ( ! defined('EE_CORE_CAF_ADMIN')) {
104
+            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH.'caffeinated/admin/');
105
+            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL.'caffeinated/admin/');
106
+            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN.'new/');
107
+            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN.'extend/');
108
+            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL.'extend/');
109
+            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN.'hooks/');
110 110
         }
111 111
     }
112 112
 
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
         // first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
223 223
         usort($this->_admin_menu_groups, [$this, '_sort_menu_maps']);
224 224
         foreach ($this->_admin_menu_groups as $group) {
225
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
225
+            if ( ! $group instanceof EE_Admin_Page_Menu_Group) {
226 226
                 throw new EE_Error(
227 227
                     sprintf(
228 228
                         esc_html__(
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
                     )
234 234
                 );
235 235
             }
236
-            $groups[ $group->menu_slug ] = $group;
236
+            $groups[$group->menu_slug] = $group;
237 237
         }
238 238
         return $groups;
239 239
     }
@@ -252,13 +252,13 @@  discard block
 block discarded – undo
252 252
         $installed_refs = [];
253 253
         $exclude        = ['assets', 'templates'];
254 254
         // grab everything in the  admin core directory
255
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
255
+        $admin_screens = glob(EE_ADMIN_PAGES.'*', GLOB_ONLYDIR);
256 256
         if ($admin_screens) {
257 257
             foreach ($admin_screens as $admin_screen) {
258 258
                 // files and anything in the exclude array need not apply
259 259
                 if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
260 260
                     // these folders represent the different EE admin pages
261
-                    $installed_refs[ basename($admin_screen) ] = $admin_screen;
261
+                    $installed_refs[basename($admin_screen)] = $admin_screen;
262 262
                 }
263 263
             }
264 264
         }
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
                 'There are no EE_Admin pages detected, it looks like EE did not install properly',
268 268
                 'event_espresso'
269 269
             );
270
-            $error_msg[] = $error_msg[0] . "\r\n"
270
+            $error_msg[] = $error_msg[0]."\r\n"
271 271
                            . sprintf(
272 272
                                esc_html__(
273 273
                                    'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
         // this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
281 281
         $installed_refs = $this->_set_caffeinated($installed_refs);
282 282
         // allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
283
-        $installed_refs             = apply_filters(
283
+        $installed_refs = apply_filters(
284 284
             'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
285 285
             $installed_refs
286 286
         );
@@ -297,8 +297,8 @@  discard block
 block discarded – undo
297 297
             $admin_init_page = $this->_load_admin_page($page);
298 298
             // verify returned object
299 299
             if ($admin_init_page instanceof EE_Admin_Page_Init) {
300
-                $this->_installed_pages[ $page ] = $admin_init_page;
301
-                if (! $admin_init_page->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
300
+                $this->_installed_pages[$page] = $admin_init_page;
301
+                if ( ! $admin_init_page->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
302 302
                     continue;
303 303
                 }
304 304
                 // skip if in full maintenance mode and maintenance_mode_parent is set
@@ -307,27 +307,27 @@  discard block
 block discarded – undo
307 307
                     empty($maintenance_mode_parent)
308 308
                     && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
309 309
                 ) {
310
-                    unset($installed_refs[ $page ]);
310
+                    unset($installed_refs[$page]);
311 311
                     continue;
312 312
                 }
313 313
                 $menu_slug                       = $admin_init_page->get_menu_map()->menu_slug;
314
-                $this->_menu_slugs[ $menu_slug ] = $page;
314
+                $this->_menu_slugs[$menu_slug] = $page;
315 315
                 // flag for register hooks on extended pages b/c extended pages use the default INIT.
316 316
                 $extend = false;
317 317
                 // now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
318
-                if (isset($this->_caffeinated_extends[ $page ])) {
318
+                if (isset($this->_caffeinated_extends[$page])) {
319 319
                     $admin_page_name = $admin_init_page->get_admin_page_name();
320
-                    $caf_path        = $this->_caffeinated_extends[ $page ]['path'];
321
-                    $caf_admin_page  = $this->_caffeinated_extends[ $page ]['admin_page'];
320
+                    $caf_path        = $this->_caffeinated_extends[$page]['path'];
321
+                    $caf_admin_page  = $this->_caffeinated_extends[$page]['admin_page'];
322 322
                     add_filter(
323 323
                         "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
324
-                        function ($path_to_file) use ($caf_path) {
324
+                        function($path_to_file) use ($caf_path) {
325 325
                             return $caf_path;
326 326
                         }
327 327
                     );
328 328
                     add_filter(
329 329
                         "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
330
-                        function ($admin_page) use ($caf_admin_page) {
330
+                        function($admin_page) use ($caf_admin_page) {
331 331
                             return $caf_admin_page;
332 332
                         }
333 333
                     );
@@ -352,7 +352,7 @@  discard block
 block discarded – undo
352 352
         $ee_menu_slugs = $this->_menu_slugs;
353 353
         // we need to loop again to run any early code
354 354
         foreach ($installed_refs as $page => $path) {
355
-            $this->_installed_pages[ $page ]->do_initial_loads();
355
+            $this->_installed_pages[$page]->do_initial_loads();
356 356
         }
357 357
         do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
358 358
     }
@@ -366,8 +366,8 @@  discard block
 block discarded – undo
366 366
      */
367 367
     public function get_admin_page_object($page_slug = '')
368 368
     {
369
-        if (isset($this->_installed_pages[ $page_slug ])) {
370
-            return $this->_installed_pages[ $page_slug ]->loaded_page_object();
369
+        if (isset($this->_installed_pages[$page_slug])) {
370
+            return $this->_installed_pages[$page_slug]->loaded_page_object();
371 371
         }
372 372
         return null;
373 373
     }
@@ -383,7 +383,7 @@  discard block
 block discarded – undo
383 383
     private function _get_classname_for_admin_page($dir_name = '')
384 384
     {
385 385
         $class_name = str_replace('_', ' ', strtolower($dir_name));
386
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
386
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page';
387 387
     }
388 388
 
389 389
 
@@ -397,7 +397,7 @@  discard block
 block discarded – undo
397 397
     private function _get_classname_for_admin_init_page($dir_name = '')
398 398
     {
399 399
         $class_name = str_replace('_', ' ', strtolower($dir_name));
400
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
400
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page_Init';
401 401
     }
402 402
 
403 403
 
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
                 'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
432 432
                 'event_espresso'
433 433
             ),
434
-            '<strong>' . $class_name . '</strong>'
434
+            '<strong>'.$class_name.'</strong>'
435 435
         );
436 436
         throw new EE_Error($error_msg);
437 437
     }
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
                 // if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
492 492
                 if (is_array($page_map) || empty($page_map)) {
493 493
                     new PersistentAdminNotice(
494
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
494
+                        'menu_map_warning_'.str_replace(' ', '_', $page->label).'_'.EVENT_ESPRESSO_VERSION,
495 495
                         sprintf(
496 496
                             esc_html__(
497 497
                                 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
@@ -503,7 +503,7 @@  discard block
 block discarded – undo
503 503
                     continue;
504 504
                 }
505 505
                 // if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
506
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
506
+                if ( ! $page_map instanceof EE_Admin_Page_Menu_Map) {
507 507
                     throw new EE_Error(
508 508
                         sprintf(
509 509
                             esc_html__(
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
                     continue;
524 524
                 }
525 525
                 // assign to group (remember $page_map has the admin page stored in it).
526
-                $pages_array[ $page_map->menu_group ][] = $page_map;
526
+                $pages_array[$page_map->menu_group][] = $page_map;
527 527
             }
528 528
         }
529 529
         if (empty($pages_array)) {
@@ -532,20 +532,20 @@  discard block
 block discarded – undo
532 532
         // let's sort the groups, make sure it's a valid group, add header (if to show).
533 533
         foreach ($pages_array as $group => $menu_maps) {
534 534
             // valid_group?
535
-            if (! array_key_exists($group, $menu_groups)) {
535
+            if ( ! array_key_exists($group, $menu_groups)) {
536 536
                 continue;
537 537
             }
538 538
             // sort pages.
539 539
             usort($menu_maps, [$this, '_sort_menu_maps']);
540 540
             // prepend header
541
-            array_unshift($menu_maps, $menu_groups[ $group ]);
541
+            array_unshift($menu_maps, $menu_groups[$group]);
542 542
             // reset $pages_array with prepped data
543
-            $pages_array[ $group ] = $menu_maps;
543
+            $pages_array[$group] = $menu_maps;
544 544
         }
545 545
         // now let's setup the _prepped_menu_maps property
546 546
         foreach ($menu_groups as $group => $group_objs) {
547
-            if (isset($pages_array[ $group ])) {
548
-                $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[ $group ]);
547
+            if (isset($pages_array[$group])) {
548
+                $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
549 549
             }
550 550
         }/**/
551 551
     }
@@ -575,32 +575,32 @@  discard block
 block discarded – undo
575 575
     {
576 576
 
577 577
         // first let's check if there IS a caffeinated folder. If there is not then lets get out.
578
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) {
578
+        if ( ! is_dir(EE_PLUGIN_DIR_PATH.'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) {
579 579
             return $installed_refs;
580 580
         }
581 581
         $this->_define_caffeinated_constants();
582 582
         $exclude = ['tickets'];
583 583
         // okay let's setup an "New" pages first (we'll return installed refs later)
584
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
584
+        $new_admin_screens = glob(EE_CORE_CAF_ADMIN.'new/*', GLOB_ONLYDIR);
585 585
         if ($new_admin_screens) {
586 586
             foreach ($new_admin_screens as $admin_screen) {
587 587
                 // files and anything in the exclude array need not apply
588 588
                 if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
589 589
                     // these folders represent the different NEW EE admin pages
590
-                    $installed_refs[ basename($admin_screen) ] = $admin_screen;
590
+                    $installed_refs[basename($admin_screen)] = $admin_screen;
591 591
                     // set autoloaders for our admin page classes based on included path information
592 592
                     EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
593 593
                 }
594 594
             }
595 595
         }
596 596
         // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
597
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
597
+        $extends = glob(EE_CORE_CAF_ADMIN.'extend/*', GLOB_ONLYDIR);
598 598
         if ($extends) {
599 599
             foreach ($extends as $extend) {
600 600
                 if (is_dir($extend)) {
601 601
                     $extend_ref = basename($extend);
602 602
                     // now let's make sure there is a file that matches the expected format
603
-                    $filename                                                = str_replace(
603
+                    $filename = str_replace(
604 604
                         ' ',
605 605
                         '_',
606 606
                         ucwords(
@@ -611,8 +611,8 @@  discard block
 block discarded – undo
611 611
                             )
612 612
                         )
613 613
                     );
614
-                    $filename                                                = 'Extend_' . $filename . '_Admin_Page';
615
-                    $this->_caffeinated_extends[ $extend_ref ]['path']       = str_replace(
614
+                    $filename                                                = 'Extend_'.$filename.'_Admin_Page';
615
+                    $this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
616 616
                         ['\\', '/'],
617 617
                         '/',
618 618
                         EE_CORE_CAF_ADMIN
@@ -622,7 +622,7 @@  discard block
 block discarded – undo
622 622
                         . $filename
623 623
                         . '.core.php'
624 624
                     );
625
-                    $this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename;
625
+                    $this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
626 626
                     // set autoloaders for our admin page classes based on included path information
627 627
                     EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
628 628
                 }
@@ -630,12 +630,12 @@  discard block
 block discarded – undo
630 630
         }
631 631
         // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
632 632
         $ee_admin_hooks = [];
633
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
633
+        $hooks          = glob(EE_CORE_CAF_ADMIN.'hooks/*.class.php');
634 634
         if ($hooks) {
635 635
             foreach ($hooks as $hook) {
636 636
                 if (is_readable($hook)) {
637 637
                     require_once $hook;
638
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
638
+                    $classname = str_replace(EE_CORE_CAF_ADMIN.'hooks/', '', $hook);
639 639
                     $classname = str_replace('.class.php', '', $classname);
640 640
                     if (class_exists($classname)) {
641 641
                         $ee_admin_hooks[] = $this->loader->getShared($classname);
Please login to merge, or discard this patch.
Indentation   +661 added lines, -661 removed lines patch added patch discarded remove patch
@@ -13,665 +13,665 @@
 block discarded – undo
13 13
  */
14 14
 class EE_Admin_Page_Loader
15 15
 {
16
-    /**
17
-     * _installed_pages
18
-     * objects for page_init objects detected and loaded
19
-     *
20
-     * @access private
21
-     * @var EE_Admin_Page_Init[]
22
-     */
23
-    private $_installed_pages = [];
24
-
25
-
26
-    /**
27
-     * this is used to hold the registry of menu slugs for all the installed admin pages
28
-     *
29
-     * @var array
30
-     */
31
-    private $_menu_slugs = [];
32
-
33
-
34
-    /**
35
-     * _caffeinated_extends
36
-     * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
37
-     * pieces needed to do so).  This property is defined in the _set_caffeinated method.
38
-     *
39
-     * @var array
40
-     */
41
-    private $_caffeinated_extends = [];
42
-
43
-    /**
44
-     * _prepped_menu_maps
45
-     * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
46
-     *
47
-     * @since  4.4.0
48
-     * @var EE_Admin_Page_Menu_Map[]
49
-     */
50
-    private $_prepped_menu_maps = [];
51
-
52
-
53
-    /**
54
-     * _admin_menu_groups
55
-     * array that holds the group headings and details for
56
-     *
57
-     * @access private
58
-     * @var array
59
-     */
60
-    private $_admin_menu_groups = [];
61
-
62
-
63
-    /**
64
-     * This property will hold the hook file for setting up the filter that does all the connections between admin
65
-     * pages.
66
-     *
67
-     * @var string
68
-     */
69
-    public $hook_file;
70
-
71
-    /**
72
-     * @var LoaderInterface
73
-     */
74
-    protected $loader;
75
-
76
-
77
-    /**
78
-     * @throws EE_Error
79
-     */
80
-    public function __construct(LoaderInterface $loader)
81
-    {
82
-        $this->loader = $loader;
83
-        // define the default "groups" for the admin_pages
84
-        $this->_set_menu_groups();
85
-        // let's do a scan and see what installed pages we have
86
-        $this->_get_installed_pages();
87
-        // set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
88
-        add_action('admin_menu', [$this, 'set_menus']);
89
-        add_action('network_admin_menu', [$this, 'set_network_menus']);
90
-    }
91
-
92
-
93
-    /**
94
-     * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
95
-     * files in the caffeinated folder.
96
-     *
97
-     * @access private
98
-     * @return void
99
-     */
100
-    private function _define_caffeinated_constants()
101
-    {
102
-        if (! defined('EE_CORE_CAF_ADMIN')) {
103
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
104
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
105
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
106
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
107
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
108
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
109
-        }
110
-    }
111
-
112
-
113
-    /**
114
-     * _set_menu_groups
115
-     * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
116
-     *
117
-     * @access private
118
-     * @return void
119
-     */
120
-    private function _set_menu_groups()
121
-    {
122
-        // set array of EE_Admin_Page_Menu_Group objects
123
-        $this->_admin_menu_groups = apply_filters(
124
-            'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
125
-            [
126
-                'main'       => $this->loader->getNew(
127
-                    'EE_Admin_Page_Menu_Group',
128
-                    [
129
-                        'menu_label'   => esc_html__('Main', 'event_espresso'),
130
-                        'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
131
-                        'menu_slug'    => 'main',
132
-                        'capability'   => 'ee_read_ee',
133
-                        'menu_order'   => 0,
134
-                        'parent_slug'  => 'espresso_events',
135
-                    ]
136
-                ),
137
-                'management' => $this->loader->getNew(
138
-                    'EE_Admin_Page_Menu_Group',
139
-                    [
140
-                        'menu_label'   => esc_html__('Management', 'event_espresso'),
141
-                        'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
142
-                        'menu_slug'    => 'management',
143
-                        'capability'   => 'ee_read_ee',
144
-                        'menu_order'   => 10,
145
-                        'parent_slug'  => 'espresso_events',
146
-                    ]
147
-                ),
148
-                'settings'   => $this->loader->getNew(
149
-                    'EE_Admin_Page_Menu_Group',
150
-                    [
151
-                        'menu_label'   => esc_html__('Settings', 'event_espresso'),
152
-                        'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
153
-                        'menu_slug'    => 'settings',
154
-                        'capability'   => 'ee_read_ee',
155
-                        'menu_order'   => 30,
156
-                        'parent_slug'  => 'espresso_events',
157
-                    ]
158
-                ),
159
-                'templates'  => $this->loader->getNew(
160
-                    'EE_Admin_Page_Menu_Group',
161
-                    [
162
-                        'menu_label'   => esc_html__('Templates', 'event_espresso'),
163
-                        'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
164
-                        'menu_slug'    => 'templates',
165
-                        'capability'   => 'ee_read_ee',
166
-                        'menu_order'   => 40,
167
-                        'parent_slug'  => 'espresso_events',
168
-                    ]
169
-                ),
170
-                'extras'     => $this->loader->getNew(
171
-                    'EE_Admin_Page_Menu_Group',
172
-                    [
173
-                        'menu_label'              => esc_html__('Extras', 'event_espresso'),
174
-                        'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
175
-                        'menu_slug'               => 'extras',
176
-                        'capability'              => 'ee_read_ee',
177
-                        'menu_order'              => 50,
178
-                        'parent_slug'             => 'espresso_events',
179
-                        'maintenance_mode_parent' => 'espresso_maintenance_settings',
180
-                    ]
181
-                ),
182
-                'tools'      => $this->loader->getNew(
183
-                    'EE_Admin_Page_Menu_Group',
184
-                    [
185
-                        'menu_label'   => esc_html__('Tools', 'event_espresso'),
186
-                        'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
187
-                        'menu_slug'    => 'tools',
188
-                        'capability'   => 'ee_read_ee',
189
-                        'menu_order'   => 60,
190
-                        'parent_slug'  => 'espresso_events',
191
-                    ]
192
-                ),
193
-                'addons'     => $this->loader->getNew(
194
-                    'EE_Admin_Page_Menu_Group',
195
-                    [
196
-                        'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
197
-                        'menu_label'   => esc_html__('Add-ons', 'event_espresso'),
198
-                        'menu_slug'    => 'addons',
199
-                        'capability'   => 'ee_read_ee',
200
-                        'menu_order'   => 20,
201
-                        'parent_slug'  => 'espresso_events',
202
-                    ]
203
-                ),
204
-            ]
205
-        );
206
-    }
207
-
208
-
209
-    /**
210
-     * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
211
-     * slug.  The other utility with this function is it validates that all the groups are instances of
212
-     * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
213
-     *
214
-     * @return EE_Admin_Page_Menu_Group[]
215
-     * @throws EE_Error
216
-     * @since  4.4.0
217
-     */
218
-    private function _rearrange_menu_groups()
219
-    {
220
-        $groups = [];
221
-        // first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
222
-        usort($this->_admin_menu_groups, [$this, '_sort_menu_maps']);
223
-        foreach ($this->_admin_menu_groups as $group) {
224
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
225
-                throw new EE_Error(
226
-                    sprintf(
227
-                        esc_html__(
228
-                            'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
229
-                            'event_espresso'
230
-                        ),
231
-                        print_r($group, true)
232
-                    )
233
-                );
234
-            }
235
-            $groups[ $group->menu_slug ] = $group;
236
-        }
237
-        return $groups;
238
-    }
239
-
240
-
241
-    /**
242
-     * _get_installed_pages
243
-     * This just gets the list of installed EE_Admin_pages.
244
-     *
245
-     * @access private
246
-     * @return void
247
-     * @throws EE_Error
248
-     */
249
-    private function _get_installed_pages()
250
-    {
251
-        $installed_refs = [];
252
-        $exclude        = ['assets', 'templates'];
253
-        // grab everything in the  admin core directory
254
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
255
-        if ($admin_screens) {
256
-            foreach ($admin_screens as $admin_screen) {
257
-                // files and anything in the exclude array need not apply
258
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
259
-                    // these folders represent the different EE admin pages
260
-                    $installed_refs[ basename($admin_screen) ] = $admin_screen;
261
-                }
262
-            }
263
-        }
264
-        if (empty($installed_refs)) {
265
-            $error_msg[] = esc_html__(
266
-                'There are no EE_Admin pages detected, it looks like EE did not install properly',
267
-                'event_espresso'
268
-            );
269
-            $error_msg[] = $error_msg[0] . "\r\n"
270
-                           . sprintf(
271
-                               esc_html__(
272
-                                   'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
273
-                                   'event_espresso'
274
-                               ),
275
-                               EE_ADMIN_PAGES
276
-                           );
277
-            throw new EE_Error(implode('||', $error_msg));
278
-        }
279
-        // this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
280
-        $installed_refs = $this->_set_caffeinated($installed_refs);
281
-        // allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
282
-        $installed_refs             = apply_filters(
283
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
284
-            $installed_refs
285
-        );
286
-        $this->_caffeinated_extends = apply_filters(
287
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
288
-            $this->_caffeinated_extends
289
-        );
290
-        // loop through admin pages and setup the $_installed_pages array.
291
-        $hooks_ref = [];
292
-        foreach ($installed_refs as $page => $path) {
293
-            // set autoloaders for our admin page classes based on included path information
294
-            EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
295
-            // build list of installed pages
296
-            $admin_init_page = $this->_load_admin_page($page);
297
-            // verify returned object
298
-            if ($admin_init_page instanceof EE_Admin_Page_Init) {
299
-                $this->_installed_pages[ $page ] = $admin_init_page;
300
-                if (! $admin_init_page->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
301
-                    continue;
302
-                }
303
-                // skip if in full maintenance mode and maintenance_mode_parent is set
304
-                $maintenance_mode_parent = $admin_init_page->get_menu_map()->maintenance_mode_parent;
305
-                if (
306
-                    empty($maintenance_mode_parent)
307
-                    && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
308
-                ) {
309
-                    unset($installed_refs[ $page ]);
310
-                    continue;
311
-                }
312
-                $menu_slug                       = $admin_init_page->get_menu_map()->menu_slug;
313
-                $this->_menu_slugs[ $menu_slug ] = $page;
314
-                // flag for register hooks on extended pages b/c extended pages use the default INIT.
315
-                $extend = false;
316
-                // now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
317
-                if (isset($this->_caffeinated_extends[ $page ])) {
318
-                    $admin_page_name = $admin_init_page->get_admin_page_name();
319
-                    $caf_path        = $this->_caffeinated_extends[ $page ]['path'];
320
-                    $caf_admin_page  = $this->_caffeinated_extends[ $page ]['admin_page'];
321
-                    add_filter(
322
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
323
-                        function ($path_to_file) use ($caf_path) {
324
-                            return $caf_path;
325
-                        }
326
-                    );
327
-                    add_filter(
328
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
329
-                        function ($admin_page) use ($caf_admin_page) {
330
-                            return $caf_admin_page;
331
-                        }
332
-                    );
333
-                    $extend = true;
334
-                }
335
-                // let's do the registered hooks
336
-                $extended_hooks = $admin_init_page->register_hooks($extend);
337
-                $hooks_ref      = array_merge($hooks_ref, $extended_hooks);
338
-            }
339
-        }
340
-        // the hooks_ref is all the pages where we have $extended _Hooks files
341
-        // that will extend a class in a different folder.
342
-        // So we want to make sure we load the file for the parent.
343
-        // first make sure we've got unique values
344
-        $hooks_ref = array_unique($hooks_ref);
345
-        // now let's loop and require!
346
-        foreach ($hooks_ref as $path) {
347
-            require_once($path);
348
-        }
349
-        // make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
350
-        global $ee_menu_slugs;
351
-        $ee_menu_slugs = $this->_menu_slugs;
352
-        // we need to loop again to run any early code
353
-        foreach ($installed_refs as $page => $path) {
354
-            $this->_installed_pages[ $page ]->do_initial_loads();
355
-        }
356
-        do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
357
-    }
358
-
359
-
360
-    /**
361
-     * get_admin_page_object
362
-     *
363
-     * @param string $page_slug
364
-     * @return EE_Admin_Page
365
-     */
366
-    public function get_admin_page_object($page_slug = '')
367
-    {
368
-        if (isset($this->_installed_pages[ $page_slug ])) {
369
-            return $this->_installed_pages[ $page_slug ]->loaded_page_object();
370
-        }
371
-        return null;
372
-    }
373
-
374
-
375
-    /**
376
-     * _get_classname_for_admin_page
377
-     * generates an "Admin Page" class based on the directory  name
378
-     *
379
-     * @param $dir_name
380
-     * @return string
381
-     */
382
-    private function _get_classname_for_admin_page($dir_name = '')
383
-    {
384
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
385
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
386
-    }
387
-
388
-
389
-    /**
390
-     * _get_classname_for_admin_init_page
391
-     * generates an "Admin Page Init" class based on the directory  name
392
-     *
393
-     * @param $dir_name
394
-     * @return string
395
-     */
396
-    private function _get_classname_for_admin_init_page($dir_name = '')
397
-    {
398
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
399
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
400
-    }
401
-
402
-
403
-    /**
404
-     * _load_admin_page
405
-     * Loads and instantiates page_init object for a single EE_admin page.
406
-     *
407
-     * @param string $page page_reference
408
-     * @return object|bool  return page object if valid, bool false if not.
409
-     * @throws EE_Error
410
-     */
411
-    private function _load_admin_page($page = '')
412
-    {
413
-        $class_name = $this->_get_classname_for_admin_init_page($page);
414
-        if (class_exists($class_name)) {
415
-            return $this->loader->getShared($class_name);
416
-        }
417
-        $error_msg = sprintf(
418
-            esc_html__('Something went wrong with loading the %s admin page.', 'event_espresso'),
419
-            $page
420
-        );
421
-        $error_msg .= '||'; // separates public from developer messages
422
-        $error_msg .= "\r\n";
423
-        $error_msg .= sprintf(
424
-            esc_html__('There is no Init class in place for the %s admin page.', 'event_espresso'),
425
-            $page
426
-        );
427
-        $error_msg .= '<br />';
428
-        $error_msg .= sprintf(
429
-            esc_html__(
430
-                'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
431
-                'event_espresso'
432
-            ),
433
-            '<strong>' . $class_name . '</strong>'
434
-        );
435
-        throw new EE_Error($error_msg);
436
-    }
437
-
438
-
439
-    /**
440
-     * set_menus
441
-     * This method sets up the menus for EE Admin Pages
442
-     *
443
-     * @access private
444
-     * @return void
445
-     * @throws EE_Error
446
-     */
447
-    public function set_menus($network_admin = false)
448
-    {
449
-        // prep the menu pages (sort, group.)
450
-        $this->_prep_pages();
451
-        foreach ($this->_prepped_menu_maps as $menu_map) {
452
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
453
-                $menu_map->add_menu_page($network_admin);
454
-            }
455
-        }
456
-    }
457
-
458
-
459
-    /**
460
-     * set_network_menus
461
-     * This method sets up the menus for network EE Admin Pages.
462
-     * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
463
-     * are only added to the menu map if they are intended for the admin menu
464
-     *
465
-     * @return void
466
-     * @throws EE_Error
467
-     */
468
-    public function set_network_menus()
469
-    {
470
-        $this->set_menus(true);
471
-    }
472
-
473
-
474
-    /**
475
-     * _prep_pages
476
-     * sets the _prepped_menu_maps property
477
-     *
478
-     * @access private
479
-     * @return void
480
-     * @throws EE_Error
481
-     */
482
-    private function _prep_pages()
483
-    {
484
-        $pages_array = [];
485
-        // rearrange _admin_menu_groups to be indexed by group slug.
486
-        $menu_groups = $this->_rearrange_menu_groups();
487
-        foreach ($this->_installed_pages as $page) {
488
-            if ($page instanceof EE_Admin_page_Init) {
489
-                $page_map = $page->get_menu_map();
490
-                // if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
491
-                if (is_array($page_map) || empty($page_map)) {
492
-                    new PersistentAdminNotice(
493
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
494
-                        sprintf(
495
-                            esc_html__(
496
-                                'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
497
-                                'event_espresso'
498
-                            ),
499
-                            $page->label
500
-                        )
501
-                    );
502
-                    continue;
503
-                }
504
-                // if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
505
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
506
-                    throw new EE_Error(
507
-                        sprintf(
508
-                            esc_html__(
509
-                                'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
510
-                                'event_espresso'
511
-                            ),
512
-                            $page->label,
513
-                            $page_map
514
-                        )
515
-                    );
516
-                }
517
-                // use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
518
-                if (
519
-                    empty($page_map->maintenance_mode_parent)
520
-                    && EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance
521
-                ) {
522
-                    continue;
523
-                }
524
-                // assign to group (remember $page_map has the admin page stored in it).
525
-                $pages_array[ $page_map->menu_group ][] = $page_map;
526
-            }
527
-        }
528
-        if (empty($pages_array)) {
529
-            throw new EE_Error(esc_html__('Something went wrong when prepping the admin pages', 'event_espresso'));
530
-        }
531
-        // let's sort the groups, make sure it's a valid group, add header (if to show).
532
-        foreach ($pages_array as $group => $menu_maps) {
533
-            // valid_group?
534
-            if (! array_key_exists($group, $menu_groups)) {
535
-                continue;
536
-            }
537
-            // sort pages.
538
-            usort($menu_maps, [$this, '_sort_menu_maps']);
539
-            // prepend header
540
-            array_unshift($menu_maps, $menu_groups[ $group ]);
541
-            // reset $pages_array with prepped data
542
-            $pages_array[ $group ] = $menu_maps;
543
-        }
544
-        // now let's setup the _prepped_menu_maps property
545
-        foreach ($menu_groups as $group => $group_objs) {
546
-            if (isset($pages_array[ $group ])) {
547
-                $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[ $group ]);
548
-            }
549
-        }/**/
550
-    }
551
-
552
-
553
-    /**
554
-     * This method is the "workhorse" for detecting and setting up caffeinated functionality.
555
-     * In this method there are three checks being done:
556
-     * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
557
-     * array) etc.  (new page sets are found in caffeinated/new/{page})
558
-     * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
559
-     * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
560
-     * Extend_Events_Admin_Page extends Events_Admin_Page.
561
-     * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
562
-     * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
563
-     * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
564
-     * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
565
-     * admin_pages)
566
-     *
567
-     * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
568
-     *                              loaded.
569
-     * @return array
570
-     * @throws EE_Error
571
-     * @throws EE_Error
572
-     */
573
-    private function _set_caffeinated($installed_refs)
574
-    {
575
-
576
-        // first let's check if there IS a caffeinated folder. If there is not then lets get out.
577
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) {
578
-            return $installed_refs;
579
-        }
580
-        $this->_define_caffeinated_constants();
581
-        $exclude = ['tickets'];
582
-        // okay let's setup an "New" pages first (we'll return installed refs later)
583
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
584
-        if ($new_admin_screens) {
585
-            foreach ($new_admin_screens as $admin_screen) {
586
-                // files and anything in the exclude array need not apply
587
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
588
-                    // these folders represent the different NEW EE admin pages
589
-                    $installed_refs[ basename($admin_screen) ] = $admin_screen;
590
-                    // set autoloaders for our admin page classes based on included path information
591
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
592
-                }
593
-            }
594
-        }
595
-        // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
596
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
597
-        if ($extends) {
598
-            foreach ($extends as $extend) {
599
-                if (is_dir($extend)) {
600
-                    $extend_ref = basename($extend);
601
-                    // now let's make sure there is a file that matches the expected format
602
-                    $filename                                                = str_replace(
603
-                        ' ',
604
-                        '_',
605
-                        ucwords(
606
-                            str_replace(
607
-                                '_',
608
-                                ' ',
609
-                                $extend_ref
610
-                            )
611
-                        )
612
-                    );
613
-                    $filename                                                = 'Extend_' . $filename . '_Admin_Page';
614
-                    $this->_caffeinated_extends[ $extend_ref ]['path']       = str_replace(
615
-                        ['\\', '/'],
616
-                        '/',
617
-                        EE_CORE_CAF_ADMIN
618
-                        . 'extend/'
619
-                        . $extend_ref
620
-                        . '/'
621
-                        . $filename
622
-                        . '.core.php'
623
-                    );
624
-                    $this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename;
625
-                    // set autoloaders for our admin page classes based on included path information
626
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
627
-                }
628
-            }
629
-        }
630
-        // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
631
-        $ee_admin_hooks = [];
632
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
633
-        if ($hooks) {
634
-            foreach ($hooks as $hook) {
635
-                if (is_readable($hook)) {
636
-                    require_once $hook;
637
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
638
-                    $classname = str_replace('.class.php', '', $classname);
639
-                    if (class_exists($classname)) {
640
-                        $ee_admin_hooks[] = $this->loader->getShared($classname);
641
-                    }
642
-                }
643
-            }
644
-        }
645
-        apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
646
-        return $installed_refs;
647
-    }
648
-
649
-
650
-    /**
651
-     * Utility method for sorting the _menu_maps (callback for usort php function)
652
-     *
653
-     * @param EE_Admin_Page_Menu_Map $a menu_map object
654
-     * @param EE_Admin_Page_Menu_Map $b being compared to
655
-     * @return int    sort order
656
-     * @since  4.4.0
657
-     */
658
-    private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
659
-    {
660
-        if ($a->menu_order == $b->menu_order) {
661
-            return 0;
662
-        }
663
-        return ($a->menu_order < $b->menu_order) ? -1 : 1;
664
-    }
665
-
666
-
667
-    /**
668
-     * _default_header_link
669
-     * This is just a dummy method to use with header submenu items
670
-     *
671
-     * @return bool false
672
-     */
673
-    public function _default_header_link()
674
-    {
675
-        return false;
676
-    }
16
+	/**
17
+	 * _installed_pages
18
+	 * objects for page_init objects detected and loaded
19
+	 *
20
+	 * @access private
21
+	 * @var EE_Admin_Page_Init[]
22
+	 */
23
+	private $_installed_pages = [];
24
+
25
+
26
+	/**
27
+	 * this is used to hold the registry of menu slugs for all the installed admin pages
28
+	 *
29
+	 * @var array
30
+	 */
31
+	private $_menu_slugs = [];
32
+
33
+
34
+	/**
35
+	 * _caffeinated_extends
36
+	 * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
37
+	 * pieces needed to do so).  This property is defined in the _set_caffeinated method.
38
+	 *
39
+	 * @var array
40
+	 */
41
+	private $_caffeinated_extends = [];
42
+
43
+	/**
44
+	 * _prepped_menu_maps
45
+	 * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
46
+	 *
47
+	 * @since  4.4.0
48
+	 * @var EE_Admin_Page_Menu_Map[]
49
+	 */
50
+	private $_prepped_menu_maps = [];
51
+
52
+
53
+	/**
54
+	 * _admin_menu_groups
55
+	 * array that holds the group headings and details for
56
+	 *
57
+	 * @access private
58
+	 * @var array
59
+	 */
60
+	private $_admin_menu_groups = [];
61
+
62
+
63
+	/**
64
+	 * This property will hold the hook file for setting up the filter that does all the connections between admin
65
+	 * pages.
66
+	 *
67
+	 * @var string
68
+	 */
69
+	public $hook_file;
70
+
71
+	/**
72
+	 * @var LoaderInterface
73
+	 */
74
+	protected $loader;
75
+
76
+
77
+	/**
78
+	 * @throws EE_Error
79
+	 */
80
+	public function __construct(LoaderInterface $loader)
81
+	{
82
+		$this->loader = $loader;
83
+		// define the default "groups" for the admin_pages
84
+		$this->_set_menu_groups();
85
+		// let's do a scan and see what installed pages we have
86
+		$this->_get_installed_pages();
87
+		// set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
88
+		add_action('admin_menu', [$this, 'set_menus']);
89
+		add_action('network_admin_menu', [$this, 'set_network_menus']);
90
+	}
91
+
92
+
93
+	/**
94
+	 * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
95
+	 * files in the caffeinated folder.
96
+	 *
97
+	 * @access private
98
+	 * @return void
99
+	 */
100
+	private function _define_caffeinated_constants()
101
+	{
102
+		if (! defined('EE_CORE_CAF_ADMIN')) {
103
+			define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
104
+			define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
105
+			define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
106
+			define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
107
+			define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
108
+			define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
109
+		}
110
+	}
111
+
112
+
113
+	/**
114
+	 * _set_menu_groups
115
+	 * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
116
+	 *
117
+	 * @access private
118
+	 * @return void
119
+	 */
120
+	private function _set_menu_groups()
121
+	{
122
+		// set array of EE_Admin_Page_Menu_Group objects
123
+		$this->_admin_menu_groups = apply_filters(
124
+			'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
125
+			[
126
+				'main'       => $this->loader->getNew(
127
+					'EE_Admin_Page_Menu_Group',
128
+					[
129
+						'menu_label'   => esc_html__('Main', 'event_espresso'),
130
+						'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
131
+						'menu_slug'    => 'main',
132
+						'capability'   => 'ee_read_ee',
133
+						'menu_order'   => 0,
134
+						'parent_slug'  => 'espresso_events',
135
+					]
136
+				),
137
+				'management' => $this->loader->getNew(
138
+					'EE_Admin_Page_Menu_Group',
139
+					[
140
+						'menu_label'   => esc_html__('Management', 'event_espresso'),
141
+						'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
142
+						'menu_slug'    => 'management',
143
+						'capability'   => 'ee_read_ee',
144
+						'menu_order'   => 10,
145
+						'parent_slug'  => 'espresso_events',
146
+					]
147
+				),
148
+				'settings'   => $this->loader->getNew(
149
+					'EE_Admin_Page_Menu_Group',
150
+					[
151
+						'menu_label'   => esc_html__('Settings', 'event_espresso'),
152
+						'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
153
+						'menu_slug'    => 'settings',
154
+						'capability'   => 'ee_read_ee',
155
+						'menu_order'   => 30,
156
+						'parent_slug'  => 'espresso_events',
157
+					]
158
+				),
159
+				'templates'  => $this->loader->getNew(
160
+					'EE_Admin_Page_Menu_Group',
161
+					[
162
+						'menu_label'   => esc_html__('Templates', 'event_espresso'),
163
+						'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
164
+						'menu_slug'    => 'templates',
165
+						'capability'   => 'ee_read_ee',
166
+						'menu_order'   => 40,
167
+						'parent_slug'  => 'espresso_events',
168
+					]
169
+				),
170
+				'extras'     => $this->loader->getNew(
171
+					'EE_Admin_Page_Menu_Group',
172
+					[
173
+						'menu_label'              => esc_html__('Extras', 'event_espresso'),
174
+						'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
175
+						'menu_slug'               => 'extras',
176
+						'capability'              => 'ee_read_ee',
177
+						'menu_order'              => 50,
178
+						'parent_slug'             => 'espresso_events',
179
+						'maintenance_mode_parent' => 'espresso_maintenance_settings',
180
+					]
181
+				),
182
+				'tools'      => $this->loader->getNew(
183
+					'EE_Admin_Page_Menu_Group',
184
+					[
185
+						'menu_label'   => esc_html__('Tools', 'event_espresso'),
186
+						'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
187
+						'menu_slug'    => 'tools',
188
+						'capability'   => 'ee_read_ee',
189
+						'menu_order'   => 60,
190
+						'parent_slug'  => 'espresso_events',
191
+					]
192
+				),
193
+				'addons'     => $this->loader->getNew(
194
+					'EE_Admin_Page_Menu_Group',
195
+					[
196
+						'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
197
+						'menu_label'   => esc_html__('Add-ons', 'event_espresso'),
198
+						'menu_slug'    => 'addons',
199
+						'capability'   => 'ee_read_ee',
200
+						'menu_order'   => 20,
201
+						'parent_slug'  => 'espresso_events',
202
+					]
203
+				),
204
+			]
205
+		);
206
+	}
207
+
208
+
209
+	/**
210
+	 * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
211
+	 * slug.  The other utility with this function is it validates that all the groups are instances of
212
+	 * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
213
+	 *
214
+	 * @return EE_Admin_Page_Menu_Group[]
215
+	 * @throws EE_Error
216
+	 * @since  4.4.0
217
+	 */
218
+	private function _rearrange_menu_groups()
219
+	{
220
+		$groups = [];
221
+		// first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
222
+		usort($this->_admin_menu_groups, [$this, '_sort_menu_maps']);
223
+		foreach ($this->_admin_menu_groups as $group) {
224
+			if (! $group instanceof EE_Admin_Page_Menu_Group) {
225
+				throw new EE_Error(
226
+					sprintf(
227
+						esc_html__(
228
+							'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
229
+							'event_espresso'
230
+						),
231
+						print_r($group, true)
232
+					)
233
+				);
234
+			}
235
+			$groups[ $group->menu_slug ] = $group;
236
+		}
237
+		return $groups;
238
+	}
239
+
240
+
241
+	/**
242
+	 * _get_installed_pages
243
+	 * This just gets the list of installed EE_Admin_pages.
244
+	 *
245
+	 * @access private
246
+	 * @return void
247
+	 * @throws EE_Error
248
+	 */
249
+	private function _get_installed_pages()
250
+	{
251
+		$installed_refs = [];
252
+		$exclude        = ['assets', 'templates'];
253
+		// grab everything in the  admin core directory
254
+		$admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
255
+		if ($admin_screens) {
256
+			foreach ($admin_screens as $admin_screen) {
257
+				// files and anything in the exclude array need not apply
258
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
259
+					// these folders represent the different EE admin pages
260
+					$installed_refs[ basename($admin_screen) ] = $admin_screen;
261
+				}
262
+			}
263
+		}
264
+		if (empty($installed_refs)) {
265
+			$error_msg[] = esc_html__(
266
+				'There are no EE_Admin pages detected, it looks like EE did not install properly',
267
+				'event_espresso'
268
+			);
269
+			$error_msg[] = $error_msg[0] . "\r\n"
270
+						   . sprintf(
271
+							   esc_html__(
272
+								   'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
273
+								   'event_espresso'
274
+							   ),
275
+							   EE_ADMIN_PAGES
276
+						   );
277
+			throw new EE_Error(implode('||', $error_msg));
278
+		}
279
+		// this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
280
+		$installed_refs = $this->_set_caffeinated($installed_refs);
281
+		// allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
282
+		$installed_refs             = apply_filters(
283
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
284
+			$installed_refs
285
+		);
286
+		$this->_caffeinated_extends = apply_filters(
287
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
288
+			$this->_caffeinated_extends
289
+		);
290
+		// loop through admin pages and setup the $_installed_pages array.
291
+		$hooks_ref = [];
292
+		foreach ($installed_refs as $page => $path) {
293
+			// set autoloaders for our admin page classes based on included path information
294
+			EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
295
+			// build list of installed pages
296
+			$admin_init_page = $this->_load_admin_page($page);
297
+			// verify returned object
298
+			if ($admin_init_page instanceof EE_Admin_Page_Init) {
299
+				$this->_installed_pages[ $page ] = $admin_init_page;
300
+				if (! $admin_init_page->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
301
+					continue;
302
+				}
303
+				// skip if in full maintenance mode and maintenance_mode_parent is set
304
+				$maintenance_mode_parent = $admin_init_page->get_menu_map()->maintenance_mode_parent;
305
+				if (
306
+					empty($maintenance_mode_parent)
307
+					&& EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
308
+				) {
309
+					unset($installed_refs[ $page ]);
310
+					continue;
311
+				}
312
+				$menu_slug                       = $admin_init_page->get_menu_map()->menu_slug;
313
+				$this->_menu_slugs[ $menu_slug ] = $page;
314
+				// flag for register hooks on extended pages b/c extended pages use the default INIT.
315
+				$extend = false;
316
+				// now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
317
+				if (isset($this->_caffeinated_extends[ $page ])) {
318
+					$admin_page_name = $admin_init_page->get_admin_page_name();
319
+					$caf_path        = $this->_caffeinated_extends[ $page ]['path'];
320
+					$caf_admin_page  = $this->_caffeinated_extends[ $page ]['admin_page'];
321
+					add_filter(
322
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
323
+						function ($path_to_file) use ($caf_path) {
324
+							return $caf_path;
325
+						}
326
+					);
327
+					add_filter(
328
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
329
+						function ($admin_page) use ($caf_admin_page) {
330
+							return $caf_admin_page;
331
+						}
332
+					);
333
+					$extend = true;
334
+				}
335
+				// let's do the registered hooks
336
+				$extended_hooks = $admin_init_page->register_hooks($extend);
337
+				$hooks_ref      = array_merge($hooks_ref, $extended_hooks);
338
+			}
339
+		}
340
+		// the hooks_ref is all the pages where we have $extended _Hooks files
341
+		// that will extend a class in a different folder.
342
+		// So we want to make sure we load the file for the parent.
343
+		// first make sure we've got unique values
344
+		$hooks_ref = array_unique($hooks_ref);
345
+		// now let's loop and require!
346
+		foreach ($hooks_ref as $path) {
347
+			require_once($path);
348
+		}
349
+		// make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
350
+		global $ee_menu_slugs;
351
+		$ee_menu_slugs = $this->_menu_slugs;
352
+		// we need to loop again to run any early code
353
+		foreach ($installed_refs as $page => $path) {
354
+			$this->_installed_pages[ $page ]->do_initial_loads();
355
+		}
356
+		do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
357
+	}
358
+
359
+
360
+	/**
361
+	 * get_admin_page_object
362
+	 *
363
+	 * @param string $page_slug
364
+	 * @return EE_Admin_Page
365
+	 */
366
+	public function get_admin_page_object($page_slug = '')
367
+	{
368
+		if (isset($this->_installed_pages[ $page_slug ])) {
369
+			return $this->_installed_pages[ $page_slug ]->loaded_page_object();
370
+		}
371
+		return null;
372
+	}
373
+
374
+
375
+	/**
376
+	 * _get_classname_for_admin_page
377
+	 * generates an "Admin Page" class based on the directory  name
378
+	 *
379
+	 * @param $dir_name
380
+	 * @return string
381
+	 */
382
+	private function _get_classname_for_admin_page($dir_name = '')
383
+	{
384
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
385
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
386
+	}
387
+
388
+
389
+	/**
390
+	 * _get_classname_for_admin_init_page
391
+	 * generates an "Admin Page Init" class based on the directory  name
392
+	 *
393
+	 * @param $dir_name
394
+	 * @return string
395
+	 */
396
+	private function _get_classname_for_admin_init_page($dir_name = '')
397
+	{
398
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
399
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
400
+	}
401
+
402
+
403
+	/**
404
+	 * _load_admin_page
405
+	 * Loads and instantiates page_init object for a single EE_admin page.
406
+	 *
407
+	 * @param string $page page_reference
408
+	 * @return object|bool  return page object if valid, bool false if not.
409
+	 * @throws EE_Error
410
+	 */
411
+	private function _load_admin_page($page = '')
412
+	{
413
+		$class_name = $this->_get_classname_for_admin_init_page($page);
414
+		if (class_exists($class_name)) {
415
+			return $this->loader->getShared($class_name);
416
+		}
417
+		$error_msg = sprintf(
418
+			esc_html__('Something went wrong with loading the %s admin page.', 'event_espresso'),
419
+			$page
420
+		);
421
+		$error_msg .= '||'; // separates public from developer messages
422
+		$error_msg .= "\r\n";
423
+		$error_msg .= sprintf(
424
+			esc_html__('There is no Init class in place for the %s admin page.', 'event_espresso'),
425
+			$page
426
+		);
427
+		$error_msg .= '<br />';
428
+		$error_msg .= sprintf(
429
+			esc_html__(
430
+				'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
431
+				'event_espresso'
432
+			),
433
+			'<strong>' . $class_name . '</strong>'
434
+		);
435
+		throw new EE_Error($error_msg);
436
+	}
437
+
438
+
439
+	/**
440
+	 * set_menus
441
+	 * This method sets up the menus for EE Admin Pages
442
+	 *
443
+	 * @access private
444
+	 * @return void
445
+	 * @throws EE_Error
446
+	 */
447
+	public function set_menus($network_admin = false)
448
+	{
449
+		// prep the menu pages (sort, group.)
450
+		$this->_prep_pages();
451
+		foreach ($this->_prepped_menu_maps as $menu_map) {
452
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
453
+				$menu_map->add_menu_page($network_admin);
454
+			}
455
+		}
456
+	}
457
+
458
+
459
+	/**
460
+	 * set_network_menus
461
+	 * This method sets up the menus for network EE Admin Pages.
462
+	 * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
463
+	 * are only added to the menu map if they are intended for the admin menu
464
+	 *
465
+	 * @return void
466
+	 * @throws EE_Error
467
+	 */
468
+	public function set_network_menus()
469
+	{
470
+		$this->set_menus(true);
471
+	}
472
+
473
+
474
+	/**
475
+	 * _prep_pages
476
+	 * sets the _prepped_menu_maps property
477
+	 *
478
+	 * @access private
479
+	 * @return void
480
+	 * @throws EE_Error
481
+	 */
482
+	private function _prep_pages()
483
+	{
484
+		$pages_array = [];
485
+		// rearrange _admin_menu_groups to be indexed by group slug.
486
+		$menu_groups = $this->_rearrange_menu_groups();
487
+		foreach ($this->_installed_pages as $page) {
488
+			if ($page instanceof EE_Admin_page_Init) {
489
+				$page_map = $page->get_menu_map();
490
+				// if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
491
+				if (is_array($page_map) || empty($page_map)) {
492
+					new PersistentAdminNotice(
493
+						'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
494
+						sprintf(
495
+							esc_html__(
496
+								'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
497
+								'event_espresso'
498
+							),
499
+							$page->label
500
+						)
501
+					);
502
+					continue;
503
+				}
504
+				// if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
505
+				if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
506
+					throw new EE_Error(
507
+						sprintf(
508
+							esc_html__(
509
+								'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
510
+								'event_espresso'
511
+							),
512
+							$page->label,
513
+							$page_map
514
+						)
515
+					);
516
+				}
517
+				// use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
518
+				if (
519
+					empty($page_map->maintenance_mode_parent)
520
+					&& EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance
521
+				) {
522
+					continue;
523
+				}
524
+				// assign to group (remember $page_map has the admin page stored in it).
525
+				$pages_array[ $page_map->menu_group ][] = $page_map;
526
+			}
527
+		}
528
+		if (empty($pages_array)) {
529
+			throw new EE_Error(esc_html__('Something went wrong when prepping the admin pages', 'event_espresso'));
530
+		}
531
+		// let's sort the groups, make sure it's a valid group, add header (if to show).
532
+		foreach ($pages_array as $group => $menu_maps) {
533
+			// valid_group?
534
+			if (! array_key_exists($group, $menu_groups)) {
535
+				continue;
536
+			}
537
+			// sort pages.
538
+			usort($menu_maps, [$this, '_sort_menu_maps']);
539
+			// prepend header
540
+			array_unshift($menu_maps, $menu_groups[ $group ]);
541
+			// reset $pages_array with prepped data
542
+			$pages_array[ $group ] = $menu_maps;
543
+		}
544
+		// now let's setup the _prepped_menu_maps property
545
+		foreach ($menu_groups as $group => $group_objs) {
546
+			if (isset($pages_array[ $group ])) {
547
+				$this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[ $group ]);
548
+			}
549
+		}/**/
550
+	}
551
+
552
+
553
+	/**
554
+	 * This method is the "workhorse" for detecting and setting up caffeinated functionality.
555
+	 * In this method there are three checks being done:
556
+	 * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
557
+	 * array) etc.  (new page sets are found in caffeinated/new/{page})
558
+	 * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
559
+	 * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
560
+	 * Extend_Events_Admin_Page extends Events_Admin_Page.
561
+	 * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
562
+	 * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
563
+	 * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
564
+	 * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
565
+	 * admin_pages)
566
+	 *
567
+	 * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
568
+	 *                              loaded.
569
+	 * @return array
570
+	 * @throws EE_Error
571
+	 * @throws EE_Error
572
+	 */
573
+	private function _set_caffeinated($installed_refs)
574
+	{
575
+
576
+		// first let's check if there IS a caffeinated folder. If there is not then lets get out.
577
+		if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) {
578
+			return $installed_refs;
579
+		}
580
+		$this->_define_caffeinated_constants();
581
+		$exclude = ['tickets'];
582
+		// okay let's setup an "New" pages first (we'll return installed refs later)
583
+		$new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
584
+		if ($new_admin_screens) {
585
+			foreach ($new_admin_screens as $admin_screen) {
586
+				// files and anything in the exclude array need not apply
587
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
588
+					// these folders represent the different NEW EE admin pages
589
+					$installed_refs[ basename($admin_screen) ] = $admin_screen;
590
+					// set autoloaders for our admin page classes based on included path information
591
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
592
+				}
593
+			}
594
+		}
595
+		// let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
596
+		$extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
597
+		if ($extends) {
598
+			foreach ($extends as $extend) {
599
+				if (is_dir($extend)) {
600
+					$extend_ref = basename($extend);
601
+					// now let's make sure there is a file that matches the expected format
602
+					$filename                                                = str_replace(
603
+						' ',
604
+						'_',
605
+						ucwords(
606
+							str_replace(
607
+								'_',
608
+								' ',
609
+								$extend_ref
610
+							)
611
+						)
612
+					);
613
+					$filename                                                = 'Extend_' . $filename . '_Admin_Page';
614
+					$this->_caffeinated_extends[ $extend_ref ]['path']       = str_replace(
615
+						['\\', '/'],
616
+						'/',
617
+						EE_CORE_CAF_ADMIN
618
+						. 'extend/'
619
+						. $extend_ref
620
+						. '/'
621
+						. $filename
622
+						. '.core.php'
623
+					);
624
+					$this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename;
625
+					// set autoloaders for our admin page classes based on included path information
626
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
627
+				}
628
+			}
629
+		}
630
+		// let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
631
+		$ee_admin_hooks = [];
632
+		$hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
633
+		if ($hooks) {
634
+			foreach ($hooks as $hook) {
635
+				if (is_readable($hook)) {
636
+					require_once $hook;
637
+					$classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
638
+					$classname = str_replace('.class.php', '', $classname);
639
+					if (class_exists($classname)) {
640
+						$ee_admin_hooks[] = $this->loader->getShared($classname);
641
+					}
642
+				}
643
+			}
644
+		}
645
+		apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
646
+		return $installed_refs;
647
+	}
648
+
649
+
650
+	/**
651
+	 * Utility method for sorting the _menu_maps (callback for usort php function)
652
+	 *
653
+	 * @param EE_Admin_Page_Menu_Map $a menu_map object
654
+	 * @param EE_Admin_Page_Menu_Map $b being compared to
655
+	 * @return int    sort order
656
+	 * @since  4.4.0
657
+	 */
658
+	private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
659
+	{
660
+		if ($a->menu_order == $b->menu_order) {
661
+			return 0;
662
+		}
663
+		return ($a->menu_order < $b->menu_order) ? -1 : 1;
664
+	}
665
+
666
+
667
+	/**
668
+	 * _default_header_link
669
+	 * This is just a dummy method to use with header submenu items
670
+	 *
671
+	 * @return bool false
672
+	 */
673
+	public function _default_header_link()
674
+	{
675
+		return false;
676
+	}
677 677
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Menu_Map.core.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
         // verify that required keys are present in the incoming array.
146 146
         $missing = array_diff((array) $required, array_keys((array) $menu_args));
147 147
 
148
-        if (! empty($missing)) {
148
+        if ( ! empty($missing)) {
149 149
             throw new EE_Error(
150 150
                 sprintf(
151 151
                     esc_html__(
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
                     $value = (string) $value;
185 185
                     break;
186 186
             }
187
-            if (! EEH_Class_Tools::has_property($this, $prop)) {
187
+            if ( ! EEH_Class_Tools::has_property($this, $prop)) {
188 188
                 throw new EE_Error(
189 189
                     sprintf(
190 190
                         esc_html__(
@@ -201,7 +201,7 @@  discard block
 block discarded – undo
201 201
 
202 202
         // filter capabilities (both static and dynamic)
203 203
         $this->capability = apply_filters('FHEE_management_capability', $this->capability, null);
204
-        $this->capability = apply_filters('FHEE_' . $this->menu_slug . '_capability', $this->capability, null);
204
+        $this->capability = apply_filters('FHEE_'.$this->menu_slug.'_capability', $this->capability, null);
205 205
 
206 206
         // Might need to change parent slug depending on maintenance mode.
207 207
         if (
@@ -247,7 +247,7 @@  discard block
 block discarded – undo
247 247
                  [self::BLOG_AND_NETWORK_ADMIN, self::NETWORK_ADMIN_ONLY],
248 248
                  true
249 249
              ))
250
-            || (! $network_admin
250
+            || ( ! $network_admin
251 251
                 && in_array(
252 252
                     $show_on_menu_int,
253 253
                     [self::BLOG_AND_NETWORK_ADMIN, self::BLOG_ADMIN_ONLY],
@@ -259,7 +259,7 @@  discard block
 block discarded – undo
259 259
             $wp_page_slug = '';
260 260
         }
261 261
 
262
-        if (! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
262
+        if ( ! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
263 263
             try {
264 264
                 $this->admin_init_page->set_page_dependencies($wp_page_slug);
265 265
             } catch (EE_Error $e) {
Please login to merge, or discard this patch.
Indentation   +255 added lines, -255 removed lines patch added patch discarded remove patch
@@ -9,260 +9,260 @@
 block discarded – undo
9 9
  */
10 10
 abstract class EE_Admin_Page_Menu_Map
11 11
 {
12
-    /**
13
-     * The title for the menu page. (the page the menu links to)
14
-     *
15
-     * @since  4.4.0
16
-     * @var string
17
-     */
18
-    public $title;
19
-
12
+	/**
13
+	 * The title for the menu page. (the page the menu links to)
14
+	 *
15
+	 * @since  4.4.0
16
+	 * @var string
17
+	 */
18
+	public $title;
19
+
20 20
 
21
-    /**
22
-     * The label for the menu item. (What shows up in the actual menu).
23
-     *
24
-     * @since 4.4.0
25
-     * @var string
26
-     */
27
-    public $menu_label;
28
-
29
-
30
-    /**
31
-     * What menu item is the parent of this menu item.
32
-     *
33
-     * @since 4.4.0
34
-     * @var string
35
-     */
36
-    public $parent_slug;
37
-
38
-
39
-    /**
40
-     * What capability is required to access this page.
41
-     *
42
-     * @since 4.4.0
43
-     * @var string
44
-     */
45
-    public $capability = 'administrator';
46
-
47
-
48
-    /**
49
-     * What slug should be used to reference this menu item.
50
-     *
51
-     * @since 4.4.0
52
-     * @var string
53
-     */
54
-    public $menu_slug;
55
-
56
-
57
-    /**
58
-     * The callback for displaying the page that the menu references.
59
-     *
60
-     * @since 4.4.0
61
-     * @var string
62
-     */
63
-    public $menu_callback;
64
-
65
-
66
-    /**
67
-     * The EE_Admin_Page_Init attached to this map.
68
-     *
69
-     * @var EE_Admin_Page_Init
70
-     */
71
-    public $admin_init_page;
72
-
73
-
74
-    /**
75
-     * The EE specific group this menu item belongs in (group slug).
76
-     *
77
-     * @since 4.4.0
78
-     * @var string
79
-     */
80
-    public $menu_group;
81
-
82
-
83
-    /**
84
-     * What order this item should be in the menu.
85
-     *
86
-     * @since 4.4.0
87
-     * @var int
88
-     */
89
-    public $menu_order;
90
-
91
-
92
-    const NONE                   = 0;
93
-
94
-    const BLOG_ADMIN_ONLY        = 1;
95
-
96
-    const BLOG_AND_NETWORK_ADMIN = 2;
97
-
98
-    const NETWORK_ADMIN_ONLY     = 3;
99
-
100
-
101
-    /**
102
-     * Whether this item is displayed in the menu or not.
103
-     * Sometimes an EE Admin Page needs to register itself but is not accessible via the WordPress
104
-     * admin menu.
105
-     *
106
-     * @since 4.4.0
107
-     * @var int
108
-     */
109
-    public $show_on_menu = self::BLOG_ADMIN_ONLY;
110
-
111
-
112
-    /**
113
-     * Menu maps can define a parent slug that gets used instead of the main parent slug for the menu when
114
-     * EE_Maintenance_Mode::level_2_complete_maintenance is active.
115
-     *
116
-     * @var bool
117
-     */
118
-    public $maintenance_mode_parent = '';
119
-
120
-
121
-    /**
122
-     * @param array $menu_args            An array of arguments used to setup the menu
123
-     *                                    properties on construct.
124
-     * @param array $required             An array of keys that should be in the $menu_args, this
125
-     *                                    is used to validate that the items that should be defined
126
-     *                                    are present.
127
-     * @return void
128
-     * @throws EE_Error
129
-     * @since 4.4.0
130
-     *
131
-     */
132
-    public function __construct($menu_args, $required)
133
-    {
134
-        // filter all args before processing so plugins can manipulate various settings for menus.
135
-        $menu_args = apply_filters(
136
-            'FHEE__EE_Admin_Page_Menu_Map__construct__menu_args',
137
-            $menu_args,
138
-            $required,
139
-            get_class($this)
140
-        );
141
-
142
-
143
-        // verify that required keys are present in the incoming array.
144
-        $missing = array_diff((array) $required, array_keys((array) $menu_args));
145
-
146
-        if (! empty($missing)) {
147
-            throw new EE_Error(
148
-                sprintf(
149
-                    esc_html__(
150
-                        '%s is missing some expected keys in the argument array.  The following keys are missing: %s',
151
-                        'event_espresso'
152
-                    ),
153
-                    get_class($this),
154
-                    implode(', ', $missing)
155
-                )
156
-            );
157
-        }
158
-
159
-        // made it here okay, so let's set the properties!
160
-        foreach ($menu_args as $prop => $value) {
161
-            switch ($prop) {
162
-                case 'show_on_menu':
163
-                    $value = (int) $value;
164
-                    break;
165
-                case 'admin_init_page':
166
-                    if (in_array('admin_init_page', $required) && ! $value instanceof EE_Admin_Page_Init) {
167
-                        throw new EE_Error(
168
-                            sprintf(
169
-                                esc_html__(
170
-                                    'The value for the "admin_init_page" argument must be an instance of an EE_Admin_Page_Init object.  Instead %s was given as the value.',
171
-                                    'event_espresso'
172
-                                ),
173
-                                print_r($value, true)
174
-                            )
175
-                        );
176
-                    }
177
-                    break;
178
-                case 'menu_callback':
179
-                    break;
180
-
181
-                default:
182
-                    $value = (string) $value;
183
-                    break;
184
-            }
185
-            if (! EEH_Class_Tools::has_property($this, $prop)) {
186
-                throw new EE_Error(
187
-                    sprintf(
188
-                        esc_html__(
189
-                            'The $menu_args coming into %s has a index key (%s) representing a property that is not defined by the class.  Perhaps there is a typo?',
190
-                            'event_espresso'
191
-                        ),
192
-                        get_class($this),
193
-                        $prop
194
-                    )
195
-                );
196
-            }
197
-            $this->{$prop} = $value;
198
-        }
199
-
200
-        // filter capabilities (both static and dynamic)
201
-        $this->capability = apply_filters('FHEE_management_capability', $this->capability, null);
202
-        $this->capability = apply_filters('FHEE_' . $this->menu_slug . '_capability', $this->capability, null);
203
-
204
-        // Might need to change parent slug depending on maintenance mode.
205
-        if (
206
-            ! empty($this->maintenance_mode_parent)
207
-            && EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance
208
-        ) {
209
-            $this->parent_slug = $this->maintenance_mode_parent;
210
-        }
211
-
212
-        // if empty menu_callback let's set default (but only if we have admin page init object)
213
-        if (empty($this->menu_callback) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
214
-            $this->menu_callback = [$this->admin_init_page, 'initialize_admin_page'];
215
-        }
216
-    }
217
-
218
-
219
-    /**
220
-     * This method should define how the menu page gets added for this particular item
221
-     * and go ahead and define it.  Note that child classes MUST also return the result of
222
-     * the function used to register the WordPress admin page (the wp_page_slug string)
223
-     *
224
-     * @return string wp_page_slug.
225
-     * @since  4.4.0
226
-     */
227
-    abstract protected function _add_menu_page();
228
-
229
-
230
-    /**
231
-     * Called by client code to use this menu map for registering a WordPress admin page
232
-     *
233
-     * @param boolean $network_admin whether this is being added to the network admin page or not
234
-     * @throws EE_Error
235
-     * @throws ReflectionException
236
-     * @since  4.4.0
237
-     */
238
-    public function add_menu_page($network_admin = false)
239
-    {
240
-        $show_on_menu_int = (int) $this->show_on_menu;
241
-        if (
242
-            ($network_admin
243
-             && in_array(
244
-                 $show_on_menu_int,
245
-                 [self::BLOG_AND_NETWORK_ADMIN, self::NETWORK_ADMIN_ONLY],
246
-                 true
247
-             ))
248
-            || (! $network_admin
249
-                && in_array(
250
-                    $show_on_menu_int,
251
-                    [self::BLOG_AND_NETWORK_ADMIN, self::BLOG_ADMIN_ONLY],
252
-                    true
253
-                ))
254
-        ) {
255
-            $wp_page_slug = $this->_add_menu_page();
256
-        } else {
257
-            $wp_page_slug = '';
258
-        }
259
-
260
-        if (! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
261
-            try {
262
-                $this->admin_init_page->set_page_dependencies($wp_page_slug);
263
-            } catch (EE_Error $e) {
264
-                $e->get_error();
265
-            }
266
-        }
267
-    }
21
+	/**
22
+	 * The label for the menu item. (What shows up in the actual menu).
23
+	 *
24
+	 * @since 4.4.0
25
+	 * @var string
26
+	 */
27
+	public $menu_label;
28
+
29
+
30
+	/**
31
+	 * What menu item is the parent of this menu item.
32
+	 *
33
+	 * @since 4.4.0
34
+	 * @var string
35
+	 */
36
+	public $parent_slug;
37
+
38
+
39
+	/**
40
+	 * What capability is required to access this page.
41
+	 *
42
+	 * @since 4.4.0
43
+	 * @var string
44
+	 */
45
+	public $capability = 'administrator';
46
+
47
+
48
+	/**
49
+	 * What slug should be used to reference this menu item.
50
+	 *
51
+	 * @since 4.4.0
52
+	 * @var string
53
+	 */
54
+	public $menu_slug;
55
+
56
+
57
+	/**
58
+	 * The callback for displaying the page that the menu references.
59
+	 *
60
+	 * @since 4.4.0
61
+	 * @var string
62
+	 */
63
+	public $menu_callback;
64
+
65
+
66
+	/**
67
+	 * The EE_Admin_Page_Init attached to this map.
68
+	 *
69
+	 * @var EE_Admin_Page_Init
70
+	 */
71
+	public $admin_init_page;
72
+
73
+
74
+	/**
75
+	 * The EE specific group this menu item belongs in (group slug).
76
+	 *
77
+	 * @since 4.4.0
78
+	 * @var string
79
+	 */
80
+	public $menu_group;
81
+
82
+
83
+	/**
84
+	 * What order this item should be in the menu.
85
+	 *
86
+	 * @since 4.4.0
87
+	 * @var int
88
+	 */
89
+	public $menu_order;
90
+
91
+
92
+	const NONE                   = 0;
93
+
94
+	const BLOG_ADMIN_ONLY        = 1;
95
+
96
+	const BLOG_AND_NETWORK_ADMIN = 2;
97
+
98
+	const NETWORK_ADMIN_ONLY     = 3;
99
+
100
+
101
+	/**
102
+	 * Whether this item is displayed in the menu or not.
103
+	 * Sometimes an EE Admin Page needs to register itself but is not accessible via the WordPress
104
+	 * admin menu.
105
+	 *
106
+	 * @since 4.4.0
107
+	 * @var int
108
+	 */
109
+	public $show_on_menu = self::BLOG_ADMIN_ONLY;
110
+
111
+
112
+	/**
113
+	 * Menu maps can define a parent slug that gets used instead of the main parent slug for the menu when
114
+	 * EE_Maintenance_Mode::level_2_complete_maintenance is active.
115
+	 *
116
+	 * @var bool
117
+	 */
118
+	public $maintenance_mode_parent = '';
119
+
120
+
121
+	/**
122
+	 * @param array $menu_args            An array of arguments used to setup the menu
123
+	 *                                    properties on construct.
124
+	 * @param array $required             An array of keys that should be in the $menu_args, this
125
+	 *                                    is used to validate that the items that should be defined
126
+	 *                                    are present.
127
+	 * @return void
128
+	 * @throws EE_Error
129
+	 * @since 4.4.0
130
+	 *
131
+	 */
132
+	public function __construct($menu_args, $required)
133
+	{
134
+		// filter all args before processing so plugins can manipulate various settings for menus.
135
+		$menu_args = apply_filters(
136
+			'FHEE__EE_Admin_Page_Menu_Map__construct__menu_args',
137
+			$menu_args,
138
+			$required,
139
+			get_class($this)
140
+		);
141
+
142
+
143
+		// verify that required keys are present in the incoming array.
144
+		$missing = array_diff((array) $required, array_keys((array) $menu_args));
145
+
146
+		if (! empty($missing)) {
147
+			throw new EE_Error(
148
+				sprintf(
149
+					esc_html__(
150
+						'%s is missing some expected keys in the argument array.  The following keys are missing: %s',
151
+						'event_espresso'
152
+					),
153
+					get_class($this),
154
+					implode(', ', $missing)
155
+				)
156
+			);
157
+		}
158
+
159
+		// made it here okay, so let's set the properties!
160
+		foreach ($menu_args as $prop => $value) {
161
+			switch ($prop) {
162
+				case 'show_on_menu':
163
+					$value = (int) $value;
164
+					break;
165
+				case 'admin_init_page':
166
+					if (in_array('admin_init_page', $required) && ! $value instanceof EE_Admin_Page_Init) {
167
+						throw new EE_Error(
168
+							sprintf(
169
+								esc_html__(
170
+									'The value for the "admin_init_page" argument must be an instance of an EE_Admin_Page_Init object.  Instead %s was given as the value.',
171
+									'event_espresso'
172
+								),
173
+								print_r($value, true)
174
+							)
175
+						);
176
+					}
177
+					break;
178
+				case 'menu_callback':
179
+					break;
180
+
181
+				default:
182
+					$value = (string) $value;
183
+					break;
184
+			}
185
+			if (! EEH_Class_Tools::has_property($this, $prop)) {
186
+				throw new EE_Error(
187
+					sprintf(
188
+						esc_html__(
189
+							'The $menu_args coming into %s has a index key (%s) representing a property that is not defined by the class.  Perhaps there is a typo?',
190
+							'event_espresso'
191
+						),
192
+						get_class($this),
193
+						$prop
194
+					)
195
+				);
196
+			}
197
+			$this->{$prop} = $value;
198
+		}
199
+
200
+		// filter capabilities (both static and dynamic)
201
+		$this->capability = apply_filters('FHEE_management_capability', $this->capability, null);
202
+		$this->capability = apply_filters('FHEE_' . $this->menu_slug . '_capability', $this->capability, null);
203
+
204
+		// Might need to change parent slug depending on maintenance mode.
205
+		if (
206
+			! empty($this->maintenance_mode_parent)
207
+			&& EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance
208
+		) {
209
+			$this->parent_slug = $this->maintenance_mode_parent;
210
+		}
211
+
212
+		// if empty menu_callback let's set default (but only if we have admin page init object)
213
+		if (empty($this->menu_callback) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
214
+			$this->menu_callback = [$this->admin_init_page, 'initialize_admin_page'];
215
+		}
216
+	}
217
+
218
+
219
+	/**
220
+	 * This method should define how the menu page gets added for this particular item
221
+	 * and go ahead and define it.  Note that child classes MUST also return the result of
222
+	 * the function used to register the WordPress admin page (the wp_page_slug string)
223
+	 *
224
+	 * @return string wp_page_slug.
225
+	 * @since  4.4.0
226
+	 */
227
+	abstract protected function _add_menu_page();
228
+
229
+
230
+	/**
231
+	 * Called by client code to use this menu map for registering a WordPress admin page
232
+	 *
233
+	 * @param boolean $network_admin whether this is being added to the network admin page or not
234
+	 * @throws EE_Error
235
+	 * @throws ReflectionException
236
+	 * @since  4.4.0
237
+	 */
238
+	public function add_menu_page($network_admin = false)
239
+	{
240
+		$show_on_menu_int = (int) $this->show_on_menu;
241
+		if (
242
+			($network_admin
243
+			 && in_array(
244
+				 $show_on_menu_int,
245
+				 [self::BLOG_AND_NETWORK_ADMIN, self::NETWORK_ADMIN_ONLY],
246
+				 true
247
+			 ))
248
+			|| (! $network_admin
249
+				&& in_array(
250
+					$show_on_menu_int,
251
+					[self::BLOG_AND_NETWORK_ADMIN, self::BLOG_ADMIN_ONLY],
252
+					true
253
+				))
254
+		) {
255
+			$wp_page_slug = $this->_add_menu_page();
256
+		} else {
257
+			$wp_page_slug = '';
258
+		}
259
+
260
+		if (! empty($wp_page_slug) && $this->admin_init_page instanceof EE_Admin_Page_Init) {
261
+			try {
262
+				$this->admin_init_page->set_page_dependencies($wp_page_slug);
263
+			} catch (EE_Error $e) {
264
+				$e->get_error();
265
+			}
266
+		}
267
+	}
268 268
 }
Please login to merge, or discard this patch.
modules/ticket_sales_monitor/EED_Ticket_Sales_Monitor.module.php 2 patches
Spacing   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
     {
184 184
         // self::debug hardcoded to false
185 185
         if (self::debug) {
186
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
186
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
187 187
         }
188 188
         do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
189 189
         $expired_ticket_IDs = array();
@@ -194,29 +194,29 @@  discard block
 block discarded – undo
194 194
         $timestamp = $session_lifespan->expiration();
195 195
         $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
196 196
         if (self::debug) {
197
-            echo self::$nl . ' . time(): ' . time();
198
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
199
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
200
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
201
-            echo self::$nl . ' . timestamp: ' . $timestamp;
202
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
197
+            echo self::$nl.' . time(): '.time();
198
+            echo self::$nl.' . time() as date: '.date('Y-m-d H:i a');
199
+            echo self::$nl.' . session expiration: '.$session_lifespan->expiration();
200
+            echo self::$nl.' . session expiration as date: '.date('Y-m-d H:i a', $session_lifespan->expiration());
201
+            echo self::$nl.' . timestamp: '.$timestamp;
202
+            echo self::$nl.' . $expired_ticket_line_items: '.count($expired_ticket_line_items);
203 203
         }
204
-        if (! empty($expired_ticket_line_items)) {
204
+        if ( ! empty($expired_ticket_line_items)) {
205 205
             foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
206
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
206
+                if ( ! $expired_ticket_line_item instanceof EE_Line_Item) {
207 207
                     continue;
208 208
                 }
209
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
209
+                $expired_ticket_IDs[$expired_ticket_line_item->OBJ_ID()] = $expired_ticket_line_item->OBJ_ID();
210 210
                 if (self::debug) {
211
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
212
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
211
+                    echo self::$nl.' . $expired_ticket_line_item->OBJ_ID(): '.$expired_ticket_line_item->OBJ_ID();
212
+                    echo self::$nl.' . $expired_ticket_line_item->timestamp(): '
213 213
                          . date(
214 214
                              'Y-m-d h:i a',
215 215
                              $expired_ticket_line_item->timestamp(true)
216 216
                          );
217 217
                 }
218 218
             }
219
-            if (! empty($expired_ticket_IDs)) {
219
+            if ( ! empty($expired_ticket_IDs)) {
220 220
                 EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
221 221
                     \EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
222 222
                     array(),
@@ -255,8 +255,8 @@  discard block
 block discarded – undo
255 255
         }
256 256
         // self::debug hardcoded to false
257 257
         if (self::debug) {
258
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
259
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
258
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
259
+            echo self::$nl.self::$nl.'<b> RETURNED QTY: '.$qty.'</b>';
260 260
         }
261 261
         return $qty;
262 262
     }
@@ -275,36 +275,36 @@  discard block
 block discarded – undo
275 275
     {
276 276
         // self::debug hardcoded to false
277 277
         if (self::debug) {
278
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
278
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
279 279
         }
280
-        if (! $ticket instanceof EE_Ticket) {
280
+        if ( ! $ticket instanceof EE_Ticket) {
281 281
             return 0;
282 282
         }
283 283
         if (self::debug) {
284
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
285
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
284
+            echo self::$nl.'<b> . ticket->ID: '.$ticket->ID().'</b>';
285
+            echo self::$nl.' . original ticket->reserved: '.$ticket->reserved();
286 286
         }
287 287
         $ticket->refresh_from_db();
288 288
         // first let's determine the ticket availability based on sales
289 289
         $available = $ticket->qty('saleable');
290 290
         if (self::debug) {
291
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
292
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
293
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
294
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
295
-            echo self::$nl . ' . . . available: ' . $available;
291
+            echo self::$nl.' . . . ticket->qty: '.$ticket->qty();
292
+            echo self::$nl.' . . . ticket->sold: '.$ticket->sold();
293
+            echo self::$nl.' . . . ticket->reserved: '.$ticket->reserved();
294
+            echo self::$nl.' . . . ticket->qty(saleable): '.$ticket->qty('saleable');
295
+            echo self::$nl.' . . . available: '.$available;
296 296
         }
297 297
         if ($available < 1) {
298 298
             $this->_ticket_sold_out($ticket);
299 299
             return 0;
300 300
         }
301 301
         if (self::debug) {
302
-            echo self::$nl . ' . . . qty: ' . $qty;
302
+            echo self::$nl.' . . . qty: '.$qty;
303 303
         }
304 304
         if ($available < $qty) {
305 305
             $qty = $available;
306 306
             if (self::debug) {
307
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
307
+                echo self::$nl.' . . . QTY ADJUSTED: '.$qty;
308 308
             }
309 309
             $this->_ticket_quantity_decremented($ticket);
310 310
         }
@@ -328,9 +328,9 @@  discard block
 block discarded – undo
328 328
     {
329 329
         // self::debug hardcoded to false
330 330
         if (self::debug) {
331
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
331
+            echo self::$nl.self::$nl.' . . . INCREASE RESERVED: '.$quantity;
332 332
         }
333
-        return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:' . __LINE__);
333
+        return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:'.__LINE__);
334 334
     }
335 335
 
336 336
 
@@ -344,12 +344,12 @@  discard block
 block discarded – undo
344 344
     {
345 345
         // self::debug hardcoded to false
346 346
         if (self::debug) {
347
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
348
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
347
+            echo self::$nl.' . . . ticket->ID: '.$ticket->ID();
348
+            echo self::$nl.' . . . ticket->reserved before: '.$ticket->reserved();
349 349
         }
350
-        $ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
350
+        $ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:'.__LINE__);
351 351
         if (self::debug) {
352
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
352
+            echo self::$nl.' . . . ticket->reserved after: '.$ticket->reserved();
353 353
         }
354 354
         return $ticket->save() ? 1 : 0;
355 355
     }
@@ -367,8 +367,8 @@  discard block
 block discarded – undo
367 367
     {
368 368
         // self::debug hardcoded to false
369 369
         if (self::debug) {
370
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
371
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
370
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
371
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
372 372
         }
373 373
         $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
374 374
     }
@@ -386,8 +386,8 @@  discard block
 block discarded – undo
386 386
     {
387 387
         // self::debug hardcoded to false
388 388
         if (self::debug) {
389
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
390
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
389
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
390
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
391 391
         }
392 392
         $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
393 393
     }
@@ -438,7 +438,7 @@  discard block
 block discarded – undo
438 438
         if ($ticket instanceof EE_Ticket) {
439 439
             $ticket->add_extra_meta(
440 440
                 EE_Ticket::META_KEY_TICKET_RESERVATIONS,
441
-                __LINE__ . ') ' . __METHOD__ . '()'
441
+                __LINE__.') '.__METHOD__.'()'
442 442
             );
443 443
             if ($quantity > 0) {
444 444
                 EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
     {
462 462
         $ticket->add_extra_meta(
463 463
             EE_Ticket::META_KEY_TICKET_RESERVATIONS,
464
-            __LINE__ . ') ' . __METHOD__ . '()'
464
+            __LINE__.') '.__METHOD__.'()'
465 465
         );
466 466
         EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
467 467
     }
@@ -497,7 +497,7 @@  discard block
 block discarded – undo
497 497
     {
498 498
         // self::debug hardcoded to false
499 499
         if (self::debug) {
500
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
500
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
501 501
         }
502 502
         $refresh_msg = '';
503 503
         $none_added_msg = '';
@@ -508,7 +508,7 @@  discard block
 block discarded – undo
508 508
             );
509 509
             $none_added_msg = esc_html__('No tickets were added for the event.', 'event_espresso');
510 510
         }
511
-        if (! empty($this->sold_out_tickets)) {
511
+        if ( ! empty($this->sold_out_tickets)) {
512 512
             EE_Error::add_attention(
513 513
                 sprintf(
514 514
                     apply_filters(
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
             // and reset the cart
532 532
             EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
533 533
         }
534
-        if (! empty($this->decremented_tickets)) {
534
+        if ( ! empty($this->decremented_tickets)) {
535 535
             EE_Error::add_attention(
536 536
                 sprintf(
537 537
                     apply_filters(
@@ -569,9 +569,9 @@  discard block
 block discarded – undo
569 569
     {
570 570
         // self::debug hardcoded to false
571 571
         if (self::debug) {
572
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
573
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
574
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
572
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
573
+            echo self::$nl.' . transaction->ID: '.$transaction->ID();
574
+            echo self::$nl.' . TXN status_ID: '.$transaction->status_ID();
575 575
         }
576 576
         // check if 'finalize_registration' step has been completed...
577 577
         $finalized = $transaction->reg_step_completed('finalize_registration');
@@ -583,13 +583,13 @@  discard block
 block discarded – undo
583 583
                 __LINE__,
584 584
                 array('finalized' => $finalized),
585 585
                 false,
586
-                'EE_Transaction: ' . $transaction->ID()
586
+                'EE_Transaction: '.$transaction->ID()
587 587
             );
588 588
         }
589 589
         // how many tickets were released
590 590
         $count = 0;
591 591
         if (self::debug) {
592
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
592
+            echo self::$nl.' . . . TXN finalized: '.$finalized;
593 593
         }
594 594
         $release_tickets_with_TXN_status = array(
595 595
             EEM_Transaction::failed_status_code,
@@ -598,28 +598,28 @@  discard block
 block discarded – undo
598 598
         );
599 599
         $events = array();
600 600
         // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
601
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
601
+        if ( ! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
602 602
             // cancel any reserved tickets for registrations that were not approved
603 603
             $registrations = $transaction->registrations();
604 604
             if (self::debug) {
605
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
605
+                echo self::$nl.' . . . # registrations: '.count($registrations);
606 606
                 $reg = reset($registrations);
607 607
                 $ticket = $reg->ticket();
608 608
                 if ($ticket instanceof EE_Ticket) {
609 609
                     $ticket->add_extra_meta(
610 610
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
611
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
611
+                        __LINE__.') Release All Tickets TXN:'.$transaction->ID()
612 612
                     );
613 613
                 }
614 614
             }
615
-            if (! empty($registrations)) {
615
+            if ( ! empty($registrations)) {
616 616
                 foreach ($registrations as $registration) {
617 617
                     if (
618 618
                         $registration instanceof EE_Registration
619 619
                         && $this->_release_reserved_ticket_for_registration($registration, $transaction)
620 620
                     ) {
621 621
                         $count++;
622
-                        $events[ $registration->event_ID() ] = $registration->event();
622
+                        $events[$registration->event_ID()] = $registration->event();
623 623
                     }
624 624
                 }
625 625
             }
@@ -650,10 +650,10 @@  discard block
 block discarded – undo
650 650
         $STS_ID = $transaction->status_ID();
651 651
         // self::debug hardcoded to false
652 652
         if (self::debug) {
653
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
654
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
655
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
656
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
653
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
654
+            echo self::$nl.' . . registration->ID: '.$registration->ID();
655
+            echo self::$nl.' . . registration->status_ID: '.$registration->status_ID();
656
+            echo self::$nl.' . . transaction->status_ID(): '.$STS_ID;
657 657
         }
658 658
         if (
659 659
 // release Tickets for Failed Transactions and Abandoned Transactions
@@ -666,12 +666,12 @@  discard block
 block discarded – undo
666 666
             )
667 667
         ) {
668 668
             if (self::debug) {
669
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
669
+                echo self::$nl.self::$nl.' . . RELEASE RESERVED TICKET';
670 670
                 $rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
671
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
671
+                echo self::$nl.' . . . registration HAS_RESERVED_TICKET_KEY: ';
672 672
                 var_dump($rsrvd);
673 673
             }
674
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
674
+            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:'.__LINE__);
675 675
             return 1;
676 676
         }
677 677
         return 0;
@@ -701,7 +701,7 @@  discard block
 block discarded – undo
701 701
         }
702 702
         // self::debug hardcoded to false
703 703
         if (self::debug) {
704
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
704
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
705 705
         }
706 706
         // first check of the session has a valid Checkout object
707 707
         $checkout = $session->checkout();
@@ -713,12 +713,12 @@  discard block
 block discarded – undo
713 713
         $cart = $session->cart();
714 714
         if ($cart instanceof EE_Cart) {
715 715
             if (self::debug) {
716
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
716
+                echo self::$nl.self::$nl.' cart instance of EE_Cart: ';
717 717
             }
718 718
             EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
719 719
         } else {
720 720
             if (self::debug) {
721
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
721
+                echo self::$nl.self::$nl.' invalid EE_Cart: ';
722 722
                 var_export($cart, true);
723 723
             }
724 724
         }
@@ -740,39 +740,39 @@  discard block
 block discarded – undo
740 740
     {
741 741
         // self::debug hardcoded to false
742 742
         if (self::debug) {
743
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
743
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
744 744
         }
745 745
         $ticket_line_items = $cart->get_tickets();
746 746
         if (empty($ticket_line_items)) {
747 747
             return;
748 748
         }
749 749
         if (self::debug) {
750
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
750
+            echo '<br /> . ticket_line_item count: '.count($ticket_line_items);
751 751
         }
752 752
         foreach ($ticket_line_items as $ticket_line_item) {
753 753
             if (self::debug) {
754
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
754
+                echo self::$nl.' . ticket_line_item->ID(): '.$ticket_line_item->ID();
755 755
             }
756 756
             if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
757 757
                 if (self::debug) {
758
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
758
+                    echo self::$nl.' . . ticket_line_item->OBJ_ID(): '.$ticket_line_item->OBJ_ID();
759 759
                 }
760 760
                 $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
761 761
                 if ($ticket instanceof EE_Ticket) {
762 762
                     if (self::debug) {
763
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
764
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
763
+                        echo self::$nl.' . . ticket->ID(): '.$ticket->ID();
764
+                        echo self::$nl.' . . ticket_line_item->quantity(): '.$ticket_line_item->quantity();
765 765
                     }
766 766
                     $ticket->add_extra_meta(
767 767
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
768
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
768
+                        __LINE__.') '.__METHOD__.'() SID = '.$session->id()
769 769
                     );
770 770
                     $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
771 771
                 }
772 772
             }
773 773
         }
774 774
         if (self::debug) {
775
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
775
+            echo self::$nl.self::$nl.' RESET COMPLETED ';
776 776
         }
777 777
     }
778 778
 
@@ -814,7 +814,7 @@  discard block
 block discarded – undo
814 814
     {
815 815
         // self::debug hardcoded to false
816 816
         if (self::debug) {
817
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
817
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
818 818
         }
819 819
         // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
820 820
         if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
                     __LINE__,
864 864
                     array($transaction),
865 865
                     false,
866
-                    'EE_Transaction: ' . $transaction->ID()
866
+                    'EE_Transaction: '.$transaction->ID()
867 867
                 );
868 868
             }
869 869
             return;
@@ -880,7 +880,7 @@  discard block
 block discarded – undo
880 880
                         __LINE__,
881 881
                         array($payment),
882 882
                         false,
883
-                        'EE_Transaction: ' . $transaction->ID()
883
+                        'EE_Transaction: '.$transaction->ID()
884 884
                     );
885 885
                 }
886 886
                 return;
@@ -942,7 +942,7 @@  discard block
 block discarded – undo
942 942
             }
943 943
             $total_line_item = $transaction->total_line_item();
944 944
             // $transaction_in_progress->line
945
-            if (! $total_line_item instanceof EE_Line_Item) {
945
+            if ( ! $total_line_item instanceof EE_Line_Item) {
946 946
                 throw new DomainException(
947 947
                     esc_html__(
948 948
                         'Transaction does not have a valid Total Line Item associated with it.',
@@ -980,7 +980,7 @@  discard block
 block discarded – undo
980 980
         $ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
981 981
         foreach ($ticket_line_items as $ticket_line_item) {
982 982
             if ($ticket_line_item instanceof EE_Line_Item) {
983
-                $valid_reserved_tickets[ $ticket_line_item->ID() ] = $ticket_line_item;
983
+                $valid_reserved_tickets[$ticket_line_item->ID()] = $ticket_line_item;
984 984
             }
985 985
         }
986 986
         return $valid_reserved_tickets;
@@ -1013,7 +1013,7 @@  discard block
 block discarded – undo
1013 1013
         $total_tickets_released = 0;
1014 1014
         $sold_out_events = array();
1015 1015
         foreach ($tickets_with_reservations as $ticket_with_reservations) {
1016
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
1016
+            if ( ! $ticket_with_reservations instanceof EE_Ticket) {
1017 1017
                 continue;
1018 1018
             }
1019 1019
             // The $valid_reserved_ticket_line_items tells us what the reserved count on their tickets (and datetimes)
@@ -1035,9 +1035,9 @@  discard block
 block discarded – undo
1035 1035
             if ($expired_reservations_count > 0) {
1036 1036
                 $ticket_with_reservations->add_extra_meta(
1037 1037
                     EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1038
-                    __LINE__ . ') ' . $source . '()'
1038
+                    __LINE__.') '.$source.'()'
1039 1039
                 );
1040
-                $ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:' . __LINE__);
1040
+                $ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:'.__LINE__);
1041 1041
                 $total_tickets_released += $expired_reservations_count;
1042 1042
                 $event = $ticket_with_reservations->get_related_event();
1043 1043
                 // track sold out events
@@ -1073,7 +1073,7 @@  discard block
 block discarded – undo
1073 1073
     {
1074 1074
         /** @type WPDB $wpdb */
1075 1075
         global $wpdb;
1076
-        if (! absint($timestamp)) {
1076
+        if ( ! absint($timestamp)) {
1077 1077
             /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1078 1078
             $session_lifespan = LoaderFactory::getLoader()->getShared(
1079 1079
                 'EventEspresso\core\domain\values\session\SessionLifespan'
@@ -1082,7 +1082,7 @@  discard block
 block discarded – undo
1082 1082
         }
1083 1083
         return $wpdb->query(
1084 1084
             $wpdb->prepare(
1085
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1085
+                'DELETE FROM '.EEM_Line_Item::instance()->table().'
1086 1086
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1087 1087
                 // use GMT time because that's what LIN_timestamps are in
1088 1088
                 date('Y-m-d H:i:s', $timestamp)
Please login to merge, or discard this patch.
Indentation   +1067 added lines, -1067 removed lines patch added patch discarded remove patch
@@ -19,1073 +19,1073 @@
 block discarded – undo
19 19
  */
20 20
 class EED_Ticket_Sales_Monitor extends EED_Module
21 21
 {
22
-    const debug = false;
23
-
24
-    private static $nl = '';
25
-
26
-    /**
27
-     * an array of raw ticket data from EED_Ticket_Selector
28
-     *
29
-     * @var array $ticket_selections
30
-     */
31
-    protected $ticket_selections = array();
32
-
33
-    /**
34
-     * the raw ticket data from EED_Ticket_Selector is organized in rows
35
-     * according to how they are displayed in the actual Ticket_Selector
36
-     * this tracks the current row being processed
37
-     *
38
-     * @var int $current_row
39
-     */
40
-    protected $current_row = 0;
41
-
42
-    /**
43
-     * an array for tracking names of tickets that have sold out
44
-     *
45
-     * @var array $sold_out_tickets
46
-     */
47
-    protected $sold_out_tickets = array();
48
-
49
-    /**
50
-     * an array for tracking names of tickets that have had their quantities reduced
51
-     *
52
-     * @var array $decremented_tickets
53
-     */
54
-    protected $decremented_tickets = array();
55
-
56
-
57
-    /**
58
-     * set_hooks - for hooking into EE Core, other modules, etc
59
-     *
60
-     * @return    void
61
-     */
62
-    public static function set_hooks()
63
-    {
64
-        self::$nl = defined('EE_TESTS_DIR') ? "\n" : '<br />';
65
-        // release tickets for expired carts
66
-        add_action(
67
-            'EED_Ticket_Selector__process_ticket_selections__before',
68
-            array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
69
-            1
70
-        );
71
-        // check ticket reserves AFTER MER does it's check (hence priority 20)
72
-        add_filter(
73
-            'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
74
-            array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
75
-            20,
76
-            3
77
-        );
78
-        // add notices for sold out tickets
79
-        add_action(
80
-            'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
81
-            array('EED_Ticket_Sales_Monitor', 'post_notices'),
82
-            10
83
-        );
84
-
85
-        // handle tickets deleted from cart
86
-        add_action(
87
-            'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
88
-            array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
89
-            10,
90
-            2
91
-        );
92
-        // handle emptied carts
93
-        add_action(
94
-            'AHEE__EE_Session__reset_cart__before_reset',
95
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
96
-            10,
97
-            1
98
-        );
99
-        add_action(
100
-            'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
101
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
102
-            10,
103
-            1
104
-        );
105
-        // handle cancelled registrations
106
-        add_action(
107
-            'AHEE__EE_Session__reset_checkout__before_reset',
108
-            array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
109
-            10,
110
-            1
111
-        );
112
-        // cron tasks
113
-        add_action(
114
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
115
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
116
-            10,
117
-            1
118
-        );
119
-        add_action(
120
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
121
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
122
-            10,
123
-            1
124
-        );
125
-        add_action(
126
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
127
-            array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
128
-            10,
129
-            1
130
-        );
131
-    }
132
-
133
-
134
-    /**
135
-     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
136
-     *
137
-     * @return void
138
-     */
139
-    public static function set_hooks_admin()
140
-    {
141
-        EED_Ticket_Sales_Monitor::set_hooks();
142
-    }
143
-
144
-
145
-    /**
146
-     * @return EED_Ticket_Sales_Monitor|EED_Module
147
-     */
148
-    public static function instance()
149
-    {
150
-        return parent::get_instance(__CLASS__);
151
-    }
152
-
153
-
154
-    /**
155
-     * @param WP_Query $WP_Query
156
-     * @return    void
157
-     */
158
-    public function run($WP_Query)
159
-    {
160
-    }
161
-
162
-
163
-
164
-    /********************************** PRE_TICKET_SALES  **********************************/
165
-
166
-
167
-    /**
168
-     * Retrieves grand totals from the line items that have no TXN ID
169
-     * and timestamps less than the current time minus the session lifespan.
170
-     * These are carts that have been abandoned before the "registrant" even attempted to checkout.
171
-     * We're going to release the tickets for these line items before attempting to add more to the cart.
172
-     *
173
-     * @return void
174
-     * @throws DomainException
175
-     * @throws EE_Error
176
-     * @throws InvalidArgumentException
177
-     * @throws InvalidDataTypeException
178
-     * @throws InvalidInterfaceException
179
-     * @throws UnexpectedEntityException
180
-     */
181
-    public static function release_tickets_for_expired_carts()
182
-    {
183
-        // self::debug hardcoded to false
184
-        if (self::debug) {
185
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
186
-        }
187
-        do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
188
-        $expired_ticket_IDs = array();
189
-        /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
190
-        $session_lifespan = LoaderFactory::getLoader()->getShared(
191
-            'EventEspresso\core\domain\values\session\SessionLifespan'
192
-        );
193
-        $timestamp = $session_lifespan->expiration();
194
-        $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
195
-        if (self::debug) {
196
-            echo self::$nl . ' . time(): ' . time();
197
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
198
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
199
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
200
-            echo self::$nl . ' . timestamp: ' . $timestamp;
201
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
202
-        }
203
-        if (! empty($expired_ticket_line_items)) {
204
-            foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
205
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
206
-                    continue;
207
-                }
208
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
209
-                if (self::debug) {
210
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
211
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
212
-                         . date(
213
-                             'Y-m-d h:i a',
214
-                             $expired_ticket_line_item->timestamp(true)
215
-                         );
216
-                }
217
-            }
218
-            if (! empty($expired_ticket_IDs)) {
219
-                EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
220
-                    \EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
221
-                    array(),
222
-                    __FUNCTION__
223
-                );
224
-                // now  let's get rid of expired line items so that they can't interfere with tracking
225
-                EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
226
-            }
227
-        }
228
-        do_action(
229
-            'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
230
-            $expired_ticket_IDs,
231
-            $expired_ticket_line_items
232
-        );
233
-    }
234
-
235
-
236
-
237
-    /********************************** VALIDATE_TICKET_SALE  **********************************/
238
-
239
-
240
-    /**
241
-     * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
242
-     *
243
-     * @param int       $qty
244
-     * @param EE_Ticket $ticket
245
-     * @return bool
246
-     * @throws UnexpectedEntityException
247
-     * @throws EE_Error
248
-     */
249
-    public static function validate_ticket_sale($qty, EE_Ticket $ticket)
250
-    {
251
-        $qty = absint($qty);
252
-        if ($qty > 0) {
253
-            $qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
254
-        }
255
-        // self::debug hardcoded to false
256
-        if (self::debug) {
257
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
258
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
259
-        }
260
-        return $qty;
261
-    }
262
-
263
-
264
-    /**
265
-     * checks whether an individual ticket is available for purchase based on datetime, and ticket details
266
-     *
267
-     * @param   EE_Ticket $ticket
268
-     * @param int         $qty
269
-     * @return int
270
-     * @throws UnexpectedEntityException
271
-     * @throws EE_Error
272
-     */
273
-    protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
274
-    {
275
-        // self::debug hardcoded to false
276
-        if (self::debug) {
277
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
278
-        }
279
-        if (! $ticket instanceof EE_Ticket) {
280
-            return 0;
281
-        }
282
-        if (self::debug) {
283
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
284
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
285
-        }
286
-        $ticket->refresh_from_db();
287
-        // first let's determine the ticket availability based on sales
288
-        $available = $ticket->qty('saleable');
289
-        if (self::debug) {
290
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
291
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
292
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
293
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
294
-            echo self::$nl . ' . . . available: ' . $available;
295
-        }
296
-        if ($available < 1) {
297
-            $this->_ticket_sold_out($ticket);
298
-            return 0;
299
-        }
300
-        if (self::debug) {
301
-            echo self::$nl . ' . . . qty: ' . $qty;
302
-        }
303
-        if ($available < $qty) {
304
-            $qty = $available;
305
-            if (self::debug) {
306
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
307
-            }
308
-            $this->_ticket_quantity_decremented($ticket);
309
-        }
310
-        if ($this->_reserve_ticket($ticket, $qty)) {
311
-            return $qty;
312
-        } else {
313
-            return 0;
314
-        }
315
-    }
316
-
317
-
318
-    /**
319
-     * increments ticket reserved based on quantity passed
320
-     *
321
-     * @param    EE_Ticket $ticket
322
-     * @param int          $quantity
323
-     * @return bool indicating success or failure
324
-     * @throws EE_Error
325
-     */
326
-    protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
327
-    {
328
-        // self::debug hardcoded to false
329
-        if (self::debug) {
330
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
331
-        }
332
-        return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:' . __LINE__);
333
-    }
334
-
335
-
336
-    /**
337
-     * @param  EE_Ticket $ticket
338
-     * @param  int       $quantity
339
-     * @return bool
340
-     * @throws EE_Error
341
-     */
342
-    protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
343
-    {
344
-        // self::debug hardcoded to false
345
-        if (self::debug) {
346
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
347
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
348
-        }
349
-        $ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
350
-        if (self::debug) {
351
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
352
-        }
353
-        return $ticket->save() ? 1 : 0;
354
-    }
355
-
356
-
357
-    /**
358
-     * removes quantities within the ticket selector based on zero ticket availability
359
-     *
360
-     * @param    EE_Ticket $ticket
361
-     * @return    void
362
-     * @throws UnexpectedEntityException
363
-     * @throws EE_Error
364
-     */
365
-    protected function _ticket_sold_out(EE_Ticket $ticket)
366
-    {
367
-        // self::debug hardcoded to false
368
-        if (self::debug) {
369
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
370
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
371
-        }
372
-        $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
373
-    }
374
-
375
-
376
-    /**
377
-     * adjusts quantities within the ticket selector based on decreased ticket availability
378
-     *
379
-     * @param    EE_Ticket $ticket
380
-     * @return void
381
-     * @throws UnexpectedEntityException
382
-     * @throws EE_Error
383
-     */
384
-    protected function _ticket_quantity_decremented(EE_Ticket $ticket)
385
-    {
386
-        // self::debug hardcoded to false
387
-        if (self::debug) {
388
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
389
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
390
-        }
391
-        $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
392
-    }
393
-
394
-
395
-    /**
396
-     * builds string out of ticket and event name
397
-     *
398
-     * @param    EE_Ticket $ticket
399
-     * @return string
400
-     * @throws UnexpectedEntityException
401
-     * @throws EE_Error
402
-     */
403
-    protected function _get_ticket_and_event_name(EE_Ticket $ticket)
404
-    {
405
-        $event = $ticket->get_related_event();
406
-        if ($event instanceof EE_Event) {
407
-            $ticket_name = sprintf(
408
-                _x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
409
-                $ticket->name(),
410
-                $event->name()
411
-            );
412
-        } else {
413
-            $ticket_name = $ticket->name();
414
-        }
415
-        return $ticket_name;
416
-    }
417
-
418
-
419
-
420
-    /********************************** EVENT CART  **********************************/
421
-
422
-
423
-    /**
424
-     * releases or reserves ticket(s) based on quantity passed
425
-     *
426
-     * @param  EE_Line_Item $line_item
427
-     * @param  int          $quantity
428
-     * @return void
429
-     * @throws EE_Error
430
-     * @throws InvalidArgumentException
431
-     * @throws InvalidDataTypeException
432
-     * @throws InvalidInterfaceException
433
-     */
434
-    public static function ticket_quantity_updated(EE_Line_Item $line_item, $quantity = 1)
435
-    {
436
-        $ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
437
-        if ($ticket instanceof EE_Ticket) {
438
-            $ticket->add_extra_meta(
439
-                EE_Ticket::META_KEY_TICKET_RESERVATIONS,
440
-                __LINE__ . ') ' . __METHOD__ . '()'
441
-            );
442
-            if ($quantity > 0) {
443
-                EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
444
-            } else {
445
-                EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
446
-            }
447
-        }
448
-    }
449
-
450
-
451
-    /**
452
-     * releases reserved ticket(s) based on quantity passed
453
-     *
454
-     * @param  EE_Ticket $ticket
455
-     * @param  int       $quantity
456
-     * @return void
457
-     * @throws EE_Error
458
-     */
459
-    public static function ticket_removed_from_cart(EE_Ticket $ticket, $quantity = 1)
460
-    {
461
-        $ticket->add_extra_meta(
462
-            EE_Ticket::META_KEY_TICKET_RESERVATIONS,
463
-            __LINE__ . ') ' . __METHOD__ . '()'
464
-        );
465
-        EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
466
-    }
467
-
468
-
469
-
470
-    /********************************** POST_NOTICES  **********************************/
471
-
472
-
473
-    /**
474
-     * @return void
475
-     * @throws EE_Error
476
-     * @throws InvalidArgumentException
477
-     * @throws ReflectionException
478
-     * @throws InvalidDataTypeException
479
-     * @throws InvalidInterfaceException
480
-     */
481
-    public static function post_notices()
482
-    {
483
-        EED_Ticket_Sales_Monitor::instance()->_post_notices();
484
-    }
485
-
486
-
487
-    /**
488
-     * @return void
489
-     * @throws EE_Error
490
-     * @throws InvalidArgumentException
491
-     * @throws ReflectionException
492
-     * @throws InvalidDataTypeException
493
-     * @throws InvalidInterfaceException
494
-     */
495
-    protected function _post_notices()
496
-    {
497
-        // self::debug hardcoded to false
498
-        if (self::debug) {
499
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
500
-        }
501
-        $refresh_msg = '';
502
-        $none_added_msg = '';
503
-        if (defined('DOING_AJAX') && DOING_AJAX) {
504
-            $refresh_msg = esc_html__(
505
-                'Please refresh the page to view updated ticket quantities.',
506
-                'event_espresso'
507
-            );
508
-            $none_added_msg = esc_html__('No tickets were added for the event.', 'event_espresso');
509
-        }
510
-        if (! empty($this->sold_out_tickets)) {
511
-            EE_Error::add_attention(
512
-                sprintf(
513
-                    apply_filters(
514
-                        'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
515
-                        esc_html__(
516
-                            'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
517
-                            'event_espresso'
518
-                        )
519
-                    ),
520
-                    '<br />',
521
-                    implode('<br />', $this->sold_out_tickets),
522
-                    $none_added_msg,
523
-                    $refresh_msg
524
-                )
525
-            );
526
-            // alter code flow in the Ticket Selector for better UX
527
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
528
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
529
-            $this->sold_out_tickets = array();
530
-            // and reset the cart
531
-            EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
532
-        }
533
-        if (! empty($this->decremented_tickets)) {
534
-            EE_Error::add_attention(
535
-                sprintf(
536
-                    apply_filters(
537
-                        'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
538
-                        esc_html__(
539
-                            'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
540
-                            'event_espresso'
541
-                        )
542
-                    ),
543
-                    '<br />',
544
-                    implode('<br />', $this->decremented_tickets),
545
-                    $none_added_msg,
546
-                    $refresh_msg
547
-                )
548
-            );
549
-            $this->decremented_tickets = array();
550
-        }
551
-    }
552
-
553
-
554
-
555
-    /********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
556
-
557
-
558
-    /**
559
-     * releases reserved tickets for all registrations of an EE_Transaction
560
-     * by default, will NOT release tickets for finalized transactions
561
-     *
562
-     * @param    EE_Transaction $transaction
563
-     * @return int
564
-     * @throws EE_Error
565
-     * @throws InvalidSessionDataException
566
-     */
567
-    protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
568
-    {
569
-        // self::debug hardcoded to false
570
-        if (self::debug) {
571
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
572
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
573
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
574
-        }
575
-        // check if 'finalize_registration' step has been completed...
576
-        $finalized = $transaction->reg_step_completed('finalize_registration');
577
-        if (self::debug) {
578
-            // DEBUG LOG
579
-            EEH_Debug_Tools::log(
580
-                __CLASS__,
581
-                __FUNCTION__,
582
-                __LINE__,
583
-                array('finalized' => $finalized),
584
-                false,
585
-                'EE_Transaction: ' . $transaction->ID()
586
-            );
587
-        }
588
-        // how many tickets were released
589
-        $count = 0;
590
-        if (self::debug) {
591
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
592
-        }
593
-        $release_tickets_with_TXN_status = array(
594
-            EEM_Transaction::failed_status_code,
595
-            EEM_Transaction::abandoned_status_code,
596
-            EEM_Transaction::incomplete_status_code,
597
-        );
598
-        $events = array();
599
-        // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
600
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
601
-            // cancel any reserved tickets for registrations that were not approved
602
-            $registrations = $transaction->registrations();
603
-            if (self::debug) {
604
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
605
-                $reg = reset($registrations);
606
-                $ticket = $reg->ticket();
607
-                if ($ticket instanceof EE_Ticket) {
608
-                    $ticket->add_extra_meta(
609
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
610
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
611
-                    );
612
-                }
613
-            }
614
-            if (! empty($registrations)) {
615
-                foreach ($registrations as $registration) {
616
-                    if (
617
-                        $registration instanceof EE_Registration
618
-                        && $this->_release_reserved_ticket_for_registration($registration, $transaction)
619
-                    ) {
620
-                        $count++;
621
-                        $events[ $registration->event_ID() ] = $registration->event();
622
-                    }
623
-                }
624
-            }
625
-        }
626
-        if ($events !== array()) {
627
-            foreach ($events as $event) {
628
-                /** @var EE_Event $event */
629
-                $event->perform_sold_out_status_check();
630
-            }
631
-        }
632
-        return $count;
633
-    }
634
-
635
-
636
-    /**
637
-     * releases reserved tickets for an EE_Registration
638
-     * by default, will NOT release tickets for APPROVED registrations
639
-     *
640
-     * @param EE_Registration $registration
641
-     * @param EE_Transaction  $transaction
642
-     * @return int
643
-     * @throws EE_Error
644
-     */
645
-    protected function _release_reserved_ticket_for_registration(
646
-        EE_Registration $registration,
647
-        EE_Transaction $transaction
648
-    ) {
649
-        $STS_ID = $transaction->status_ID();
650
-        // self::debug hardcoded to false
651
-        if (self::debug) {
652
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
653
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
654
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
655
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
656
-        }
657
-        if (
22
+	const debug = false;
23
+
24
+	private static $nl = '';
25
+
26
+	/**
27
+	 * an array of raw ticket data from EED_Ticket_Selector
28
+	 *
29
+	 * @var array $ticket_selections
30
+	 */
31
+	protected $ticket_selections = array();
32
+
33
+	/**
34
+	 * the raw ticket data from EED_Ticket_Selector is organized in rows
35
+	 * according to how they are displayed in the actual Ticket_Selector
36
+	 * this tracks the current row being processed
37
+	 *
38
+	 * @var int $current_row
39
+	 */
40
+	protected $current_row = 0;
41
+
42
+	/**
43
+	 * an array for tracking names of tickets that have sold out
44
+	 *
45
+	 * @var array $sold_out_tickets
46
+	 */
47
+	protected $sold_out_tickets = array();
48
+
49
+	/**
50
+	 * an array for tracking names of tickets that have had their quantities reduced
51
+	 *
52
+	 * @var array $decremented_tickets
53
+	 */
54
+	protected $decremented_tickets = array();
55
+
56
+
57
+	/**
58
+	 * set_hooks - for hooking into EE Core, other modules, etc
59
+	 *
60
+	 * @return    void
61
+	 */
62
+	public static function set_hooks()
63
+	{
64
+		self::$nl = defined('EE_TESTS_DIR') ? "\n" : '<br />';
65
+		// release tickets for expired carts
66
+		add_action(
67
+			'EED_Ticket_Selector__process_ticket_selections__before',
68
+			array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
69
+			1
70
+		);
71
+		// check ticket reserves AFTER MER does it's check (hence priority 20)
72
+		add_filter(
73
+			'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
74
+			array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
75
+			20,
76
+			3
77
+		);
78
+		// add notices for sold out tickets
79
+		add_action(
80
+			'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
81
+			array('EED_Ticket_Sales_Monitor', 'post_notices'),
82
+			10
83
+		);
84
+
85
+		// handle tickets deleted from cart
86
+		add_action(
87
+			'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
88
+			array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
89
+			10,
90
+			2
91
+		);
92
+		// handle emptied carts
93
+		add_action(
94
+			'AHEE__EE_Session__reset_cart__before_reset',
95
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
96
+			10,
97
+			1
98
+		);
99
+		add_action(
100
+			'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
101
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
102
+			10,
103
+			1
104
+		);
105
+		// handle cancelled registrations
106
+		add_action(
107
+			'AHEE__EE_Session__reset_checkout__before_reset',
108
+			array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
109
+			10,
110
+			1
111
+		);
112
+		// cron tasks
113
+		add_action(
114
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
115
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
116
+			10,
117
+			1
118
+		);
119
+		add_action(
120
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
121
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
122
+			10,
123
+			1
124
+		);
125
+		add_action(
126
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
127
+			array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
128
+			10,
129
+			1
130
+		);
131
+	}
132
+
133
+
134
+	/**
135
+	 * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
136
+	 *
137
+	 * @return void
138
+	 */
139
+	public static function set_hooks_admin()
140
+	{
141
+		EED_Ticket_Sales_Monitor::set_hooks();
142
+	}
143
+
144
+
145
+	/**
146
+	 * @return EED_Ticket_Sales_Monitor|EED_Module
147
+	 */
148
+	public static function instance()
149
+	{
150
+		return parent::get_instance(__CLASS__);
151
+	}
152
+
153
+
154
+	/**
155
+	 * @param WP_Query $WP_Query
156
+	 * @return    void
157
+	 */
158
+	public function run($WP_Query)
159
+	{
160
+	}
161
+
162
+
163
+
164
+	/********************************** PRE_TICKET_SALES  **********************************/
165
+
166
+
167
+	/**
168
+	 * Retrieves grand totals from the line items that have no TXN ID
169
+	 * and timestamps less than the current time minus the session lifespan.
170
+	 * These are carts that have been abandoned before the "registrant" even attempted to checkout.
171
+	 * We're going to release the tickets for these line items before attempting to add more to the cart.
172
+	 *
173
+	 * @return void
174
+	 * @throws DomainException
175
+	 * @throws EE_Error
176
+	 * @throws InvalidArgumentException
177
+	 * @throws InvalidDataTypeException
178
+	 * @throws InvalidInterfaceException
179
+	 * @throws UnexpectedEntityException
180
+	 */
181
+	public static function release_tickets_for_expired_carts()
182
+	{
183
+		// self::debug hardcoded to false
184
+		if (self::debug) {
185
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
186
+		}
187
+		do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
188
+		$expired_ticket_IDs = array();
189
+		/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
190
+		$session_lifespan = LoaderFactory::getLoader()->getShared(
191
+			'EventEspresso\core\domain\values\session\SessionLifespan'
192
+		);
193
+		$timestamp = $session_lifespan->expiration();
194
+		$expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
195
+		if (self::debug) {
196
+			echo self::$nl . ' . time(): ' . time();
197
+			echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
198
+			echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
199
+			echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
200
+			echo self::$nl . ' . timestamp: ' . $timestamp;
201
+			echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
202
+		}
203
+		if (! empty($expired_ticket_line_items)) {
204
+			foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
205
+				if (! $expired_ticket_line_item instanceof EE_Line_Item) {
206
+					continue;
207
+				}
208
+				$expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
209
+				if (self::debug) {
210
+					echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
211
+					echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
212
+						 . date(
213
+							 'Y-m-d h:i a',
214
+							 $expired_ticket_line_item->timestamp(true)
215
+						 );
216
+				}
217
+			}
218
+			if (! empty($expired_ticket_IDs)) {
219
+				EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
220
+					\EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
221
+					array(),
222
+					__FUNCTION__
223
+				);
224
+				// now  let's get rid of expired line items so that they can't interfere with tracking
225
+				EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
226
+			}
227
+		}
228
+		do_action(
229
+			'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
230
+			$expired_ticket_IDs,
231
+			$expired_ticket_line_items
232
+		);
233
+	}
234
+
235
+
236
+
237
+	/********************************** VALIDATE_TICKET_SALE  **********************************/
238
+
239
+
240
+	/**
241
+	 * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
242
+	 *
243
+	 * @param int       $qty
244
+	 * @param EE_Ticket $ticket
245
+	 * @return bool
246
+	 * @throws UnexpectedEntityException
247
+	 * @throws EE_Error
248
+	 */
249
+	public static function validate_ticket_sale($qty, EE_Ticket $ticket)
250
+	{
251
+		$qty = absint($qty);
252
+		if ($qty > 0) {
253
+			$qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
254
+		}
255
+		// self::debug hardcoded to false
256
+		if (self::debug) {
257
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
258
+			echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
259
+		}
260
+		return $qty;
261
+	}
262
+
263
+
264
+	/**
265
+	 * checks whether an individual ticket is available for purchase based on datetime, and ticket details
266
+	 *
267
+	 * @param   EE_Ticket $ticket
268
+	 * @param int         $qty
269
+	 * @return int
270
+	 * @throws UnexpectedEntityException
271
+	 * @throws EE_Error
272
+	 */
273
+	protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
274
+	{
275
+		// self::debug hardcoded to false
276
+		if (self::debug) {
277
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
278
+		}
279
+		if (! $ticket instanceof EE_Ticket) {
280
+			return 0;
281
+		}
282
+		if (self::debug) {
283
+			echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
284
+			echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
285
+		}
286
+		$ticket->refresh_from_db();
287
+		// first let's determine the ticket availability based on sales
288
+		$available = $ticket->qty('saleable');
289
+		if (self::debug) {
290
+			echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
291
+			echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
292
+			echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
293
+			echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
294
+			echo self::$nl . ' . . . available: ' . $available;
295
+		}
296
+		if ($available < 1) {
297
+			$this->_ticket_sold_out($ticket);
298
+			return 0;
299
+		}
300
+		if (self::debug) {
301
+			echo self::$nl . ' . . . qty: ' . $qty;
302
+		}
303
+		if ($available < $qty) {
304
+			$qty = $available;
305
+			if (self::debug) {
306
+				echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
307
+			}
308
+			$this->_ticket_quantity_decremented($ticket);
309
+		}
310
+		if ($this->_reserve_ticket($ticket, $qty)) {
311
+			return $qty;
312
+		} else {
313
+			return 0;
314
+		}
315
+	}
316
+
317
+
318
+	/**
319
+	 * increments ticket reserved based on quantity passed
320
+	 *
321
+	 * @param    EE_Ticket $ticket
322
+	 * @param int          $quantity
323
+	 * @return bool indicating success or failure
324
+	 * @throws EE_Error
325
+	 */
326
+	protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
327
+	{
328
+		// self::debug hardcoded to false
329
+		if (self::debug) {
330
+			echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
331
+		}
332
+		return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:' . __LINE__);
333
+	}
334
+
335
+
336
+	/**
337
+	 * @param  EE_Ticket $ticket
338
+	 * @param  int       $quantity
339
+	 * @return bool
340
+	 * @throws EE_Error
341
+	 */
342
+	protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
343
+	{
344
+		// self::debug hardcoded to false
345
+		if (self::debug) {
346
+			echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
347
+			echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
348
+		}
349
+		$ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
350
+		if (self::debug) {
351
+			echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
352
+		}
353
+		return $ticket->save() ? 1 : 0;
354
+	}
355
+
356
+
357
+	/**
358
+	 * removes quantities within the ticket selector based on zero ticket availability
359
+	 *
360
+	 * @param    EE_Ticket $ticket
361
+	 * @return    void
362
+	 * @throws UnexpectedEntityException
363
+	 * @throws EE_Error
364
+	 */
365
+	protected function _ticket_sold_out(EE_Ticket $ticket)
366
+	{
367
+		// self::debug hardcoded to false
368
+		if (self::debug) {
369
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
370
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
371
+		}
372
+		$this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
373
+	}
374
+
375
+
376
+	/**
377
+	 * adjusts quantities within the ticket selector based on decreased ticket availability
378
+	 *
379
+	 * @param    EE_Ticket $ticket
380
+	 * @return void
381
+	 * @throws UnexpectedEntityException
382
+	 * @throws EE_Error
383
+	 */
384
+	protected function _ticket_quantity_decremented(EE_Ticket $ticket)
385
+	{
386
+		// self::debug hardcoded to false
387
+		if (self::debug) {
388
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
389
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
390
+		}
391
+		$this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
392
+	}
393
+
394
+
395
+	/**
396
+	 * builds string out of ticket and event name
397
+	 *
398
+	 * @param    EE_Ticket $ticket
399
+	 * @return string
400
+	 * @throws UnexpectedEntityException
401
+	 * @throws EE_Error
402
+	 */
403
+	protected function _get_ticket_and_event_name(EE_Ticket $ticket)
404
+	{
405
+		$event = $ticket->get_related_event();
406
+		if ($event instanceof EE_Event) {
407
+			$ticket_name = sprintf(
408
+				_x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
409
+				$ticket->name(),
410
+				$event->name()
411
+			);
412
+		} else {
413
+			$ticket_name = $ticket->name();
414
+		}
415
+		return $ticket_name;
416
+	}
417
+
418
+
419
+
420
+	/********************************** EVENT CART  **********************************/
421
+
422
+
423
+	/**
424
+	 * releases or reserves ticket(s) based on quantity passed
425
+	 *
426
+	 * @param  EE_Line_Item $line_item
427
+	 * @param  int          $quantity
428
+	 * @return void
429
+	 * @throws EE_Error
430
+	 * @throws InvalidArgumentException
431
+	 * @throws InvalidDataTypeException
432
+	 * @throws InvalidInterfaceException
433
+	 */
434
+	public static function ticket_quantity_updated(EE_Line_Item $line_item, $quantity = 1)
435
+	{
436
+		$ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
437
+		if ($ticket instanceof EE_Ticket) {
438
+			$ticket->add_extra_meta(
439
+				EE_Ticket::META_KEY_TICKET_RESERVATIONS,
440
+				__LINE__ . ') ' . __METHOD__ . '()'
441
+			);
442
+			if ($quantity > 0) {
443
+				EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
444
+			} else {
445
+				EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
446
+			}
447
+		}
448
+	}
449
+
450
+
451
+	/**
452
+	 * releases reserved ticket(s) based on quantity passed
453
+	 *
454
+	 * @param  EE_Ticket $ticket
455
+	 * @param  int       $quantity
456
+	 * @return void
457
+	 * @throws EE_Error
458
+	 */
459
+	public static function ticket_removed_from_cart(EE_Ticket $ticket, $quantity = 1)
460
+	{
461
+		$ticket->add_extra_meta(
462
+			EE_Ticket::META_KEY_TICKET_RESERVATIONS,
463
+			__LINE__ . ') ' . __METHOD__ . '()'
464
+		);
465
+		EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
466
+	}
467
+
468
+
469
+
470
+	/********************************** POST_NOTICES  **********************************/
471
+
472
+
473
+	/**
474
+	 * @return void
475
+	 * @throws EE_Error
476
+	 * @throws InvalidArgumentException
477
+	 * @throws ReflectionException
478
+	 * @throws InvalidDataTypeException
479
+	 * @throws InvalidInterfaceException
480
+	 */
481
+	public static function post_notices()
482
+	{
483
+		EED_Ticket_Sales_Monitor::instance()->_post_notices();
484
+	}
485
+
486
+
487
+	/**
488
+	 * @return void
489
+	 * @throws EE_Error
490
+	 * @throws InvalidArgumentException
491
+	 * @throws ReflectionException
492
+	 * @throws InvalidDataTypeException
493
+	 * @throws InvalidInterfaceException
494
+	 */
495
+	protected function _post_notices()
496
+	{
497
+		// self::debug hardcoded to false
498
+		if (self::debug) {
499
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
500
+		}
501
+		$refresh_msg = '';
502
+		$none_added_msg = '';
503
+		if (defined('DOING_AJAX') && DOING_AJAX) {
504
+			$refresh_msg = esc_html__(
505
+				'Please refresh the page to view updated ticket quantities.',
506
+				'event_espresso'
507
+			);
508
+			$none_added_msg = esc_html__('No tickets were added for the event.', 'event_espresso');
509
+		}
510
+		if (! empty($this->sold_out_tickets)) {
511
+			EE_Error::add_attention(
512
+				sprintf(
513
+					apply_filters(
514
+						'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
515
+						esc_html__(
516
+							'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
517
+							'event_espresso'
518
+						)
519
+					),
520
+					'<br />',
521
+					implode('<br />', $this->sold_out_tickets),
522
+					$none_added_msg,
523
+					$refresh_msg
524
+				)
525
+			);
526
+			// alter code flow in the Ticket Selector for better UX
527
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
528
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
529
+			$this->sold_out_tickets = array();
530
+			// and reset the cart
531
+			EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
532
+		}
533
+		if (! empty($this->decremented_tickets)) {
534
+			EE_Error::add_attention(
535
+				sprintf(
536
+					apply_filters(
537
+						'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
538
+						esc_html__(
539
+							'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
540
+							'event_espresso'
541
+						)
542
+					),
543
+					'<br />',
544
+					implode('<br />', $this->decremented_tickets),
545
+					$none_added_msg,
546
+					$refresh_msg
547
+				)
548
+			);
549
+			$this->decremented_tickets = array();
550
+		}
551
+	}
552
+
553
+
554
+
555
+	/********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
556
+
557
+
558
+	/**
559
+	 * releases reserved tickets for all registrations of an EE_Transaction
560
+	 * by default, will NOT release tickets for finalized transactions
561
+	 *
562
+	 * @param    EE_Transaction $transaction
563
+	 * @return int
564
+	 * @throws EE_Error
565
+	 * @throws InvalidSessionDataException
566
+	 */
567
+	protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
568
+	{
569
+		// self::debug hardcoded to false
570
+		if (self::debug) {
571
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
572
+			echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
573
+			echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
574
+		}
575
+		// check if 'finalize_registration' step has been completed...
576
+		$finalized = $transaction->reg_step_completed('finalize_registration');
577
+		if (self::debug) {
578
+			// DEBUG LOG
579
+			EEH_Debug_Tools::log(
580
+				__CLASS__,
581
+				__FUNCTION__,
582
+				__LINE__,
583
+				array('finalized' => $finalized),
584
+				false,
585
+				'EE_Transaction: ' . $transaction->ID()
586
+			);
587
+		}
588
+		// how many tickets were released
589
+		$count = 0;
590
+		if (self::debug) {
591
+			echo self::$nl . ' . . . TXN finalized: ' . $finalized;
592
+		}
593
+		$release_tickets_with_TXN_status = array(
594
+			EEM_Transaction::failed_status_code,
595
+			EEM_Transaction::abandoned_status_code,
596
+			EEM_Transaction::incomplete_status_code,
597
+		);
598
+		$events = array();
599
+		// if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
600
+		if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
601
+			// cancel any reserved tickets for registrations that were not approved
602
+			$registrations = $transaction->registrations();
603
+			if (self::debug) {
604
+				echo self::$nl . ' . . . # registrations: ' . count($registrations);
605
+				$reg = reset($registrations);
606
+				$ticket = $reg->ticket();
607
+				if ($ticket instanceof EE_Ticket) {
608
+					$ticket->add_extra_meta(
609
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
610
+						__LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
611
+					);
612
+				}
613
+			}
614
+			if (! empty($registrations)) {
615
+				foreach ($registrations as $registration) {
616
+					if (
617
+						$registration instanceof EE_Registration
618
+						&& $this->_release_reserved_ticket_for_registration($registration, $transaction)
619
+					) {
620
+						$count++;
621
+						$events[ $registration->event_ID() ] = $registration->event();
622
+					}
623
+				}
624
+			}
625
+		}
626
+		if ($events !== array()) {
627
+			foreach ($events as $event) {
628
+				/** @var EE_Event $event */
629
+				$event->perform_sold_out_status_check();
630
+			}
631
+		}
632
+		return $count;
633
+	}
634
+
635
+
636
+	/**
637
+	 * releases reserved tickets for an EE_Registration
638
+	 * by default, will NOT release tickets for APPROVED registrations
639
+	 *
640
+	 * @param EE_Registration $registration
641
+	 * @param EE_Transaction  $transaction
642
+	 * @return int
643
+	 * @throws EE_Error
644
+	 */
645
+	protected function _release_reserved_ticket_for_registration(
646
+		EE_Registration $registration,
647
+		EE_Transaction $transaction
648
+	) {
649
+		$STS_ID = $transaction->status_ID();
650
+		// self::debug hardcoded to false
651
+		if (self::debug) {
652
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
653
+			echo self::$nl . ' . . registration->ID: ' . $registration->ID();
654
+			echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
655
+			echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
656
+		}
657
+		if (
658 658
 // release Tickets for Failed Transactions and Abandoned Transactions
659
-            $STS_ID === EEM_Transaction::failed_status_code
660
-            || $STS_ID === EEM_Transaction::abandoned_status_code
661
-            || (
662
-                // also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
663
-                $STS_ID === EEM_Transaction::incomplete_status_code
664
-                && $registration->status_ID() !== EEM_Registration::status_id_approved
665
-            )
666
-        ) {
667
-            if (self::debug) {
668
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
669
-                $rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
670
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
671
-                var_dump($rsrvd);
672
-            }
673
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
674
-            return 1;
675
-        }
676
-        return 0;
677
-    }
678
-
679
-
680
-
681
-    /********************************** SESSION_CART_RESET  **********************************/
682
-
683
-
684
-    /**
685
-     * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
686
-     *
687
-     * @param EE_Session $session
688
-     * @return void
689
-     * @throws EE_Error
690
-     * @throws InvalidArgumentException
691
-     * @throws ReflectionException
692
-     * @throws InvalidDataTypeException
693
-     * @throws InvalidInterfaceException
694
-     */
695
-    public static function session_cart_reset(EE_Session $session)
696
-    {
697
-        // don't release tickets if checkout was already reset
698
-        if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
699
-            return;
700
-        }
701
-        // self::debug hardcoded to false
702
-        if (self::debug) {
703
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
704
-        }
705
-        // first check of the session has a valid Checkout object
706
-        $checkout = $session->checkout();
707
-        if ($checkout instanceof EE_Checkout) {
708
-            // and use that to clear ticket reservations because it will update the associated registration meta data
709
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
710
-            return;
711
-        }
712
-        $cart = $session->cart();
713
-        if ($cart instanceof EE_Cart) {
714
-            if (self::debug) {
715
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
716
-            }
717
-            EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
718
-        } else {
719
-            if (self::debug) {
720
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
721
-                var_export($cart, true);
722
-            }
723
-        }
724
-    }
725
-
726
-
727
-    /**
728
-     * releases reserved tickets in the EE_Cart
729
-     *
730
-     * @param EE_Cart $cart
731
-     * @return void
732
-     * @throws EE_Error
733
-     * @throws InvalidArgumentException
734
-     * @throws ReflectionException
735
-     * @throws InvalidDataTypeException
736
-     * @throws InvalidInterfaceException
737
-     */
738
-    protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
739
-    {
740
-        // self::debug hardcoded to false
741
-        if (self::debug) {
742
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
743
-        }
744
-        $ticket_line_items = $cart->get_tickets();
745
-        if (empty($ticket_line_items)) {
746
-            return;
747
-        }
748
-        if (self::debug) {
749
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
750
-        }
751
-        foreach ($ticket_line_items as $ticket_line_item) {
752
-            if (self::debug) {
753
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
754
-            }
755
-            if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
756
-                if (self::debug) {
757
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
758
-                }
759
-                $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
760
-                if ($ticket instanceof EE_Ticket) {
761
-                    if (self::debug) {
762
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
763
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
764
-                    }
765
-                    $ticket->add_extra_meta(
766
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
767
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
768
-                    );
769
-                    $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
770
-                }
771
-            }
772
-        }
773
-        if (self::debug) {
774
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
775
-        }
776
-    }
777
-
778
-
779
-
780
-    /********************************** SESSION_CHECKOUT_RESET  **********************************/
781
-
782
-
783
-    /**
784
-     * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
785
-     *
786
-     * @param EE_Session $session
787
-     * @return void
788
-     * @throws EE_Error
789
-     * @throws InvalidSessionDataException
790
-     */
791
-    public static function session_checkout_reset(EE_Session $session)
792
-    {
793
-        // don't release tickets if cart was already reset
794
-        if (did_action('AHEE__EE_Session__reset_cart__before_reset')) {
795
-            return;
796
-        }
797
-        $checkout = $session->checkout();
798
-        if ($checkout instanceof EE_Checkout) {
799
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
800
-        }
801
-    }
802
-
803
-
804
-    /**
805
-     * releases reserved tickets for the EE_Checkout->transaction
806
-     *
807
-     * @param EE_Checkout $checkout
808
-     * @return void
809
-     * @throws EE_Error
810
-     * @throws InvalidSessionDataException
811
-     */
812
-    protected function _session_checkout_reset(EE_Checkout $checkout)
813
-    {
814
-        // self::debug hardcoded to false
815
-        if (self::debug) {
816
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
817
-        }
818
-        // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
819
-        if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
820
-            return;
821
-        }
822
-        $this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
823
-    }
824
-
825
-
826
-
827
-    /********************************** SESSION_EXPIRED_RESET  **********************************/
828
-
829
-
830
-    /**
831
-     * @param    EE_Session $session
832
-     * @return    void
833
-     */
834
-    public static function session_expired_reset(EE_Session $session)
835
-    {
836
-    }
837
-
838
-
839
-
840
-    /********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
841
-
842
-
843
-    /**
844
-     * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
845
-     * by default, will NOT release tickets for free transactions, or any that have received a payment
846
-     *
847
-     * @param EE_Transaction $transaction
848
-     * @return void
849
-     * @throws EE_Error
850
-     * @throws InvalidSessionDataException
851
-     */
852
-    public static function process_abandoned_transactions(EE_Transaction $transaction)
853
-    {
854
-        // is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
855
-        if ($transaction->is_free() || $transaction->paid() > 0) {
856
-            // self::debug hardcoded to false
857
-            if (self::debug) {
858
-                // DEBUG LOG
859
-                EEH_Debug_Tools::log(
860
-                    __CLASS__,
861
-                    __FUNCTION__,
862
-                    __LINE__,
863
-                    array($transaction),
864
-                    false,
865
-                    'EE_Transaction: ' . $transaction->ID()
866
-                );
867
-            }
868
-            return;
869
-        }
870
-        // have their been any successful payments made ?
871
-        $payments = $transaction->payments();
872
-        foreach ($payments as $payment) {
873
-            if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
874
-                if (self::debug) {
875
-                    // DEBUG LOG
876
-                    EEH_Debug_Tools::log(
877
-                        __CLASS__,
878
-                        __FUNCTION__,
879
-                        __LINE__,
880
-                        array($payment),
881
-                        false,
882
-                        'EE_Transaction: ' . $transaction->ID()
883
-                    );
884
-                }
885
-                return;
886
-            }
887
-        }
888
-        // since you haven't even attempted to pay for your ticket...
889
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
890
-    }
891
-
892
-
893
-
894
-    /********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
895
-
896
-
897
-    /**
898
-     * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
899
-     *
900
-     * @param EE_Transaction $transaction
901
-     * @return void
902
-     * @throws EE_Error
903
-     * @throws InvalidSessionDataException
904
-     */
905
-    public static function process_failed_transactions(EE_Transaction $transaction)
906
-    {
907
-        // since you haven't even attempted to pay for your ticket...
908
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
909
-    }
910
-
911
-
912
-
913
-    /********************************** RESET RESERVATION COUNTS  *********************************/
914
-
915
-
916
-    /**
917
-     * Resets the ticket and datetime reserved counts.
918
-     *
919
-     * For all the tickets with reservations, recalculates what their actual reserved counts should be based
920
-     * on the valid transactions.
921
-     *
922
-     * @return int number of tickets whose reservations were released.
923
-     * @throws EE_Error
924
-     * @throws DomainException
925
-     * @throws InvalidDataTypeException
926
-     * @throws InvalidInterfaceException
927
-     * @throws InvalidArgumentException
928
-     * @throws UnexpectedEntityException
929
-     * @throws ReflectionException
930
-     */
931
-    public static function reset_reservation_counts()
932
-    {
933
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
934
-        $valid_reserved_tickets = array();
935
-        /** @var EE_Transaction[] $transactions_in_progress */
936
-        $transactions_in_progress = EEM_Transaction::instance()->get_transactions_in_progress();
937
-        foreach ($transactions_in_progress as $transaction) {
938
-            // if this TXN has been fully completed, then skip it
939
-            if ($transaction->reg_step_completed('finalize_registration')) {
940
-                continue;
941
-            }
942
-            $total_line_item = $transaction->total_line_item();
943
-            // $transaction_in_progress->line
944
-            if (! $total_line_item instanceof EE_Line_Item) {
945
-                throw new DomainException(
946
-                    esc_html__(
947
-                        'Transaction does not have a valid Total Line Item associated with it.',
948
-                        'event_espresso'
949
-                    )
950
-                );
951
-            }
952
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
953
-                $total_line_item
954
-            );
955
-        }
956
-        $total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
957
-        foreach ($total_line_items as $total_line_item) {
958
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
959
-                $total_line_item
960
-            );
961
-        }
962
-        $tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
963
-        return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
964
-            $tickets_with_reservations,
965
-            $valid_reserved_tickets,
966
-            __FUNCTION__
967
-        );
968
-    }
969
-
970
-
971
-    /**
972
-     * @param EE_Line_Item $total_line_item
973
-     * @return EE_Line_Item[]
974
-     */
975
-    private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item)
976
-    {
977
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
978
-        $valid_reserved_tickets = array();
979
-        $ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
980
-        foreach ($ticket_line_items as $ticket_line_item) {
981
-            if ($ticket_line_item instanceof EE_Line_Item) {
982
-                $valid_reserved_tickets[ $ticket_line_item->ID() ] = $ticket_line_item;
983
-            }
984
-        }
985
-        return $valid_reserved_tickets;
986
-    }
987
-
988
-
989
-    /**
990
-     * Releases ticket and datetime reservations (ie, reduces the number of reserved spots on them).
991
-     *
992
-     * Given the list of tickets which have reserved spots on them, uses the complete list of line items for tickets
993
-     * whose transactions aren't complete and also aren't yet expired (ie, they're incomplete and younger than the
994
-     * session's expiry time) to update the ticket (and their datetimes') reserved counts.
995
-     *
996
-     * @param EE_Ticket[]    $tickets_with_reservations all tickets with TKT_reserved > 0
997
-     * @param EE_Line_Item[] $valid_reserved_ticket_line_items all line items for tickets and incomplete transactions
998
-     *                       whose session has NOT expired. We will use these to determine the number of ticket
999
-     *                       reservations are now invalid. We don't use the list of invalid ticket line items because
1000
-     *                       we don't know which of those have already been taken into account when reducing ticket
1001
-     *                       reservation counts, and which haven't.
1002
-     * @return int
1003
-     * @throws UnexpectedEntityException
1004
-     * @throws DomainException
1005
-     * @throws EE_Error
1006
-     */
1007
-    protected static function release_reservations_for_tickets(
1008
-        array $tickets_with_reservations,
1009
-        array $valid_reserved_ticket_line_items = array(),
1010
-        $source = ''
1011
-    ) {
1012
-        $total_tickets_released = 0;
1013
-        $sold_out_events = array();
1014
-        foreach ($tickets_with_reservations as $ticket_with_reservations) {
1015
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
1016
-                continue;
1017
-            }
1018
-            // The $valid_reserved_ticket_line_items tells us what the reserved count on their tickets (and datetimes)
1019
-            // SHOULD be. Instead of just directly updating the list, we're going to use EE_Ticket::decreaseReserved()
1020
-            // to try to avoid race conditions, so instead of just finding the number to update TO, we're going to find
1021
-            // the number to RELEASE. It's the same end result, just different path.
1022
-            // Begin by assuming we're going to release all the reservations on this ticket.
1023
-            $expired_reservations_count = $ticket_with_reservations->reserved();
1024
-            // Now reduce that number using the list of current valid reservations.
1025
-            foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
1026
-                if (
1027
-                    $valid_reserved_ticket_line_item instanceof EE_Line_Item
1028
-                    && $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
1029
-                ) {
1030
-                    $expired_reservations_count -= $valid_reserved_ticket_line_item->quantity();
1031
-                }
1032
-            }
1033
-            // Only bother saving the tickets and datetimes if we're actually going to release some spots.
1034
-            if ($expired_reservations_count > 0) {
1035
-                $ticket_with_reservations->add_extra_meta(
1036
-                    EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1037
-                    __LINE__ . ') ' . $source . '()'
1038
-                );
1039
-                $ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:' . __LINE__);
1040
-                $total_tickets_released += $expired_reservations_count;
1041
-                $event = $ticket_with_reservations->get_related_event();
1042
-                // track sold out events
1043
-                if ($event instanceof EE_Event && $event->is_sold_out()) {
1044
-                    $sold_out_events[] = $event;
1045
-                }
1046
-            }
1047
-        }
1048
-        // Double check whether sold out events should remain sold out after releasing tickets
1049
-        if ($sold_out_events !== array()) {
1050
-            foreach ($sold_out_events as $sold_out_event) {
1051
-                /** @var EE_Event $sold_out_event */
1052
-                $sold_out_event->perform_sold_out_status_check();
1053
-            }
1054
-        }
1055
-        return $total_tickets_released;
1056
-    }
1057
-
1058
-
1059
-
1060
-    /********************************** SHUTDOWN  **********************************/
1061
-
1062
-
1063
-    /**
1064
-     * @param int $timestamp
1065
-     * @return false|int
1066
-     * @throws EE_Error
1067
-     * @throws InvalidArgumentException
1068
-     * @throws InvalidDataTypeException
1069
-     * @throws InvalidInterfaceException
1070
-     */
1071
-    public static function clear_expired_line_items_with_no_transaction($timestamp = 0)
1072
-    {
1073
-        /** @type WPDB $wpdb */
1074
-        global $wpdb;
1075
-        if (! absint($timestamp)) {
1076
-            /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1077
-            $session_lifespan = LoaderFactory::getLoader()->getShared(
1078
-                'EventEspresso\core\domain\values\session\SessionLifespan'
1079
-            );
1080
-            $timestamp = $session_lifespan->expiration();
1081
-        }
1082
-        return $wpdb->query(
1083
-            $wpdb->prepare(
1084
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
659
+			$STS_ID === EEM_Transaction::failed_status_code
660
+			|| $STS_ID === EEM_Transaction::abandoned_status_code
661
+			|| (
662
+				// also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
663
+				$STS_ID === EEM_Transaction::incomplete_status_code
664
+				&& $registration->status_ID() !== EEM_Registration::status_id_approved
665
+			)
666
+		) {
667
+			if (self::debug) {
668
+				echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
669
+				$rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
670
+				echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
671
+				var_dump($rsrvd);
672
+			}
673
+			$registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
674
+			return 1;
675
+		}
676
+		return 0;
677
+	}
678
+
679
+
680
+
681
+	/********************************** SESSION_CART_RESET  **********************************/
682
+
683
+
684
+	/**
685
+	 * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
686
+	 *
687
+	 * @param EE_Session $session
688
+	 * @return void
689
+	 * @throws EE_Error
690
+	 * @throws InvalidArgumentException
691
+	 * @throws ReflectionException
692
+	 * @throws InvalidDataTypeException
693
+	 * @throws InvalidInterfaceException
694
+	 */
695
+	public static function session_cart_reset(EE_Session $session)
696
+	{
697
+		// don't release tickets if checkout was already reset
698
+		if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
699
+			return;
700
+		}
701
+		// self::debug hardcoded to false
702
+		if (self::debug) {
703
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
704
+		}
705
+		// first check of the session has a valid Checkout object
706
+		$checkout = $session->checkout();
707
+		if ($checkout instanceof EE_Checkout) {
708
+			// and use that to clear ticket reservations because it will update the associated registration meta data
709
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
710
+			return;
711
+		}
712
+		$cart = $session->cart();
713
+		if ($cart instanceof EE_Cart) {
714
+			if (self::debug) {
715
+				echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
716
+			}
717
+			EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
718
+		} else {
719
+			if (self::debug) {
720
+				echo self::$nl . self::$nl . ' invalid EE_Cart: ';
721
+				var_export($cart, true);
722
+			}
723
+		}
724
+	}
725
+
726
+
727
+	/**
728
+	 * releases reserved tickets in the EE_Cart
729
+	 *
730
+	 * @param EE_Cart $cart
731
+	 * @return void
732
+	 * @throws EE_Error
733
+	 * @throws InvalidArgumentException
734
+	 * @throws ReflectionException
735
+	 * @throws InvalidDataTypeException
736
+	 * @throws InvalidInterfaceException
737
+	 */
738
+	protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
739
+	{
740
+		// self::debug hardcoded to false
741
+		if (self::debug) {
742
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
743
+		}
744
+		$ticket_line_items = $cart->get_tickets();
745
+		if (empty($ticket_line_items)) {
746
+			return;
747
+		}
748
+		if (self::debug) {
749
+			echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
750
+		}
751
+		foreach ($ticket_line_items as $ticket_line_item) {
752
+			if (self::debug) {
753
+				echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
754
+			}
755
+			if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
756
+				if (self::debug) {
757
+					echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
758
+				}
759
+				$ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
760
+				if ($ticket instanceof EE_Ticket) {
761
+					if (self::debug) {
762
+						echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
763
+						echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
764
+					}
765
+					$ticket->add_extra_meta(
766
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
767
+						__LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
768
+					);
769
+					$this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
770
+				}
771
+			}
772
+		}
773
+		if (self::debug) {
774
+			echo self::$nl . self::$nl . ' RESET COMPLETED ';
775
+		}
776
+	}
777
+
778
+
779
+
780
+	/********************************** SESSION_CHECKOUT_RESET  **********************************/
781
+
782
+
783
+	/**
784
+	 * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
785
+	 *
786
+	 * @param EE_Session $session
787
+	 * @return void
788
+	 * @throws EE_Error
789
+	 * @throws InvalidSessionDataException
790
+	 */
791
+	public static function session_checkout_reset(EE_Session $session)
792
+	{
793
+		// don't release tickets if cart was already reset
794
+		if (did_action('AHEE__EE_Session__reset_cart__before_reset')) {
795
+			return;
796
+		}
797
+		$checkout = $session->checkout();
798
+		if ($checkout instanceof EE_Checkout) {
799
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
800
+		}
801
+	}
802
+
803
+
804
+	/**
805
+	 * releases reserved tickets for the EE_Checkout->transaction
806
+	 *
807
+	 * @param EE_Checkout $checkout
808
+	 * @return void
809
+	 * @throws EE_Error
810
+	 * @throws InvalidSessionDataException
811
+	 */
812
+	protected function _session_checkout_reset(EE_Checkout $checkout)
813
+	{
814
+		// self::debug hardcoded to false
815
+		if (self::debug) {
816
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
817
+		}
818
+		// we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
819
+		if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
820
+			return;
821
+		}
822
+		$this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
823
+	}
824
+
825
+
826
+
827
+	/********************************** SESSION_EXPIRED_RESET  **********************************/
828
+
829
+
830
+	/**
831
+	 * @param    EE_Session $session
832
+	 * @return    void
833
+	 */
834
+	public static function session_expired_reset(EE_Session $session)
835
+	{
836
+	}
837
+
838
+
839
+
840
+	/********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
841
+
842
+
843
+	/**
844
+	 * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
845
+	 * by default, will NOT release tickets for free transactions, or any that have received a payment
846
+	 *
847
+	 * @param EE_Transaction $transaction
848
+	 * @return void
849
+	 * @throws EE_Error
850
+	 * @throws InvalidSessionDataException
851
+	 */
852
+	public static function process_abandoned_transactions(EE_Transaction $transaction)
853
+	{
854
+		// is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
855
+		if ($transaction->is_free() || $transaction->paid() > 0) {
856
+			// self::debug hardcoded to false
857
+			if (self::debug) {
858
+				// DEBUG LOG
859
+				EEH_Debug_Tools::log(
860
+					__CLASS__,
861
+					__FUNCTION__,
862
+					__LINE__,
863
+					array($transaction),
864
+					false,
865
+					'EE_Transaction: ' . $transaction->ID()
866
+				);
867
+			}
868
+			return;
869
+		}
870
+		// have their been any successful payments made ?
871
+		$payments = $transaction->payments();
872
+		foreach ($payments as $payment) {
873
+			if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
874
+				if (self::debug) {
875
+					// DEBUG LOG
876
+					EEH_Debug_Tools::log(
877
+						__CLASS__,
878
+						__FUNCTION__,
879
+						__LINE__,
880
+						array($payment),
881
+						false,
882
+						'EE_Transaction: ' . $transaction->ID()
883
+					);
884
+				}
885
+				return;
886
+			}
887
+		}
888
+		// since you haven't even attempted to pay for your ticket...
889
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
890
+	}
891
+
892
+
893
+
894
+	/********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
895
+
896
+
897
+	/**
898
+	 * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
899
+	 *
900
+	 * @param EE_Transaction $transaction
901
+	 * @return void
902
+	 * @throws EE_Error
903
+	 * @throws InvalidSessionDataException
904
+	 */
905
+	public static function process_failed_transactions(EE_Transaction $transaction)
906
+	{
907
+		// since you haven't even attempted to pay for your ticket...
908
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
909
+	}
910
+
911
+
912
+
913
+	/********************************** RESET RESERVATION COUNTS  *********************************/
914
+
915
+
916
+	/**
917
+	 * Resets the ticket and datetime reserved counts.
918
+	 *
919
+	 * For all the tickets with reservations, recalculates what their actual reserved counts should be based
920
+	 * on the valid transactions.
921
+	 *
922
+	 * @return int number of tickets whose reservations were released.
923
+	 * @throws EE_Error
924
+	 * @throws DomainException
925
+	 * @throws InvalidDataTypeException
926
+	 * @throws InvalidInterfaceException
927
+	 * @throws InvalidArgumentException
928
+	 * @throws UnexpectedEntityException
929
+	 * @throws ReflectionException
930
+	 */
931
+	public static function reset_reservation_counts()
932
+	{
933
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
934
+		$valid_reserved_tickets = array();
935
+		/** @var EE_Transaction[] $transactions_in_progress */
936
+		$transactions_in_progress = EEM_Transaction::instance()->get_transactions_in_progress();
937
+		foreach ($transactions_in_progress as $transaction) {
938
+			// if this TXN has been fully completed, then skip it
939
+			if ($transaction->reg_step_completed('finalize_registration')) {
940
+				continue;
941
+			}
942
+			$total_line_item = $transaction->total_line_item();
943
+			// $transaction_in_progress->line
944
+			if (! $total_line_item instanceof EE_Line_Item) {
945
+				throw new DomainException(
946
+					esc_html__(
947
+						'Transaction does not have a valid Total Line Item associated with it.',
948
+						'event_espresso'
949
+					)
950
+				);
951
+			}
952
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
953
+				$total_line_item
954
+			);
955
+		}
956
+		$total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
957
+		foreach ($total_line_items as $total_line_item) {
958
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
959
+				$total_line_item
960
+			);
961
+		}
962
+		$tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
963
+		return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
964
+			$tickets_with_reservations,
965
+			$valid_reserved_tickets,
966
+			__FUNCTION__
967
+		);
968
+	}
969
+
970
+
971
+	/**
972
+	 * @param EE_Line_Item $total_line_item
973
+	 * @return EE_Line_Item[]
974
+	 */
975
+	private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item)
976
+	{
977
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
978
+		$valid_reserved_tickets = array();
979
+		$ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
980
+		foreach ($ticket_line_items as $ticket_line_item) {
981
+			if ($ticket_line_item instanceof EE_Line_Item) {
982
+				$valid_reserved_tickets[ $ticket_line_item->ID() ] = $ticket_line_item;
983
+			}
984
+		}
985
+		return $valid_reserved_tickets;
986
+	}
987
+
988
+
989
+	/**
990
+	 * Releases ticket and datetime reservations (ie, reduces the number of reserved spots on them).
991
+	 *
992
+	 * Given the list of tickets which have reserved spots on them, uses the complete list of line items for tickets
993
+	 * whose transactions aren't complete and also aren't yet expired (ie, they're incomplete and younger than the
994
+	 * session's expiry time) to update the ticket (and their datetimes') reserved counts.
995
+	 *
996
+	 * @param EE_Ticket[]    $tickets_with_reservations all tickets with TKT_reserved > 0
997
+	 * @param EE_Line_Item[] $valid_reserved_ticket_line_items all line items for tickets and incomplete transactions
998
+	 *                       whose session has NOT expired. We will use these to determine the number of ticket
999
+	 *                       reservations are now invalid. We don't use the list of invalid ticket line items because
1000
+	 *                       we don't know which of those have already been taken into account when reducing ticket
1001
+	 *                       reservation counts, and which haven't.
1002
+	 * @return int
1003
+	 * @throws UnexpectedEntityException
1004
+	 * @throws DomainException
1005
+	 * @throws EE_Error
1006
+	 */
1007
+	protected static function release_reservations_for_tickets(
1008
+		array $tickets_with_reservations,
1009
+		array $valid_reserved_ticket_line_items = array(),
1010
+		$source = ''
1011
+	) {
1012
+		$total_tickets_released = 0;
1013
+		$sold_out_events = array();
1014
+		foreach ($tickets_with_reservations as $ticket_with_reservations) {
1015
+			if (! $ticket_with_reservations instanceof EE_Ticket) {
1016
+				continue;
1017
+			}
1018
+			// The $valid_reserved_ticket_line_items tells us what the reserved count on their tickets (and datetimes)
1019
+			// SHOULD be. Instead of just directly updating the list, we're going to use EE_Ticket::decreaseReserved()
1020
+			// to try to avoid race conditions, so instead of just finding the number to update TO, we're going to find
1021
+			// the number to RELEASE. It's the same end result, just different path.
1022
+			// Begin by assuming we're going to release all the reservations on this ticket.
1023
+			$expired_reservations_count = $ticket_with_reservations->reserved();
1024
+			// Now reduce that number using the list of current valid reservations.
1025
+			foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
1026
+				if (
1027
+					$valid_reserved_ticket_line_item instanceof EE_Line_Item
1028
+					&& $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
1029
+				) {
1030
+					$expired_reservations_count -= $valid_reserved_ticket_line_item->quantity();
1031
+				}
1032
+			}
1033
+			// Only bother saving the tickets and datetimes if we're actually going to release some spots.
1034
+			if ($expired_reservations_count > 0) {
1035
+				$ticket_with_reservations->add_extra_meta(
1036
+					EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1037
+					__LINE__ . ') ' . $source . '()'
1038
+				);
1039
+				$ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:' . __LINE__);
1040
+				$total_tickets_released += $expired_reservations_count;
1041
+				$event = $ticket_with_reservations->get_related_event();
1042
+				// track sold out events
1043
+				if ($event instanceof EE_Event && $event->is_sold_out()) {
1044
+					$sold_out_events[] = $event;
1045
+				}
1046
+			}
1047
+		}
1048
+		// Double check whether sold out events should remain sold out after releasing tickets
1049
+		if ($sold_out_events !== array()) {
1050
+			foreach ($sold_out_events as $sold_out_event) {
1051
+				/** @var EE_Event $sold_out_event */
1052
+				$sold_out_event->perform_sold_out_status_check();
1053
+			}
1054
+		}
1055
+		return $total_tickets_released;
1056
+	}
1057
+
1058
+
1059
+
1060
+	/********************************** SHUTDOWN  **********************************/
1061
+
1062
+
1063
+	/**
1064
+	 * @param int $timestamp
1065
+	 * @return false|int
1066
+	 * @throws EE_Error
1067
+	 * @throws InvalidArgumentException
1068
+	 * @throws InvalidDataTypeException
1069
+	 * @throws InvalidInterfaceException
1070
+	 */
1071
+	public static function clear_expired_line_items_with_no_transaction($timestamp = 0)
1072
+	{
1073
+		/** @type WPDB $wpdb */
1074
+		global $wpdb;
1075
+		if (! absint($timestamp)) {
1076
+			/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1077
+			$session_lifespan = LoaderFactory::getLoader()->getShared(
1078
+				'EventEspresso\core\domain\values\session\SessionLifespan'
1079
+			);
1080
+			$timestamp = $session_lifespan->expiration();
1081
+		}
1082
+		return $wpdb->query(
1083
+			$wpdb->prepare(
1084
+				'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1085 1085
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1086
-                // use GMT time because that's what LIN_timestamps are in
1087
-                date('Y-m-d H:i:s', $timestamp)
1088
-            )
1089
-        );
1090
-    }
1086
+				// use GMT time because that's what LIN_timestamps are in
1087
+				date('Y-m-d H:i:s', $timestamp)
1088
+			)
1089
+		);
1090
+	}
1091 1091
 }
Please login to merge, or discard this patch.
thank_you_page/templates/thank-you-page-registration-details.template.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
     $event_name    = '';
22 22
     $wait_list     = false;
23 23
     foreach ($registrations as $registration) {
24
-        if (! $registration instanceof EE_Registration) {
24
+        if ( ! $registration instanceof EE_Registration) {
25 25
             continue;
26 26
         }
27 27
         if ($event_name != $registration->event_name() && ! empty($event_name)) { ?>
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
             <tbody>
56 56
             <?php
57 57
         }
58
-        if ($is_primary || (! $is_primary && $reg_url_link == $registration->reg_url_link())) { ?>
58
+        if ($is_primary || ( ! $is_primary && $reg_url_link == $registration->reg_url_link())) { ?>
59 59
             <tr>
60 60
                 <td width="40%">
61 61
                     <?php
Please login to merge, or discard this patch.
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -14,24 +14,24 @@  discard block
 block discarded – undo
14 14
 
15 15
 <div class="ee-registration-details-dv">
16 16
     <?php
17
-    $registrations = $transaction->registrations();
18
-    $registrations = is_array($registrations) ? $registrations : [];
19
-    $reg_count     = count($registrations);
20
-    $reg_cntr      = 0;
21
-    $event_name    = '';
22
-    $wait_list     = false;
23
-    foreach ($registrations as $registration) {
24
-        if (! $registration instanceof EE_Registration) {
25
-            continue;
26
-        }
27
-        if ($event_name != $registration->event_name() && ! empty($event_name)) { ?>
17
+	$registrations = $transaction->registrations();
18
+	$registrations = is_array($registrations) ? $registrations : [];
19
+	$reg_count     = count($registrations);
20
+	$reg_cntr      = 0;
21
+	$event_name    = '';
22
+	$wait_list     = false;
23
+	foreach ($registrations as $registration) {
24
+		if (! $registration instanceof EE_Registration) {
25
+			continue;
26
+		}
27
+		if ($event_name != $registration->event_name() && ! empty($event_name)) { ?>
28 28
             </tbody>
29 29
             </table>
30 30
             <?php
31
-        }
32
-        $reg_cntr++;
33
-        if ($event_name != $registration->event_name()) {
34
-            ?>
31
+		}
32
+		$reg_cntr++;
33
+		if ($event_name != $registration->event_name()) {
34
+			?>
35 35
             <h5>
36 36
                 <span class="smaller-text grey-text">
37 37
                     <?php esc_html_e('for', 'event_espresso'); ?> :
@@ -54,23 +54,23 @@  discard block
 block discarded – undo
54 54
             </thead>
55 55
             <tbody>
56 56
             <?php
57
-        }
58
-        if ($is_primary || (! $is_primary && $reg_url_link == $registration->reg_url_link())) { ?>
57
+		}
58
+		if ($is_primary || (! $is_primary && $reg_url_link == $registration->reg_url_link())) { ?>
59 59
             <tr>
60 60
                 <td width="40%">
61 61
                     <?php
62
-                    if ($registration->attendee() instanceof EE_Attendee) {
63
-                        echo esc_html($registration->attendee()->full_name(true));
64
-                    }
65
-                    ?>
62
+					if ($registration->attendee() instanceof EE_Attendee) {
63
+						echo esc_html($registration->attendee()->full_name(true));
64
+					}
65
+					?>
66 66
                     <p class="tiny-text" style="margin: .75em 0 0;">
67 67
                         <?php if ($registration->count_question_groups()) { ?>
68 68
                             <a class="ee-icon-only-lnk"
69 69
                                href="<?php echo esc_url_raw($registration->edit_attendee_information_url()); ?>"
70 70
                                title="<?php esc_attr_e(
71
-                                   'Click here to edit Attendee Information',
72
-                                   'event_espresso'
73
-                               ); ?>"
71
+								   'Click here to edit Attendee Information',
72
+								   'event_espresso'
73
+							   ); ?>"
74 74
                             >
75 75
                                 <span class="ee-icon ee-icon-user-edit"></span>
76 76
                                 <?php esc_html_e('edit info', 'event_espresso'); ?>
@@ -78,15 +78,15 @@  discard block
 block discarded – undo
78 78
                         <?php } ?>
79 79
                         <a class="ee-resend-reg-confirmation-email ee-icon-only-lnk"
80 80
                            href="<?php echo esc_url_raw(
81
-                               add_query_arg(
82
-                                   ['token' => $registration->reg_url_link(), 'resend_reg_confirmation' => 'true'],
83
-                                   EE_Registry::instance()->CFG->core->thank_you_page_url()
84
-                               )
85
-                           ); ?>"
81
+							   add_query_arg(
82
+								   ['token' => $registration->reg_url_link(), 'resend_reg_confirmation' => 'true'],
83
+								   EE_Registry::instance()->CFG->core->thank_you_page_url()
84
+							   )
85
+						   ); ?>"
86 86
                            title="<?php esc_attr_e(
87
-                               'Click here to resend the Registration Confirmation email',
88
-                               'event_espresso'
89
-                           ); ?>"
87
+							   'Click here to resend the Registration Confirmation email',
88
+							   'event_espresso'
89
+						   ); ?>"
90 90
                            rel="<?php echo esc_attr($registration->reg_url_link()); ?>"
91 91
                         >
92 92
                             <span class="dashicons dashicons-email-alt"></span>
@@ -100,27 +100,27 @@  discard block
 block discarded – undo
100 100
                 <td width="35%" class="jst-left">
101 101
                     <?php $registration->e_pretty_status(true) ?>
102 102
                     <?php
103
-                    if ($registration->status_ID() === EEM_Registration::status_id_wait_list) {
104
-                        $wait_list = true;
105
-                    }
106
-                    ?>
103
+					if ($registration->status_ID() === EEM_Registration::status_id_wait_list) {
104
+						$wait_list = true;
105
+					}
106
+					?>
107 107
                 </td>
108 108
             </tr>
109 109
             <?php do_action(
110
-                'AHEE__thank_you_page_registration_details_template__after_registration_table_row',
111
-                $registration
112
-            ); ?>
110
+				'AHEE__thank_you_page_registration_details_template__after_registration_table_row',
111
+				$registration
112
+			); ?>
113 113
             <?php
114
-            $event_name = $registration->event_name();
115
-        }
116
-        if ($reg_cntr >= $reg_count) {
117
-            ?>
114
+			$event_name = $registration->event_name();
115
+		}
116
+		if ($reg_cntr >= $reg_count) {
117
+			?>
118 118
             </tbody>
119 119
             </table>
120 120
             <?php
121
-        }
122
-    }
123
-    ?>
121
+		}
122
+	}
123
+	?>
124 124
     <?php if ($is_primary && $SPCO_attendee_information_url) { ?>
125 125
         <p class="small-text jst-rght">
126 126
             <a href='<?php echo esc_url_raw($SPCO_attendee_information_url) ?>'>
@@ -129,22 +129,22 @@  discard block
 block discarded – undo
129 129
         </p>
130 130
     <?php } ?>
131 131
     <?php
132
-    if ($wait_list) {
133
-        echo apply_filters(
134
-            'AFEE__thank_you_page_registration_details_template__wait_list_notice',
135
-            sprintf(
136
-                esc_html__(
137
-                    '%1$sre: Wait List Registrations%2$sPlease note that the total cost listed below in the Transaction Details is for ALL registrations, including those that are on the wait list, even though they can not be currently paid for. If any spaces become available however, you may be notified by the Event admin and have the opportunity to secure the remaining tickets by making a payment for them.%3$s',
138
-                    'event_espresso'
139
-                ),
140
-                '<h6 class="" style="margin-bottom:.25em;"><span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>',
141
-                '</h6 ><p class="ee-wait-list-notice">',
142
-                '</p ><br />'
143
-            )
144
-        );
145
-    }
146
-    do_action('AHEE__thank_you_page_registration_details_template__after_registration_details');
147
-    ?>
132
+	if ($wait_list) {
133
+		echo apply_filters(
134
+			'AFEE__thank_you_page_registration_details_template__wait_list_notice',
135
+			sprintf(
136
+				esc_html__(
137
+					'%1$sre: Wait List Registrations%2$sPlease note that the total cost listed below in the Transaction Details is for ALL registrations, including those that are on the wait list, even though they can not be currently paid for. If any spaces become available however, you may be notified by the Event admin and have the opportunity to secure the remaining tickets by making a payment for them.%3$s',
138
+					'event_espresso'
139
+				),
140
+				'<h6 class="" style="margin-bottom:.25em;"><span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>',
141
+				'</h6 ><p class="ee-wait-list-notice">',
142
+				'</p ><br />'
143
+			)
144
+		);
145
+	}
146
+	do_action('AHEE__thank_you_page_registration_details_template__after_registration_details');
147
+	?>
148 148
 
149 149
 </div>
150 150
 <!-- end of .registration-details -->
Please login to merge, or discard this patch.
thank_you_page/templates/thank-you-page-transaction-details.template.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -28,8 +28,8 @@  discard block
 block discarded – undo
28 28
                 <label><?php esc_html_e('Amount Owing: ', 'event_espresso'); ?></label>
29 29
             </td>
30 30
             <td class="<?php echo ($transaction->paid() == $transaction->total())
31
-                ? 'ee-transaction-paid'
32
-                : 'ee-transaction-unpaid' ?>">
31
+				? 'ee-transaction-paid'
32
+				: 'ee-transaction-unpaid' ?>">
33 33
                 <?php echo EEH_Template::format_currency($transaction->remaining()); // already escaped ?>
34 34
             </td>
35 35
         </tr>
@@ -39,7 +39,7 @@  discard block
 block discarded – undo
39 39
             </td>
40 40
             <td>
41 41
                 <?php $transaction->e_pretty_status(true);
42
-                if ($show_try_pay_again_link && ! $transaction->is_completed()) { ?>
42
+				if ($show_try_pay_again_link && ! $transaction->is_completed()) { ?>
43 43
                     &nbsp; <span class="small-text">
44 44
                         <a href='<?php echo esc_url_raw($SPCO_payment_options_url) ?>'>
45 45
                             <?php esc_html_e('View Payment Options', 'event_espresso'); ?>
@@ -57,9 +57,9 @@  discard block
 block discarded – undo
57 57
             </td>
58 58
         </tr>
59 59
         <?php do_action(
60
-            'AHEE__thank_you_page_transaction_details_template__after_transaction_table_row',
61
-            $transaction
62
-        ); ?>
60
+			'AHEE__thank_you_page_transaction_details_template__after_transaction_table_row',
61
+			$transaction
62
+		); ?>
63 63
         </tbody>
64 64
     </table>
65 65
 
Please login to merge, or discard this patch.
modules/thank_you_page/EED_Thank_You_Page.module.php 2 patches
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -129,8 +129,8 @@  discard block
 block discarded – undo
129 129
      */
130 130
     public static function set_definitions()
131 131
     {
132
-        define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
133
-        define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/');
132
+        define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__).'assets/');
133
+        define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', '/', plugin_dir_path(__FILE__)).'templates/');
134 134
     }
135 135
 
136 136
 
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
             return $this->_current_txn;
148 148
         }
149 149
         $TXN_model = EE_Registry::instance()->load_model('Transaction');
150
-        if (! $TXN_model instanceof EEM_Transaction) {
150
+        if ( ! $TXN_model instanceof EEM_Transaction) {
151 151
             EE_Error::add_error(
152 152
                 esc_html__('The transaction model could not be established.', 'event_espresso'),
153 153
                 __FILE__,
@@ -185,7 +185,7 @@  discard block
 block discarded – undo
185 185
      */
186 186
     public function get_txn_payments($since = 0)
187 187
     {
188
-        if (! $this->get_txn()) {
188
+        if ( ! $this->get_txn()) {
189 189
             return [];
190 190
         }
191 191
         $args = array('order_by' => array('PAY_timestamp' => 'ASC'));
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
     {
328 328
         wp_register_script(
329 329
             'thank_you_page',
330
-            THANK_YOU_ASSETS_URL . 'thank_you_page.js',
330
+            THANK_YOU_ASSETS_URL.'thank_you_page.js',
331 331
             array('espresso_core', 'heartbeat'),
332 332
             EVENT_ESPRESSO_VERSION,
333 333
             true
@@ -347,9 +347,9 @@  discard block
 block discarded – undo
347 347
     public function init()
348 348
     {
349 349
         $this->_get_reg_url_link();
350
-        if (! $this->get_txn()) {
350
+        if ( ! $this->get_txn()) {
351 351
             echo EEH_HTML::div(
352
-                EEH_HTML::h4(esc_html__('We\'re sorry...', 'event_espresso')) .
352
+                EEH_HTML::h4(esc_html__('We\'re sorry...', 'event_espresso')).
353 353
                 sprintf(
354 354
                     esc_html__(
355 355
                         'This is a system page for displaying transaction information after a purchase.%1$sYou are most likely seeing this notice because you have navigated to this page%1$sthrough some means other than completing a transaction.%1$sSorry for the disappointment, but you will most likely find nothing of interest here.%1$s%1$s',
@@ -440,12 +440,12 @@  discard block
 block discarded – undo
440 440
     public function thank_you_page_results()
441 441
     {
442 442
         $this->init();
443
-        if (! $this->_current_txn instanceof EE_Transaction) {
443
+        if ( ! $this->_current_txn instanceof EE_Transaction) {
444 444
             return EE_Error::get_notices();
445 445
         }
446 446
         // link to receipt
447 447
         $template_args['TXN_receipt_url'] = $this->_current_txn->receipt_url();
448
-        if (! empty($template_args['TXN_receipt_url'])) {
448
+        if ( ! empty($template_args['TXN_receipt_url'])) {
449 449
             $template_args['order_conf_desc'] = esc_html__(
450 450
                 '%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation or click the button below to view / download / print a full description of your purchases and registration information.',
451 451
                 'event_espresso'
@@ -463,7 +463,7 @@  discard block
 block discarded – undo
463 463
             add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_ajax_content'));
464 464
         }
465 465
         return EEH_Template::locate_template(
466
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-overview.template.php',
466
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-overview.template.php',
467 467
             $template_args
468 468
         );
469 469
     }
@@ -513,7 +513,7 @@  discard block
 block discarded – undo
513 513
             '$SPCO_attendee_information_url'
514 514
         );
515 515
         echo EEH_Template::locate_template(
516
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-registration-details.template.php',
516
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-registration-details.template.php',
517 517
             $template_args
518 518
         );
519 519
     }
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
      */
586 586
     public function get_ajax_content()
587 587
     {
588
-        if (! $this->get_txn()) {
588
+        if ( ! $this->get_txn()) {
589 589
             return;
590 590
         }
591 591
         // first determine which event(s) require pre-approval or not
@@ -596,9 +596,9 @@  discard block
 block discarded – undo
596 596
                 $event = $registration->event();
597 597
                 if ($event instanceof EE_Event) {
598 598
                     if ($registration->is_not_approved() && $registration->event() instanceof EE_Event) {
599
-                        $events_requiring_pre_approval[ $event->ID() ] = $event;
599
+                        $events_requiring_pre_approval[$event->ID()] = $event;
600 600
                     } else {
601
-                        $events[ $event->ID() ] = $event;
601
+                        $events[$event->ID()] = $event;
602 602
                     }
603 603
                 }
604 604
             }
@@ -616,7 +616,7 @@  discard block
 block discarded – undo
616 616
      */
617 617
     public function display_details_for_events($events = array())
618 618
     {
619
-        if (! empty($events)) {
619
+        if ( ! empty($events)) {
620 620
             ?>
621 621
             <div id="espresso-thank-you-page-ajax-content-dv">
622 622
                 <div id="espresso-thank-you-page-ajax-transaction-dv"></div>
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
                                 'event_espresso'
630 630
                             ); ?></span>
631 631
                     </div>
632
-                    <?php if (! $this->_is_offline_payment_method && ! $this->_payments_closed) : ?>
632
+                    <?php if ( ! $this->_is_offline_payment_method && ! $this->_payments_closed) : ?>
633 633
                         <p id="ee-ajax-loading-pg" class="highlight-bg small-text clear">
634 634
                             <?php echo apply_filters(
635 635
                                 'EED_Thank_You_Page__get_ajax_content__waiting_for_IPN_msg',
@@ -662,7 +662,7 @@  discard block
 block discarded – undo
662 662
      */
663 663
     public function display_details_for_events_requiring_pre_approval($events = array())
664 664
     {
665
-        if (! empty($events)) {
665
+        if ( ! empty($events)) {
666 666
             ?>
667 667
             <div id="espresso-thank-you-page-not-approved-message-dv">
668 668
                 <h4 class="orange-text"><?php esc_html_e('Important Notice:', 'event_espresso'); ?></h4>
@@ -719,7 +719,7 @@  discard block
 block discarded – undo
719 719
             '$SPCO_payment_options_url'
720 720
         );
721 721
         return EEH_Template::locate_template(
722
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-transaction-details.template.php',
722
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-transaction-details.template.php',
723 723
             $template_args
724 724
         );
725 725
     }
@@ -735,7 +735,7 @@  discard block
 block discarded – undo
735 735
     public function get_payment_row_html(EE_Payment $payment = null)
736 736
     {
737 737
         $html = '';
738
-        if (! $payment instanceof EE_Payment) {
738
+        if ( ! $payment instanceof EE_Payment) {
739 739
             return '';
740 740
         }
741 741
         if (
@@ -749,25 +749,25 @@  discard block
 block discarded – undo
749 749
             $payment->set_status(EEM_Payment::status_id_pending);
750 750
         }
751 751
         $payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined
752
-            ? '<br /><span class="small-text">' . esc_html($payment->gateway_response()) . '</span>'
752
+            ? '<br /><span class="small-text">'.esc_html($payment->gateway_response()).'</span>'
753 753
             : '';
754 754
         $html .= '
755 755
             <tr>
756 756
                 <td>
757
-                    ' . esc_html($payment->timestamp()) . '
757
+                    ' . esc_html($payment->timestamp()).'
758 758
                 </td>
759 759
                 <td>
760 760
                     ' . (
761 761
             $payment->payment_method() instanceof EE_Payment_Method
762 762
                 ? esc_html($payment->payment_method()->name())
763 763
                 : esc_html__('Unknown', 'event_espresso')
764
-            ) . '
764
+            ).'
765 765
                 </td>
766 766
                 <td class="jst-rght">
767
-                    ' . EEH_Template::format_currency($payment->amount()) . '
767
+                    ' . EEH_Template::format_currency($payment->amount()).'
768 768
                 </td>
769 769
                 <td class="jst-rght" style="line-height:1;">
770
-                    ' . $payment->pretty_status(true) . $payment_declined_msg . '
770
+                    ' . $payment->pretty_status(true).$payment_declined_msg.'
771 771
                 </td>
772 772
             </tr>';
773 773
         do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment);
@@ -825,7 +825,7 @@  discard block
 block discarded – undo
825 825
             '$SPCO_payment_options_url'
826 826
         );
827 827
         return EEH_Template::locate_template(
828
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-payment-details.template.php',
828
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-payment-details.template.php',
829 829
             $template_args
830 830
         );
831 831
     }
Please login to merge, or discard this patch.
Indentation   +789 added lines, -789 removed lines patch added patch discarded remove patch
@@ -10,613 +10,613 @@  discard block
 block discarded – undo
10 10
  */
11 11
 class EED_Thank_You_Page extends EED_Module
12 12
 {
13
-    /**
14
-     * time in seconds to wait for the IPN to arrive before telling the registrant to bugger off ( 1200s = 20 minutes )
15
-     */
16
-    const IPN_wait_time = 1200;
17
-
18
-    /**
19
-     * The transaction specified by the reg_url_link passed from the Request, or from the Session
20
-     *
21
-     * @var EE_Transaction $_current_txn
22
-     */
23
-    private $_current_txn;
24
-
25
-    /**
26
-     * @var EE_Registration $_primary_registrant
27
-     */
28
-    private $_primary_registrant;
29
-
30
-    /**
31
-     * The reg_url_link passed from the Request, or from the Session
32
-     *
33
-     * @var string $_reg_url_link
34
-     */
35
-    private $_reg_url_link;
36
-
37
-    /**
38
-     * whether the incoming reg_url_link is for the primary registrant or not
39
-     *
40
-     * @var boolean $_is_primary
41
-     */
42
-    private $_is_primary;
43
-
44
-    /**
45
-     * The URL for revisiting the SPCO attendee information step
46
-     *
47
-     * @var string $_SPCO_attendee_information_url
48
-     */
49
-    private $_SPCO_attendee_information_url;
50
-
51
-    /**
52
-     * The URL for revisiting the SPCO payment options step
53
-     *
54
-     * @var string $_SPCO_payment_options_url
55
-     */
56
-    private $_SPCO_payment_options_url;
57
-
58
-    /**
59
-     * whether to display the Payment Options link
60
-     *
61
-     * @var boolean $_show_try_pay_again_link
62
-     */
63
-    private $_show_try_pay_again_link = false;
64
-
65
-    /**
66
-     * whether payments are allowed at this time
67
-     *
68
-     * @var boolean $_payments_closed
69
-     */
70
-    private $_payments_closed = false;
71
-
72
-    /**
73
-     * whether the selected payment method is Bank, Check , Invoice, etc
74
-     *
75
-     * @var boolean $_is_offline_payment_method
76
-     */
77
-    private $_is_offline_payment_method = true;
78
-
79
-
80
-    /**
81
-     * @return EED_Module|EED_Thank_You_Page
82
-     * @throws EE_Error
83
-     * @throws ReflectionException
84
-     */
85
-    public static function instance()
86
-    {
87
-        return parent::get_instance(__CLASS__);
88
-    }
89
-
90
-
91
-    /**
92
-     * set_hooks - for hooking into EE Core, modules, etc
93
-     *
94
-     * @return void
95
-     */
96
-    public static function set_hooks()
97
-    {
98
-        add_action('wp_loaded', array('EED_Thank_You_Page', 'set_definitions'), 2);
99
-    }
100
-
101
-
102
-    /**
103
-     * set_hooks_admin - for hooking into EE Admin Core, modules, etc
104
-     *
105
-     * @return void
106
-     */
107
-    public static function set_hooks_admin()
108
-    {
109
-        add_action(
110
-            'wp_ajax_espresso_resend_reg_confirmation_email',
111
-            array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
112
-            10,
113
-            2
114
-        );
115
-        add_action(
116
-            'wp_ajax_nopriv_espresso_resend_reg_confirmation_email',
117
-            array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
118
-            10,
119
-            2
120
-        );
121
-    }
122
-
123
-
124
-    /**
125
-     * set_definitions
126
-     *
127
-     * @return void
128
-     */
129
-    public static function set_definitions()
130
-    {
131
-        define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
132
-        define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/');
133
-    }
134
-
135
-
136
-    /**
137
-     * get_txn
138
-     *
139
-     * @return EE_Transaction
140
-     * @throws EE_Error
141
-     * @throws ReflectionException
142
-     */
143
-    public function get_txn()
144
-    {
145
-        if ($this->_current_txn instanceof EE_Transaction) {
146
-            return $this->_current_txn;
147
-        }
148
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
149
-        if (! $TXN_model instanceof EEM_Transaction) {
150
-            EE_Error::add_error(
151
-                esc_html__('The transaction model could not be established.', 'event_espresso'),
152
-                __FILE__,
153
-                __FUNCTION__,
154
-                __LINE__
155
-            );
156
-            return null;
157
-        }
158
-        // get the transaction. yes, we may have just loaded it, but it may have been updated, or this may be via an ajax request
159
-        $this->_current_txn = $TXN_model->get_transaction_from_reg_url_link($this->_reg_url_link);
160
-        // verify TXN
161
-        if (WP_DEBUG && ! $this->_current_txn instanceof EE_Transaction) {
162
-            EE_Error::add_error(
163
-                esc_html__(
164
-                    'No transaction information could be retrieved or the transaction data is not of the correct type.',
165
-                    'event_espresso'
166
-                ),
167
-                __FILE__,
168
-                __FUNCTION__,
169
-                __LINE__
170
-            );
171
-            return null;
172
-        }
173
-        return $this->_current_txn;
174
-    }
175
-
176
-
177
-    /**
178
-     * get_txn_payments
179
-     *
180
-     * @param int $since
181
-     * @return EE_Payment[]
182
-     * @throws EE_Error
183
-     * @throws ReflectionException
184
-     */
185
-    public function get_txn_payments($since = 0)
186
-    {
187
-        if (! $this->get_txn()) {
188
-            return [];
189
-        }
190
-        $args = array('order_by' => array('PAY_timestamp' => 'ASC'));
191
-        if ($since > 0) {
192
-            $args[0] = array('PAY_timestamp' => array('>', $since));
193
-        }
194
-        // get array of payments with most recent first
195
-        return $this->_current_txn->payments($args);
196
-    }
197
-
198
-
199
-    /**
200
-     * @return bool
201
-     */
202
-    public function isOfflinePaymentMethod()
203
-    {
204
-        return $this->_is_offline_payment_method;
205
-    }
206
-
207
-
208
-
209
-
210
-    /**
211
-     * get_reg_url_link
212
-     *
213
-     * @return void
214
-     */
215
-    private function _get_reg_url_link()
216
-    {
217
-        if ($this->_reg_url_link) {
218
-            return;
219
-        }
220
-        // check for reg_url_link
221
-        $reg_url_link = self::getRequest()->getRequestParam('e_reg_url_link');
222
-        // only do thank you page stuff if we have a REG_url_link in the url
223
-        if (WP_DEBUG && ! $reg_url_link) {
224
-            EE_Error::add_error(
225
-                esc_html__(
226
-                    'No transaction information could be retrieved because the registration URL link is missing or invalid.',
227
-                    'event_espresso'
228
-                ),
229
-                __FILE__,
230
-                __FUNCTION__,
231
-                __LINE__
232
-            );
233
-        }
234
-        $this->set_reg_url_link($reg_url_link);
235
-    }
236
-
237
-
238
-    /**
239
-     * set_reg_url_link
240
-     *
241
-     * @param string $reg_url_link
242
-     */
243
-    public function set_reg_url_link($reg_url_link = null)
244
-    {
245
-        $this->_reg_url_link = ! empty($reg_url_link) ? $reg_url_link : $this->_reg_url_link;
246
-    }
247
-
248
-
249
-    /**
250
-     * run - initial module setup
251
-     * this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
252
-     *
253
-     * @param WP $WP
254
-     * @return void
255
-     */
256
-    public function run($WP)
257
-    {
258
-    }
259
-
260
-
261
-    /**
262
-     * load_resources
263
-     *
264
-     * @return void
265
-     * @throws EE_Error
266
-     * @throws ReflectionException
267
-     */
268
-    public function load_resources()
269
-    {
270
-        $this->_get_reg_url_link();
271
-        // resend_reg_confirmation_email ?
272
-        if (self::getRequest()->requestParamIsSet('resend')) {
273
-            EED_Thank_You_Page::resend_reg_confirmation_email();
274
-        }
275
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
276
-        $this->_translate_strings();
277
-        // load assets
278
-        add_action('wp_enqueue_scripts', array($this, 'load_js'), 10);
279
-    }
280
-
281
-
282
-    /**
283
-     * load_js
284
-     *
285
-     * @return void
286
-     */
287
-    protected function _translate_strings()
288
-    {
289
-        EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->_reg_url_link;
290
-        EE_Registry::$i18n_js_strings['initial_access'] = time();
291
-        EE_Registry::$i18n_js_strings['IPN_wait_time'] = EED_Thank_You_Page::IPN_wait_time;
292
-        EE_Registry::$i18n_js_strings['TXN_complete'] = EEM_Transaction::complete_status_code;
293
-        EE_Registry::$i18n_js_strings['TXN_incomplete'] = EEM_Transaction::incomplete_status_code;
294
-        EE_Registry::$i18n_js_strings['checking_for_new_payments'] = __(
295
-            'checking for new payments...',
296
-            'event_espresso'
297
-        );
298
-        EE_Registry::$i18n_js_strings['loading_payment_info'] = __(
299
-            'loading payment information...',
300
-            'event_espresso'
301
-        );
302
-        EE_Registry::$i18n_js_strings['server_error'] = __(
303
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again.',
304
-            'event_espresso'
305
-        );
306
-        EE_Registry::$i18n_js_strings['slow_IPN'] = apply_filters(
307
-            'EED_Thank_You_Page__load_js__slow_IPN',
308
-            sprintf(
309
-                __(
310
-                    '%sThe Payment Notification appears to be taking longer than usual to arrive. Maybe check back later or just wait for your payment and registration confirmation results to be sent to you via email. We apologize for any inconvenience this may have caused.%s',
311
-                    'event_espresso'
312
-                ),
313
-                '<div id="espresso-thank-you-page-slow-IPN-dv" class="ee-attention jst-left">',
314
-                '</div>'
315
-            )
316
-        );
317
-    }
318
-
319
-
320
-    /**
321
-     * load_js
322
-     *
323
-     * @return void
324
-     */
325
-    public function load_js()
326
-    {
327
-        wp_register_script(
328
-            'thank_you_page',
329
-            THANK_YOU_ASSETS_URL . 'thank_you_page.js',
330
-            array('espresso_core', 'heartbeat'),
331
-            EVENT_ESPRESSO_VERSION,
332
-            true
333
-        );
334
-        wp_enqueue_script('thank_you_page');
335
-        wp_enqueue_style('espresso_default');
336
-    }
337
-
338
-
339
-    /**
340
-     * init
341
-     *
342
-     * @return void
343
-     * @throws EE_Error
344
-     * @throws ReflectionException
345
-     */
346
-    public function init()
347
-    {
348
-        $this->_get_reg_url_link();
349
-        if (! $this->get_txn()) {
350
-            echo EEH_HTML::div(
351
-                EEH_HTML::h4(esc_html__('We\'re sorry...', 'event_espresso')) .
352
-                sprintf(
353
-                    esc_html__(
354
-                        'This is a system page for displaying transaction information after a purchase.%1$sYou are most likely seeing this notice because you have navigated to this page%1$sthrough some means other than completing a transaction.%1$sSorry for the disappointment, but you will most likely find nothing of interest here.%1$s%1$s',
355
-                        'event_espresso'
356
-                    ),
357
-                    '<br/>'
358
-                ),
359
-                '',
360
-                'ee-attention'
361
-            );
362
-            return;
363
-        }
364
-        // if we've made it to the Thank You page, then let's toggle any "Failed" transactions to "Incomplete"
365
-        if ($this->_current_txn->status_ID() === EEM_Transaction::failed_status_code) {
366
-            $this->_current_txn->set_status(EEM_Transaction::incomplete_status_code);
367
-            $this->_current_txn->save();
368
-        }
369
-        $this->_primary_registrant = $this->_current_txn->primary_registration() instanceof EE_Registration
370
-            ? $this->_current_txn->primary_registration()
371
-            : null;
372
-        $this->_is_primary = $this->_primary_registrant->reg_url_link() === $this->_reg_url_link;
373
-        $show_try_pay_again_link_default = apply_filters(
374
-            'AFEE__EED_Thank_You_Page__init__show_try_pay_again_link_default',
375
-            true
376
-        );
377
-        $this->_show_try_pay_again_link = $show_try_pay_again_link_default;
378
-        // txn status ?
379
-        if ($this->_current_txn->is_completed()) {
380
-            $this->_show_try_pay_again_link = $show_try_pay_again_link_default;
381
-        } elseif (
382
-            $this->_current_txn->is_incomplete()
383
-            && ($this->_primary_registrant->is_approved()
384
-                || $this->_primary_registrant->is_pending_payment())
385
-        ) {
386
-            $this->_show_try_pay_again_link = true;
387
-        } elseif ($this->_primary_registrant->is_approved() || $this->_primary_registrant->is_pending_payment()) {
388
-            // its pending
389
-            $this->_show_try_pay_again_link = isset(
390
-                EE_Registry::instance()->CFG->registration->show_pending_payment_options
391
-            )
392
-                                              && EE_Registry::instance()->CFG
393
-                                                  ->registration->show_pending_payment_options
394
-                ? true
395
-                : $show_try_pay_again_link_default;
396
-        }
397
-        $this->_payments_closed = ! $this->_current_txn->payment_method() instanceof EE_Payment_Method;
398
-        $this->_is_offline_payment_method = false;
399
-        if (
13
+	/**
14
+	 * time in seconds to wait for the IPN to arrive before telling the registrant to bugger off ( 1200s = 20 minutes )
15
+	 */
16
+	const IPN_wait_time = 1200;
17
+
18
+	/**
19
+	 * The transaction specified by the reg_url_link passed from the Request, or from the Session
20
+	 *
21
+	 * @var EE_Transaction $_current_txn
22
+	 */
23
+	private $_current_txn;
24
+
25
+	/**
26
+	 * @var EE_Registration $_primary_registrant
27
+	 */
28
+	private $_primary_registrant;
29
+
30
+	/**
31
+	 * The reg_url_link passed from the Request, or from the Session
32
+	 *
33
+	 * @var string $_reg_url_link
34
+	 */
35
+	private $_reg_url_link;
36
+
37
+	/**
38
+	 * whether the incoming reg_url_link is for the primary registrant or not
39
+	 *
40
+	 * @var boolean $_is_primary
41
+	 */
42
+	private $_is_primary;
43
+
44
+	/**
45
+	 * The URL for revisiting the SPCO attendee information step
46
+	 *
47
+	 * @var string $_SPCO_attendee_information_url
48
+	 */
49
+	private $_SPCO_attendee_information_url;
50
+
51
+	/**
52
+	 * The URL for revisiting the SPCO payment options step
53
+	 *
54
+	 * @var string $_SPCO_payment_options_url
55
+	 */
56
+	private $_SPCO_payment_options_url;
57
+
58
+	/**
59
+	 * whether to display the Payment Options link
60
+	 *
61
+	 * @var boolean $_show_try_pay_again_link
62
+	 */
63
+	private $_show_try_pay_again_link = false;
64
+
65
+	/**
66
+	 * whether payments are allowed at this time
67
+	 *
68
+	 * @var boolean $_payments_closed
69
+	 */
70
+	private $_payments_closed = false;
71
+
72
+	/**
73
+	 * whether the selected payment method is Bank, Check , Invoice, etc
74
+	 *
75
+	 * @var boolean $_is_offline_payment_method
76
+	 */
77
+	private $_is_offline_payment_method = true;
78
+
79
+
80
+	/**
81
+	 * @return EED_Module|EED_Thank_You_Page
82
+	 * @throws EE_Error
83
+	 * @throws ReflectionException
84
+	 */
85
+	public static function instance()
86
+	{
87
+		return parent::get_instance(__CLASS__);
88
+	}
89
+
90
+
91
+	/**
92
+	 * set_hooks - for hooking into EE Core, modules, etc
93
+	 *
94
+	 * @return void
95
+	 */
96
+	public static function set_hooks()
97
+	{
98
+		add_action('wp_loaded', array('EED_Thank_You_Page', 'set_definitions'), 2);
99
+	}
100
+
101
+
102
+	/**
103
+	 * set_hooks_admin - for hooking into EE Admin Core, modules, etc
104
+	 *
105
+	 * @return void
106
+	 */
107
+	public static function set_hooks_admin()
108
+	{
109
+		add_action(
110
+			'wp_ajax_espresso_resend_reg_confirmation_email',
111
+			array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
112
+			10,
113
+			2
114
+		);
115
+		add_action(
116
+			'wp_ajax_nopriv_espresso_resend_reg_confirmation_email',
117
+			array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
118
+			10,
119
+			2
120
+		);
121
+	}
122
+
123
+
124
+	/**
125
+	 * set_definitions
126
+	 *
127
+	 * @return void
128
+	 */
129
+	public static function set_definitions()
130
+	{
131
+		define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
132
+		define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/');
133
+	}
134
+
135
+
136
+	/**
137
+	 * get_txn
138
+	 *
139
+	 * @return EE_Transaction
140
+	 * @throws EE_Error
141
+	 * @throws ReflectionException
142
+	 */
143
+	public function get_txn()
144
+	{
145
+		if ($this->_current_txn instanceof EE_Transaction) {
146
+			return $this->_current_txn;
147
+		}
148
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
149
+		if (! $TXN_model instanceof EEM_Transaction) {
150
+			EE_Error::add_error(
151
+				esc_html__('The transaction model could not be established.', 'event_espresso'),
152
+				__FILE__,
153
+				__FUNCTION__,
154
+				__LINE__
155
+			);
156
+			return null;
157
+		}
158
+		// get the transaction. yes, we may have just loaded it, but it may have been updated, or this may be via an ajax request
159
+		$this->_current_txn = $TXN_model->get_transaction_from_reg_url_link($this->_reg_url_link);
160
+		// verify TXN
161
+		if (WP_DEBUG && ! $this->_current_txn instanceof EE_Transaction) {
162
+			EE_Error::add_error(
163
+				esc_html__(
164
+					'No transaction information could be retrieved or the transaction data is not of the correct type.',
165
+					'event_espresso'
166
+				),
167
+				__FILE__,
168
+				__FUNCTION__,
169
+				__LINE__
170
+			);
171
+			return null;
172
+		}
173
+		return $this->_current_txn;
174
+	}
175
+
176
+
177
+	/**
178
+	 * get_txn_payments
179
+	 *
180
+	 * @param int $since
181
+	 * @return EE_Payment[]
182
+	 * @throws EE_Error
183
+	 * @throws ReflectionException
184
+	 */
185
+	public function get_txn_payments($since = 0)
186
+	{
187
+		if (! $this->get_txn()) {
188
+			return [];
189
+		}
190
+		$args = array('order_by' => array('PAY_timestamp' => 'ASC'));
191
+		if ($since > 0) {
192
+			$args[0] = array('PAY_timestamp' => array('>', $since));
193
+		}
194
+		// get array of payments with most recent first
195
+		return $this->_current_txn->payments($args);
196
+	}
197
+
198
+
199
+	/**
200
+	 * @return bool
201
+	 */
202
+	public function isOfflinePaymentMethod()
203
+	{
204
+		return $this->_is_offline_payment_method;
205
+	}
206
+
207
+
208
+
209
+
210
+	/**
211
+	 * get_reg_url_link
212
+	 *
213
+	 * @return void
214
+	 */
215
+	private function _get_reg_url_link()
216
+	{
217
+		if ($this->_reg_url_link) {
218
+			return;
219
+		}
220
+		// check for reg_url_link
221
+		$reg_url_link = self::getRequest()->getRequestParam('e_reg_url_link');
222
+		// only do thank you page stuff if we have a REG_url_link in the url
223
+		if (WP_DEBUG && ! $reg_url_link) {
224
+			EE_Error::add_error(
225
+				esc_html__(
226
+					'No transaction information could be retrieved because the registration URL link is missing or invalid.',
227
+					'event_espresso'
228
+				),
229
+				__FILE__,
230
+				__FUNCTION__,
231
+				__LINE__
232
+			);
233
+		}
234
+		$this->set_reg_url_link($reg_url_link);
235
+	}
236
+
237
+
238
+	/**
239
+	 * set_reg_url_link
240
+	 *
241
+	 * @param string $reg_url_link
242
+	 */
243
+	public function set_reg_url_link($reg_url_link = null)
244
+	{
245
+		$this->_reg_url_link = ! empty($reg_url_link) ? $reg_url_link : $this->_reg_url_link;
246
+	}
247
+
248
+
249
+	/**
250
+	 * run - initial module setup
251
+	 * this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
252
+	 *
253
+	 * @param WP $WP
254
+	 * @return void
255
+	 */
256
+	public function run($WP)
257
+	{
258
+	}
259
+
260
+
261
+	/**
262
+	 * load_resources
263
+	 *
264
+	 * @return void
265
+	 * @throws EE_Error
266
+	 * @throws ReflectionException
267
+	 */
268
+	public function load_resources()
269
+	{
270
+		$this->_get_reg_url_link();
271
+		// resend_reg_confirmation_email ?
272
+		if (self::getRequest()->requestParamIsSet('resend')) {
273
+			EED_Thank_You_Page::resend_reg_confirmation_email();
274
+		}
275
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
276
+		$this->_translate_strings();
277
+		// load assets
278
+		add_action('wp_enqueue_scripts', array($this, 'load_js'), 10);
279
+	}
280
+
281
+
282
+	/**
283
+	 * load_js
284
+	 *
285
+	 * @return void
286
+	 */
287
+	protected function _translate_strings()
288
+	{
289
+		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->_reg_url_link;
290
+		EE_Registry::$i18n_js_strings['initial_access'] = time();
291
+		EE_Registry::$i18n_js_strings['IPN_wait_time'] = EED_Thank_You_Page::IPN_wait_time;
292
+		EE_Registry::$i18n_js_strings['TXN_complete'] = EEM_Transaction::complete_status_code;
293
+		EE_Registry::$i18n_js_strings['TXN_incomplete'] = EEM_Transaction::incomplete_status_code;
294
+		EE_Registry::$i18n_js_strings['checking_for_new_payments'] = __(
295
+			'checking for new payments...',
296
+			'event_espresso'
297
+		);
298
+		EE_Registry::$i18n_js_strings['loading_payment_info'] = __(
299
+			'loading payment information...',
300
+			'event_espresso'
301
+		);
302
+		EE_Registry::$i18n_js_strings['server_error'] = __(
303
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again.',
304
+			'event_espresso'
305
+		);
306
+		EE_Registry::$i18n_js_strings['slow_IPN'] = apply_filters(
307
+			'EED_Thank_You_Page__load_js__slow_IPN',
308
+			sprintf(
309
+				__(
310
+					'%sThe Payment Notification appears to be taking longer than usual to arrive. Maybe check back later or just wait for your payment and registration confirmation results to be sent to you via email. We apologize for any inconvenience this may have caused.%s',
311
+					'event_espresso'
312
+				),
313
+				'<div id="espresso-thank-you-page-slow-IPN-dv" class="ee-attention jst-left">',
314
+				'</div>'
315
+			)
316
+		);
317
+	}
318
+
319
+
320
+	/**
321
+	 * load_js
322
+	 *
323
+	 * @return void
324
+	 */
325
+	public function load_js()
326
+	{
327
+		wp_register_script(
328
+			'thank_you_page',
329
+			THANK_YOU_ASSETS_URL . 'thank_you_page.js',
330
+			array('espresso_core', 'heartbeat'),
331
+			EVENT_ESPRESSO_VERSION,
332
+			true
333
+		);
334
+		wp_enqueue_script('thank_you_page');
335
+		wp_enqueue_style('espresso_default');
336
+	}
337
+
338
+
339
+	/**
340
+	 * init
341
+	 *
342
+	 * @return void
343
+	 * @throws EE_Error
344
+	 * @throws ReflectionException
345
+	 */
346
+	public function init()
347
+	{
348
+		$this->_get_reg_url_link();
349
+		if (! $this->get_txn()) {
350
+			echo EEH_HTML::div(
351
+				EEH_HTML::h4(esc_html__('We\'re sorry...', 'event_espresso')) .
352
+				sprintf(
353
+					esc_html__(
354
+						'This is a system page for displaying transaction information after a purchase.%1$sYou are most likely seeing this notice because you have navigated to this page%1$sthrough some means other than completing a transaction.%1$sSorry for the disappointment, but you will most likely find nothing of interest here.%1$s%1$s',
355
+						'event_espresso'
356
+					),
357
+					'<br/>'
358
+				),
359
+				'',
360
+				'ee-attention'
361
+			);
362
+			return;
363
+		}
364
+		// if we've made it to the Thank You page, then let's toggle any "Failed" transactions to "Incomplete"
365
+		if ($this->_current_txn->status_ID() === EEM_Transaction::failed_status_code) {
366
+			$this->_current_txn->set_status(EEM_Transaction::incomplete_status_code);
367
+			$this->_current_txn->save();
368
+		}
369
+		$this->_primary_registrant = $this->_current_txn->primary_registration() instanceof EE_Registration
370
+			? $this->_current_txn->primary_registration()
371
+			: null;
372
+		$this->_is_primary = $this->_primary_registrant->reg_url_link() === $this->_reg_url_link;
373
+		$show_try_pay_again_link_default = apply_filters(
374
+			'AFEE__EED_Thank_You_Page__init__show_try_pay_again_link_default',
375
+			true
376
+		);
377
+		$this->_show_try_pay_again_link = $show_try_pay_again_link_default;
378
+		// txn status ?
379
+		if ($this->_current_txn->is_completed()) {
380
+			$this->_show_try_pay_again_link = $show_try_pay_again_link_default;
381
+		} elseif (
382
+			$this->_current_txn->is_incomplete()
383
+			&& ($this->_primary_registrant->is_approved()
384
+				|| $this->_primary_registrant->is_pending_payment())
385
+		) {
386
+			$this->_show_try_pay_again_link = true;
387
+		} elseif ($this->_primary_registrant->is_approved() || $this->_primary_registrant->is_pending_payment()) {
388
+			// its pending
389
+			$this->_show_try_pay_again_link = isset(
390
+				EE_Registry::instance()->CFG->registration->show_pending_payment_options
391
+			)
392
+											  && EE_Registry::instance()->CFG
393
+												  ->registration->show_pending_payment_options
394
+				? true
395
+				: $show_try_pay_again_link_default;
396
+		}
397
+		$this->_payments_closed = ! $this->_current_txn->payment_method() instanceof EE_Payment_Method;
398
+		$this->_is_offline_payment_method = false;
399
+		if (
400 400
 // if payment method is unknown
401
-            ! $this->_current_txn->payment_method() instanceof EE_Payment_Method
402
-            || (
403
-                // or is an offline payment method
404
-                $this->_current_txn->payment_method() instanceof EE_Payment_Method
405
-                && $this->_current_txn->payment_method()->is_off_line()
406
-            )
407
-        ) {
408
-            $this->_is_offline_payment_method = true;
409
-        }
410
-        // link to SPCO
411
-        $revisit_spco_url = add_query_arg(
412
-            array('ee' => '_register', 'revisit' => true, 'e_reg_url_link' => $this->_reg_url_link),
413
-            EE_Registry::instance()->CFG->core->reg_page_url()
414
-        );
415
-        // link to SPCO payment_options
416
-        $this->_SPCO_payment_options_url = $this->_primary_registrant instanceof EE_Registration
417
-            ? $this->_primary_registrant->payment_overview_url()
418
-            : add_query_arg(
419
-                array('step' => 'payment_options'),
420
-                $revisit_spco_url
421
-            );
422
-        // link to SPCO attendee_information
423
-        $this->_SPCO_attendee_information_url = $this->_primary_registrant instanceof EE_Registration
424
-            ? $this->_primary_registrant->edit_attendee_information_url()
425
-            : false;
426
-        do_action('AHEE__EED_Thank_You_Page__init_end', $this->_current_txn);
427
-        // set no cache headers and constants
428
-        EE_System::do_not_cache();
429
-    }
430
-
431
-
432
-    /**
433
-     * display_thank_you_page_results
434
-     *
435
-     * @return string
436
-     * @throws EE_Error
437
-     * @throws ReflectionException
438
-     */
439
-    public function thank_you_page_results()
440
-    {
441
-        $this->init();
442
-        if (! $this->_current_txn instanceof EE_Transaction) {
443
-            return EE_Error::get_notices();
444
-        }
445
-        // link to receipt
446
-        $template_args['TXN_receipt_url'] = $this->_current_txn->receipt_url();
447
-        if (! empty($template_args['TXN_receipt_url'])) {
448
-            $template_args['order_conf_desc'] = esc_html__(
449
-                '%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation or click the button below to view / download / print a full description of your purchases and registration information.',
450
-                'event_espresso'
451
-            );
452
-        } else {
453
-            $template_args['order_conf_desc'] = esc_html__(
454
-                '%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation.',
455
-                'event_espresso'
456
-            );
457
-        }
458
-        $template_args['transaction'] = $this->_current_txn;
459
-        $template_args['revisit'] = self::getRequest()->getRequestParam('revisit', false, 'bool');
460
-        add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_registration_details'));
461
-        if ($this->_is_primary && ! $this->_current_txn->is_free()) {
462
-            add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_ajax_content'));
463
-        }
464
-        return EEH_Template::locate_template(
465
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-overview.template.php',
466
-            $template_args
467
-        );
468
-    }
469
-
470
-
471
-    /**
472
-     * _update_server_wait_time
473
-     *
474
-     * @param array $thank_you_page_data thank you page portion of the incoming JSON array from the WP heartbeat data
475
-     * @return array
476
-     * @throws EE_Error
477
-     * @throws ReflectionException
478
-     */
479
-    private function _update_server_wait_time($thank_you_page_data = array())
480
-    {
481
-        $response['espresso_thank_you_page'] = array(
482
-            'still_waiting' => isset($thank_you_page_data['initial_access'])
483
-                ? time() - $thank_you_page_data['initial_access']
484
-                : 0,
485
-            'txn_status'    => $this->_current_txn->status_ID(),
486
-        );
487
-        return $response;
488
-    }
489
-
490
-
491
-    /**
492
-     * get_registration_details
493
-     *
494
-     * @throws EE_Error
495
-     */
496
-    public function get_registration_details()
497
-    {
498
-        // prepare variables for displaying
499
-        $template_args = array();
500
-        $template_args['transaction'] = $this->_current_txn;
501
-        $template_args['reg_url_link'] = $this->_reg_url_link;
502
-        $template_args['is_primary'] = $this->_is_primary;
503
-        $template_args['SPCO_attendee_information_url'] = $this->_SPCO_attendee_information_url;
504
-        $template_args['resend_reg_confirmation_url'] = add_query_arg(
505
-            array('token' => $this->_reg_url_link, 'resend_reg_confirmation' => 'true'),
506
-            EE_Registry::instance()->CFG->core->thank_you_page_url()
507
-        );
508
-        // verify template arguments
509
-        EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
510
-        EEH_Template_Validator::verify_isnt_null(
511
-            $template_args['SPCO_attendee_information_url'],
512
-            '$SPCO_attendee_information_url'
513
-        );
514
-        echo EEH_Template::locate_template(
515
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-registration-details.template.php',
516
-            $template_args
517
-        );
518
-    }
519
-
520
-
521
-    /**
522
-     * resend_reg_confirmation_email
523
-     *
524
-     * @throws EE_Error
525
-     * @throws ReflectionException
526
-     */
527
-    public static function resend_reg_confirmation_email()
528
-    {
529
-        $reg_url_link = self::getRequest()->getRequestParam('token');
530
-        // was a REG_ID passed ?
531
-        if ($reg_url_link) {
532
-            $registration = EEM_Registration::instance()->get_one(
533
-                array(array('REG_url_link' => $reg_url_link))
534
-            );
535
-            if ($registration instanceof EE_Registration) {
536
-                // resend email
537
-                EED_Messages::process_resend(array('_REG_ID' => $registration->ID()));
538
-            } else {
539
-                EE_Error::add_error(
540
-                    esc_html__(
541
-                        'The Registration Confirmation email could not be sent because a valid Registration could not be retrieved from the database.',
542
-                        'event_espresso'
543
-                    ),
544
-                    __FILE__,
545
-                    __FUNCTION__,
546
-                    __LINE__
547
-                );
548
-            }
549
-        } else {
550
-            EE_Error::add_error(
551
-                esc_html__(
552
-                    'The Registration Confirmation email could not be sent because a registration token is missing or invalid.',
553
-                    'event_espresso'
554
-                ),
555
-                __FILE__,
556
-                __FUNCTION__,
557
-                __LINE__
558
-            );
559
-        }
560
-        // request sent via AJAX ?
561
-        if (EE_FRONT_AJAX) {
562
-            echo wp_json_encode(EE_Error::get_notices(false));
563
-            die();
564
-            // or was JS disabled ?
565
-        } else {
566
-            // save errors so that they get picked up on the next request
567
-            EE_Error::get_notices(true, true);
568
-            wp_safe_redirect(
569
-                add_query_arg(
570
-                    array('e_reg_url_link' => $reg_url_link),
571
-                    EE_Registry::instance()->CFG->core->thank_you_page_url()
572
-                )
573
-            );
574
-        }
575
-    }
576
-
577
-
578
-    /**
579
-     * get_ajax_content
580
-     *
581
-     * @return void
582
-     * @throws EE_Error
583
-     * @throws ReflectionException
584
-     */
585
-    public function get_ajax_content()
586
-    {
587
-        if (! $this->get_txn()) {
588
-            return;
589
-        }
590
-        // first determine which event(s) require pre-approval or not
591
-        $events = array();
592
-        $events_requiring_pre_approval = array();
593
-        foreach ($this->_current_txn->registrations() as $registration) {
594
-            if ($registration instanceof EE_Registration) {
595
-                $event = $registration->event();
596
-                if ($event instanceof EE_Event) {
597
-                    if ($registration->is_not_approved() && $registration->event() instanceof EE_Event) {
598
-                        $events_requiring_pre_approval[ $event->ID() ] = $event;
599
-                    } else {
600
-                        $events[ $event->ID() ] = $event;
601
-                    }
602
-                }
603
-            }
604
-        }
605
-        $this->display_details_for_events_requiring_pre_approval($events_requiring_pre_approval);
606
-        $this->display_details_for_events($events);
607
-    }
608
-
609
-
610
-    /**
611
-     * display_details_for_events
612
-     *
613
-     * @param EE_Event[] $events
614
-     * @return void
615
-     */
616
-    public function display_details_for_events($events = array())
617
-    {
618
-        if (! empty($events)) {
619
-            ?>
401
+			! $this->_current_txn->payment_method() instanceof EE_Payment_Method
402
+			|| (
403
+				// or is an offline payment method
404
+				$this->_current_txn->payment_method() instanceof EE_Payment_Method
405
+				&& $this->_current_txn->payment_method()->is_off_line()
406
+			)
407
+		) {
408
+			$this->_is_offline_payment_method = true;
409
+		}
410
+		// link to SPCO
411
+		$revisit_spco_url = add_query_arg(
412
+			array('ee' => '_register', 'revisit' => true, 'e_reg_url_link' => $this->_reg_url_link),
413
+			EE_Registry::instance()->CFG->core->reg_page_url()
414
+		);
415
+		// link to SPCO payment_options
416
+		$this->_SPCO_payment_options_url = $this->_primary_registrant instanceof EE_Registration
417
+			? $this->_primary_registrant->payment_overview_url()
418
+			: add_query_arg(
419
+				array('step' => 'payment_options'),
420
+				$revisit_spco_url
421
+			);
422
+		// link to SPCO attendee_information
423
+		$this->_SPCO_attendee_information_url = $this->_primary_registrant instanceof EE_Registration
424
+			? $this->_primary_registrant->edit_attendee_information_url()
425
+			: false;
426
+		do_action('AHEE__EED_Thank_You_Page__init_end', $this->_current_txn);
427
+		// set no cache headers and constants
428
+		EE_System::do_not_cache();
429
+	}
430
+
431
+
432
+	/**
433
+	 * display_thank_you_page_results
434
+	 *
435
+	 * @return string
436
+	 * @throws EE_Error
437
+	 * @throws ReflectionException
438
+	 */
439
+	public function thank_you_page_results()
440
+	{
441
+		$this->init();
442
+		if (! $this->_current_txn instanceof EE_Transaction) {
443
+			return EE_Error::get_notices();
444
+		}
445
+		// link to receipt
446
+		$template_args['TXN_receipt_url'] = $this->_current_txn->receipt_url();
447
+		if (! empty($template_args['TXN_receipt_url'])) {
448
+			$template_args['order_conf_desc'] = esc_html__(
449
+				'%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation or click the button below to view / download / print a full description of your purchases and registration information.',
450
+				'event_espresso'
451
+			);
452
+		} else {
453
+			$template_args['order_conf_desc'] = esc_html__(
454
+				'%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation.',
455
+				'event_espresso'
456
+			);
457
+		}
458
+		$template_args['transaction'] = $this->_current_txn;
459
+		$template_args['revisit'] = self::getRequest()->getRequestParam('revisit', false, 'bool');
460
+		add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_registration_details'));
461
+		if ($this->_is_primary && ! $this->_current_txn->is_free()) {
462
+			add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_ajax_content'));
463
+		}
464
+		return EEH_Template::locate_template(
465
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-overview.template.php',
466
+			$template_args
467
+		);
468
+	}
469
+
470
+
471
+	/**
472
+	 * _update_server_wait_time
473
+	 *
474
+	 * @param array $thank_you_page_data thank you page portion of the incoming JSON array from the WP heartbeat data
475
+	 * @return array
476
+	 * @throws EE_Error
477
+	 * @throws ReflectionException
478
+	 */
479
+	private function _update_server_wait_time($thank_you_page_data = array())
480
+	{
481
+		$response['espresso_thank_you_page'] = array(
482
+			'still_waiting' => isset($thank_you_page_data['initial_access'])
483
+				? time() - $thank_you_page_data['initial_access']
484
+				: 0,
485
+			'txn_status'    => $this->_current_txn->status_ID(),
486
+		);
487
+		return $response;
488
+	}
489
+
490
+
491
+	/**
492
+	 * get_registration_details
493
+	 *
494
+	 * @throws EE_Error
495
+	 */
496
+	public function get_registration_details()
497
+	{
498
+		// prepare variables for displaying
499
+		$template_args = array();
500
+		$template_args['transaction'] = $this->_current_txn;
501
+		$template_args['reg_url_link'] = $this->_reg_url_link;
502
+		$template_args['is_primary'] = $this->_is_primary;
503
+		$template_args['SPCO_attendee_information_url'] = $this->_SPCO_attendee_information_url;
504
+		$template_args['resend_reg_confirmation_url'] = add_query_arg(
505
+			array('token' => $this->_reg_url_link, 'resend_reg_confirmation' => 'true'),
506
+			EE_Registry::instance()->CFG->core->thank_you_page_url()
507
+		);
508
+		// verify template arguments
509
+		EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
510
+		EEH_Template_Validator::verify_isnt_null(
511
+			$template_args['SPCO_attendee_information_url'],
512
+			'$SPCO_attendee_information_url'
513
+		);
514
+		echo EEH_Template::locate_template(
515
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-registration-details.template.php',
516
+			$template_args
517
+		);
518
+	}
519
+
520
+
521
+	/**
522
+	 * resend_reg_confirmation_email
523
+	 *
524
+	 * @throws EE_Error
525
+	 * @throws ReflectionException
526
+	 */
527
+	public static function resend_reg_confirmation_email()
528
+	{
529
+		$reg_url_link = self::getRequest()->getRequestParam('token');
530
+		// was a REG_ID passed ?
531
+		if ($reg_url_link) {
532
+			$registration = EEM_Registration::instance()->get_one(
533
+				array(array('REG_url_link' => $reg_url_link))
534
+			);
535
+			if ($registration instanceof EE_Registration) {
536
+				// resend email
537
+				EED_Messages::process_resend(array('_REG_ID' => $registration->ID()));
538
+			} else {
539
+				EE_Error::add_error(
540
+					esc_html__(
541
+						'The Registration Confirmation email could not be sent because a valid Registration could not be retrieved from the database.',
542
+						'event_espresso'
543
+					),
544
+					__FILE__,
545
+					__FUNCTION__,
546
+					__LINE__
547
+				);
548
+			}
549
+		} else {
550
+			EE_Error::add_error(
551
+				esc_html__(
552
+					'The Registration Confirmation email could not be sent because a registration token is missing or invalid.',
553
+					'event_espresso'
554
+				),
555
+				__FILE__,
556
+				__FUNCTION__,
557
+				__LINE__
558
+			);
559
+		}
560
+		// request sent via AJAX ?
561
+		if (EE_FRONT_AJAX) {
562
+			echo wp_json_encode(EE_Error::get_notices(false));
563
+			die();
564
+			// or was JS disabled ?
565
+		} else {
566
+			// save errors so that they get picked up on the next request
567
+			EE_Error::get_notices(true, true);
568
+			wp_safe_redirect(
569
+				add_query_arg(
570
+					array('e_reg_url_link' => $reg_url_link),
571
+					EE_Registry::instance()->CFG->core->thank_you_page_url()
572
+				)
573
+			);
574
+		}
575
+	}
576
+
577
+
578
+	/**
579
+	 * get_ajax_content
580
+	 *
581
+	 * @return void
582
+	 * @throws EE_Error
583
+	 * @throws ReflectionException
584
+	 */
585
+	public function get_ajax_content()
586
+	{
587
+		if (! $this->get_txn()) {
588
+			return;
589
+		}
590
+		// first determine which event(s) require pre-approval or not
591
+		$events = array();
592
+		$events_requiring_pre_approval = array();
593
+		foreach ($this->_current_txn->registrations() as $registration) {
594
+			if ($registration instanceof EE_Registration) {
595
+				$event = $registration->event();
596
+				if ($event instanceof EE_Event) {
597
+					if ($registration->is_not_approved() && $registration->event() instanceof EE_Event) {
598
+						$events_requiring_pre_approval[ $event->ID() ] = $event;
599
+					} else {
600
+						$events[ $event->ID() ] = $event;
601
+					}
602
+				}
603
+			}
604
+		}
605
+		$this->display_details_for_events_requiring_pre_approval($events_requiring_pre_approval);
606
+		$this->display_details_for_events($events);
607
+	}
608
+
609
+
610
+	/**
611
+	 * display_details_for_events
612
+	 *
613
+	 * @param EE_Event[] $events
614
+	 * @return void
615
+	 */
616
+	public function display_details_for_events($events = array())
617
+	{
618
+		if (! empty($events)) {
619
+			?>
620 620
             <div id="espresso-thank-you-page-ajax-content-dv">
621 621
                 <div id="espresso-thank-you-page-ajax-transaction-dv"></div>
622 622
                 <div id="espresso-thank-you-page-ajax-payment-dv"></div>
@@ -624,19 +624,19 @@  discard block
 block discarded – undo
624 624
                     <div id="ee-ajax-loading-dv" class="float-left lt-blue-text">
625 625
                         <span class="dashicons dashicons-upload"></span><span id="ee-ajax-loading-msg-spn">
626 626
                             <?php esc_html_e(
627
-                                'loading transaction and payment information...',
628
-                                'event_espresso'
629
-                            ); ?></span>
627
+								'loading transaction and payment information...',
628
+								'event_espresso'
629
+							); ?></span>
630 630
                     </div>
631 631
                     <?php if (! $this->_is_offline_payment_method && ! $this->_payments_closed) : ?>
632 632
                         <p id="ee-ajax-loading-pg" class="highlight-bg small-text clear">
633 633
                             <?php echo apply_filters(
634
-                                'EED_Thank_You_Page__get_ajax_content__waiting_for_IPN_msg',
635
-                                esc_html__(
636
-                                    'Some payment gateways can take 15 minutes or more to return their payment notification, so please be patient if you require payment confirmation as soon as possible. Please note that as soon as everything is finalized, we will send your full payment and registration confirmation results to you via email.',
637
-                                    'event_espresso'
638
-                                )
639
-                            ); ?>
634
+								'EED_Thank_You_Page__get_ajax_content__waiting_for_IPN_msg',
635
+								esc_html__(
636
+									'Some payment gateways can take 15 minutes or more to return their payment notification, so please be patient if you require payment confirmation as soon as possible. Please note that as soon as everything is finalized, we will send your full payment and registration confirmation results to you via email.',
637
+									'event_espresso'
638
+								)
639
+							); ?>
640 640
                             <br/>
641 641
                             <span class="jst-rght ee-block small-text lt-grey-text">
642 642
                                 <?php esc_html_e('current wait time ', 'event_espresso'); ?>
@@ -647,120 +647,120 @@  discard block
 block discarded – undo
647 647
                 <div class="clear"></div>
648 648
             </div>
649 649
             <?php
650
-        }
651
-    }
652
-
653
-
654
-    /**
655
-     * display_details_for_events_requiring_pre_approval
656
-     *
657
-     * @param EE_Event[] $events
658
-     * @return void
659
-     * @throws EE_Error
660
-     * @throws EE_Error
661
-     */
662
-    public function display_details_for_events_requiring_pre_approval($events = array())
663
-    {
664
-        if (! empty($events)) {
665
-            ?>
650
+		}
651
+	}
652
+
653
+
654
+	/**
655
+	 * display_details_for_events_requiring_pre_approval
656
+	 *
657
+	 * @param EE_Event[] $events
658
+	 * @return void
659
+	 * @throws EE_Error
660
+	 * @throws EE_Error
661
+	 */
662
+	public function display_details_for_events_requiring_pre_approval($events = array())
663
+	{
664
+		if (! empty($events)) {
665
+			?>
666 666
             <div id="espresso-thank-you-page-not-approved-message-dv">
667 667
                 <h4 class="orange-text"><?php esc_html_e('Important Notice:', 'event_espresso'); ?></h4>
668 668
                 <p id="events-requiring-pre-approval-pg" class="small-text">
669 669
                     <?php echo apply_filters(
670
-                        'AHEE__EED_Thank_You_Page__get_ajax_content__not_approved_message',
671
-                        esc_html__(
672
-                            'The following Event(s) you have registered for do not require payment at this time and will not be billed for during this transaction. Billing will only occur after all attendees have been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.',
673
-                            'event_espresso'
674
-                        )
675
-                    ); ?>
670
+						'AHEE__EED_Thank_You_Page__get_ajax_content__not_approved_message',
671
+						esc_html__(
672
+							'The following Event(s) you have registered for do not require payment at this time and will not be billed for during this transaction. Billing will only occur after all attendees have been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.',
673
+							'event_espresso'
674
+						)
675
+					); ?>
676 676
                 </p>
677 677
                 <ul class="events-requiring-pre-approval-ul">
678 678
                     <?php
679
-                    foreach ($events as $event) {
680
-                        if ($event instanceof EE_Event) {
681
-                            echo '<li><span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>',
682
-                            esc_html($event->name()),
683
-                            '</li>';
684
-                        }
685
-                    } ?>
679
+					foreach ($events as $event) {
680
+						if ($event instanceof EE_Event) {
681
+							echo '<li><span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>',
682
+							esc_html($event->name()),
683
+							'</li>';
684
+						}
685
+					} ?>
686 686
                 </ul>
687 687
                 <div class="clear"></div>
688 688
             </div>
689 689
             <?php
690
-        }
691
-    }
692
-
693
-
694
-    /**
695
-     * get_transaction_details
696
-     *
697
-     * @return string
698
-     * @throws EE_Error
699
-     */
700
-    public function get_transaction_details()
701
-    {
702
-        // prepare variables for displaying
703
-        $template_args = array();
704
-        $template_args['transaction'] = $this->_current_txn;
705
-        $template_args['reg_url_link'] = $this->_reg_url_link;
706
-        $template_args['primary_registrant_name'] = $this->_primary_registrant->attendee()->full_name(true);
707
-        // link to SPCO payment_options
708
-        $template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
709
-        $template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
710
-        // verify template arguments
711
-        EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
712
-        EEH_Template_Validator::verify_isnt_null(
713
-            $template_args['show_try_pay_again_link'],
714
-            '$show_try_pay_again_link'
715
-        );
716
-        EEH_Template_Validator::verify_isnt_null(
717
-            $template_args['SPCO_payment_options_url'],
718
-            '$SPCO_payment_options_url'
719
-        );
720
-        return EEH_Template::locate_template(
721
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-transaction-details.template.php',
722
-            $template_args
723
-        );
724
-    }
725
-
726
-
727
-    /**
728
-     * get_payment_row_html
729
-     *
730
-     * @param EE_Payment $payment
731
-     * @return string
732
-     * @throws EE_Error
733
-     */
734
-    public function get_payment_row_html(EE_Payment $payment = null)
735
-    {
736
-        $html = '';
737
-        if (! $payment instanceof EE_Payment) {
738
-            return '';
739
-        }
740
-        if (
741
-            $payment->payment_method() instanceof EE_Payment_Method
742
-            && $payment->status() === EEM_Payment::status_id_failed
743
-            && $payment->payment_method()->is_off_site()
744
-        ) {
745
-            // considering the registrant has made it to the Thank You page,
746
-            // any failed payments may actually be pending and the IPN is just slow
747
-            // so let's
748
-            $payment->set_status(EEM_Payment::status_id_pending);
749
-        }
750
-        $payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined
751
-            ? '<br /><span class="small-text">' . esc_html($payment->gateway_response()) . '</span>'
752
-            : '';
753
-        $html .= '
690
+		}
691
+	}
692
+
693
+
694
+	/**
695
+	 * get_transaction_details
696
+	 *
697
+	 * @return string
698
+	 * @throws EE_Error
699
+	 */
700
+	public function get_transaction_details()
701
+	{
702
+		// prepare variables for displaying
703
+		$template_args = array();
704
+		$template_args['transaction'] = $this->_current_txn;
705
+		$template_args['reg_url_link'] = $this->_reg_url_link;
706
+		$template_args['primary_registrant_name'] = $this->_primary_registrant->attendee()->full_name(true);
707
+		// link to SPCO payment_options
708
+		$template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
709
+		$template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
710
+		// verify template arguments
711
+		EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
712
+		EEH_Template_Validator::verify_isnt_null(
713
+			$template_args['show_try_pay_again_link'],
714
+			'$show_try_pay_again_link'
715
+		);
716
+		EEH_Template_Validator::verify_isnt_null(
717
+			$template_args['SPCO_payment_options_url'],
718
+			'$SPCO_payment_options_url'
719
+		);
720
+		return EEH_Template::locate_template(
721
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-transaction-details.template.php',
722
+			$template_args
723
+		);
724
+	}
725
+
726
+
727
+	/**
728
+	 * get_payment_row_html
729
+	 *
730
+	 * @param EE_Payment $payment
731
+	 * @return string
732
+	 * @throws EE_Error
733
+	 */
734
+	public function get_payment_row_html(EE_Payment $payment = null)
735
+	{
736
+		$html = '';
737
+		if (! $payment instanceof EE_Payment) {
738
+			return '';
739
+		}
740
+		if (
741
+			$payment->payment_method() instanceof EE_Payment_Method
742
+			&& $payment->status() === EEM_Payment::status_id_failed
743
+			&& $payment->payment_method()->is_off_site()
744
+		) {
745
+			// considering the registrant has made it to the Thank You page,
746
+			// any failed payments may actually be pending and the IPN is just slow
747
+			// so let's
748
+			$payment->set_status(EEM_Payment::status_id_pending);
749
+		}
750
+		$payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined
751
+			? '<br /><span class="small-text">' . esc_html($payment->gateway_response()) . '</span>'
752
+			: '';
753
+		$html .= '
754 754
             <tr>
755 755
                 <td>
756 756
                     ' . esc_html($payment->timestamp()) . '
757 757
                 </td>
758 758
                 <td>
759 759
                     ' . (
760
-            $payment->payment_method() instanceof EE_Payment_Method
761
-                ? esc_html($payment->payment_method()->name())
762
-                : esc_html__('Unknown', 'event_espresso')
763
-            ) . '
760
+			$payment->payment_method() instanceof EE_Payment_Method
761
+				? esc_html($payment->payment_method()->name())
762
+				: esc_html__('Unknown', 'event_espresso')
763
+			) . '
764 764
                 </td>
765 765
                 <td class="jst-rght">
766 766
                     ' . EEH_Template::format_currency($payment->amount()) . '
@@ -769,81 +769,81 @@  discard block
 block discarded – undo
769 769
                     ' . $payment->pretty_status(true) . $payment_declined_msg . '
770 770
                 </td>
771 771
             </tr>';
772
-        do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment);
773
-        return $html;
774
-    }
775
-
776
-
777
-    /**
778
-     * get_payment_details
779
-     *
780
-     * @param EE_Payment[] $payments
781
-     * @return string
782
-     * @throws EE_Error
783
-     * @throws ReflectionException
784
-     */
785
-    public function get_payment_details($payments = array())
786
-    {
787
-        // prepare variables for displaying
788
-        $template_args = array();
789
-        $template_args['transaction'] = $this->_current_txn;
790
-        $template_args['reg_url_link'] = $this->_reg_url_link;
791
-        $template_args['payments'] = array();
792
-        foreach ($payments as $payment) {
793
-            $template_args['payments'][] = $this->get_payment_row_html($payment);
794
-        }
795
-        // create a hacky payment object, but dont save it
796
-        $payment = EE_Payment::new_instance(
797
-            array(
798
-                'TXN_ID'        => $this->_current_txn->ID(),
799
-                'STS_ID'        => EEM_Payment::status_id_pending,
800
-                'PAY_timestamp' => time(),
801
-                'PAY_amount'    => $this->_current_txn->total(),
802
-                'PMD_ID'        => $this->_current_txn->payment_method_ID(),
803
-            )
804
-        );
805
-        $payment_method = $this->_current_txn->payment_method();
806
-        if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base) {
807
-            $template_args['gateway_content'] = $payment_method->type_obj()->payment_overview_content($payment);
808
-        } else {
809
-            $template_args['gateway_content'] = '';
810
-        }
811
-        // link to SPCO payment_options
812
-        $template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
813
-        $template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
814
-        // verify template arguments
815
-        EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
816
-        EEH_Template_Validator::verify_isnt_null($template_args['payments'], '$payments');
817
-        EEH_Template_Validator::verify_isnt_null(
818
-            $template_args['show_try_pay_again_link'],
819
-            '$show_try_pay_again_link'
820
-        );
821
-        EEH_Template_Validator::verify_isnt_null($template_args['gateway_content'], '$gateway_content');
822
-        EEH_Template_Validator::verify_isnt_null(
823
-            $template_args['SPCO_payment_options_url'],
824
-            '$SPCO_payment_options_url'
825
-        );
826
-        return EEH_Template::locate_template(
827
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-payment-details.template.php',
828
-            $template_args
829
-        );
830
-    }
831
-
832
-
833
-    /**
834
-     * get_payment_details
835
-     *
836
-     * @param array $payments
837
-     * @return string
838
-     * @throws EE_Error
839
-     */
840
-    public function get_new_payments($payments = array())
841
-    {
842
-        $payments_html = '';
843
-        // prepare variables for displaying
844
-        foreach ($payments as $payment) {
845
-            $payments_html .= $this->get_payment_row_html($payment);
846
-        }
847
-        return $payments_html;
848
-    }
772
+		do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment);
773
+		return $html;
774
+	}
775
+
776
+
777
+	/**
778
+	 * get_payment_details
779
+	 *
780
+	 * @param EE_Payment[] $payments
781
+	 * @return string
782
+	 * @throws EE_Error
783
+	 * @throws ReflectionException
784
+	 */
785
+	public function get_payment_details($payments = array())
786
+	{
787
+		// prepare variables for displaying
788
+		$template_args = array();
789
+		$template_args['transaction'] = $this->_current_txn;
790
+		$template_args['reg_url_link'] = $this->_reg_url_link;
791
+		$template_args['payments'] = array();
792
+		foreach ($payments as $payment) {
793
+			$template_args['payments'][] = $this->get_payment_row_html($payment);
794
+		}
795
+		// create a hacky payment object, but dont save it
796
+		$payment = EE_Payment::new_instance(
797
+			array(
798
+				'TXN_ID'        => $this->_current_txn->ID(),
799
+				'STS_ID'        => EEM_Payment::status_id_pending,
800
+				'PAY_timestamp' => time(),
801
+				'PAY_amount'    => $this->_current_txn->total(),
802
+				'PMD_ID'        => $this->_current_txn->payment_method_ID(),
803
+			)
804
+		);
805
+		$payment_method = $this->_current_txn->payment_method();
806
+		if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base) {
807
+			$template_args['gateway_content'] = $payment_method->type_obj()->payment_overview_content($payment);
808
+		} else {
809
+			$template_args['gateway_content'] = '';
810
+		}
811
+		// link to SPCO payment_options
812
+		$template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
813
+		$template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
814
+		// verify template arguments
815
+		EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
816
+		EEH_Template_Validator::verify_isnt_null($template_args['payments'], '$payments');
817
+		EEH_Template_Validator::verify_isnt_null(
818
+			$template_args['show_try_pay_again_link'],
819
+			'$show_try_pay_again_link'
820
+		);
821
+		EEH_Template_Validator::verify_isnt_null($template_args['gateway_content'], '$gateway_content');
822
+		EEH_Template_Validator::verify_isnt_null(
823
+			$template_args['SPCO_payment_options_url'],
824
+			'$SPCO_payment_options_url'
825
+		);
826
+		return EEH_Template::locate_template(
827
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-payment-details.template.php',
828
+			$template_args
829
+		);
830
+	}
831
+
832
+
833
+	/**
834
+	 * get_payment_details
835
+	 *
836
+	 * @param array $payments
837
+	 * @return string
838
+	 * @throws EE_Error
839
+	 */
840
+	public function get_new_payments($payments = array())
841
+	{
842
+		$payments_html = '';
843
+		// prepare variables for displaying
844
+		foreach ($payments as $payment) {
845
+			$payments_html .= $this->get_payment_row_html($payment);
846
+		}
847
+		return $payments_html;
848
+	}
849 849
 }
Please login to merge, or discard this patch.
single_page_checkout/templates/registration_page_wrapper.template.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -14,7 +14,7 @@  discard block
 block discarded – undo
14 14
 
15 15
 <div id="ee-single-page-checkout-dv" class="">
16 16
     <?php
17
-    if (! $empty_cart) {
17
+    if ( ! $empty_cart) {
18 18
         if (apply_filters('FHEE__registration_page_wrapper_template__display_time_limit', false)) { ?>
19 19
             <p id="spco-registration-time-limit-pg" class="spco-steps-pg ee-attention important-notice"
20 20
                style="display: none;">
@@ -31,7 +31,7 @@  discard block
 block discarded – undo
31 31
                 <span id="spco-registration-expiration-spn" class="" style="display:none;"></span>
32 32
             </p>
33 33
         <?php }
34
-        if (! $revisit && apply_filters('FHEE__registration_page_wrapper_template__steps_display', true)) {
34
+        if ( ! $revisit && apply_filters('FHEE__registration_page_wrapper_template__steps_display', true)) {
35 35
             ?>
36 36
             <h2 id="spco-steps-big-hdr" class="spco-steps-big-hdr">
37 37
                 <?php esc_html_e(' Steps', 'event_espresso'); ?>
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
         foreach ($reg_steps as $reg_step) {
78 78
             if ($reg_step instanceof EE_SPCO_Reg_Step && $reg_step->slug() != 'finalize_registration') {
79 79
                 $slug = $reg_step->slug();
80
-                do_action('AHEE__' . $slug . '__reg_step_start', $reg_step);
80
+                do_action('AHEE__'.$slug.'__reg_step_start', $reg_step);
81 81
                 // todo: deprecate hook AHEE__registration_page_attendee_information__start
82 82
                 ?>
83 83
                 <div id="spco-<?php echo esc_attr($slug); ?>-dv"
Please login to merge, or discard this patch.
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -16,38 +16,38 @@  discard block
 block discarded – undo
16 16
 
17 17
 <div id="ee-single-page-checkout-dv" class="">
18 18
     <?php
19
-    if (! $empty_cart) {
20
-        if (apply_filters('FHEE__registration_page_wrapper_template__display_time_limit', false)) { ?>
19
+	if (! $empty_cart) {
20
+		if (apply_filters('FHEE__registration_page_wrapper_template__display_time_limit', false)) { ?>
21 21
             <p id="spco-registration-time-limit-pg" class="spco-steps-pg ee-attention important-notice"
22 22
                style="display: none;">
23 23
                 <?php echo sprintf(
24
-                    apply_filters(
25
-                        'FHEE__registration_page_wrapper_template___time_limit',
26
-                        esc_html__('You have %1$s to complete your registration.', 'event_espresso')
27
-                    ),
28
-                    '<span id="spco-registration-time-limit-spn" class="spco-registration-time-limit-spn">'
29
-                    . $registration_time_limit
30
-                    . '</span>'
31
-                );
32
-                ?>
24
+					apply_filters(
25
+						'FHEE__registration_page_wrapper_template___time_limit',
26
+						esc_html__('You have %1$s to complete your registration.', 'event_espresso')
27
+					),
28
+					'<span id="spco-registration-time-limit-spn" class="spco-registration-time-limit-spn">'
29
+					. $registration_time_limit
30
+					. '</span>'
31
+				);
32
+				?>
33 33
                 <span id="spco-registration-expiration-spn" class="" style="display:none;"></span>
34 34
             </p>
35 35
         <?php }
36
-        if (! $revisit && apply_filters('FHEE__registration_page_wrapper_template__steps_display', true)) {
37
-            ?>
36
+		if (! $revisit && apply_filters('FHEE__registration_page_wrapper_template__steps_display', true)) {
37
+			?>
38 38
             <h2 id="spco-steps-big-hdr" class="spco-steps-big-hdr">
39 39
                 <?php esc_html_e(' Steps', 'event_espresso'); ?>
40 40
             </h2>
41 41
 
42 42
             <div id="spco-steps-display-dv">
43 43
                 <?php
44
-                $step_nmbr = 1;
45
-                $total_steps = count($reg_steps) - 1;
46
-                foreach ($reg_steps as $reg_step) {
47
-                    if ($reg_step instanceof EE_SPCO_Reg_Step && $reg_step->slug() != 'finalize_registration') {
48
-                        $slug = $reg_step->slug();
49
-                        $step_display_dv_class = $reg_step->is_current_step() ? 'active-step' : 'inactive-step';
50
-                        ?>
44
+				$step_nmbr = 1;
45
+				$total_steps = count($reg_steps) - 1;
46
+				foreach ($reg_steps as $reg_step) {
47
+					if ($reg_step instanceof EE_SPCO_Reg_Step && $reg_step->slug() != 'finalize_registration') {
48
+						$slug = $reg_step->slug();
49
+						$step_display_dv_class = $reg_step->is_current_step() ? 'active-step' : 'inactive-step';
50
+						?>
51 51
                         <div id="spco-step-<?php echo esc_attr($slug); ?>-display-dv"
52 52
                              class="spco-step-display-dv <?php echo esc_attr($step_display_dv_class); ?> steps-<?php echo esc_attr($total_steps); ?>"
53 53
                         >
@@ -60,28 +60,28 @@  discard block
 block discarded – undo
60 60
                         </div>
61 61
 
62 62
                         <?php
63
-                        if ($step_nmbr < $total_steps) { ?>
63
+						if ($step_nmbr < $total_steps) { ?>
64 64
                             <div class="spco-step-arrow-dv">&raquo;</div>
65 65
                             <?php
66
-                        }
67
-                        $step_nmbr++;
68
-                    }
69
-                }
70
-                ?>
66
+						}
67
+						$step_nmbr++;
68
+					}
69
+				}
70
+				?>
71 71
                 <div class="clear-float"></div>
72 72
             </div>
73 73
 
74 74
             <?php
75
-        }
75
+		}
76 76
 
77
-        do_action('AHEE__SPCO__before_registration_steps');
78
-        $step_nmbr = 1;
79
-        foreach ($reg_steps as $reg_step) {
80
-            if ($reg_step instanceof EE_SPCO_Reg_Step && $reg_step->slug() != 'finalize_registration') {
81
-                $slug = $reg_step->slug();
82
-                do_action('AHEE__' . $slug . '__reg_step_start', $reg_step);
83
-                // todo: deprecate hook AHEE__registration_page_attendee_information__start
84
-                ?>
77
+		do_action('AHEE__SPCO__before_registration_steps');
78
+		$step_nmbr = 1;
79
+		foreach ($reg_steps as $reg_step) {
80
+			if ($reg_step instanceof EE_SPCO_Reg_Step && $reg_step->slug() != 'finalize_registration') {
81
+				$slug = $reg_step->slug();
82
+				do_action('AHEE__' . $slug . '__reg_step_start', $reg_step);
83
+				// todo: deprecate hook AHEE__registration_page_attendee_information__start
84
+				?>
85 85
                 <div id="spco-<?php echo esc_attr($slug); ?>-dv"
86 86
                      class="spco-step-dv <?php echo esc_attr($reg_step->div_class()); ?>"
87 87
                 >
@@ -89,20 +89,20 @@  discard block
 block discarded – undo
89 89
                     <?php do_action('AHEE__SPCO_after_reg_step_form', $slug, $next_step); ?>
90 90
                 </div>
91 91
                 <?php $step_nmbr++;
92
-            }
93
-        }
94
-        do_action('AHEE__SPCO__after_registration_steps');
95
-    } else {
96
-        ?>
92
+			}
93
+		}
94
+		do_action('AHEE__SPCO__after_registration_steps');
95
+	} else {
96
+		?>
97 97
         <h3 id="spco-empty-cart-hdr" class="spco-step-title-hdr">
98 98
             <?php esc_html_e('Nothing in your Event Queue', 'event_espresso'); ?>
99 99
         </h3>
100 100
         <p><?php echo wp_kses($empty_msg, AllowedTags::getWithFormTags()); ?></p>
101 101
         <?php echo wp_kses($cookies_not_set_msg, AllowedTags::getWithFormTags()); ?>
102 102
         <?php
103
-    }
104
-    do_action('AHEE__SPCO__reg_form_footer');
105
-    ?>
103
+	}
104
+	do_action('AHEE__SPCO__reg_form_footer');
105
+	?>
106 106
 
107 107
 </div>
108 108
 
Please login to merge, or discard this patch.
attendee_information/EE_SPCO_Reg_Step_Attendee_Information.class.php 2 patches
Spacing   +93 added lines, -93 removed lines patch added patch discarded remove patch
@@ -65,11 +65,11 @@  discard block
 block discarded – undo
65 65
 
66 66
     public function translate_js_strings()
67 67
     {
68
-        EE_Registry::$i18n_js_strings['required_field']            = esc_html__(
68
+        EE_Registry::$i18n_js_strings['required_field'] = esc_html__(
69 69
             ' is a required question.',
70 70
             'event_espresso'
71 71
         );
72
-        EE_Registry::$i18n_js_strings['required_multi_field']      = esc_html__(
72
+        EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__(
73 73
             ' is a required question. Please enter a value for at least one of the options.',
74 74
             'event_espresso'
75 75
         );
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
             'Please answer all required questions correctly before proceeding.',
78 78
             'event_espresso'
79 79
         );
80
-        EE_Registry::$i18n_js_strings['attendee_info_copied']      = sprintf(
80
+        EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf(
81 81
             esc_html_x(
82 82
                 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.',
83 83
                 'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.',
@@ -85,11 +85,11 @@  discard block
 block discarded – undo
85 85
             ),
86 86
             '<br/>'
87 87
         );
88
-        EE_Registry::$i18n_js_strings['attendee_info_copy_error']  = esc_html__(
88
+        EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__(
89 89
             'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.',
90 90
             'event_espresso'
91 91
         );
92
-        EE_Registry::$i18n_js_strings['enter_valid_email']         = esc_html__(
92
+        EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__(
93 93
             'You must enter a valid email address.',
94 94
             'event_espresso'
95 95
         );
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
         ];
153 153
 
154 154
         // if this isn't a revisit, and they have the privacy consent box enabled, add it
155
-        if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
155
+        if ( ! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
156 156
             $extra_inputs_section->add_subsections(
157 157
                 [
158 158
                     'consent_box' => new EE_Form_Section_Proper(
@@ -201,15 +201,15 @@  discard block
 block discarded – undo
201 201
                     $registration instanceof EE_Registration
202 202
                     && $this->checkout->visit_allows_processing_of_this_registration($registration)
203 203
                 ) {
204
-                    $subsections[ $registration->reg_url_link() ]                       =
204
+                    $subsections[$registration->reg_url_link()]                       =
205 205
                         $this->_registrations_reg_form($registration);
206
-                    $template_args['registrations'][ $registration->reg_url_link() ]    = $registration;
207
-                    $template_args['ticket_count'][ $registration->ticket()->ID() ]     = isset(
208
-                        $template_args['ticket_count'][ $registration->ticket()->ID() ]
206
+                    $template_args['registrations'][$registration->reg_url_link()]    = $registration;
207
+                    $template_args['ticket_count'][$registration->ticket()->ID()]     = isset(
208
+                        $template_args['ticket_count'][$registration->ticket()->ID()]
209 209
                     )
210
-                        ? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
210
+                        ? $template_args['ticket_count'][$registration->ticket()->ID()] + 1
211 211
                         : 1;
212
-                    $ticket_line_item                                                   =
212
+                    $ticket_line_item =
213 213
                         EEH_Line_Item::get_line_items_by_object_type_and_IDs(
214 214
                             $this->checkout->cart->get_grand_total(),
215 215
                             'Ticket',
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
                     $ticket_line_item                                                   = is_array($ticket_line_item)
219 219
                         ? reset($ticket_line_item)
220 220
                         : $ticket_line_item;
221
-                    $template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
221
+                    $template_args['ticket_line_item'][$registration->ticket()->ID()] =
222 222
                         $Line_Item_Display->display_line_item($ticket_line_item);
223 223
                     if ($registration->is_primary_registrant()) {
224 224
                         $primary_registrant = $registration->reg_url_link();
@@ -232,10 +232,10 @@  discard block
 block discarded – undo
232 232
                     : $this->_auto_copy_attendee_info();
233 233
                 // generate hidden input
234 234
                 if (
235
-                    isset($subsections[ $primary_registrant ])
236
-                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
235
+                    isset($subsections[$primary_registrant])
236
+                    && $subsections[$primary_registrant] instanceof EE_Form_Section_Proper
237 237
                 ) {
238
-                    $subsections[ $primary_registrant ]->add_subsections(
238
+                    $subsections[$primary_registrant]->add_subsections(
239 239
                         $copy_options,
240 240
                         'primary_registrant',
241 241
                         false
@@ -247,8 +247,8 @@  discard block
 block discarded – undo
247 247
         // Set the registration form template (default: one form per ticket details table).
248 248
         // We decide the template to used based on the number of forms.
249 249
         $this->_template = $this->reg_form_count > 1
250
-            ? SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_main.template.php'
251
-            : SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_single.template.php';
250
+            ? SPCO_REG_STEPS_PATH . $this->_slug.'/attendee_info_main.template.php'
251
+            : SPCO_REG_STEPS_PATH.$this->_slug.'/attendee_info_single.template.php';
252 252
 
253 253
         return new EE_Form_Section_Proper(
254 254
             [
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
         $form_args = [];
283 283
         // verify that registration has valid event
284 284
         if ($registration->event() instanceof EE_Event) {
285
-            $field_name      = 'Event_Question_Group.'
285
+            $field_name = 'Event_Question_Group.'
286 286
                                . EEM_Event_Question_Group::instance()->fieldNameForContext(
287 287
                                    $registration->is_primary_registrant()
288 288
                                );
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
             if ($question_groups) {
306 306
                 // array of params to pass to parent constructor
307 307
                 $form_args = [
308
-                    'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
308
+                    'html_id'         => 'ee-registration-'.$registration->reg_url_link(),
309 309
                     'html_class'      => 'ee-reg-form-attendee-dv',
310 310
                     'html_style'      => $this->checkout->admin_request
311 311
                         ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
                 ];
328 328
                 foreach ($question_groups as $question_group) {
329 329
                     if ($question_group instanceof EE_Question_Group) {
330
-                        $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form(
330
+                        $form_args['subsections'][$question_group->identifier()] = $this->_question_group_reg_form(
331 331
                             $registration,
332 332
                             $question_group
333 333
                         );
@@ -361,7 +361,7 @@  discard block
 block discarded – undo
361 361
         $attendee_nmbr++;
362 362
 
363 363
         // Increment the reg forms number if form is valid.
364
-        if (! empty($form_args)) {
364
+        if ( ! empty($form_args)) {
365 365
             $this->reg_form_count++;
366 366
         }
367 367
 
@@ -384,7 +384,7 @@  discard block
 block discarded – undo
384 384
         // generate hidden input
385 385
         return new EE_Hidden_Input(
386 386
             [
387
-                'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
387
+                'html_id' => 'additional-attendee-reg-info-'.$registration->reg_url_link(),
388 388
                 'default' => $additional_attendee_reg_info,
389 389
             ]
390 390
         );
@@ -405,12 +405,12 @@  discard block
 block discarded – undo
405 405
     {
406 406
         // array of params to pass to parent constructor
407 407
         $form_args = [
408
-            'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(),
408
+            'html_id'         => 'ee-reg-form-qstn-grp-'.$question_group->identifier().'-'.$registration->ID(),
409 409
             'html_class'      => $this->checkout->admin_request
410 410
                 ? 'form-table ee-reg-form-qstn-grp-dv'
411 411
                 : 'ee-reg-form-qstn-grp-dv',
412
-            'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-'
413
-                                 . $registration->ID() . '-lbl',
412
+            'html_label_id'   => 'ee-reg-form-qstn-grp-'.$question_group->identifier().'-'
413
+                                 . $registration->ID().'-lbl',
414 414
             'subsections'     => [
415 415
                 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
416 416
             ],
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
         // where params
422 422
         $query_params = ['QST_deleted' => 0];
423 423
         // don't load admin only questions on the frontend
424
-        if (! $this->checkout->admin_request) {
424
+        if ( ! $this->checkout->admin_request) {
425 425
             $query_params['QST_admin_only'] = ['!=', true];
426 426
         }
427 427
         $questions = $question_group->get_many_related(
@@ -455,7 +455,7 @@  discard block
 block discarded – undo
455 455
                 $identifier                              = $question->is_system_question()
456 456
                     ? $question->system_ID()
457 457
                     : $question->ID();
458
-                $form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question);
458
+                $form_args['subsections'][$identifier] = $this->reg_form_question($registration, $question);
459 459
             }
460 460
         }
461 461
         $form_args['subsections'] = apply_filters(
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
     {
568 568
         return new EE_Form_Section_HTML(
569 569
             EEH_Template::locate_template(
570
-                SPCO_REG_STEPS_PATH . $this->_slug . '/_auto_copy_attendee_info.template.php',
570
+                SPCO_REG_STEPS_PATH.$this->_slug.'/_auto_copy_attendee_info.template.php',
571 571
                 apply_filters(
572 572
                     'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
573 573
                     []
@@ -596,20 +596,20 @@  discard block
 block discarded – undo
596 596
             if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
597 597
                 // if this is a new ticket OR if this is the very first additional attendee after the primary attendee
598 598
                 if ($registration->ticket()->ID() !== $prev_ticket) {
599
-                    $item_name                          = $registration->ticket()->name();
600
-                    $item_name                          .= $registration->ticket()->description() !== ''
601
-                        ? ' - ' . $registration->ticket()->description()
599
+                    $item_name = $registration->ticket()->name();
600
+                    $item_name .= $registration->ticket()->description() !== ''
601
+                        ? ' - '.$registration->ticket()->description()
602 602
                         : '';
603
-                    $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-'
603
+                    $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-'
604 604
                                                 . $registration->ticket()->ID()
605
-                                                . ']' ] =
605
+                                                . ']'] =
606 606
                         new EE_Form_Section_HTML(
607
-                            '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
607
+                            '<h6 class="spco-copy-attendee-event-hdr">'.$item_name.'</h6>'
608 608
                         );
609
-                    $prev_ticket                        = $registration->ticket()->ID();
609
+                    $prev_ticket = $registration->ticket()->ID();
610 610
                 }
611 611
 
612
-                $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] =
612
+                $copy_attendee_info_inputs['spco_copy_attendee_chk['.$registration->ID().']'] =
613 613
                     new EE_Checkbox_Multi_Input(
614 614
                         [
615 615
                             $registration->ID() => sprintf(
@@ -618,7 +618,7 @@  discard block
 block discarded – undo
618 618
                             ),
619 619
                         ],
620 620
                         [
621
-                            'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
621
+                            'html_id'                 => 'spco-copy-attendee-chk-'.$registration->reg_url_link(),
622 622
                             'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
623 623
                             'display_html_label_text' => false,
624 624
                         ]
@@ -664,7 +664,7 @@  discard block
 block discarded – undo
664 664
             $registration,
665 665
             $question->system_ID()
666 666
         );
667
-        $answer       = $answer_value === null
667
+        $answer = $answer_value === null
668 668
             ? EEM_Answer::instance()->get_one(
669 669
                 [['QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()]]
670 670
             )
@@ -683,14 +683,14 @@  discard block
 block discarded – undo
683 683
         }
684 684
         // verify instance
685 685
         if ($answer instanceof EE_Answer) {
686
-            if (! empty($answer_value)) {
686
+            if ( ! empty($answer_value)) {
687 687
                 $answer->set('ANS_value', $answer_value);
688 688
             }
689 689
             $answer->cache('Question', $question);
690 690
             // remember system ID had a bug where sometimes it could be null
691 691
             $answer_cache_id = $question->is_system_question()
692
-                ? $question->system_ID() . '-' . $registration->reg_url_link()
693
-                : $question->ID() . '-' . $registration->reg_url_link();
692
+                ? $question->system_ID().'-'.$registration->reg_url_link()
693
+                : $question->ID().'-'.$registration->reg_url_link();
694 694
             $registration->cache('Answer', $answer, $answer_cache_id);
695 695
         }
696 696
         return $this->_generate_question_input($registration, $question, $answer);
@@ -713,7 +713,7 @@  discard block
 block discarded – undo
713 713
         $identifier                               = $question->is_system_question()
714 714
             ? $question->system_ID()
715 715
             : $question->ID();
716
-        $this->_required_questions[ $identifier ] = $question->required();
716
+        $this->_required_questions[$identifier] = $question->required();
717 717
         add_filter(
718 718
             'FHEE__EE_Question__generate_form_input__country_options',
719 719
             [$this, 'use_cached_countries_for_form_input'],
@@ -726,18 +726,18 @@  discard block
 block discarded – undo
726 726
             10,
727 727
             4
728 728
         );
729
-        $input_constructor_args                  = [
730
-            'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
731
-            'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
732
-            'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
733
-            'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
729
+        $input_constructor_args = [
730
+            'html_name'        => 'ee_reg_qstn['.$registration->ID().']['.$identifier.']',
731
+            'html_id'          => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier,
732
+            'html_class'       => 'ee-reg-qstn ee-reg-qstn-'.$identifier,
733
+            'html_label_id'    => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier,
734 734
             'html_label_class' => 'ee-reg-qstn',
735 735
         ];
736 736
         $input_constructor_args['html_label_id'] .= '-lbl';
737 737
         if ($answer instanceof EE_Answer && $answer->ID()) {
738
-            $input_constructor_args['html_name']     .= '[' . $answer->ID() . ']';
739
-            $input_constructor_args['html_id']       .= '-' . $answer->ID();
740
-            $input_constructor_args['html_label_id'] .= '-' . $answer->ID();
738
+            $input_constructor_args['html_name']     .= '['.$answer->ID().']';
739
+            $input_constructor_args['html_id']       .= '-'.$answer->ID();
740
+            $input_constructor_args['html_label_id'] .= '-'.$answer->ID();
741 741
         }
742 742
         $form_input = $question->generate_form_input(
743 743
             $registration,
@@ -781,10 +781,10 @@  discard block
 block discarded – undo
781 781
         $countries = $this->checkout->action === 'process_reg_step'
782 782
             ? EEM_Country::instance()->get_all_countries()
783 783
             : EEM_Country::instance()->get_all_active_countries();
784
-        if (! empty($countries)) {
784
+        if ( ! empty($countries)) {
785 785
             foreach ($countries as $country) {
786 786
                 if ($country instanceof EE_Country) {
787
-                    $country_options[ $country->ID() ] = $country->name();
787
+                    $country_options[$country->ID()] = $country->name();
788 788
                 }
789 789
             }
790 790
         }
@@ -830,10 +830,10 @@  discard block
 block discarded – undo
830 830
         $states        = $this->checkout->action === 'process_reg_step'
831 831
             ? EEM_State::instance()->get_all_states()
832 832
             : EEM_State::instance()->get_all_active_states();
833
-        if (! empty($states)) {
833
+        if ( ! empty($states)) {
834 834
             foreach ($states as $state) {
835 835
                 if ($state instanceof EE_State) {
836
-                    $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
836
+                    $state_options[$state->country()->name()][$state->ID()] = $state->name();
837 837
                 }
838 838
             }
839 839
         }
@@ -877,7 +877,7 @@  discard block
 block discarded – undo
877 877
             );
878 878
             return false;
879 879
         }
880
-        if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
880
+        if ( ! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
881 881
             EE_Error::add_error(
882 882
                 esc_html__(
883 883
                     'A valid transaction could not be initiated for processing your registrations.',
@@ -904,7 +904,7 @@  discard block
 block discarded – undo
904 904
                     '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.',
905 905
                     'event_espresso'
906 906
                 ),
907
-                '<a href="' . get_post_type_archive_link('espresso_events') . '" >',
907
+                '<a href="'.get_post_type_archive_link('espresso_events').'" >',
908 908
                 '</a>',
909 909
                 '<br />'
910 910
             );
@@ -924,7 +924,7 @@  discard block
 block discarded – undo
924 924
             // but return immediately if the previous step exited early due to errors
925 925
             return false;
926 926
         }
927
-        if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
927
+        if ( ! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
928 928
             // generate a correctly translated string for all possible singular/plural combinations
929 929
             if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
930 930
                 $error_msg = sprintf(
@@ -1007,7 +1007,7 @@  discard block
 block discarded – undo
1007 1007
         // grab the saved registrations from the transaction
1008 1008
         foreach ($registrations as $registration) {
1009 1009
             // verify EE_Registration object
1010
-            if (! $registration instanceof EE_Registration) {
1010
+            if ( ! $registration instanceof EE_Registration) {
1011 1011
                 EE_Error::add_error(
1012 1012
                     esc_html__(
1013 1013
                         'An invalid Registration object was discovered when attempting to process your registration information.',
@@ -1021,12 +1021,12 @@  discard block
 block discarded – undo
1021 1021
             }
1022 1022
             $reg_url_link = $registration->reg_url_link();
1023 1023
             // reg_url_link exists ?
1024
-            if (! empty($reg_url_link)) {
1024
+            if ( ! empty($reg_url_link)) {
1025 1025
                 // should this registration be processed during this visit ?
1026 1026
                 if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
1027 1027
                     // if NOT revisiting, then let's save the registration now,
1028 1028
                     // so that we have a REG_ID to use when generating other objects
1029
-                    if (! $this->checkout->revisit) {
1029
+                    if ( ! $this->checkout->revisit) {
1030 1030
                         $registration->save();
1031 1031
                     }
1032 1032
                     /**
@@ -1052,18 +1052,18 @@  discard block
 block discarded – undo
1052 1052
 
1053 1053
                     // Houston, we have a registration!
1054 1054
                     $att_nmbr++;
1055
-                    $this->_attendee_data[ $reg_url_link ] = [];
1055
+                    $this->_attendee_data[$reg_url_link] = [];
1056 1056
                     // grab any existing related answer objects
1057 1057
                     $this->_registration_answers = $registration->answers();
1058 1058
                     // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
1059
-                    if (isset($valid_data[ $reg_url_link ])) {
1059
+                    if (isset($valid_data[$reg_url_link])) {
1060 1060
                         // do we need to copy basic info from primary attendee ?
1061
-                        $copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info'])
1062
-                                        && absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
1061
+                        $copy_primary = isset($valid_data[$reg_url_link]['additional_attendee_reg_info'])
1062
+                                        && absint($valid_data[$reg_url_link]['additional_attendee_reg_info']) === 0;
1063 1063
                         // filter form input data for this registration
1064
-                        $valid_data[ $reg_url_link ] = (array) apply_filters(
1064
+                        $valid_data[$reg_url_link] = (array) apply_filters(
1065 1065
                             'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
1066
-                            $valid_data[ $reg_url_link ]
1066
+                            $valid_data[$reg_url_link]
1067 1067
                         );
1068 1068
                         if (isset($valid_data['primary_attendee'])) {
1069 1069
                             $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
@@ -1072,8 +1072,8 @@  discard block
 block discarded – undo
1072 1072
                             unset($valid_data['primary_attendee']);
1073 1073
                         }
1074 1074
                         // now loop through our array of valid post data && process attendee reg forms
1075
-                        foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) {
1076
-                            if (! in_array($form_section, $non_input_form_sections, true)) {
1075
+                        foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) {
1076
+                            if ( ! in_array($form_section, $non_input_form_sections, true)) {
1077 1077
                                 foreach ($form_inputs as $form_input => $input_value) {
1078 1078
                                     // check for critical inputs
1079 1079
                                     if (
@@ -1090,13 +1090,13 @@  discard block
 block discarded – undo
1090 1090
                                         && ! empty($input_value)
1091 1091
                                         && $reg_url_link === $primary_registrant['line_item_id']
1092 1092
                                     ) {
1093
-                                        $primary_registrant[ $form_input ] = $input_value;
1093
+                                        $primary_registrant[$form_input] = $input_value;
1094 1094
                                     } elseif (
1095 1095
                                         $copy_primary
1096 1096
                                               && $input_value === null
1097
-                                              && isset($primary_registrant[ $form_input ])
1097
+                                              && isset($primary_registrant[$form_input])
1098 1098
                                     ) {
1099
-                                        $input_value = $primary_registrant[ $form_input ];
1099
+                                        $input_value = $primary_registrant[$form_input];
1100 1100
                                     }
1101 1101
                                     // now attempt to save the input data
1102 1102
                                     if (
@@ -1136,15 +1136,15 @@  discard block
 block discarded – undo
1136 1136
                         $attendee = $this->checkout->primary_attendee_obj;
1137 1137
                     } else {
1138 1138
                         // ensure critical details are set for additional attendees
1139
-                        $this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1
1139
+                        $this->_attendee_data[$reg_url_link] = $att_nmbr > 1
1140 1140
                             ? $this->_copy_critical_attendee_details_from_primary_registrant(
1141
-                                $this->_attendee_data[ $reg_url_link ]
1141
+                                $this->_attendee_data[$reg_url_link]
1142 1142
                             )
1143
-                            : $this->_attendee_data[ $reg_url_link ];
1143
+                            : $this->_attendee_data[$reg_url_link];
1144 1144
                         // execute create attendee command (which may return an existing attendee)
1145 1145
                         $attendee = EE_Registry::instance()->BUS->execute(
1146 1146
                             new CreateAttendeeCommand(
1147
-                                $this->_attendee_data[ $reg_url_link ],
1147
+                                $this->_attendee_data[$reg_url_link],
1148 1148
                                 $registration
1149 1149
                             )
1150 1150
                         );
@@ -1155,7 +1155,7 @@  discard block
 block discarded – undo
1155 1155
                     }
1156 1156
                     // add relation to registration, set attendee ID, and cache attendee
1157 1157
                     $this->_associate_attendee_with_registration($registration, $attendee);
1158
-                    if (! $registration->attendee() instanceof EE_Attendee) {
1158
+                    if ( ! $registration->attendee() instanceof EE_Attendee) {
1159 1159
                         EE_Error::add_error(
1160 1160
                             sprintf(
1161 1161
                                 esc_html_x(
@@ -1205,7 +1205,7 @@  discard block
 block discarded – undo
1205 1205
                     __LINE__
1206 1206
                 );
1207 1207
                 // remove malformed data
1208
-                unset($valid_data[ $reg_url_link ]);
1208
+                unset($valid_data[$reg_url_link]);
1209 1209
                 return false;
1210 1210
             }
1211 1211
         } // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
@@ -1255,10 +1255,10 @@  discard block
 block discarded – undo
1255 1255
          * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
1256 1256
          */
1257 1257
         $answer_cache_id = $this->checkout->reg_url_link
1258
-            ? $form_input . '-' . $registration->reg_url_link()
1258
+            ? $form_input.'-'.$registration->reg_url_link()
1259 1259
             : (string) $form_input;
1260
-        $answer_is_obj   = isset($this->_registration_answers[ $answer_cache_id ])
1261
-                           && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer;
1260
+        $answer_is_obj   = isset($this->_registration_answers[$answer_cache_id])
1261
+                           && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer;
1262 1262
         // rename form_inputs if they are EE_Attendee properties
1263 1263
         switch ((string) $form_input) {
1264 1264
             case 'state':
@@ -1274,24 +1274,24 @@  discard block
 block discarded – undo
1274 1274
                 break;
1275 1275
 
1276 1276
             default:
1277
-                $ATT_input = 'ATT_' . $form_input;
1277
+                $ATT_input = 'ATT_'.$form_input;
1278 1278
                 $attendee_property = EEM_Attendee::instance()->has_field($ATT_input);
1279
-                $form_input        = $attendee_property ? 'ATT_' . $form_input : $form_input;
1279
+                $form_input        = $attendee_property ? 'ATT_'.$form_input : $form_input;
1280 1280
         }
1281 1281
         // if this form input has a corresponding attendee property
1282 1282
         if ($attendee_property) {
1283
-            $this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value;
1283
+            $this->_attendee_data[$registration->reg_url_link()][$form_input] = $input_value;
1284 1284
             if ($answer_is_obj) {
1285 1285
                 // and delete the corresponding answer since we won't be storing this data in that object
1286
-                $registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer');
1287
-                $this->_registration_answers[ $answer_cache_id ]->delete_permanently();
1286
+                $registration->_remove_relation_to($this->_registration_answers[$answer_cache_id], 'Answer');
1287
+                $this->_registration_answers[$answer_cache_id]->delete_permanently();
1288 1288
             }
1289 1289
             return true;
1290 1290
         }
1291 1291
         if ($answer_is_obj) {
1292 1292
             // save this data to the answer object
1293
-            $this->_registration_answers[ $answer_cache_id ]->set_value($input_value);
1294
-            $result = $this->_registration_answers[ $answer_cache_id ]->save();
1293
+            $this->_registration_answers[$answer_cache_id]->set_value($input_value);
1294
+            $result = $this->_registration_answers[$answer_cache_id]->save();
1295 1295
             return $result !== false;
1296 1296
         }
1297 1297
         foreach ($this->_registration_answers as $answer) {
@@ -1318,7 +1318,7 @@  discard block
 block discarded – undo
1318 1318
     ) {
1319 1319
         if (empty($input_value)) {
1320 1320
             // if the form input isn't marked as being required, then just return
1321
-            if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) {
1321
+            if ( ! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) {
1322 1322
                 return true;
1323 1323
             }
1324 1324
             switch ($form_input) {
@@ -1416,7 +1416,7 @@  discard block
 block discarded – undo
1416 1416
                 false
1417 1417
             )
1418 1418
         ) {
1419
-            $address_details           = [
1419
+            $address_details = [
1420 1420
                 'ATT_address',
1421 1421
                 'ATT_address2',
1422 1422
                 'ATT_city',
@@ -1429,10 +1429,10 @@  discard block
 block discarded – undo
1429 1429
         }
1430 1430
         foreach ($critical_attendee_details as $critical_attendee_detail) {
1431 1431
             if (
1432
-                ! isset($attendee_data[ $critical_attendee_detail ])
1433
-                || empty($attendee_data[ $critical_attendee_detail ])
1432
+                ! isset($attendee_data[$critical_attendee_detail])
1433
+                || empty($attendee_data[$critical_attendee_detail])
1434 1434
             ) {
1435
-                $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get(
1435
+                $attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get(
1436 1436
                     $critical_attendee_detail
1437 1437
                 );
1438 1438
             }
Please login to merge, or discard this patch.
Indentation   +1451 added lines, -1451 removed lines patch added patch discarded remove patch
@@ -17,1458 +17,1458 @@
 block discarded – undo
17 17
  */
18 18
 class EE_SPCO_Reg_Step_Attendee_Information extends EE_SPCO_Reg_Step
19 19
 {
20
-    /**
21
-     * @type bool $_print_copy_info
22
-     */
23
-    private $_print_copy_info = false;
24
-
25
-    /**
26
-     * @type array $_attendee_data
27
-     */
28
-    private $_attendee_data = [];
29
-
30
-    /**
31
-     * @type array $_required_questions
32
-     */
33
-    private $_required_questions = [];
34
-
35
-    /**
36
-     * @type array $_registration_answers
37
-     */
38
-    private $_registration_answers = [];
39
-
40
-    /**
41
-     * @type int $reg_form_count
42
-     */
43
-    protected $reg_form_count = 0;
44
-
45
-
46
-    /**
47
-     *    class constructor
48
-     *
49
-     * @access    public
50
-     * @param EE_Checkout $checkout
51
-     */
52
-    public function __construct(EE_Checkout $checkout)
53
-    {
54
-        $this->request  = EED_Single_Page_Checkout::getRequest();
55
-        $this->_slug    = 'attendee_information';
56
-        $this->_name    = esc_html__('Attendee Information', 'event_espresso');
57
-        $this->checkout = $checkout;
58
-        $this->_reset_success_message();
59
-        $this->set_instructions(
60
-            esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso')
61
-        );
62
-    }
63
-
64
-
65
-    public function translate_js_strings()
66
-    {
67
-        EE_Registry::$i18n_js_strings['required_field']            = esc_html__(
68
-            ' is a required question.',
69
-            'event_espresso'
70
-        );
71
-        EE_Registry::$i18n_js_strings['required_multi_field']      = esc_html__(
72
-            ' is a required question. Please enter a value for at least one of the options.',
73
-            'event_espresso'
74
-        );
75
-        EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__(
76
-            'Please answer all required questions correctly before proceeding.',
77
-            'event_espresso'
78
-        );
79
-        EE_Registry::$i18n_js_strings['attendee_info_copied']      = sprintf(
80
-            esc_html_x(
81
-                'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.',
82
-                'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.',
83
-                'event_espresso'
84
-            ),
85
-            '<br/>'
86
-        );
87
-        EE_Registry::$i18n_js_strings['attendee_info_copy_error']  = esc_html__(
88
-            'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.',
89
-            'event_espresso'
90
-        );
91
-        EE_Registry::$i18n_js_strings['enter_valid_email']         = esc_html__(
92
-            'You must enter a valid email address.',
93
-            'event_espresso'
94
-        );
95
-        EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__(
96
-            'You must enter a valid email address and answer all other required questions before you can proceed.',
97
-            'event_espresso'
98
-        );
99
-    }
100
-
101
-
102
-    public function enqueue_styles_and_scripts()
103
-    {
104
-    }
105
-
106
-
107
-    /**
108
-     * @return boolean
109
-     */
110
-    public function initialize_reg_step()
111
-    {
112
-        return true;
113
-    }
114
-
115
-
116
-    /**
117
-     * @return EE_Form_Section_Proper
118
-     * @throws DomainException
119
-     * @throws EE_Error
120
-     * @throws InvalidArgumentException
121
-     * @throws ReflectionException
122
-     * @throws EntityNotFoundException
123
-     * @throws InvalidDataTypeException
124
-     * @throws InvalidInterfaceException
125
-     */
126
-    public function generate_reg_form()
127
-    {
128
-        /**
129
-         * @var $reg_config EE_Registration_Config
130
-         */
131
-        $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
132
-
133
-        $this->_print_copy_info = $reg_config->copyAttendeeInfo();
134
-
135
-        // Init reg forms count.
136
-        $this->reg_form_count = 0;
137
-
138
-        $primary_registrant = null;
139
-        // autoload Line_Item_Display classes
140
-        EEH_Autoloader::register_line_item_display_autoloaders();
141
-        $Line_Item_Display = new EE_Line_Item_Display();
142
-        // calculate taxes
143
-        $Line_Item_Display->display_line_item(
144
-            $this->checkout->cart->get_grand_total(),
145
-            ['set_tax_rate' => true]
146
-        );
147
-        /** @var $subsections EE_Form_Section_Proper[] */
148
-        $extra_inputs_section = $this->reg_step_hidden_inputs();
149
-        $subsections          = [
150
-            'default_hidden_inputs' => $extra_inputs_section,
151
-        ];
152
-
153
-        // if this isn't a revisit, and they have the privacy consent box enabled, add it
154
-        if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
155
-            $extra_inputs_section->add_subsections(
156
-                [
157
-                    'consent_box' => new EE_Form_Section_Proper(
158
-                        [
159
-                            'layout_strategy' =>
160
-                                new EE_Template_Layout(
161
-                                    [
162
-                                        'input_template_file' => SPCO_REG_STEPS_PATH
163
-                                                                 . $this->_slug
164
-                                                                 . '/privacy_consent.template.php',
165
-                                    ]
166
-                                ),
167
-                            'subsections'     => [
168
-                                'consent' => new EE_Checkbox_Multi_Input(
169
-                                    [
170
-                                        'consent' => $reg_config->getConsentCheckboxLabelText(),
171
-                                    ],
172
-                                    [
173
-                                        'required'                          => true,
174
-                                        'required_validation_error_message' => esc_html__(
175
-                                            'You must consent to these terms in order to register.',
176
-                                            'event_espresso'
177
-                                        ),
178
-                                        'html_label_text'                   => '',
179
-                                    ]
180
-                                ),
181
-                            ],
182
-                        ]
183
-                    ),
184
-                ],
185
-                null,
186
-                false
187
-            );
188
-        }
189
-        $template_args = [
190
-            'revisit'       => $this->checkout->revisit,
191
-            'registrations' => [],
192
-            'ticket_count'  => [],
193
-        ];
194
-        // grab the saved registrations from the transaction
195
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
196
-        if ($registrations) {
197
-            foreach ($registrations as $registration) {
198
-                // can this registration be processed during this visit ?
199
-                if (
200
-                    $registration instanceof EE_Registration
201
-                    && $this->checkout->visit_allows_processing_of_this_registration($registration)
202
-                ) {
203
-                    $subsections[ $registration->reg_url_link() ]                       =
204
-                        $this->_registrations_reg_form($registration);
205
-                    $template_args['registrations'][ $registration->reg_url_link() ]    = $registration;
206
-                    $template_args['ticket_count'][ $registration->ticket()->ID() ]     = isset(
207
-                        $template_args['ticket_count'][ $registration->ticket()->ID() ]
208
-                    )
209
-                        ? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
210
-                        : 1;
211
-                    $ticket_line_item                                                   =
212
-                        EEH_Line_Item::get_line_items_by_object_type_and_IDs(
213
-                            $this->checkout->cart->get_grand_total(),
214
-                            'Ticket',
215
-                            [$registration->ticket()->ID()]
216
-                        );
217
-                    $ticket_line_item                                                   = is_array($ticket_line_item)
218
-                        ? reset($ticket_line_item)
219
-                        : $ticket_line_item;
220
-                    $template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
221
-                        $Line_Item_Display->display_line_item($ticket_line_item);
222
-                    if ($registration->is_primary_registrant()) {
223
-                        $primary_registrant = $registration->reg_url_link();
224
-                    }
225
-                }
226
-            }
227
-
228
-            if ($primary_registrant && count($registrations) > 1) {
229
-                $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info
230
-                    ? $this->_copy_attendee_info_form()
231
-                    : $this->_auto_copy_attendee_info();
232
-                // generate hidden input
233
-                if (
234
-                    isset($subsections[ $primary_registrant ])
235
-                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
236
-                ) {
237
-                    $subsections[ $primary_registrant ]->add_subsections(
238
-                        $copy_options,
239
-                        'primary_registrant',
240
-                        false
241
-                    );
242
-                }
243
-            }
244
-        }
245
-
246
-        // Set the registration form template (default: one form per ticket details table).
247
-        // We decide the template to used based on the number of forms.
248
-        $this->_template = $this->reg_form_count > 1
249
-            ? SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_main.template.php'
250
-            : SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_single.template.php';
251
-
252
-        return new EE_Form_Section_Proper(
253
-            [
254
-                'name'            => $this->reg_form_name(),
255
-                'html_id'         => $this->reg_form_name(),
256
-                'subsections'     => $subsections,
257
-                'layout_strategy' => new EE_Template_Layout(
258
-                    [
259
-                        'layout_template_file' => $this->_template, // layout_template
260
-                        'template_args'        => $template_args,
261
-                    ]
262
-                ),
263
-            ]
264
-        );
265
-    }
266
-
267
-
268
-    /**
269
-     * @param EE_Registration $registration
270
-     * @return EE_Form_Section_Base
271
-     * @throws EE_Error
272
-     * @throws InvalidArgumentException
273
-     * @throws EntityNotFoundException
274
-     * @throws InvalidDataTypeException
275
-     * @throws InvalidInterfaceException
276
-     * @throws ReflectionException
277
-     */
278
-    private function _registrations_reg_form(EE_Registration $registration)
279
-    {
280
-        static $attendee_nmbr = 1;
281
-        $form_args = [];
282
-        // verify that registration has valid event
283
-        if ($registration->event() instanceof EE_Event) {
284
-            $field_name      = 'Event_Question_Group.'
285
-                               . EEM_Event_Question_Group::instance()->fieldNameForContext(
286
-                                   $registration->is_primary_registrant()
287
-                               );
288
-            $question_groups = $registration->event()->question_groups(
289
-                apply_filters(
290
-                // @codingStandardsIgnoreStart
291
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
292
-                    // @codingStandardsIgnoreEnd
293
-                    [
294
-                        [
295
-                            'Event.EVT_ID' => $registration->event()->ID(),
296
-                            $field_name    => true,
297
-                            'QSG_deleted'  => false
298
-                        ],
299
-                        'order_by' => ['QSG_order' => 'ASC'],
300
-                    ],
301
-                    $registration,
302
-                    $this
303
-                )
304
-            );
305
-            if ($question_groups) {
306
-                // array of params to pass to parent constructor
307
-                $form_args = [
308
-                    'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
309
-                    'html_class'      => 'ee-reg-form-attendee-dv',
310
-                    'html_style'      => $this->checkout->admin_request
311
-                        ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
312
-                        : '',
313
-                    'subsections'     => [],
314
-                    'layout_strategy' => new EE_Fieldset_Section_Layout(
315
-                        [
316
-                            'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text',
317
-                            'legend_text'  => sprintf(
318
-                                esc_html_x(
319
-                                    'Attendee %d',
320
-                                    'Attendee 123',
321
-                                    'event_espresso'
322
-                                ),
323
-                                $attendee_nmbr
324
-                            ),
325
-                        ]
326
-                    ),
327
-                ];
328
-                foreach ($question_groups as $question_group) {
329
-                    if ($question_group instanceof EE_Question_Group) {
330
-                        $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form(
331
-                            $registration,
332
-                            $question_group
333
-                        );
334
-                    }
335
-                }
336
-                // add hidden input
337
-                $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input(
338
-                    $registration
339
-                );
340
-
341
-                /**
342
-                 * @var $reg_config EE_Registration_Config
343
-                 */
344
-                $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
345
-
346
-                // If we have question groups for additional attendees, then display the copy options
347
-                $this->_print_copy_info = apply_filters(
348
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form___printCopyInfo',
349
-                    $attendee_nmbr > 1 && $reg_config->copyAttendeeInfo(),
350
-                    $attendee_nmbr
351
-                );
352
-
353
-                if ($registration->is_primary_registrant()) {
354
-                    // generate hidden input
355
-                    $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs(
356
-                        $registration
357
-                    );
358
-                }
359
-            }
360
-        }
361
-        $attendee_nmbr++;
362
-
363
-        // Increment the reg forms number if form is valid.
364
-        if (! empty($form_args)) {
365
-            $this->reg_form_count++;
366
-        }
367
-
368
-        return ! empty($form_args)
369
-            ? new EE_Form_Section_Proper($form_args)
370
-            : new EE_Form_Section_HTML();
371
-    }
372
-
373
-
374
-    /**
375
-     * @param EE_Registration $registration
376
-     * @param bool            $additional_attendee_reg_info
377
-     * @return EE_Form_Input_Base
378
-     * @throws EE_Error
379
-     */
380
-    private function _additional_attendee_reg_info_input(
381
-        EE_Registration $registration,
382
-        $additional_attendee_reg_info = true
383
-    ) {
384
-        // generate hidden input
385
-        return new EE_Hidden_Input(
386
-            [
387
-                'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
388
-                'default' => $additional_attendee_reg_info,
389
-            ]
390
-        );
391
-    }
392
-
393
-
394
-    /**
395
-     * @param EE_Registration   $registration
396
-     * @param EE_Question_Group $question_group
397
-     * @return EE_Form_Section_Proper
398
-     * @throws EE_Error
399
-     * @throws InvalidArgumentException
400
-     * @throws InvalidDataTypeException
401
-     * @throws InvalidInterfaceException
402
-     * @throws ReflectionException
403
-     */
404
-    private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group)
405
-    {
406
-        // array of params to pass to parent constructor
407
-        $form_args = [
408
-            'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(),
409
-            'html_class'      => $this->checkout->admin_request
410
-                ? 'form-table ee-reg-form-qstn-grp-dv'
411
-                : 'ee-reg-form-qstn-grp-dv',
412
-            'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-'
413
-                                 . $registration->ID() . '-lbl',
414
-            'subsections'     => [
415
-                'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
416
-            ],
417
-            'layout_strategy' => $this->checkout->admin_request
418
-                ? new EE_Admin_Two_Column_Layout()
419
-                : new EE_Div_Per_Section_Layout(),
420
-        ];
421
-        // where params
422
-        $query_params = ['QST_deleted' => 0];
423
-        // don't load admin only questions on the frontend
424
-        if (! $this->checkout->admin_request) {
425
-            $query_params['QST_admin_only'] = ['!=', true];
426
-        }
427
-        $questions = $question_group->get_many_related(
428
-            'Question',
429
-            apply_filters(
430
-                'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params',
431
-                [
432
-                    $query_params,
433
-                    'order_by' => [
434
-                        'Question_Group_Question.QGQ_order' => 'ASC',
435
-                    ],
436
-                ],
437
-                $question_group,
438
-                $registration,
439
-                $this
440
-            )
441
-        );
442
-        // filter for additional content before questions
443
-        $form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML(
444
-            apply_filters(
445
-                'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions',
446
-                '',
447
-                $registration,
448
-                $question_group,
449
-                $this
450
-            )
451
-        );
452
-        // loop thru questions
453
-        foreach ($questions as $question) {
454
-            if ($question instanceof EE_Question) {
455
-                $identifier                              = $question->is_system_question()
456
-                    ? $question->system_ID()
457
-                    : $question->ID();
458
-                $form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question);
459
-            }
460
-        }
461
-        $form_args['subsections'] = apply_filters(
462
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array',
463
-            $form_args['subsections'],
464
-            $registration,
465
-            $question_group,
466
-            $this
467
-        );
468
-        // filter for additional content after questions
469
-        $form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML(
470
-            apply_filters(
471
-                'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions',
472
-                '',
473
-                $registration,
474
-                $question_group,
475
-                $this
476
-            )
477
-        );
478
-        // d($form_args);
479
-        $question_group_reg_form = new EE_Form_Section_Proper($form_args);
480
-        return apply_filters(
481
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
482
-            $question_group_reg_form,
483
-            $registration,
484
-            $question_group,
485
-            $this
486
-        );
487
-    }
488
-
489
-
490
-    /**
491
-     * @param EE_Question_Group $question_group
492
-     * @return    EE_Form_Section_HTML
493
-     */
494
-    private function _question_group_header(EE_Question_Group $question_group)
495
-    {
496
-        $html = '';
497
-        // group_name
498
-        if ($question_group->show_group_name() && $question_group->name() !== '') {
499
-            if ($this->checkout->admin_request) {
500
-                $html .= EEH_HTML::br();
501
-                $html .= EEH_HTML::h3(
502
-                    $question_group->name(),
503
-                    '',
504
-                    'ee-reg-form-qstn-grp-title title',
505
-                    'font-size: 1.3em; padding-left:0;'
506
-                );
507
-            } else {
508
-                $html .= EEH_HTML::h4(
509
-                    $question_group->name(),
510
-                    '',
511
-                    'ee-reg-form-qstn-grp-title section-title'
512
-                );
513
-            }
514
-        }
515
-        // group_desc
516
-        if ($question_group->show_group_desc() && $question_group->desc() !== '') {
517
-            $html .= EEH_HTML::p(
518
-                $question_group->desc(),
519
-                '',
520
-                $this->checkout->admin_request
521
-                    ? 'ee-reg-form-qstn-grp-desc-pg'
522
-                    : 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text'
523
-            );
524
-        }
525
-        return new EE_Form_Section_HTML($html);
526
-    }
527
-
528
-
529
-    /**
530
-     * @return    EE_Form_Section_Proper
531
-     * @throws EE_Error
532
-     * @throws InvalidArgumentException
533
-     * @throws ReflectionException
534
-     * @throws InvalidDataTypeException
535
-     * @throws InvalidInterfaceException
536
-     */
537
-    private function _copy_attendee_info_form()
538
-    {
539
-        // array of params to pass to parent constructor
540
-        return new EE_Form_Section_Proper(
541
-            [
542
-                'subsections'     => $this->_copy_attendee_info_inputs(),
543
-                'layout_strategy' => new EE_Template_Layout(
544
-                    [
545
-                        'layout_template_file'     => SPCO_REG_STEPS_PATH
546
-                                                      . $this->_slug
547
-                                                      . '/copy_attendee_info.template.php',
548
-                        'begin_template_file'      => null,
549
-                        'input_template_file'      => null,
550
-                        'subsection_template_file' => null,
551
-                        'end_template_file'        => null,
552
-                    ]
553
-                ),
554
-            ]
555
-        );
556
-    }
557
-
558
-
559
-    /**
560
-     * @return EE_Form_Section_HTML
561
-     * @throws DomainException
562
-     * @throws InvalidArgumentException
563
-     * @throws InvalidDataTypeException
564
-     * @throws InvalidInterfaceException
565
-     */
566
-    private function _auto_copy_attendee_info()
567
-    {
568
-        return new EE_Form_Section_HTML(
569
-            EEH_Template::locate_template(
570
-                SPCO_REG_STEPS_PATH . $this->_slug . '/_auto_copy_attendee_info.template.php',
571
-                apply_filters(
572
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
573
-                    []
574
-                )
575
-            )
576
-        );
577
-    }
578
-
579
-
580
-    /**
581
-     * @return array
582
-     * @throws EE_Error
583
-     * @throws InvalidArgumentException
584
-     * @throws ReflectionException
585
-     * @throws InvalidDataTypeException
586
-     * @throws InvalidInterfaceException
587
-     */
588
-    private function _copy_attendee_info_inputs()
589
-    {
590
-        $copy_attendee_info_inputs = [];
591
-        $prev_ticket               = null;
592
-        // grab the saved registrations from the transaction
593
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
594
-        foreach ($registrations as $registration) {
595
-            // for all  attendees other than the primary attendee
596
-            if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
597
-                // if this is a new ticket OR if this is the very first additional attendee after the primary attendee
598
-                if ($registration->ticket()->ID() !== $prev_ticket) {
599
-                    $item_name                          = $registration->ticket()->name();
600
-                    $item_name                          .= $registration->ticket()->description() !== ''
601
-                        ? ' - ' . $registration->ticket()->description()
602
-                        : '';
603
-                    $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-'
604
-                                                . $registration->ticket()->ID()
605
-                                                . ']' ] =
606
-                        new EE_Form_Section_HTML(
607
-                            '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
608
-                        );
609
-                    $prev_ticket                        = $registration->ticket()->ID();
610
-                }
611
-
612
-                $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] =
613
-                    new EE_Checkbox_Multi_Input(
614
-                        [
615
-                            $registration->ID() => sprintf(
616
-                                esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'),
617
-                                $registration->count()
618
-                            ),
619
-                        ],
620
-                        [
621
-                            'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
622
-                            'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
623
-                            'display_html_label_text' => false,
624
-                        ]
625
-                    );
626
-            }
627
-        }
628
-        return $copy_attendee_info_inputs;
629
-    }
630
-
631
-
632
-    /**
633
-     * @param EE_Registration $registration
634
-     * @return    EE_Form_Input_Base
635
-     * @throws EE_Error
636
-     */
637
-    private function _additional_primary_registrant_inputs(EE_Registration $registration)
638
-    {
639
-        // generate hidden input
640
-        return new EE_Hidden_Input(
641
-            [
642
-                'html_id' => 'primary_registrant',
643
-                'default' => $registration->reg_url_link(),
644
-            ]
645
-        );
646
-    }
647
-
648
-
649
-    /**
650
-     * @param EE_Registration $registration
651
-     * @param EE_Question     $question
652
-     * @return EE_Form_Input_Base
653
-     * @throws EE_Error
654
-     * @throws InvalidArgumentException
655
-     * @throws InvalidDataTypeException
656
-     * @throws InvalidInterfaceException
657
-     * @throws ReflectionException
658
-     */
659
-    public function reg_form_question(EE_Registration $registration, EE_Question $question)
660
-    {
661
-
662
-        // if this question was for an attendee detail, then check for that answer
663
-        $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value(
664
-            $registration,
665
-            $question->system_ID()
666
-        );
667
-        $answer       = $answer_value === null
668
-            ? EEM_Answer::instance()->get_one(
669
-                [['QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()]]
670
-            )
671
-            : null;
672
-        // if NOT returning to edit an existing registration
673
-        // OR if this question is for an attendee property
674
-        // OR we still don't have an EE_Answer object
675
-        if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) {
676
-            // create an EE_Answer object for storing everything in
677
-            $answer = EE_Answer::new_instance(
678
-                [
679
-                    'QST_ID' => $question->ID(),
680
-                    'REG_ID' => $registration->ID(),
681
-                ]
682
-            );
683
-        }
684
-        // verify instance
685
-        if ($answer instanceof EE_Answer) {
686
-            if (! empty($answer_value)) {
687
-                $answer->set('ANS_value', $answer_value);
688
-            }
689
-            $answer->cache('Question', $question);
690
-            // remember system ID had a bug where sometimes it could be null
691
-            $answer_cache_id = $question->is_system_question()
692
-                ? $question->system_ID() . '-' . $registration->reg_url_link()
693
-                : $question->ID() . '-' . $registration->reg_url_link();
694
-            $registration->cache('Answer', $answer, $answer_cache_id);
695
-        }
696
-        return $this->_generate_question_input($registration, $question, $answer);
697
-    }
698
-
699
-
700
-    /**
701
-     * @param EE_Registration $registration
702
-     * @param EE_Question     $question
703
-     * @param                 $answer
704
-     * @return EE_Form_Input_Base
705
-     * @throws EE_Error
706
-     * @throws InvalidArgumentException
707
-     * @throws ReflectionException
708
-     * @throws InvalidDataTypeException
709
-     * @throws InvalidInterfaceException
710
-     */
711
-    private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer)
712
-    {
713
-        $identifier                               = $question->is_system_question()
714
-            ? $question->system_ID()
715
-            : $question->ID();
716
-        $this->_required_questions[ $identifier ] = $question->required();
717
-        add_filter(
718
-            'FHEE__EE_Question__generate_form_input__country_options',
719
-            [$this, 'use_cached_countries_for_form_input'],
720
-            10,
721
-            4
722
-        );
723
-        add_filter(
724
-            'FHEE__EE_Question__generate_form_input__state_options',
725
-            [$this, 'use_cached_states_for_form_input'],
726
-            10,
727
-            4
728
-        );
729
-        $input_constructor_args                  = [
730
-            'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
731
-            'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
732
-            'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
733
-            'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
734
-            'html_label_class' => 'ee-reg-qstn',
735
-        ];
736
-        $input_constructor_args['html_label_id'] .= '-lbl';
737
-        if ($answer instanceof EE_Answer && $answer->ID()) {
738
-            $input_constructor_args['html_name']     .= '[' . $answer->ID() . ']';
739
-            $input_constructor_args['html_id']       .= '-' . $answer->ID();
740
-            $input_constructor_args['html_label_id'] .= '-' . $answer->ID();
741
-        }
742
-        $form_input = $question->generate_form_input(
743
-            $registration,
744
-            $answer,
745
-            $input_constructor_args
746
-        );
747
-        remove_filter(
748
-            'FHEE__EE_Question__generate_form_input__country_options',
749
-            [$this, 'use_cached_countries_for_form_input']
750
-        );
751
-        remove_filter(
752
-            'FHEE__EE_Question__generate_form_input__state_options',
753
-            [$this, 'use_cached_states_for_form_input']
754
-        );
755
-        return $form_input;
756
-    }
757
-
758
-
759
-    /**
760
-     * Gets the list of countries for the form input
761
-     *
762
-     * @param array|null      $countries_list
763
-     * @param EE_Question     $question
764
-     * @param EE_Registration $registration
765
-     * @param EE_Answer       $answer
766
-     * @return array 2d keys are country IDs, values are their names
767
-     * @throws EE_Error
768
-     * @throws InvalidArgumentException
769
-     * @throws InvalidDataTypeException
770
-     * @throws InvalidInterfaceException
771
-     * @throws ReflectionException
772
-     */
773
-    public function use_cached_countries_for_form_input(
774
-        $countries_list,
775
-        EE_Question $question = null,
776
-        EE_Registration $registration = null,
777
-        EE_Answer $answer = null
778
-    ) {
779
-        $country_options = ['' => ''];
780
-        // get possibly cached list of countries
781
-        $countries = $this->checkout->action === 'process_reg_step'
782
-            ? EEM_Country::instance()->get_all_countries()
783
-            : EEM_Country::instance()->get_all_active_countries();
784
-        if (! empty($countries)) {
785
-            foreach ($countries as $country) {
786
-                if ($country instanceof EE_Country) {
787
-                    $country_options[ $country->ID() ] = $country->name();
788
-                }
789
-            }
790
-        }
791
-        if ($question instanceof EE_Question && $registration instanceof EE_Registration) {
792
-            $answer = EEM_Answer::instance()->get_one(
793
-                [['QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()]]
794
-            );
795
-        } else {
796
-            $answer = EE_Answer::new_instance();
797
-        }
798
-        return apply_filters(
799
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
800
-            $country_options,
801
-            $this,
802
-            $registration,
803
-            $question,
804
-            $answer
805
-        );
806
-    }
807
-
808
-
809
-    /**
810
-     * Gets the list of states for the form input
811
-     *
812
-     * @param array|null      $states_list
813
-     * @param EE_Question     $question
814
-     * @param EE_Registration $registration
815
-     * @param EE_Answer       $answer
816
-     * @return array 2d keys are state IDs, values are their names
817
-     * @throws EE_Error
818
-     * @throws InvalidArgumentException
819
-     * @throws InvalidDataTypeException
820
-     * @throws InvalidInterfaceException
821
-     * @throws ReflectionException
822
-     */
823
-    public function use_cached_states_for_form_input(
824
-        $states_list,
825
-        EE_Question $question = null,
826
-        EE_Registration $registration = null,
827
-        EE_Answer $answer = null
828
-    ) {
829
-        $state_options = ['' => ['' => '']];
830
-        $states        = $this->checkout->action === 'process_reg_step'
831
-            ? EEM_State::instance()->get_all_states()
832
-            : EEM_State::instance()->get_all_active_states();
833
-        if (! empty($states)) {
834
-            foreach ($states as $state) {
835
-                if ($state instanceof EE_State) {
836
-                    $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
837
-                }
838
-            }
839
-        }
840
-        return apply_filters(
841
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
842
-            $state_options,
843
-            $this,
844
-            $registration,
845
-            $question,
846
-            $answer
847
-        );
848
-    }
849
-
850
-
851
-    /********************************************************************************************************/
852
-    /****************************************  PROCESS REG STEP  ****************************************/
853
-    /********************************************************************************************************/
854
-
855
-
856
-    /**
857
-     * @return bool
858
-     * @throws EE_Error
859
-     * @throws InvalidArgumentException
860
-     * @throws ReflectionException
861
-     * @throws RuntimeException
862
-     * @throws InvalidDataTypeException
863
-     * @throws InvalidInterfaceException
864
-     */
865
-    public function process_reg_step()
866
-    {
867
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
868
-        // grab validated data from form
869
-        $valid_data = $this->checkout->current_step->valid_data();
870
-        // if we don't have any $valid_data then something went TERRIBLY WRONG !!!
871
-        if (empty($valid_data)) {
872
-            EE_Error::add_error(
873
-                esc_html__('No valid question responses were received.', 'event_espresso'),
874
-                __FILE__,
875
-                __FUNCTION__,
876
-                __LINE__
877
-            );
878
-            return false;
879
-        }
880
-        if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
881
-            EE_Error::add_error(
882
-                esc_html__(
883
-                    'A valid transaction could not be initiated for processing your registrations.',
884
-                    'event_espresso'
885
-                ),
886
-                __FILE__,
887
-                __FUNCTION__,
888
-                __LINE__
889
-            );
890
-            return false;
891
-        }
892
-        // get cached registrations
893
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
894
-        // verify we got the goods
895
-        if (empty($registrations)) {
896
-            // combine the old translated string with a new one, in order to not break translations
897
-            $error_message = esc_html__(
898
-                'Your form data could not be applied to any valid registrations.',
899
-                'event_espresso'
900
-            )
901
-            . sprintf(
902
-                esc_html_x(
903
-                    '%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.',
904
-                    '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.',
905
-                    'event_espresso'
906
-                ),
907
-                '<a href="' . get_post_type_archive_link('espresso_events') . '" >',
908
-                '</a>',
909
-                '<br />'
910
-            );
911
-            EE_Error::add_error(
912
-                $error_message,
913
-                __FILE__,
914
-                __FUNCTION__,
915
-                __LINE__
916
-            );
917
-            return false;
918
-        }
919
-        // extract attendee info from form data and save to model objects
920
-        $registrations_processed = $this->_process_registrations($registrations, $valid_data);
921
-        // if first pass thru SPCO,
922
-        // then let's check processed registrations against the total number of tickets in the cart
923
-        if ($registrations_processed === false) {
924
-            // but return immediately if the previous step exited early due to errors
925
-            return false;
926
-        }
927
-        if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
928
-            // generate a correctly translated string for all possible singular/plural combinations
929
-            if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
930
-                $error_msg = sprintf(
931
-                    esc_html_x(
932
-                        'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed',
933
-                        'There was 1 ticket in the Event Queue, but 2 registrations were processed',
934
-                        'event_espresso'
935
-                    ),
936
-                    $this->checkout->total_ticket_count,
937
-                    $registrations_processed
938
-                );
939
-            } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) {
940
-                $error_msg = sprintf(
941
-                    esc_html_x(
942
-                        'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed',
943
-                        'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed',
944
-                        'event_espresso'
945
-                    ),
946
-                    $this->checkout->total_ticket_count,
947
-                    $registrations_processed
948
-                );
949
-            } else {
950
-                $error_msg = sprintf(
951
-                    esc_html__(
952
-                        'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed',
953
-                        'event_espresso'
954
-                    ),
955
-                    $this->checkout->total_ticket_count,
956
-                    $registrations_processed
957
-                );
958
-            }
959
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
960
-            return false;
961
-        }
962
-        // mark this reg step as completed
963
-        $this->set_completed();
964
-        $this->_set_success_message(
965
-            esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso')
966
-        );
967
-        // do action in case a plugin wants to do something with the data submitted in step 1.
968
-        // passes EE_Single_Page_Checkout, and it's posted data
969
-        do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data);
970
-        return true;
971
-    }
972
-
973
-
974
-    /**
975
-     *    _process_registrations
976
-     *
977
-     * @param EE_Registration[] $registrations
978
-     * @param array[][]         $valid_data
979
-     * @return bool|int
980
-     * @throws EntityNotFoundException
981
-     * @throws EE_Error
982
-     * @throws InvalidArgumentException
983
-     * @throws ReflectionException
984
-     * @throws RuntimeException
985
-     * @throws InvalidDataTypeException
986
-     * @throws InvalidInterfaceException
987
-     */
988
-    private function _process_registrations($registrations = [], $valid_data = [])
989
-    {
990
-        // load resources and set some defaults
991
-        EE_Registry::instance()->load_model('Attendee');
992
-        // holder for primary registrant attendee object
993
-        $this->checkout->primary_attendee_obj = null;
994
-        // array for tracking reg form data for the primary registrant
995
-        $primary_registrant = [
996
-            'line_item_id' => null,
997
-        ];
998
-        $copy_primary       = false;
999
-        // reg form sections that do not contain inputs
1000
-        $non_input_form_sections = [
1001
-            'primary_registrant',
1002
-            'additional_attendee_reg_info',
1003
-            'spco_copy_attendee_chk',
1004
-        ];
1005
-        // attendee counter
1006
-        $att_nmbr = 0;
1007
-        // grab the saved registrations from the transaction
1008
-        foreach ($registrations as $registration) {
1009
-            // verify EE_Registration object
1010
-            if (! $registration instanceof EE_Registration) {
1011
-                EE_Error::add_error(
1012
-                    esc_html__(
1013
-                        'An invalid Registration object was discovered when attempting to process your registration information.',
1014
-                        'event_espresso'
1015
-                    ),
1016
-                    __FILE__,
1017
-                    __FUNCTION__,
1018
-                    __LINE__
1019
-                );
1020
-                return false;
1021
-            }
1022
-            $reg_url_link = $registration->reg_url_link();
1023
-            // reg_url_link exists ?
1024
-            if (! empty($reg_url_link)) {
1025
-                // should this registration be processed during this visit ?
1026
-                if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
1027
-                    // if NOT revisiting, then let's save the registration now,
1028
-                    // so that we have a REG_ID to use when generating other objects
1029
-                    if (! $this->checkout->revisit) {
1030
-                        $registration->save();
1031
-                    }
1032
-                    /**
1033
-                     * This allows plugins to trigger a fail on processing of a
1034
-                     * registration for any conditions they may have for it to pass.
1035
-                     *
1036
-                     * @var bool   if true is returned by the plugin then the
1037
-                     *            registration processing is halted.
1038
-                     */
1039
-                    if (
1040
-                        apply_filters(
1041
-                            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
1042
-                            false,
1043
-                            $att_nmbr,
1044
-                            $registration,
1045
-                            $registrations,
1046
-                            $valid_data,
1047
-                            $this
1048
-                        )
1049
-                    ) {
1050
-                        return false;
1051
-                    }
1052
-
1053
-                    // Houston, we have a registration!
1054
-                    $att_nmbr++;
1055
-                    $this->_attendee_data[ $reg_url_link ] = [];
1056
-                    // grab any existing related answer objects
1057
-                    $this->_registration_answers = $registration->answers();
1058
-                    // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
1059
-                    if (isset($valid_data[ $reg_url_link ])) {
1060
-                        // do we need to copy basic info from primary attendee ?
1061
-                        $copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info'])
1062
-                                        && absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
1063
-                        // filter form input data for this registration
1064
-                        $valid_data[ $reg_url_link ] = (array) apply_filters(
1065
-                            'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
1066
-                            $valid_data[ $reg_url_link ]
1067
-                        );
1068
-                        if (isset($valid_data['primary_attendee'])) {
1069
-                            $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
1070
-                                ? $valid_data['primary_attendee']
1071
-                                : false;
1072
-                            unset($valid_data['primary_attendee']);
1073
-                        }
1074
-                        // now loop through our array of valid post data && process attendee reg forms
1075
-                        foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) {
1076
-                            if (! in_array($form_section, $non_input_form_sections, true)) {
1077
-                                foreach ($form_inputs as $form_input => $input_value) {
1078
-                                    // check for critical inputs
1079
-                                    if (
1080
-                                        ! $this->_verify_critical_attendee_details_are_set_and_validate_email(
1081
-                                            $form_input,
1082
-                                            $input_value
1083
-                                        )
1084
-                                    ) {
1085
-                                        return false;
1086
-                                    }
1087
-                                    // store a bit of data about the primary attendee
1088
-                                    if (
1089
-                                        $att_nmbr === 1
1090
-                                        && ! empty($input_value)
1091
-                                        && $reg_url_link === $primary_registrant['line_item_id']
1092
-                                    ) {
1093
-                                        $primary_registrant[ $form_input ] = $input_value;
1094
-                                    } elseif (
1095
-                                        $copy_primary
1096
-                                              && $input_value === null
1097
-                                              && isset($primary_registrant[ $form_input ])
1098
-                                    ) {
1099
-                                        $input_value = $primary_registrant[ $form_input ];
1100
-                                    }
1101
-                                    // now attempt to save the input data
1102
-                                    if (
1103
-                                        ! $this->_save_registration_form_input(
1104
-                                            $registration,
1105
-                                            $form_input,
1106
-                                            $input_value
1107
-                                        )
1108
-                                    ) {
1109
-                                        EE_Error::add_error(
1110
-                                            sprintf(
1111
-                                                esc_html_x(
1112
-                                                    'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
1113
-                                                    'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"',
1114
-                                                    'event_espresso'
1115
-                                                ),
1116
-                                                $form_input,
1117
-                                                $input_value
1118
-                                            ),
1119
-                                            __FILE__,
1120
-                                            __FUNCTION__,
1121
-                                            __LINE__
1122
-                                        );
1123
-                                        return false;
1124
-                                    }
1125
-                                }
1126
-                            }
1127
-                        }  // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs )
1128
-                    }
1129
-                    // this registration does not require additional attendee information ?
1130
-                    if (
1131
-                        $copy_primary
1132
-                        && $att_nmbr > 1
1133
-                        && $this->checkout->primary_attendee_obj instanceof EE_Attendee
1134
-                    ) {
1135
-                        // just copy the primary registrant
1136
-                        $attendee = $this->checkout->primary_attendee_obj;
1137
-                    } else {
1138
-                        // ensure critical details are set for additional attendees
1139
-                        $this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1
1140
-                            ? $this->_copy_critical_attendee_details_from_primary_registrant(
1141
-                                $this->_attendee_data[ $reg_url_link ]
1142
-                            )
1143
-                            : $this->_attendee_data[ $reg_url_link ];
1144
-                        // execute create attendee command (which may return an existing attendee)
1145
-                        $attendee = EE_Registry::instance()->BUS->execute(
1146
-                            new CreateAttendeeCommand(
1147
-                                $this->_attendee_data[ $reg_url_link ],
1148
-                                $registration
1149
-                            )
1150
-                        );
1151
-                        // who's #1 ?
1152
-                        if ($att_nmbr === 1) {
1153
-                            $this->checkout->primary_attendee_obj = $attendee;
1154
-                        }
1155
-                    }
1156
-                    // add relation to registration, set attendee ID, and cache attendee
1157
-                    $this->_associate_attendee_with_registration($registration, $attendee);
1158
-                    if (! $registration->attendee() instanceof EE_Attendee) {
1159
-                        EE_Error::add_error(
1160
-                            sprintf(
1161
-                                esc_html_x(
1162
-                                    'Registration %s has an invalid or missing Attendee object.',
1163
-                                    'Registration 123-456-789 has an invalid or missing Attendee object.',
1164
-                                    'event_espresso'
1165
-                                ),
1166
-                                $reg_url_link
1167
-                            ),
1168
-                            __FILE__,
1169
-                            __FUNCTION__,
1170
-                            __LINE__
1171
-                        );
1172
-                        return false;
1173
-                    }
1174
-                    /** @type EE_Registration_Processor $registration_processor */
1175
-                    $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1176
-                    // at this point, we should have enough details about the registrant to consider the registration
1177
-                    // NOT incomplete
1178
-                    $registration_processor->toggle_incomplete_registration_status_to_default(
1179
-                        $registration,
1180
-                        false,
1181
-                        new Context(
1182
-                            'spco_reg_step_attendee_information_process_registrations',
1183
-                            esc_html__(
1184
-                                'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
1185
-                                'event_espresso'
1186
-                            )
1187
-                        )
1188
-                    );
1189
-                    // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
1190
-                    // abandoned
1191
-                    $this->checkout->transaction->toggle_failed_transaction_status();
1192
-                    // if we've gotten this far, then let's save what we have
1193
-                    $registration->save();
1194
-                    // add relation between TXN and registration
1195
-                    $this->_associate_registration_with_transaction($registration);
1196
-                }
1197
-            } else {
1198
-                EE_Error::add_error(
1199
-                    esc_html__(
1200
-                        'An invalid or missing line item ID was encountered while attempting to process the registration form.',
1201
-                        'event_espresso'
1202
-                    ),
1203
-                    __FILE__,
1204
-                    __FUNCTION__,
1205
-                    __LINE__
1206
-                );
1207
-                // remove malformed data
1208
-                unset($valid_data[ $reg_url_link ]);
1209
-                return false;
1210
-            }
1211
-        } // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
1212
-        return $att_nmbr;
1213
-    }
1214
-
1215
-
1216
-    /**
1217
-     *    _save_registration_form_input
1218
-     *
1219
-     * @param EE_Registration $registration
1220
-     * @param string          $form_input
1221
-     * @param string          $input_value
1222
-     * @return bool
1223
-     * @throws EE_Error
1224
-     * @throws InvalidArgumentException
1225
-     * @throws InvalidDataTypeException
1226
-     * @throws InvalidInterfaceException
1227
-     * @throws ReflectionException
1228
-     */
1229
-    private function _save_registration_form_input(
1230
-        EE_Registration $registration,
1231
-        $form_input = '',
1232
-        $input_value = ''
1233
-    ) {
1234
-        // If email_confirm is sent it's not saved
1235
-        if ((string) $form_input === 'email_confirm') {
1236
-            return true;
1237
-        }
1238
-
1239
-        // allow for plugins to hook in and do their own processing of the form input.
1240
-        // For plugins to bypass normal processing here, they just need to return a boolean value.
1241
-        if (
1242
-            apply_filters(
1243
-                'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
1244
-                false,
1245
-                $registration,
1246
-                $form_input,
1247
-                $input_value,
1248
-                $this
1249
-            )
1250
-        ) {
1251
-            return true;
1252
-        }
1253
-        /*
20
+	/**
21
+	 * @type bool $_print_copy_info
22
+	 */
23
+	private $_print_copy_info = false;
24
+
25
+	/**
26
+	 * @type array $_attendee_data
27
+	 */
28
+	private $_attendee_data = [];
29
+
30
+	/**
31
+	 * @type array $_required_questions
32
+	 */
33
+	private $_required_questions = [];
34
+
35
+	/**
36
+	 * @type array $_registration_answers
37
+	 */
38
+	private $_registration_answers = [];
39
+
40
+	/**
41
+	 * @type int $reg_form_count
42
+	 */
43
+	protected $reg_form_count = 0;
44
+
45
+
46
+	/**
47
+	 *    class constructor
48
+	 *
49
+	 * @access    public
50
+	 * @param EE_Checkout $checkout
51
+	 */
52
+	public function __construct(EE_Checkout $checkout)
53
+	{
54
+		$this->request  = EED_Single_Page_Checkout::getRequest();
55
+		$this->_slug    = 'attendee_information';
56
+		$this->_name    = esc_html__('Attendee Information', 'event_espresso');
57
+		$this->checkout = $checkout;
58
+		$this->_reset_success_message();
59
+		$this->set_instructions(
60
+			esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso')
61
+		);
62
+	}
63
+
64
+
65
+	public function translate_js_strings()
66
+	{
67
+		EE_Registry::$i18n_js_strings['required_field']            = esc_html__(
68
+			' is a required question.',
69
+			'event_espresso'
70
+		);
71
+		EE_Registry::$i18n_js_strings['required_multi_field']      = esc_html__(
72
+			' is a required question. Please enter a value for at least one of the options.',
73
+			'event_espresso'
74
+		);
75
+		EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__(
76
+			'Please answer all required questions correctly before proceeding.',
77
+			'event_espresso'
78
+		);
79
+		EE_Registry::$i18n_js_strings['attendee_info_copied']      = sprintf(
80
+			esc_html_x(
81
+				'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.',
82
+				'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.',
83
+				'event_espresso'
84
+			),
85
+			'<br/>'
86
+		);
87
+		EE_Registry::$i18n_js_strings['attendee_info_copy_error']  = esc_html__(
88
+			'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.',
89
+			'event_espresso'
90
+		);
91
+		EE_Registry::$i18n_js_strings['enter_valid_email']         = esc_html__(
92
+			'You must enter a valid email address.',
93
+			'event_espresso'
94
+		);
95
+		EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__(
96
+			'You must enter a valid email address and answer all other required questions before you can proceed.',
97
+			'event_espresso'
98
+		);
99
+	}
100
+
101
+
102
+	public function enqueue_styles_and_scripts()
103
+	{
104
+	}
105
+
106
+
107
+	/**
108
+	 * @return boolean
109
+	 */
110
+	public function initialize_reg_step()
111
+	{
112
+		return true;
113
+	}
114
+
115
+
116
+	/**
117
+	 * @return EE_Form_Section_Proper
118
+	 * @throws DomainException
119
+	 * @throws EE_Error
120
+	 * @throws InvalidArgumentException
121
+	 * @throws ReflectionException
122
+	 * @throws EntityNotFoundException
123
+	 * @throws InvalidDataTypeException
124
+	 * @throws InvalidInterfaceException
125
+	 */
126
+	public function generate_reg_form()
127
+	{
128
+		/**
129
+		 * @var $reg_config EE_Registration_Config
130
+		 */
131
+		$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
132
+
133
+		$this->_print_copy_info = $reg_config->copyAttendeeInfo();
134
+
135
+		// Init reg forms count.
136
+		$this->reg_form_count = 0;
137
+
138
+		$primary_registrant = null;
139
+		// autoload Line_Item_Display classes
140
+		EEH_Autoloader::register_line_item_display_autoloaders();
141
+		$Line_Item_Display = new EE_Line_Item_Display();
142
+		// calculate taxes
143
+		$Line_Item_Display->display_line_item(
144
+			$this->checkout->cart->get_grand_total(),
145
+			['set_tax_rate' => true]
146
+		);
147
+		/** @var $subsections EE_Form_Section_Proper[] */
148
+		$extra_inputs_section = $this->reg_step_hidden_inputs();
149
+		$subsections          = [
150
+			'default_hidden_inputs' => $extra_inputs_section,
151
+		];
152
+
153
+		// if this isn't a revisit, and they have the privacy consent box enabled, add it
154
+		if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
155
+			$extra_inputs_section->add_subsections(
156
+				[
157
+					'consent_box' => new EE_Form_Section_Proper(
158
+						[
159
+							'layout_strategy' =>
160
+								new EE_Template_Layout(
161
+									[
162
+										'input_template_file' => SPCO_REG_STEPS_PATH
163
+																 . $this->_slug
164
+																 . '/privacy_consent.template.php',
165
+									]
166
+								),
167
+							'subsections'     => [
168
+								'consent' => new EE_Checkbox_Multi_Input(
169
+									[
170
+										'consent' => $reg_config->getConsentCheckboxLabelText(),
171
+									],
172
+									[
173
+										'required'                          => true,
174
+										'required_validation_error_message' => esc_html__(
175
+											'You must consent to these terms in order to register.',
176
+											'event_espresso'
177
+										),
178
+										'html_label_text'                   => '',
179
+									]
180
+								),
181
+							],
182
+						]
183
+					),
184
+				],
185
+				null,
186
+				false
187
+			);
188
+		}
189
+		$template_args = [
190
+			'revisit'       => $this->checkout->revisit,
191
+			'registrations' => [],
192
+			'ticket_count'  => [],
193
+		];
194
+		// grab the saved registrations from the transaction
195
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
196
+		if ($registrations) {
197
+			foreach ($registrations as $registration) {
198
+				// can this registration be processed during this visit ?
199
+				if (
200
+					$registration instanceof EE_Registration
201
+					&& $this->checkout->visit_allows_processing_of_this_registration($registration)
202
+				) {
203
+					$subsections[ $registration->reg_url_link() ]                       =
204
+						$this->_registrations_reg_form($registration);
205
+					$template_args['registrations'][ $registration->reg_url_link() ]    = $registration;
206
+					$template_args['ticket_count'][ $registration->ticket()->ID() ]     = isset(
207
+						$template_args['ticket_count'][ $registration->ticket()->ID() ]
208
+					)
209
+						? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
210
+						: 1;
211
+					$ticket_line_item                                                   =
212
+						EEH_Line_Item::get_line_items_by_object_type_and_IDs(
213
+							$this->checkout->cart->get_grand_total(),
214
+							'Ticket',
215
+							[$registration->ticket()->ID()]
216
+						);
217
+					$ticket_line_item                                                   = is_array($ticket_line_item)
218
+						? reset($ticket_line_item)
219
+						: $ticket_line_item;
220
+					$template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
221
+						$Line_Item_Display->display_line_item($ticket_line_item);
222
+					if ($registration->is_primary_registrant()) {
223
+						$primary_registrant = $registration->reg_url_link();
224
+					}
225
+				}
226
+			}
227
+
228
+			if ($primary_registrant && count($registrations) > 1) {
229
+				$copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info
230
+					? $this->_copy_attendee_info_form()
231
+					: $this->_auto_copy_attendee_info();
232
+				// generate hidden input
233
+				if (
234
+					isset($subsections[ $primary_registrant ])
235
+					&& $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
236
+				) {
237
+					$subsections[ $primary_registrant ]->add_subsections(
238
+						$copy_options,
239
+						'primary_registrant',
240
+						false
241
+					);
242
+				}
243
+			}
244
+		}
245
+
246
+		// Set the registration form template (default: one form per ticket details table).
247
+		// We decide the template to used based on the number of forms.
248
+		$this->_template = $this->reg_form_count > 1
249
+			? SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_main.template.php'
250
+			: SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_single.template.php';
251
+
252
+		return new EE_Form_Section_Proper(
253
+			[
254
+				'name'            => $this->reg_form_name(),
255
+				'html_id'         => $this->reg_form_name(),
256
+				'subsections'     => $subsections,
257
+				'layout_strategy' => new EE_Template_Layout(
258
+					[
259
+						'layout_template_file' => $this->_template, // layout_template
260
+						'template_args'        => $template_args,
261
+					]
262
+				),
263
+			]
264
+		);
265
+	}
266
+
267
+
268
+	/**
269
+	 * @param EE_Registration $registration
270
+	 * @return EE_Form_Section_Base
271
+	 * @throws EE_Error
272
+	 * @throws InvalidArgumentException
273
+	 * @throws EntityNotFoundException
274
+	 * @throws InvalidDataTypeException
275
+	 * @throws InvalidInterfaceException
276
+	 * @throws ReflectionException
277
+	 */
278
+	private function _registrations_reg_form(EE_Registration $registration)
279
+	{
280
+		static $attendee_nmbr = 1;
281
+		$form_args = [];
282
+		// verify that registration has valid event
283
+		if ($registration->event() instanceof EE_Event) {
284
+			$field_name      = 'Event_Question_Group.'
285
+							   . EEM_Event_Question_Group::instance()->fieldNameForContext(
286
+								   $registration->is_primary_registrant()
287
+							   );
288
+			$question_groups = $registration->event()->question_groups(
289
+				apply_filters(
290
+				// @codingStandardsIgnoreStart
291
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
292
+					// @codingStandardsIgnoreEnd
293
+					[
294
+						[
295
+							'Event.EVT_ID' => $registration->event()->ID(),
296
+							$field_name    => true,
297
+							'QSG_deleted'  => false
298
+						],
299
+						'order_by' => ['QSG_order' => 'ASC'],
300
+					],
301
+					$registration,
302
+					$this
303
+				)
304
+			);
305
+			if ($question_groups) {
306
+				// array of params to pass to parent constructor
307
+				$form_args = [
308
+					'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
309
+					'html_class'      => 'ee-reg-form-attendee-dv',
310
+					'html_style'      => $this->checkout->admin_request
311
+						? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
312
+						: '',
313
+					'subsections'     => [],
314
+					'layout_strategy' => new EE_Fieldset_Section_Layout(
315
+						[
316
+							'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text',
317
+							'legend_text'  => sprintf(
318
+								esc_html_x(
319
+									'Attendee %d',
320
+									'Attendee 123',
321
+									'event_espresso'
322
+								),
323
+								$attendee_nmbr
324
+							),
325
+						]
326
+					),
327
+				];
328
+				foreach ($question_groups as $question_group) {
329
+					if ($question_group instanceof EE_Question_Group) {
330
+						$form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form(
331
+							$registration,
332
+							$question_group
333
+						);
334
+					}
335
+				}
336
+				// add hidden input
337
+				$form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input(
338
+					$registration
339
+				);
340
+
341
+				/**
342
+				 * @var $reg_config EE_Registration_Config
343
+				 */
344
+				$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
345
+
346
+				// If we have question groups for additional attendees, then display the copy options
347
+				$this->_print_copy_info = apply_filters(
348
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form___printCopyInfo',
349
+					$attendee_nmbr > 1 && $reg_config->copyAttendeeInfo(),
350
+					$attendee_nmbr
351
+				);
352
+
353
+				if ($registration->is_primary_registrant()) {
354
+					// generate hidden input
355
+					$form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs(
356
+						$registration
357
+					);
358
+				}
359
+			}
360
+		}
361
+		$attendee_nmbr++;
362
+
363
+		// Increment the reg forms number if form is valid.
364
+		if (! empty($form_args)) {
365
+			$this->reg_form_count++;
366
+		}
367
+
368
+		return ! empty($form_args)
369
+			? new EE_Form_Section_Proper($form_args)
370
+			: new EE_Form_Section_HTML();
371
+	}
372
+
373
+
374
+	/**
375
+	 * @param EE_Registration $registration
376
+	 * @param bool            $additional_attendee_reg_info
377
+	 * @return EE_Form_Input_Base
378
+	 * @throws EE_Error
379
+	 */
380
+	private function _additional_attendee_reg_info_input(
381
+		EE_Registration $registration,
382
+		$additional_attendee_reg_info = true
383
+	) {
384
+		// generate hidden input
385
+		return new EE_Hidden_Input(
386
+			[
387
+				'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
388
+				'default' => $additional_attendee_reg_info,
389
+			]
390
+		);
391
+	}
392
+
393
+
394
+	/**
395
+	 * @param EE_Registration   $registration
396
+	 * @param EE_Question_Group $question_group
397
+	 * @return EE_Form_Section_Proper
398
+	 * @throws EE_Error
399
+	 * @throws InvalidArgumentException
400
+	 * @throws InvalidDataTypeException
401
+	 * @throws InvalidInterfaceException
402
+	 * @throws ReflectionException
403
+	 */
404
+	private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group)
405
+	{
406
+		// array of params to pass to parent constructor
407
+		$form_args = [
408
+			'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(),
409
+			'html_class'      => $this->checkout->admin_request
410
+				? 'form-table ee-reg-form-qstn-grp-dv'
411
+				: 'ee-reg-form-qstn-grp-dv',
412
+			'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-'
413
+								 . $registration->ID() . '-lbl',
414
+			'subsections'     => [
415
+				'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
416
+			],
417
+			'layout_strategy' => $this->checkout->admin_request
418
+				? new EE_Admin_Two_Column_Layout()
419
+				: new EE_Div_Per_Section_Layout(),
420
+		];
421
+		// where params
422
+		$query_params = ['QST_deleted' => 0];
423
+		// don't load admin only questions on the frontend
424
+		if (! $this->checkout->admin_request) {
425
+			$query_params['QST_admin_only'] = ['!=', true];
426
+		}
427
+		$questions = $question_group->get_many_related(
428
+			'Question',
429
+			apply_filters(
430
+				'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params',
431
+				[
432
+					$query_params,
433
+					'order_by' => [
434
+						'Question_Group_Question.QGQ_order' => 'ASC',
435
+					],
436
+				],
437
+				$question_group,
438
+				$registration,
439
+				$this
440
+			)
441
+		);
442
+		// filter for additional content before questions
443
+		$form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML(
444
+			apply_filters(
445
+				'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions',
446
+				'',
447
+				$registration,
448
+				$question_group,
449
+				$this
450
+			)
451
+		);
452
+		// loop thru questions
453
+		foreach ($questions as $question) {
454
+			if ($question instanceof EE_Question) {
455
+				$identifier                              = $question->is_system_question()
456
+					? $question->system_ID()
457
+					: $question->ID();
458
+				$form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question);
459
+			}
460
+		}
461
+		$form_args['subsections'] = apply_filters(
462
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array',
463
+			$form_args['subsections'],
464
+			$registration,
465
+			$question_group,
466
+			$this
467
+		);
468
+		// filter for additional content after questions
469
+		$form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML(
470
+			apply_filters(
471
+				'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions',
472
+				'',
473
+				$registration,
474
+				$question_group,
475
+				$this
476
+			)
477
+		);
478
+		// d($form_args);
479
+		$question_group_reg_form = new EE_Form_Section_Proper($form_args);
480
+		return apply_filters(
481
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
482
+			$question_group_reg_form,
483
+			$registration,
484
+			$question_group,
485
+			$this
486
+		);
487
+	}
488
+
489
+
490
+	/**
491
+	 * @param EE_Question_Group $question_group
492
+	 * @return    EE_Form_Section_HTML
493
+	 */
494
+	private function _question_group_header(EE_Question_Group $question_group)
495
+	{
496
+		$html = '';
497
+		// group_name
498
+		if ($question_group->show_group_name() && $question_group->name() !== '') {
499
+			if ($this->checkout->admin_request) {
500
+				$html .= EEH_HTML::br();
501
+				$html .= EEH_HTML::h3(
502
+					$question_group->name(),
503
+					'',
504
+					'ee-reg-form-qstn-grp-title title',
505
+					'font-size: 1.3em; padding-left:0;'
506
+				);
507
+			} else {
508
+				$html .= EEH_HTML::h4(
509
+					$question_group->name(),
510
+					'',
511
+					'ee-reg-form-qstn-grp-title section-title'
512
+				);
513
+			}
514
+		}
515
+		// group_desc
516
+		if ($question_group->show_group_desc() && $question_group->desc() !== '') {
517
+			$html .= EEH_HTML::p(
518
+				$question_group->desc(),
519
+				'',
520
+				$this->checkout->admin_request
521
+					? 'ee-reg-form-qstn-grp-desc-pg'
522
+					: 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text'
523
+			);
524
+		}
525
+		return new EE_Form_Section_HTML($html);
526
+	}
527
+
528
+
529
+	/**
530
+	 * @return    EE_Form_Section_Proper
531
+	 * @throws EE_Error
532
+	 * @throws InvalidArgumentException
533
+	 * @throws ReflectionException
534
+	 * @throws InvalidDataTypeException
535
+	 * @throws InvalidInterfaceException
536
+	 */
537
+	private function _copy_attendee_info_form()
538
+	{
539
+		// array of params to pass to parent constructor
540
+		return new EE_Form_Section_Proper(
541
+			[
542
+				'subsections'     => $this->_copy_attendee_info_inputs(),
543
+				'layout_strategy' => new EE_Template_Layout(
544
+					[
545
+						'layout_template_file'     => SPCO_REG_STEPS_PATH
546
+													  . $this->_slug
547
+													  . '/copy_attendee_info.template.php',
548
+						'begin_template_file'      => null,
549
+						'input_template_file'      => null,
550
+						'subsection_template_file' => null,
551
+						'end_template_file'        => null,
552
+					]
553
+				),
554
+			]
555
+		);
556
+	}
557
+
558
+
559
+	/**
560
+	 * @return EE_Form_Section_HTML
561
+	 * @throws DomainException
562
+	 * @throws InvalidArgumentException
563
+	 * @throws InvalidDataTypeException
564
+	 * @throws InvalidInterfaceException
565
+	 */
566
+	private function _auto_copy_attendee_info()
567
+	{
568
+		return new EE_Form_Section_HTML(
569
+			EEH_Template::locate_template(
570
+				SPCO_REG_STEPS_PATH . $this->_slug . '/_auto_copy_attendee_info.template.php',
571
+				apply_filters(
572
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
573
+					[]
574
+				)
575
+			)
576
+		);
577
+	}
578
+
579
+
580
+	/**
581
+	 * @return array
582
+	 * @throws EE_Error
583
+	 * @throws InvalidArgumentException
584
+	 * @throws ReflectionException
585
+	 * @throws InvalidDataTypeException
586
+	 * @throws InvalidInterfaceException
587
+	 */
588
+	private function _copy_attendee_info_inputs()
589
+	{
590
+		$copy_attendee_info_inputs = [];
591
+		$prev_ticket               = null;
592
+		// grab the saved registrations from the transaction
593
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
594
+		foreach ($registrations as $registration) {
595
+			// for all  attendees other than the primary attendee
596
+			if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
597
+				// if this is a new ticket OR if this is the very first additional attendee after the primary attendee
598
+				if ($registration->ticket()->ID() !== $prev_ticket) {
599
+					$item_name                          = $registration->ticket()->name();
600
+					$item_name                          .= $registration->ticket()->description() !== ''
601
+						? ' - ' . $registration->ticket()->description()
602
+						: '';
603
+					$copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-'
604
+												. $registration->ticket()->ID()
605
+												. ']' ] =
606
+						new EE_Form_Section_HTML(
607
+							'<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
608
+						);
609
+					$prev_ticket                        = $registration->ticket()->ID();
610
+				}
611
+
612
+				$copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] =
613
+					new EE_Checkbox_Multi_Input(
614
+						[
615
+							$registration->ID() => sprintf(
616
+								esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'),
617
+								$registration->count()
618
+							),
619
+						],
620
+						[
621
+							'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
622
+							'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
623
+							'display_html_label_text' => false,
624
+						]
625
+					);
626
+			}
627
+		}
628
+		return $copy_attendee_info_inputs;
629
+	}
630
+
631
+
632
+	/**
633
+	 * @param EE_Registration $registration
634
+	 * @return    EE_Form_Input_Base
635
+	 * @throws EE_Error
636
+	 */
637
+	private function _additional_primary_registrant_inputs(EE_Registration $registration)
638
+	{
639
+		// generate hidden input
640
+		return new EE_Hidden_Input(
641
+			[
642
+				'html_id' => 'primary_registrant',
643
+				'default' => $registration->reg_url_link(),
644
+			]
645
+		);
646
+	}
647
+
648
+
649
+	/**
650
+	 * @param EE_Registration $registration
651
+	 * @param EE_Question     $question
652
+	 * @return EE_Form_Input_Base
653
+	 * @throws EE_Error
654
+	 * @throws InvalidArgumentException
655
+	 * @throws InvalidDataTypeException
656
+	 * @throws InvalidInterfaceException
657
+	 * @throws ReflectionException
658
+	 */
659
+	public function reg_form_question(EE_Registration $registration, EE_Question $question)
660
+	{
661
+
662
+		// if this question was for an attendee detail, then check for that answer
663
+		$answer_value = EEM_Answer::instance()->get_attendee_property_answer_value(
664
+			$registration,
665
+			$question->system_ID()
666
+		);
667
+		$answer       = $answer_value === null
668
+			? EEM_Answer::instance()->get_one(
669
+				[['QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()]]
670
+			)
671
+			: null;
672
+		// if NOT returning to edit an existing registration
673
+		// OR if this question is for an attendee property
674
+		// OR we still don't have an EE_Answer object
675
+		if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) {
676
+			// create an EE_Answer object for storing everything in
677
+			$answer = EE_Answer::new_instance(
678
+				[
679
+					'QST_ID' => $question->ID(),
680
+					'REG_ID' => $registration->ID(),
681
+				]
682
+			);
683
+		}
684
+		// verify instance
685
+		if ($answer instanceof EE_Answer) {
686
+			if (! empty($answer_value)) {
687
+				$answer->set('ANS_value', $answer_value);
688
+			}
689
+			$answer->cache('Question', $question);
690
+			// remember system ID had a bug where sometimes it could be null
691
+			$answer_cache_id = $question->is_system_question()
692
+				? $question->system_ID() . '-' . $registration->reg_url_link()
693
+				: $question->ID() . '-' . $registration->reg_url_link();
694
+			$registration->cache('Answer', $answer, $answer_cache_id);
695
+		}
696
+		return $this->_generate_question_input($registration, $question, $answer);
697
+	}
698
+
699
+
700
+	/**
701
+	 * @param EE_Registration $registration
702
+	 * @param EE_Question     $question
703
+	 * @param                 $answer
704
+	 * @return EE_Form_Input_Base
705
+	 * @throws EE_Error
706
+	 * @throws InvalidArgumentException
707
+	 * @throws ReflectionException
708
+	 * @throws InvalidDataTypeException
709
+	 * @throws InvalidInterfaceException
710
+	 */
711
+	private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer)
712
+	{
713
+		$identifier                               = $question->is_system_question()
714
+			? $question->system_ID()
715
+			: $question->ID();
716
+		$this->_required_questions[ $identifier ] = $question->required();
717
+		add_filter(
718
+			'FHEE__EE_Question__generate_form_input__country_options',
719
+			[$this, 'use_cached_countries_for_form_input'],
720
+			10,
721
+			4
722
+		);
723
+		add_filter(
724
+			'FHEE__EE_Question__generate_form_input__state_options',
725
+			[$this, 'use_cached_states_for_form_input'],
726
+			10,
727
+			4
728
+		);
729
+		$input_constructor_args                  = [
730
+			'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
731
+			'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
732
+			'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
733
+			'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
734
+			'html_label_class' => 'ee-reg-qstn',
735
+		];
736
+		$input_constructor_args['html_label_id'] .= '-lbl';
737
+		if ($answer instanceof EE_Answer && $answer->ID()) {
738
+			$input_constructor_args['html_name']     .= '[' . $answer->ID() . ']';
739
+			$input_constructor_args['html_id']       .= '-' . $answer->ID();
740
+			$input_constructor_args['html_label_id'] .= '-' . $answer->ID();
741
+		}
742
+		$form_input = $question->generate_form_input(
743
+			$registration,
744
+			$answer,
745
+			$input_constructor_args
746
+		);
747
+		remove_filter(
748
+			'FHEE__EE_Question__generate_form_input__country_options',
749
+			[$this, 'use_cached_countries_for_form_input']
750
+		);
751
+		remove_filter(
752
+			'FHEE__EE_Question__generate_form_input__state_options',
753
+			[$this, 'use_cached_states_for_form_input']
754
+		);
755
+		return $form_input;
756
+	}
757
+
758
+
759
+	/**
760
+	 * Gets the list of countries for the form input
761
+	 *
762
+	 * @param array|null      $countries_list
763
+	 * @param EE_Question     $question
764
+	 * @param EE_Registration $registration
765
+	 * @param EE_Answer       $answer
766
+	 * @return array 2d keys are country IDs, values are their names
767
+	 * @throws EE_Error
768
+	 * @throws InvalidArgumentException
769
+	 * @throws InvalidDataTypeException
770
+	 * @throws InvalidInterfaceException
771
+	 * @throws ReflectionException
772
+	 */
773
+	public function use_cached_countries_for_form_input(
774
+		$countries_list,
775
+		EE_Question $question = null,
776
+		EE_Registration $registration = null,
777
+		EE_Answer $answer = null
778
+	) {
779
+		$country_options = ['' => ''];
780
+		// get possibly cached list of countries
781
+		$countries = $this->checkout->action === 'process_reg_step'
782
+			? EEM_Country::instance()->get_all_countries()
783
+			: EEM_Country::instance()->get_all_active_countries();
784
+		if (! empty($countries)) {
785
+			foreach ($countries as $country) {
786
+				if ($country instanceof EE_Country) {
787
+					$country_options[ $country->ID() ] = $country->name();
788
+				}
789
+			}
790
+		}
791
+		if ($question instanceof EE_Question && $registration instanceof EE_Registration) {
792
+			$answer = EEM_Answer::instance()->get_one(
793
+				[['QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()]]
794
+			);
795
+		} else {
796
+			$answer = EE_Answer::new_instance();
797
+		}
798
+		return apply_filters(
799
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
800
+			$country_options,
801
+			$this,
802
+			$registration,
803
+			$question,
804
+			$answer
805
+		);
806
+	}
807
+
808
+
809
+	/**
810
+	 * Gets the list of states for the form input
811
+	 *
812
+	 * @param array|null      $states_list
813
+	 * @param EE_Question     $question
814
+	 * @param EE_Registration $registration
815
+	 * @param EE_Answer       $answer
816
+	 * @return array 2d keys are state IDs, values are their names
817
+	 * @throws EE_Error
818
+	 * @throws InvalidArgumentException
819
+	 * @throws InvalidDataTypeException
820
+	 * @throws InvalidInterfaceException
821
+	 * @throws ReflectionException
822
+	 */
823
+	public function use_cached_states_for_form_input(
824
+		$states_list,
825
+		EE_Question $question = null,
826
+		EE_Registration $registration = null,
827
+		EE_Answer $answer = null
828
+	) {
829
+		$state_options = ['' => ['' => '']];
830
+		$states        = $this->checkout->action === 'process_reg_step'
831
+			? EEM_State::instance()->get_all_states()
832
+			: EEM_State::instance()->get_all_active_states();
833
+		if (! empty($states)) {
834
+			foreach ($states as $state) {
835
+				if ($state instanceof EE_State) {
836
+					$state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
837
+				}
838
+			}
839
+		}
840
+		return apply_filters(
841
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
842
+			$state_options,
843
+			$this,
844
+			$registration,
845
+			$question,
846
+			$answer
847
+		);
848
+	}
849
+
850
+
851
+	/********************************************************************************************************/
852
+	/****************************************  PROCESS REG STEP  ****************************************/
853
+	/********************************************************************************************************/
854
+
855
+
856
+	/**
857
+	 * @return bool
858
+	 * @throws EE_Error
859
+	 * @throws InvalidArgumentException
860
+	 * @throws ReflectionException
861
+	 * @throws RuntimeException
862
+	 * @throws InvalidDataTypeException
863
+	 * @throws InvalidInterfaceException
864
+	 */
865
+	public function process_reg_step()
866
+	{
867
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
868
+		// grab validated data from form
869
+		$valid_data = $this->checkout->current_step->valid_data();
870
+		// if we don't have any $valid_data then something went TERRIBLY WRONG !!!
871
+		if (empty($valid_data)) {
872
+			EE_Error::add_error(
873
+				esc_html__('No valid question responses were received.', 'event_espresso'),
874
+				__FILE__,
875
+				__FUNCTION__,
876
+				__LINE__
877
+			);
878
+			return false;
879
+		}
880
+		if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
881
+			EE_Error::add_error(
882
+				esc_html__(
883
+					'A valid transaction could not be initiated for processing your registrations.',
884
+					'event_espresso'
885
+				),
886
+				__FILE__,
887
+				__FUNCTION__,
888
+				__LINE__
889
+			);
890
+			return false;
891
+		}
892
+		// get cached registrations
893
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
894
+		// verify we got the goods
895
+		if (empty($registrations)) {
896
+			// combine the old translated string with a new one, in order to not break translations
897
+			$error_message = esc_html__(
898
+				'Your form data could not be applied to any valid registrations.',
899
+				'event_espresso'
900
+			)
901
+			. sprintf(
902
+				esc_html_x(
903
+					'%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.',
904
+					'(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.',
905
+					'event_espresso'
906
+				),
907
+				'<a href="' . get_post_type_archive_link('espresso_events') . '" >',
908
+				'</a>',
909
+				'<br />'
910
+			);
911
+			EE_Error::add_error(
912
+				$error_message,
913
+				__FILE__,
914
+				__FUNCTION__,
915
+				__LINE__
916
+			);
917
+			return false;
918
+		}
919
+		// extract attendee info from form data and save to model objects
920
+		$registrations_processed = $this->_process_registrations($registrations, $valid_data);
921
+		// if first pass thru SPCO,
922
+		// then let's check processed registrations against the total number of tickets in the cart
923
+		if ($registrations_processed === false) {
924
+			// but return immediately if the previous step exited early due to errors
925
+			return false;
926
+		}
927
+		if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
928
+			// generate a correctly translated string for all possible singular/plural combinations
929
+			if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
930
+				$error_msg = sprintf(
931
+					esc_html_x(
932
+						'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed',
933
+						'There was 1 ticket in the Event Queue, but 2 registrations were processed',
934
+						'event_espresso'
935
+					),
936
+					$this->checkout->total_ticket_count,
937
+					$registrations_processed
938
+				);
939
+			} elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) {
940
+				$error_msg = sprintf(
941
+					esc_html_x(
942
+						'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed',
943
+						'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed',
944
+						'event_espresso'
945
+					),
946
+					$this->checkout->total_ticket_count,
947
+					$registrations_processed
948
+				);
949
+			} else {
950
+				$error_msg = sprintf(
951
+					esc_html__(
952
+						'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed',
953
+						'event_espresso'
954
+					),
955
+					$this->checkout->total_ticket_count,
956
+					$registrations_processed
957
+				);
958
+			}
959
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
960
+			return false;
961
+		}
962
+		// mark this reg step as completed
963
+		$this->set_completed();
964
+		$this->_set_success_message(
965
+			esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso')
966
+		);
967
+		// do action in case a plugin wants to do something with the data submitted in step 1.
968
+		// passes EE_Single_Page_Checkout, and it's posted data
969
+		do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data);
970
+		return true;
971
+	}
972
+
973
+
974
+	/**
975
+	 *    _process_registrations
976
+	 *
977
+	 * @param EE_Registration[] $registrations
978
+	 * @param array[][]         $valid_data
979
+	 * @return bool|int
980
+	 * @throws EntityNotFoundException
981
+	 * @throws EE_Error
982
+	 * @throws InvalidArgumentException
983
+	 * @throws ReflectionException
984
+	 * @throws RuntimeException
985
+	 * @throws InvalidDataTypeException
986
+	 * @throws InvalidInterfaceException
987
+	 */
988
+	private function _process_registrations($registrations = [], $valid_data = [])
989
+	{
990
+		// load resources and set some defaults
991
+		EE_Registry::instance()->load_model('Attendee');
992
+		// holder for primary registrant attendee object
993
+		$this->checkout->primary_attendee_obj = null;
994
+		// array for tracking reg form data for the primary registrant
995
+		$primary_registrant = [
996
+			'line_item_id' => null,
997
+		];
998
+		$copy_primary       = false;
999
+		// reg form sections that do not contain inputs
1000
+		$non_input_form_sections = [
1001
+			'primary_registrant',
1002
+			'additional_attendee_reg_info',
1003
+			'spco_copy_attendee_chk',
1004
+		];
1005
+		// attendee counter
1006
+		$att_nmbr = 0;
1007
+		// grab the saved registrations from the transaction
1008
+		foreach ($registrations as $registration) {
1009
+			// verify EE_Registration object
1010
+			if (! $registration instanceof EE_Registration) {
1011
+				EE_Error::add_error(
1012
+					esc_html__(
1013
+						'An invalid Registration object was discovered when attempting to process your registration information.',
1014
+						'event_espresso'
1015
+					),
1016
+					__FILE__,
1017
+					__FUNCTION__,
1018
+					__LINE__
1019
+				);
1020
+				return false;
1021
+			}
1022
+			$reg_url_link = $registration->reg_url_link();
1023
+			// reg_url_link exists ?
1024
+			if (! empty($reg_url_link)) {
1025
+				// should this registration be processed during this visit ?
1026
+				if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
1027
+					// if NOT revisiting, then let's save the registration now,
1028
+					// so that we have a REG_ID to use when generating other objects
1029
+					if (! $this->checkout->revisit) {
1030
+						$registration->save();
1031
+					}
1032
+					/**
1033
+					 * This allows plugins to trigger a fail on processing of a
1034
+					 * registration for any conditions they may have for it to pass.
1035
+					 *
1036
+					 * @var bool   if true is returned by the plugin then the
1037
+					 *            registration processing is halted.
1038
+					 */
1039
+					if (
1040
+						apply_filters(
1041
+							'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
1042
+							false,
1043
+							$att_nmbr,
1044
+							$registration,
1045
+							$registrations,
1046
+							$valid_data,
1047
+							$this
1048
+						)
1049
+					) {
1050
+						return false;
1051
+					}
1052
+
1053
+					// Houston, we have a registration!
1054
+					$att_nmbr++;
1055
+					$this->_attendee_data[ $reg_url_link ] = [];
1056
+					// grab any existing related answer objects
1057
+					$this->_registration_answers = $registration->answers();
1058
+					// unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
1059
+					if (isset($valid_data[ $reg_url_link ])) {
1060
+						// do we need to copy basic info from primary attendee ?
1061
+						$copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info'])
1062
+										&& absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
1063
+						// filter form input data for this registration
1064
+						$valid_data[ $reg_url_link ] = (array) apply_filters(
1065
+							'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
1066
+							$valid_data[ $reg_url_link ]
1067
+						);
1068
+						if (isset($valid_data['primary_attendee'])) {
1069
+							$primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
1070
+								? $valid_data['primary_attendee']
1071
+								: false;
1072
+							unset($valid_data['primary_attendee']);
1073
+						}
1074
+						// now loop through our array of valid post data && process attendee reg forms
1075
+						foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) {
1076
+							if (! in_array($form_section, $non_input_form_sections, true)) {
1077
+								foreach ($form_inputs as $form_input => $input_value) {
1078
+									// check for critical inputs
1079
+									if (
1080
+										! $this->_verify_critical_attendee_details_are_set_and_validate_email(
1081
+											$form_input,
1082
+											$input_value
1083
+										)
1084
+									) {
1085
+										return false;
1086
+									}
1087
+									// store a bit of data about the primary attendee
1088
+									if (
1089
+										$att_nmbr === 1
1090
+										&& ! empty($input_value)
1091
+										&& $reg_url_link === $primary_registrant['line_item_id']
1092
+									) {
1093
+										$primary_registrant[ $form_input ] = $input_value;
1094
+									} elseif (
1095
+										$copy_primary
1096
+											  && $input_value === null
1097
+											  && isset($primary_registrant[ $form_input ])
1098
+									) {
1099
+										$input_value = $primary_registrant[ $form_input ];
1100
+									}
1101
+									// now attempt to save the input data
1102
+									if (
1103
+										! $this->_save_registration_form_input(
1104
+											$registration,
1105
+											$form_input,
1106
+											$input_value
1107
+										)
1108
+									) {
1109
+										EE_Error::add_error(
1110
+											sprintf(
1111
+												esc_html_x(
1112
+													'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
1113
+													'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"',
1114
+													'event_espresso'
1115
+												),
1116
+												$form_input,
1117
+												$input_value
1118
+											),
1119
+											__FILE__,
1120
+											__FUNCTION__,
1121
+											__LINE__
1122
+										);
1123
+										return false;
1124
+									}
1125
+								}
1126
+							}
1127
+						}  // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs )
1128
+					}
1129
+					// this registration does not require additional attendee information ?
1130
+					if (
1131
+						$copy_primary
1132
+						&& $att_nmbr > 1
1133
+						&& $this->checkout->primary_attendee_obj instanceof EE_Attendee
1134
+					) {
1135
+						// just copy the primary registrant
1136
+						$attendee = $this->checkout->primary_attendee_obj;
1137
+					} else {
1138
+						// ensure critical details are set for additional attendees
1139
+						$this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1
1140
+							? $this->_copy_critical_attendee_details_from_primary_registrant(
1141
+								$this->_attendee_data[ $reg_url_link ]
1142
+							)
1143
+							: $this->_attendee_data[ $reg_url_link ];
1144
+						// execute create attendee command (which may return an existing attendee)
1145
+						$attendee = EE_Registry::instance()->BUS->execute(
1146
+							new CreateAttendeeCommand(
1147
+								$this->_attendee_data[ $reg_url_link ],
1148
+								$registration
1149
+							)
1150
+						);
1151
+						// who's #1 ?
1152
+						if ($att_nmbr === 1) {
1153
+							$this->checkout->primary_attendee_obj = $attendee;
1154
+						}
1155
+					}
1156
+					// add relation to registration, set attendee ID, and cache attendee
1157
+					$this->_associate_attendee_with_registration($registration, $attendee);
1158
+					if (! $registration->attendee() instanceof EE_Attendee) {
1159
+						EE_Error::add_error(
1160
+							sprintf(
1161
+								esc_html_x(
1162
+									'Registration %s has an invalid or missing Attendee object.',
1163
+									'Registration 123-456-789 has an invalid or missing Attendee object.',
1164
+									'event_espresso'
1165
+								),
1166
+								$reg_url_link
1167
+							),
1168
+							__FILE__,
1169
+							__FUNCTION__,
1170
+							__LINE__
1171
+						);
1172
+						return false;
1173
+					}
1174
+					/** @type EE_Registration_Processor $registration_processor */
1175
+					$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1176
+					// at this point, we should have enough details about the registrant to consider the registration
1177
+					// NOT incomplete
1178
+					$registration_processor->toggle_incomplete_registration_status_to_default(
1179
+						$registration,
1180
+						false,
1181
+						new Context(
1182
+							'spco_reg_step_attendee_information_process_registrations',
1183
+							esc_html__(
1184
+								'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
1185
+								'event_espresso'
1186
+							)
1187
+						)
1188
+					);
1189
+					// we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
1190
+					// abandoned
1191
+					$this->checkout->transaction->toggle_failed_transaction_status();
1192
+					// if we've gotten this far, then let's save what we have
1193
+					$registration->save();
1194
+					// add relation between TXN and registration
1195
+					$this->_associate_registration_with_transaction($registration);
1196
+				}
1197
+			} else {
1198
+				EE_Error::add_error(
1199
+					esc_html__(
1200
+						'An invalid or missing line item ID was encountered while attempting to process the registration form.',
1201
+						'event_espresso'
1202
+					),
1203
+					__FILE__,
1204
+					__FUNCTION__,
1205
+					__LINE__
1206
+				);
1207
+				// remove malformed data
1208
+				unset($valid_data[ $reg_url_link ]);
1209
+				return false;
1210
+			}
1211
+		} // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
1212
+		return $att_nmbr;
1213
+	}
1214
+
1215
+
1216
+	/**
1217
+	 *    _save_registration_form_input
1218
+	 *
1219
+	 * @param EE_Registration $registration
1220
+	 * @param string          $form_input
1221
+	 * @param string          $input_value
1222
+	 * @return bool
1223
+	 * @throws EE_Error
1224
+	 * @throws InvalidArgumentException
1225
+	 * @throws InvalidDataTypeException
1226
+	 * @throws InvalidInterfaceException
1227
+	 * @throws ReflectionException
1228
+	 */
1229
+	private function _save_registration_form_input(
1230
+		EE_Registration $registration,
1231
+		$form_input = '',
1232
+		$input_value = ''
1233
+	) {
1234
+		// If email_confirm is sent it's not saved
1235
+		if ((string) $form_input === 'email_confirm') {
1236
+			return true;
1237
+		}
1238
+
1239
+		// allow for plugins to hook in and do their own processing of the form input.
1240
+		// For plugins to bypass normal processing here, they just need to return a boolean value.
1241
+		if (
1242
+			apply_filters(
1243
+				'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
1244
+				false,
1245
+				$registration,
1246
+				$form_input,
1247
+				$input_value,
1248
+				$this
1249
+			)
1250
+		) {
1251
+			return true;
1252
+		}
1253
+		/*
1254 1254
          * $answer_cache_id is the key used to find the EE_Answer we want
1255 1255
          * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
1256 1256
          */
1257
-        $answer_cache_id = $this->checkout->reg_url_link
1258
-            ? $form_input . '-' . $registration->reg_url_link()
1259
-            : (string) $form_input;
1260
-        $answer_is_obj   = isset($this->_registration_answers[ $answer_cache_id ])
1261
-                           && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer;
1262
-        // rename form_inputs if they are EE_Attendee properties
1263
-        switch ((string) $form_input) {
1264
-            case 'state':
1265
-            case 'STA_ID':
1266
-                $attendee_property = true;
1267
-                $form_input        = 'STA_ID';
1268
-                break;
1269
-
1270
-            case 'country':
1271
-            case 'CNT_ISO':
1272
-                $attendee_property = true;
1273
-                $form_input        = 'CNT_ISO';
1274
-                break;
1275
-
1276
-            default:
1277
-                $ATT_input = 'ATT_' . $form_input;
1278
-                $attendee_property = EEM_Attendee::instance()->has_field($ATT_input);
1279
-                $form_input        = $attendee_property ? 'ATT_' . $form_input : $form_input;
1280
-        }
1281
-        // if this form input has a corresponding attendee property
1282
-        if ($attendee_property) {
1283
-            $this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value;
1284
-            if ($answer_is_obj) {
1285
-                // and delete the corresponding answer since we won't be storing this data in that object
1286
-                $registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer');
1287
-                $this->_registration_answers[ $answer_cache_id ]->delete_permanently();
1288
-            }
1289
-            return true;
1290
-        }
1291
-        if ($answer_is_obj) {
1292
-            // save this data to the answer object
1293
-            $this->_registration_answers[ $answer_cache_id ]->set_value($input_value);
1294
-            $result = $this->_registration_answers[ $answer_cache_id ]->save();
1295
-            return $result !== false;
1296
-        }
1297
-        foreach ($this->_registration_answers as $answer) {
1298
-            if ($answer instanceof EE_Answer && (string) $answer->question_ID() === $answer_cache_id) {
1299
-                $answer->set_value($input_value);
1300
-                $result = $answer->save();
1301
-                return $result !== false;
1302
-            }
1303
-        }
1304
-        return false;
1305
-    }
1306
-
1307
-
1308
-    /**
1309
-     *    _verify_critical_attendee_details_are_set
1310
-     *
1311
-     * @param string $form_input
1312
-     * @param string $input_value
1313
-     * @return boolean
1314
-     */
1315
-    private function _verify_critical_attendee_details_are_set_and_validate_email(
1316
-        $form_input = '',
1317
-        $input_value = ''
1318
-    ) {
1319
-        if (empty($input_value)) {
1320
-            // if the form input isn't marked as being required, then just return
1321
-            if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) {
1322
-                return true;
1323
-            }
1324
-            switch ($form_input) {
1325
-                case 'fname':
1326
-                    EE_Error::add_error(
1327
-                        esc_html__('First Name is a required value.', 'event_espresso'),
1328
-                        __FILE__,
1329
-                        __FUNCTION__,
1330
-                        __LINE__
1331
-                    );
1332
-                    return false;
1333
-                case 'lname':
1334
-                    EE_Error::add_error(
1335
-                        esc_html__('Last Name is a required value.', 'event_espresso'),
1336
-                        __FILE__,
1337
-                        __FUNCTION__,
1338
-                        __LINE__
1339
-                    );
1340
-                    return false;
1341
-                case 'email':
1342
-                    EE_Error::add_error(
1343
-                        esc_html__('Please enter a valid email address.', 'event_espresso'),
1344
-                        __FILE__,
1345
-                        __FUNCTION__,
1346
-                        __LINE__
1347
-                    );
1348
-                    return false;
1349
-            }
1350
-        }
1351
-        return true;
1352
-    }
1353
-
1354
-
1355
-    /**
1356
-     *    _associate_attendee_with_registration
1357
-     *
1358
-     * @param EE_Registration $registration
1359
-     * @param EE_Attendee     $attendee
1360
-     * @return void
1361
-     * @throws EE_Error
1362
-     * @throws InvalidArgumentException
1363
-     * @throws ReflectionException
1364
-     * @throws RuntimeException
1365
-     * @throws InvalidDataTypeException
1366
-     * @throws InvalidInterfaceException
1367
-     */
1368
-    private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee)
1369
-    {
1370
-        // add relation to attendee
1371
-        $registration->_add_relation_to($attendee, 'Attendee');
1372
-        $registration->set_attendee_id($attendee->ID());
1373
-        $registration->update_cache_after_object_save('Attendee', $attendee);
1374
-    }
1375
-
1376
-
1377
-    /**
1378
-     *    _associate_registration_with_transaction
1379
-     *
1380
-     * @param EE_Registration $registration
1381
-     * @return void
1382
-     * @throws EE_Error
1383
-     * @throws InvalidArgumentException
1384
-     * @throws ReflectionException
1385
-     * @throws InvalidDataTypeException
1386
-     * @throws InvalidInterfaceException
1387
-     */
1388
-    private function _associate_registration_with_transaction(EE_Registration $registration)
1389
-    {
1390
-        // add relation to registration
1391
-        $this->checkout->transaction->_add_relation_to($registration, 'Registration');
1392
-        $this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
1393
-    }
1394
-
1395
-
1396
-    /**
1397
-     *    _copy_critical_attendee_details_from_primary_registrant
1398
-     *    ensures that all attendees at least have data for first name, last name, and email address
1399
-     *
1400
-     * @param array $attendee_data
1401
-     * @return array
1402
-     * @throws EE_Error
1403
-     * @throws InvalidArgumentException
1404
-     * @throws ReflectionException
1405
-     * @throws InvalidDataTypeException
1406
-     * @throws InvalidInterfaceException
1407
-     */
1408
-    private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = [])
1409
-    {
1410
-        // bare minimum critical details include first name, last name, email address
1411
-        $critical_attendee_details = ['ATT_fname', 'ATT_lname', 'ATT_email'];
1412
-        // add address info to critical details?
1413
-        if (
1414
-            apply_filters(
1415
-                'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details',
1416
-                false
1417
-            )
1418
-        ) {
1419
-            $address_details           = [
1420
-                'ATT_address',
1421
-                'ATT_address2',
1422
-                'ATT_city',
1423
-                'STA_ID',
1424
-                'CNT_ISO',
1425
-                'ATT_zip',
1426
-                'ATT_phone',
1427
-            ];
1428
-            $critical_attendee_details = array_merge($critical_attendee_details, $address_details);
1429
-        }
1430
-        foreach ($critical_attendee_details as $critical_attendee_detail) {
1431
-            if (
1432
-                ! isset($attendee_data[ $critical_attendee_detail ])
1433
-                || empty($attendee_data[ $critical_attendee_detail ])
1434
-            ) {
1435
-                $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get(
1436
-                    $critical_attendee_detail
1437
-                );
1438
-            }
1439
-        }
1440
-        return $attendee_data;
1441
-    }
1442
-
1443
-
1444
-    /**
1445
-     *    update_reg_step
1446
-     *    this is the final step after a user  revisits the site to edit their attendee information
1447
-     *    this gets called AFTER the process_reg_step() method above
1448
-     *
1449
-     * @return bool
1450
-     * @throws EE_Error
1451
-     * @throws InvalidArgumentException
1452
-     * @throws ReflectionException
1453
-     * @throws RuntimeException
1454
-     * @throws InvalidDataTypeException
1455
-     * @throws InvalidInterfaceException
1456
-     */
1457
-    public function update_reg_step()
1458
-    {
1459
-        // save everything
1460
-        if ($this->process_reg_step()) {
1461
-            $this->checkout->redirect     = true;
1462
-            $this->checkout->redirect_url = add_query_arg(
1463
-                [
1464
-                    'e_reg_url_link' => $this->checkout->reg_url_link,
1465
-                    'revisit'        => true,
1466
-                ],
1467
-                $this->checkout->thank_you_page_url
1468
-            );
1469
-            $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1470
-            return true;
1471
-        }
1472
-        return false;
1473
-    }
1257
+		$answer_cache_id = $this->checkout->reg_url_link
1258
+			? $form_input . '-' . $registration->reg_url_link()
1259
+			: (string) $form_input;
1260
+		$answer_is_obj   = isset($this->_registration_answers[ $answer_cache_id ])
1261
+						   && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer;
1262
+		// rename form_inputs if they are EE_Attendee properties
1263
+		switch ((string) $form_input) {
1264
+			case 'state':
1265
+			case 'STA_ID':
1266
+				$attendee_property = true;
1267
+				$form_input        = 'STA_ID';
1268
+				break;
1269
+
1270
+			case 'country':
1271
+			case 'CNT_ISO':
1272
+				$attendee_property = true;
1273
+				$form_input        = 'CNT_ISO';
1274
+				break;
1275
+
1276
+			default:
1277
+				$ATT_input = 'ATT_' . $form_input;
1278
+				$attendee_property = EEM_Attendee::instance()->has_field($ATT_input);
1279
+				$form_input        = $attendee_property ? 'ATT_' . $form_input : $form_input;
1280
+		}
1281
+		// if this form input has a corresponding attendee property
1282
+		if ($attendee_property) {
1283
+			$this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value;
1284
+			if ($answer_is_obj) {
1285
+				// and delete the corresponding answer since we won't be storing this data in that object
1286
+				$registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer');
1287
+				$this->_registration_answers[ $answer_cache_id ]->delete_permanently();
1288
+			}
1289
+			return true;
1290
+		}
1291
+		if ($answer_is_obj) {
1292
+			// save this data to the answer object
1293
+			$this->_registration_answers[ $answer_cache_id ]->set_value($input_value);
1294
+			$result = $this->_registration_answers[ $answer_cache_id ]->save();
1295
+			return $result !== false;
1296
+		}
1297
+		foreach ($this->_registration_answers as $answer) {
1298
+			if ($answer instanceof EE_Answer && (string) $answer->question_ID() === $answer_cache_id) {
1299
+				$answer->set_value($input_value);
1300
+				$result = $answer->save();
1301
+				return $result !== false;
1302
+			}
1303
+		}
1304
+		return false;
1305
+	}
1306
+
1307
+
1308
+	/**
1309
+	 *    _verify_critical_attendee_details_are_set
1310
+	 *
1311
+	 * @param string $form_input
1312
+	 * @param string $input_value
1313
+	 * @return boolean
1314
+	 */
1315
+	private function _verify_critical_attendee_details_are_set_and_validate_email(
1316
+		$form_input = '',
1317
+		$input_value = ''
1318
+	) {
1319
+		if (empty($input_value)) {
1320
+			// if the form input isn't marked as being required, then just return
1321
+			if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) {
1322
+				return true;
1323
+			}
1324
+			switch ($form_input) {
1325
+				case 'fname':
1326
+					EE_Error::add_error(
1327
+						esc_html__('First Name is a required value.', 'event_espresso'),
1328
+						__FILE__,
1329
+						__FUNCTION__,
1330
+						__LINE__
1331
+					);
1332
+					return false;
1333
+				case 'lname':
1334
+					EE_Error::add_error(
1335
+						esc_html__('Last Name is a required value.', 'event_espresso'),
1336
+						__FILE__,
1337
+						__FUNCTION__,
1338
+						__LINE__
1339
+					);
1340
+					return false;
1341
+				case 'email':
1342
+					EE_Error::add_error(
1343
+						esc_html__('Please enter a valid email address.', 'event_espresso'),
1344
+						__FILE__,
1345
+						__FUNCTION__,
1346
+						__LINE__
1347
+					);
1348
+					return false;
1349
+			}
1350
+		}
1351
+		return true;
1352
+	}
1353
+
1354
+
1355
+	/**
1356
+	 *    _associate_attendee_with_registration
1357
+	 *
1358
+	 * @param EE_Registration $registration
1359
+	 * @param EE_Attendee     $attendee
1360
+	 * @return void
1361
+	 * @throws EE_Error
1362
+	 * @throws InvalidArgumentException
1363
+	 * @throws ReflectionException
1364
+	 * @throws RuntimeException
1365
+	 * @throws InvalidDataTypeException
1366
+	 * @throws InvalidInterfaceException
1367
+	 */
1368
+	private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee)
1369
+	{
1370
+		// add relation to attendee
1371
+		$registration->_add_relation_to($attendee, 'Attendee');
1372
+		$registration->set_attendee_id($attendee->ID());
1373
+		$registration->update_cache_after_object_save('Attendee', $attendee);
1374
+	}
1375
+
1376
+
1377
+	/**
1378
+	 *    _associate_registration_with_transaction
1379
+	 *
1380
+	 * @param EE_Registration $registration
1381
+	 * @return void
1382
+	 * @throws EE_Error
1383
+	 * @throws InvalidArgumentException
1384
+	 * @throws ReflectionException
1385
+	 * @throws InvalidDataTypeException
1386
+	 * @throws InvalidInterfaceException
1387
+	 */
1388
+	private function _associate_registration_with_transaction(EE_Registration $registration)
1389
+	{
1390
+		// add relation to registration
1391
+		$this->checkout->transaction->_add_relation_to($registration, 'Registration');
1392
+		$this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
1393
+	}
1394
+
1395
+
1396
+	/**
1397
+	 *    _copy_critical_attendee_details_from_primary_registrant
1398
+	 *    ensures that all attendees at least have data for first name, last name, and email address
1399
+	 *
1400
+	 * @param array $attendee_data
1401
+	 * @return array
1402
+	 * @throws EE_Error
1403
+	 * @throws InvalidArgumentException
1404
+	 * @throws ReflectionException
1405
+	 * @throws InvalidDataTypeException
1406
+	 * @throws InvalidInterfaceException
1407
+	 */
1408
+	private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = [])
1409
+	{
1410
+		// bare minimum critical details include first name, last name, email address
1411
+		$critical_attendee_details = ['ATT_fname', 'ATT_lname', 'ATT_email'];
1412
+		// add address info to critical details?
1413
+		if (
1414
+			apply_filters(
1415
+				'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details',
1416
+				false
1417
+			)
1418
+		) {
1419
+			$address_details           = [
1420
+				'ATT_address',
1421
+				'ATT_address2',
1422
+				'ATT_city',
1423
+				'STA_ID',
1424
+				'CNT_ISO',
1425
+				'ATT_zip',
1426
+				'ATT_phone',
1427
+			];
1428
+			$critical_attendee_details = array_merge($critical_attendee_details, $address_details);
1429
+		}
1430
+		foreach ($critical_attendee_details as $critical_attendee_detail) {
1431
+			if (
1432
+				! isset($attendee_data[ $critical_attendee_detail ])
1433
+				|| empty($attendee_data[ $critical_attendee_detail ])
1434
+			) {
1435
+				$attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get(
1436
+					$critical_attendee_detail
1437
+				);
1438
+			}
1439
+		}
1440
+		return $attendee_data;
1441
+	}
1442
+
1443
+
1444
+	/**
1445
+	 *    update_reg_step
1446
+	 *    this is the final step after a user  revisits the site to edit their attendee information
1447
+	 *    this gets called AFTER the process_reg_step() method above
1448
+	 *
1449
+	 * @return bool
1450
+	 * @throws EE_Error
1451
+	 * @throws InvalidArgumentException
1452
+	 * @throws ReflectionException
1453
+	 * @throws RuntimeException
1454
+	 * @throws InvalidDataTypeException
1455
+	 * @throws InvalidInterfaceException
1456
+	 */
1457
+	public function update_reg_step()
1458
+	{
1459
+		// save everything
1460
+		if ($this->process_reg_step()) {
1461
+			$this->checkout->redirect     = true;
1462
+			$this->checkout->redirect_url = add_query_arg(
1463
+				[
1464
+					'e_reg_url_link' => $this->checkout->reg_url_link,
1465
+					'revisit'        => true,
1466
+				],
1467
+				$this->checkout->thank_you_page_url
1468
+			);
1469
+			$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1470
+			return true;
1471
+		}
1472
+		return false;
1473
+	}
1474 1474
 }
Please login to merge, or discard this patch.