Completed
Branch FET-Wait-List (92c8c5)
by
unknown
134:10 queued 122:28
created
attendee_information/EE_SPCO_Reg_Step_Attendee_Information.class.php 1 patch
Indentation   +1327 added lines, -1327 removed lines patch added patch discarded remove patch
@@ -17,1335 +17,1335 @@
 block discarded – undo
17 17
 class EE_SPCO_Reg_Step_Attendee_Information extends EE_SPCO_Reg_Step
18 18
 {
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 = array();
29
-
30
-    /**
31
-     * @type array $_required_questions
32
-     */
33
-    private $_required_questions = array();
34
-
35
-    /**
36
-     * @type array $_registration_answers
37
-     */
38
-    private $_registration_answers = array();
39
-
40
-
41
-    /**
42
-     *    class constructor
43
-     *
44
-     * @access    public
45
-     * @param    EE_Checkout $checkout
46
-     */
47
-    public function __construct(EE_Checkout $checkout)
48
-    {
49
-        $this->_slug     = 'attendee_information';
50
-        $this->_name     = esc_html__('Attendee Information', 'event_espresso');
51
-        $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php';
52
-        $this->checkout  = $checkout;
53
-        $this->_reset_success_message();
54
-        $this->set_instructions(
55
-            esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso')
56
-        );
57
-    }
58
-
59
-
60
-    public function translate_js_strings()
61
-    {
62
-        EE_Registry::$i18n_js_strings['required_field']            = esc_html__(
63
-            ' is a required question.',
64
-            'event_espresso'
65
-        );
66
-        EE_Registry::$i18n_js_strings['required_multi_field']      = esc_html__(
67
-            ' is a required question. Please enter a value for at least one of the options.',
68
-            'event_espresso'
69
-        );
70
-        EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__(
71
-            'Please answer all required questions correctly before proceeding.',
72
-            'event_espresso'
73
-        );
74
-        EE_Registry::$i18n_js_strings['attendee_info_copied']      = sprintf(
75
-            esc_html__(
76
-                'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.',
77
-                'event_espresso'
78
-            ),
79
-            '<br/>'
80
-        );
81
-        EE_Registry::$i18n_js_strings['attendee_info_copy_error']  = esc_html__(
82
-            'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.',
83
-            'event_espresso'
84
-        );
85
-        EE_Registry::$i18n_js_strings['enter_valid_email']         = esc_html__(
86
-            'You must enter a valid email address.',
87
-            'event_espresso'
88
-        );
89
-        EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__(
90
-            'You must enter a valid email address and answer all other required questions before you can proceed.',
91
-            'event_espresso'
92
-        );
93
-    }
94
-
95
-
96
-    public function enqueue_styles_and_scripts()
97
-    {
98
-    }
99
-
100
-
101
-    /**
102
-     * @return boolean
103
-     */
104
-    public function initialize_reg_step()
105
-    {
106
-        return true;
107
-    }
108
-
109
-
110
-    /**
111
-     * @return EE_Form_Section_Proper
112
-     * @throws EE_Error
113
-     * @throws InvalidArgumentException
114
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
115
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
116
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
117
-     */
118
-    public function generate_reg_form()
119
-    {
120
-        $this->_print_copy_info = false;
121
-        $primary_registrant     = null;
122
-        // autoload Line_Item_Display classes
123
-        EEH_Autoloader::register_line_item_display_autoloaders();
124
-        $Line_Item_Display = new EE_Line_Item_Display();
125
-        // calculate taxes
126
-        $Line_Item_Display->display_line_item(
127
-            $this->checkout->cart->get_grand_total(),
128
-            array('set_tax_rate' => true)
129
-        );
130
-        /** @var $subsections EE_Form_Section_Proper[] */
131
-        $subsections   = array(
132
-            'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
133
-        );
134
-        $template_args = array(
135
-            'revisit'       => $this->checkout->revisit,
136
-            'registrations' => array(),
137
-            'ticket_count'  => array(),
138
-        );
139
-        // grab the saved registrations from the transaction
140
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
141
-        if ($registrations) {
142
-            foreach ($registrations as $registration) {
143
-                // can this registration be processed during this visit ?
144
-                if ($registration instanceof EE_Registration
145
-                    && $this->checkout->visit_allows_processing_of_this_registration($registration)
146
-                ) {
147
-                    $subsections[$registration->reg_url_link()] = $this->_registrations_reg_form($registration);
148
-                    if (! $this->checkout->admin_request) {
149
-                        $template_args['registrations'][$registration->reg_url_link()]    = $registration;
150
-                        $template_args['ticket_count'][$registration->ticket()->ID()]     = isset(
151
-                            $template_args['ticket_count'][$registration->ticket()->ID()]
152
-                        )
153
-                            ? $template_args['ticket_count'][$registration->ticket()->ID()] + 1
154
-                            : 1;
155
-                        $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
156
-                            $this->checkout->cart->get_grand_total(),
157
-                            'Ticket',
158
-                            array($registration->ticket()->ID())
159
-                        );
160
-                        $ticket_line_item = is_array($ticket_line_item)
161
-                            ? reset($ticket_line_item)
162
-                            : $ticket_line_item;
163
-                        $template_args['ticket_line_item'][$registration->ticket()->ID()] =
164
-                            $Line_Item_Display->display_line_item($ticket_line_item);
165
-                    }
166
-                    if ($registration->is_primary_registrant()) {
167
-                        $primary_registrant = $registration->reg_url_link();
168
-                    }
169
-                }
170
-            }
171
-            // print_copy_info ?
172
-            if ($primary_registrant && ! $this->checkout->admin_request && count($registrations) > 1) {
173
-                // TODO: add admin option for toggling copy attendee info,
174
-                // then use that value to change $this->_print_copy_info
175
-                $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info
176
-                    ? $this->_copy_attendee_info_form()
177
-                    : $this->_auto_copy_attendee_info();
178
-                // generate hidden input
179
-                if (isset($subsections[$primary_registrant])
180
-                    && $subsections[$primary_registrant] instanceof EE_Form_Section_Proper
181
-                ) {
182
-                    $subsections[$primary_registrant]->add_subsections(
183
-                        $copy_options,
184
-                        'primary_registrant',
185
-                        false
186
-                    );
187
-                }
188
-            }
189
-        }
190
-
191
-        return new EE_Form_Section_Proper(
192
-            array(
193
-                'name'            => $this->reg_form_name(),
194
-                'html_id'         => $this->reg_form_name(),
195
-                'subsections'     => $subsections,
196
-                'layout_strategy' => $this->checkout->admin_request ?
197
-                    new EE_Div_Per_Section_Layout() :
198
-                    new EE_Template_Layout(
199
-                        array(
200
-                            'layout_template_file' => $this->_template, // layout_template
201
-                            'template_args'        => $template_args,
202
-                        )
203
-                    ),
204
-            )
205
-        );
206
-    }
207
-
208
-
209
-    /**
210
-     * @param EE_Registration $registration
211
-     * @return EE_Form_Section_Base
212
-     * @throws EE_Error
213
-     * @throws InvalidArgumentException
214
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
215
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
216
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
217
-     */
218
-    private function _registrations_reg_form(EE_Registration $registration)
219
-    {
220
-        static $attendee_nmbr = 1;
221
-        $form_args = array();
222
-        // verify that registration has valid event
223
-        if ($registration->event() instanceof EE_Event) {
224
-            $question_groups = $registration->event()->question_groups(
225
-                apply_filters(
226
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
227
-                    array(
228
-                        array(
229
-                            'Event.EVT_ID'                     => $registration->event()->ID(),
230
-                            'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false,
231
-                        ),
232
-                        'order_by' => array('QSG_order' => 'ASC'),
233
-                    ),
234
-                    $registration,
235
-                    $this
236
-                )
237
-            );
238
-            if ($question_groups) {
239
-                // array of params to pass to parent constructor
240
-                $form_args = array(
241
-                    'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
242
-                    'html_class'      => 'ee-reg-form-attendee-dv',
243
-                    'html_style'      => $this->checkout->admin_request
244
-                        ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
245
-                        : '',
246
-                    'subsections'     => array(),
247
-                    'layout_strategy' => new EE_Fieldset_Section_Layout(
248
-                        array(
249
-                            'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text',
250
-                            'legend_text'  => sprintf(__('Attendee %d', 'event_espresso'), $attendee_nmbr),
251
-                        )
252
-                    ),
253
-                );
254
-                foreach ($question_groups as $question_group) {
255
-                    if ($question_group instanceof EE_Question_Group) {
256
-                        $form_args['subsections'][$question_group->identifier()] = $this->_question_group_reg_form(
257
-                            $registration,
258
-                            $question_group
259
-                        );
260
-                    }
261
-                }
262
-                // add hidden input
263
-                $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input(
264
-                    $registration
265
-                );
266
-                // if we have question groups for additional attendees, then display the copy options
267
-                $this->_print_copy_info = $attendee_nmbr > 1 ? true : $this->_print_copy_info;
268
-                if ($registration->is_primary_registrant()) {
269
-                    // generate hidden input
270
-                    $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs(
271
-                        $registration
272
-                    );
273
-                }
274
-            }
275
-        }
276
-        $attendee_nmbr++;
277
-        return ! empty($form_args) ? new EE_Form_Section_Proper($form_args) : new EE_Form_Section_HTML();
278
-    }
279
-
280
-
281
-    /**
282
-     * _additional_attendee_reg_info_input
283
-     *
284
-     * @access public
285
-     * @param EE_Registration $registration
286
-     * @param bool            $additional_attendee_reg_info
287
-     * @return    EE_Form_Input_Base
288
-     * @throws \EE_Error
289
-     */
290
-    private function _additional_attendee_reg_info_input(
291
-        EE_Registration $registration,
292
-        $additional_attendee_reg_info = true
293
-    ) {
294
-        // generate hidden input
295
-        return new EE_Hidden_Input(
296
-            array(
297
-                'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
298
-                'default' => $additional_attendee_reg_info,
299
-            )
300
-        );
301
-    }
302
-
303
-
304
-    /**
305
-     * @param EE_Registration   $registration
306
-     * @param EE_Question_Group $question_group
307
-     * @return EE_Form_Section_Proper
308
-     * @throws EE_Error
309
-     * @throws InvalidArgumentException
310
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
311
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
312
-     */
313
-    private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group)
314
-    {
315
-        // array of params to pass to parent constructor
316
-        $form_args = array(
317
-            'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier(),
318
-            'html_class'      => $this->checkout->admin_request
319
-                ? 'form-table ee-reg-form-qstn-grp-dv'
320
-                : 'ee-reg-form-qstn-grp-dv',
321
-            'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-lbl',
322
-            'subsections'     => array(
323
-                'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
324
-            ),
325
-            'layout_strategy' => $this->checkout->admin_request
326
-                ? new EE_Admin_Two_Column_Layout()
327
-                : new EE_Div_Per_Section_Layout(),
328
-        );
329
-        // where params
330
-        $query_params = array('QST_deleted' => 0);
331
-        // don't load admin only questions on the frontend
332
-        if (! $this->checkout->admin_request) {
333
-            $query_params['QST_admin_only'] = array('!=', true);
334
-        }
335
-        $questions = $question_group->get_many_related(
336
-            'Question',
337
-            apply_filters(
338
-                'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params',
339
-                array(
340
-                    $query_params,
341
-                    'order_by' => array(
342
-                        'Question_Group_Question.QGQ_order' => 'ASC',
343
-                    ),
344
-                ),
345
-                $question_group,
346
-                $registration,
347
-                $this
348
-            )
349
-        );
350
-        // filter for additional content before questions
351
-        $form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML(
352
-            apply_filters(
353
-                'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions',
354
-                '',
355
-                $registration,
356
-                $question_group,
357
-                $this
358
-            )
359
-        );
360
-        // loop thru questions
361
-        foreach ($questions as $question) {
362
-            if ($question instanceof EE_Question) {
363
-                $identifier                            = $question->is_system_question()
364
-                    ? $question->system_ID()
365
-                    : $question->ID();
366
-                $form_args['subsections'][$identifier] = $this->reg_form_question($registration, $question);
367
-            }
368
-        }
369
-        $form_args['subsections'] = apply_filters(
370
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array',
371
-            $form_args['subsections'],
372
-            $registration,
373
-            $question_group,
374
-            $this
375
-        );
376
-        // filter for additional content after questions
377
-        $form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML(
378
-            apply_filters(
379
-                'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions',
380
-                '',
381
-                $registration,
382
-                $question_group,
383
-                $this
384
-            )
385
-        );
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 = array();
29
+
30
+	/**
31
+	 * @type array $_required_questions
32
+	 */
33
+	private $_required_questions = array();
34
+
35
+	/**
36
+	 * @type array $_registration_answers
37
+	 */
38
+	private $_registration_answers = array();
39
+
40
+
41
+	/**
42
+	 *    class constructor
43
+	 *
44
+	 * @access    public
45
+	 * @param    EE_Checkout $checkout
46
+	 */
47
+	public function __construct(EE_Checkout $checkout)
48
+	{
49
+		$this->_slug     = 'attendee_information';
50
+		$this->_name     = esc_html__('Attendee Information', 'event_espresso');
51
+		$this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php';
52
+		$this->checkout  = $checkout;
53
+		$this->_reset_success_message();
54
+		$this->set_instructions(
55
+			esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso')
56
+		);
57
+	}
58
+
59
+
60
+	public function translate_js_strings()
61
+	{
62
+		EE_Registry::$i18n_js_strings['required_field']            = esc_html__(
63
+			' is a required question.',
64
+			'event_espresso'
65
+		);
66
+		EE_Registry::$i18n_js_strings['required_multi_field']      = esc_html__(
67
+			' is a required question. Please enter a value for at least one of the options.',
68
+			'event_espresso'
69
+		);
70
+		EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__(
71
+			'Please answer all required questions correctly before proceeding.',
72
+			'event_espresso'
73
+		);
74
+		EE_Registry::$i18n_js_strings['attendee_info_copied']      = sprintf(
75
+			esc_html__(
76
+				'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.',
77
+				'event_espresso'
78
+			),
79
+			'<br/>'
80
+		);
81
+		EE_Registry::$i18n_js_strings['attendee_info_copy_error']  = esc_html__(
82
+			'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.',
83
+			'event_espresso'
84
+		);
85
+		EE_Registry::$i18n_js_strings['enter_valid_email']         = esc_html__(
86
+			'You must enter a valid email address.',
87
+			'event_espresso'
88
+		);
89
+		EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__(
90
+			'You must enter a valid email address and answer all other required questions before you can proceed.',
91
+			'event_espresso'
92
+		);
93
+	}
94
+
95
+
96
+	public function enqueue_styles_and_scripts()
97
+	{
98
+	}
99
+
100
+
101
+	/**
102
+	 * @return boolean
103
+	 */
104
+	public function initialize_reg_step()
105
+	{
106
+		return true;
107
+	}
108
+
109
+
110
+	/**
111
+	 * @return EE_Form_Section_Proper
112
+	 * @throws EE_Error
113
+	 * @throws InvalidArgumentException
114
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
115
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
116
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
117
+	 */
118
+	public function generate_reg_form()
119
+	{
120
+		$this->_print_copy_info = false;
121
+		$primary_registrant     = null;
122
+		// autoload Line_Item_Display classes
123
+		EEH_Autoloader::register_line_item_display_autoloaders();
124
+		$Line_Item_Display = new EE_Line_Item_Display();
125
+		// calculate taxes
126
+		$Line_Item_Display->display_line_item(
127
+			$this->checkout->cart->get_grand_total(),
128
+			array('set_tax_rate' => true)
129
+		);
130
+		/** @var $subsections EE_Form_Section_Proper[] */
131
+		$subsections   = array(
132
+			'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
133
+		);
134
+		$template_args = array(
135
+			'revisit'       => $this->checkout->revisit,
136
+			'registrations' => array(),
137
+			'ticket_count'  => array(),
138
+		);
139
+		// grab the saved registrations from the transaction
140
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
141
+		if ($registrations) {
142
+			foreach ($registrations as $registration) {
143
+				// can this registration be processed during this visit ?
144
+				if ($registration instanceof EE_Registration
145
+					&& $this->checkout->visit_allows_processing_of_this_registration($registration)
146
+				) {
147
+					$subsections[$registration->reg_url_link()] = $this->_registrations_reg_form($registration);
148
+					if (! $this->checkout->admin_request) {
149
+						$template_args['registrations'][$registration->reg_url_link()]    = $registration;
150
+						$template_args['ticket_count'][$registration->ticket()->ID()]     = isset(
151
+							$template_args['ticket_count'][$registration->ticket()->ID()]
152
+						)
153
+							? $template_args['ticket_count'][$registration->ticket()->ID()] + 1
154
+							: 1;
155
+						$ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
156
+							$this->checkout->cart->get_grand_total(),
157
+							'Ticket',
158
+							array($registration->ticket()->ID())
159
+						);
160
+						$ticket_line_item = is_array($ticket_line_item)
161
+							? reset($ticket_line_item)
162
+							: $ticket_line_item;
163
+						$template_args['ticket_line_item'][$registration->ticket()->ID()] =
164
+							$Line_Item_Display->display_line_item($ticket_line_item);
165
+					}
166
+					if ($registration->is_primary_registrant()) {
167
+						$primary_registrant = $registration->reg_url_link();
168
+					}
169
+				}
170
+			}
171
+			// print_copy_info ?
172
+			if ($primary_registrant && ! $this->checkout->admin_request && count($registrations) > 1) {
173
+				// TODO: add admin option for toggling copy attendee info,
174
+				// then use that value to change $this->_print_copy_info
175
+				$copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info
176
+					? $this->_copy_attendee_info_form()
177
+					: $this->_auto_copy_attendee_info();
178
+				// generate hidden input
179
+				if (isset($subsections[$primary_registrant])
180
+					&& $subsections[$primary_registrant] instanceof EE_Form_Section_Proper
181
+				) {
182
+					$subsections[$primary_registrant]->add_subsections(
183
+						$copy_options,
184
+						'primary_registrant',
185
+						false
186
+					);
187
+				}
188
+			}
189
+		}
190
+
191
+		return new EE_Form_Section_Proper(
192
+			array(
193
+				'name'            => $this->reg_form_name(),
194
+				'html_id'         => $this->reg_form_name(),
195
+				'subsections'     => $subsections,
196
+				'layout_strategy' => $this->checkout->admin_request ?
197
+					new EE_Div_Per_Section_Layout() :
198
+					new EE_Template_Layout(
199
+						array(
200
+							'layout_template_file' => $this->_template, // layout_template
201
+							'template_args'        => $template_args,
202
+						)
203
+					),
204
+			)
205
+		);
206
+	}
207
+
208
+
209
+	/**
210
+	 * @param EE_Registration $registration
211
+	 * @return EE_Form_Section_Base
212
+	 * @throws EE_Error
213
+	 * @throws InvalidArgumentException
214
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
215
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
216
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
217
+	 */
218
+	private function _registrations_reg_form(EE_Registration $registration)
219
+	{
220
+		static $attendee_nmbr = 1;
221
+		$form_args = array();
222
+		// verify that registration has valid event
223
+		if ($registration->event() instanceof EE_Event) {
224
+			$question_groups = $registration->event()->question_groups(
225
+				apply_filters(
226
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
227
+					array(
228
+						array(
229
+							'Event.EVT_ID'                     => $registration->event()->ID(),
230
+							'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false,
231
+						),
232
+						'order_by' => array('QSG_order' => 'ASC'),
233
+					),
234
+					$registration,
235
+					$this
236
+				)
237
+			);
238
+			if ($question_groups) {
239
+				// array of params to pass to parent constructor
240
+				$form_args = array(
241
+					'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
242
+					'html_class'      => 'ee-reg-form-attendee-dv',
243
+					'html_style'      => $this->checkout->admin_request
244
+						? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
245
+						: '',
246
+					'subsections'     => array(),
247
+					'layout_strategy' => new EE_Fieldset_Section_Layout(
248
+						array(
249
+							'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text',
250
+							'legend_text'  => sprintf(__('Attendee %d', 'event_espresso'), $attendee_nmbr),
251
+						)
252
+					),
253
+				);
254
+				foreach ($question_groups as $question_group) {
255
+					if ($question_group instanceof EE_Question_Group) {
256
+						$form_args['subsections'][$question_group->identifier()] = $this->_question_group_reg_form(
257
+							$registration,
258
+							$question_group
259
+						);
260
+					}
261
+				}
262
+				// add hidden input
263
+				$form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input(
264
+					$registration
265
+				);
266
+				// if we have question groups for additional attendees, then display the copy options
267
+				$this->_print_copy_info = $attendee_nmbr > 1 ? true : $this->_print_copy_info;
268
+				if ($registration->is_primary_registrant()) {
269
+					// generate hidden input
270
+					$form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs(
271
+						$registration
272
+					);
273
+				}
274
+			}
275
+		}
276
+		$attendee_nmbr++;
277
+		return ! empty($form_args) ? new EE_Form_Section_Proper($form_args) : new EE_Form_Section_HTML();
278
+	}
279
+
280
+
281
+	/**
282
+	 * _additional_attendee_reg_info_input
283
+	 *
284
+	 * @access public
285
+	 * @param EE_Registration $registration
286
+	 * @param bool            $additional_attendee_reg_info
287
+	 * @return    EE_Form_Input_Base
288
+	 * @throws \EE_Error
289
+	 */
290
+	private function _additional_attendee_reg_info_input(
291
+		EE_Registration $registration,
292
+		$additional_attendee_reg_info = true
293
+	) {
294
+		// generate hidden input
295
+		return new EE_Hidden_Input(
296
+			array(
297
+				'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
298
+				'default' => $additional_attendee_reg_info,
299
+			)
300
+		);
301
+	}
302
+
303
+
304
+	/**
305
+	 * @param EE_Registration   $registration
306
+	 * @param EE_Question_Group $question_group
307
+	 * @return EE_Form_Section_Proper
308
+	 * @throws EE_Error
309
+	 * @throws InvalidArgumentException
310
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
311
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
312
+	 */
313
+	private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group)
314
+	{
315
+		// array of params to pass to parent constructor
316
+		$form_args = array(
317
+			'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier(),
318
+			'html_class'      => $this->checkout->admin_request
319
+				? 'form-table ee-reg-form-qstn-grp-dv'
320
+				: 'ee-reg-form-qstn-grp-dv',
321
+			'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-lbl',
322
+			'subsections'     => array(
323
+				'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
324
+			),
325
+			'layout_strategy' => $this->checkout->admin_request
326
+				? new EE_Admin_Two_Column_Layout()
327
+				: new EE_Div_Per_Section_Layout(),
328
+		);
329
+		// where params
330
+		$query_params = array('QST_deleted' => 0);
331
+		// don't load admin only questions on the frontend
332
+		if (! $this->checkout->admin_request) {
333
+			$query_params['QST_admin_only'] = array('!=', true);
334
+		}
335
+		$questions = $question_group->get_many_related(
336
+			'Question',
337
+			apply_filters(
338
+				'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params',
339
+				array(
340
+					$query_params,
341
+					'order_by' => array(
342
+						'Question_Group_Question.QGQ_order' => 'ASC',
343
+					),
344
+				),
345
+				$question_group,
346
+				$registration,
347
+				$this
348
+			)
349
+		);
350
+		// filter for additional content before questions
351
+		$form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML(
352
+			apply_filters(
353
+				'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions',
354
+				'',
355
+				$registration,
356
+				$question_group,
357
+				$this
358
+			)
359
+		);
360
+		// loop thru questions
361
+		foreach ($questions as $question) {
362
+			if ($question instanceof EE_Question) {
363
+				$identifier                            = $question->is_system_question()
364
+					? $question->system_ID()
365
+					: $question->ID();
366
+				$form_args['subsections'][$identifier] = $this->reg_form_question($registration, $question);
367
+			}
368
+		}
369
+		$form_args['subsections'] = apply_filters(
370
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array',
371
+			$form_args['subsections'],
372
+			$registration,
373
+			$question_group,
374
+			$this
375
+		);
376
+		// filter for additional content after questions
377
+		$form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML(
378
+			apply_filters(
379
+				'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions',
380
+				'',
381
+				$registration,
382
+				$question_group,
383
+				$this
384
+			)
385
+		);
386 386
 //		d( $form_args );
387
-        $question_group_reg_form = new EE_Form_Section_Proper($form_args);
388
-        return apply_filters(
389
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
390
-            $question_group_reg_form,
391
-            $registration,
392
-            $question_group,
393
-            $this
394
-        );
395
-    }
396
-
397
-
398
-    /**
399
-     * @access public
400
-     * @param EE_Question_Group $question_group
401
-     * @return    EE_Form_Section_HTML
402
-     */
403
-    private function _question_group_header(EE_Question_Group $question_group)
404
-    {
405
-        $html = '';
406
-        // group_name
407
-        if ($question_group->show_group_name() && $question_group->name() !== '') {
408
-            if ($this->checkout->admin_request) {
409
-                $html .= EEH_HTML::br();
410
-                $html .= EEH_HTML::h3(
411
-                    $question_group->name(),
412
-                    '',
413
-                    'ee-reg-form-qstn-grp-title title',
414
-                    'font-size: 1.3em; padding-left:0;'
415
-                );
416
-            } else {
417
-                $html .= EEH_HTML::h4(
418
-                    $question_group->name(),
419
-                    '',
420
-                    'ee-reg-form-qstn-grp-title section-title'
421
-                );
422
-            }
423
-        }
424
-        // group_desc
425
-        if ($question_group->show_group_desc() && $question_group->desc() !== '') {
426
-            $html .= EEH_HTML::p(
427
-                $question_group->desc(),
428
-                '',
429
-                $this->checkout->admin_request
430
-                    ? 'ee-reg-form-qstn-grp-desc-pg'
431
-                    : 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text'
432
-            );
433
-        }
434
-        return new EE_Form_Section_HTML($html);
435
-    }
436
-
437
-
438
-    /**
439
-     * @access public
440
-     * @return    EE_Form_Section_Proper
441
-     * @throws \EE_Error
442
-     */
443
-    private function _copy_attendee_info_form()
444
-    {
445
-        // array of params to pass to parent constructor
446
-        return new EE_Form_Section_Proper(
447
-            array(
448
-                'subsections'     => $this->_copy_attendee_info_inputs(),
449
-                'layout_strategy' => new EE_Template_Layout(
450
-                    array(
451
-                        'layout_template_file'     => SPCO_REG_STEPS_PATH
452
-                                                      . $this->_slug
453
-                                                      . DS
454
-                                                      . 'copy_attendee_info.template.php',
455
-                        'begin_template_file'      => null,
456
-                        'input_template_file'      => null,
457
-                        'subsection_template_file' => null,
458
-                        'end_template_file'        => null,
459
-                    )
460
-                ),
461
-            )
462
-        );
463
-    }
464
-
465
-
466
-    /**
467
-     * _auto_copy_attendee_info
468
-     *
469
-     * @access public
470
-     * @return EE_Form_Section_HTML
471
-     */
472
-    private function _auto_copy_attendee_info()
473
-    {
474
-        return new EE_Form_Section_HTML(
475
-            EEH_Template::locate_template(
476
-                SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php',
477
-                apply_filters(
478
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
479
-                    array()
480
-                ),
481
-                true,
482
-                true
483
-            )
484
-        );
485
-    }
486
-
487
-
488
-    /**
489
-     * _copy_attendee_info_inputs
490
-     *
491
-     * @access public
492
-     * @return array
493
-     * @throws \EE_Error
494
-     */
495
-    private function _copy_attendee_info_inputs()
496
-    {
497
-        $copy_attendee_info_inputs = array();
498
-        $prev_ticket               = null;
499
-        // grab the saved registrations from the transaction
500
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
501
-        foreach ($registrations as $registration) {
502
-            // for all  attendees other than the primary attendee
503
-            if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
504
-                // if this is a new ticket OR if this is the very first additional attendee after the primary attendee
505
-                if ($registration->ticket()->ID() !== $prev_ticket) {
506
-                    $item_name = $registration->ticket()->name();
507
-                    $item_name .= $registration->ticket()->description() !== ''
508
-                        ? ' - ' . $registration->ticket()->description()
509
-                        : '';
510
-                    $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']'] =
511
-                        new EE_Form_Section_HTML(
512
-                            '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
513
-                        );
514
-                    $prev_ticket = $registration->ticket()->ID();
515
-                }
516
-
517
-                $copy_attendee_info_inputs['spco_copy_attendee_chk[' . $registration->ID() . ']'] =
518
-                    new EE_Checkbox_Multi_Input(
519
-                        array(
520
-                            $registration->ID() => sprintf(
521
-                                esc_html__('Attendee #%s', 'event_espresso'),
522
-                                $registration->count()
523
-                            ),
524
-                        ),
525
-                        array(
526
-                            'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
527
-                            'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
528
-                            'display_html_label_text' => false,
529
-                        )
530
-                    );
531
-            }
532
-        }
533
-        return $copy_attendee_info_inputs;
534
-    }
535
-
536
-
537
-    /**
538
-     * _additional_primary_registrant_inputs
539
-     *
540
-     * @access public
541
-     * @param EE_Registration $registration
542
-     * @return    EE_Form_Input_Base
543
-     * @throws \EE_Error
544
-     */
545
-    private function _additional_primary_registrant_inputs(EE_Registration $registration)
546
-    {
547
-        // generate hidden input
548
-        return new EE_Hidden_Input(
549
-            array(
550
-                'html_id' => 'primary_registrant',
551
-                'default' => $registration->reg_url_link(),
552
-            )
553
-        );
554
-    }
555
-
556
-
557
-    /**
558
-     * @access public
559
-     * @param EE_Registration $registration
560
-     * @param EE_Question     $question
561
-     * @return EE_Form_Input_Base
562
-     * @throws EE_Error
563
-     * @throws InvalidArgumentException
564
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
565
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
566
-     */
567
-    public function reg_form_question(EE_Registration $registration, EE_Question $question)
568
-    {
569
-
570
-        // if this question was for an attendee detail, then check for that answer
571
-        $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value(
572
-            $registration,
573
-            $question->system_ID()
574
-        );
575
-        $answer       = $answer_value === null
576
-            ? EEM_Answer::instance()->get_one(
577
-                array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
578
-            )
579
-            : null;
580
-        // if NOT returning to edit an existing registration
581
-        // OR if this question is for an attendee property
582
-        // OR we still don't have an EE_Answer object
583
-        if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) {
584
-            // create an EE_Answer object for storing everything in
585
-            $answer = EE_Answer::new_instance(array(
586
-                'QST_ID' => $question->ID(),
587
-                'REG_ID' => $registration->ID(),
588
-            ));
589
-        }
590
-        // verify instance
591
-        if ($answer instanceof EE_Answer) {
592
-            if (! empty($answer_value)) {
593
-                $answer->set('ANS_value', $answer_value);
594
-            }
595
-            $answer->cache('Question', $question);
596
-            //remember system ID had a bug where sometimes it could be null
597
-            $answer_cache_id = $question->is_system_question()
598
-                ? $question->system_ID() . '-' . $registration->reg_url_link()
599
-                : $question->ID() . '-' . $registration->reg_url_link();
600
-            $registration->cache('Answer', $answer, $answer_cache_id);
601
-        }
602
-        return $this->_generate_question_input($registration, $question, $answer);
603
-    }
604
-
605
-
606
-    /**
607
-     * @param EE_Registration $registration
608
-     * @param EE_Question     $question
609
-     * @param                 mixed EE_Answer|NULL      $answer
610
-     * @return EE_Form_Input_Base
611
-     * @throws \EE_Error
612
-     */
613
-    private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer)
614
-    {
615
-        $identifier                             = $question->is_system_question()
616
-            ? $question->system_ID()
617
-            : $question->ID();
618
-        $this->_required_questions[$identifier] = $question->required() ? true : false;
619
-        add_filter(
620
-            'FHEE__EE_Question__generate_form_input__country_options',
621
-            array($this, 'use_cached_countries_for_form_input'),
622
-            10,
623
-            4
624
-        );
625
-        add_filter(
626
-            'FHEE__EE_Question__generate_form_input__state_options',
627
-            array($this, 'use_cached_states_for_form_input'),
628
-            10,
629
-            4
630
-        );
631
-        $input_constructor_args                  = array(
632
-            'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
633
-            'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
634
-            'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
635
-            'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
636
-            'html_label_class' => 'ee-reg-qstn',
637
-        );
638
-        $input_constructor_args['html_label_id'] .= '-lbl';
639
-        if ($answer instanceof EE_Answer && $answer->ID()) {
640
-            $input_constructor_args['html_name']     .= '[' . $answer->ID() . ']';
641
-            $input_constructor_args['html_id']       .= '-' . $answer->ID();
642
-            $input_constructor_args['html_label_id'] .= '-' . $answer->ID();
643
-        }
644
-        $form_input = $question->generate_form_input(
645
-            $registration,
646
-            $answer,
647
-            $input_constructor_args
648
-        );
649
-        remove_filter(
650
-            'FHEE__EE_Question__generate_form_input__country_options',
651
-            array($this, 'use_cached_countries_for_form_input')
652
-        );
653
-        remove_filter(
654
-            'FHEE__EE_Question__generate_form_input__state_options',
655
-            array($this, 'use_cached_states_for_form_input')
656
-        );
657
-        return $form_input;
658
-    }
659
-
660
-
661
-    /**
662
-     * Gets the list of countries for the form input
663
-     *
664
-     * @param array|null       $countries_list
665
-     * @param \EE_Question     $question
666
-     * @param \EE_Registration $registration
667
-     * @param \EE_Answer       $answer
668
-     * @return array 2d keys are country IDs, values are their names
669
-     * @throws EE_Error
670
-     * @throws InvalidArgumentException
671
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
672
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
673
-     */
674
-    public function use_cached_countries_for_form_input(
675
-        $countries_list,
676
-        \EE_Question $question = null,
677
-        \EE_Registration $registration = null,
678
-        \EE_Answer $answer = null
679
-    ) {
680
-        $country_options = array('' => '');
681
-        // get possibly cached list of countries
682
-        $countries = $this->checkout->action === 'process_reg_step'
683
-            ? EEM_Country::instance()->get_all_countries()
684
-            : EEM_Country::instance()->get_all_active_countries();
685
-        if (! empty($countries)) {
686
-            foreach ($countries as $country) {
687
-                if ($country instanceof EE_Country) {
688
-                    $country_options[$country->ID()] = $country->name();
689
-                }
690
-            }
691
-        }
692
-        if ($question instanceof EE_Question
693
-            && $registration instanceof EE_Registration) {
694
-            $answer = EEM_Answer::instance()->get_one(
695
-                array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
696
-            );
697
-        } else {
698
-            $answer = EE_Answer::new_instance();
699
-        }
700
-        $country_options = apply_filters(
701
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
702
-            $country_options,
703
-            $this,
704
-            $registration,
705
-            $question,
706
-            $answer
707
-        );
708
-        return $country_options;
709
-    }
710
-
711
-
712
-    /**
713
-     * Gets the list of states for the form input
714
-     *
715
-     * @param array|null       $states_list
716
-     * @param \EE_Question     $question
717
-     * @param \EE_Registration $registration
718
-     * @param \EE_Answer       $answer
719
-     * @return array 2d keys are state IDs, values are their names
720
-     * @throws EE_Error
721
-     * @throws InvalidArgumentException
722
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
723
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
724
-     */
725
-    public function use_cached_states_for_form_input(
726
-        $states_list,
727
-        \EE_Question $question = null,
728
-        \EE_Registration $registration = null,
729
-        \EE_Answer $answer = null
730
-    ) {
731
-        $state_options = array('' => array('' => ''));
732
-        $states        = $this->checkout->action === 'process_reg_step'
733
-            ? EEM_State::instance()->get_all_states()
734
-            : EEM_State::instance()->get_all_active_states();
735
-        if (! empty($states)) {
736
-            foreach ($states as $state) {
737
-                if ($state instanceof EE_State) {
738
-                    $state_options[$state->country()->name()][$state->ID()] = $state->name();
739
-                }
740
-            }
741
-        }
742
-        $state_options = apply_filters(
743
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
744
-            $state_options,
745
-            $this,
746
-            $registration,
747
-            $question,
748
-            $answer
749
-        );
750
-        return $state_options;
751
-    }
752
-
753
-
754
-
755
-
756
-
757
-
758
-    /********************************************************************************************************/
759
-    /****************************************  PROCESS REG STEP  ****************************************/
760
-    /********************************************************************************************************/
761
-    /**
762
-     * @return bool
763
-     * @throws EE_Error
764
-     * @throws InvalidArgumentException
765
-     * @throws ReflectionException
766
-     * @throws RuntimeException
767
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
768
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
769
-     */
770
-    public function process_reg_step()
771
-    {
772
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
773
-        // grab validated data from form
774
-        $valid_data = $this->checkout->current_step->valid_data();
775
-        // EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
776
-        // EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ );
777
-        // if we don't have any $valid_data then something went TERRIBLY WRONG !!!
778
-        if (empty($valid_data)) {
779
-            EE_Error::add_error(
780
-                esc_html__('No valid question responses were received.', 'event_espresso'),
781
-                __FILE__,
782
-                __FUNCTION__,
783
-                __LINE__
784
-            );
785
-            return false;
786
-        }
787
-        if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
788
-            EE_Error::add_error(
789
-                esc_html__(
790
-                    'A valid transaction could not be initiated for processing your registrations.',
791
-                    'event_espresso'
792
-                ),
793
-                __FILE__,
794
-                __FUNCTION__,
795
-                __LINE__
796
-            );
797
-            return false;
798
-        }
799
-        // get cached registrations
800
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
801
-        // verify we got the goods
802
-        if (empty($registrations)) {
803
-            EE_Error::add_error(
804
-                esc_html__('Your form data could not be applied to any valid registrations.', 'event_espresso'),
805
-                __FILE__,
806
-                __FUNCTION__,
807
-                __LINE__
808
-            );
809
-            return false;
810
-        }
811
-        // extract attendee info from form data and save to model objects
812
-        $registrations_processed = $this->_process_registrations($registrations, $valid_data);
813
-        // if first pass thru SPCO,
814
-        // then let's check processed registrations against the total number of tickets in the cart
815
-        if ($registrations_processed === false) {
816
-            // but return immediately if the previous step exited early due to errors
817
-            return false;
818
-        } elseif (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
819
-            // generate a correctly translated string for all possible singular/plural combinations
820
-            if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
821
-                $error_msg = sprintf(
822
-                    esc_html__(
823
-                        'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed',
824
-                        'event_espresso'
825
-                    ),
826
-                    $this->checkout->total_ticket_count,
827
-                    $registrations_processed
828
-                );
829
-            } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) {
830
-                $error_msg = sprintf(
831
-                    esc_html__(
832
-                        'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed',
833
-                        'event_espresso'
834
-                    ),
835
-                    $this->checkout->total_ticket_count,
836
-                    $registrations_processed
837
-                );
838
-            } else {
839
-                $error_msg = sprintf(
840
-                    esc_html__(
841
-                        'There was a total of %1$d tickets in the Event Queue, but %2$ds registrations were processed',
842
-                        'event_espresso'
843
-                    ),
844
-                    $this->checkout->total_ticket_count,
845
-                    $registrations_processed
846
-                );
847
-            }
848
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
849
-            return false;
850
-        }
851
-        // mark this reg step as completed
852
-        $this->set_completed();
853
-        $this->_set_success_message(
854
-            esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso')
855
-        );
856
-        //do action in case a plugin wants to do something with the data submitted in step 1.
857
-        //passes EE_Single_Page_Checkout, and it's posted data
858
-        do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data);
859
-        return true;
860
-    }
861
-
862
-
863
-    /**
864
-     *    _process_registrations
865
-     *
866
-     * @param EE_Registration[] $registrations
867
-     * @param array             $valid_data
868
-     * @return bool|int
869
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
870
-     * @throws EE_Error
871
-     * @throws InvalidArgumentException
872
-     * @throws ReflectionException
873
-     * @throws RuntimeException
874
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
875
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
876
-     */
877
-    private function _process_registrations($registrations = array(), $valid_data = array())
878
-    {
879
-        // load resources and set some defaults
880
-        EE_Registry::instance()->load_model('Attendee');
881
-        // holder for primary registrant attendee object
882
-        $this->checkout->primary_attendee_obj = null;
883
-        // array for tracking reg form data for the primary registrant
884
-        $primary_registrant = array(
885
-            'line_item_id' => null,
886
-        );
887
-        $copy_primary       = false;
888
-        // reg form sections that do not contain inputs
889
-        $non_input_form_sections = array(
890
-            'primary_registrant',
891
-            'additional_attendee_reg_info',
892
-            'spco_copy_attendee_chk',
893
-        );
894
-        // attendee counter
895
-        $att_nmbr = 0;
896
-        // grab the saved registrations from the transaction
897
-        foreach ($registrations as $registration) {
898
-            // verify EE_Registration object
899
-            if (! $registration instanceof EE_Registration) {
900
-                EE_Error::add_error(
901
-                    esc_html__(
902
-                        'An invalid Registration object was discovered when attempting to process your registration information.',
903
-                        'event_espresso'
904
-                    ),
905
-                    __FILE__,
906
-                    __FUNCTION__,
907
-                    __LINE__
908
-                );
909
-                return false;
910
-            }
911
-            /** @var string $reg_url_link */
912
-            $reg_url_link = $registration->reg_url_link();
913
-            // reg_url_link exists ?
914
-            if (! empty($reg_url_link)) {
915
-                // should this registration be processed during this visit ?
916
-                if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
917
-                    // if NOT revisiting, then let's save the registration now,
918
-                    // so that we have a REG_ID to use when generating other objects
919
-                    if (! $this->checkout->revisit) {
920
-                        $registration->save();
921
-                    }
922
-                    /**
923
-                     * This allows plugins to trigger a fail on processing of a
924
-                     * registration for any conditions they may have for it to pass.
925
-                     *
926
-                     * @var bool   if true is returned by the plugin then the
927
-                     *            registration processing is halted.
928
-                     */
929
-                    if (apply_filters(
930
-                        'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
931
-                        false,
932
-                        $att_nmbr,
933
-                        $registration,
934
-                        $registrations,
935
-                        $valid_data,
936
-                        $this
937
-                    )) {
938
-                        return false;
939
-                    }
940
-
941
-                    // Houston, we have a registration!
942
-                    $att_nmbr++;
943
-                    $this->_attendee_data[$reg_url_link] = array();
944
-                    // grab any existing related answer objects
945
-                    $this->_registration_answers = $registration->answers();
946
-                    // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
947
-                    if (isset($valid_data[$reg_url_link])) {
948
-                        // do we need to copy basic info from primary attendee ?
949
-                        $copy_primary = isset($valid_data[$reg_url_link]['additional_attendee_reg_info'])
950
-                                        && absint($valid_data[$reg_url_link]['additional_attendee_reg_info']) === 0
951
-                            ? true
952
-                            : false;
953
-                        // filter form input data for this registration
954
-                        $valid_data[$reg_url_link] = (array)apply_filters(
955
-                            'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
956
-                            $valid_data[$reg_url_link]
957
-                        );
958
-                        if (isset($valid_data['primary_attendee'])) {
959
-                            $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
960
-                                ? $valid_data['primary_attendee']
961
-                                : false;
962
-                            unset($valid_data['primary_attendee']);
963
-                        }
964
-                        // now loop through our array of valid post data && process attendee reg forms
965
-                        foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) {
966
-                            if (! in_array($form_section, $non_input_form_sections)) {
967
-                                foreach ($form_inputs as $form_input => $input_value) {
968
-                                    // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ );
969
-                                    // check for critical inputs
970
-                                    if (! $this->_verify_critical_attendee_details_are_set_and_validate_email(
971
-                                        $form_input,
972
-                                        $input_value
973
-                                    )
974
-                                    ) {
975
-                                        return false;
976
-                                    }
977
-                                    // store a bit of data about the primary attendee
978
-                                    if ($att_nmbr === 1
979
-                                        && ! empty($input_value)
980
-                                        && $reg_url_link === $primary_registrant['line_item_id']
981
-                                    ) {
982
-                                        $primary_registrant[$form_input] = $input_value;
983
-                                    } elseif ($copy_primary
984
-                                        && $input_value === null
985
-                                        && isset($primary_registrant[$form_input])
986
-                                    ) {
987
-                                        $input_value = $primary_registrant[$form_input];
988
-                                    }
989
-                                    // now attempt to save the input data
990
-                                    if (! $this->_save_registration_form_input(
991
-                                        $registration,
992
-                                        $form_input,
993
-                                        $input_value
994
-                                    )
995
-                                    ) {
996
-                                        EE_Error::add_error(
997
-                                            sprintf(
998
-                                                esc_html__(
999
-                                                    'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
1000
-                                                    'event_espresso'
1001
-                                                ),
1002
-                                                $form_input,
1003
-                                                $input_value
1004
-                                            ),
1005
-                                            __FILE__,
1006
-                                            __FUNCTION__,
1007
-                                            __LINE__
1008
-                                        );
1009
-                                        return false;
1010
-                                    }
1011
-                                }
1012
-                            }
1013
-                        }  // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs )
1014
-                    }
1015
-                    //EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ );
1016
-                    // this registration does not require additional attendee information ?
1017
-                    if ($copy_primary
1018
-                        && $att_nmbr > 1
1019
-                        && $this->checkout->primary_attendee_obj instanceof EE_Attendee
1020
-                    ) {
1021
-                        // just copy the primary registrant
1022
-                        $attendee = $this->checkout->primary_attendee_obj;
1023
-                    } else {
1024
-                        // ensure critical details are set for additional attendees
1025
-                        $this->_attendee_data[$reg_url_link] = $att_nmbr > 1
1026
-                            ? $this->_copy_critical_attendee_details_from_primary_registrant(
1027
-                                $this->_attendee_data[$reg_url_link]
1028
-                            )
1029
-                            : $this->_attendee_data[$reg_url_link];
1030
-                        // execute create attendee command (which may return an existing attendee)
1031
-                        $attendee = EE_Registry::instance()->BUS->execute(
1032
-                            new CreateAttendeeCommand(
1033
-                                $this->_attendee_data[$reg_url_link],
1034
-                                $registration
1035
-                            )
1036
-                        );
1037
-                        // who's #1 ?
1038
-                        if ($att_nmbr === 1) {
1039
-                            $this->checkout->primary_attendee_obj = $attendee;
1040
-                        }
1041
-                    }
1042
-                    // EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ );
1043
-                    // add relation to registration, set attendee ID, and cache attendee
1044
-                    $this->_associate_attendee_with_registration($registration, $attendee);
1045
-                    // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ );
1046
-                    if (! $registration->attendee() instanceof EE_Attendee) {
1047
-                        EE_Error::add_error(
1048
-                            sprintf(
1049
-                                esc_html__(
1050
-                                    'Registration %s has an invalid or missing Attendee object.',
1051
-                                    'event_espresso'
1052
-                                ),
1053
-                                $reg_url_link
1054
-                            ),
1055
-                            __FILE__,
1056
-                            __FUNCTION__,
1057
-                            __LINE__
1058
-                        );
1059
-                        return false;
1060
-                    }
1061
-                    /** @type EE_Registration_Processor $registration_processor */
1062
-                    $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1063
-                    // at this point, we should have enough details about the registrant to consider the registration
1064
-                    // NOT incomplete
1065
-                    $registration_processor->toggle_incomplete_registration_status_to_default(
1066
-                        $registration,
1067
-                        false,
1068
-                        new Context(
1069
-                            'spco_reg_step_attendee_information_process_registrations',
1070
-                            esc_html__(
1071
-                                'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
1072
-                                'event_espresso'
1073
-                            )
1074
-                        )
1075
-                    );
1076
-                    // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
1077
-                    // abandoned
1078
-                    $this->checkout->transaction->toggle_failed_transaction_status();
1079
-                    // if we've gotten this far, then let's save what we have
1080
-                    $registration->save();
1081
-                    // add relation between TXN and registration
1082
-                    $this->_associate_registration_with_transaction($registration);
1083
-                }
1084
-            } else {
1085
-                EE_Error::add_error(
1086
-                    esc_html__(
1087
-                        'An invalid or missing line item ID was encountered while attempting to process the registration form.',
1088
-                        'event_espresso'
1089
-                    ),
1090
-                    __FILE__,
1091
-                    __FUNCTION__,
1092
-                    __LINE__
1093
-                );
1094
-                // remove malformed data
1095
-                unset($valid_data[$reg_url_link]);
1096
-                return false;
1097
-            }
1098
-
1099
-        } // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
1100
-        return $att_nmbr;
1101
-    }
1102
-
1103
-
1104
-    /**
1105
-     *    _save_registration_form_input
1106
-     *
1107
-     * @param EE_Registration $registration
1108
-     * @param string          $form_input
1109
-     * @param string          $input_value
1110
-     * @return bool
1111
-     * @throws EE_Error
1112
-     * @throws InvalidArgumentException
1113
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1114
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1115
-     */
1116
-    private function _save_registration_form_input(
1117
-        EE_Registration $registration,
1118
-        $form_input = '',
1119
-        $input_value = ''
1120
-    ) {
1121
-        // \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 );
1122
-        // \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ );
1123
-        // \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ );
1124
-        // allow for plugins to hook in and do their own processing of the form input.
1125
-        // For plugins to bypass normal processing here, they just need to return a boolean value.
1126
-        if (apply_filters(
1127
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
1128
-            false,
1129
-            $registration,
1130
-            $form_input,
1131
-            $input_value,
1132
-            $this
1133
-        )) {
1134
-            return true;
1135
-        }
1136
-        /*
387
+		$question_group_reg_form = new EE_Form_Section_Proper($form_args);
388
+		return apply_filters(
389
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
390
+			$question_group_reg_form,
391
+			$registration,
392
+			$question_group,
393
+			$this
394
+		);
395
+	}
396
+
397
+
398
+	/**
399
+	 * @access public
400
+	 * @param EE_Question_Group $question_group
401
+	 * @return    EE_Form_Section_HTML
402
+	 */
403
+	private function _question_group_header(EE_Question_Group $question_group)
404
+	{
405
+		$html = '';
406
+		// group_name
407
+		if ($question_group->show_group_name() && $question_group->name() !== '') {
408
+			if ($this->checkout->admin_request) {
409
+				$html .= EEH_HTML::br();
410
+				$html .= EEH_HTML::h3(
411
+					$question_group->name(),
412
+					'',
413
+					'ee-reg-form-qstn-grp-title title',
414
+					'font-size: 1.3em; padding-left:0;'
415
+				);
416
+			} else {
417
+				$html .= EEH_HTML::h4(
418
+					$question_group->name(),
419
+					'',
420
+					'ee-reg-form-qstn-grp-title section-title'
421
+				);
422
+			}
423
+		}
424
+		// group_desc
425
+		if ($question_group->show_group_desc() && $question_group->desc() !== '') {
426
+			$html .= EEH_HTML::p(
427
+				$question_group->desc(),
428
+				'',
429
+				$this->checkout->admin_request
430
+					? 'ee-reg-form-qstn-grp-desc-pg'
431
+					: 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text'
432
+			);
433
+		}
434
+		return new EE_Form_Section_HTML($html);
435
+	}
436
+
437
+
438
+	/**
439
+	 * @access public
440
+	 * @return    EE_Form_Section_Proper
441
+	 * @throws \EE_Error
442
+	 */
443
+	private function _copy_attendee_info_form()
444
+	{
445
+		// array of params to pass to parent constructor
446
+		return new EE_Form_Section_Proper(
447
+			array(
448
+				'subsections'     => $this->_copy_attendee_info_inputs(),
449
+				'layout_strategy' => new EE_Template_Layout(
450
+					array(
451
+						'layout_template_file'     => SPCO_REG_STEPS_PATH
452
+													  . $this->_slug
453
+													  . DS
454
+													  . 'copy_attendee_info.template.php',
455
+						'begin_template_file'      => null,
456
+						'input_template_file'      => null,
457
+						'subsection_template_file' => null,
458
+						'end_template_file'        => null,
459
+					)
460
+				),
461
+			)
462
+		);
463
+	}
464
+
465
+
466
+	/**
467
+	 * _auto_copy_attendee_info
468
+	 *
469
+	 * @access public
470
+	 * @return EE_Form_Section_HTML
471
+	 */
472
+	private function _auto_copy_attendee_info()
473
+	{
474
+		return new EE_Form_Section_HTML(
475
+			EEH_Template::locate_template(
476
+				SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php',
477
+				apply_filters(
478
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
479
+					array()
480
+				),
481
+				true,
482
+				true
483
+			)
484
+		);
485
+	}
486
+
487
+
488
+	/**
489
+	 * _copy_attendee_info_inputs
490
+	 *
491
+	 * @access public
492
+	 * @return array
493
+	 * @throws \EE_Error
494
+	 */
495
+	private function _copy_attendee_info_inputs()
496
+	{
497
+		$copy_attendee_info_inputs = array();
498
+		$prev_ticket               = null;
499
+		// grab the saved registrations from the transaction
500
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
501
+		foreach ($registrations as $registration) {
502
+			// for all  attendees other than the primary attendee
503
+			if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
504
+				// if this is a new ticket OR if this is the very first additional attendee after the primary attendee
505
+				if ($registration->ticket()->ID() !== $prev_ticket) {
506
+					$item_name = $registration->ticket()->name();
507
+					$item_name .= $registration->ticket()->description() !== ''
508
+						? ' - ' . $registration->ticket()->description()
509
+						: '';
510
+					$copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']'] =
511
+						new EE_Form_Section_HTML(
512
+							'<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
513
+						);
514
+					$prev_ticket = $registration->ticket()->ID();
515
+				}
516
+
517
+				$copy_attendee_info_inputs['spco_copy_attendee_chk[' . $registration->ID() . ']'] =
518
+					new EE_Checkbox_Multi_Input(
519
+						array(
520
+							$registration->ID() => sprintf(
521
+								esc_html__('Attendee #%s', 'event_espresso'),
522
+								$registration->count()
523
+							),
524
+						),
525
+						array(
526
+							'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
527
+							'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
528
+							'display_html_label_text' => false,
529
+						)
530
+					);
531
+			}
532
+		}
533
+		return $copy_attendee_info_inputs;
534
+	}
535
+
536
+
537
+	/**
538
+	 * _additional_primary_registrant_inputs
539
+	 *
540
+	 * @access public
541
+	 * @param EE_Registration $registration
542
+	 * @return    EE_Form_Input_Base
543
+	 * @throws \EE_Error
544
+	 */
545
+	private function _additional_primary_registrant_inputs(EE_Registration $registration)
546
+	{
547
+		// generate hidden input
548
+		return new EE_Hidden_Input(
549
+			array(
550
+				'html_id' => 'primary_registrant',
551
+				'default' => $registration->reg_url_link(),
552
+			)
553
+		);
554
+	}
555
+
556
+
557
+	/**
558
+	 * @access public
559
+	 * @param EE_Registration $registration
560
+	 * @param EE_Question     $question
561
+	 * @return EE_Form_Input_Base
562
+	 * @throws EE_Error
563
+	 * @throws InvalidArgumentException
564
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
565
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
566
+	 */
567
+	public function reg_form_question(EE_Registration $registration, EE_Question $question)
568
+	{
569
+
570
+		// if this question was for an attendee detail, then check for that answer
571
+		$answer_value = EEM_Answer::instance()->get_attendee_property_answer_value(
572
+			$registration,
573
+			$question->system_ID()
574
+		);
575
+		$answer       = $answer_value === null
576
+			? EEM_Answer::instance()->get_one(
577
+				array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
578
+			)
579
+			: null;
580
+		// if NOT returning to edit an existing registration
581
+		// OR if this question is for an attendee property
582
+		// OR we still don't have an EE_Answer object
583
+		if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) {
584
+			// create an EE_Answer object for storing everything in
585
+			$answer = EE_Answer::new_instance(array(
586
+				'QST_ID' => $question->ID(),
587
+				'REG_ID' => $registration->ID(),
588
+			));
589
+		}
590
+		// verify instance
591
+		if ($answer instanceof EE_Answer) {
592
+			if (! empty($answer_value)) {
593
+				$answer->set('ANS_value', $answer_value);
594
+			}
595
+			$answer->cache('Question', $question);
596
+			//remember system ID had a bug where sometimes it could be null
597
+			$answer_cache_id = $question->is_system_question()
598
+				? $question->system_ID() . '-' . $registration->reg_url_link()
599
+				: $question->ID() . '-' . $registration->reg_url_link();
600
+			$registration->cache('Answer', $answer, $answer_cache_id);
601
+		}
602
+		return $this->_generate_question_input($registration, $question, $answer);
603
+	}
604
+
605
+
606
+	/**
607
+	 * @param EE_Registration $registration
608
+	 * @param EE_Question     $question
609
+	 * @param                 mixed EE_Answer|NULL      $answer
610
+	 * @return EE_Form_Input_Base
611
+	 * @throws \EE_Error
612
+	 */
613
+	private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer)
614
+	{
615
+		$identifier                             = $question->is_system_question()
616
+			? $question->system_ID()
617
+			: $question->ID();
618
+		$this->_required_questions[$identifier] = $question->required() ? true : false;
619
+		add_filter(
620
+			'FHEE__EE_Question__generate_form_input__country_options',
621
+			array($this, 'use_cached_countries_for_form_input'),
622
+			10,
623
+			4
624
+		);
625
+		add_filter(
626
+			'FHEE__EE_Question__generate_form_input__state_options',
627
+			array($this, 'use_cached_states_for_form_input'),
628
+			10,
629
+			4
630
+		);
631
+		$input_constructor_args                  = array(
632
+			'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
633
+			'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
634
+			'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
635
+			'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
636
+			'html_label_class' => 'ee-reg-qstn',
637
+		);
638
+		$input_constructor_args['html_label_id'] .= '-lbl';
639
+		if ($answer instanceof EE_Answer && $answer->ID()) {
640
+			$input_constructor_args['html_name']     .= '[' . $answer->ID() . ']';
641
+			$input_constructor_args['html_id']       .= '-' . $answer->ID();
642
+			$input_constructor_args['html_label_id'] .= '-' . $answer->ID();
643
+		}
644
+		$form_input = $question->generate_form_input(
645
+			$registration,
646
+			$answer,
647
+			$input_constructor_args
648
+		);
649
+		remove_filter(
650
+			'FHEE__EE_Question__generate_form_input__country_options',
651
+			array($this, 'use_cached_countries_for_form_input')
652
+		);
653
+		remove_filter(
654
+			'FHEE__EE_Question__generate_form_input__state_options',
655
+			array($this, 'use_cached_states_for_form_input')
656
+		);
657
+		return $form_input;
658
+	}
659
+
660
+
661
+	/**
662
+	 * Gets the list of countries for the form input
663
+	 *
664
+	 * @param array|null       $countries_list
665
+	 * @param \EE_Question     $question
666
+	 * @param \EE_Registration $registration
667
+	 * @param \EE_Answer       $answer
668
+	 * @return array 2d keys are country IDs, values are their names
669
+	 * @throws EE_Error
670
+	 * @throws InvalidArgumentException
671
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
672
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
673
+	 */
674
+	public function use_cached_countries_for_form_input(
675
+		$countries_list,
676
+		\EE_Question $question = null,
677
+		\EE_Registration $registration = null,
678
+		\EE_Answer $answer = null
679
+	) {
680
+		$country_options = array('' => '');
681
+		// get possibly cached list of countries
682
+		$countries = $this->checkout->action === 'process_reg_step'
683
+			? EEM_Country::instance()->get_all_countries()
684
+			: EEM_Country::instance()->get_all_active_countries();
685
+		if (! empty($countries)) {
686
+			foreach ($countries as $country) {
687
+				if ($country instanceof EE_Country) {
688
+					$country_options[$country->ID()] = $country->name();
689
+				}
690
+			}
691
+		}
692
+		if ($question instanceof EE_Question
693
+			&& $registration instanceof EE_Registration) {
694
+			$answer = EEM_Answer::instance()->get_one(
695
+				array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
696
+			);
697
+		} else {
698
+			$answer = EE_Answer::new_instance();
699
+		}
700
+		$country_options = apply_filters(
701
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
702
+			$country_options,
703
+			$this,
704
+			$registration,
705
+			$question,
706
+			$answer
707
+		);
708
+		return $country_options;
709
+	}
710
+
711
+
712
+	/**
713
+	 * Gets the list of states for the form input
714
+	 *
715
+	 * @param array|null       $states_list
716
+	 * @param \EE_Question     $question
717
+	 * @param \EE_Registration $registration
718
+	 * @param \EE_Answer       $answer
719
+	 * @return array 2d keys are state IDs, values are their names
720
+	 * @throws EE_Error
721
+	 * @throws InvalidArgumentException
722
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
723
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
724
+	 */
725
+	public function use_cached_states_for_form_input(
726
+		$states_list,
727
+		\EE_Question $question = null,
728
+		\EE_Registration $registration = null,
729
+		\EE_Answer $answer = null
730
+	) {
731
+		$state_options = array('' => array('' => ''));
732
+		$states        = $this->checkout->action === 'process_reg_step'
733
+			? EEM_State::instance()->get_all_states()
734
+			: EEM_State::instance()->get_all_active_states();
735
+		if (! empty($states)) {
736
+			foreach ($states as $state) {
737
+				if ($state instanceof EE_State) {
738
+					$state_options[$state->country()->name()][$state->ID()] = $state->name();
739
+				}
740
+			}
741
+		}
742
+		$state_options = apply_filters(
743
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
744
+			$state_options,
745
+			$this,
746
+			$registration,
747
+			$question,
748
+			$answer
749
+		);
750
+		return $state_options;
751
+	}
752
+
753
+
754
+
755
+
756
+
757
+
758
+	/********************************************************************************************************/
759
+	/****************************************  PROCESS REG STEP  ****************************************/
760
+	/********************************************************************************************************/
761
+	/**
762
+	 * @return bool
763
+	 * @throws EE_Error
764
+	 * @throws InvalidArgumentException
765
+	 * @throws ReflectionException
766
+	 * @throws RuntimeException
767
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
768
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
769
+	 */
770
+	public function process_reg_step()
771
+	{
772
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
773
+		// grab validated data from form
774
+		$valid_data = $this->checkout->current_step->valid_data();
775
+		// EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
776
+		// EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ );
777
+		// if we don't have any $valid_data then something went TERRIBLY WRONG !!!
778
+		if (empty($valid_data)) {
779
+			EE_Error::add_error(
780
+				esc_html__('No valid question responses were received.', 'event_espresso'),
781
+				__FILE__,
782
+				__FUNCTION__,
783
+				__LINE__
784
+			);
785
+			return false;
786
+		}
787
+		if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
788
+			EE_Error::add_error(
789
+				esc_html__(
790
+					'A valid transaction could not be initiated for processing your registrations.',
791
+					'event_espresso'
792
+				),
793
+				__FILE__,
794
+				__FUNCTION__,
795
+				__LINE__
796
+			);
797
+			return false;
798
+		}
799
+		// get cached registrations
800
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
801
+		// verify we got the goods
802
+		if (empty($registrations)) {
803
+			EE_Error::add_error(
804
+				esc_html__('Your form data could not be applied to any valid registrations.', 'event_espresso'),
805
+				__FILE__,
806
+				__FUNCTION__,
807
+				__LINE__
808
+			);
809
+			return false;
810
+		}
811
+		// extract attendee info from form data and save to model objects
812
+		$registrations_processed = $this->_process_registrations($registrations, $valid_data);
813
+		// if first pass thru SPCO,
814
+		// then let's check processed registrations against the total number of tickets in the cart
815
+		if ($registrations_processed === false) {
816
+			// but return immediately if the previous step exited early due to errors
817
+			return false;
818
+		} elseif (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
819
+			// generate a correctly translated string for all possible singular/plural combinations
820
+			if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
821
+				$error_msg = sprintf(
822
+					esc_html__(
823
+						'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed',
824
+						'event_espresso'
825
+					),
826
+					$this->checkout->total_ticket_count,
827
+					$registrations_processed
828
+				);
829
+			} elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) {
830
+				$error_msg = sprintf(
831
+					esc_html__(
832
+						'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed',
833
+						'event_espresso'
834
+					),
835
+					$this->checkout->total_ticket_count,
836
+					$registrations_processed
837
+				);
838
+			} else {
839
+				$error_msg = sprintf(
840
+					esc_html__(
841
+						'There was a total of %1$d tickets in the Event Queue, but %2$ds registrations were processed',
842
+						'event_espresso'
843
+					),
844
+					$this->checkout->total_ticket_count,
845
+					$registrations_processed
846
+				);
847
+			}
848
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
849
+			return false;
850
+		}
851
+		// mark this reg step as completed
852
+		$this->set_completed();
853
+		$this->_set_success_message(
854
+			esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso')
855
+		);
856
+		//do action in case a plugin wants to do something with the data submitted in step 1.
857
+		//passes EE_Single_Page_Checkout, and it's posted data
858
+		do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data);
859
+		return true;
860
+	}
861
+
862
+
863
+	/**
864
+	 *    _process_registrations
865
+	 *
866
+	 * @param EE_Registration[] $registrations
867
+	 * @param array             $valid_data
868
+	 * @return bool|int
869
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
870
+	 * @throws EE_Error
871
+	 * @throws InvalidArgumentException
872
+	 * @throws ReflectionException
873
+	 * @throws RuntimeException
874
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
875
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
876
+	 */
877
+	private function _process_registrations($registrations = array(), $valid_data = array())
878
+	{
879
+		// load resources and set some defaults
880
+		EE_Registry::instance()->load_model('Attendee');
881
+		// holder for primary registrant attendee object
882
+		$this->checkout->primary_attendee_obj = null;
883
+		// array for tracking reg form data for the primary registrant
884
+		$primary_registrant = array(
885
+			'line_item_id' => null,
886
+		);
887
+		$copy_primary       = false;
888
+		// reg form sections that do not contain inputs
889
+		$non_input_form_sections = array(
890
+			'primary_registrant',
891
+			'additional_attendee_reg_info',
892
+			'spco_copy_attendee_chk',
893
+		);
894
+		// attendee counter
895
+		$att_nmbr = 0;
896
+		// grab the saved registrations from the transaction
897
+		foreach ($registrations as $registration) {
898
+			// verify EE_Registration object
899
+			if (! $registration instanceof EE_Registration) {
900
+				EE_Error::add_error(
901
+					esc_html__(
902
+						'An invalid Registration object was discovered when attempting to process your registration information.',
903
+						'event_espresso'
904
+					),
905
+					__FILE__,
906
+					__FUNCTION__,
907
+					__LINE__
908
+				);
909
+				return false;
910
+			}
911
+			/** @var string $reg_url_link */
912
+			$reg_url_link = $registration->reg_url_link();
913
+			// reg_url_link exists ?
914
+			if (! empty($reg_url_link)) {
915
+				// should this registration be processed during this visit ?
916
+				if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
917
+					// if NOT revisiting, then let's save the registration now,
918
+					// so that we have a REG_ID to use when generating other objects
919
+					if (! $this->checkout->revisit) {
920
+						$registration->save();
921
+					}
922
+					/**
923
+					 * This allows plugins to trigger a fail on processing of a
924
+					 * registration for any conditions they may have for it to pass.
925
+					 *
926
+					 * @var bool   if true is returned by the plugin then the
927
+					 *            registration processing is halted.
928
+					 */
929
+					if (apply_filters(
930
+						'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
931
+						false,
932
+						$att_nmbr,
933
+						$registration,
934
+						$registrations,
935
+						$valid_data,
936
+						$this
937
+					)) {
938
+						return false;
939
+					}
940
+
941
+					// Houston, we have a registration!
942
+					$att_nmbr++;
943
+					$this->_attendee_data[$reg_url_link] = array();
944
+					// grab any existing related answer objects
945
+					$this->_registration_answers = $registration->answers();
946
+					// unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
947
+					if (isset($valid_data[$reg_url_link])) {
948
+						// do we need to copy basic info from primary attendee ?
949
+						$copy_primary = isset($valid_data[$reg_url_link]['additional_attendee_reg_info'])
950
+										&& absint($valid_data[$reg_url_link]['additional_attendee_reg_info']) === 0
951
+							? true
952
+							: false;
953
+						// filter form input data for this registration
954
+						$valid_data[$reg_url_link] = (array)apply_filters(
955
+							'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
956
+							$valid_data[$reg_url_link]
957
+						);
958
+						if (isset($valid_data['primary_attendee'])) {
959
+							$primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
960
+								? $valid_data['primary_attendee']
961
+								: false;
962
+							unset($valid_data['primary_attendee']);
963
+						}
964
+						// now loop through our array of valid post data && process attendee reg forms
965
+						foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) {
966
+							if (! in_array($form_section, $non_input_form_sections)) {
967
+								foreach ($form_inputs as $form_input => $input_value) {
968
+									// \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ );
969
+									// check for critical inputs
970
+									if (! $this->_verify_critical_attendee_details_are_set_and_validate_email(
971
+										$form_input,
972
+										$input_value
973
+									)
974
+									) {
975
+										return false;
976
+									}
977
+									// store a bit of data about the primary attendee
978
+									if ($att_nmbr === 1
979
+										&& ! empty($input_value)
980
+										&& $reg_url_link === $primary_registrant['line_item_id']
981
+									) {
982
+										$primary_registrant[$form_input] = $input_value;
983
+									} elseif ($copy_primary
984
+										&& $input_value === null
985
+										&& isset($primary_registrant[$form_input])
986
+									) {
987
+										$input_value = $primary_registrant[$form_input];
988
+									}
989
+									// now attempt to save the input data
990
+									if (! $this->_save_registration_form_input(
991
+										$registration,
992
+										$form_input,
993
+										$input_value
994
+									)
995
+									) {
996
+										EE_Error::add_error(
997
+											sprintf(
998
+												esc_html__(
999
+													'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
1000
+													'event_espresso'
1001
+												),
1002
+												$form_input,
1003
+												$input_value
1004
+											),
1005
+											__FILE__,
1006
+											__FUNCTION__,
1007
+											__LINE__
1008
+										);
1009
+										return false;
1010
+									}
1011
+								}
1012
+							}
1013
+						}  // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs )
1014
+					}
1015
+					//EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ );
1016
+					// this registration does not require additional attendee information ?
1017
+					if ($copy_primary
1018
+						&& $att_nmbr > 1
1019
+						&& $this->checkout->primary_attendee_obj instanceof EE_Attendee
1020
+					) {
1021
+						// just copy the primary registrant
1022
+						$attendee = $this->checkout->primary_attendee_obj;
1023
+					} else {
1024
+						// ensure critical details are set for additional attendees
1025
+						$this->_attendee_data[$reg_url_link] = $att_nmbr > 1
1026
+							? $this->_copy_critical_attendee_details_from_primary_registrant(
1027
+								$this->_attendee_data[$reg_url_link]
1028
+							)
1029
+							: $this->_attendee_data[$reg_url_link];
1030
+						// execute create attendee command (which may return an existing attendee)
1031
+						$attendee = EE_Registry::instance()->BUS->execute(
1032
+							new CreateAttendeeCommand(
1033
+								$this->_attendee_data[$reg_url_link],
1034
+								$registration
1035
+							)
1036
+						);
1037
+						// who's #1 ?
1038
+						if ($att_nmbr === 1) {
1039
+							$this->checkout->primary_attendee_obj = $attendee;
1040
+						}
1041
+					}
1042
+					// EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ );
1043
+					// add relation to registration, set attendee ID, and cache attendee
1044
+					$this->_associate_attendee_with_registration($registration, $attendee);
1045
+					// \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ );
1046
+					if (! $registration->attendee() instanceof EE_Attendee) {
1047
+						EE_Error::add_error(
1048
+							sprintf(
1049
+								esc_html__(
1050
+									'Registration %s has an invalid or missing Attendee object.',
1051
+									'event_espresso'
1052
+								),
1053
+								$reg_url_link
1054
+							),
1055
+							__FILE__,
1056
+							__FUNCTION__,
1057
+							__LINE__
1058
+						);
1059
+						return false;
1060
+					}
1061
+					/** @type EE_Registration_Processor $registration_processor */
1062
+					$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1063
+					// at this point, we should have enough details about the registrant to consider the registration
1064
+					// NOT incomplete
1065
+					$registration_processor->toggle_incomplete_registration_status_to_default(
1066
+						$registration,
1067
+						false,
1068
+						new Context(
1069
+							'spco_reg_step_attendee_information_process_registrations',
1070
+							esc_html__(
1071
+								'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
1072
+								'event_espresso'
1073
+							)
1074
+						)
1075
+					);
1076
+					// we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
1077
+					// abandoned
1078
+					$this->checkout->transaction->toggle_failed_transaction_status();
1079
+					// if we've gotten this far, then let's save what we have
1080
+					$registration->save();
1081
+					// add relation between TXN and registration
1082
+					$this->_associate_registration_with_transaction($registration);
1083
+				}
1084
+			} else {
1085
+				EE_Error::add_error(
1086
+					esc_html__(
1087
+						'An invalid or missing line item ID was encountered while attempting to process the registration form.',
1088
+						'event_espresso'
1089
+					),
1090
+					__FILE__,
1091
+					__FUNCTION__,
1092
+					__LINE__
1093
+				);
1094
+				// remove malformed data
1095
+				unset($valid_data[$reg_url_link]);
1096
+				return false;
1097
+			}
1098
+
1099
+		} // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
1100
+		return $att_nmbr;
1101
+	}
1102
+
1103
+
1104
+	/**
1105
+	 *    _save_registration_form_input
1106
+	 *
1107
+	 * @param EE_Registration $registration
1108
+	 * @param string          $form_input
1109
+	 * @param string          $input_value
1110
+	 * @return bool
1111
+	 * @throws EE_Error
1112
+	 * @throws InvalidArgumentException
1113
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1114
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1115
+	 */
1116
+	private function _save_registration_form_input(
1117
+		EE_Registration $registration,
1118
+		$form_input = '',
1119
+		$input_value = ''
1120
+	) {
1121
+		// \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 );
1122
+		// \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ );
1123
+		// \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ );
1124
+		// allow for plugins to hook in and do their own processing of the form input.
1125
+		// For plugins to bypass normal processing here, they just need to return a boolean value.
1126
+		if (apply_filters(
1127
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
1128
+			false,
1129
+			$registration,
1130
+			$form_input,
1131
+			$input_value,
1132
+			$this
1133
+		)) {
1134
+			return true;
1135
+		}
1136
+		/*
1137 1137
          * $answer_cache_id is the key used to find the EE_Answer we want
1138 1138
          * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
1139 1139
          */
1140
-        $answer_cache_id = $this->checkout->reg_url_link
1141
-            ? $form_input . '-' . $registration->reg_url_link()
1142
-            : $form_input;
1143
-        $answer_is_obj   = isset($this->_registration_answers[$answer_cache_id])
1144
-                           && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer
1145
-            ? true
1146
-            : false;
1147
-        //rename form_inputs if they are EE_Attendee properties
1148
-        switch ((string) $form_input) {
1149
-            case 'state':
1150
-            case 'STA_ID':
1151
-                $attendee_property = true;
1152
-                $form_input        = 'STA_ID';
1153
-                break;
1154
-
1155
-            case 'country':
1156
-            case 'CNT_ISO':
1157
-                $attendee_property = true;
1158
-                $form_input        = 'CNT_ISO';
1159
-                break;
1160
-
1161
-            default:
1162
-                $ATT_input = 'ATT_' . $form_input;
1163
-                //EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ );
1164
-                $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false;
1165
-                $form_input        = $attendee_property ? 'ATT_' . $form_input : $form_input;
1166
-        }
1167
-        // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ );
1168
-        // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ );
1169
-        // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ );
1170
-        // if this form input has a corresponding attendee property
1171
-        if ($attendee_property) {
1172
-            $this->_attendee_data[$registration->reg_url_link()][$form_input] = $input_value;
1173
-            if ($answer_is_obj) {
1174
-                // and delete the corresponding answer since we won't be storing this data in that object
1175
-                $registration->_remove_relation_to($this->_registration_answers[$answer_cache_id], 'Answer');
1176
-                $this->_registration_answers[$answer_cache_id]->delete_permanently();
1177
-            }
1178
-            return true;
1179
-        } elseif ($answer_is_obj) {
1180
-            // save this data to the answer object
1181
-            $this->_registration_answers[$answer_cache_id]->set_value($input_value);
1182
-            $result = $this->_registration_answers[$answer_cache_id]->save();
1183
-            return $result !== false ? true : false;
1184
-        } else {
1185
-            foreach ($this->_registration_answers as $answer) {
1186
-                if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) {
1187
-                    $answer->set_value($input_value);
1188
-                    $result = $answer->save();
1189
-                    return $result !== false ? true : false;
1190
-                }
1191
-            }
1192
-        }
1193
-        return false;
1194
-    }
1195
-
1196
-
1197
-    /**
1198
-     *    _verify_critical_attendee_details_are_set
1199
-     *
1200
-     * @param string $form_input
1201
-     * @param string $input_value
1202
-     * @return boolean
1203
-     */
1204
-    private function _verify_critical_attendee_details_are_set_and_validate_email(
1205
-        $form_input = '',
1206
-        $input_value = ''
1207
-    ) {
1208
-        if (empty($input_value)) {
1209
-            // if the form input isn't marked as being required, then just return
1210
-            if (! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) {
1211
-                return true;
1212
-            }
1213
-            switch ($form_input) {
1214
-                case 'fname':
1215
-                    EE_Error::add_error(
1216
-                        esc_html__('First Name is a required value.', 'event_espresso'),
1217
-                        __FILE__,
1218
-                        __FUNCTION__,
1219
-                        __LINE__
1220
-                    );
1221
-                    return false;
1222
-                    break;
1223
-                case 'lname':
1224
-                    EE_Error::add_error(
1225
-                        esc_html__('Last Name is a required value.', 'event_espresso'),
1226
-                        __FILE__,
1227
-                        __FUNCTION__,
1228
-                        __LINE__
1229
-                    );
1230
-                    return false;
1231
-                    break;
1232
-                case 'email':
1233
-                    EE_Error::add_error(
1234
-                        esc_html__('Please enter a valid email address.', 'event_espresso'),
1235
-                        __FILE__,
1236
-                        __FUNCTION__,
1237
-                        __LINE__
1238
-                    );
1239
-                    return false;
1240
-                    break;
1241
-            }
1242
-        }
1243
-        return true;
1244
-    }
1245
-
1246
-
1247
-    /**
1248
-     *    _associate_attendee_with_registration
1249
-     *
1250
-     * @param EE_Registration $registration
1251
-     * @param EE_Attendee     $attendee
1252
-     * @return void
1253
-     * @throws EE_Error
1254
-     * @throws RuntimeException
1255
-     */
1256
-    private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee)
1257
-    {
1258
-        // add relation to attendee
1259
-        $registration->_add_relation_to($attendee, 'Attendee');
1260
-        $registration->set_attendee_id($attendee->ID());
1261
-        $registration->update_cache_after_object_save('Attendee', $attendee);
1262
-    }
1263
-
1264
-
1265
-    /**
1266
-     *    _associate_registration_with_transaction
1267
-     *
1268
-     * @param EE_Registration $registration
1269
-     * @return void
1270
-     * @throws \EE_Error
1271
-     */
1272
-    private function _associate_registration_with_transaction(EE_Registration $registration)
1273
-    {
1274
-        // add relation to registration
1275
-        $this->checkout->transaction->_add_relation_to($registration, 'Registration');
1276
-        $this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
1277
-    }
1278
-
1279
-
1280
-    /**
1281
-     *    _copy_critical_attendee_details_from_primary_registrant
1282
-     *    ensures that all attendees at least have data for first name, last name, and email address
1283
-     *
1284
-     * @param array $attendee_data
1285
-     * @return array
1286
-     * @throws \EE_Error
1287
-     */
1288
-    private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array())
1289
-    {
1290
-        // bare minimum critical details include first name, last name, email address
1291
-        $critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email');
1292
-        // add address info to critical details?
1293
-        if (apply_filters(
1294
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details',
1295
-            false
1296
-        )) {
1297
-            $address_details           = array(
1298
-                'ATT_address',
1299
-                'ATT_address2',
1300
-                'ATT_city',
1301
-                'STA_ID',
1302
-                'CNT_ISO',
1303
-                'ATT_zip',
1304
-                'ATT_phone',
1305
-            );
1306
-            $critical_attendee_details = array_merge($critical_attendee_details, $address_details);
1307
-        }
1308
-        foreach ($critical_attendee_details as $critical_attendee_detail) {
1309
-            if (! isset($attendee_data[$critical_attendee_detail])
1310
-                || empty($attendee_data[$critical_attendee_detail])
1311
-            ) {
1312
-                $attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get(
1313
-                    $critical_attendee_detail
1314
-                );
1315
-            }
1316
-        }
1317
-        return $attendee_data;
1318
-    }
1319
-
1320
-
1321
-    /**
1322
-     *    update_reg_step
1323
-     *    this is the final step after a user  revisits the site to edit their attendee information
1324
-     *    this gets called AFTER the process_reg_step() method above
1325
-     *
1326
-     * @return bool
1327
-     * @throws EE_Error
1328
-     * @throws InvalidArgumentException
1329
-     * @throws ReflectionException
1330
-     * @throws RuntimeException
1331
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1332
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1333
-     */
1334
-    public function update_reg_step()
1335
-    {
1336
-        // save everything
1337
-        if ($this->process_reg_step()) {
1338
-            $this->checkout->redirect     = true;
1339
-            $this->checkout->redirect_url = add_query_arg(
1340
-                array(
1341
-                    'e_reg_url_link' => $this->checkout->reg_url_link,
1342
-                    'revisit'        => true,
1343
-                ),
1344
-                $this->checkout->thank_you_page_url
1345
-            );
1346
-            $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1347
-            return true;
1348
-        }
1349
-        return false;
1350
-    }
1140
+		$answer_cache_id = $this->checkout->reg_url_link
1141
+			? $form_input . '-' . $registration->reg_url_link()
1142
+			: $form_input;
1143
+		$answer_is_obj   = isset($this->_registration_answers[$answer_cache_id])
1144
+						   && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer
1145
+			? true
1146
+			: false;
1147
+		//rename form_inputs if they are EE_Attendee properties
1148
+		switch ((string) $form_input) {
1149
+			case 'state':
1150
+			case 'STA_ID':
1151
+				$attendee_property = true;
1152
+				$form_input        = 'STA_ID';
1153
+				break;
1154
+
1155
+			case 'country':
1156
+			case 'CNT_ISO':
1157
+				$attendee_property = true;
1158
+				$form_input        = 'CNT_ISO';
1159
+				break;
1160
+
1161
+			default:
1162
+				$ATT_input = 'ATT_' . $form_input;
1163
+				//EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ );
1164
+				$attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false;
1165
+				$form_input        = $attendee_property ? 'ATT_' . $form_input : $form_input;
1166
+		}
1167
+		// EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ );
1168
+		// EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ );
1169
+		// EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ );
1170
+		// if this form input has a corresponding attendee property
1171
+		if ($attendee_property) {
1172
+			$this->_attendee_data[$registration->reg_url_link()][$form_input] = $input_value;
1173
+			if ($answer_is_obj) {
1174
+				// and delete the corresponding answer since we won't be storing this data in that object
1175
+				$registration->_remove_relation_to($this->_registration_answers[$answer_cache_id], 'Answer');
1176
+				$this->_registration_answers[$answer_cache_id]->delete_permanently();
1177
+			}
1178
+			return true;
1179
+		} elseif ($answer_is_obj) {
1180
+			// save this data to the answer object
1181
+			$this->_registration_answers[$answer_cache_id]->set_value($input_value);
1182
+			$result = $this->_registration_answers[$answer_cache_id]->save();
1183
+			return $result !== false ? true : false;
1184
+		} else {
1185
+			foreach ($this->_registration_answers as $answer) {
1186
+				if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) {
1187
+					$answer->set_value($input_value);
1188
+					$result = $answer->save();
1189
+					return $result !== false ? true : false;
1190
+				}
1191
+			}
1192
+		}
1193
+		return false;
1194
+	}
1195
+
1196
+
1197
+	/**
1198
+	 *    _verify_critical_attendee_details_are_set
1199
+	 *
1200
+	 * @param string $form_input
1201
+	 * @param string $input_value
1202
+	 * @return boolean
1203
+	 */
1204
+	private function _verify_critical_attendee_details_are_set_and_validate_email(
1205
+		$form_input = '',
1206
+		$input_value = ''
1207
+	) {
1208
+		if (empty($input_value)) {
1209
+			// if the form input isn't marked as being required, then just return
1210
+			if (! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) {
1211
+				return true;
1212
+			}
1213
+			switch ($form_input) {
1214
+				case 'fname':
1215
+					EE_Error::add_error(
1216
+						esc_html__('First Name is a required value.', 'event_espresso'),
1217
+						__FILE__,
1218
+						__FUNCTION__,
1219
+						__LINE__
1220
+					);
1221
+					return false;
1222
+					break;
1223
+				case 'lname':
1224
+					EE_Error::add_error(
1225
+						esc_html__('Last Name is a required value.', 'event_espresso'),
1226
+						__FILE__,
1227
+						__FUNCTION__,
1228
+						__LINE__
1229
+					);
1230
+					return false;
1231
+					break;
1232
+				case 'email':
1233
+					EE_Error::add_error(
1234
+						esc_html__('Please enter a valid email address.', 'event_espresso'),
1235
+						__FILE__,
1236
+						__FUNCTION__,
1237
+						__LINE__
1238
+					);
1239
+					return false;
1240
+					break;
1241
+			}
1242
+		}
1243
+		return true;
1244
+	}
1245
+
1246
+
1247
+	/**
1248
+	 *    _associate_attendee_with_registration
1249
+	 *
1250
+	 * @param EE_Registration $registration
1251
+	 * @param EE_Attendee     $attendee
1252
+	 * @return void
1253
+	 * @throws EE_Error
1254
+	 * @throws RuntimeException
1255
+	 */
1256
+	private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee)
1257
+	{
1258
+		// add relation to attendee
1259
+		$registration->_add_relation_to($attendee, 'Attendee');
1260
+		$registration->set_attendee_id($attendee->ID());
1261
+		$registration->update_cache_after_object_save('Attendee', $attendee);
1262
+	}
1263
+
1264
+
1265
+	/**
1266
+	 *    _associate_registration_with_transaction
1267
+	 *
1268
+	 * @param EE_Registration $registration
1269
+	 * @return void
1270
+	 * @throws \EE_Error
1271
+	 */
1272
+	private function _associate_registration_with_transaction(EE_Registration $registration)
1273
+	{
1274
+		// add relation to registration
1275
+		$this->checkout->transaction->_add_relation_to($registration, 'Registration');
1276
+		$this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
1277
+	}
1278
+
1279
+
1280
+	/**
1281
+	 *    _copy_critical_attendee_details_from_primary_registrant
1282
+	 *    ensures that all attendees at least have data for first name, last name, and email address
1283
+	 *
1284
+	 * @param array $attendee_data
1285
+	 * @return array
1286
+	 * @throws \EE_Error
1287
+	 */
1288
+	private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array())
1289
+	{
1290
+		// bare minimum critical details include first name, last name, email address
1291
+		$critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email');
1292
+		// add address info to critical details?
1293
+		if (apply_filters(
1294
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details',
1295
+			false
1296
+		)) {
1297
+			$address_details           = array(
1298
+				'ATT_address',
1299
+				'ATT_address2',
1300
+				'ATT_city',
1301
+				'STA_ID',
1302
+				'CNT_ISO',
1303
+				'ATT_zip',
1304
+				'ATT_phone',
1305
+			);
1306
+			$critical_attendee_details = array_merge($critical_attendee_details, $address_details);
1307
+		}
1308
+		foreach ($critical_attendee_details as $critical_attendee_detail) {
1309
+			if (! isset($attendee_data[$critical_attendee_detail])
1310
+				|| empty($attendee_data[$critical_attendee_detail])
1311
+			) {
1312
+				$attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get(
1313
+					$critical_attendee_detail
1314
+				);
1315
+			}
1316
+		}
1317
+		return $attendee_data;
1318
+	}
1319
+
1320
+
1321
+	/**
1322
+	 *    update_reg_step
1323
+	 *    this is the final step after a user  revisits the site to edit their attendee information
1324
+	 *    this gets called AFTER the process_reg_step() method above
1325
+	 *
1326
+	 * @return bool
1327
+	 * @throws EE_Error
1328
+	 * @throws InvalidArgumentException
1329
+	 * @throws ReflectionException
1330
+	 * @throws RuntimeException
1331
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1332
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1333
+	 */
1334
+	public function update_reg_step()
1335
+	{
1336
+		// save everything
1337
+		if ($this->process_reg_step()) {
1338
+			$this->checkout->redirect     = true;
1339
+			$this->checkout->redirect_url = add_query_arg(
1340
+				array(
1341
+					'e_reg_url_link' => $this->checkout->reg_url_link,
1342
+					'revisit'        => true,
1343
+				),
1344
+				$this->checkout->thank_you_page_url
1345
+			);
1346
+			$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1347
+			return true;
1348
+		}
1349
+		return false;
1350
+	}
1351 1351
 }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +219 added lines, -219 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('ABSPATH')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 /*
5 5
   Plugin Name:		Event Espresso
@@ -40,243 +40,243 @@  discard block
 block discarded – undo
40 40
  * @since            4.0
41 41
  */
42 42
 if (function_exists('espresso_version')) {
43
-    /**
44
-     *    espresso_duplicate_plugin_error
45
-     *    displays if more than one version of EE is activated at the same time
46
-     */
47
-    function espresso_duplicate_plugin_error()
48
-    {
49
-        ?>
43
+	/**
44
+	 *    espresso_duplicate_plugin_error
45
+	 *    displays if more than one version of EE is activated at the same time
46
+	 */
47
+	function espresso_duplicate_plugin_error()
48
+	{
49
+		?>
50 50
         <div class="error">
51 51
             <p>
52 52
                 <?php echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                ); ?>
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+				); ?>
56 56
             </p>
57 57
         </div>
58 58
         <?php
59
-        espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-    }
59
+		espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+	}
61 61
 
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
65
-    if ( ! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
65
+	if ( ! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                            esc_html__(
79
-                                    'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                                    'event_espresso'
81
-                            ),
82
-                            EE_MIN_PHP_VER_REQUIRED,
83
-                            PHP_VERSION,
84
-                            '<br/>',
85
-                            '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+							esc_html__(
79
+									'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+									'event_espresso'
81
+							),
82
+							EE_MIN_PHP_VER_REQUIRED,
83
+							PHP_VERSION,
84
+							'<br/>',
85
+							'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        /**
97
-         * espresso_version
98
-         * Returns the plugin version
99
-         *
100
-         * @return string
101
-         */
102
-        function espresso_version()
103
-        {
104
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.47.rc.008');
105
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		/**
97
+		 * espresso_version
98
+		 * Returns the plugin version
99
+		 *
100
+		 * @return string
101
+		 */
102
+		function espresso_version()
103
+		{
104
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.47.rc.008');
105
+		}
106 106
 
107
-        // define versions
108
-        define('EVENT_ESPRESSO_VERSION', espresso_version());
109
-        define('EE_MIN_WP_VER_REQUIRED', '4.1');
110
-        define('EE_MIN_WP_VER_RECOMMENDED', '4.4.2');
111
-        define('EE_MIN_PHP_VER_RECOMMENDED', '5.4.44');
112
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
113
-        //used to be DIRECTORY_SEPARATOR, but that caused issues on windows
114
-        if ( ! defined('DS')) {
115
-            define('DS', '/');
116
-        }
117
-        if ( ! defined('PS')) {
118
-            define('PS', PATH_SEPARATOR);
119
-        }
120
-        if ( ! defined('SP')) {
121
-            define('SP', ' ');
122
-        }
123
-        if ( ! defined('EENL')) {
124
-            define('EENL', "\n");
125
-        }
126
-        define('EE_SUPPORT_EMAIL', '[email protected]');
127
-        // define the plugin directory and URL
128
-        define('EE_PLUGIN_BASENAME', plugin_basename(EVENT_ESPRESSO_MAIN_FILE));
129
-        define('EE_PLUGIN_DIR_PATH', plugin_dir_path(EVENT_ESPRESSO_MAIN_FILE));
130
-        define('EE_PLUGIN_DIR_URL', plugin_dir_url(EVENT_ESPRESSO_MAIN_FILE));
131
-        // main root folder paths
132
-        define('EE_ADMIN_PAGES', EE_PLUGIN_DIR_PATH . 'admin_pages' . DS);
133
-        define('EE_CORE', EE_PLUGIN_DIR_PATH . 'core' . DS);
134
-        define('EE_MODULES', EE_PLUGIN_DIR_PATH . 'modules' . DS);
135
-        define('EE_PUBLIC', EE_PLUGIN_DIR_PATH . 'public' . DS);
136
-        define('EE_SHORTCODES', EE_PLUGIN_DIR_PATH . 'shortcodes' . DS);
137
-        define('EE_WIDGETS', EE_PLUGIN_DIR_PATH . 'widgets' . DS);
138
-        define('EE_PAYMENT_METHODS', EE_PLUGIN_DIR_PATH . 'payment_methods' . DS);
139
-        define('EE_CAFF_PATH', EE_PLUGIN_DIR_PATH . 'caffeinated' . DS);
140
-        // core system paths
141
-        define('EE_ADMIN', EE_CORE . 'admin' . DS);
142
-        define('EE_CPTS', EE_CORE . 'CPTs' . DS);
143
-        define('EE_CLASSES', EE_CORE . 'db_classes' . DS);
144
-        define('EE_INTERFACES', EE_CORE . 'interfaces' . DS);
145
-        define('EE_BUSINESS', EE_CORE . 'business' . DS);
146
-        define('EE_MODELS', EE_CORE . 'db_models' . DS);
147
-        define('EE_HELPERS', EE_CORE . 'helpers' . DS);
148
-        define('EE_LIBRARIES', EE_CORE . 'libraries' . DS);
149
-        define('EE_TEMPLATES', EE_CORE . 'templates' . DS);
150
-        define('EE_THIRD_PARTY', EE_CORE . 'third_party_libs' . DS);
151
-        define('EE_GLOBAL_ASSETS', EE_TEMPLATES . 'global_assets' . DS);
152
-        define('EE_FORM_SECTIONS', EE_LIBRARIES . 'form_sections' . DS);
153
-        // gateways
154
-        define('EE_GATEWAYS', EE_MODULES . 'gateways' . DS);
155
-        define('EE_GATEWAYS_URL', EE_PLUGIN_DIR_URL . 'modules' . DS . 'gateways' . DS);
156
-        // asset URL paths
157
-        define('EE_TEMPLATES_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'templates' . DS);
158
-        define('EE_GLOBAL_ASSETS_URL', EE_TEMPLATES_URL . 'global_assets' . DS);
159
-        define('EE_IMAGES_URL', EE_GLOBAL_ASSETS_URL . 'images' . DS);
160
-        define('EE_THIRD_PARTY_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'third_party_libs' . DS);
161
-        define('EE_HELPERS_ASSETS', EE_PLUGIN_DIR_URL . 'core/helpers/assets/');
162
-        define('EE_LIBRARIES_URL', EE_PLUGIN_DIR_URL . 'core/libraries/');
163
-        // define upload paths
164
-        $uploads = wp_upload_dir();
165
-        // define the uploads directory and URL
166
-        define('EVENT_ESPRESSO_UPLOAD_DIR', $uploads['basedir'] . DS . 'espresso' . DS);
167
-        define('EVENT_ESPRESSO_UPLOAD_URL', $uploads['baseurl'] . DS . 'espresso' . DS);
168
-        // define the templates directory and URL
169
-        define('EVENT_ESPRESSO_TEMPLATE_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'templates' . DS);
170
-        define('EVENT_ESPRESSO_TEMPLATE_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'templates' . DS);
171
-        // define the gateway directory and URL
172
-        define('EVENT_ESPRESSO_GATEWAY_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'gateways' . DS);
173
-        define('EVENT_ESPRESSO_GATEWAY_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'gateways' . DS);
174
-        // languages folder/path
175
-        define('EE_LANGUAGES_SAFE_LOC', '..' . DS . 'uploads' . DS . 'espresso' . DS . 'languages' . DS);
176
-        define('EE_LANGUAGES_SAFE_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'languages' . DS);
177
-        //check for dompdf fonts in uploads
178
-        if (file_exists(EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS)) {
179
-            define('DOMPDF_FONT_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS);
180
-        }
181
-        //ajax constants
182
-        define(
183
-                'EE_FRONT_AJAX',
184
-                isset($_REQUEST['ee_front_ajax']) || isset($_REQUEST['data']['ee_front_ajax']) ? true : false
185
-        );
186
-        define(
187
-                'EE_ADMIN_AJAX',
188
-                isset($_REQUEST['ee_admin_ajax']) || isset($_REQUEST['data']['ee_admin_ajax']) ? true : false
189
-        );
190
-        //just a handy constant occasionally needed for finding values representing infinity in the DB
191
-        //you're better to use this than its straight value (currently -1) in case you ever
192
-        //want to change its default value! or find when -1 means infinity
193
-        define('EE_INF_IN_DB', -1);
194
-        define('EE_INF', INF > (float)PHP_INT_MAX ? INF : PHP_INT_MAX);
195
-        define('EE_DEBUG', false);
196
-        // for older WP versions
197
-        if ( ! defined('MONTH_IN_SECONDS')) {
198
-            define('MONTH_IN_SECONDS', DAY_IN_SECONDS * 30);
199
-        }
200
-        /**
201
-         *    espresso_plugin_activation
202
-         *    adds a wp-option to indicate that EE has been activated via the WP admin plugins page
203
-         */
204
-        function espresso_plugin_activation()
205
-        {
206
-            update_option('ee_espresso_activation', true);
207
-        }
107
+		// define versions
108
+		define('EVENT_ESPRESSO_VERSION', espresso_version());
109
+		define('EE_MIN_WP_VER_REQUIRED', '4.1');
110
+		define('EE_MIN_WP_VER_RECOMMENDED', '4.4.2');
111
+		define('EE_MIN_PHP_VER_RECOMMENDED', '5.4.44');
112
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
113
+		//used to be DIRECTORY_SEPARATOR, but that caused issues on windows
114
+		if ( ! defined('DS')) {
115
+			define('DS', '/');
116
+		}
117
+		if ( ! defined('PS')) {
118
+			define('PS', PATH_SEPARATOR);
119
+		}
120
+		if ( ! defined('SP')) {
121
+			define('SP', ' ');
122
+		}
123
+		if ( ! defined('EENL')) {
124
+			define('EENL', "\n");
125
+		}
126
+		define('EE_SUPPORT_EMAIL', '[email protected]');
127
+		// define the plugin directory and URL
128
+		define('EE_PLUGIN_BASENAME', plugin_basename(EVENT_ESPRESSO_MAIN_FILE));
129
+		define('EE_PLUGIN_DIR_PATH', plugin_dir_path(EVENT_ESPRESSO_MAIN_FILE));
130
+		define('EE_PLUGIN_DIR_URL', plugin_dir_url(EVENT_ESPRESSO_MAIN_FILE));
131
+		// main root folder paths
132
+		define('EE_ADMIN_PAGES', EE_PLUGIN_DIR_PATH . 'admin_pages' . DS);
133
+		define('EE_CORE', EE_PLUGIN_DIR_PATH . 'core' . DS);
134
+		define('EE_MODULES', EE_PLUGIN_DIR_PATH . 'modules' . DS);
135
+		define('EE_PUBLIC', EE_PLUGIN_DIR_PATH . 'public' . DS);
136
+		define('EE_SHORTCODES', EE_PLUGIN_DIR_PATH . 'shortcodes' . DS);
137
+		define('EE_WIDGETS', EE_PLUGIN_DIR_PATH . 'widgets' . DS);
138
+		define('EE_PAYMENT_METHODS', EE_PLUGIN_DIR_PATH . 'payment_methods' . DS);
139
+		define('EE_CAFF_PATH', EE_PLUGIN_DIR_PATH . 'caffeinated' . DS);
140
+		// core system paths
141
+		define('EE_ADMIN', EE_CORE . 'admin' . DS);
142
+		define('EE_CPTS', EE_CORE . 'CPTs' . DS);
143
+		define('EE_CLASSES', EE_CORE . 'db_classes' . DS);
144
+		define('EE_INTERFACES', EE_CORE . 'interfaces' . DS);
145
+		define('EE_BUSINESS', EE_CORE . 'business' . DS);
146
+		define('EE_MODELS', EE_CORE . 'db_models' . DS);
147
+		define('EE_HELPERS', EE_CORE . 'helpers' . DS);
148
+		define('EE_LIBRARIES', EE_CORE . 'libraries' . DS);
149
+		define('EE_TEMPLATES', EE_CORE . 'templates' . DS);
150
+		define('EE_THIRD_PARTY', EE_CORE . 'third_party_libs' . DS);
151
+		define('EE_GLOBAL_ASSETS', EE_TEMPLATES . 'global_assets' . DS);
152
+		define('EE_FORM_SECTIONS', EE_LIBRARIES . 'form_sections' . DS);
153
+		// gateways
154
+		define('EE_GATEWAYS', EE_MODULES . 'gateways' . DS);
155
+		define('EE_GATEWAYS_URL', EE_PLUGIN_DIR_URL . 'modules' . DS . 'gateways' . DS);
156
+		// asset URL paths
157
+		define('EE_TEMPLATES_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'templates' . DS);
158
+		define('EE_GLOBAL_ASSETS_URL', EE_TEMPLATES_URL . 'global_assets' . DS);
159
+		define('EE_IMAGES_URL', EE_GLOBAL_ASSETS_URL . 'images' . DS);
160
+		define('EE_THIRD_PARTY_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'third_party_libs' . DS);
161
+		define('EE_HELPERS_ASSETS', EE_PLUGIN_DIR_URL . 'core/helpers/assets/');
162
+		define('EE_LIBRARIES_URL', EE_PLUGIN_DIR_URL . 'core/libraries/');
163
+		// define upload paths
164
+		$uploads = wp_upload_dir();
165
+		// define the uploads directory and URL
166
+		define('EVENT_ESPRESSO_UPLOAD_DIR', $uploads['basedir'] . DS . 'espresso' . DS);
167
+		define('EVENT_ESPRESSO_UPLOAD_URL', $uploads['baseurl'] . DS . 'espresso' . DS);
168
+		// define the templates directory and URL
169
+		define('EVENT_ESPRESSO_TEMPLATE_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'templates' . DS);
170
+		define('EVENT_ESPRESSO_TEMPLATE_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'templates' . DS);
171
+		// define the gateway directory and URL
172
+		define('EVENT_ESPRESSO_GATEWAY_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'gateways' . DS);
173
+		define('EVENT_ESPRESSO_GATEWAY_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'gateways' . DS);
174
+		// languages folder/path
175
+		define('EE_LANGUAGES_SAFE_LOC', '..' . DS . 'uploads' . DS . 'espresso' . DS . 'languages' . DS);
176
+		define('EE_LANGUAGES_SAFE_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'languages' . DS);
177
+		//check for dompdf fonts in uploads
178
+		if (file_exists(EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS)) {
179
+			define('DOMPDF_FONT_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS);
180
+		}
181
+		//ajax constants
182
+		define(
183
+				'EE_FRONT_AJAX',
184
+				isset($_REQUEST['ee_front_ajax']) || isset($_REQUEST['data']['ee_front_ajax']) ? true : false
185
+		);
186
+		define(
187
+				'EE_ADMIN_AJAX',
188
+				isset($_REQUEST['ee_admin_ajax']) || isset($_REQUEST['data']['ee_admin_ajax']) ? true : false
189
+		);
190
+		//just a handy constant occasionally needed for finding values representing infinity in the DB
191
+		//you're better to use this than its straight value (currently -1) in case you ever
192
+		//want to change its default value! or find when -1 means infinity
193
+		define('EE_INF_IN_DB', -1);
194
+		define('EE_INF', INF > (float)PHP_INT_MAX ? INF : PHP_INT_MAX);
195
+		define('EE_DEBUG', false);
196
+		// for older WP versions
197
+		if ( ! defined('MONTH_IN_SECONDS')) {
198
+			define('MONTH_IN_SECONDS', DAY_IN_SECONDS * 30);
199
+		}
200
+		/**
201
+		 *    espresso_plugin_activation
202
+		 *    adds a wp-option to indicate that EE has been activated via the WP admin plugins page
203
+		 */
204
+		function espresso_plugin_activation()
205
+		{
206
+			update_option('ee_espresso_activation', true);
207
+		}
208 208
 
209
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
210
-        /**
211
-         *    espresso_load_error_handling
212
-         *    this function loads EE's class for handling exceptions and errors
213
-         */
214
-        function espresso_load_error_handling()
215
-        {
216
-            // load debugging tools
217
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
218
-                require_once(EE_HELPERS . 'EEH_Debug_Tools.helper.php');
219
-                EEH_Debug_Tools::instance();
220
-            }
221
-            // load error handling
222
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
223
-                require_once(EE_CORE . 'EE_Error.core.php');
224
-            } else {
225
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
226
-            }
227
-        }
209
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
210
+		/**
211
+		 *    espresso_load_error_handling
212
+		 *    this function loads EE's class for handling exceptions and errors
213
+		 */
214
+		function espresso_load_error_handling()
215
+		{
216
+			// load debugging tools
217
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
218
+				require_once(EE_HELPERS . 'EEH_Debug_Tools.helper.php');
219
+				EEH_Debug_Tools::instance();
220
+			}
221
+			// load error handling
222
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
223
+				require_once(EE_CORE . 'EE_Error.core.php');
224
+			} else {
225
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
226
+			}
227
+		}
228 228
 
229
-        /**
230
-         *    espresso_load_required
231
-         *    given a class name and path, this function will load that file or throw an exception
232
-         *
233
-         * @param    string $classname
234
-         * @param    string $full_path_to_file
235
-         * @throws    EE_Error
236
-         */
237
-        function espresso_load_required($classname, $full_path_to_file)
238
-        {
239
-            static $error_handling_loaded = false;
240
-            if ( ! $error_handling_loaded) {
241
-                espresso_load_error_handling();
242
-                $error_handling_loaded = true;
243
-            }
244
-            if (is_readable($full_path_to_file)) {
245
-                require_once($full_path_to_file);
246
-            } else {
247
-                throw new EE_Error (
248
-                        sprintf(
249
-                                esc_html__(
250
-                                        'The %s class file could not be located or is not readable due to file permissions.',
251
-                                        'event_espresso'
252
-                                ),
253
-                                $classname
254
-                        )
255
-                );
256
-            }
257
-        }
229
+		/**
230
+		 *    espresso_load_required
231
+		 *    given a class name and path, this function will load that file or throw an exception
232
+		 *
233
+		 * @param    string $classname
234
+		 * @param    string $full_path_to_file
235
+		 * @throws    EE_Error
236
+		 */
237
+		function espresso_load_required($classname, $full_path_to_file)
238
+		{
239
+			static $error_handling_loaded = false;
240
+			if ( ! $error_handling_loaded) {
241
+				espresso_load_error_handling();
242
+				$error_handling_loaded = true;
243
+			}
244
+			if (is_readable($full_path_to_file)) {
245
+				require_once($full_path_to_file);
246
+			} else {
247
+				throw new EE_Error (
248
+						sprintf(
249
+								esc_html__(
250
+										'The %s class file could not be located or is not readable due to file permissions.',
251
+										'event_espresso'
252
+								),
253
+								$classname
254
+						)
255
+				);
256
+			}
257
+		}
258 258
 
259
-        espresso_load_required('EEH_Base', EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php');
260
-        espresso_load_required('EEH_File', EE_CORE . 'helpers' . DS . 'EEH_File.helper.php');
261
-        espresso_load_required('EE_Bootstrap', EE_CORE . 'EE_Bootstrap.core.php');
262
-        new EE_Bootstrap();
263
-    }
259
+		espresso_load_required('EEH_Base', EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php');
260
+		espresso_load_required('EEH_File', EE_CORE . 'helpers' . DS . 'EEH_File.helper.php');
261
+		espresso_load_required('EE_Bootstrap', EE_CORE . 'EE_Bootstrap.core.php');
262
+		new EE_Bootstrap();
263
+	}
264 264
 }
265 265
 if ( ! function_exists('espresso_deactivate_plugin')) {
266
-    /**
267
-     *    deactivate_plugin
268
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
269
-     *
270
-     * @access public
271
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
272
-     * @return    void
273
-     */
274
-    function espresso_deactivate_plugin($plugin_basename = '')
275
-    {
276
-        if ( ! function_exists('deactivate_plugins')) {
277
-            require_once(ABSPATH . 'wp-admin/includes/plugin.php');
278
-        }
279
-        unset($_GET['activate'], $_REQUEST['activate']);
280
-        deactivate_plugins($plugin_basename);
281
-    }
266
+	/**
267
+	 *    deactivate_plugin
268
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
269
+	 *
270
+	 * @access public
271
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
272
+	 * @return    void
273
+	 */
274
+	function espresso_deactivate_plugin($plugin_basename = '')
275
+	{
276
+		if ( ! function_exists('deactivate_plugins')) {
277
+			require_once(ABSPATH . 'wp-admin/includes/plugin.php');
278
+		}
279
+		unset($_GET['activate'], $_REQUEST['activate']);
280
+		deactivate_plugins($plugin_basename);
281
+	}
282 282
 }
283 283
\ No newline at end of file
Please login to merge, or discard this patch.