Completed
Branch BUG/4.10-migrations-fails (beba67)
by
unknown
16:56 queued 08:55
created
attendee_information/EE_SPCO_Reg_Step_Attendee_Information.class.php 2 patches
Indentation   +1443 added lines, -1443 removed lines patch added patch discarded remove patch
@@ -18,1453 +18,1453 @@
 block discarded – undo
18 18
 class EE_SPCO_Reg_Step_Attendee_Information extends EE_SPCO_Reg_Step
19 19
 {
20 20
 
21
-    /**
22
-     * @type bool $_print_copy_info
23
-     */
24
-    private $_print_copy_info = false;
25
-
26
-    /**
27
-     * @type array $_attendee_data
28
-     */
29
-    private $_attendee_data = array();
30
-
31
-    /**
32
-     * @type array $_required_questions
33
-     */
34
-    private $_required_questions = array();
35
-
36
-    /**
37
-     * @type array $_registration_answers
38
-     */
39
-    private $_registration_answers = array();
21
+	/**
22
+	 * @type bool $_print_copy_info
23
+	 */
24
+	private $_print_copy_info = false;
25
+
26
+	/**
27
+	 * @type array $_attendee_data
28
+	 */
29
+	private $_attendee_data = array();
30
+
31
+	/**
32
+	 * @type array $_required_questions
33
+	 */
34
+	private $_required_questions = array();
35
+
36
+	/**
37
+	 * @type array $_registration_answers
38
+	 */
39
+	private $_registration_answers = array();
40 40
    
41
-    /**
42
-     * @type int $reg_form_count
43
-     */
44
-    protected $reg_form_count = 0;
45
-
46
-
47
-    /**
48
-     *    class constructor
49
-     *
50
-     * @access    public
51
-     * @param    EE_Checkout $checkout
52
-     */
53
-    public function __construct(EE_Checkout $checkout)
54
-    {
55
-        $this->_slug = 'attendee_information';
56
-        $this->_name = esc_html__('Attendee Information', 'event_espresso');
57
-        $this->checkout = $checkout;
58
-        $this->_reset_success_message();
59
-        $this->set_instructions(
60
-            esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso')
61
-        );
62
-    }
63
-
64
-
65
-    public function translate_js_strings()
66
-    {
67
-        EE_Registry::$i18n_js_strings['required_field'] = esc_html__(
68
-            ' is a required question.',
69
-            'event_espresso'
70
-        );
71
-        EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__(
72
-            ' is a required question. Please enter a value for at least one of the options.',
73
-            'event_espresso'
74
-        );
75
-        EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__(
76
-            'Please answer all required questions correctly before proceeding.',
77
-            'event_espresso'
78
-        );
79
-        EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf(
80
-            esc_html_x(
81
-                'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.',
82
-                'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.',
83
-                'event_espresso'
84
-            ),
85
-            '<br/>'
86
-        );
87
-        EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__(
88
-            'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.',
89
-            'event_espresso'
90
-        );
91
-        EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__(
92
-            'You must enter a valid email address.',
93
-            'event_espresso'
94
-        );
95
-        EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__(
96
-            'You must enter a valid email address and answer all other required questions before you can proceed.',
97
-            'event_espresso'
98
-        );
99
-    }
100
-
101
-
102
-    public function enqueue_styles_and_scripts()
103
-    {
104
-    }
105
-
106
-
107
-    /**
108
-     * @return boolean
109
-     */
110
-    public function initialize_reg_step()
111
-    {
112
-        return true;
113
-    }
114
-
115
-
116
-    /**
117
-     * @return EE_Form_Section_Proper
118
-     * @throws DomainException
119
-     * @throws EE_Error
120
-     * @throws InvalidArgumentException
121
-     * @throws ReflectionException
122
-     * @throws EntityNotFoundException
123
-     * @throws InvalidDataTypeException
124
-     * @throws InvalidInterfaceException
125
-     */
126
-    public function generate_reg_form()
127
-    {
128
-        /**
129
-         * @var $reg_config EE_Registration_Config
130
-         */
131
-        $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
41
+	/**
42
+	 * @type int $reg_form_count
43
+	 */
44
+	protected $reg_form_count = 0;
45
+
46
+
47
+	/**
48
+	 *    class constructor
49
+	 *
50
+	 * @access    public
51
+	 * @param    EE_Checkout $checkout
52
+	 */
53
+	public function __construct(EE_Checkout $checkout)
54
+	{
55
+		$this->_slug = 'attendee_information';
56
+		$this->_name = esc_html__('Attendee Information', 'event_espresso');
57
+		$this->checkout = $checkout;
58
+		$this->_reset_success_message();
59
+		$this->set_instructions(
60
+			esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso')
61
+		);
62
+	}
63
+
64
+
65
+	public function translate_js_strings()
66
+	{
67
+		EE_Registry::$i18n_js_strings['required_field'] = esc_html__(
68
+			' is a required question.',
69
+			'event_espresso'
70
+		);
71
+		EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__(
72
+			' is a required question. Please enter a value for at least one of the options.',
73
+			'event_espresso'
74
+		);
75
+		EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__(
76
+			'Please answer all required questions correctly before proceeding.',
77
+			'event_espresso'
78
+		);
79
+		EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf(
80
+			esc_html_x(
81
+				'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.',
82
+				'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.',
83
+				'event_espresso'
84
+			),
85
+			'<br/>'
86
+		);
87
+		EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__(
88
+			'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.',
89
+			'event_espresso'
90
+		);
91
+		EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__(
92
+			'You must enter a valid email address.',
93
+			'event_espresso'
94
+		);
95
+		EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__(
96
+			'You must enter a valid email address and answer all other required questions before you can proceed.',
97
+			'event_espresso'
98
+		);
99
+	}
100
+
101
+
102
+	public function enqueue_styles_and_scripts()
103
+	{
104
+	}
105
+
106
+
107
+	/**
108
+	 * @return boolean
109
+	 */
110
+	public function initialize_reg_step()
111
+	{
112
+		return true;
113
+	}
114
+
115
+
116
+	/**
117
+	 * @return EE_Form_Section_Proper
118
+	 * @throws DomainException
119
+	 * @throws EE_Error
120
+	 * @throws InvalidArgumentException
121
+	 * @throws ReflectionException
122
+	 * @throws EntityNotFoundException
123
+	 * @throws InvalidDataTypeException
124
+	 * @throws InvalidInterfaceException
125
+	 */
126
+	public function generate_reg_form()
127
+	{
128
+		/**
129
+		 * @var $reg_config EE_Registration_Config
130
+		 */
131
+		$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
132 132
  
133
-        $this->_print_copy_info = $reg_config->copyAttendeeInfo();
134
-
135
-        // Init reg forms count.
136
-        $this->reg_form_count = 0;
137
-
138
-        $primary_registrant = null;
139
-        // autoload Line_Item_Display classes
140
-        EEH_Autoloader::register_line_item_display_autoloaders();
141
-        $Line_Item_Display = new EE_Line_Item_Display();
142
-        // calculate taxes
143
-        $Line_Item_Display->display_line_item(
144
-            $this->checkout->cart->get_grand_total(),
145
-            array('set_tax_rate' => true)
146
-        );
147
-        /** @var $subsections EE_Form_Section_Proper[] */
148
-        $extra_inputs_section = $this->reg_step_hidden_inputs();
149
-        $subsections = array(
150
-            'default_hidden_inputs' => $extra_inputs_section,
151
-        );
152
-
153
-        // if this isn't a revisit, and they have the privacy consent box enalbed, add it
154
-        if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
155
-            $extra_inputs_section->add_subsections(
156
-                array(
157
-                    'consent_box' => new EE_Form_Section_Proper(
158
-                        array(
159
-                            'layout_strategy' =>
160
-                                new EE_Template_Layout(
161
-                                    array(
162
-                                        'input_template_file' => SPCO_REG_STEPS_PATH . $this->_slug . '/privacy_consent.template.php',
163
-                                    )
164
-                                ),
165
-                            'subsections'     => array(
166
-                                'consent' => new EE_Checkbox_Multi_Input(
167
-                                    array(
168
-                                        'consent' => $reg_config->getConsentCheckboxLabelText(),
169
-                                    ),
170
-                                    array(
171
-                                        'required'                          => true,
172
-                                        'required_validation_error_message' => esc_html__(
173
-                                            'You must consent to these terms in order to register.',
174
-                                            'event_espresso'
175
-                                        ),
176
-                                        'html_label_text'                   => '',
177
-                                    )
178
-                                ),
179
-                            ),
180
-                        )
181
-                    ),
182
-                ),
183
-                null,
184
-                false
185
-            );
186
-        }
187
-        $template_args = array(
188
-            'revisit'       => $this->checkout->revisit,
189
-            'registrations' => array(),
190
-            'ticket_count'  => array(),
191
-        );
192
-        // grab the saved registrations from the transaction
193
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
194
-        if ($registrations) {
195
-            foreach ($registrations as $registration) {
196
-                // can this registration be processed during this visit ?
197
-                if ($registration instanceof EE_Registration
198
-                    && $this->checkout->visit_allows_processing_of_this_registration($registration)
199
-                ) {
200
-                    $subsections[ $registration->reg_url_link() ] = $this->_registrations_reg_form($registration);
201
-                    $template_args['registrations'][ $registration->reg_url_link() ] = $registration;
202
-                    $template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
203
-                        $template_args['ticket_count'][ $registration->ticket()->ID() ]
204
-                    )
205
-                        ? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
206
-                        : 1;
207
-                    $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
208
-                        $this->checkout->cart->get_grand_total(),
209
-                        'Ticket',
210
-                        array($registration->ticket()->ID())
211
-                    );
212
-                    $ticket_line_item = is_array($ticket_line_item)
213
-                        ? reset($ticket_line_item)
214
-                        : $ticket_line_item;
215
-                    $template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
216
-                        $Line_Item_Display->display_line_item($ticket_line_item);
217
-                    if ($registration->is_primary_registrant()) {
218
-                        $primary_registrant = $registration->reg_url_link();
219
-                    }
220
-                }
221
-            }
222
-
223
-            if ($primary_registrant && count($registrations) > 1) {
224
-                $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info
225
-                    ? $this->_copy_attendee_info_form()
226
-                    : $this->_auto_copy_attendee_info();
227
-                // generate hidden input
228
-                if (isset($subsections[ $primary_registrant ])
229
-                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
230
-                ) {
231
-                    $subsections[ $primary_registrant ]->add_subsections(
232
-                        $copy_options,
233
-                        'primary_registrant',
234
-                        false
235
-                    );
236
-                }
237
-            }
238
-        }
239
-
240
-        // Set the registration form template (default: one form per ticket details table).
241
-        // We decide the template to used based on the number of forms.
242
-        $this->_template = $this->reg_form_count > 1
243
-            ? SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_main.template.php'
244
-            : SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_single.template.php';
245
-
246
-        return new EE_Form_Section_Proper(
247
-            array(
248
-                'name'            => $this->reg_form_name(),
249
-                'html_id'         => $this->reg_form_name(),
250
-                'subsections'     => $subsections,
251
-                'layout_strategy' => new EE_Template_Layout(
252
-                    array(
253
-                        'layout_template_file' => $this->_template, // layout_template
254
-                        'template_args'        => $template_args,
255
-                    )
256
-                ),
257
-            )
258
-        );
259
-    }
260
-
261
-
262
-    /**
263
-     * @param EE_Registration $registration
264
-     * @return EE_Form_Section_Base
265
-     * @throws EE_Error
266
-     * @throws InvalidArgumentException
267
-     * @throws EntityNotFoundException
268
-     * @throws InvalidDataTypeException
269
-     * @throws InvalidInterfaceException
270
-     * @throws ReflectionException
271
-     */
272
-    private function _registrations_reg_form(EE_Registration $registration)
273
-    {
274
-        static $attendee_nmbr = 1;
275
-        $form_args = array();
276
-        // verify that registration has valid event
277
-        if ($registration->event() instanceof EE_Event) {
278
-            $field_name = 'Event_Question_Group.'
279
-                . EEM_Event_Question_Group::instance()->fieldNameForContext(
280
-                    $registration->is_primary_registrant()
281
-                );
282
-            $question_groups = $registration->event()->question_groups(
283
-                apply_filters(
284
-                    // @codingStandardsIgnoreStart
285
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
286
-                    // @codingStandardsIgnoreEnd
287
-                    [
288
-                        [
289
-                            'Event.EVT_ID' => $registration->event()->ID(),
290
-                            $field_name    => true,
291
-                        ],
292
-                        'order_by' => ['QSG_order' => 'ASC'],
293
-                    ],
294
-                    $registration,
295
-                    $this
296
-                )
297
-            );
298
-            if ($question_groups) {
299
-                // array of params to pass to parent constructor
300
-                $form_args = array(
301
-                    'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
302
-                    'html_class'      => 'ee-reg-form-attendee-dv',
303
-                    'html_style'      => $this->checkout->admin_request
304
-                        ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
305
-                        : '',
306
-                    'subsections'     => array(),
307
-                    'layout_strategy' => new EE_Fieldset_Section_Layout(
308
-                        array(
309
-                            'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text',
310
-                            'legend_text'  => sprintf(
311
-                                esc_html_x(
312
-                                    'Attendee %d',
313
-                                    'Attendee 123',
314
-                                    'event_espresso'
315
-                                ),
316
-                                $attendee_nmbr
317
-                            ),
318
-                        )
319
-                    ),
320
-                );
321
-                foreach ($question_groups as $question_group) {
322
-                    if ($question_group instanceof EE_Question_Group) {
323
-                        $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form(
324
-                            $registration,
325
-                            $question_group
326
-                        );
327
-                    }
328
-                }
329
-                // add hidden input
330
-                $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input(
331
-                    $registration
332
-                );
333
-
334
-                /**
335
-                 * @var $reg_config EE_Registration_Config
336
-                 */
337
-                $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
338
-
339
-                // If we have question groups for additional attendees, then display the copy options
340
-                $this->_print_copy_info = apply_filters(
341
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form___printCopyInfo',
342
-                    $attendee_nmbr > 1 ? $reg_config->copyAttendeeInfo() : false,
343
-                    $attendee_nmbr
344
-                );
345
-
346
-                if ($registration->is_primary_registrant()) {
347
-                    // generate hidden input
348
-                    $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs(
349
-                        $registration
350
-                    );
351
-                }
352
-            }
353
-        }
354
-        $attendee_nmbr++;
133
+		$this->_print_copy_info = $reg_config->copyAttendeeInfo();
134
+
135
+		// Init reg forms count.
136
+		$this->reg_form_count = 0;
137
+
138
+		$primary_registrant = null;
139
+		// autoload Line_Item_Display classes
140
+		EEH_Autoloader::register_line_item_display_autoloaders();
141
+		$Line_Item_Display = new EE_Line_Item_Display();
142
+		// calculate taxes
143
+		$Line_Item_Display->display_line_item(
144
+			$this->checkout->cart->get_grand_total(),
145
+			array('set_tax_rate' => true)
146
+		);
147
+		/** @var $subsections EE_Form_Section_Proper[] */
148
+		$extra_inputs_section = $this->reg_step_hidden_inputs();
149
+		$subsections = array(
150
+			'default_hidden_inputs' => $extra_inputs_section,
151
+		);
152
+
153
+		// if this isn't a revisit, and they have the privacy consent box enalbed, add it
154
+		if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
155
+			$extra_inputs_section->add_subsections(
156
+				array(
157
+					'consent_box' => new EE_Form_Section_Proper(
158
+						array(
159
+							'layout_strategy' =>
160
+								new EE_Template_Layout(
161
+									array(
162
+										'input_template_file' => SPCO_REG_STEPS_PATH . $this->_slug . '/privacy_consent.template.php',
163
+									)
164
+								),
165
+							'subsections'     => array(
166
+								'consent' => new EE_Checkbox_Multi_Input(
167
+									array(
168
+										'consent' => $reg_config->getConsentCheckboxLabelText(),
169
+									),
170
+									array(
171
+										'required'                          => true,
172
+										'required_validation_error_message' => esc_html__(
173
+											'You must consent to these terms in order to register.',
174
+											'event_espresso'
175
+										),
176
+										'html_label_text'                   => '',
177
+									)
178
+								),
179
+							),
180
+						)
181
+					),
182
+				),
183
+				null,
184
+				false
185
+			);
186
+		}
187
+		$template_args = array(
188
+			'revisit'       => $this->checkout->revisit,
189
+			'registrations' => array(),
190
+			'ticket_count'  => array(),
191
+		);
192
+		// grab the saved registrations from the transaction
193
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
194
+		if ($registrations) {
195
+			foreach ($registrations as $registration) {
196
+				// can this registration be processed during this visit ?
197
+				if ($registration instanceof EE_Registration
198
+					&& $this->checkout->visit_allows_processing_of_this_registration($registration)
199
+				) {
200
+					$subsections[ $registration->reg_url_link() ] = $this->_registrations_reg_form($registration);
201
+					$template_args['registrations'][ $registration->reg_url_link() ] = $registration;
202
+					$template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
203
+						$template_args['ticket_count'][ $registration->ticket()->ID() ]
204
+					)
205
+						? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
206
+						: 1;
207
+					$ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
208
+						$this->checkout->cart->get_grand_total(),
209
+						'Ticket',
210
+						array($registration->ticket()->ID())
211
+					);
212
+					$ticket_line_item = is_array($ticket_line_item)
213
+						? reset($ticket_line_item)
214
+						: $ticket_line_item;
215
+					$template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
216
+						$Line_Item_Display->display_line_item($ticket_line_item);
217
+					if ($registration->is_primary_registrant()) {
218
+						$primary_registrant = $registration->reg_url_link();
219
+					}
220
+				}
221
+			}
222
+
223
+			if ($primary_registrant && count($registrations) > 1) {
224
+				$copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info
225
+					? $this->_copy_attendee_info_form()
226
+					: $this->_auto_copy_attendee_info();
227
+				// generate hidden input
228
+				if (isset($subsections[ $primary_registrant ])
229
+					&& $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
230
+				) {
231
+					$subsections[ $primary_registrant ]->add_subsections(
232
+						$copy_options,
233
+						'primary_registrant',
234
+						false
235
+					);
236
+				}
237
+			}
238
+		}
239
+
240
+		// Set the registration form template (default: one form per ticket details table).
241
+		// We decide the template to used based on the number of forms.
242
+		$this->_template = $this->reg_form_count > 1
243
+			? SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_main.template.php'
244
+			: SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_single.template.php';
245
+
246
+		return new EE_Form_Section_Proper(
247
+			array(
248
+				'name'            => $this->reg_form_name(),
249
+				'html_id'         => $this->reg_form_name(),
250
+				'subsections'     => $subsections,
251
+				'layout_strategy' => new EE_Template_Layout(
252
+					array(
253
+						'layout_template_file' => $this->_template, // layout_template
254
+						'template_args'        => $template_args,
255
+					)
256
+				),
257
+			)
258
+		);
259
+	}
260
+
261
+
262
+	/**
263
+	 * @param EE_Registration $registration
264
+	 * @return EE_Form_Section_Base
265
+	 * @throws EE_Error
266
+	 * @throws InvalidArgumentException
267
+	 * @throws EntityNotFoundException
268
+	 * @throws InvalidDataTypeException
269
+	 * @throws InvalidInterfaceException
270
+	 * @throws ReflectionException
271
+	 */
272
+	private function _registrations_reg_form(EE_Registration $registration)
273
+	{
274
+		static $attendee_nmbr = 1;
275
+		$form_args = array();
276
+		// verify that registration has valid event
277
+		if ($registration->event() instanceof EE_Event) {
278
+			$field_name = 'Event_Question_Group.'
279
+				. EEM_Event_Question_Group::instance()->fieldNameForContext(
280
+					$registration->is_primary_registrant()
281
+				);
282
+			$question_groups = $registration->event()->question_groups(
283
+				apply_filters(
284
+					// @codingStandardsIgnoreStart
285
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters',
286
+					// @codingStandardsIgnoreEnd
287
+					[
288
+						[
289
+							'Event.EVT_ID' => $registration->event()->ID(),
290
+							$field_name    => true,
291
+						],
292
+						'order_by' => ['QSG_order' => 'ASC'],
293
+					],
294
+					$registration,
295
+					$this
296
+				)
297
+			);
298
+			if ($question_groups) {
299
+				// array of params to pass to parent constructor
300
+				$form_args = array(
301
+					'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
302
+					'html_class'      => 'ee-reg-form-attendee-dv',
303
+					'html_style'      => $this->checkout->admin_request
304
+						? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
305
+						: '',
306
+					'subsections'     => array(),
307
+					'layout_strategy' => new EE_Fieldset_Section_Layout(
308
+						array(
309
+							'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text',
310
+							'legend_text'  => sprintf(
311
+								esc_html_x(
312
+									'Attendee %d',
313
+									'Attendee 123',
314
+									'event_espresso'
315
+								),
316
+								$attendee_nmbr
317
+							),
318
+						)
319
+					),
320
+				);
321
+				foreach ($question_groups as $question_group) {
322
+					if ($question_group instanceof EE_Question_Group) {
323
+						$form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form(
324
+							$registration,
325
+							$question_group
326
+						);
327
+					}
328
+				}
329
+				// add hidden input
330
+				$form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input(
331
+					$registration
332
+				);
333
+
334
+				/**
335
+				 * @var $reg_config EE_Registration_Config
336
+				 */
337
+				$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
338
+
339
+				// If we have question groups for additional attendees, then display the copy options
340
+				$this->_print_copy_info = apply_filters(
341
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form___printCopyInfo',
342
+					$attendee_nmbr > 1 ? $reg_config->copyAttendeeInfo() : false,
343
+					$attendee_nmbr
344
+				);
345
+
346
+				if ($registration->is_primary_registrant()) {
347
+					// generate hidden input
348
+					$form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs(
349
+						$registration
350
+					);
351
+				}
352
+			}
353
+		}
354
+		$attendee_nmbr++;
355 355
         
356
-        // Increment the reg forms number if form is valid.
357
-        if (!empty($form_args)) {
358
-            $this->reg_form_count++;
359
-        }
360
-
361
-        return ! empty($form_args)
362
-            ? new EE_Form_Section_Proper($form_args)
363
-            : new EE_Form_Section_HTML();
364
-    }
365
-
366
-
367
-    /**
368
-     * @param EE_Registration $registration
369
-     * @param bool            $additional_attendee_reg_info
370
-     * @return EE_Form_Input_Base
371
-     * @throws EE_Error
372
-     */
373
-    private function _additional_attendee_reg_info_input(
374
-        EE_Registration $registration,
375
-        $additional_attendee_reg_info = true
376
-    ) {
377
-        // generate hidden input
378
-        return new EE_Hidden_Input(
379
-            array(
380
-                'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
381
-                'default' => $additional_attendee_reg_info,
382
-            )
383
-        );
384
-    }
385
-
386
-
387
-    /**
388
-     * @param EE_Registration   $registration
389
-     * @param EE_Question_Group $question_group
390
-     * @return EE_Form_Section_Proper
391
-     * @throws EE_Error
392
-     * @throws InvalidArgumentException
393
-     * @throws InvalidDataTypeException
394
-     * @throws InvalidInterfaceException
395
-     * @throws ReflectionException
396
-     */
397
-    private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group)
398
-    {
399
-        // array of params to pass to parent constructor
400
-        $form_args = array(
401
-            'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(),
402
-            'html_class'      => $this->checkout->admin_request
403
-                ? 'form-table ee-reg-form-qstn-grp-dv'
404
-                : 'ee-reg-form-qstn-grp-dv',
405
-            'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-'
406
-                                 . $registration->ID() . '-lbl',
407
-            'subsections'     => array(
408
-                'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
409
-            ),
410
-            'layout_strategy' => $this->checkout->admin_request
411
-                ? new EE_Admin_Two_Column_Layout()
412
-                : new EE_Div_Per_Section_Layout(),
413
-        );
414
-        // where params
415
-        $query_params = array('QST_deleted' => 0);
416
-        // don't load admin only questions on the frontend
417
-        if (! $this->checkout->admin_request) {
418
-            $query_params['QST_admin_only'] = array('!=', true);
419
-        }
420
-        $questions = $question_group->get_many_related(
421
-            'Question',
422
-            apply_filters(
423
-                'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params',
424
-                array(
425
-                    $query_params,
426
-                    'order_by' => array(
427
-                        'Question_Group_Question.QGQ_order' => 'ASC',
428
-                    ),
429
-                ),
430
-                $question_group,
431
-                $registration,
432
-                $this
433
-            )
434
-        );
435
-        // filter for additional content before questions
436
-        $form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML(
437
-            apply_filters(
438
-                'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions',
439
-                '',
440
-                $registration,
441
-                $question_group,
442
-                $this
443
-            )
444
-        );
445
-        // loop thru questions
446
-        foreach ($questions as $question) {
447
-            if ($question instanceof EE_Question) {
448
-                $identifier = $question->is_system_question()
449
-                    ? $question->system_ID()
450
-                    : $question->ID();
451
-                $form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question);
452
-            }
453
-        }
454
-        $form_args['subsections'] = apply_filters(
455
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array',
456
-            $form_args['subsections'],
457
-            $registration,
458
-            $question_group,
459
-            $this
460
-        );
461
-        // filter for additional content after questions
462
-        $form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML(
463
-            apply_filters(
464
-                'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions',
465
-                '',
466
-                $registration,
467
-                $question_group,
468
-                $this
469
-            )
470
-        );
471
-        // d($form_args);
472
-        $question_group_reg_form = new EE_Form_Section_Proper($form_args);
473
-        return apply_filters(
474
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
475
-            $question_group_reg_form,
476
-            $registration,
477
-            $question_group,
478
-            $this
479
-        );
480
-    }
481
-
482
-
483
-    /**
484
-     * @param EE_Question_Group $question_group
485
-     * @return    EE_Form_Section_HTML
486
-     */
487
-    private function _question_group_header(EE_Question_Group $question_group)
488
-    {
489
-        $html = '';
490
-        // group_name
491
-        if ($question_group->show_group_name() && $question_group->name() !== '') {
492
-            if ($this->checkout->admin_request) {
493
-                $html .= EEH_HTML::br();
494
-                $html .= EEH_HTML::h3(
495
-                    $question_group->name(),
496
-                    '',
497
-                    'ee-reg-form-qstn-grp-title title',
498
-                    'font-size: 1.3em; padding-left:0;'
499
-                );
500
-            } else {
501
-                $html .= EEH_HTML::h4(
502
-                    $question_group->name(),
503
-                    '',
504
-                    'ee-reg-form-qstn-grp-title section-title'
505
-                );
506
-            }
507
-        }
508
-        // group_desc
509
-        if ($question_group->show_group_desc() && $question_group->desc() !== '') {
510
-            $html .= EEH_HTML::p(
511
-                $question_group->desc(),
512
-                '',
513
-                $this->checkout->admin_request
514
-                    ? 'ee-reg-form-qstn-grp-desc-pg'
515
-                    : 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text'
516
-            );
517
-        }
518
-        return new EE_Form_Section_HTML($html);
519
-    }
520
-
521
-
522
-    /**
523
-     * @return    EE_Form_Section_Proper
524
-     * @throws EE_Error
525
-     * @throws InvalidArgumentException
526
-     * @throws ReflectionException
527
-     * @throws InvalidDataTypeException
528
-     * @throws InvalidInterfaceException
529
-     */
530
-    private function _copy_attendee_info_form()
531
-    {
532
-        // array of params to pass to parent constructor
533
-        return new EE_Form_Section_Proper(
534
-            array(
535
-                'subsections'     => $this->_copy_attendee_info_inputs(),
536
-                'layout_strategy' => new EE_Template_Layout(
537
-                    array(
538
-                        'layout_template_file'     => SPCO_REG_STEPS_PATH
539
-                                                      . $this->_slug
540
-                                                      . '/copy_attendee_info.template.php',
541
-                        'begin_template_file'      => null,
542
-                        'input_template_file'      => null,
543
-                        'subsection_template_file' => null,
544
-                        'end_template_file'        => null,
545
-                    )
546
-                ),
547
-            )
548
-        );
549
-    }
550
-
551
-
552
-    /**
553
-     * @return EE_Form_Section_HTML
554
-     * @throws DomainException
555
-     * @throws InvalidArgumentException
556
-     * @throws InvalidDataTypeException
557
-     * @throws InvalidInterfaceException
558
-     */
559
-    private function _auto_copy_attendee_info()
560
-    {
561
-        return new EE_Form_Section_HTML(
562
-            EEH_Template::locate_template(
563
-                SPCO_REG_STEPS_PATH . $this->_slug . '/_auto_copy_attendee_info.template.php',
564
-                apply_filters(
565
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
566
-                    array()
567
-                ),
568
-                true,
569
-                true
570
-            )
571
-        );
572
-    }
573
-
574
-
575
-    /**
576
-     * @return array
577
-     * @throws EE_Error
578
-     * @throws InvalidArgumentException
579
-     * @throws ReflectionException
580
-     * @throws InvalidDataTypeException
581
-     * @throws InvalidInterfaceException
582
-     */
583
-    private function _copy_attendee_info_inputs()
584
-    {
585
-        $copy_attendee_info_inputs = array();
586
-        $prev_ticket = null;
587
-        // grab the saved registrations from the transaction
588
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
589
-        foreach ($registrations as $registration) {
590
-            // for all  attendees other than the primary attendee
591
-            if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
592
-                // if this is a new ticket OR if this is the very first additional attendee after the primary attendee
593
-                if ($registration->ticket()->ID() !== $prev_ticket) {
594
-                    $item_name = $registration->ticket()->name();
595
-                    $item_name .= $registration->ticket()->description() !== ''
596
-                        ? ' - ' . $registration->ticket()->description()
597
-                        : '';
598
-                    $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID(
599
-                    ) . ']' ] =
600
-                        new EE_Form_Section_HTML(
601
-                            '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
602
-                        );
603
-                    $prev_ticket = $registration->ticket()->ID();
604
-                }
605
-
606
-                $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] =
607
-                    new EE_Checkbox_Multi_Input(
608
-                        array(
609
-                            $registration->ID() => sprintf(
610
-                                esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'),
611
-                                $registration->count()
612
-                            ),
613
-                        ),
614
-                        array(
615
-                            'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
616
-                            'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
617
-                            'display_html_label_text' => false,
618
-                        )
619
-                    );
620
-            }
621
-        }
622
-        return $copy_attendee_info_inputs;
623
-    }
624
-
625
-
626
-    /**
627
-     * @param EE_Registration $registration
628
-     * @return    EE_Form_Input_Base
629
-     * @throws EE_Error
630
-     */
631
-    private function _additional_primary_registrant_inputs(EE_Registration $registration)
632
-    {
633
-        // generate hidden input
634
-        return new EE_Hidden_Input(
635
-            array(
636
-                'html_id' => 'primary_registrant',
637
-                'default' => $registration->reg_url_link(),
638
-            )
639
-        );
640
-    }
641
-
642
-
643
-    /**
644
-     * @param EE_Registration $registration
645
-     * @param EE_Question     $question
646
-     * @return EE_Form_Input_Base
647
-     * @throws EE_Error
648
-     * @throws InvalidArgumentException
649
-     * @throws InvalidDataTypeException
650
-     * @throws InvalidInterfaceException
651
-     * @throws ReflectionException
652
-     */
653
-    public function reg_form_question(EE_Registration $registration, EE_Question $question)
654
-    {
655
-
656
-        // if this question was for an attendee detail, then check for that answer
657
-        $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value(
658
-            $registration,
659
-            $question->system_ID()
660
-        );
661
-        $answer = $answer_value === null
662
-            ? EEM_Answer::instance()->get_one(
663
-                array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
664
-            )
665
-            : null;
666
-        // if NOT returning to edit an existing registration
667
-        // OR if this question is for an attendee property
668
-        // OR we still don't have an EE_Answer object
669
-        if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) {
670
-            // create an EE_Answer object for storing everything in
671
-            $answer = EE_Answer::new_instance(
672
-                array(
673
-                    'QST_ID' => $question->ID(),
674
-                    'REG_ID' => $registration->ID(),
675
-                )
676
-            );
677
-        }
678
-        // verify instance
679
-        if ($answer instanceof EE_Answer) {
680
-            if (! empty($answer_value)) {
681
-                $answer->set('ANS_value', $answer_value);
682
-            }
683
-            $answer->cache('Question', $question);
684
-            // remember system ID had a bug where sometimes it could be null
685
-            $answer_cache_id = $question->is_system_question()
686
-                ? $question->system_ID() . '-' . $registration->reg_url_link()
687
-                : $question->ID() . '-' . $registration->reg_url_link();
688
-            $registration->cache('Answer', $answer, $answer_cache_id);
689
-        }
690
-        return $this->_generate_question_input($registration, $question, $answer);
691
-    }
692
-
693
-
694
-    /**
695
-     * @param EE_Registration $registration
696
-     * @param EE_Question     $question
697
-     * @param                 $answer
698
-     * @return EE_Form_Input_Base
699
-     * @throws EE_Error
700
-     * @throws InvalidArgumentException
701
-     * @throws ReflectionException
702
-     * @throws InvalidDataTypeException
703
-     * @throws InvalidInterfaceException
704
-     */
705
-    private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer)
706
-    {
707
-        $identifier = $question->is_system_question()
708
-            ? $question->system_ID()
709
-            : $question->ID();
710
-        $this->_required_questions[ $identifier ] = $question->required() ? true : false;
711
-        add_filter(
712
-            'FHEE__EE_Question__generate_form_input__country_options',
713
-            array($this, 'use_cached_countries_for_form_input'),
714
-            10,
715
-            4
716
-        );
717
-        add_filter(
718
-            'FHEE__EE_Question__generate_form_input__state_options',
719
-            array($this, 'use_cached_states_for_form_input'),
720
-            10,
721
-            4
722
-        );
723
-        $input_constructor_args = array(
724
-            'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
725
-            'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
726
-            'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
727
-            'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
728
-            'html_label_class' => 'ee-reg-qstn',
729
-        );
730
-        $input_constructor_args['html_label_id'] .= '-lbl';
731
-        if ($answer instanceof EE_Answer && $answer->ID()) {
732
-            $input_constructor_args['html_name'] .= '[' . $answer->ID() . ']';
733
-            $input_constructor_args['html_id'] .= '-' . $answer->ID();
734
-            $input_constructor_args['html_label_id'] .= '-' . $answer->ID();
735
-        }
736
-        $form_input = $question->generate_form_input(
737
-            $registration,
738
-            $answer,
739
-            $input_constructor_args
740
-        );
741
-        remove_filter(
742
-            'FHEE__EE_Question__generate_form_input__country_options',
743
-            array($this, 'use_cached_countries_for_form_input')
744
-        );
745
-        remove_filter(
746
-            'FHEE__EE_Question__generate_form_input__state_options',
747
-            array($this, 'use_cached_states_for_form_input')
748
-        );
749
-        return $form_input;
750
-    }
751
-
752
-
753
-    /**
754
-     * Gets the list of countries for the form input
755
-     *
756
-     * @param array|null      $countries_list
757
-     * @param EE_Question     $question
758
-     * @param EE_Registration $registration
759
-     * @param EE_Answer       $answer
760
-     * @return array 2d keys are country IDs, values are their names
761
-     * @throws EE_Error
762
-     * @throws InvalidArgumentException
763
-     * @throws InvalidDataTypeException
764
-     * @throws InvalidInterfaceException
765
-     * @throws ReflectionException
766
-     */
767
-    public function use_cached_countries_for_form_input(
768
-        $countries_list,
769
-        EE_Question $question = null,
770
-        EE_Registration $registration = null,
771
-        EE_Answer $answer = null
772
-    ) {
773
-        $country_options = array('' => '');
774
-        // get possibly cached list of countries
775
-        $countries = $this->checkout->action === 'process_reg_step'
776
-            ? EEM_Country::instance()->get_all_countries()
777
-            : EEM_Country::instance()->get_all_active_countries();
778
-        if (! empty($countries)) {
779
-            foreach ($countries as $country) {
780
-                if ($country instanceof EE_Country) {
781
-                    $country_options[ $country->ID() ] = $country->name();
782
-                }
783
-            }
784
-        }
785
-        if ($question instanceof EE_Question && $registration instanceof EE_Registration) {
786
-            $answer = EEM_Answer::instance()->get_one(
787
-                array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
788
-            );
789
-        } else {
790
-            $answer = EE_Answer::new_instance();
791
-        }
792
-        $country_options = apply_filters(
793
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
794
-            $country_options,
795
-            $this,
796
-            $registration,
797
-            $question,
798
-            $answer
799
-        );
800
-        return $country_options;
801
-    }
802
-
803
-
804
-    /**
805
-     * Gets the list of states for the form input
806
-     *
807
-     * @param array|null      $states_list
808
-     * @param EE_Question     $question
809
-     * @param EE_Registration $registration
810
-     * @param EE_Answer       $answer
811
-     * @return array 2d keys are state IDs, values are their names
812
-     * @throws EE_Error
813
-     * @throws InvalidArgumentException
814
-     * @throws InvalidDataTypeException
815
-     * @throws InvalidInterfaceException
816
-     * @throws ReflectionException
817
-     */
818
-    public function use_cached_states_for_form_input(
819
-        $states_list,
820
-        EE_Question $question = null,
821
-        EE_Registration $registration = null,
822
-        EE_Answer $answer = null
823
-    ) {
824
-        $state_options = array('' => array('' => ''));
825
-        $states = $this->checkout->action === 'process_reg_step'
826
-            ? EEM_State::instance()->get_all_states()
827
-            : EEM_State::instance()->get_all_active_states();
828
-        if (! empty($states)) {
829
-            foreach ($states as $state) {
830
-                if ($state instanceof EE_State) {
831
-                    $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
832
-                }
833
-            }
834
-        }
835
-        $state_options = apply_filters(
836
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
837
-            $state_options,
838
-            $this,
839
-            $registration,
840
-            $question,
841
-            $answer
842
-        );
843
-        return $state_options;
844
-    }
845
-
846
-
847
-    /********************************************************************************************************/
848
-    /****************************************  PROCESS REG STEP  ****************************************/
849
-    /********************************************************************************************************/
850
-
851
-
852
-    /**
853
-     * @return bool
854
-     * @throws EE_Error
855
-     * @throws InvalidArgumentException
856
-     * @throws ReflectionException
857
-     * @throws RuntimeException
858
-     * @throws InvalidDataTypeException
859
-     * @throws InvalidInterfaceException
860
-     */
861
-    public function process_reg_step()
862
-    {
863
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
864
-        // grab validated data from form
865
-        $valid_data = $this->checkout->current_step->valid_data();
866
-        // EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
867
-        // EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ );
868
-        // if we don't have any $valid_data then something went TERRIBLY WRONG !!!
869
-        if (empty($valid_data)) {
870
-            EE_Error::add_error(
871
-                esc_html__('No valid question responses were received.', 'event_espresso'),
872
-                __FILE__,
873
-                __FUNCTION__,
874
-                __LINE__
875
-            );
876
-            return false;
877
-        }
878
-        if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
879
-            EE_Error::add_error(
880
-                esc_html__(
881
-                    'A valid transaction could not be initiated for processing your registrations.',
882
-                    'event_espresso'
883
-                ),
884
-                __FILE__,
885
-                __FUNCTION__,
886
-                __LINE__
887
-            );
888
-            return false;
889
-        }
890
-        // get cached registrations
891
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
892
-        // verify we got the goods
893
-        if (empty($registrations)) {
894
-            // combine the old translated string with a new one, in order to not break translations
895
-            $error_message = esc_html__(
896
-                'Your form data could not be applied to any valid registrations.',
897
-                'event_espresso'
898
-            )
899
-            . sprintf(
900
-                esc_html_x(
901
-                    '%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.',
902
-                    '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.',
903
-                    'event_espresso'
904
-                ),
905
-                '<a href="' . get_post_type_archive_link('espresso_events') . '" >',
906
-                '</a>',
907
-                '<br />'
908
-            );
909
-            EE_Error::add_error(
910
-                $error_message,
911
-                __FILE__,
912
-                __FUNCTION__,
913
-                __LINE__
914
-            );
915
-            return false;
916
-        }
917
-        // extract attendee info from form data and save to model objects
918
-        $registrations_processed = $this->_process_registrations($registrations, $valid_data);
919
-        // if first pass thru SPCO,
920
-        // then let's check processed registrations against the total number of tickets in the cart
921
-        if ($registrations_processed === false) {
922
-            // but return immediately if the previous step exited early due to errors
923
-            return false;
924
-        }
925
-        if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
926
-            // generate a correctly translated string for all possible singular/plural combinations
927
-            if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
928
-                $error_msg = sprintf(
929
-                    esc_html_x(
930
-                        'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed',
931
-                        'There was 1 ticket in the Event Queue, but 2 registrations were processed',
932
-                        'event_espresso'
933
-                    ),
934
-                    $this->checkout->total_ticket_count,
935
-                    $registrations_processed
936
-                );
937
-            } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) {
938
-                $error_msg = sprintf(
939
-                    esc_html_x(
940
-                        'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed',
941
-                        'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed',
942
-                        'event_espresso'
943
-                    ),
944
-                    $this->checkout->total_ticket_count,
945
-                    $registrations_processed
946
-                );
947
-            } else {
948
-                $error_msg = sprintf(
949
-                    esc_html__(
950
-                        'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed',
951
-                        'event_espresso'
952
-                    ),
953
-                    $this->checkout->total_ticket_count,
954
-                    $registrations_processed
955
-                );
956
-            }
957
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
958
-            return false;
959
-        }
960
-        // mark this reg step as completed
961
-        $this->set_completed();
962
-        $this->_set_success_message(
963
-            esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso')
964
-        );
965
-        // do action in case a plugin wants to do something with the data submitted in step 1.
966
-        // passes EE_Single_Page_Checkout, and it's posted data
967
-        do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data);
968
-        return true;
969
-    }
970
-
971
-
972
-    /**
973
-     *    _process_registrations
974
-     *
975
-     * @param EE_Registration[] $registrations
976
-     * @param array[][]         $valid_data
977
-     * @return bool|int
978
-     * @throws EntityNotFoundException
979
-     * @throws EE_Error
980
-     * @throws InvalidArgumentException
981
-     * @throws ReflectionException
982
-     * @throws RuntimeException
983
-     * @throws InvalidDataTypeException
984
-     * @throws InvalidInterfaceException
985
-     */
986
-    private function _process_registrations($registrations = array(), $valid_data = array())
987
-    {
988
-        // load resources and set some defaults
989
-        EE_Registry::instance()->load_model('Attendee');
990
-        // holder for primary registrant attendee object
991
-        $this->checkout->primary_attendee_obj = null;
992
-        // array for tracking reg form data for the primary registrant
993
-        $primary_registrant = array(
994
-            'line_item_id' => null,
995
-        );
996
-        $copy_primary = false;
997
-        // reg form sections that do not contain inputs
998
-        $non_input_form_sections = array(
999
-            'primary_registrant',
1000
-            'additional_attendee_reg_info',
1001
-            'spco_copy_attendee_chk',
1002
-        );
1003
-        // attendee counter
1004
-        $att_nmbr = 0;
1005
-        // grab the saved registrations from the transaction
1006
-        foreach ($registrations as $registration) {
1007
-            // verify EE_Registration object
1008
-            if (! $registration instanceof EE_Registration) {
1009
-                EE_Error::add_error(
1010
-                    esc_html__(
1011
-                        'An invalid Registration object was discovered when attempting to process your registration information.',
1012
-                        'event_espresso'
1013
-                    ),
1014
-                    __FILE__,
1015
-                    __FUNCTION__,
1016
-                    __LINE__
1017
-                );
1018
-                return false;
1019
-            }
1020
-            /** @var string $reg_url_link */
1021
-            $reg_url_link = $registration->reg_url_link();
1022
-            // reg_url_link exists ?
1023
-            if (! empty($reg_url_link)) {
1024
-                // should this registration be processed during this visit ?
1025
-                if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
1026
-                    // if NOT revisiting, then let's save the registration now,
1027
-                    // so that we have a REG_ID to use when generating other objects
1028
-                    if (! $this->checkout->revisit) {
1029
-                        $registration->save();
1030
-                    }
1031
-                    /**
1032
-                     * This allows plugins to trigger a fail on processing of a
1033
-                     * registration for any conditions they may have for it to pass.
1034
-                     *
1035
-                     * @var bool   if true is returned by the plugin then the
1036
-                     *            registration processing is halted.
1037
-                     */
1038
-                    if (apply_filters(
1039
-                        'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
1040
-                        false,
1041
-                        $att_nmbr,
1042
-                        $registration,
1043
-                        $registrations,
1044
-                        $valid_data,
1045
-                        $this
1046
-                    )) {
1047
-                        return false;
1048
-                    }
1049
-
1050
-                    // Houston, we have a registration!
1051
-                    $att_nmbr++;
1052
-                    $this->_attendee_data[ $reg_url_link ] = array();
1053
-                    // grab any existing related answer objects
1054
-                    $this->_registration_answers = $registration->answers();
1055
-                    // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
1056
-                    if (isset($valid_data[ $reg_url_link ])) {
1057
-                        // do we need to copy basic info from primary attendee ?
1058
-                        $copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info'])
1059
-                                        && absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
1060
-                        // filter form input data for this registration
1061
-                        $valid_data[ $reg_url_link ] = (array) apply_filters(
1062
-                            'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
1063
-                            $valid_data[ $reg_url_link ]
1064
-                        );
1065
-                        if (isset($valid_data['primary_attendee'])) {
1066
-                            $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
1067
-                                ? $valid_data['primary_attendee']
1068
-                                : false;
1069
-                            unset($valid_data['primary_attendee']);
1070
-                        }
1071
-                        // now loop through our array of valid post data && process attendee reg forms
1072
-                        foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) {
1073
-                            if (! in_array($form_section, $non_input_form_sections, true)) {
1074
-                                foreach ($form_inputs as $form_input => $input_value) {
1075
-                                    // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ );
1076
-                                    // check for critical inputs
1077
-                                    if (! $this->_verify_critical_attendee_details_are_set_and_validate_email(
1078
-                                        $form_input,
1079
-                                        $input_value
1080
-                                    )
1081
-                                    ) {
1082
-                                        return false;
1083
-                                    }
1084
-                                    // store a bit of data about the primary attendee
1085
-                                    if ($att_nmbr === 1
1086
-                                        && ! empty($input_value)
1087
-                                        && $reg_url_link === $primary_registrant['line_item_id']
1088
-                                    ) {
1089
-                                        $primary_registrant[ $form_input ] = $input_value;
1090
-                                    } elseif ($copy_primary
1091
-                                              && $input_value === null
1092
-                                              && isset($primary_registrant[ $form_input ])
1093
-                                    ) {
1094
-                                        $input_value = $primary_registrant[ $form_input ];
1095
-                                    }
1096
-                                    // now attempt to save the input data
1097
-                                    if (! $this->_save_registration_form_input(
1098
-                                        $registration,
1099
-                                        $form_input,
1100
-                                        $input_value
1101
-                                    )
1102
-                                    ) {
1103
-                                        EE_Error::add_error(
1104
-                                            sprintf(
1105
-                                                esc_html_x(
1106
-                                                    'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
1107
-                                                    'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"',
1108
-                                                    'event_espresso'
1109
-                                                ),
1110
-                                                $form_input,
1111
-                                                $input_value
1112
-                                            ),
1113
-                                            __FILE__,
1114
-                                            __FUNCTION__,
1115
-                                            __LINE__
1116
-                                        );
1117
-                                        return false;
1118
-                                    }
1119
-                                }
1120
-                            }
1121
-                        }  // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs )
1122
-                    }
1123
-                    // EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ );
1124
-                    // this registration does not require additional attendee information ?
1125
-                    if ($copy_primary
1126
-                        && $att_nmbr > 1
1127
-                        && $this->checkout->primary_attendee_obj instanceof EE_Attendee
1128
-                    ) {
1129
-                        // just copy the primary registrant
1130
-                        $attendee = $this->checkout->primary_attendee_obj;
1131
-                    } else {
1132
-                        // ensure critical details are set for additional attendees
1133
-                        $this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1
1134
-                            ? $this->_copy_critical_attendee_details_from_primary_registrant(
1135
-                                $this->_attendee_data[ $reg_url_link ]
1136
-                            )
1137
-                            : $this->_attendee_data[ $reg_url_link ];
1138
-                        // execute create attendee command (which may return an existing attendee)
1139
-                        $attendee = EE_Registry::instance()->BUS->execute(
1140
-                            new CreateAttendeeCommand(
1141
-                                $this->_attendee_data[ $reg_url_link ],
1142
-                                $registration
1143
-                            )
1144
-                        );
1145
-                        // who's #1 ?
1146
-                        if ($att_nmbr === 1) {
1147
-                            $this->checkout->primary_attendee_obj = $attendee;
1148
-                        }
1149
-                    }
1150
-                    // EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ );
1151
-                    // add relation to registration, set attendee ID, and cache attendee
1152
-                    $this->_associate_attendee_with_registration($registration, $attendee);
1153
-                    // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ );
1154
-                    if (! $registration->attendee() instanceof EE_Attendee) {
1155
-                        EE_Error::add_error(
1156
-                            sprintf(
1157
-                                esc_html_x(
1158
-                                    'Registration %s has an invalid or missing Attendee object.',
1159
-                                    'Registration 123-456-789 has an invalid or missing Attendee object.',
1160
-                                    'event_espresso'
1161
-                                ),
1162
-                                $reg_url_link
1163
-                            ),
1164
-                            __FILE__,
1165
-                            __FUNCTION__,
1166
-                            __LINE__
1167
-                        );
1168
-                        return false;
1169
-                    }
1170
-                    /** @type EE_Registration_Processor $registration_processor */
1171
-                    $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1172
-                    // at this point, we should have enough details about the registrant to consider the registration
1173
-                    // NOT incomplete
1174
-                    $registration_processor->toggle_incomplete_registration_status_to_default(
1175
-                        $registration,
1176
-                        false,
1177
-                        new Context(
1178
-                            'spco_reg_step_attendee_information_process_registrations',
1179
-                            esc_html__(
1180
-                                'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
1181
-                                'event_espresso'
1182
-                            )
1183
-                        )
1184
-                    );
1185
-                    // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
1186
-                    // abandoned
1187
-                    $this->checkout->transaction->toggle_failed_transaction_status();
1188
-                    // if we've gotten this far, then let's save what we have
1189
-                    $registration->save();
1190
-                    // add relation between TXN and registration
1191
-                    $this->_associate_registration_with_transaction($registration);
1192
-                }
1193
-            } else {
1194
-                EE_Error::add_error(
1195
-                    esc_html__(
1196
-                        'An invalid or missing line item ID was encountered while attempting to process the registration form.',
1197
-                        'event_espresso'
1198
-                    ),
1199
-                    __FILE__,
1200
-                    __FUNCTION__,
1201
-                    __LINE__
1202
-                );
1203
-                // remove malformed data
1204
-                unset($valid_data[ $reg_url_link ]);
1205
-                return false;
1206
-            }
1207
-        } // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
1208
-        return $att_nmbr;
1209
-    }
1210
-
1211
-
1212
-    /**
1213
-     *    _save_registration_form_input
1214
-     *
1215
-     * @param EE_Registration $registration
1216
-     * @param string          $form_input
1217
-     * @param string          $input_value
1218
-     * @return bool
1219
-     * @throws EE_Error
1220
-     * @throws InvalidArgumentException
1221
-     * @throws InvalidDataTypeException
1222
-     * @throws InvalidInterfaceException
1223
-     * @throws ReflectionException
1224
-     */
1225
-    private function _save_registration_form_input(
1226
-        EE_Registration $registration,
1227
-        $form_input = '',
1228
-        $input_value = ''
1229
-    ) {
1230
-        // \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 );
1231
-        // \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ );
1232
-        // \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ );
1233
-        // allow for plugins to hook in and do their own processing of the form input.
1234
-        // For plugins to bypass normal processing here, they just need to return a boolean value.
1235
-        if (apply_filters(
1236
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
1237
-            false,
1238
-            $registration,
1239
-            $form_input,
1240
-            $input_value,
1241
-            $this
1242
-        )) {
1243
-            return true;
1244
-        }
1245
-        /*
356
+		// Increment the reg forms number if form is valid.
357
+		if (!empty($form_args)) {
358
+			$this->reg_form_count++;
359
+		}
360
+
361
+		return ! empty($form_args)
362
+			? new EE_Form_Section_Proper($form_args)
363
+			: new EE_Form_Section_HTML();
364
+	}
365
+
366
+
367
+	/**
368
+	 * @param EE_Registration $registration
369
+	 * @param bool            $additional_attendee_reg_info
370
+	 * @return EE_Form_Input_Base
371
+	 * @throws EE_Error
372
+	 */
373
+	private function _additional_attendee_reg_info_input(
374
+		EE_Registration $registration,
375
+		$additional_attendee_reg_info = true
376
+	) {
377
+		// generate hidden input
378
+		return new EE_Hidden_Input(
379
+			array(
380
+				'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
381
+				'default' => $additional_attendee_reg_info,
382
+			)
383
+		);
384
+	}
385
+
386
+
387
+	/**
388
+	 * @param EE_Registration   $registration
389
+	 * @param EE_Question_Group $question_group
390
+	 * @return EE_Form_Section_Proper
391
+	 * @throws EE_Error
392
+	 * @throws InvalidArgumentException
393
+	 * @throws InvalidDataTypeException
394
+	 * @throws InvalidInterfaceException
395
+	 * @throws ReflectionException
396
+	 */
397
+	private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group)
398
+	{
399
+		// array of params to pass to parent constructor
400
+		$form_args = array(
401
+			'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(),
402
+			'html_class'      => $this->checkout->admin_request
403
+				? 'form-table ee-reg-form-qstn-grp-dv'
404
+				: 'ee-reg-form-qstn-grp-dv',
405
+			'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-'
406
+								 . $registration->ID() . '-lbl',
407
+			'subsections'     => array(
408
+				'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
409
+			),
410
+			'layout_strategy' => $this->checkout->admin_request
411
+				? new EE_Admin_Two_Column_Layout()
412
+				: new EE_Div_Per_Section_Layout(),
413
+		);
414
+		// where params
415
+		$query_params = array('QST_deleted' => 0);
416
+		// don't load admin only questions on the frontend
417
+		if (! $this->checkout->admin_request) {
418
+			$query_params['QST_admin_only'] = array('!=', true);
419
+		}
420
+		$questions = $question_group->get_many_related(
421
+			'Question',
422
+			apply_filters(
423
+				'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params',
424
+				array(
425
+					$query_params,
426
+					'order_by' => array(
427
+						'Question_Group_Question.QGQ_order' => 'ASC',
428
+					),
429
+				),
430
+				$question_group,
431
+				$registration,
432
+				$this
433
+			)
434
+		);
435
+		// filter for additional content before questions
436
+		$form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML(
437
+			apply_filters(
438
+				'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions',
439
+				'',
440
+				$registration,
441
+				$question_group,
442
+				$this
443
+			)
444
+		);
445
+		// loop thru questions
446
+		foreach ($questions as $question) {
447
+			if ($question instanceof EE_Question) {
448
+				$identifier = $question->is_system_question()
449
+					? $question->system_ID()
450
+					: $question->ID();
451
+				$form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question);
452
+			}
453
+		}
454
+		$form_args['subsections'] = apply_filters(
455
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array',
456
+			$form_args['subsections'],
457
+			$registration,
458
+			$question_group,
459
+			$this
460
+		);
461
+		// filter for additional content after questions
462
+		$form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML(
463
+			apply_filters(
464
+				'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions',
465
+				'',
466
+				$registration,
467
+				$question_group,
468
+				$this
469
+			)
470
+		);
471
+		// d($form_args);
472
+		$question_group_reg_form = new EE_Form_Section_Proper($form_args);
473
+		return apply_filters(
474
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
475
+			$question_group_reg_form,
476
+			$registration,
477
+			$question_group,
478
+			$this
479
+		);
480
+	}
481
+
482
+
483
+	/**
484
+	 * @param EE_Question_Group $question_group
485
+	 * @return    EE_Form_Section_HTML
486
+	 */
487
+	private function _question_group_header(EE_Question_Group $question_group)
488
+	{
489
+		$html = '';
490
+		// group_name
491
+		if ($question_group->show_group_name() && $question_group->name() !== '') {
492
+			if ($this->checkout->admin_request) {
493
+				$html .= EEH_HTML::br();
494
+				$html .= EEH_HTML::h3(
495
+					$question_group->name(),
496
+					'',
497
+					'ee-reg-form-qstn-grp-title title',
498
+					'font-size: 1.3em; padding-left:0;'
499
+				);
500
+			} else {
501
+				$html .= EEH_HTML::h4(
502
+					$question_group->name(),
503
+					'',
504
+					'ee-reg-form-qstn-grp-title section-title'
505
+				);
506
+			}
507
+		}
508
+		// group_desc
509
+		if ($question_group->show_group_desc() && $question_group->desc() !== '') {
510
+			$html .= EEH_HTML::p(
511
+				$question_group->desc(),
512
+				'',
513
+				$this->checkout->admin_request
514
+					? 'ee-reg-form-qstn-grp-desc-pg'
515
+					: 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text'
516
+			);
517
+		}
518
+		return new EE_Form_Section_HTML($html);
519
+	}
520
+
521
+
522
+	/**
523
+	 * @return    EE_Form_Section_Proper
524
+	 * @throws EE_Error
525
+	 * @throws InvalidArgumentException
526
+	 * @throws ReflectionException
527
+	 * @throws InvalidDataTypeException
528
+	 * @throws InvalidInterfaceException
529
+	 */
530
+	private function _copy_attendee_info_form()
531
+	{
532
+		// array of params to pass to parent constructor
533
+		return new EE_Form_Section_Proper(
534
+			array(
535
+				'subsections'     => $this->_copy_attendee_info_inputs(),
536
+				'layout_strategy' => new EE_Template_Layout(
537
+					array(
538
+						'layout_template_file'     => SPCO_REG_STEPS_PATH
539
+													  . $this->_slug
540
+													  . '/copy_attendee_info.template.php',
541
+						'begin_template_file'      => null,
542
+						'input_template_file'      => null,
543
+						'subsection_template_file' => null,
544
+						'end_template_file'        => null,
545
+					)
546
+				),
547
+			)
548
+		);
549
+	}
550
+
551
+
552
+	/**
553
+	 * @return EE_Form_Section_HTML
554
+	 * @throws DomainException
555
+	 * @throws InvalidArgumentException
556
+	 * @throws InvalidDataTypeException
557
+	 * @throws InvalidInterfaceException
558
+	 */
559
+	private function _auto_copy_attendee_info()
560
+	{
561
+		return new EE_Form_Section_HTML(
562
+			EEH_Template::locate_template(
563
+				SPCO_REG_STEPS_PATH . $this->_slug . '/_auto_copy_attendee_info.template.php',
564
+				apply_filters(
565
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
566
+					array()
567
+				),
568
+				true,
569
+				true
570
+			)
571
+		);
572
+	}
573
+
574
+
575
+	/**
576
+	 * @return array
577
+	 * @throws EE_Error
578
+	 * @throws InvalidArgumentException
579
+	 * @throws ReflectionException
580
+	 * @throws InvalidDataTypeException
581
+	 * @throws InvalidInterfaceException
582
+	 */
583
+	private function _copy_attendee_info_inputs()
584
+	{
585
+		$copy_attendee_info_inputs = array();
586
+		$prev_ticket = null;
587
+		// grab the saved registrations from the transaction
588
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
589
+		foreach ($registrations as $registration) {
590
+			// for all  attendees other than the primary attendee
591
+			if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
592
+				// if this is a new ticket OR if this is the very first additional attendee after the primary attendee
593
+				if ($registration->ticket()->ID() !== $prev_ticket) {
594
+					$item_name = $registration->ticket()->name();
595
+					$item_name .= $registration->ticket()->description() !== ''
596
+						? ' - ' . $registration->ticket()->description()
597
+						: '';
598
+					$copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID(
599
+					) . ']' ] =
600
+						new EE_Form_Section_HTML(
601
+							'<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
602
+						);
603
+					$prev_ticket = $registration->ticket()->ID();
604
+				}
605
+
606
+				$copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] =
607
+					new EE_Checkbox_Multi_Input(
608
+						array(
609
+							$registration->ID() => sprintf(
610
+								esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'),
611
+								$registration->count()
612
+							),
613
+						),
614
+						array(
615
+							'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
616
+							'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
617
+							'display_html_label_text' => false,
618
+						)
619
+					);
620
+			}
621
+		}
622
+		return $copy_attendee_info_inputs;
623
+	}
624
+
625
+
626
+	/**
627
+	 * @param EE_Registration $registration
628
+	 * @return    EE_Form_Input_Base
629
+	 * @throws EE_Error
630
+	 */
631
+	private function _additional_primary_registrant_inputs(EE_Registration $registration)
632
+	{
633
+		// generate hidden input
634
+		return new EE_Hidden_Input(
635
+			array(
636
+				'html_id' => 'primary_registrant',
637
+				'default' => $registration->reg_url_link(),
638
+			)
639
+		);
640
+	}
641
+
642
+
643
+	/**
644
+	 * @param EE_Registration $registration
645
+	 * @param EE_Question     $question
646
+	 * @return EE_Form_Input_Base
647
+	 * @throws EE_Error
648
+	 * @throws InvalidArgumentException
649
+	 * @throws InvalidDataTypeException
650
+	 * @throws InvalidInterfaceException
651
+	 * @throws ReflectionException
652
+	 */
653
+	public function reg_form_question(EE_Registration $registration, EE_Question $question)
654
+	{
655
+
656
+		// if this question was for an attendee detail, then check for that answer
657
+		$answer_value = EEM_Answer::instance()->get_attendee_property_answer_value(
658
+			$registration,
659
+			$question->system_ID()
660
+		);
661
+		$answer = $answer_value === null
662
+			? EEM_Answer::instance()->get_one(
663
+				array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
664
+			)
665
+			: null;
666
+		// if NOT returning to edit an existing registration
667
+		// OR if this question is for an attendee property
668
+		// OR we still don't have an EE_Answer object
669
+		if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) {
670
+			// create an EE_Answer object for storing everything in
671
+			$answer = EE_Answer::new_instance(
672
+				array(
673
+					'QST_ID' => $question->ID(),
674
+					'REG_ID' => $registration->ID(),
675
+				)
676
+			);
677
+		}
678
+		// verify instance
679
+		if ($answer instanceof EE_Answer) {
680
+			if (! empty($answer_value)) {
681
+				$answer->set('ANS_value', $answer_value);
682
+			}
683
+			$answer->cache('Question', $question);
684
+			// remember system ID had a bug where sometimes it could be null
685
+			$answer_cache_id = $question->is_system_question()
686
+				? $question->system_ID() . '-' . $registration->reg_url_link()
687
+				: $question->ID() . '-' . $registration->reg_url_link();
688
+			$registration->cache('Answer', $answer, $answer_cache_id);
689
+		}
690
+		return $this->_generate_question_input($registration, $question, $answer);
691
+	}
692
+
693
+
694
+	/**
695
+	 * @param EE_Registration $registration
696
+	 * @param EE_Question     $question
697
+	 * @param                 $answer
698
+	 * @return EE_Form_Input_Base
699
+	 * @throws EE_Error
700
+	 * @throws InvalidArgumentException
701
+	 * @throws ReflectionException
702
+	 * @throws InvalidDataTypeException
703
+	 * @throws InvalidInterfaceException
704
+	 */
705
+	private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer)
706
+	{
707
+		$identifier = $question->is_system_question()
708
+			? $question->system_ID()
709
+			: $question->ID();
710
+		$this->_required_questions[ $identifier ] = $question->required() ? true : false;
711
+		add_filter(
712
+			'FHEE__EE_Question__generate_form_input__country_options',
713
+			array($this, 'use_cached_countries_for_form_input'),
714
+			10,
715
+			4
716
+		);
717
+		add_filter(
718
+			'FHEE__EE_Question__generate_form_input__state_options',
719
+			array($this, 'use_cached_states_for_form_input'),
720
+			10,
721
+			4
722
+		);
723
+		$input_constructor_args = array(
724
+			'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
725
+			'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
726
+			'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
727
+			'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
728
+			'html_label_class' => 'ee-reg-qstn',
729
+		);
730
+		$input_constructor_args['html_label_id'] .= '-lbl';
731
+		if ($answer instanceof EE_Answer && $answer->ID()) {
732
+			$input_constructor_args['html_name'] .= '[' . $answer->ID() . ']';
733
+			$input_constructor_args['html_id'] .= '-' . $answer->ID();
734
+			$input_constructor_args['html_label_id'] .= '-' . $answer->ID();
735
+		}
736
+		$form_input = $question->generate_form_input(
737
+			$registration,
738
+			$answer,
739
+			$input_constructor_args
740
+		);
741
+		remove_filter(
742
+			'FHEE__EE_Question__generate_form_input__country_options',
743
+			array($this, 'use_cached_countries_for_form_input')
744
+		);
745
+		remove_filter(
746
+			'FHEE__EE_Question__generate_form_input__state_options',
747
+			array($this, 'use_cached_states_for_form_input')
748
+		);
749
+		return $form_input;
750
+	}
751
+
752
+
753
+	/**
754
+	 * Gets the list of countries for the form input
755
+	 *
756
+	 * @param array|null      $countries_list
757
+	 * @param EE_Question     $question
758
+	 * @param EE_Registration $registration
759
+	 * @param EE_Answer       $answer
760
+	 * @return array 2d keys are country IDs, values are their names
761
+	 * @throws EE_Error
762
+	 * @throws InvalidArgumentException
763
+	 * @throws InvalidDataTypeException
764
+	 * @throws InvalidInterfaceException
765
+	 * @throws ReflectionException
766
+	 */
767
+	public function use_cached_countries_for_form_input(
768
+		$countries_list,
769
+		EE_Question $question = null,
770
+		EE_Registration $registration = null,
771
+		EE_Answer $answer = null
772
+	) {
773
+		$country_options = array('' => '');
774
+		// get possibly cached list of countries
775
+		$countries = $this->checkout->action === 'process_reg_step'
776
+			? EEM_Country::instance()->get_all_countries()
777
+			: EEM_Country::instance()->get_all_active_countries();
778
+		if (! empty($countries)) {
779
+			foreach ($countries as $country) {
780
+				if ($country instanceof EE_Country) {
781
+					$country_options[ $country->ID() ] = $country->name();
782
+				}
783
+			}
784
+		}
785
+		if ($question instanceof EE_Question && $registration instanceof EE_Registration) {
786
+			$answer = EEM_Answer::instance()->get_one(
787
+				array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()))
788
+			);
789
+		} else {
790
+			$answer = EE_Answer::new_instance();
791
+		}
792
+		$country_options = apply_filters(
793
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
794
+			$country_options,
795
+			$this,
796
+			$registration,
797
+			$question,
798
+			$answer
799
+		);
800
+		return $country_options;
801
+	}
802
+
803
+
804
+	/**
805
+	 * Gets the list of states for the form input
806
+	 *
807
+	 * @param array|null      $states_list
808
+	 * @param EE_Question     $question
809
+	 * @param EE_Registration $registration
810
+	 * @param EE_Answer       $answer
811
+	 * @return array 2d keys are state IDs, values are their names
812
+	 * @throws EE_Error
813
+	 * @throws InvalidArgumentException
814
+	 * @throws InvalidDataTypeException
815
+	 * @throws InvalidInterfaceException
816
+	 * @throws ReflectionException
817
+	 */
818
+	public function use_cached_states_for_form_input(
819
+		$states_list,
820
+		EE_Question $question = null,
821
+		EE_Registration $registration = null,
822
+		EE_Answer $answer = null
823
+	) {
824
+		$state_options = array('' => array('' => ''));
825
+		$states = $this->checkout->action === 'process_reg_step'
826
+			? EEM_State::instance()->get_all_states()
827
+			: EEM_State::instance()->get_all_active_states();
828
+		if (! empty($states)) {
829
+			foreach ($states as $state) {
830
+				if ($state instanceof EE_State) {
831
+					$state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
832
+				}
833
+			}
834
+		}
835
+		$state_options = apply_filters(
836
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
837
+			$state_options,
838
+			$this,
839
+			$registration,
840
+			$question,
841
+			$answer
842
+		);
843
+		return $state_options;
844
+	}
845
+
846
+
847
+	/********************************************************************************************************/
848
+	/****************************************  PROCESS REG STEP  ****************************************/
849
+	/********************************************************************************************************/
850
+
851
+
852
+	/**
853
+	 * @return bool
854
+	 * @throws EE_Error
855
+	 * @throws InvalidArgumentException
856
+	 * @throws ReflectionException
857
+	 * @throws RuntimeException
858
+	 * @throws InvalidDataTypeException
859
+	 * @throws InvalidInterfaceException
860
+	 */
861
+	public function process_reg_step()
862
+	{
863
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
864
+		// grab validated data from form
865
+		$valid_data = $this->checkout->current_step->valid_data();
866
+		// EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
867
+		// EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ );
868
+		// if we don't have any $valid_data then something went TERRIBLY WRONG !!!
869
+		if (empty($valid_data)) {
870
+			EE_Error::add_error(
871
+				esc_html__('No valid question responses were received.', 'event_espresso'),
872
+				__FILE__,
873
+				__FUNCTION__,
874
+				__LINE__
875
+			);
876
+			return false;
877
+		}
878
+		if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
879
+			EE_Error::add_error(
880
+				esc_html__(
881
+					'A valid transaction could not be initiated for processing your registrations.',
882
+					'event_espresso'
883
+				),
884
+				__FILE__,
885
+				__FUNCTION__,
886
+				__LINE__
887
+			);
888
+			return false;
889
+		}
890
+		// get cached registrations
891
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
892
+		// verify we got the goods
893
+		if (empty($registrations)) {
894
+			// combine the old translated string with a new one, in order to not break translations
895
+			$error_message = esc_html__(
896
+				'Your form data could not be applied to any valid registrations.',
897
+				'event_espresso'
898
+			)
899
+			. sprintf(
900
+				esc_html_x(
901
+					'%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.',
902
+					'(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.',
903
+					'event_espresso'
904
+				),
905
+				'<a href="' . get_post_type_archive_link('espresso_events') . '" >',
906
+				'</a>',
907
+				'<br />'
908
+			);
909
+			EE_Error::add_error(
910
+				$error_message,
911
+				__FILE__,
912
+				__FUNCTION__,
913
+				__LINE__
914
+			);
915
+			return false;
916
+		}
917
+		// extract attendee info from form data and save to model objects
918
+		$registrations_processed = $this->_process_registrations($registrations, $valid_data);
919
+		// if first pass thru SPCO,
920
+		// then let's check processed registrations against the total number of tickets in the cart
921
+		if ($registrations_processed === false) {
922
+			// but return immediately if the previous step exited early due to errors
923
+			return false;
924
+		}
925
+		if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
926
+			// generate a correctly translated string for all possible singular/plural combinations
927
+			if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
928
+				$error_msg = sprintf(
929
+					esc_html_x(
930
+						'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed',
931
+						'There was 1 ticket in the Event Queue, but 2 registrations were processed',
932
+						'event_espresso'
933
+					),
934
+					$this->checkout->total_ticket_count,
935
+					$registrations_processed
936
+				);
937
+			} elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) {
938
+				$error_msg = sprintf(
939
+					esc_html_x(
940
+						'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed',
941
+						'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed',
942
+						'event_espresso'
943
+					),
944
+					$this->checkout->total_ticket_count,
945
+					$registrations_processed
946
+				);
947
+			} else {
948
+				$error_msg = sprintf(
949
+					esc_html__(
950
+						'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed',
951
+						'event_espresso'
952
+					),
953
+					$this->checkout->total_ticket_count,
954
+					$registrations_processed
955
+				);
956
+			}
957
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
958
+			return false;
959
+		}
960
+		// mark this reg step as completed
961
+		$this->set_completed();
962
+		$this->_set_success_message(
963
+			esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso')
964
+		);
965
+		// do action in case a plugin wants to do something with the data submitted in step 1.
966
+		// passes EE_Single_Page_Checkout, and it's posted data
967
+		do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data);
968
+		return true;
969
+	}
970
+
971
+
972
+	/**
973
+	 *    _process_registrations
974
+	 *
975
+	 * @param EE_Registration[] $registrations
976
+	 * @param array[][]         $valid_data
977
+	 * @return bool|int
978
+	 * @throws EntityNotFoundException
979
+	 * @throws EE_Error
980
+	 * @throws InvalidArgumentException
981
+	 * @throws ReflectionException
982
+	 * @throws RuntimeException
983
+	 * @throws InvalidDataTypeException
984
+	 * @throws InvalidInterfaceException
985
+	 */
986
+	private function _process_registrations($registrations = array(), $valid_data = array())
987
+	{
988
+		// load resources and set some defaults
989
+		EE_Registry::instance()->load_model('Attendee');
990
+		// holder for primary registrant attendee object
991
+		$this->checkout->primary_attendee_obj = null;
992
+		// array for tracking reg form data for the primary registrant
993
+		$primary_registrant = array(
994
+			'line_item_id' => null,
995
+		);
996
+		$copy_primary = false;
997
+		// reg form sections that do not contain inputs
998
+		$non_input_form_sections = array(
999
+			'primary_registrant',
1000
+			'additional_attendee_reg_info',
1001
+			'spco_copy_attendee_chk',
1002
+		);
1003
+		// attendee counter
1004
+		$att_nmbr = 0;
1005
+		// grab the saved registrations from the transaction
1006
+		foreach ($registrations as $registration) {
1007
+			// verify EE_Registration object
1008
+			if (! $registration instanceof EE_Registration) {
1009
+				EE_Error::add_error(
1010
+					esc_html__(
1011
+						'An invalid Registration object was discovered when attempting to process your registration information.',
1012
+						'event_espresso'
1013
+					),
1014
+					__FILE__,
1015
+					__FUNCTION__,
1016
+					__LINE__
1017
+				);
1018
+				return false;
1019
+			}
1020
+			/** @var string $reg_url_link */
1021
+			$reg_url_link = $registration->reg_url_link();
1022
+			// reg_url_link exists ?
1023
+			if (! empty($reg_url_link)) {
1024
+				// should this registration be processed during this visit ?
1025
+				if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
1026
+					// if NOT revisiting, then let's save the registration now,
1027
+					// so that we have a REG_ID to use when generating other objects
1028
+					if (! $this->checkout->revisit) {
1029
+						$registration->save();
1030
+					}
1031
+					/**
1032
+					 * This allows plugins to trigger a fail on processing of a
1033
+					 * registration for any conditions they may have for it to pass.
1034
+					 *
1035
+					 * @var bool   if true is returned by the plugin then the
1036
+					 *            registration processing is halted.
1037
+					 */
1038
+					if (apply_filters(
1039
+						'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
1040
+						false,
1041
+						$att_nmbr,
1042
+						$registration,
1043
+						$registrations,
1044
+						$valid_data,
1045
+						$this
1046
+					)) {
1047
+						return false;
1048
+					}
1049
+
1050
+					// Houston, we have a registration!
1051
+					$att_nmbr++;
1052
+					$this->_attendee_data[ $reg_url_link ] = array();
1053
+					// grab any existing related answer objects
1054
+					$this->_registration_answers = $registration->answers();
1055
+					// unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
1056
+					if (isset($valid_data[ $reg_url_link ])) {
1057
+						// do we need to copy basic info from primary attendee ?
1058
+						$copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info'])
1059
+										&& absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
1060
+						// filter form input data for this registration
1061
+						$valid_data[ $reg_url_link ] = (array) apply_filters(
1062
+							'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
1063
+							$valid_data[ $reg_url_link ]
1064
+						);
1065
+						if (isset($valid_data['primary_attendee'])) {
1066
+							$primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
1067
+								? $valid_data['primary_attendee']
1068
+								: false;
1069
+							unset($valid_data['primary_attendee']);
1070
+						}
1071
+						// now loop through our array of valid post data && process attendee reg forms
1072
+						foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) {
1073
+							if (! in_array($form_section, $non_input_form_sections, true)) {
1074
+								foreach ($form_inputs as $form_input => $input_value) {
1075
+									// \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ );
1076
+									// check for critical inputs
1077
+									if (! $this->_verify_critical_attendee_details_are_set_and_validate_email(
1078
+										$form_input,
1079
+										$input_value
1080
+									)
1081
+									) {
1082
+										return false;
1083
+									}
1084
+									// store a bit of data about the primary attendee
1085
+									if ($att_nmbr === 1
1086
+										&& ! empty($input_value)
1087
+										&& $reg_url_link === $primary_registrant['line_item_id']
1088
+									) {
1089
+										$primary_registrant[ $form_input ] = $input_value;
1090
+									} elseif ($copy_primary
1091
+											  && $input_value === null
1092
+											  && isset($primary_registrant[ $form_input ])
1093
+									) {
1094
+										$input_value = $primary_registrant[ $form_input ];
1095
+									}
1096
+									// now attempt to save the input data
1097
+									if (! $this->_save_registration_form_input(
1098
+										$registration,
1099
+										$form_input,
1100
+										$input_value
1101
+									)
1102
+									) {
1103
+										EE_Error::add_error(
1104
+											sprintf(
1105
+												esc_html_x(
1106
+													'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
1107
+													'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"',
1108
+													'event_espresso'
1109
+												),
1110
+												$form_input,
1111
+												$input_value
1112
+											),
1113
+											__FILE__,
1114
+											__FUNCTION__,
1115
+											__LINE__
1116
+										);
1117
+										return false;
1118
+									}
1119
+								}
1120
+							}
1121
+						}  // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs )
1122
+					}
1123
+					// EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ );
1124
+					// this registration does not require additional attendee information ?
1125
+					if ($copy_primary
1126
+						&& $att_nmbr > 1
1127
+						&& $this->checkout->primary_attendee_obj instanceof EE_Attendee
1128
+					) {
1129
+						// just copy the primary registrant
1130
+						$attendee = $this->checkout->primary_attendee_obj;
1131
+					} else {
1132
+						// ensure critical details are set for additional attendees
1133
+						$this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1
1134
+							? $this->_copy_critical_attendee_details_from_primary_registrant(
1135
+								$this->_attendee_data[ $reg_url_link ]
1136
+							)
1137
+							: $this->_attendee_data[ $reg_url_link ];
1138
+						// execute create attendee command (which may return an existing attendee)
1139
+						$attendee = EE_Registry::instance()->BUS->execute(
1140
+							new CreateAttendeeCommand(
1141
+								$this->_attendee_data[ $reg_url_link ],
1142
+								$registration
1143
+							)
1144
+						);
1145
+						// who's #1 ?
1146
+						if ($att_nmbr === 1) {
1147
+							$this->checkout->primary_attendee_obj = $attendee;
1148
+						}
1149
+					}
1150
+					// EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ );
1151
+					// add relation to registration, set attendee ID, and cache attendee
1152
+					$this->_associate_attendee_with_registration($registration, $attendee);
1153
+					// \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ );
1154
+					if (! $registration->attendee() instanceof EE_Attendee) {
1155
+						EE_Error::add_error(
1156
+							sprintf(
1157
+								esc_html_x(
1158
+									'Registration %s has an invalid or missing Attendee object.',
1159
+									'Registration 123-456-789 has an invalid or missing Attendee object.',
1160
+									'event_espresso'
1161
+								),
1162
+								$reg_url_link
1163
+							),
1164
+							__FILE__,
1165
+							__FUNCTION__,
1166
+							__LINE__
1167
+						);
1168
+						return false;
1169
+					}
1170
+					/** @type EE_Registration_Processor $registration_processor */
1171
+					$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1172
+					// at this point, we should have enough details about the registrant to consider the registration
1173
+					// NOT incomplete
1174
+					$registration_processor->toggle_incomplete_registration_status_to_default(
1175
+						$registration,
1176
+						false,
1177
+						new Context(
1178
+							'spco_reg_step_attendee_information_process_registrations',
1179
+							esc_html__(
1180
+								'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
1181
+								'event_espresso'
1182
+							)
1183
+						)
1184
+					);
1185
+					// we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
1186
+					// abandoned
1187
+					$this->checkout->transaction->toggle_failed_transaction_status();
1188
+					// if we've gotten this far, then let's save what we have
1189
+					$registration->save();
1190
+					// add relation between TXN and registration
1191
+					$this->_associate_registration_with_transaction($registration);
1192
+				}
1193
+			} else {
1194
+				EE_Error::add_error(
1195
+					esc_html__(
1196
+						'An invalid or missing line item ID was encountered while attempting to process the registration form.',
1197
+						'event_espresso'
1198
+					),
1199
+					__FILE__,
1200
+					__FUNCTION__,
1201
+					__LINE__
1202
+				);
1203
+				// remove malformed data
1204
+				unset($valid_data[ $reg_url_link ]);
1205
+				return false;
1206
+			}
1207
+		} // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
1208
+		return $att_nmbr;
1209
+	}
1210
+
1211
+
1212
+	/**
1213
+	 *    _save_registration_form_input
1214
+	 *
1215
+	 * @param EE_Registration $registration
1216
+	 * @param string          $form_input
1217
+	 * @param string          $input_value
1218
+	 * @return bool
1219
+	 * @throws EE_Error
1220
+	 * @throws InvalidArgumentException
1221
+	 * @throws InvalidDataTypeException
1222
+	 * @throws InvalidInterfaceException
1223
+	 * @throws ReflectionException
1224
+	 */
1225
+	private function _save_registration_form_input(
1226
+		EE_Registration $registration,
1227
+		$form_input = '',
1228
+		$input_value = ''
1229
+	) {
1230
+		// \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 );
1231
+		// \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ );
1232
+		// \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ );
1233
+		// allow for plugins to hook in and do their own processing of the form input.
1234
+		// For plugins to bypass normal processing here, they just need to return a boolean value.
1235
+		if (apply_filters(
1236
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
1237
+			false,
1238
+			$registration,
1239
+			$form_input,
1240
+			$input_value,
1241
+			$this
1242
+		)) {
1243
+			return true;
1244
+		}
1245
+		/*
1246 1246
          * $answer_cache_id is the key used to find the EE_Answer we want
1247 1247
          * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
1248 1248
          */
1249
-        $answer_cache_id = $this->checkout->reg_url_link
1250
-            ? $form_input . '-' . $registration->reg_url_link()
1251
-            : $form_input;
1252
-        $answer_is_obj = isset($this->_registration_answers[ $answer_cache_id ])
1253
-                         && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer;
1254
-        // rename form_inputs if they are EE_Attendee properties
1255
-        switch ((string) $form_input) {
1256
-            case 'state':
1257
-            case 'STA_ID':
1258
-                $attendee_property = true;
1259
-                $form_input = 'STA_ID';
1260
-                break;
1261
-
1262
-            case 'country':
1263
-            case 'CNT_ISO':
1264
-                $attendee_property = true;
1265
-                $form_input = 'CNT_ISO';
1266
-                break;
1267
-
1268
-            default:
1269
-                $ATT_input = 'ATT_' . $form_input;
1270
-                // EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ );
1271
-                $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false;
1272
-                $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input;
1273
-        }
1274
-        // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ );
1275
-        // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ );
1276
-        // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ );
1277
-        // if this form input has a corresponding attendee property
1278
-        if ($attendee_property) {
1279
-            $this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value;
1280
-            if ($answer_is_obj) {
1281
-                // and delete the corresponding answer since we won't be storing this data in that object
1282
-                $registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer');
1283
-                $this->_registration_answers[ $answer_cache_id ]->delete_permanently();
1284
-            }
1285
-            return true;
1286
-        }
1287
-        if ($answer_is_obj) {
1288
-            // save this data to the answer object
1289
-            $this->_registration_answers[ $answer_cache_id ]->set_value($input_value);
1290
-            $result = $this->_registration_answers[ $answer_cache_id ]->save();
1291
-            return $result !== false;
1292
-        }
1293
-        foreach ($this->_registration_answers as $answer) {
1294
-            if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) {
1295
-                $answer->set_value($input_value);
1296
-                $result = $answer->save();
1297
-                return $result !== false;
1298
-            }
1299
-        }
1300
-        return false;
1301
-    }
1302
-
1303
-
1304
-    /**
1305
-     *    _verify_critical_attendee_details_are_set
1306
-     *
1307
-     * @param string $form_input
1308
-     * @param string $input_value
1309
-     * @return boolean
1310
-     */
1311
-    private function _verify_critical_attendee_details_are_set_and_validate_email(
1312
-        $form_input = '',
1313
-        $input_value = ''
1314
-    ) {
1315
-        if (empty($input_value)) {
1316
-            // if the form input isn't marked as being required, then just return
1317
-            if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) {
1318
-                return true;
1319
-            }
1320
-            switch ($form_input) {
1321
-                case 'fname':
1322
-                    EE_Error::add_error(
1323
-                        esc_html__('First Name is a required value.', 'event_espresso'),
1324
-                        __FILE__,
1325
-                        __FUNCTION__,
1326
-                        __LINE__
1327
-                    );
1328
-                    return false;
1329
-                    break;
1330
-                case 'lname':
1331
-                    EE_Error::add_error(
1332
-                        esc_html__('Last Name is a required value.', 'event_espresso'),
1333
-                        __FILE__,
1334
-                        __FUNCTION__,
1335
-                        __LINE__
1336
-                    );
1337
-                    return false;
1338
-                    break;
1339
-                case 'email':
1340
-                    EE_Error::add_error(
1341
-                        esc_html__('Please enter a valid email address.', 'event_espresso'),
1342
-                        __FILE__,
1343
-                        __FUNCTION__,
1344
-                        __LINE__
1345
-                    );
1346
-                    return false;
1347
-                    break;
1348
-            }
1349
-        }
1350
-        return true;
1351
-    }
1352
-
1353
-
1354
-    /**
1355
-     *    _associate_attendee_with_registration
1356
-     *
1357
-     * @param EE_Registration $registration
1358
-     * @param EE_Attendee     $attendee
1359
-     * @return void
1360
-     * @throws EE_Error
1361
-     * @throws InvalidArgumentException
1362
-     * @throws ReflectionException
1363
-     * @throws RuntimeException
1364
-     * @throws InvalidDataTypeException
1365
-     * @throws InvalidInterfaceException
1366
-     */
1367
-    private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee)
1368
-    {
1369
-        // add relation to attendee
1370
-        $registration->_add_relation_to($attendee, 'Attendee');
1371
-        $registration->set_attendee_id($attendee->ID());
1372
-        $registration->update_cache_after_object_save('Attendee', $attendee);
1373
-    }
1374
-
1375
-
1376
-    /**
1377
-     *    _associate_registration_with_transaction
1378
-     *
1379
-     * @param EE_Registration $registration
1380
-     * @return void
1381
-     * @throws EE_Error
1382
-     * @throws InvalidArgumentException
1383
-     * @throws ReflectionException
1384
-     * @throws InvalidDataTypeException
1385
-     * @throws InvalidInterfaceException
1386
-     */
1387
-    private function _associate_registration_with_transaction(EE_Registration $registration)
1388
-    {
1389
-        // add relation to registration
1390
-        $this->checkout->transaction->_add_relation_to($registration, 'Registration');
1391
-        $this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
1392
-    }
1393
-
1394
-
1395
-    /**
1396
-     *    _copy_critical_attendee_details_from_primary_registrant
1397
-     *    ensures that all attendees at least have data for first name, last name, and email address
1398
-     *
1399
-     * @param array $attendee_data
1400
-     * @return array
1401
-     * @throws EE_Error
1402
-     * @throws InvalidArgumentException
1403
-     * @throws ReflectionException
1404
-     * @throws InvalidDataTypeException
1405
-     * @throws InvalidInterfaceException
1406
-     */
1407
-    private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array())
1408
-    {
1409
-        // bare minimum critical details include first name, last name, email address
1410
-        $critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email');
1411
-        // add address info to critical details?
1412
-        if (apply_filters(
1413
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details',
1414
-            false
1415
-        )) {
1416
-            $address_details = array(
1417
-                'ATT_address',
1418
-                'ATT_address2',
1419
-                'ATT_city',
1420
-                'STA_ID',
1421
-                'CNT_ISO',
1422
-                'ATT_zip',
1423
-                'ATT_phone',
1424
-            );
1425
-            $critical_attendee_details = array_merge($critical_attendee_details, $address_details);
1426
-        }
1427
-        foreach ($critical_attendee_details as $critical_attendee_detail) {
1428
-            if (! isset($attendee_data[ $critical_attendee_detail ])
1429
-                || empty($attendee_data[ $critical_attendee_detail ])
1430
-            ) {
1431
-                $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get(
1432
-                    $critical_attendee_detail
1433
-                );
1434
-            }
1435
-        }
1436
-        return $attendee_data;
1437
-    }
1438
-
1439
-
1440
-    /**
1441
-     *    update_reg_step
1442
-     *    this is the final step after a user  revisits the site to edit their attendee information
1443
-     *    this gets called AFTER the process_reg_step() method above
1444
-     *
1445
-     * @return bool
1446
-     * @throws EE_Error
1447
-     * @throws InvalidArgumentException
1448
-     * @throws ReflectionException
1449
-     * @throws RuntimeException
1450
-     * @throws InvalidDataTypeException
1451
-     * @throws InvalidInterfaceException
1452
-     */
1453
-    public function update_reg_step()
1454
-    {
1455
-        // save everything
1456
-        if ($this->process_reg_step()) {
1457
-            $this->checkout->redirect = true;
1458
-            $this->checkout->redirect_url = add_query_arg(
1459
-                array(
1460
-                    'e_reg_url_link' => $this->checkout->reg_url_link,
1461
-                    'revisit'        => true,
1462
-                ),
1463
-                $this->checkout->thank_you_page_url
1464
-            );
1465
-            $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1466
-            return true;
1467
-        }
1468
-        return false;
1469
-    }
1249
+		$answer_cache_id = $this->checkout->reg_url_link
1250
+			? $form_input . '-' . $registration->reg_url_link()
1251
+			: $form_input;
1252
+		$answer_is_obj = isset($this->_registration_answers[ $answer_cache_id ])
1253
+						 && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer;
1254
+		// rename form_inputs if they are EE_Attendee properties
1255
+		switch ((string) $form_input) {
1256
+			case 'state':
1257
+			case 'STA_ID':
1258
+				$attendee_property = true;
1259
+				$form_input = 'STA_ID';
1260
+				break;
1261
+
1262
+			case 'country':
1263
+			case 'CNT_ISO':
1264
+				$attendee_property = true;
1265
+				$form_input = 'CNT_ISO';
1266
+				break;
1267
+
1268
+			default:
1269
+				$ATT_input = 'ATT_' . $form_input;
1270
+				// EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ );
1271
+				$attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false;
1272
+				$form_input = $attendee_property ? 'ATT_' . $form_input : $form_input;
1273
+		}
1274
+		// EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ );
1275
+		// EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ );
1276
+		// EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ );
1277
+		// if this form input has a corresponding attendee property
1278
+		if ($attendee_property) {
1279
+			$this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value;
1280
+			if ($answer_is_obj) {
1281
+				// and delete the corresponding answer since we won't be storing this data in that object
1282
+				$registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer');
1283
+				$this->_registration_answers[ $answer_cache_id ]->delete_permanently();
1284
+			}
1285
+			return true;
1286
+		}
1287
+		if ($answer_is_obj) {
1288
+			// save this data to the answer object
1289
+			$this->_registration_answers[ $answer_cache_id ]->set_value($input_value);
1290
+			$result = $this->_registration_answers[ $answer_cache_id ]->save();
1291
+			return $result !== false;
1292
+		}
1293
+		foreach ($this->_registration_answers as $answer) {
1294
+			if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) {
1295
+				$answer->set_value($input_value);
1296
+				$result = $answer->save();
1297
+				return $result !== false;
1298
+			}
1299
+		}
1300
+		return false;
1301
+	}
1302
+
1303
+
1304
+	/**
1305
+	 *    _verify_critical_attendee_details_are_set
1306
+	 *
1307
+	 * @param string $form_input
1308
+	 * @param string $input_value
1309
+	 * @return boolean
1310
+	 */
1311
+	private function _verify_critical_attendee_details_are_set_and_validate_email(
1312
+		$form_input = '',
1313
+		$input_value = ''
1314
+	) {
1315
+		if (empty($input_value)) {
1316
+			// if the form input isn't marked as being required, then just return
1317
+			if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) {
1318
+				return true;
1319
+			}
1320
+			switch ($form_input) {
1321
+				case 'fname':
1322
+					EE_Error::add_error(
1323
+						esc_html__('First Name is a required value.', 'event_espresso'),
1324
+						__FILE__,
1325
+						__FUNCTION__,
1326
+						__LINE__
1327
+					);
1328
+					return false;
1329
+					break;
1330
+				case 'lname':
1331
+					EE_Error::add_error(
1332
+						esc_html__('Last Name is a required value.', 'event_espresso'),
1333
+						__FILE__,
1334
+						__FUNCTION__,
1335
+						__LINE__
1336
+					);
1337
+					return false;
1338
+					break;
1339
+				case 'email':
1340
+					EE_Error::add_error(
1341
+						esc_html__('Please enter a valid email address.', 'event_espresso'),
1342
+						__FILE__,
1343
+						__FUNCTION__,
1344
+						__LINE__
1345
+					);
1346
+					return false;
1347
+					break;
1348
+			}
1349
+		}
1350
+		return true;
1351
+	}
1352
+
1353
+
1354
+	/**
1355
+	 *    _associate_attendee_with_registration
1356
+	 *
1357
+	 * @param EE_Registration $registration
1358
+	 * @param EE_Attendee     $attendee
1359
+	 * @return void
1360
+	 * @throws EE_Error
1361
+	 * @throws InvalidArgumentException
1362
+	 * @throws ReflectionException
1363
+	 * @throws RuntimeException
1364
+	 * @throws InvalidDataTypeException
1365
+	 * @throws InvalidInterfaceException
1366
+	 */
1367
+	private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee)
1368
+	{
1369
+		// add relation to attendee
1370
+		$registration->_add_relation_to($attendee, 'Attendee');
1371
+		$registration->set_attendee_id($attendee->ID());
1372
+		$registration->update_cache_after_object_save('Attendee', $attendee);
1373
+	}
1374
+
1375
+
1376
+	/**
1377
+	 *    _associate_registration_with_transaction
1378
+	 *
1379
+	 * @param EE_Registration $registration
1380
+	 * @return void
1381
+	 * @throws EE_Error
1382
+	 * @throws InvalidArgumentException
1383
+	 * @throws ReflectionException
1384
+	 * @throws InvalidDataTypeException
1385
+	 * @throws InvalidInterfaceException
1386
+	 */
1387
+	private function _associate_registration_with_transaction(EE_Registration $registration)
1388
+	{
1389
+		// add relation to registration
1390
+		$this->checkout->transaction->_add_relation_to($registration, 'Registration');
1391
+		$this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
1392
+	}
1393
+
1394
+
1395
+	/**
1396
+	 *    _copy_critical_attendee_details_from_primary_registrant
1397
+	 *    ensures that all attendees at least have data for first name, last name, and email address
1398
+	 *
1399
+	 * @param array $attendee_data
1400
+	 * @return array
1401
+	 * @throws EE_Error
1402
+	 * @throws InvalidArgumentException
1403
+	 * @throws ReflectionException
1404
+	 * @throws InvalidDataTypeException
1405
+	 * @throws InvalidInterfaceException
1406
+	 */
1407
+	private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array())
1408
+	{
1409
+		// bare minimum critical details include first name, last name, email address
1410
+		$critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email');
1411
+		// add address info to critical details?
1412
+		if (apply_filters(
1413
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details',
1414
+			false
1415
+		)) {
1416
+			$address_details = array(
1417
+				'ATT_address',
1418
+				'ATT_address2',
1419
+				'ATT_city',
1420
+				'STA_ID',
1421
+				'CNT_ISO',
1422
+				'ATT_zip',
1423
+				'ATT_phone',
1424
+			);
1425
+			$critical_attendee_details = array_merge($critical_attendee_details, $address_details);
1426
+		}
1427
+		foreach ($critical_attendee_details as $critical_attendee_detail) {
1428
+			if (! isset($attendee_data[ $critical_attendee_detail ])
1429
+				|| empty($attendee_data[ $critical_attendee_detail ])
1430
+			) {
1431
+				$attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get(
1432
+					$critical_attendee_detail
1433
+				);
1434
+			}
1435
+		}
1436
+		return $attendee_data;
1437
+	}
1438
+
1439
+
1440
+	/**
1441
+	 *    update_reg_step
1442
+	 *    this is the final step after a user  revisits the site to edit their attendee information
1443
+	 *    this gets called AFTER the process_reg_step() method above
1444
+	 *
1445
+	 * @return bool
1446
+	 * @throws EE_Error
1447
+	 * @throws InvalidArgumentException
1448
+	 * @throws ReflectionException
1449
+	 * @throws RuntimeException
1450
+	 * @throws InvalidDataTypeException
1451
+	 * @throws InvalidInterfaceException
1452
+	 */
1453
+	public function update_reg_step()
1454
+	{
1455
+		// save everything
1456
+		if ($this->process_reg_step()) {
1457
+			$this->checkout->redirect = true;
1458
+			$this->checkout->redirect_url = add_query_arg(
1459
+				array(
1460
+					'e_reg_url_link' => $this->checkout->reg_url_link,
1461
+					'revisit'        => true,
1462
+				),
1463
+				$this->checkout->thank_you_page_url
1464
+			);
1465
+			$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1466
+			return true;
1467
+		}
1468
+		return false;
1469
+	}
1470 1470
 }
Please login to merge, or discard this patch.
Spacing   +83 added lines, -83 removed lines patch added patch discarded remove patch
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
         );
152 152
 
153 153
         // if this isn't a revisit, and they have the privacy consent box enalbed, add it
154
-        if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
154
+        if ( ! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) {
155 155
             $extra_inputs_section->add_subsections(
156 156
                 array(
157 157
                     'consent_box' => new EE_Form_Section_Proper(
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
                             'layout_strategy' =>
160 160
                                 new EE_Template_Layout(
161 161
                                     array(
162
-                                        'input_template_file' => SPCO_REG_STEPS_PATH . $this->_slug . '/privacy_consent.template.php',
162
+                                        'input_template_file' => SPCO_REG_STEPS_PATH.$this->_slug.'/privacy_consent.template.php',
163 163
                                     )
164 164
                                 ),
165 165
                             'subsections'     => array(
@@ -197,12 +197,12 @@  discard block
 block discarded – undo
197 197
                 if ($registration instanceof EE_Registration
198 198
                     && $this->checkout->visit_allows_processing_of_this_registration($registration)
199 199
                 ) {
200
-                    $subsections[ $registration->reg_url_link() ] = $this->_registrations_reg_form($registration);
201
-                    $template_args['registrations'][ $registration->reg_url_link() ] = $registration;
202
-                    $template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
203
-                        $template_args['ticket_count'][ $registration->ticket()->ID() ]
200
+                    $subsections[$registration->reg_url_link()] = $this->_registrations_reg_form($registration);
201
+                    $template_args['registrations'][$registration->reg_url_link()] = $registration;
202
+                    $template_args['ticket_count'][$registration->ticket()->ID()] = isset(
203
+                        $template_args['ticket_count'][$registration->ticket()->ID()]
204 204
                     )
205
-                        ? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
205
+                        ? $template_args['ticket_count'][$registration->ticket()->ID()] + 1
206 206
                         : 1;
207 207
                     $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
208 208
                         $this->checkout->cart->get_grand_total(),
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
                     $ticket_line_item = is_array($ticket_line_item)
213 213
                         ? reset($ticket_line_item)
214 214
                         : $ticket_line_item;
215
-                    $template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
215
+                    $template_args['ticket_line_item'][$registration->ticket()->ID()] =
216 216
                         $Line_Item_Display->display_line_item($ticket_line_item);
217 217
                     if ($registration->is_primary_registrant()) {
218 218
                         $primary_registrant = $registration->reg_url_link();
@@ -225,10 +225,10 @@  discard block
 block discarded – undo
225 225
                     ? $this->_copy_attendee_info_form()
226 226
                     : $this->_auto_copy_attendee_info();
227 227
                 // generate hidden input
228
-                if (isset($subsections[ $primary_registrant ])
229
-                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
228
+                if (isset($subsections[$primary_registrant])
229
+                    && $subsections[$primary_registrant] instanceof EE_Form_Section_Proper
230 230
                 ) {
231
-                    $subsections[ $primary_registrant ]->add_subsections(
231
+                    $subsections[$primary_registrant]->add_subsections(
232 232
                         $copy_options,
233 233
                         'primary_registrant',
234 234
                         false
@@ -240,8 +240,8 @@  discard block
 block discarded – undo
240 240
         // Set the registration form template (default: one form per ticket details table).
241 241
         // We decide the template to used based on the number of forms.
242 242
         $this->_template = $this->reg_form_count > 1
243
-            ? SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_main.template.php'
244
-            : SPCO_REG_STEPS_PATH . $this->_slug . '/attendee_info_single.template.php';
243
+            ? SPCO_REG_STEPS_PATH . $this->_slug.'/attendee_info_main.template.php'
244
+            : SPCO_REG_STEPS_PATH.$this->_slug.'/attendee_info_single.template.php';
245 245
 
246 246
         return new EE_Form_Section_Proper(
247 247
             array(
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
             if ($question_groups) {
299 299
                 // array of params to pass to parent constructor
300 300
                 $form_args = array(
301
-                    'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
301
+                    'html_id'         => 'ee-registration-'.$registration->reg_url_link(),
302 302
                     'html_class'      => 'ee-reg-form-attendee-dv',
303 303
                     'html_style'      => $this->checkout->admin_request
304 304
                         ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
                 );
321 321
                 foreach ($question_groups as $question_group) {
322 322
                     if ($question_group instanceof EE_Question_Group) {
323
-                        $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form(
323
+                        $form_args['subsections'][$question_group->identifier()] = $this->_question_group_reg_form(
324 324
                             $registration,
325 325
                             $question_group
326 326
                         );
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
         $attendee_nmbr++;
355 355
         
356 356
         // Increment the reg forms number if form is valid.
357
-        if (!empty($form_args)) {
357
+        if ( ! empty($form_args)) {
358 358
             $this->reg_form_count++;
359 359
         }
360 360
 
@@ -377,7 +377,7 @@  discard block
 block discarded – undo
377 377
         // generate hidden input
378 378
         return new EE_Hidden_Input(
379 379
             array(
380
-                'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
380
+                'html_id' => 'additional-attendee-reg-info-'.$registration->reg_url_link(),
381 381
                 'default' => $additional_attendee_reg_info,
382 382
             )
383 383
         );
@@ -398,12 +398,12 @@  discard block
 block discarded – undo
398 398
     {
399 399
         // array of params to pass to parent constructor
400 400
         $form_args = array(
401
-            'html_id'         => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(),
401
+            'html_id'         => 'ee-reg-form-qstn-grp-'.$question_group->identifier().'-'.$registration->ID(),
402 402
             'html_class'      => $this->checkout->admin_request
403 403
                 ? 'form-table ee-reg-form-qstn-grp-dv'
404 404
                 : 'ee-reg-form-qstn-grp-dv',
405
-            'html_label_id'   => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-'
406
-                                 . $registration->ID() . '-lbl',
405
+            'html_label_id'   => 'ee-reg-form-qstn-grp-'.$question_group->identifier().'-'
406
+                                 . $registration->ID().'-lbl',
407 407
             'subsections'     => array(
408 408
                 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group),
409 409
             ),
@@ -414,7 +414,7 @@  discard block
 block discarded – undo
414 414
         // where params
415 415
         $query_params = array('QST_deleted' => 0);
416 416
         // don't load admin only questions on the frontend
417
-        if (! $this->checkout->admin_request) {
417
+        if ( ! $this->checkout->admin_request) {
418 418
             $query_params['QST_admin_only'] = array('!=', true);
419 419
         }
420 420
         $questions = $question_group->get_many_related(
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
                 $identifier = $question->is_system_question()
449 449
                     ? $question->system_ID()
450 450
                     : $question->ID();
451
-                $form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question);
451
+                $form_args['subsections'][$identifier] = $this->reg_form_question($registration, $question);
452 452
             }
453 453
         }
454 454
         $form_args['subsections'] = apply_filters(
@@ -560,7 +560,7 @@  discard block
 block discarded – undo
560 560
     {
561 561
         return new EE_Form_Section_HTML(
562 562
             EEH_Template::locate_template(
563
-                SPCO_REG_STEPS_PATH . $this->_slug . '/_auto_copy_attendee_info.template.php',
563
+                SPCO_REG_STEPS_PATH.$this->_slug.'/_auto_copy_attendee_info.template.php',
564 564
                 apply_filters(
565 565
                     'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args',
566 566
                     array()
@@ -593,17 +593,17 @@  discard block
 block discarded – undo
593 593
                 if ($registration->ticket()->ID() !== $prev_ticket) {
594 594
                     $item_name = $registration->ticket()->name();
595 595
                     $item_name .= $registration->ticket()->description() !== ''
596
-                        ? ' - ' . $registration->ticket()->description()
596
+                        ? ' - '.$registration->ticket()->description()
597 597
                         : '';
598
-                    $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID(
599
-                    ) . ']' ] =
598
+                    $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-'.$registration->ticket()->ID(
599
+                    ).']'] =
600 600
                         new EE_Form_Section_HTML(
601
-                            '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
601
+                            '<h6 class="spco-copy-attendee-event-hdr">'.$item_name.'</h6>'
602 602
                         );
603 603
                     $prev_ticket = $registration->ticket()->ID();
604 604
                 }
605 605
 
606
-                $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] =
606
+                $copy_attendee_info_inputs['spco_copy_attendee_chk['.$registration->ID().']'] =
607 607
                     new EE_Checkbox_Multi_Input(
608 608
                         array(
609 609
                             $registration->ID() => sprintf(
@@ -612,7 +612,7 @@  discard block
 block discarded – undo
612 612
                             ),
613 613
                         ),
614 614
                         array(
615
-                            'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
615
+                            'html_id'                 => 'spco-copy-attendee-chk-'.$registration->reg_url_link(),
616 616
                             'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
617 617
                             'display_html_label_text' => false,
618 618
                         )
@@ -677,14 +677,14 @@  discard block
 block discarded – undo
677 677
         }
678 678
         // verify instance
679 679
         if ($answer instanceof EE_Answer) {
680
-            if (! empty($answer_value)) {
680
+            if ( ! empty($answer_value)) {
681 681
                 $answer->set('ANS_value', $answer_value);
682 682
             }
683 683
             $answer->cache('Question', $question);
684 684
             // remember system ID had a bug where sometimes it could be null
685 685
             $answer_cache_id = $question->is_system_question()
686
-                ? $question->system_ID() . '-' . $registration->reg_url_link()
687
-                : $question->ID() . '-' . $registration->reg_url_link();
686
+                ? $question->system_ID().'-'.$registration->reg_url_link()
687
+                : $question->ID().'-'.$registration->reg_url_link();
688 688
             $registration->cache('Answer', $answer, $answer_cache_id);
689 689
         }
690 690
         return $this->_generate_question_input($registration, $question, $answer);
@@ -707,7 +707,7 @@  discard block
 block discarded – undo
707 707
         $identifier = $question->is_system_question()
708 708
             ? $question->system_ID()
709 709
             : $question->ID();
710
-        $this->_required_questions[ $identifier ] = $question->required() ? true : false;
710
+        $this->_required_questions[$identifier] = $question->required() ? true : false;
711 711
         add_filter(
712 712
             'FHEE__EE_Question__generate_form_input__country_options',
713 713
             array($this, 'use_cached_countries_for_form_input'),
@@ -721,17 +721,17 @@  discard block
 block discarded – undo
721 721
             4
722 722
         );
723 723
         $input_constructor_args = array(
724
-            'html_name'        => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']',
725
-            'html_id'          => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
726
-            'html_class'       => 'ee-reg-qstn ee-reg-qstn-' . $identifier,
727
-            'html_label_id'    => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier,
724
+            'html_name'        => 'ee_reg_qstn['.$registration->ID().']['.$identifier.']',
725
+            'html_id'          => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier,
726
+            'html_class'       => 'ee-reg-qstn ee-reg-qstn-'.$identifier,
727
+            'html_label_id'    => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier,
728 728
             'html_label_class' => 'ee-reg-qstn',
729 729
         );
730 730
         $input_constructor_args['html_label_id'] .= '-lbl';
731 731
         if ($answer instanceof EE_Answer && $answer->ID()) {
732
-            $input_constructor_args['html_name'] .= '[' . $answer->ID() . ']';
733
-            $input_constructor_args['html_id'] .= '-' . $answer->ID();
734
-            $input_constructor_args['html_label_id'] .= '-' . $answer->ID();
732
+            $input_constructor_args['html_name'] .= '['.$answer->ID().']';
733
+            $input_constructor_args['html_id'] .= '-'.$answer->ID();
734
+            $input_constructor_args['html_label_id'] .= '-'.$answer->ID();
735 735
         }
736 736
         $form_input = $question->generate_form_input(
737 737
             $registration,
@@ -775,10 +775,10 @@  discard block
 block discarded – undo
775 775
         $countries = $this->checkout->action === 'process_reg_step'
776 776
             ? EEM_Country::instance()->get_all_countries()
777 777
             : EEM_Country::instance()->get_all_active_countries();
778
-        if (! empty($countries)) {
778
+        if ( ! empty($countries)) {
779 779
             foreach ($countries as $country) {
780 780
                 if ($country instanceof EE_Country) {
781
-                    $country_options[ $country->ID() ] = $country->name();
781
+                    $country_options[$country->ID()] = $country->name();
782 782
                 }
783 783
             }
784 784
         }
@@ -825,10 +825,10 @@  discard block
 block discarded – undo
825 825
         $states = $this->checkout->action === 'process_reg_step'
826 826
             ? EEM_State::instance()->get_all_states()
827 827
             : EEM_State::instance()->get_all_active_states();
828
-        if (! empty($states)) {
828
+        if ( ! empty($states)) {
829 829
             foreach ($states as $state) {
830 830
                 if ($state instanceof EE_State) {
831
-                    $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
831
+                    $state_options[$state->country()->name()][$state->ID()] = $state->name();
832 832
                 }
833 833
             }
834 834
         }
@@ -875,7 +875,7 @@  discard block
 block discarded – undo
875 875
             );
876 876
             return false;
877 877
         }
878
-        if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
878
+        if ( ! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) {
879 879
             EE_Error::add_error(
880 880
                 esc_html__(
881 881
                     'A valid transaction could not be initiated for processing your registrations.',
@@ -902,7 +902,7 @@  discard block
 block discarded – undo
902 902
                     '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.',
903 903
                     'event_espresso'
904 904
                 ),
905
-                '<a href="' . get_post_type_archive_link('espresso_events') . '" >',
905
+                '<a href="'.get_post_type_archive_link('espresso_events').'" >',
906 906
                 '</a>',
907 907
                 '<br />'
908 908
             );
@@ -922,7 +922,7 @@  discard block
 block discarded – undo
922 922
             // but return immediately if the previous step exited early due to errors
923 923
             return false;
924 924
         }
925
-        if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
925
+        if ( ! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) {
926 926
             // generate a correctly translated string for all possible singular/plural combinations
927 927
             if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) {
928 928
                 $error_msg = sprintf(
@@ -1005,7 +1005,7 @@  discard block
 block discarded – undo
1005 1005
         // grab the saved registrations from the transaction
1006 1006
         foreach ($registrations as $registration) {
1007 1007
             // verify EE_Registration object
1008
-            if (! $registration instanceof EE_Registration) {
1008
+            if ( ! $registration instanceof EE_Registration) {
1009 1009
                 EE_Error::add_error(
1010 1010
                     esc_html__(
1011 1011
                         'An invalid Registration object was discovered when attempting to process your registration information.',
@@ -1020,12 +1020,12 @@  discard block
 block discarded – undo
1020 1020
             /** @var string $reg_url_link */
1021 1021
             $reg_url_link = $registration->reg_url_link();
1022 1022
             // reg_url_link exists ?
1023
-            if (! empty($reg_url_link)) {
1023
+            if ( ! empty($reg_url_link)) {
1024 1024
                 // should this registration be processed during this visit ?
1025 1025
                 if ($this->checkout->visit_allows_processing_of_this_registration($registration)) {
1026 1026
                     // if NOT revisiting, then let's save the registration now,
1027 1027
                     // so that we have a REG_ID to use when generating other objects
1028
-                    if (! $this->checkout->revisit) {
1028
+                    if ( ! $this->checkout->revisit) {
1029 1029
                         $registration->save();
1030 1030
                     }
1031 1031
                     /**
@@ -1049,18 +1049,18 @@  discard block
 block discarded – undo
1049 1049
 
1050 1050
                     // Houston, we have a registration!
1051 1051
                     $att_nmbr++;
1052
-                    $this->_attendee_data[ $reg_url_link ] = array();
1052
+                    $this->_attendee_data[$reg_url_link] = array();
1053 1053
                     // grab any existing related answer objects
1054 1054
                     $this->_registration_answers = $registration->answers();
1055 1055
                     // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] );
1056
-                    if (isset($valid_data[ $reg_url_link ])) {
1056
+                    if (isset($valid_data[$reg_url_link])) {
1057 1057
                         // do we need to copy basic info from primary attendee ?
1058
-                        $copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info'])
1059
-                                        && absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
1058
+                        $copy_primary = isset($valid_data[$reg_url_link]['additional_attendee_reg_info'])
1059
+                                        && absint($valid_data[$reg_url_link]['additional_attendee_reg_info']) === 0;
1060 1060
                         // filter form input data for this registration
1061
-                        $valid_data[ $reg_url_link ] = (array) apply_filters(
1061
+                        $valid_data[$reg_url_link] = (array) apply_filters(
1062 1062
                             'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
1063
-                            $valid_data[ $reg_url_link ]
1063
+                            $valid_data[$reg_url_link]
1064 1064
                         );
1065 1065
                         if (isset($valid_data['primary_attendee'])) {
1066 1066
                             $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee'])
@@ -1069,12 +1069,12 @@  discard block
 block discarded – undo
1069 1069
                             unset($valid_data['primary_attendee']);
1070 1070
                         }
1071 1071
                         // now loop through our array of valid post data && process attendee reg forms
1072
-                        foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) {
1073
-                            if (! in_array($form_section, $non_input_form_sections, true)) {
1072
+                        foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) {
1073
+                            if ( ! in_array($form_section, $non_input_form_sections, true)) {
1074 1074
                                 foreach ($form_inputs as $form_input => $input_value) {
1075 1075
                                     // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ );
1076 1076
                                     // check for critical inputs
1077
-                                    if (! $this->_verify_critical_attendee_details_are_set_and_validate_email(
1077
+                                    if ( ! $this->_verify_critical_attendee_details_are_set_and_validate_email(
1078 1078
                                         $form_input,
1079 1079
                                         $input_value
1080 1080
                                     )
@@ -1086,15 +1086,15 @@  discard block
 block discarded – undo
1086 1086
                                         && ! empty($input_value)
1087 1087
                                         && $reg_url_link === $primary_registrant['line_item_id']
1088 1088
                                     ) {
1089
-                                        $primary_registrant[ $form_input ] = $input_value;
1089
+                                        $primary_registrant[$form_input] = $input_value;
1090 1090
                                     } elseif ($copy_primary
1091 1091
                                               && $input_value === null
1092
-                                              && isset($primary_registrant[ $form_input ])
1092
+                                              && isset($primary_registrant[$form_input])
1093 1093
                                     ) {
1094
-                                        $input_value = $primary_registrant[ $form_input ];
1094
+                                        $input_value = $primary_registrant[$form_input];
1095 1095
                                     }
1096 1096
                                     // now attempt to save the input data
1097
-                                    if (! $this->_save_registration_form_input(
1097
+                                    if ( ! $this->_save_registration_form_input(
1098 1098
                                         $registration,
1099 1099
                                         $form_input,
1100 1100
                                         $input_value
@@ -1130,15 +1130,15 @@  discard block
 block discarded – undo
1130 1130
                         $attendee = $this->checkout->primary_attendee_obj;
1131 1131
                     } else {
1132 1132
                         // ensure critical details are set for additional attendees
1133
-                        $this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1
1133
+                        $this->_attendee_data[$reg_url_link] = $att_nmbr > 1
1134 1134
                             ? $this->_copy_critical_attendee_details_from_primary_registrant(
1135
-                                $this->_attendee_data[ $reg_url_link ]
1135
+                                $this->_attendee_data[$reg_url_link]
1136 1136
                             )
1137
-                            : $this->_attendee_data[ $reg_url_link ];
1137
+                            : $this->_attendee_data[$reg_url_link];
1138 1138
                         // execute create attendee command (which may return an existing attendee)
1139 1139
                         $attendee = EE_Registry::instance()->BUS->execute(
1140 1140
                             new CreateAttendeeCommand(
1141
-                                $this->_attendee_data[ $reg_url_link ],
1141
+                                $this->_attendee_data[$reg_url_link],
1142 1142
                                 $registration
1143 1143
                             )
1144 1144
                         );
@@ -1151,7 +1151,7 @@  discard block
 block discarded – undo
1151 1151
                     // add relation to registration, set attendee ID, and cache attendee
1152 1152
                     $this->_associate_attendee_with_registration($registration, $attendee);
1153 1153
                     // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ );
1154
-                    if (! $registration->attendee() instanceof EE_Attendee) {
1154
+                    if ( ! $registration->attendee() instanceof EE_Attendee) {
1155 1155
                         EE_Error::add_error(
1156 1156
                             sprintf(
1157 1157
                                 esc_html_x(
@@ -1201,7 +1201,7 @@  discard block
 block discarded – undo
1201 1201
                     __LINE__
1202 1202
                 );
1203 1203
                 // remove malformed data
1204
-                unset($valid_data[ $reg_url_link ]);
1204
+                unset($valid_data[$reg_url_link]);
1205 1205
                 return false;
1206 1206
             }
1207 1207
         } // end of foreach ( $this->checkout->transaction->registrations()  as $registration )
@@ -1247,10 +1247,10 @@  discard block
 block discarded – undo
1247 1247
          * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
1248 1248
          */
1249 1249
         $answer_cache_id = $this->checkout->reg_url_link
1250
-            ? $form_input . '-' . $registration->reg_url_link()
1250
+            ? $form_input.'-'.$registration->reg_url_link()
1251 1251
             : $form_input;
1252
-        $answer_is_obj = isset($this->_registration_answers[ $answer_cache_id ])
1253
-                         && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer;
1252
+        $answer_is_obj = isset($this->_registration_answers[$answer_cache_id])
1253
+                         && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer;
1254 1254
         // rename form_inputs if they are EE_Attendee properties
1255 1255
         switch ((string) $form_input) {
1256 1256
             case 'state':
@@ -1266,28 +1266,28 @@  discard block
 block discarded – undo
1266 1266
                 break;
1267 1267
 
1268 1268
             default:
1269
-                $ATT_input = 'ATT_' . $form_input;
1269
+                $ATT_input = 'ATT_'.$form_input;
1270 1270
                 // EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ );
1271 1271
                 $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false;
1272
-                $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input;
1272
+                $form_input = $attendee_property ? 'ATT_'.$form_input : $form_input;
1273 1273
         }
1274 1274
         // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ );
1275 1275
         // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ );
1276 1276
         // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ );
1277 1277
         // if this form input has a corresponding attendee property
1278 1278
         if ($attendee_property) {
1279
-            $this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value;
1279
+            $this->_attendee_data[$registration->reg_url_link()][$form_input] = $input_value;
1280 1280
             if ($answer_is_obj) {
1281 1281
                 // and delete the corresponding answer since we won't be storing this data in that object
1282
-                $registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer');
1283
-                $this->_registration_answers[ $answer_cache_id ]->delete_permanently();
1282
+                $registration->_remove_relation_to($this->_registration_answers[$answer_cache_id], 'Answer');
1283
+                $this->_registration_answers[$answer_cache_id]->delete_permanently();
1284 1284
             }
1285 1285
             return true;
1286 1286
         }
1287 1287
         if ($answer_is_obj) {
1288 1288
             // save this data to the answer object
1289
-            $this->_registration_answers[ $answer_cache_id ]->set_value($input_value);
1290
-            $result = $this->_registration_answers[ $answer_cache_id ]->save();
1289
+            $this->_registration_answers[$answer_cache_id]->set_value($input_value);
1290
+            $result = $this->_registration_answers[$answer_cache_id]->save();
1291 1291
             return $result !== false;
1292 1292
         }
1293 1293
         foreach ($this->_registration_answers as $answer) {
@@ -1314,7 +1314,7 @@  discard block
 block discarded – undo
1314 1314
     ) {
1315 1315
         if (empty($input_value)) {
1316 1316
             // if the form input isn't marked as being required, then just return
1317
-            if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) {
1317
+            if ( ! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) {
1318 1318
                 return true;
1319 1319
             }
1320 1320
             switch ($form_input) {
@@ -1425,10 +1425,10 @@  discard block
 block discarded – undo
1425 1425
             $critical_attendee_details = array_merge($critical_attendee_details, $address_details);
1426 1426
         }
1427 1427
         foreach ($critical_attendee_details as $critical_attendee_detail) {
1428
-            if (! isset($attendee_data[ $critical_attendee_detail ])
1429
-                || empty($attendee_data[ $critical_attendee_detail ])
1428
+            if ( ! isset($attendee_data[$critical_attendee_detail])
1429
+                || empty($attendee_data[$critical_attendee_detail])
1430 1430
             ) {
1431
-                $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get(
1431
+                $attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get(
1432 1432
                     $critical_attendee_detail
1433 1433
                 );
1434 1434
             }
Please login to merge, or discard this patch.
core/data_migration_scripts/EE_DMS_Core_4_1_0.dms.php 1 patch
Indentation   +1178 added lines, -1178 removed lines patch added patch discarded remove patch
@@ -12,11 +12,11 @@  discard block
 block discarded – undo
12 12
 $stages = glob(EE_CORE . 'data_migration_scripts/4_1_0_stages/*');
13 13
 $class_to_filepath = array();
14 14
 if (! empty($stages)) {
15
-    foreach ($stages as $filepath) {
16
-        $matches = array();
17
-        preg_match('~4_1_0_stages/(.*).dmsstage.php~', $filepath, $matches);
18
-        $class_to_filepath[ $matches[1] ] = $filepath;
19
-    }
15
+	foreach ($stages as $filepath) {
16
+		$matches = array();
17
+		preg_match('~4_1_0_stages/(.*).dmsstage.php~', $filepath, $matches);
18
+		$class_to_filepath[ $matches[1] ] = $filepath;
19
+	}
20 20
 }
21 21
 // give addons a chance to autoload their stages too
22 22
 $class_to_filepath = apply_filters('FHEE__EE_DMS_4_1_0__autoloaded_stages', $class_to_filepath);
@@ -44,91 +44,91 @@  discard block
 block discarded – undo
44 44
 
45 45
 
46 46
 
47
-    /**
48
-     * EE_DMS_Core_4_1_0 constructor.
49
-     *
50
-     * @param TableManager  $table_manager
51
-     * @param TableAnalysis $table_analysis
52
-     */
53
-    public function __construct(TableManager $table_manager = null, TableAnalysis $table_analysis = null)
54
-    {
55
-        $this->_pretty_name = esc_html__("Data Migration from Event Espresso 3 to Event Espresso 4.1.0", "event_espresso");
56
-        $this->_priority = 10;
57
-        $this->_migration_stages = array(
58
-                new EE_DMS_4_1_0_org_options(),
59
-                new EE_DMS_4_1_0_shortcodes(),
60
-                new EE_DMS_4_1_0_gateways(),
61
-                new EE_DMS_4_1_0_events(),
62
-                new EE_DMS_4_1_0_prices(),
63
-                new EE_DMS_4_1_0_category_details(),
64
-                new EE_DMS_4_1_0_event_category(),
65
-                new EE_DMS_4_1_0_venues(),
66
-                new EE_DMS_4_1_0_event_venue(),
67
-                new EE_DMS_4_1_0_question_groups(),
68
-                new EE_DMS_4_1_0_questions(),
69
-                new EE_DMS_4_1_0_question_group_question(),
70
-                new EE_DMS_4_1_0_event_question_group(),
71
-                new EE_DMS_4_1_0_attendees(),
72
-                new EE_DMS_4_1_0_line_items(),
73
-                new EE_DMS_4_1_0_answers(),
74
-                new EE_DMS_4_1_0_checkins(),
75
-        );
76
-        parent::__construct($table_manager, $table_analysis);
77
-    }
78
-
79
-
80
-
81
-    /**
82
-     * Checks if this 3.1 Check-in table exists. If it doesn't we can't migrate Check-ins
83
-     *
84
-     * @global wpdb $wpdb
85
-     * @return boolean
86
-     */
87
-    private function _checkin_table_exists()
88
-    {
89
-        global $wpdb;
90
-        $results = $wpdb->get_results("SHOW TABLES LIKE '" . $wpdb->prefix . "events_attendee_checkin" . "'");
91
-        if ($results) {
92
-            return true;
93
-        } else {
94
-            return false;
95
-        }
96
-    }
97
-
98
-
99
-
100
-    public function can_migrate_from_version($version_array)
101
-    {
102
-        $version_string = $version_array['Core'];
103
-        if (version_compare($version_string, '4.0.0.decaf', '<') && version_compare($version_string, '3.1.26', '>=')) {
47
+	/**
48
+	 * EE_DMS_Core_4_1_0 constructor.
49
+	 *
50
+	 * @param TableManager  $table_manager
51
+	 * @param TableAnalysis $table_analysis
52
+	 */
53
+	public function __construct(TableManager $table_manager = null, TableAnalysis $table_analysis = null)
54
+	{
55
+		$this->_pretty_name = esc_html__("Data Migration from Event Espresso 3 to Event Espresso 4.1.0", "event_espresso");
56
+		$this->_priority = 10;
57
+		$this->_migration_stages = array(
58
+				new EE_DMS_4_1_0_org_options(),
59
+				new EE_DMS_4_1_0_shortcodes(),
60
+				new EE_DMS_4_1_0_gateways(),
61
+				new EE_DMS_4_1_0_events(),
62
+				new EE_DMS_4_1_0_prices(),
63
+				new EE_DMS_4_1_0_category_details(),
64
+				new EE_DMS_4_1_0_event_category(),
65
+				new EE_DMS_4_1_0_venues(),
66
+				new EE_DMS_4_1_0_event_venue(),
67
+				new EE_DMS_4_1_0_question_groups(),
68
+				new EE_DMS_4_1_0_questions(),
69
+				new EE_DMS_4_1_0_question_group_question(),
70
+				new EE_DMS_4_1_0_event_question_group(),
71
+				new EE_DMS_4_1_0_attendees(),
72
+				new EE_DMS_4_1_0_line_items(),
73
+				new EE_DMS_4_1_0_answers(),
74
+				new EE_DMS_4_1_0_checkins(),
75
+		);
76
+		parent::__construct($table_manager, $table_analysis);
77
+	}
78
+
79
+
80
+
81
+	/**
82
+	 * Checks if this 3.1 Check-in table exists. If it doesn't we can't migrate Check-ins
83
+	 *
84
+	 * @global wpdb $wpdb
85
+	 * @return boolean
86
+	 */
87
+	private function _checkin_table_exists()
88
+	{
89
+		global $wpdb;
90
+		$results = $wpdb->get_results("SHOW TABLES LIKE '" . $wpdb->prefix . "events_attendee_checkin" . "'");
91
+		if ($results) {
92
+			return true;
93
+		} else {
94
+			return false;
95
+		}
96
+	}
97
+
98
+
99
+
100
+	public function can_migrate_from_version($version_array)
101
+	{
102
+		$version_string = $version_array['Core'];
103
+		if (version_compare($version_string, '4.0.0.decaf', '<') && version_compare($version_string, '3.1.26', '>=')) {
104 104
 //          echo "$version_string can be migrated fro";
105
-            return true;
106
-        } elseif (! $version_string) {
105
+			return true;
106
+		} elseif (! $version_string) {
107 107
 //          echo "no version string provided: $version_string";
108
-            // no version string provided... this must be pre 4.1
109
-            // because since 4.1 we're
110
-            return false;// changed mind. dont want people thinking they should migrate yet because they cant
111
-        } else {
108
+			// no version string provided... this must be pre 4.1
109
+			// because since 4.1 we're
110
+			return false;// changed mind. dont want people thinking they should migrate yet because they cant
111
+		} else {
112 112
 //          echo "$version_string doesnt apply";
113
-            return false;
114
-        }
115
-    }
113
+			return false;
114
+		}
115
+	}
116 116
 
117 117
 
118 118
 
119
-    public function schema_changes_before_migration()
120
-    {
121
-        // relies on 4.1's EEH_Activation::create_table
122
-        require_once(EE_HELPERS . 'EEH_Activation.helper.php');
123
-        $table_name = 'esp_answer';
124
-        $sql = "ANS_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
119
+	public function schema_changes_before_migration()
120
+	{
121
+		// relies on 4.1's EEH_Activation::create_table
122
+		require_once(EE_HELPERS . 'EEH_Activation.helper.php');
123
+		$table_name = 'esp_answer';
124
+		$sql = "ANS_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
125 125
 					REG_ID int(10) unsigned NOT NULL,
126 126
 					QST_ID int(10) unsigned NOT NULL,
127 127
 					ANS_value text NOT NULL,
128 128
 					PRIMARY KEY  (ANS_ID)";
129
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
130
-        $table_name = 'esp_attendee_meta';
131
-        $sql = "ATTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
129
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
130
+		$table_name = 'esp_attendee_meta';
131
+		$sql = "ATTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
132 132
 						ATT_ID bigint(20) unsigned NOT NULL,
133 133
 						ATT_fname varchar(45) NOT NULL,
134 134
 						ATT_lname varchar(45) NOT NULL,
@@ -144,9 +144,9 @@  discard block
 block discarded – undo
144 144
 								KEY ATT_fname (ATT_fname),
145 145
 								KEY ATT_lname (ATT_lname),
146 146
 								KEY ATT_email (ATT_email(191))";
147
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
148
-        $table_name = 'esp_country';
149
-        $sql = "CNT_ISO varchar(2) COLLATE utf8_bin NOT NULL,
147
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
148
+		$table_name = 'esp_country';
149
+		$sql = "CNT_ISO varchar(2) COLLATE utf8_bin NOT NULL,
150 150
 					  CNT_ISO3 varchar(3) COLLATE utf8_bin NOT NULL,
151 151
 					  RGN_ID tinyint(3) unsigned DEFAULT NULL,
152 152
 					  CNT_name varchar(45) COLLATE utf8_bin NOT NULL,
@@ -162,9 +162,9 @@  discard block
 block discarded – undo
162 162
 					  CNT_is_EU tinyint(1) DEFAULT '0',
163 163
 					  CNT_active tinyint(1) DEFAULT '0',
164 164
 					  PRIMARY KEY  (CNT_ISO)";
165
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
166
-        $table_name = 'esp_datetime';
167
-        $sql = "DTT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
165
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
166
+		$table_name = 'esp_datetime';
167
+		$sql = "DTT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
168 168
 				  EVT_ID bigint(20) unsigned NOT NULL,
169 169
 				  DTT_EVT_start datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
170 170
 				  DTT_EVT_end datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
@@ -177,9 +177,9 @@  discard block
 block discarded – undo
177 177
 						PRIMARY KEY  (DTT_ID),
178 178
 						KEY EVT_ID (EVT_ID),
179 179
 						KEY DTT_is_primary (DTT_is_primary)";
180
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
181
-        $table_name = 'esp_event_meta';
182
-        $sql = "
180
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
181
+		$table_name = 'esp_event_meta';
182
+		$sql = "
183 183
 			EVTM_ID int(10) NOT NULL AUTO_INCREMENT,
184 184
 			EVT_ID bigint(20) unsigned NOT NULL,
185 185
 			EVT_display_desc tinyint(1) unsigned NOT NULL DEFAULT 1,
@@ -194,31 +194,31 @@  discard block
 block discarded – undo
194 194
 			EVT_external_URL varchar(200) NULL,
195 195
 			EVT_donations tinyint(1) NULL,
196 196
 			PRIMARY KEY  (EVTM_ID)";
197
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
198
-        $table_name = 'esp_event_question_group';
199
-        $sql = "EQG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
197
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
198
+		$table_name = 'esp_event_question_group';
199
+		$sql = "EQG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
200 200
 					EVT_ID bigint(20) unsigned NOT NULL,
201 201
 					QSG_ID int(10) unsigned NOT NULL,
202 202
 					EQG_primary tinyint(1) unsigned NOT NULL DEFAULT 0,
203 203
 					PRIMARY KEY  (EQG_ID)";
204
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
205
-        $table_name = 'esp_event_venue';
206
-        $sql = "EVV_ID int(11) NOT NULL AUTO_INCREMENT,
204
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
205
+		$table_name = 'esp_event_venue';
206
+		$sql = "EVV_ID int(11) NOT NULL AUTO_INCREMENT,
207 207
 				EVT_ID bigint(20) unsigned NOT NULL,
208 208
 				VNU_ID bigint(20) unsigned NOT NULL,
209 209
 				EVV_primary tinyint(1) unsigned NOT NULL DEFAULT 0,
210 210
 				PRIMARY KEY  (EVV_ID)";
211
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
212
-        $table_name = 'esp_extra_meta';
213
-        $sql = "EXM_ID int(11) NOT NULL AUTO_INCREMENT,
211
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
212
+		$table_name = 'esp_extra_meta';
213
+		$sql = "EXM_ID int(11) NOT NULL AUTO_INCREMENT,
214 214
 				OBJ_ID int(11) DEFAULT NULL,
215 215
 				EXM_type varchar(45) DEFAULT NULL,
216 216
 				EXM_key varchar(45) DEFAULT NULL,
217 217
 				EXM_value text,
218 218
 				PRIMARY KEY  (EXM_ID)";
219
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
220
-        $table_name = 'esp_line_item';
221
-        $sql = "LIN_ID int(11) NOT NULL AUTO_INCREMENT,
219
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
220
+		$table_name = 'esp_line_item';
221
+		$sql = "LIN_ID int(11) NOT NULL AUTO_INCREMENT,
222 222
 				LIN_code varchar(245) NOT NULL DEFAULT '',
223 223
 				TXN_ID int(11) DEFAULT NULL,
224 224
 				LIN_name varchar(245) NOT NULL DEFAULT '',
@@ -234,18 +234,18 @@  discard block
 block discarded – undo
234 234
 				OBJ_ID int(11) DEFAULT NULL,
235 235
 				OBJ_type varchar(45)DEFAULT NULL,
236 236
 				PRIMARY KEY  (LIN_ID)";
237
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
238
-        $table_name = 'esp_message_template';
239
-        $sql = "MTP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
237
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
238
+		$table_name = 'esp_message_template';
239
+		$sql = "MTP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
240 240
 					GRP_ID int(10) unsigned NOT NULL,
241 241
 					MTP_context varchar(50) NOT NULL,
242 242
 					MTP_template_field varchar(30) NOT NULL,
243 243
 					MTP_content text NOT NULL,
244 244
 					PRIMARY KEY  (MTP_ID),
245 245
 					KEY GRP_ID (GRP_ID)";
246
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
247
-        $table_name = 'esp_message_template_group';
248
-        $sql = "GRP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
246
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
247
+		$table_name = 'esp_message_template_group';
248
+		$sql = "GRP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
249 249
 					EVT_ID bigint(20) unsigned DEFAULT NULL,
250 250
 					MTP_user_id int(10) NOT NULL DEFAULT '1',
251 251
 					MTP_messenger varchar(30) NOT NULL,
@@ -257,9 +257,9 @@  discard block
 block discarded – undo
257 257
 					PRIMARY KEY  (GRP_ID),
258 258
 					KEY EVT_ID (EVT_ID),
259 259
 					KEY MTP_user_id (MTP_user_id)";
260
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
261
-        $table_name = 'esp_payment';
262
-        $sql = "PAY_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
260
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
261
+		$table_name = 'esp_payment';
262
+		$sql = "PAY_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
263 263
 					TXN_ID int(10) unsigned DEFAULT NULL,
264 264
 					STS_ID varchar(3) COLLATE utf8_bin DEFAULT NULL,
265 265
 					PAY_timestamp datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
@@ -275,9 +275,9 @@  discard block
 block discarded – undo
275 275
 					PRIMARY KEY  (PAY_ID),
276 276
 					KEY TXN_ID (TXN_ID),
277 277
 					KEY PAY_timestamp (PAY_timestamp)";
278
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
279
-        $table_name = "esp_ticket";
280
-        $sql = "TKT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
278
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
279
+		$table_name = "esp_ticket";
280
+		$sql = "TKT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
281 281
 					  TTM_ID int(10) unsigned NOT NULL,
282 282
 					  TKT_name varchar(245) NOT NULL DEFAULT '',
283 283
 					  TKT_description text NOT NULL,
@@ -296,28 +296,28 @@  discard block
 block discarded – undo
296 296
 					  TKT_parent int(10) unsigned DEFAULT '0',
297 297
 					  TKT_deleted tinyint(1) NOT NULL DEFAULT '0',
298 298
 					  PRIMARY KEY  (TKT_ID)";
299
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
300
-        $table_name = "esp_ticket_price";
301
-        $sql = "TKP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
299
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
300
+		$table_name = "esp_ticket_price";
301
+		$sql = "TKP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
302 302
 					  TKT_ID int(10) unsigned NOT NULL,
303 303
 					  PRC_ID int(10) unsigned NOT NULL,
304 304
 					  PRIMARY KEY  (TKP_ID)";
305
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
306
-        $table_name = "esp_datetime_ticket";
307
-        $sql = "DTK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
305
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
306
+		$table_name = "esp_datetime_ticket";
307
+		$sql = "DTK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
308 308
 					  DTT_ID int(10) unsigned NOT NULL,
309 309
 					  TKT_ID int(10) unsigned NOT NULL,
310 310
 					  PRIMARY KEY  (DTK_ID)";
311
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
312
-        $table_name = "esp_ticket_template";
313
-        $sql = "TTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
311
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
312
+		$table_name = "esp_ticket_template";
313
+		$sql = "TTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
314 314
 					  TTM_name varchar(45) NOT NULL,
315 315
 					  TTM_description text,
316 316
 					  TTM_file varchar(45),
317 317
 					  PRIMARY KEY  (TTM_ID)";
318
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
319
-        $table_name = "esp_price";
320
-        $sql = "PRC_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
318
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
319
+		$table_name = "esp_price";
320
+		$sql = "PRC_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
321 321
 					  PRT_ID tinyint(3) unsigned NOT NULL,
322 322
 					  PRC_amount decimal(10,3) NOT NULL DEFAULT '0.00',
323 323
 					  PRC_name varchar(245) NOT NULL,
@@ -328,9 +328,9 @@  discard block
 block discarded – undo
328 328
 					  PRC_order tinyint(3) unsigned NOT NULL DEFAULT '0',
329 329
 					  PRC_parent int(10) unsigned DEFAULT 0,
330 330
 					  PRIMARY KEY  (PRC_ID)";
331
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
332
-        $table_name = "esp_price_type";
333
-        $sql = "PRT_ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
331
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
332
+		$table_name = "esp_price_type";
333
+		$sql = "PRT_ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
334 334
 				  PRT_name varchar(45) NOT NULL,
335 335
 				  PBT_ID tinyint(3) unsigned NOT NULL DEFAULT '1',
336 336
 				  PRT_is_percent tinyint(1) NOT NULL DEFAULT '0',
@@ -338,9 +338,9 @@  discard block
 block discarded – undo
338 338
 				  PRT_deleted tinyint(1) NOT NULL DEFAULT '0',
339 339
 				  UNIQUE KEY PRT_name_UNIQUE (PRT_name),
340 340
 				  PRIMARY KEY  (PRT_ID)";
341
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
342
-        $table_name = 'esp_question';
343
-        $sql = 'QST_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
341
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
342
+		$table_name = 'esp_question';
343
+		$sql = 'QST_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
344 344
 					QST_display_text text NOT NULL,
345 345
 					QST_admin_label varchar(255) NOT NULL,
346 346
 					QST_system varchar(25) DEFAULT NULL,
@@ -352,10 +352,10 @@  discard block
 block discarded – undo
352 352
 					QST_wp_user bigint(20) unsigned NULL,
353 353
 					QST_deleted tinyint(1) unsigned NOT NULL DEFAULT 0,
354 354
 					PRIMARY KEY  (QST_ID)';
355
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
356
-        $this->_get_table_manager()->dropIndex('esp_question_group', 'QSG_identifier_UNIQUE');
357
-        $table_name = 'esp_question_group';
358
-        $sql = 'QSG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
355
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
356
+		$this->_get_table_manager()->dropIndex('esp_question_group', 'QSG_identifier_UNIQUE');
357
+		$table_name = 'esp_question_group';
358
+		$sql = 'QSG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
359 359
 					QSG_name varchar(255) NOT NULL,
360 360
 					QSG_identifier varchar(100) NOT NULL,
361 361
 					QSG_desc text NULL,
@@ -366,23 +366,23 @@  discard block
 block discarded – undo
366 366
 					QSG_deleted tinyint(1) unsigned NOT NULL DEFAULT 0,
367 367
 					PRIMARY KEY  (QSG_ID),
368 368
 					UNIQUE KEY QSG_identifier_UNIQUE (QSG_identifier ASC)';
369
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
370
-        $table_name = 'esp_question_group_question';
371
-        $sql = "QGQ_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
369
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
370
+		$table_name = 'esp_question_group_question';
371
+		$sql = "QGQ_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
372 372
 					QSG_ID int(10) unsigned NOT NULL,
373 373
 					QST_ID int(10) unsigned NOT NULL,
374 374
 					PRIMARY KEY  (QGQ_ID) ";
375
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
376
-        $table_name = 'esp_question_option';
377
-        $sql = "QSO_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
375
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
376
+		$table_name = 'esp_question_option';
377
+		$sql = "QSO_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
378 378
 					QSO_value varchar(255) NOT NULL,
379 379
 					QSO_desc text NOT NULL,
380 380
 					QST_ID int(10) unsigned NOT NULL,
381 381
 					QSO_deleted tinyint(1) unsigned NOT NULL DEFAULT 0,
382 382
 					PRIMARY KEY  (QSO_ID)";
383
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
384
-        $table_name = 'esp_registration';
385
-        $sql = "REG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
383
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
384
+		$table_name = 'esp_registration';
385
+		$sql = "REG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
386 386
 					  EVT_ID bigint(20) unsigned NOT NULL,
387 387
 					  ATT_ID bigint(20) unsigned NOT NULL,
388 388
 					  TXN_ID int(10) unsigned NOT NULL,
@@ -405,25 +405,25 @@  discard block
 block discarded – undo
405 405
 					  KEY STS_ID (STS_ID),
406 406
 					  KEY REG_url_link (REG_url_link),
407 407
 					  KEY REG_code (REG_code)";
408
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
409
-        $table_name = 'esp_checkin';
410
-        $sql = "CHK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
408
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
409
+		$table_name = 'esp_checkin';
410
+		$sql = "CHK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
411 411
 					REG_ID int(10) unsigned NOT NULL,
412 412
 					DTT_ID int(10) unsigned NOT NULL,
413 413
 					CHK_in tinyint(1) unsigned NOT NULL DEFAULT 1,
414 414
 					CHK_timestamp datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
415 415
 					PRIMARY KEY  (CHK_ID)";
416
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
417
-        $table_name = 'esp_state';
418
-        $sql = "STA_ID smallint(5) unsigned NOT NULL AUTO_INCREMENT,
416
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
417
+		$table_name = 'esp_state';
418
+		$sql = "STA_ID smallint(5) unsigned NOT NULL AUTO_INCREMENT,
419 419
 					  CNT_ISO varchar(2) COLLATE utf8_bin NOT NULL,
420 420
 					  STA_abbrev varchar(6) COLLATE utf8_bin NOT NULL,
421 421
 					  STA_name varchar(100) COLLATE utf8_bin NOT NULL,
422 422
 					  STA_active tinyint(1) DEFAULT '1',
423 423
 					  PRIMARY KEY  (STA_ID)";
424
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
425
-        $table_name = 'esp_status';
426
-        $sql = "STS_ID varchar(3) COLLATE utf8_bin NOT NULL,
424
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
425
+		$table_name = 'esp_status';
426
+		$sql = "STS_ID varchar(3) COLLATE utf8_bin NOT NULL,
427 427
 					  STS_code varchar(45) COLLATE utf8_bin NOT NULL,
428 428
 					  STS_type set('event','registration','transaction','payment','email') COLLATE utf8_bin NOT NULL,
429 429
 					  STS_can_edit tinyint(1) NOT NULL DEFAULT 0,
@@ -431,9 +431,9 @@  discard block
 block discarded – undo
431 431
 					  STS_open tinyint(1) NOT NULL DEFAULT 1,
432 432
 					  UNIQUE KEY STS_ID_UNIQUE (STS_ID),
433 433
 					  KEY STS_type (STS_type)";
434
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
435
-        $table_name = 'esp_transaction';
436
-        $sql = "TXN_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
434
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
435
+		$table_name = 'esp_transaction';
436
+		$sql = "TXN_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
437 437
 					  TXN_timestamp datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
438 438
 					  TXN_total decimal(10,3) DEFAULT '0.00',
439 439
 					  TXN_paid decimal(10,3) NOT NULL DEFAULT '0.00',
@@ -443,9 +443,9 @@  discard block
 block discarded – undo
443 443
 					  PRIMARY KEY  (TXN_ID),
444 444
 					  KEY TXN_timestamp (TXN_timestamp),
445 445
 					  KEY STS_ID (STS_ID)";
446
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
447
-        $table_name = 'esp_venue_meta';
448
-        $sql = "VNUM_ID int(11) NOT NULL AUTO_INCREMENT,
446
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
447
+		$table_name = 'esp_venue_meta';
448
+		$sql = "VNUM_ID int(11) NOT NULL AUTO_INCREMENT,
449 449
 			VNU_ID bigint(20) unsigned NOT NULL DEFAULT 0,
450 450
 			VNU_address varchar(255) DEFAULT NULL,
451 451
 			VNU_address2 varchar(255) DEFAULT NULL,
@@ -463,52 +463,52 @@  discard block
 block discarded – undo
463 463
 			PRIMARY KEY  (VNUM_ID),
464 464
 			KEY STA_ID (STA_ID),
465 465
 			KEY CNT_ISO (CNT_ISO)";
466
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
467
-        // setting up the default stats and countries is also essential for the data migrations to run
468
-        // (because many need to convert old string states to foreign keys into the states table)
469
-        $this->insert_default_states();
470
-        $this->insert_default_countries();
471
-        // setting up default prices, price types, and tickets is also essential for the price migrations
472
-        $this->insert_default_price_types();
473
-        $this->insert_default_prices();
474
-        $this->insert_default_tickets();
475
-        // setting up the config wp option pretty well counts as a 'schema change', or at least should happen ehre
476
-        EE_Config::instance()->update_espresso_config(false, true);
477
-        return true;
478
-    }
479
-
480
-
481
-
482
-    /**
483
-     * Yes we could have cleaned up the ee3 tables here. But just in case someone
484
-     * didn't backup their DB, and decides they want ot keep using EE3, we'll
485
-     * leave them for now. Mayeb remove them in 4.5 or something.
486
-     *
487
-     * @return boolean
488
-     */
489
-    public function schema_changes_after_migration()
490
-    {
491
-        return true;
492
-    }
493
-
494
-
495
-
496
-    /**
497
-     * insert_default_states
498
-     *
499
-     * @access public
500
-     * @static
501
-     * @return void
502
-     */
503
-    public function insert_default_states()
504
-    {
505
-        global $wpdb;
506
-        $state_table = $wpdb->prefix . "esp_state";
507
-        if ($this->_get_table_analysis()->tableExists($state_table)) {
508
-            $SQL = "SELECT COUNT('STA_ID') FROM " . $state_table;
509
-            $states = $wpdb->get_var($SQL);
510
-            if (! $states) {
511
-                $SQL = "INSERT INTO " . $state_table . "
466
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
467
+		// setting up the default stats and countries is also essential for the data migrations to run
468
+		// (because many need to convert old string states to foreign keys into the states table)
469
+		$this->insert_default_states();
470
+		$this->insert_default_countries();
471
+		// setting up default prices, price types, and tickets is also essential for the price migrations
472
+		$this->insert_default_price_types();
473
+		$this->insert_default_prices();
474
+		$this->insert_default_tickets();
475
+		// setting up the config wp option pretty well counts as a 'schema change', or at least should happen ehre
476
+		EE_Config::instance()->update_espresso_config(false, true);
477
+		return true;
478
+	}
479
+
480
+
481
+
482
+	/**
483
+	 * Yes we could have cleaned up the ee3 tables here. But just in case someone
484
+	 * didn't backup their DB, and decides they want ot keep using EE3, we'll
485
+	 * leave them for now. Mayeb remove them in 4.5 or something.
486
+	 *
487
+	 * @return boolean
488
+	 */
489
+	public function schema_changes_after_migration()
490
+	{
491
+		return true;
492
+	}
493
+
494
+
495
+
496
+	/**
497
+	 * insert_default_states
498
+	 *
499
+	 * @access public
500
+	 * @static
501
+	 * @return void
502
+	 */
503
+	public function insert_default_states()
504
+	{
505
+		global $wpdb;
506
+		$state_table = $wpdb->prefix . "esp_state";
507
+		if ($this->_get_table_analysis()->tableExists($state_table)) {
508
+			$SQL = "SELECT COUNT('STA_ID') FROM " . $state_table;
509
+			$states = $wpdb->get_var($SQL);
510
+			if (! $states) {
511
+				$SQL = "INSERT INTO " . $state_table . "
512 512
 				(STA_ID, CNT_ISO, STA_abbrev, STA_name, STA_active) VALUES
513 513
 				(1, 'US', 'AK', 'Alaska', 1),
514 514
 				(2, 'US', 'AL', 'Alabama', 1),
@@ -582,29 +582,29 @@  discard block
 block discarded – undo
582 582
 				(70, 'CA', 'NT', 'Northwest Territories', 1),
583 583
 				(71, 'CA', 'NU', 'Nunavut', 1),
584 584
 				(72, 'CA', 'YT', 'Yukon', 1);";
585
-                $wpdb->query($SQL);
586
-            }
587
-        }
588
-    }
589
-
590
-
591
-
592
-    /**
593
-     * insert_default_countries
594
-     *
595
-     * @access public
596
-     * @static
597
-     * @return void
598
-     */
599
-    public function insert_default_countries()
600
-    {
601
-        global $wpdb;
602
-        $country_table = $wpdb->prefix . "esp_country";
603
-        if ($this->_get_table_analysis()->tableExists($country_table)) {
604
-            $SQL = "SELECT COUNT('CNT_ISO') FROM " . $country_table;
605
-            $countries = $wpdb->get_var($SQL);
606
-            if (! $countries) {
607
-                $SQL = "INSERT INTO " . $country_table . "
585
+				$wpdb->query($SQL);
586
+			}
587
+		}
588
+	}
589
+
590
+
591
+
592
+	/**
593
+	 * insert_default_countries
594
+	 *
595
+	 * @access public
596
+	 * @static
597
+	 * @return void
598
+	 */
599
+	public function insert_default_countries()
600
+	{
601
+		global $wpdb;
602
+		$country_table = $wpdb->prefix . "esp_country";
603
+		if ($this->_get_table_analysis()->tableExists($country_table)) {
604
+			$SQL = "SELECT COUNT('CNT_ISO') FROM " . $country_table;
605
+			$countries = $wpdb->get_var($SQL);
606
+			if (! $countries) {
607
+				$SQL = "INSERT INTO " . $country_table . "
608 608
 				(CNT_ISO, CNT_ISO3, RGN_ID, CNT_name, CNT_cur_code, CNT_cur_single, CNT_cur_plural, CNT_cur_sign, CNT_cur_sign_b4, CNT_cur_dec_plc, CNT_tel_code, CNT_is_EU, CNT_active) VALUES
609 609
 				('AD', 'AND', 0, 'Andorra', 'EUR', 'Euro', 'Euros', '€', 1, 2, '+376', 0, 0),
610 610
 				('AE', 'ARE', 0, 'United Arab Emirates', 'AED', 'Dirham', 'Dirhams', 'د.إ', 1, 2, '+971', 0, 0),
@@ -832,984 +832,984 @@  discard block
 block discarded – undo
832 832
 				('ZA', 'ZAF', 0, 'South Africa', 'ZAR', 'Rand', 'Rands', 'R', 1, 2, '+27', 0, 0),
833 833
 				('ZM', 'ZMB', 0, 'Zambia', 'ZMK', 'Kwacha', 'Kwachas', '', 1, 2, '+260', 0, 0),
834 834
 				('ZW', 'ZWE', 0, 'Zimbabwe', 'ZWD', 'Dollar', 'Dollars', 'Z$', 1, 2, '+263', 0, 0);";
835
-                $wpdb->query($SQL);
836
-            }
837
-        }
838
-    }
839
-
840
-
841
-
842
-    /**
843
-     * insert_default_price_types
844
-     *
845
-     * @access public
846
-     * @static
847
-     * @return void
848
-     */
849
-    public function insert_default_price_types()
850
-    {
851
-        global $wpdb;
852
-        $price_type_table = $wpdb->prefix . "esp_price_type";
853
-        if ($this->_get_table_analysis()->tableExists($price_type_table)) {
854
-            $SQL = 'SELECT COUNT(PRT_ID) FROM ' . $price_type_table;
855
-            $price_types_exist = $wpdb->get_var($SQL);
856
-            if (! $price_types_exist) {
857
-                $SQL = "INSERT INTO $price_type_table ( PRT_ID, PRT_name, PBT_ID, PRT_is_percent, PRT_order, PRT_deleted ) VALUES
835
+				$wpdb->query($SQL);
836
+			}
837
+		}
838
+	}
839
+
840
+
841
+
842
+	/**
843
+	 * insert_default_price_types
844
+	 *
845
+	 * @access public
846
+	 * @static
847
+	 * @return void
848
+	 */
849
+	public function insert_default_price_types()
850
+	{
851
+		global $wpdb;
852
+		$price_type_table = $wpdb->prefix . "esp_price_type";
853
+		if ($this->_get_table_analysis()->tableExists($price_type_table)) {
854
+			$SQL = 'SELECT COUNT(PRT_ID) FROM ' . $price_type_table;
855
+			$price_types_exist = $wpdb->get_var($SQL);
856
+			if (! $price_types_exist) {
857
+				$SQL = "INSERT INTO $price_type_table ( PRT_ID, PRT_name, PBT_ID, PRT_is_percent, PRT_order, PRT_deleted ) VALUES
858 858
 							(1, '" . esc_html__('Base Price', 'event_espresso') . "', 1,  0, 0, 0),
859 859
 							(2, '" . esc_html__('Percent Discount', 'event_espresso') . "', 2,  1, 20, 0),
860 860
 							(3, '" . esc_html__('Fixed Discount', 'event_espresso') . "', 2,  0, 30, 0),
861 861
 							(4, '" . esc_html__('Percent Surcharge', 'event_espresso') . "', 3,  1, 40, 0),
862 862
 							(5, '" . esc_html__('Fixed Surcharge', 'event_espresso') . "', 3,  0, 50, 0);";
863
-                $SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_price_types__SQL', $SQL);
864
-                $wpdb->query($SQL);
865
-            }
866
-        }
867
-    }
868
-
869
-
870
-
871
-    /**
872
-     * insert_default_prices. We assume we're upgrading to regular here.
873
-     * If we're INSTALLING 4.1 CAF, then we add a few extra default prices
874
-     * when EEH_Activaion's initialize_db_content is called via  ahook in
875
-     * EE_BRewing_regular
876
-     *
877
-     * @access public
878
-     * @static
879
-     * @return void
880
-     */
881
-    public function insert_default_prices()
882
-    {
883
-        global $wpdb;
884
-        $price_table = $wpdb->prefix . "esp_price";
885
-        if ($this->_get_table_analysis()->tableExists($price_table)) {
886
-            $SQL = 'SELECT COUNT(PRC_ID) FROM ' . $price_table;
887
-            $prices_exist = $wpdb->get_var($SQL);
888
-            if (! $prices_exist) {
889
-                $SQL = "INSERT INTO $price_table
863
+				$SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_price_types__SQL', $SQL);
864
+				$wpdb->query($SQL);
865
+			}
866
+		}
867
+	}
868
+
869
+
870
+
871
+	/**
872
+	 * insert_default_prices. We assume we're upgrading to regular here.
873
+	 * If we're INSTALLING 4.1 CAF, then we add a few extra default prices
874
+	 * when EEH_Activaion's initialize_db_content is called via  ahook in
875
+	 * EE_BRewing_regular
876
+	 *
877
+	 * @access public
878
+	 * @static
879
+	 * @return void
880
+	 */
881
+	public function insert_default_prices()
882
+	{
883
+		global $wpdb;
884
+		$price_table = $wpdb->prefix . "esp_price";
885
+		if ($this->_get_table_analysis()->tableExists($price_table)) {
886
+			$SQL = 'SELECT COUNT(PRC_ID) FROM ' . $price_table;
887
+			$prices_exist = $wpdb->get_var($SQL);
888
+			if (! $prices_exist) {
889
+				$SQL = "INSERT INTO $price_table
890 890
 							(PRC_ID, PRT_ID, PRC_amount, PRC_name, PRC_desc,  PRC_is_default, PRC_overrides, PRC_order, PRC_deleted, PRC_parent ) VALUES
891 891
 							(1, 1, '0.00', 'Free Admission', '', 1, null, 0, 0, 0);";
892
-                $SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_prices__SQL', $SQL);
893
-                $wpdb->query($SQL);
894
-            }
895
-        }
896
-    }
897
-
898
-
899
-
900
-    /**
901
-     * insert default ticket
902
-     *
903
-     * @access public
904
-     * @static
905
-     * @return void
906
-     */
907
-    public function insert_default_tickets()
908
-    {
909
-        global $wpdb;
910
-        $ticket_table = $wpdb->prefix . "esp_ticket";
911
-        if ($this->_get_table_analysis()->tableExists($ticket_table)) {
912
-            $SQL = 'SELECT COUNT(TKT_ID) FROM ' . $ticket_table;
913
-            $tickets_exist = $wpdb->get_var($SQL);
914
-            if (! $tickets_exist) {
915
-                $SQL = "INSERT INTO $ticket_table
892
+				$SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_prices__SQL', $SQL);
893
+				$wpdb->query($SQL);
894
+			}
895
+		}
896
+	}
897
+
898
+
899
+
900
+	/**
901
+	 * insert default ticket
902
+	 *
903
+	 * @access public
904
+	 * @static
905
+	 * @return void
906
+	 */
907
+	public function insert_default_tickets()
908
+	{
909
+		global $wpdb;
910
+		$ticket_table = $wpdb->prefix . "esp_ticket";
911
+		if ($this->_get_table_analysis()->tableExists($ticket_table)) {
912
+			$SQL = 'SELECT COUNT(TKT_ID) FROM ' . $ticket_table;
913
+			$tickets_exist = $wpdb->get_var($SQL);
914
+			if (! $tickets_exist) {
915
+				$SQL = "INSERT INTO $ticket_table
916 916
 					( TKT_ID, TTM_ID, TKT_name, TKT_description, TKT_qty, TKT_sold, TKT_uses, TKT_min, TKT_max, TKT_price, TKT_start_date, TKT_end_date, TKT_taxable, TKT_order, TKT_row, TKT_is_default, TKT_parent, TKT_deleted ) VALUES
917 917
 					( 1, 0, '"
918
-                       . esc_html__("Free Ticket", "event_espresso")
919
-                       . "', '', 100, 0, -1, 0, -1, 0.00, '0000-00-00 00:00:00', '0000-00-00 00:00:00', 0, 0, 1, 1, 0, 0);";
920
-                $SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_tickets__SQL', $SQL);
921
-                $wpdb->query($SQL);
922
-            }
923
-        }
924
-        $ticket_price_table = $wpdb->prefix . "esp_ticket_price";
925
-        if ($this->_get_table_analysis()->tableExists($ticket_price_table)) {
926
-            $SQL = 'SELECT COUNT(TKP_ID) FROM ' . $ticket_price_table;
927
-            $ticket_prc_exist = $wpdb->get_var($SQL);
928
-            if (! $ticket_prc_exist) {
929
-                $SQL = "INSERT INTO $ticket_price_table
918
+					   . esc_html__("Free Ticket", "event_espresso")
919
+					   . "', '', 100, 0, -1, 0, -1, 0.00, '0000-00-00 00:00:00', '0000-00-00 00:00:00', 0, 0, 1, 1, 0, 0);";
920
+				$SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_tickets__SQL', $SQL);
921
+				$wpdb->query($SQL);
922
+			}
923
+		}
924
+		$ticket_price_table = $wpdb->prefix . "esp_ticket_price";
925
+		if ($this->_get_table_analysis()->tableExists($ticket_price_table)) {
926
+			$SQL = 'SELECT COUNT(TKP_ID) FROM ' . $ticket_price_table;
927
+			$ticket_prc_exist = $wpdb->get_var($SQL);
928
+			if (! $ticket_prc_exist) {
929
+				$SQL = "INSERT INTO $ticket_price_table
930 930
 				( TKP_ID, TKT_ID, PRC_ID ) VALUES
931 931
 				( 1, 1, 1 )
932 932
 				";
933
-                $SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_tickets__SQL__ticket_price', $SQL);
934
-                $wpdb->query($SQL);
935
-            }
936
-        }
937
-    }
938
-
939
-
940
-
941
-    /**
942
-     * Gets a country entry as an array, or creates one if none is found. Much like EEM_Country::instance()->get_one(),
943
-     * but is independent of outside code which can change in future versions of EE. Also, $country_name CAN be a 3.1
944
-     * country ID (int), a 2-letter ISO, 3-letter ISO, or name
945
-     *
946
-     * @global type  $wpdb
947
-     * @param string $country_name
948
-     * @return array where keys are columns, values are column values
949
-     */
950
-    public function get_or_create_country($country_name)
951
-    {
952
-        if (! $country_name) {
953
-            throw new EE_Error(esc_html__("Could not get a country because country name is blank", "event_espresso"));
954
-        }
955
-        global $wpdb;
956
-        $country_table = $wpdb->prefix . "esp_country";
957
-        if (is_int($country_name)) {
958
-            $country_name = $this->get_iso_from_3_1_country_id($country_name);
959
-        }
960
-        $country = $wpdb->get_row($wpdb->prepare("SELECT * FROM $country_table WHERE
933
+				$SQL = apply_filters('FHEE__EE_DMS_4_1_0__insert_default_tickets__SQL__ticket_price', $SQL);
934
+				$wpdb->query($SQL);
935
+			}
936
+		}
937
+	}
938
+
939
+
940
+
941
+	/**
942
+	 * Gets a country entry as an array, or creates one if none is found. Much like EEM_Country::instance()->get_one(),
943
+	 * but is independent of outside code which can change in future versions of EE. Also, $country_name CAN be a 3.1
944
+	 * country ID (int), a 2-letter ISO, 3-letter ISO, or name
945
+	 *
946
+	 * @global type  $wpdb
947
+	 * @param string $country_name
948
+	 * @return array where keys are columns, values are column values
949
+	 */
950
+	public function get_or_create_country($country_name)
951
+	{
952
+		if (! $country_name) {
953
+			throw new EE_Error(esc_html__("Could not get a country because country name is blank", "event_espresso"));
954
+		}
955
+		global $wpdb;
956
+		$country_table = $wpdb->prefix . "esp_country";
957
+		if (is_int($country_name)) {
958
+			$country_name = $this->get_iso_from_3_1_country_id($country_name);
959
+		}
960
+		$country = $wpdb->get_row($wpdb->prepare("SELECT * FROM $country_table WHERE
961 961
 			CNT_ISO LIKE %s OR
962 962
 			CNT_ISO3 LIKE %s OR
963 963
 			CNT_name LIKE %s LIMIT 1", $country_name, $country_name, $country_name), ARRAY_A);
964
-        if (! $country) {
965
-            // insert a new one then
966
-            $cols_n_values = array(
967
-                    'CNT_ISO'         => $this->_find_available_country_iso(2),
968
-                    'CNT_ISO3'        => $this->_find_available_country_iso(3),
969
-                    'RGN_ID'          => 0,
970
-                    'CNT_name'        => $country_name,
971
-                    'CNT_cur_code'    => 'USD',
972
-                    'CNT_cur_single'  => 'Dollar',
973
-                    'CNT_cur_plural'  => 'Dollars',
974
-                    'CNT_cur_sign'    => '&#36;',
975
-                    'CNT_cur_sign_b4' => true,
976
-                    'CNT_cur_dec_plc' => 2,
977
-                    'CNT_cur_dec_mrk' => '.',
978
-                    'CNT_cur_thsnds'  => ',',
979
-                    'CNT_tel_code'    => '+1',
980
-                    'CNT_is_EU'       => false,
981
-                    'CNT_active'      => true,
982
-            );
983
-            $data_types = array(
984
-                    '%s',// CNT_ISO
985
-                    '%s',// CNT_ISO3
986
-                    '%d',// RGN_ID
987
-                    '%s',// CNT_name
988
-                    '%s',// CNT_cur_code
989
-                    '%s',// CNT_cur_single
990
-                    '%s',// CNT_cur_plural
991
-                    '%s',// CNT_cur_sign
992
-                    '%d',// CNT_cur_sign_b4
993
-                    '%d',// CNT_cur_dec_plc
994
-                    '%s',// CNT_cur_dec_mrk
995
-                    '%s',// CNT_cur_thsnds
996
-                    '%s',// CNT_tel_code
997
-                    '%d',// CNT_is_EU
998
-                    '%d',// CNT_active
999
-            );
1000
-            $success = $wpdb->insert(
1001
-                $country_table,
1002
-                $cols_n_values,
1003
-                $data_types
1004
-            );
1005
-            if (! $success) {
1006
-                throw new EE_Error($this->_create_error_message_for_db_insertion(
1007
-                    'N/A',
1008
-                    array('country_id' => $country_name),
1009
-                    $country_table,
1010
-                    $cols_n_values,
1011
-                    $data_types
1012
-                ));
1013
-            }
1014
-            $country = $cols_n_values;
1015
-        }
1016
-        return $country;
1017
-    }
1018
-
1019
-
1020
-
1021
-    /**
1022
-     * finds a country iso which hasnt been used yet
1023
-     *
1024
-     * @global type $wpdb
1025
-     * @return string
1026
-     */
1027
-    private function _find_available_country_iso($num_letters = 2)
1028
-    {
1029
-        global $wpdb;
1030
-        $country_table = $wpdb->prefix . "esp_country";
1031
-        $attempts = 0;
1032
-        do {
1033
-            $current_iso = strtoupper(wp_generate_password($num_letters, false));
1034
-            $country_with_that_iso = $wpdb->get_var($wpdb->prepare("SELECT count(CNT_ISO) FROM "
1035
-                                                                   . $country_table
1036
-                                                                   . " WHERE CNT_ISO=%s", $current_iso));
1037
-            $attempts++;
1038
-            // keep going until we find an available country code, or we arbitrarily
1039
-            // decide we've tried this enough. Somehow they have way too many countries
1040
-            // (probably because they're mis-using the EE3 country_id like a custom question)
1041
-        } while (intval($country_with_that_iso) && $attempts < 200);
1042
-        return $current_iso;
1043
-    }
1044
-
1045
-
1046
-
1047
-    /**
1048
-     * Gets a state entry as an array, or creates one if none is found. Much like EEM_State::instance()->get_one(), but
1049
-     * is independent of outside code which can change in future versions of EE
1050
-     *
1051
-     * @global type  $wpdb
1052
-     * @param string $state_name
1053
-     * @return array where keys are columns, values are column values
1054
-     */
1055
-    public function get_or_create_state($state_name, $country_name = '')
1056
-    {
1057
-        if (! $state_name) {
1058
-            throw new EE_Error(esc_html__(
1059
-                "Could not get-or-create state because no state name was provided",
1060
-                "event_espresso"
1061
-            ));
1062
-        }
1063
-        try {
1064
-            $country = $this->get_or_create_country($country_name);
1065
-            $country_iso = $country['CNT_ISO'];
1066
-        } catch (EE_Error $e) {
1067
-            $country_iso = $this->get_default_country_iso();
1068
-        }
1069
-        global $wpdb;
1070
-        $state_table = $wpdb->prefix . "esp_state";
1071
-        $state = $wpdb->get_row($wpdb->prepare("SELECT * FROM $state_table WHERE
964
+		if (! $country) {
965
+			// insert a new one then
966
+			$cols_n_values = array(
967
+					'CNT_ISO'         => $this->_find_available_country_iso(2),
968
+					'CNT_ISO3'        => $this->_find_available_country_iso(3),
969
+					'RGN_ID'          => 0,
970
+					'CNT_name'        => $country_name,
971
+					'CNT_cur_code'    => 'USD',
972
+					'CNT_cur_single'  => 'Dollar',
973
+					'CNT_cur_plural'  => 'Dollars',
974
+					'CNT_cur_sign'    => '&#36;',
975
+					'CNT_cur_sign_b4' => true,
976
+					'CNT_cur_dec_plc' => 2,
977
+					'CNT_cur_dec_mrk' => '.',
978
+					'CNT_cur_thsnds'  => ',',
979
+					'CNT_tel_code'    => '+1',
980
+					'CNT_is_EU'       => false,
981
+					'CNT_active'      => true,
982
+			);
983
+			$data_types = array(
984
+					'%s',// CNT_ISO
985
+					'%s',// CNT_ISO3
986
+					'%d',// RGN_ID
987
+					'%s',// CNT_name
988
+					'%s',// CNT_cur_code
989
+					'%s',// CNT_cur_single
990
+					'%s',// CNT_cur_plural
991
+					'%s',// CNT_cur_sign
992
+					'%d',// CNT_cur_sign_b4
993
+					'%d',// CNT_cur_dec_plc
994
+					'%s',// CNT_cur_dec_mrk
995
+					'%s',// CNT_cur_thsnds
996
+					'%s',// CNT_tel_code
997
+					'%d',// CNT_is_EU
998
+					'%d',// CNT_active
999
+			);
1000
+			$success = $wpdb->insert(
1001
+				$country_table,
1002
+				$cols_n_values,
1003
+				$data_types
1004
+			);
1005
+			if (! $success) {
1006
+				throw new EE_Error($this->_create_error_message_for_db_insertion(
1007
+					'N/A',
1008
+					array('country_id' => $country_name),
1009
+					$country_table,
1010
+					$cols_n_values,
1011
+					$data_types
1012
+				));
1013
+			}
1014
+			$country = $cols_n_values;
1015
+		}
1016
+		return $country;
1017
+	}
1018
+
1019
+
1020
+
1021
+	/**
1022
+	 * finds a country iso which hasnt been used yet
1023
+	 *
1024
+	 * @global type $wpdb
1025
+	 * @return string
1026
+	 */
1027
+	private function _find_available_country_iso($num_letters = 2)
1028
+	{
1029
+		global $wpdb;
1030
+		$country_table = $wpdb->prefix . "esp_country";
1031
+		$attempts = 0;
1032
+		do {
1033
+			$current_iso = strtoupper(wp_generate_password($num_letters, false));
1034
+			$country_with_that_iso = $wpdb->get_var($wpdb->prepare("SELECT count(CNT_ISO) FROM "
1035
+																   . $country_table
1036
+																   . " WHERE CNT_ISO=%s", $current_iso));
1037
+			$attempts++;
1038
+			// keep going until we find an available country code, or we arbitrarily
1039
+			// decide we've tried this enough. Somehow they have way too many countries
1040
+			// (probably because they're mis-using the EE3 country_id like a custom question)
1041
+		} while (intval($country_with_that_iso) && $attempts < 200);
1042
+		return $current_iso;
1043
+	}
1044
+
1045
+
1046
+
1047
+	/**
1048
+	 * Gets a state entry as an array, or creates one if none is found. Much like EEM_State::instance()->get_one(), but
1049
+	 * is independent of outside code which can change in future versions of EE
1050
+	 *
1051
+	 * @global type  $wpdb
1052
+	 * @param string $state_name
1053
+	 * @return array where keys are columns, values are column values
1054
+	 */
1055
+	public function get_or_create_state($state_name, $country_name = '')
1056
+	{
1057
+		if (! $state_name) {
1058
+			throw new EE_Error(esc_html__(
1059
+				"Could not get-or-create state because no state name was provided",
1060
+				"event_espresso"
1061
+			));
1062
+		}
1063
+		try {
1064
+			$country = $this->get_or_create_country($country_name);
1065
+			$country_iso = $country['CNT_ISO'];
1066
+		} catch (EE_Error $e) {
1067
+			$country_iso = $this->get_default_country_iso();
1068
+		}
1069
+		global $wpdb;
1070
+		$state_table = $wpdb->prefix . "esp_state";
1071
+		$state = $wpdb->get_row($wpdb->prepare("SELECT * FROM $state_table WHERE
1072 1072
 			(STA_abbrev LIKE %s OR
1073 1073
 			STA_name LIKE %s) AND
1074 1074
 			CNT_ISO LIKE %s LIMIT 1", $state_name, $state_name, $country_iso), ARRAY_A);
1075
-        if (! $state) {
1076
-            // insert a new one then
1077
-            $cols_n_values = array(
1078
-                    'CNT_ISO'    => $country_iso,
1079
-                    'STA_abbrev' => substr($state_name, 0, 6),
1080
-                    'STA_name'   => $state_name,
1081
-                    'STA_active' => true,
1082
-            );
1083
-            $data_types = array(
1084
-                    '%s',// CNT_ISO
1085
-                    '%s',// STA_abbrev
1086
-                    '%s',// STA_name
1087
-                    '%d',// STA_active
1088
-            );
1089
-            $success = $wpdb->insert($state_table, $cols_n_values, $data_types);
1090
-            if (! $success) {
1091
-                throw new EE_Error($this->_create_error_message_for_db_insertion(
1092
-                    'N/A',
1093
-                    array('state' => $state_name, 'country_id' => $country_name),
1094
-                    $state_table,
1095
-                    $cols_n_values,
1096
-                    $data_types
1097
-                ));
1098
-            }
1099
-            $state = $cols_n_values;
1100
-            $state['STA_ID'] = $wpdb->insert_id;
1101
-        }
1102
-        return $state;
1103
-    }
1104
-
1105
-
1106
-
1107
-    /**
1108
-     * Fixes times like "5:00 PM" into the expected 24-hour format "17:00".
1109
-     * THis is actually just copied from the 3.1 JSON API because it needed to do the exact same thing
1110
-     *
1111
-     * @param type $timeString
1112
-     * @return string in the php DATETIME format: "G:i" (24-hour format hour with leading zeros, a colon, and minutes
1113
-     *                with leading zeros)
1114
-     */
1115
-    public function convertTimeFromAMPM($timeString)
1116
-    {
1117
-        $matches = array();
1118
-        preg_match("~(\\d*):(\\d*)~", $timeString, $matches);
1119
-        if (! $matches || count($matches) < 3) {
1120
-            $hour = '00';
1121
-            $minutes = '00';
1122
-        } else {
1123
-            $hour = intval($matches[1]);
1124
-            $minutes = $matches[2];
1125
-        }
1126
-        if (strpos($timeString, 'PM') || strpos($timeString, 'pm')) {
1127
-            $hour = intval($hour) + 12;
1128
-        }
1129
-        $hour = str_pad("$hour", 2, '0', STR_PAD_LEFT);
1130
-        $minutes = str_pad("$minutes", 2, '0', STR_PAD_LEFT);
1131
-        return "$hour:$minutes";
1132
-    }
1133
-
1134
-
1135
-
1136
-    /**
1137
-     * Gets the ISO3 fora country given its 3.1 country ID.
1138
-     *
1139
-     * @param int $country_id
1140
-     * @return string the country's ISO3 code
1141
-     */
1142
-    public function get_iso_from_3_1_country_id($country_id)
1143
-    {
1144
-        $old_countries = array(
1145
-                array(64, 'United States', 'US', 'USA', 1),
1146
-                array(15, 'Australia', 'AU', 'AUS', 1),
1147
-                array(39, 'Canada', 'CA', 'CAN', 1),
1148
-                array(171, 'United Kingdom', 'GB', 'GBR', 1),
1149
-                array(70, 'France', 'FR', 'FRA', 2),
1150
-                array(111, 'Italy', 'IT', 'ITA', 2),
1151
-                array(63, 'Spain', 'ES', 'ESP', 2),
1152
-                array(1, 'Afghanistan', 'AF', 'AFG', 1),
1153
-                array(2, 'Albania', 'AL', 'ALB', 1),
1154
-                array(3, 'Germany', 'DE', 'DEU', 2),
1155
-                array(198, 'Switzerland', 'CH', 'CHE', 1),
1156
-                array(87, 'Netherlands', 'NL', 'NLD', 2),
1157
-                array(197, 'Sweden', 'SE', 'SWE', 1),
1158
-                array(230, 'Akrotiri and Dhekelia', 'CY', 'CYP', 2),
1159
-                array(4, 'Andorra', 'AD', 'AND', 2),
1160
-                array(5, 'Angola', 'AO', 'AGO', 1),
1161
-                array(6, 'Anguilla', 'AI', 'AIA', 1),
1162
-                array(7, 'Antarctica', 'AQ', 'ATA', 1),
1163
-                array(8, 'Antigua and Barbuda', 'AG', 'ATG', 1),
1164
-                array(10, 'Saudi Arabia', 'SA', 'SAU', 1),
1165
-                array(11, 'Algeria', 'DZ', 'DZA', 1),
1166
-                array(12, 'Argentina', 'AR', 'ARG', 1),
1167
-                array(13, 'Armenia', 'AM', 'ARM', 1),
1168
-                array(14, 'Aruba', 'AW', 'ABW', 1),
1169
-                array(16, 'Austria', 'AT', 'AUT', 2),
1170
-                array(17, 'Azerbaijan', 'AZ', 'AZE', 1),
1171
-                array(18, 'Bahamas', 'BS', 'BHS', 1),
1172
-                array(19, 'Bahrain', 'BH', 'BHR', 1),
1173
-                array(20, 'Bangladesh', 'BD', 'BGD', 1),
1174
-                array(21, 'Barbados', 'BB', 'BRB', 1),
1175
-                array(22, 'Belgium ', 'BE', 'BEL', 2),
1176
-                array(23, 'Belize', 'BZ', 'BLZ', 1),
1177
-                array(24, 'Benin', 'BJ', 'BEN', 1),
1178
-                array(25, 'Bermudas', 'BM', 'BMU', 1),
1179
-                array(26, 'Belarus', 'BY', 'BLR', 1),
1180
-                array(27, 'Bolivia', 'BO', 'BOL', 1),
1181
-                array(28, 'Bosnia and Herzegovina', 'BA', 'BIH', 1),
1182
-                array(29, 'Botswana', 'BW', 'BWA', 1),
1183
-                array(96, 'Bouvet Island', 'BV', 'BVT', 1),
1184
-                array(30, 'Brazil', 'BR', 'BRA', 1),
1185
-                array(31, 'Brunei', 'BN', 'BRN', 1),
1186
-                array(32, 'Bulgaria', 'BG', 'BGR', 1),
1187
-                array(33, 'Burkina Faso', 'BF', 'BFA', 1),
1188
-                array(34, 'Burundi', 'BI', 'BDI', 1),
1189
-                array(35, 'Bhutan', 'BT', 'BTN', 1),
1190
-                array(36, 'Cape Verde', 'CV', 'CPV', 1),
1191
-                array(37, 'Cambodia', 'KH', 'KHM', 1),
1192
-                array(38, 'Cameroon', 'CM', 'CMR', 1),
1193
-                array(98, 'Cayman Islands', 'KY', 'CYM', 1),
1194
-                array(172, 'Central African Republic', 'CF', 'CAF', 1),
1195
-                array(40, 'Chad', 'TD', 'TCD', 1),
1196
-                array(41, 'Chile', 'CL', 'CHL', 1),
1197
-                array(42, 'China', 'CN', 'CHN', 1),
1198
-                array(105, 'Christmas Island', 'CX', 'CXR', 1),
1199
-                array(43, 'Cyprus', 'CY', 'CYP', 2),
1200
-                array(99, 'Cocos Island', 'CC', 'CCK', 1),
1201
-                array(100, 'Cook Islands', 'CK', 'COK', 1),
1202
-                array(44, 'Colombia', 'CO', 'COL', 1),
1203
-                array(45, 'Comoros', 'KM', 'COM', 1),
1204
-                array(46, 'Congo', 'CG', 'COG', 1),
1205
-                array(47, 'North Korea', 'KP', 'PRK', 1),
1206
-                array(50, 'Costa Rica', 'CR', 'CRI', 1),
1207
-                array(51, 'Croatia', 'HR', 'HRV', 1),
1208
-                array(52, 'Cuba', 'CU', 'CUB', 1),
1209
-                array(173, 'Czech Republic', 'CZ', 'CZE', 1),
1210
-                array(53, 'Denmark', 'DK', 'DNK', 1),
1211
-                array(54, 'Djibouti', 'DJ', 'DJI', 1),
1212
-                array(55, 'Dominica', 'DM', 'DMA', 1),
1213
-                array(174, 'Dominican Republic', 'DO', 'DOM', 1),
1214
-                array(56, 'Ecuador', 'EC', 'ECU', 1),
1215
-                array(57, 'Egypt', 'EG', 'EGY', 1),
1216
-                array(58, 'El Salvador', 'SV', 'SLV', 1),
1217
-                array(60, 'Eritrea', 'ER', 'ERI', 1),
1218
-                array(61, 'Slovakia', 'SK', 'SVK', 2),
1219
-                array(62, 'Slovenia', 'SI', 'SVN', 2),
1220
-                array(65, 'Estonia', 'EE', 'EST', 2),
1221
-                array(66, 'Ethiopia', 'ET', 'ETH', 1),
1222
-                array(102, 'Faroe islands', 'FO', 'FRO', 1),
1223
-                array(103, 'Falkland Islands', 'FK', 'FLK', 1),
1224
-                array(67, 'Fiji', 'FJ', 'FJI', 1),
1225
-                array(69, 'Finland', 'FI', 'FIN', 2),
1226
-                array(71, 'Gabon', 'GA', 'GAB', 1),
1227
-                array(72, 'Gambia', 'GM', 'GMB', 1),
1228
-                array(73, 'Georgia', 'GE', 'GEO', 1),
1229
-                array(74, 'Ghana', 'GH', 'GHA', 1),
1230
-                array(75, 'Gibraltar', 'GI', 'GIB', 1),
1231
-                array(76, 'Greece', 'GR', 'GRC', 2),
1232
-                array(77, 'Grenada', 'GD', 'GRD', 1),
1233
-                array(78, 'Greenland', 'GL', 'GRL', 1),
1234
-                array(79, 'Guadeloupe', 'GP', 'GLP', 1),
1235
-                array(80, 'Guam', 'GU', 'GUM', 1),
1236
-                array(81, 'Guatemala', 'GT', 'GTM', 1),
1237
-                array(82, 'Guinea', 'GN', 'GIN', 1),
1238
-                array(83, 'Equatorial Guinea', 'GQ', 'GNQ', 1),
1239
-                array(84, 'Guinea-Bissau', 'GW', 'GNB', 1),
1240
-                array(85, 'Guyana', 'GY', 'GUY', 1),
1241
-                array(86, 'Haiti', 'HT', 'HTI', 1),
1242
-                array(88, 'Honduras', 'HN', 'HND', 1),
1243
-                array(89, 'Hong Kong', 'HK', 'HKG', 1),
1244
-                array(90, 'Hungary', 'HU', 'HUN', 1),
1245
-                array(91, 'India', 'IN', 'IND', 1),
1246
-                array(205, 'British Indian Ocean Territory', 'IO', 'IOT', 1),
1247
-                array(92, 'Indonesia', 'ID', 'IDN', 1),
1248
-                array(93, 'Iraq', 'IQ', 'IRQ', 1),
1249
-                array(94, 'Iran', 'IR', 'IRN', 1),
1250
-                array(95, 'Ireland', 'IE', 'IRL', 2),
1251
-                array(97, 'Iceland', 'IS', 'ISL', 1),
1252
-                array(110, 'Israel', 'IL', 'ISR', 1),
1253
-                array(49, 'Ivory Coast ', 'CI', 'CIV', 1),
1254
-                array(112, 'Jamaica', 'JM', 'JAM', 1),
1255
-                array(113, 'Japan', 'JP', 'JPN', 1),
1256
-                array(114, 'Jordan', 'JO', 'JOR', 1),
1257
-                array(115, 'Kazakhstan', 'KZ', 'KAZ', 1),
1258
-                array(116, 'Kenya', 'KE', 'KEN', 1),
1259
-                array(117, 'Kyrgyzstan', 'KG', 'KGZ', 1),
1260
-                array(118, 'Kiribati', 'KI', 'KIR', 1),
1261
-                array(48, 'South Korea', 'KR', 'KOR', 1),
1262
-                array(228, 'Kosovo', 'XK', 'XKV', 2),
1263
-                // there is no official ISO code for Kosovo yet (http://geonames.wordpress.com/2010/03/08/xk-country-code-for-kosovo/) so using a temporary country code and a modified 3 character code for ISO code -- this should be updated if/when Kosovo gets its own ISO code
1264
-                array(119, 'Kuwait', 'KW', 'KWT', 1),
1265
-                array(120, 'Laos', 'LA', 'LAO', 1),
1266
-                array(121, 'Latvia', 'LV', 'LVA', 2),
1267
-                array(122, 'Lesotho', 'LS', 'LSO', 1),
1268
-                array(123, 'Lebanon', 'LB', 'LBN', 1),
1269
-                array(124, 'Liberia', 'LR', 'LBR', 1),
1270
-                array(125, 'Libya', 'LY', 'LBY', 1),
1271
-                array(126, 'Liechtenstein', 'LI', 'LIE', 1),
1272
-                array(127, 'Lithuania', 'LT', 'LTU', 2),
1273
-                array(128, 'Luxemburg', 'LU', 'LUX', 2),
1274
-                array(129, 'Macao', 'MO', 'MAC', 1),
1275
-                array(130, 'Macedonia', 'MK', 'MKD', 1),
1276
-                array(131, 'Madagascar', 'MG', 'MDG', 1),
1277
-                array(132, 'Malaysia', 'MY', 'MYS', 1),
1278
-                array(133, 'Malawi', 'MW', 'MWI', 1),
1279
-                array(134, 'Maldivas', 'MV', 'MDV', 1),
1280
-                array(135, 'Mali', 'ML', 'MLI', 1),
1281
-                array(136, 'Malta', 'MT', 'MLT', 2),
1282
-                array(101, 'Northern Marianas', 'MP', 'MNP', 1),
1283
-                array(137, 'Morocco', 'MA', 'MAR', 1),
1284
-                array(104, 'Marshall islands', 'MH', 'MHL', 1),
1285
-                array(138, 'Martinique', 'MQ', 'MTQ', 1),
1286
-                array(139, 'Mauritius', 'MU', 'MUS', 1),
1287
-                array(140, 'Mauritania', 'MR', 'MRT', 1),
1288
-                array(141, 'Mayote', 'YT', 'MYT', 2),
1289
-                array(142, 'Mexico', 'MX', 'MEX', 1),
1290
-                array(143, 'Micronesia', 'FM', 'FSM', 1),
1291
-                array(144, 'Moldova', 'MD', 'MDA', 1),
1292
-                array(145, 'Monaco', 'MC', 'MCO', 2),
1293
-                array(146, 'Mongolia', 'MN', 'MNG', 1),
1294
-                array(147, 'Montserrat', 'MS', 'MSR', 1),
1295
-                array(227, 'Montenegro', 'ME', 'MNE', 2),
1296
-                array(148, 'Mozambique', 'MZ', 'MOZ', 1),
1297
-                array(149, 'Myanmar', 'MM', 'MMR', 1),
1298
-                array(150, 'Namibia', 'NA', 'NAM', 1),
1299
-                array(151, 'Nauru', 'NR', 'NRU', 1),
1300
-                array(152, 'Nepal', 'NP', 'NPL', 1),
1301
-                array(9, 'Netherlands Antilles', 'AN', 'ANT', 1),
1302
-                array(153, 'Nicaragua', 'NI', 'NIC', 1),
1303
-                array(154, 'Niger', 'NE', 'NER', 1),
1304
-                array(155, 'Nigeria', 'NG', 'NGA', 1),
1305
-                array(156, 'Niue', 'NU', 'NIU', 1),
1306
-                array(157, 'Norway', 'NO', 'NOR', 1),
1307
-                array(158, 'New Caledonia', 'NC', 'NCL', 1),
1308
-                array(159, 'New Zealand', 'NZ', 'NZL', 1),
1309
-                array(160, 'Oman', 'OM', 'OMN', 1),
1310
-                array(161, 'Pakistan', 'PK', 'PAK', 1),
1311
-                array(162, 'Palau', 'PW', 'PLW', 1),
1312
-                array(163, 'Panama', 'PA', 'PAN', 1),
1313
-                array(164, 'Papua New Guinea', 'PG', 'PNG', 1),
1314
-                array(165, 'Paraguay', 'PY', 'PRY', 1),
1315
-                array(166, 'Peru', 'PE', 'PER', 1),
1316
-                array(68, 'Philippines', 'PH', 'PHL', 1),
1317
-                array(167, 'Poland', 'PL', 'POL', 1),
1318
-                array(168, 'Portugal', 'PT', 'PRT', 2),
1319
-                array(169, 'Puerto Rico', 'PR', 'PRI', 1),
1320
-                array(170, 'Qatar', 'QA', 'QAT', 1),
1321
-                array(176, 'Rwanda', 'RW', 'RWA', 1),
1322
-                array(177, 'Romania', 'RO', 'ROM', 2),
1323
-                array(178, 'Russia', 'RU', 'RUS', 1),
1324
-                array(229, 'Saint Pierre and Miquelon', 'PM', 'SPM', 2),
1325
-                array(180, 'Samoa', 'WS', 'WSM', 1),
1326
-                array(181, 'American Samoa', 'AS', 'ASM', 1),
1327
-                array(183, 'San Marino', 'SM', 'SMR', 2),
1328
-                array(184, 'Saint Vincent and the Grenadines', 'VC', 'VCT', 1),
1329
-                array(185, 'Saint Helena', 'SH', 'SHN', 1),
1330
-                array(186, 'Saint Lucia', 'LC', 'LCA', 1),
1331
-                array(188, 'Senegal', 'SN', 'SEN', 1),
1332
-                array(189, 'Seychelles', 'SC', 'SYC', 1),
1333
-                array(190, 'Sierra Leona', 'SL', 'SLE', 1),
1334
-                array(191, 'Singapore', 'SG', 'SGP', 1),
1335
-                array(192, 'Syria', 'SY', 'SYR', 1),
1336
-                array(193, 'Somalia', 'SO', 'SOM', 1),
1337
-                array(194, 'Sri Lanka', 'LK', 'LKA', 1),
1338
-                array(195, 'South Africa', 'ZA', 'ZAF', 1),
1339
-                array(196, 'Sudan', 'SD', 'SDN', 1),
1340
-                array(199, 'Suriname', 'SR', 'SUR', 1),
1341
-                array(200, 'Swaziland', 'SZ', 'SWZ', 1),
1342
-                array(201, 'Thailand', 'TH', 'THA', 1),
1343
-                array(202, 'Taiwan', 'TW', 'TWN', 1),
1344
-                array(203, 'Tanzania', 'TZ', 'TZA', 1),
1345
-                array(204, 'Tajikistan', 'TJ', 'TJK', 1),
1346
-                array(206, 'Timor-Leste', 'TL', 'TLS', 1),
1347
-                array(207, 'Togo', 'TG', 'TGO', 1),
1348
-                array(208, 'Tokelau', 'TK', 'TKL', 1),
1349
-                array(209, 'Tonga', 'TO', 'TON', 1),
1350
-                array(210, 'Trinidad and Tobago', 'TT', 'TTO', 1),
1351
-                array(211, 'Tunisia', 'TN', 'TUN', 1),
1352
-                array(212, 'Turkmenistan', 'TM', 'TKM', 1),
1353
-                array(213, 'Turkey', 'TR', 'TUR', 1),
1354
-                array(214, 'Tuvalu', 'TV', 'TUV', 1),
1355
-                array(215, 'Ukraine', 'UA', 'UKR', 1),
1356
-                array(216, 'Uganda', 'UG', 'UGA', 1),
1357
-                array(59, 'United Arab Emirates', 'AE', 'ARE', 1),
1358
-                array(217, 'Uruguay', 'UY', 'URY', 1),
1359
-                array(218, 'Uzbekistan', 'UZ', 'UZB', 1),
1360
-                array(219, 'Vanuatu', 'VU', 'VUT', 1),
1361
-                array(220, 'Vatican City', 'VA', 'VAT', 2),
1362
-                array(221, 'Venezuela', 'VE', 'VEN', 1),
1363
-                array(222, 'Vietnam', 'VN', 'VNM', 1),
1364
-                array(108, 'Virgin Islands', 'VI', 'VIR', 1),
1365
-                array(223, 'Yemen', 'YE', 'YEM', 1),
1366
-                array(225, 'Zambia', 'ZM', 'ZMB', 1),
1367
-                array(226, 'Zimbabwe', 'ZW', 'ZWE', 1),
1368
-        );
1369
-        $country_iso = 'US';
1370
-        foreach ($old_countries as $country_array) {
1371
-            // note: index 0 is the 3.1 country ID
1372
-            if ($country_array[0] == $country_id) {
1373
-                // note: index 2 is the ISO
1374
-                $country_iso = $country_array[2];
1375
-                break;
1376
-            }
1377
-        }
1378
-        return $country_iso;
1379
-    }
1380
-
1381
-
1382
-
1383
-    /**
1384
-     * Gets the ISO3 for the
1385
-     *
1386
-     * @return string
1387
-     */
1388
-    public function get_default_country_iso()
1389
-    {
1390
-        $old_org_options = get_option('events_organization_settings');
1391
-        $iso = $this->get_iso_from_3_1_country_id($old_org_options['organization_country']);
1392
-        return $iso;
1393
-    }
1394
-
1395
-
1396
-
1397
-    /**
1398
-     * Converst a 3.1 payment status to its equivalent 4.1 regisration status
1399
-     *
1400
-     * @param string  $payment_status                   possible value for 3.1's evens_attendee.payment_status
1401
-     * @param boolean $this_thing_required_pre_approval whether the thing we're considering (the general setting's
1402
-     *                                                  default payment status, the event's default payment status, or
1403
-     *                                                  the attendee's payment status) required pre-approval.
1404
-     * @return string STS_ID for use in 4.1
1405
-     */
1406
-    public function convert_3_1_payment_status_to_4_1_STS_ID($payment_status, $this_thing_required_pre_approval = false)
1407
-    {
1408
-        // EE team can read the related discussion: https://app.asana.com/0/2400967562914/9418495544455
1409
-        if ($this_thing_required_pre_approval) {
1410
-            return 'RNA';
1411
-        } else {
1412
-            $mapping = $default_reg_stati_conversions = array(
1413
-                    'Completed'        => 'RAP',
1414
-                    ''                 => 'RPP',
1415
-                    'Incomplete'       => 'RPP',
1416
-                    'Pending'          => 'RAP',
1417
-                    // stati that only occurred on 3.1 attendees:
1418
-                    'Payment Declined' => 'RPP',
1419
-                    'Not Completed'    => 'RPP',
1420
-                    'Cancelled'        => 'RPP',
1421
-                    'Declined'         => 'RPP',
1422
-            );
1423
-        }
1424
-        return isset($mapping[ $payment_status ]) ? $mapping[ $payment_status ] : 'RNA';
1425
-    }
1426
-
1427
-
1428
-
1429
-    /**
1430
-     * Makes sure the 3.1's image url is converted to an image attachment post to the 4.1 CPT event
1431
-     * and sets it as the featured image on the CPT event
1432
-     *
1433
-     * @param type                            $old_event
1434
-     * @param type                            $new_cpt_id
1435
-     * @param  EE_Data_Migration_Script_Stage $migration_stage the stage which called this, where errors should be added
1436
-     * @return boolean whether or not we had to do the big job of creating an image attachment
1437
-     */
1438
-    public function convert_image_url_to_attachment_and_attach_to_post(
1439
-        $guid,
1440
-        $new_cpt_id,
1441
-        EE_Data_Migration_Script_Stage $migration_stage
1442
-    ) {
1443
-        $created_attachment_post = false;
1444
-        $guid = $this->_get_original_guid($guid);
1445
-        if ($guid) {
1446
-            // check for an existing attachment post with this guid
1447
-            $attachment_post_id = $this->_get_image_attachment_id_by_GUID($guid);
1448
-            if (! $attachment_post_id) {
1449
-                // post thumbnail with that GUID doesn't exist, we should create one
1450
-                $attachment_post_id = $this->_create_image_attachment_from_GUID($guid, $migration_stage);
1451
-                $created_attachment_post = true;
1452
-            }
1453
-            // double-check we actually have an attachment post
1454
-            if ($attachment_post_id) {
1455
-                update_post_meta($new_cpt_id, '_thumbnail_id', $attachment_post_id);
1456
-            } else {
1457
-                $migration_stage->add_error(sprintf(esc_html__(
1458
-                    "Could not update event image %s for CPT with ID %d, but attachments post ID is %d",
1459
-                    "event_espresso"
1460
-                ), $guid, $new_cpt_id, $attachment_post_id));
1461
-            }
1462
-        }
1463
-        return $created_attachment_post;
1464
-    }
1465
-
1466
-
1467
-
1468
-    /**
1469
-     * In 3.1, the event thumbnail image DOESN'T point to the orignal image, but instead
1470
-     * to a large thumbnail (which has nearly the same GUID, except it adds "-{width}x{height}" before the filetype,
1471
-     * or whatever dimensions it is. Eg 'http://mysite.com/image1-300x400.jpg' instead of
1472
-     * 'http://mysite.com/image1.jpg' ). This function attempts to strip that off and get the original file, if it
1473
-     * exists
1474
-     *
1475
-     * @param string $guid_in_old_event
1476
-     * @return string either the original guid, or $guid_in_old_event if we couldn't figure out what the original was
1477
-     */
1478
-    private function _get_original_guid($guid_in_old_event)
1479
-    {
1480
-        $original_guid = preg_replace('~-\d*x\d*\.~', '.', $guid_in_old_event, 1);
1481
-        // do a head request to verify the file exists
1482
-        $head_response = wp_remote_head($original_guid);
1483
-        if (! $head_response instanceof WP_Error && $head_response['response']['message'] == 'OK') {
1484
-            return $original_guid;
1485
-        } else {
1486
-            return $guid_in_old_event;
1487
-        }
1488
-    }
1489
-
1490
-
1491
-
1492
-    /**
1493
-     * Creates an image attachment post for the GUID. If the GUID points to a remote image,
1494
-     * we download it to our uploads directory so that it can be properly processed (eg, creates different sizes of
1495
-     * thumbnails)
1496
-     *
1497
-     * @param type                           $guid
1498
-     * @param EE_Data_Migration_Script_Stage $migration_stage
1499
-     * @return int
1500
-     */
1501
-    private function _create_image_attachment_from_GUID($guid, EE_Data_Migration_Script_Stage $migration_stage)
1502
-    {
1503
-        if (! $guid) {
1504
-            $migration_stage->add_error(sprintf(esc_html__(
1505
-                "Cannot create image attachment for a blank GUID!",
1506
-                "event_espresso"
1507
-            )));
1508
-            return 0;
1509
-        }
1510
-        $wp_filetype = wp_check_filetype(basename($guid), null);
1511
-        $wp_upload_dir = wp_upload_dir();
1512
-        // if the file is located remotely, download it to our uploads DIR, because wp_genereate_attachmnet_metadata needs the file to be local
1513
-        if (strpos($guid, $wp_upload_dir['url']) === false) {
1514
-            // image is located remotely. download it and place it in the uploads directory
1515
-            if (! is_readable($guid)) {
1516
-                $migration_stage->add_error(sprintf(esc_html__(
1517
-                    "Could not create image attachment from non-existent file: %s",
1518
-                    "event_espresso"
1519
-                ), $guid));
1520
-                return 0;
1521
-            }
1522
-            $contents = file_get_contents($guid);
1523
-            if ($contents === false) {
1524
-                $migration_stage->add_error(sprintf(esc_html__(
1525
-                    "Could not read image at %s, and therefore couldnt create an attachment post for it.",
1526
-                    "event_espresso"
1527
-                ), $guid));
1528
-                return false;
1529
-            }
1530
-            $local_filepath = $wp_upload_dir['path'] . '/' . basename($guid);
1531
-            $savefile = fopen($local_filepath, 'w');
1532
-            fwrite($savefile, $contents);
1533
-            fclose($savefile);
1534
-            $guid = str_replace($wp_upload_dir['path'], $wp_upload_dir['url'], $local_filepath);
1535
-        } else {
1536
-            $local_filepath = str_replace($wp_upload_dir['url'], $wp_upload_dir['path'], $guid);
1537
-        }
1538
-        $attachment = array(
1539
-                'guid'           => $guid,
1540
-                'post_mime_type' => $wp_filetype['type'],
1541
-                'post_title'     => preg_replace('/\.[^.]+$/', '', basename($guid)),
1542
-                'post_content'   => '',
1543
-                'post_status'    => 'inherit',
1544
-        );
1545
-        $attach_id = wp_insert_attachment($attachment, $guid);
1546
-        if (! $attach_id) {
1547
-            $migration_stage->add_error(sprintf(esc_html__(
1548
-                "Could not create image attachment post from image '%s'. Attachment data was %s.",
1549
-                "event_espresso"
1550
-            ), $guid, $this->_json_encode($attachment)));
1551
-            return $attach_id;
1552
-        }
1553
-        // you must first include the image.php file
1554
-        // for the function wp_generate_attachment_metadata() to work
1555
-        require_once(ABSPATH . 'wp-admin/includes/image.php');
1556
-        $attach_data = wp_generate_attachment_metadata($attach_id, $local_filepath);
1557
-        if (! $attach_data) {
1558
-            $migration_stage->add_error(sprintf(esc_html__(
1559
-                "Coudl not genereate attachment metadata for attachment post %d with filepath %s and GUID %s. Please check the file was downloaded properly.",
1560
-                "event_espresso"
1561
-            ), $attach_id, $local_filepath, $guid));
1562
-            return $attach_id;
1563
-        }
1564
-        $metadata_save_result = wp_update_attachment_metadata($attach_id, $attach_data);
1565
-        if (! $metadata_save_result) {
1566
-            $migration_stage->add_error(sprintf(esc_html__(
1567
-                "Could not update attachment metadata for attachment %d with data %s",
1568
-                "event_espresso"
1569
-            ), $attach_id, $this->_json_encode($attach_data)));
1570
-        }
1571
-        return $attach_id;
1572
-    }
1573
-
1574
-
1575
-
1576
-    /**
1577
-     * Finds the attachment post containing info about an image attachment given the GUID (link to the image itself),
1578
-     * and returns its ID.
1579
-     *
1580
-     * @global type  $wpdb
1581
-     * @param string $guid
1582
-     * @return int
1583
-     */
1584
-    private function _get_image_attachment_id_by_GUID($guid)
1585
-    {
1586
-        global $wpdb;
1587
-        $attachment_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid=%s LIMIT 1", $guid));
1588
-        return $attachment_id;
1589
-    }
1590
-
1591
-
1592
-
1593
-    /**
1594
-     * Returns a mysql-formatted DATETIME in UTC time, given a $DATETIME_string
1595
-     * (and optionally a timezone; if none is given, the wp default is used)
1596
-     *
1597
-     * @param EE_Data_Migration_Script_base $stage
1598
-     * @param array                         $row_of_data , the row from the DB (as an array) we're trying to find the
1599
-     *                                                   UTC time for
1600
-     * @param string                        $DATETIME_string
1601
-     * @param string                        $timezone
1602
-     * @return string
1603
-     */
1604
-    public function convert_date_string_to_utc(
1605
-        EE_Data_Migration_Script_Stage $stage,
1606
-        $row_of_data,
1607
-        $DATETIME_string,
1608
-        $timezone = null
1609
-    ) {
1610
-        $original_tz = $timezone;
1611
-        if (! $timezone) {
1612
-            $timezone = $this->_get_wp_timezone();
1613
-        }
1614
-        if (! $timezone) {
1615
-            $stage->add_error(sprintf(
1616
-                esc_html__("Could not find timezone given %s for %s", "event_espresso"),
1617
-                $original_tz,
1618
-                $row_of_data
1619
-            ));
1620
-            $timezone = 'UTC';
1621
-        }
1622
-        try {
1623
-            $date_obj = new DateTime($DATETIME_string, new DateTimeZone($timezone));
1624
-            EEH_DTT_Helper::setTimezone($date_obj, new DateTimeZone('UTC'));
1625
-        } catch (Exception $e) {
1626
-            $stage->add_error(sprintf(esc_html__(
1627
-                "Could not convert time string '%s' using timezone '%s' into a proper DATETIME. Using current time instead.",
1628
-                "event_espresso"
1629
-            ), $DATETIME_string, $timezone));
1630
-            $date_obj = new DateTime();
1631
-        }
1632
-        return $date_obj->format('Y-m-d H:i:s');
1633
-    }
1634
-
1635
-
1636
-
1637
-    /**
1638
-     * Gets the default timezone string from wordpress (even if they set a gmt offset)
1639
-     *
1640
-     * @return string
1641
-     */
1642
-    private function _get_wp_timezone()
1643
-    {
1644
-        $timezone = empty($timezone) ? get_option('timezone_string') : $timezone;
1645
-        // if timezone is STILL empty then let's get the GMT offset and then set the timezone_string using our converter
1646
-        if (empty($timezone)) {
1647
-            // let's get a the WordPress UTC offset
1648
-            $offset = get_option('gmt_offset');
1649
-            $timezone = $this->timezone_convert_to_string_from_offset($offset);
1650
-        }
1651
-        return $timezone;
1652
-    }
1653
-
1654
-
1655
-
1656
-    /**
1657
-     * Gets the wordpress timezone string from a UTC offset
1658
-     *
1659
-     * @param int $offset
1660
-     * @return boolean
1661
-     */
1662
-    private function timezone_convert_to_string_from_offset($offset)
1663
-    {
1664
-        // shamelessly taken from bottom comment at http://ca1.php.net/manual/en/function.timezone-name-from-abbr.php because timezone_name_from_abbr() did not work as expected - its not reliable
1665
-        $offset *= 3600; // convert hour offset to seconds
1666
-        $abbrarray = timezone_abbreviations_list();
1667
-        foreach ($abbrarray as $abbr) {
1668
-            foreach ($abbr as $city) {
1669
-                if ($city['offset'] == $offset) {
1670
-                    return $city['timezone_id'];
1671
-                }
1672
-            }
1673
-        }
1674
-        return false;
1675
-    }
1676
-
1677
-
1678
-
1679
-    public function migration_page_hooks()
1680
-    {
1681
-        add_filter(
1682
-            'FHEE__ee_migration_page__header',
1683
-            array($this, '_migrate_page_hook_simplify_version_strings'),
1684
-            10,
1685
-            3
1686
-        );
1687
-        add_filter(
1688
-            'FHEE__ee_migration_page__p_after_header',
1689
-            array($this, '_migration_page_hook_simplify_next_db_state'),
1690
-            10,
1691
-            2
1692
-        );
1693
-        add_filter(
1694
-            'FHEE__ee_migration_page__option_1_main',
1695
-            array($this, '_migrate_page_hook_simplify_version_strings'),
1696
-            10,
1697
-            3
1698
-        );
1699
-        add_filter(
1700
-            'FHEE__ee_migration_page__option_1_button_text',
1701
-            array($this, '_migrate_page_hook_simplify_version_strings'),
1702
-            10,
1703
-            3
1704
-        );
1705
-        add_action(
1706
-            'AHEE__ee_migration_page__option_1_extra_details',
1707
-            array($this, '_migration_page_hook_option_1_extra_details'),
1708
-            10,
1709
-            3
1710
-        );
1711
-        add_filter(
1712
-            'FHEE__ee_migration_page__option_2_main',
1713
-            array($this, '_migrate_page_hook_simplify_version_strings'),
1714
-            10,
1715
-            4
1716
-        );
1717
-        add_filter(
1718
-            'FHEE__ee_migration_page__option_2_button_text',
1719
-            array($this, '_migration_page_hook_simplify_next_db_state'),
1720
-            10,
1721
-            2
1722
-        );
1723
-        add_filter(
1724
-            'FHEE__ee_migration_page__option_2_details',
1725
-            array($this, '_migration_page_hook_simplify_next_db_state'),
1726
-            10,
1727
-            2
1728
-        );
1729
-        add_action(
1730
-            'AHEE__ee_migration_page__after_migration_options_table',
1731
-            array($this, '_migration_page_hook_after_migration_options_table')
1732
-        );
1733
-        add_filter(
1734
-            'FHEE__ee_migration_page__done_migration_header',
1735
-            array($this, '_migration_page_hook_simplify_next_db_state'),
1736
-            10,
1737
-            2
1738
-        );
1739
-        add_filter(
1740
-            'FHEE__ee_migration_page__p_after_done_migration_header',
1741
-            array($this, '_migration_page_hook_simplify_next_db_state'),
1742
-            10,
1743
-            2
1744
-        );
1745
-        add_filter(
1746
-            'FHEE__ee_migration_page__migration_options_template',
1747
-            array($this,'use_migration_options_from_ee3_template')
1748
-        );
1749
-    }
1750
-
1751
-
1752
-
1753
-    public function _migrate_page_hook_simplify_version_strings(
1754
-        $old_content,
1755
-        $current_db_state,
1756
-        $next_db_state,
1757
-        $ultimate_db_state = null
1758
-    ) {
1759
-        return str_replace(
1760
-            array($current_db_state, $next_db_state, $ultimate_db_state),
1761
-            array(esc_html__('EE3', 'event_espresso'), esc_html__('EE4', 'event_espresso'), esc_html__("EE4", 'event_espresso')),
1762
-            $old_content
1763
-        );
1764
-    }
1765
-
1766
-
1767
-
1768
-    public function _migration_page_hook_simplify_next_db_state($old_content, $next_db_state)
1769
-    {
1770
-        return str_replace($next_db_state, esc_html__("EE4", 'event_espresso'), $old_content);
1771
-    }
1772
-
1773
-
1774
-
1775
-    public function _migration_page_hook_option_1_extra_details()
1776
-    {
1777
-        ?>
1075
+		if (! $state) {
1076
+			// insert a new one then
1077
+			$cols_n_values = array(
1078
+					'CNT_ISO'    => $country_iso,
1079
+					'STA_abbrev' => substr($state_name, 0, 6),
1080
+					'STA_name'   => $state_name,
1081
+					'STA_active' => true,
1082
+			);
1083
+			$data_types = array(
1084
+					'%s',// CNT_ISO
1085
+					'%s',// STA_abbrev
1086
+					'%s',// STA_name
1087
+					'%d',// STA_active
1088
+			);
1089
+			$success = $wpdb->insert($state_table, $cols_n_values, $data_types);
1090
+			if (! $success) {
1091
+				throw new EE_Error($this->_create_error_message_for_db_insertion(
1092
+					'N/A',
1093
+					array('state' => $state_name, 'country_id' => $country_name),
1094
+					$state_table,
1095
+					$cols_n_values,
1096
+					$data_types
1097
+				));
1098
+			}
1099
+			$state = $cols_n_values;
1100
+			$state['STA_ID'] = $wpdb->insert_id;
1101
+		}
1102
+		return $state;
1103
+	}
1104
+
1105
+
1106
+
1107
+	/**
1108
+	 * Fixes times like "5:00 PM" into the expected 24-hour format "17:00".
1109
+	 * THis is actually just copied from the 3.1 JSON API because it needed to do the exact same thing
1110
+	 *
1111
+	 * @param type $timeString
1112
+	 * @return string in the php DATETIME format: "G:i" (24-hour format hour with leading zeros, a colon, and minutes
1113
+	 *                with leading zeros)
1114
+	 */
1115
+	public function convertTimeFromAMPM($timeString)
1116
+	{
1117
+		$matches = array();
1118
+		preg_match("~(\\d*):(\\d*)~", $timeString, $matches);
1119
+		if (! $matches || count($matches) < 3) {
1120
+			$hour = '00';
1121
+			$minutes = '00';
1122
+		} else {
1123
+			$hour = intval($matches[1]);
1124
+			$minutes = $matches[2];
1125
+		}
1126
+		if (strpos($timeString, 'PM') || strpos($timeString, 'pm')) {
1127
+			$hour = intval($hour) + 12;
1128
+		}
1129
+		$hour = str_pad("$hour", 2, '0', STR_PAD_LEFT);
1130
+		$minutes = str_pad("$minutes", 2, '0', STR_PAD_LEFT);
1131
+		return "$hour:$minutes";
1132
+	}
1133
+
1134
+
1135
+
1136
+	/**
1137
+	 * Gets the ISO3 fora country given its 3.1 country ID.
1138
+	 *
1139
+	 * @param int $country_id
1140
+	 * @return string the country's ISO3 code
1141
+	 */
1142
+	public function get_iso_from_3_1_country_id($country_id)
1143
+	{
1144
+		$old_countries = array(
1145
+				array(64, 'United States', 'US', 'USA', 1),
1146
+				array(15, 'Australia', 'AU', 'AUS', 1),
1147
+				array(39, 'Canada', 'CA', 'CAN', 1),
1148
+				array(171, 'United Kingdom', 'GB', 'GBR', 1),
1149
+				array(70, 'France', 'FR', 'FRA', 2),
1150
+				array(111, 'Italy', 'IT', 'ITA', 2),
1151
+				array(63, 'Spain', 'ES', 'ESP', 2),
1152
+				array(1, 'Afghanistan', 'AF', 'AFG', 1),
1153
+				array(2, 'Albania', 'AL', 'ALB', 1),
1154
+				array(3, 'Germany', 'DE', 'DEU', 2),
1155
+				array(198, 'Switzerland', 'CH', 'CHE', 1),
1156
+				array(87, 'Netherlands', 'NL', 'NLD', 2),
1157
+				array(197, 'Sweden', 'SE', 'SWE', 1),
1158
+				array(230, 'Akrotiri and Dhekelia', 'CY', 'CYP', 2),
1159
+				array(4, 'Andorra', 'AD', 'AND', 2),
1160
+				array(5, 'Angola', 'AO', 'AGO', 1),
1161
+				array(6, 'Anguilla', 'AI', 'AIA', 1),
1162
+				array(7, 'Antarctica', 'AQ', 'ATA', 1),
1163
+				array(8, 'Antigua and Barbuda', 'AG', 'ATG', 1),
1164
+				array(10, 'Saudi Arabia', 'SA', 'SAU', 1),
1165
+				array(11, 'Algeria', 'DZ', 'DZA', 1),
1166
+				array(12, 'Argentina', 'AR', 'ARG', 1),
1167
+				array(13, 'Armenia', 'AM', 'ARM', 1),
1168
+				array(14, 'Aruba', 'AW', 'ABW', 1),
1169
+				array(16, 'Austria', 'AT', 'AUT', 2),
1170
+				array(17, 'Azerbaijan', 'AZ', 'AZE', 1),
1171
+				array(18, 'Bahamas', 'BS', 'BHS', 1),
1172
+				array(19, 'Bahrain', 'BH', 'BHR', 1),
1173
+				array(20, 'Bangladesh', 'BD', 'BGD', 1),
1174
+				array(21, 'Barbados', 'BB', 'BRB', 1),
1175
+				array(22, 'Belgium ', 'BE', 'BEL', 2),
1176
+				array(23, 'Belize', 'BZ', 'BLZ', 1),
1177
+				array(24, 'Benin', 'BJ', 'BEN', 1),
1178
+				array(25, 'Bermudas', 'BM', 'BMU', 1),
1179
+				array(26, 'Belarus', 'BY', 'BLR', 1),
1180
+				array(27, 'Bolivia', 'BO', 'BOL', 1),
1181
+				array(28, 'Bosnia and Herzegovina', 'BA', 'BIH', 1),
1182
+				array(29, 'Botswana', 'BW', 'BWA', 1),
1183
+				array(96, 'Bouvet Island', 'BV', 'BVT', 1),
1184
+				array(30, 'Brazil', 'BR', 'BRA', 1),
1185
+				array(31, 'Brunei', 'BN', 'BRN', 1),
1186
+				array(32, 'Bulgaria', 'BG', 'BGR', 1),
1187
+				array(33, 'Burkina Faso', 'BF', 'BFA', 1),
1188
+				array(34, 'Burundi', 'BI', 'BDI', 1),
1189
+				array(35, 'Bhutan', 'BT', 'BTN', 1),
1190
+				array(36, 'Cape Verde', 'CV', 'CPV', 1),
1191
+				array(37, 'Cambodia', 'KH', 'KHM', 1),
1192
+				array(38, 'Cameroon', 'CM', 'CMR', 1),
1193
+				array(98, 'Cayman Islands', 'KY', 'CYM', 1),
1194
+				array(172, 'Central African Republic', 'CF', 'CAF', 1),
1195
+				array(40, 'Chad', 'TD', 'TCD', 1),
1196
+				array(41, 'Chile', 'CL', 'CHL', 1),
1197
+				array(42, 'China', 'CN', 'CHN', 1),
1198
+				array(105, 'Christmas Island', 'CX', 'CXR', 1),
1199
+				array(43, 'Cyprus', 'CY', 'CYP', 2),
1200
+				array(99, 'Cocos Island', 'CC', 'CCK', 1),
1201
+				array(100, 'Cook Islands', 'CK', 'COK', 1),
1202
+				array(44, 'Colombia', 'CO', 'COL', 1),
1203
+				array(45, 'Comoros', 'KM', 'COM', 1),
1204
+				array(46, 'Congo', 'CG', 'COG', 1),
1205
+				array(47, 'North Korea', 'KP', 'PRK', 1),
1206
+				array(50, 'Costa Rica', 'CR', 'CRI', 1),
1207
+				array(51, 'Croatia', 'HR', 'HRV', 1),
1208
+				array(52, 'Cuba', 'CU', 'CUB', 1),
1209
+				array(173, 'Czech Republic', 'CZ', 'CZE', 1),
1210
+				array(53, 'Denmark', 'DK', 'DNK', 1),
1211
+				array(54, 'Djibouti', 'DJ', 'DJI', 1),
1212
+				array(55, 'Dominica', 'DM', 'DMA', 1),
1213
+				array(174, 'Dominican Republic', 'DO', 'DOM', 1),
1214
+				array(56, 'Ecuador', 'EC', 'ECU', 1),
1215
+				array(57, 'Egypt', 'EG', 'EGY', 1),
1216
+				array(58, 'El Salvador', 'SV', 'SLV', 1),
1217
+				array(60, 'Eritrea', 'ER', 'ERI', 1),
1218
+				array(61, 'Slovakia', 'SK', 'SVK', 2),
1219
+				array(62, 'Slovenia', 'SI', 'SVN', 2),
1220
+				array(65, 'Estonia', 'EE', 'EST', 2),
1221
+				array(66, 'Ethiopia', 'ET', 'ETH', 1),
1222
+				array(102, 'Faroe islands', 'FO', 'FRO', 1),
1223
+				array(103, 'Falkland Islands', 'FK', 'FLK', 1),
1224
+				array(67, 'Fiji', 'FJ', 'FJI', 1),
1225
+				array(69, 'Finland', 'FI', 'FIN', 2),
1226
+				array(71, 'Gabon', 'GA', 'GAB', 1),
1227
+				array(72, 'Gambia', 'GM', 'GMB', 1),
1228
+				array(73, 'Georgia', 'GE', 'GEO', 1),
1229
+				array(74, 'Ghana', 'GH', 'GHA', 1),
1230
+				array(75, 'Gibraltar', 'GI', 'GIB', 1),
1231
+				array(76, 'Greece', 'GR', 'GRC', 2),
1232
+				array(77, 'Grenada', 'GD', 'GRD', 1),
1233
+				array(78, 'Greenland', 'GL', 'GRL', 1),
1234
+				array(79, 'Guadeloupe', 'GP', 'GLP', 1),
1235
+				array(80, 'Guam', 'GU', 'GUM', 1),
1236
+				array(81, 'Guatemala', 'GT', 'GTM', 1),
1237
+				array(82, 'Guinea', 'GN', 'GIN', 1),
1238
+				array(83, 'Equatorial Guinea', 'GQ', 'GNQ', 1),
1239
+				array(84, 'Guinea-Bissau', 'GW', 'GNB', 1),
1240
+				array(85, 'Guyana', 'GY', 'GUY', 1),
1241
+				array(86, 'Haiti', 'HT', 'HTI', 1),
1242
+				array(88, 'Honduras', 'HN', 'HND', 1),
1243
+				array(89, 'Hong Kong', 'HK', 'HKG', 1),
1244
+				array(90, 'Hungary', 'HU', 'HUN', 1),
1245
+				array(91, 'India', 'IN', 'IND', 1),
1246
+				array(205, 'British Indian Ocean Territory', 'IO', 'IOT', 1),
1247
+				array(92, 'Indonesia', 'ID', 'IDN', 1),
1248
+				array(93, 'Iraq', 'IQ', 'IRQ', 1),
1249
+				array(94, 'Iran', 'IR', 'IRN', 1),
1250
+				array(95, 'Ireland', 'IE', 'IRL', 2),
1251
+				array(97, 'Iceland', 'IS', 'ISL', 1),
1252
+				array(110, 'Israel', 'IL', 'ISR', 1),
1253
+				array(49, 'Ivory Coast ', 'CI', 'CIV', 1),
1254
+				array(112, 'Jamaica', 'JM', 'JAM', 1),
1255
+				array(113, 'Japan', 'JP', 'JPN', 1),
1256
+				array(114, 'Jordan', 'JO', 'JOR', 1),
1257
+				array(115, 'Kazakhstan', 'KZ', 'KAZ', 1),
1258
+				array(116, 'Kenya', 'KE', 'KEN', 1),
1259
+				array(117, 'Kyrgyzstan', 'KG', 'KGZ', 1),
1260
+				array(118, 'Kiribati', 'KI', 'KIR', 1),
1261
+				array(48, 'South Korea', 'KR', 'KOR', 1),
1262
+				array(228, 'Kosovo', 'XK', 'XKV', 2),
1263
+				// there is no official ISO code for Kosovo yet (http://geonames.wordpress.com/2010/03/08/xk-country-code-for-kosovo/) so using a temporary country code and a modified 3 character code for ISO code -- this should be updated if/when Kosovo gets its own ISO code
1264
+				array(119, 'Kuwait', 'KW', 'KWT', 1),
1265
+				array(120, 'Laos', 'LA', 'LAO', 1),
1266
+				array(121, 'Latvia', 'LV', 'LVA', 2),
1267
+				array(122, 'Lesotho', 'LS', 'LSO', 1),
1268
+				array(123, 'Lebanon', 'LB', 'LBN', 1),
1269
+				array(124, 'Liberia', 'LR', 'LBR', 1),
1270
+				array(125, 'Libya', 'LY', 'LBY', 1),
1271
+				array(126, 'Liechtenstein', 'LI', 'LIE', 1),
1272
+				array(127, 'Lithuania', 'LT', 'LTU', 2),
1273
+				array(128, 'Luxemburg', 'LU', 'LUX', 2),
1274
+				array(129, 'Macao', 'MO', 'MAC', 1),
1275
+				array(130, 'Macedonia', 'MK', 'MKD', 1),
1276
+				array(131, 'Madagascar', 'MG', 'MDG', 1),
1277
+				array(132, 'Malaysia', 'MY', 'MYS', 1),
1278
+				array(133, 'Malawi', 'MW', 'MWI', 1),
1279
+				array(134, 'Maldivas', 'MV', 'MDV', 1),
1280
+				array(135, 'Mali', 'ML', 'MLI', 1),
1281
+				array(136, 'Malta', 'MT', 'MLT', 2),
1282
+				array(101, 'Northern Marianas', 'MP', 'MNP', 1),
1283
+				array(137, 'Morocco', 'MA', 'MAR', 1),
1284
+				array(104, 'Marshall islands', 'MH', 'MHL', 1),
1285
+				array(138, 'Martinique', 'MQ', 'MTQ', 1),
1286
+				array(139, 'Mauritius', 'MU', 'MUS', 1),
1287
+				array(140, 'Mauritania', 'MR', 'MRT', 1),
1288
+				array(141, 'Mayote', 'YT', 'MYT', 2),
1289
+				array(142, 'Mexico', 'MX', 'MEX', 1),
1290
+				array(143, 'Micronesia', 'FM', 'FSM', 1),
1291
+				array(144, 'Moldova', 'MD', 'MDA', 1),
1292
+				array(145, 'Monaco', 'MC', 'MCO', 2),
1293
+				array(146, 'Mongolia', 'MN', 'MNG', 1),
1294
+				array(147, 'Montserrat', 'MS', 'MSR', 1),
1295
+				array(227, 'Montenegro', 'ME', 'MNE', 2),
1296
+				array(148, 'Mozambique', 'MZ', 'MOZ', 1),
1297
+				array(149, 'Myanmar', 'MM', 'MMR', 1),
1298
+				array(150, 'Namibia', 'NA', 'NAM', 1),
1299
+				array(151, 'Nauru', 'NR', 'NRU', 1),
1300
+				array(152, 'Nepal', 'NP', 'NPL', 1),
1301
+				array(9, 'Netherlands Antilles', 'AN', 'ANT', 1),
1302
+				array(153, 'Nicaragua', 'NI', 'NIC', 1),
1303
+				array(154, 'Niger', 'NE', 'NER', 1),
1304
+				array(155, 'Nigeria', 'NG', 'NGA', 1),
1305
+				array(156, 'Niue', 'NU', 'NIU', 1),
1306
+				array(157, 'Norway', 'NO', 'NOR', 1),
1307
+				array(158, 'New Caledonia', 'NC', 'NCL', 1),
1308
+				array(159, 'New Zealand', 'NZ', 'NZL', 1),
1309
+				array(160, 'Oman', 'OM', 'OMN', 1),
1310
+				array(161, 'Pakistan', 'PK', 'PAK', 1),
1311
+				array(162, 'Palau', 'PW', 'PLW', 1),
1312
+				array(163, 'Panama', 'PA', 'PAN', 1),
1313
+				array(164, 'Papua New Guinea', 'PG', 'PNG', 1),
1314
+				array(165, 'Paraguay', 'PY', 'PRY', 1),
1315
+				array(166, 'Peru', 'PE', 'PER', 1),
1316
+				array(68, 'Philippines', 'PH', 'PHL', 1),
1317
+				array(167, 'Poland', 'PL', 'POL', 1),
1318
+				array(168, 'Portugal', 'PT', 'PRT', 2),
1319
+				array(169, 'Puerto Rico', 'PR', 'PRI', 1),
1320
+				array(170, 'Qatar', 'QA', 'QAT', 1),
1321
+				array(176, 'Rwanda', 'RW', 'RWA', 1),
1322
+				array(177, 'Romania', 'RO', 'ROM', 2),
1323
+				array(178, 'Russia', 'RU', 'RUS', 1),
1324
+				array(229, 'Saint Pierre and Miquelon', 'PM', 'SPM', 2),
1325
+				array(180, 'Samoa', 'WS', 'WSM', 1),
1326
+				array(181, 'American Samoa', 'AS', 'ASM', 1),
1327
+				array(183, 'San Marino', 'SM', 'SMR', 2),
1328
+				array(184, 'Saint Vincent and the Grenadines', 'VC', 'VCT', 1),
1329
+				array(185, 'Saint Helena', 'SH', 'SHN', 1),
1330
+				array(186, 'Saint Lucia', 'LC', 'LCA', 1),
1331
+				array(188, 'Senegal', 'SN', 'SEN', 1),
1332
+				array(189, 'Seychelles', 'SC', 'SYC', 1),
1333
+				array(190, 'Sierra Leona', 'SL', 'SLE', 1),
1334
+				array(191, 'Singapore', 'SG', 'SGP', 1),
1335
+				array(192, 'Syria', 'SY', 'SYR', 1),
1336
+				array(193, 'Somalia', 'SO', 'SOM', 1),
1337
+				array(194, 'Sri Lanka', 'LK', 'LKA', 1),
1338
+				array(195, 'South Africa', 'ZA', 'ZAF', 1),
1339
+				array(196, 'Sudan', 'SD', 'SDN', 1),
1340
+				array(199, 'Suriname', 'SR', 'SUR', 1),
1341
+				array(200, 'Swaziland', 'SZ', 'SWZ', 1),
1342
+				array(201, 'Thailand', 'TH', 'THA', 1),
1343
+				array(202, 'Taiwan', 'TW', 'TWN', 1),
1344
+				array(203, 'Tanzania', 'TZ', 'TZA', 1),
1345
+				array(204, 'Tajikistan', 'TJ', 'TJK', 1),
1346
+				array(206, 'Timor-Leste', 'TL', 'TLS', 1),
1347
+				array(207, 'Togo', 'TG', 'TGO', 1),
1348
+				array(208, 'Tokelau', 'TK', 'TKL', 1),
1349
+				array(209, 'Tonga', 'TO', 'TON', 1),
1350
+				array(210, 'Trinidad and Tobago', 'TT', 'TTO', 1),
1351
+				array(211, 'Tunisia', 'TN', 'TUN', 1),
1352
+				array(212, 'Turkmenistan', 'TM', 'TKM', 1),
1353
+				array(213, 'Turkey', 'TR', 'TUR', 1),
1354
+				array(214, 'Tuvalu', 'TV', 'TUV', 1),
1355
+				array(215, 'Ukraine', 'UA', 'UKR', 1),
1356
+				array(216, 'Uganda', 'UG', 'UGA', 1),
1357
+				array(59, 'United Arab Emirates', 'AE', 'ARE', 1),
1358
+				array(217, 'Uruguay', 'UY', 'URY', 1),
1359
+				array(218, 'Uzbekistan', 'UZ', 'UZB', 1),
1360
+				array(219, 'Vanuatu', 'VU', 'VUT', 1),
1361
+				array(220, 'Vatican City', 'VA', 'VAT', 2),
1362
+				array(221, 'Venezuela', 'VE', 'VEN', 1),
1363
+				array(222, 'Vietnam', 'VN', 'VNM', 1),
1364
+				array(108, 'Virgin Islands', 'VI', 'VIR', 1),
1365
+				array(223, 'Yemen', 'YE', 'YEM', 1),
1366
+				array(225, 'Zambia', 'ZM', 'ZMB', 1),
1367
+				array(226, 'Zimbabwe', 'ZW', 'ZWE', 1),
1368
+		);
1369
+		$country_iso = 'US';
1370
+		foreach ($old_countries as $country_array) {
1371
+			// note: index 0 is the 3.1 country ID
1372
+			if ($country_array[0] == $country_id) {
1373
+				// note: index 2 is the ISO
1374
+				$country_iso = $country_array[2];
1375
+				break;
1376
+			}
1377
+		}
1378
+		return $country_iso;
1379
+	}
1380
+
1381
+
1382
+
1383
+	/**
1384
+	 * Gets the ISO3 for the
1385
+	 *
1386
+	 * @return string
1387
+	 */
1388
+	public function get_default_country_iso()
1389
+	{
1390
+		$old_org_options = get_option('events_organization_settings');
1391
+		$iso = $this->get_iso_from_3_1_country_id($old_org_options['organization_country']);
1392
+		return $iso;
1393
+	}
1394
+
1395
+
1396
+
1397
+	/**
1398
+	 * Converst a 3.1 payment status to its equivalent 4.1 regisration status
1399
+	 *
1400
+	 * @param string  $payment_status                   possible value for 3.1's evens_attendee.payment_status
1401
+	 * @param boolean $this_thing_required_pre_approval whether the thing we're considering (the general setting's
1402
+	 *                                                  default payment status, the event's default payment status, or
1403
+	 *                                                  the attendee's payment status) required pre-approval.
1404
+	 * @return string STS_ID for use in 4.1
1405
+	 */
1406
+	public function convert_3_1_payment_status_to_4_1_STS_ID($payment_status, $this_thing_required_pre_approval = false)
1407
+	{
1408
+		// EE team can read the related discussion: https://app.asana.com/0/2400967562914/9418495544455
1409
+		if ($this_thing_required_pre_approval) {
1410
+			return 'RNA';
1411
+		} else {
1412
+			$mapping = $default_reg_stati_conversions = array(
1413
+					'Completed'        => 'RAP',
1414
+					''                 => 'RPP',
1415
+					'Incomplete'       => 'RPP',
1416
+					'Pending'          => 'RAP',
1417
+					// stati that only occurred on 3.1 attendees:
1418
+					'Payment Declined' => 'RPP',
1419
+					'Not Completed'    => 'RPP',
1420
+					'Cancelled'        => 'RPP',
1421
+					'Declined'         => 'RPP',
1422
+			);
1423
+		}
1424
+		return isset($mapping[ $payment_status ]) ? $mapping[ $payment_status ] : 'RNA';
1425
+	}
1426
+
1427
+
1428
+
1429
+	/**
1430
+	 * Makes sure the 3.1's image url is converted to an image attachment post to the 4.1 CPT event
1431
+	 * and sets it as the featured image on the CPT event
1432
+	 *
1433
+	 * @param type                            $old_event
1434
+	 * @param type                            $new_cpt_id
1435
+	 * @param  EE_Data_Migration_Script_Stage $migration_stage the stage which called this, where errors should be added
1436
+	 * @return boolean whether or not we had to do the big job of creating an image attachment
1437
+	 */
1438
+	public function convert_image_url_to_attachment_and_attach_to_post(
1439
+		$guid,
1440
+		$new_cpt_id,
1441
+		EE_Data_Migration_Script_Stage $migration_stage
1442
+	) {
1443
+		$created_attachment_post = false;
1444
+		$guid = $this->_get_original_guid($guid);
1445
+		if ($guid) {
1446
+			// check for an existing attachment post with this guid
1447
+			$attachment_post_id = $this->_get_image_attachment_id_by_GUID($guid);
1448
+			if (! $attachment_post_id) {
1449
+				// post thumbnail with that GUID doesn't exist, we should create one
1450
+				$attachment_post_id = $this->_create_image_attachment_from_GUID($guid, $migration_stage);
1451
+				$created_attachment_post = true;
1452
+			}
1453
+			// double-check we actually have an attachment post
1454
+			if ($attachment_post_id) {
1455
+				update_post_meta($new_cpt_id, '_thumbnail_id', $attachment_post_id);
1456
+			} else {
1457
+				$migration_stage->add_error(sprintf(esc_html__(
1458
+					"Could not update event image %s for CPT with ID %d, but attachments post ID is %d",
1459
+					"event_espresso"
1460
+				), $guid, $new_cpt_id, $attachment_post_id));
1461
+			}
1462
+		}
1463
+		return $created_attachment_post;
1464
+	}
1465
+
1466
+
1467
+
1468
+	/**
1469
+	 * In 3.1, the event thumbnail image DOESN'T point to the orignal image, but instead
1470
+	 * to a large thumbnail (which has nearly the same GUID, except it adds "-{width}x{height}" before the filetype,
1471
+	 * or whatever dimensions it is. Eg 'http://mysite.com/image1-300x400.jpg' instead of
1472
+	 * 'http://mysite.com/image1.jpg' ). This function attempts to strip that off and get the original file, if it
1473
+	 * exists
1474
+	 *
1475
+	 * @param string $guid_in_old_event
1476
+	 * @return string either the original guid, or $guid_in_old_event if we couldn't figure out what the original was
1477
+	 */
1478
+	private function _get_original_guid($guid_in_old_event)
1479
+	{
1480
+		$original_guid = preg_replace('~-\d*x\d*\.~', '.', $guid_in_old_event, 1);
1481
+		// do a head request to verify the file exists
1482
+		$head_response = wp_remote_head($original_guid);
1483
+		if (! $head_response instanceof WP_Error && $head_response['response']['message'] == 'OK') {
1484
+			return $original_guid;
1485
+		} else {
1486
+			return $guid_in_old_event;
1487
+		}
1488
+	}
1489
+
1490
+
1491
+
1492
+	/**
1493
+	 * Creates an image attachment post for the GUID. If the GUID points to a remote image,
1494
+	 * we download it to our uploads directory so that it can be properly processed (eg, creates different sizes of
1495
+	 * thumbnails)
1496
+	 *
1497
+	 * @param type                           $guid
1498
+	 * @param EE_Data_Migration_Script_Stage $migration_stage
1499
+	 * @return int
1500
+	 */
1501
+	private function _create_image_attachment_from_GUID($guid, EE_Data_Migration_Script_Stage $migration_stage)
1502
+	{
1503
+		if (! $guid) {
1504
+			$migration_stage->add_error(sprintf(esc_html__(
1505
+				"Cannot create image attachment for a blank GUID!",
1506
+				"event_espresso"
1507
+			)));
1508
+			return 0;
1509
+		}
1510
+		$wp_filetype = wp_check_filetype(basename($guid), null);
1511
+		$wp_upload_dir = wp_upload_dir();
1512
+		// if the file is located remotely, download it to our uploads DIR, because wp_genereate_attachmnet_metadata needs the file to be local
1513
+		if (strpos($guid, $wp_upload_dir['url']) === false) {
1514
+			// image is located remotely. download it and place it in the uploads directory
1515
+			if (! is_readable($guid)) {
1516
+				$migration_stage->add_error(sprintf(esc_html__(
1517
+					"Could not create image attachment from non-existent file: %s",
1518
+					"event_espresso"
1519
+				), $guid));
1520
+				return 0;
1521
+			}
1522
+			$contents = file_get_contents($guid);
1523
+			if ($contents === false) {
1524
+				$migration_stage->add_error(sprintf(esc_html__(
1525
+					"Could not read image at %s, and therefore couldnt create an attachment post for it.",
1526
+					"event_espresso"
1527
+				), $guid));
1528
+				return false;
1529
+			}
1530
+			$local_filepath = $wp_upload_dir['path'] . '/' . basename($guid);
1531
+			$savefile = fopen($local_filepath, 'w');
1532
+			fwrite($savefile, $contents);
1533
+			fclose($savefile);
1534
+			$guid = str_replace($wp_upload_dir['path'], $wp_upload_dir['url'], $local_filepath);
1535
+		} else {
1536
+			$local_filepath = str_replace($wp_upload_dir['url'], $wp_upload_dir['path'], $guid);
1537
+		}
1538
+		$attachment = array(
1539
+				'guid'           => $guid,
1540
+				'post_mime_type' => $wp_filetype['type'],
1541
+				'post_title'     => preg_replace('/\.[^.]+$/', '', basename($guid)),
1542
+				'post_content'   => '',
1543
+				'post_status'    => 'inherit',
1544
+		);
1545
+		$attach_id = wp_insert_attachment($attachment, $guid);
1546
+		if (! $attach_id) {
1547
+			$migration_stage->add_error(sprintf(esc_html__(
1548
+				"Could not create image attachment post from image '%s'. Attachment data was %s.",
1549
+				"event_espresso"
1550
+			), $guid, $this->_json_encode($attachment)));
1551
+			return $attach_id;
1552
+		}
1553
+		// you must first include the image.php file
1554
+		// for the function wp_generate_attachment_metadata() to work
1555
+		require_once(ABSPATH . 'wp-admin/includes/image.php');
1556
+		$attach_data = wp_generate_attachment_metadata($attach_id, $local_filepath);
1557
+		if (! $attach_data) {
1558
+			$migration_stage->add_error(sprintf(esc_html__(
1559
+				"Coudl not genereate attachment metadata for attachment post %d with filepath %s and GUID %s. Please check the file was downloaded properly.",
1560
+				"event_espresso"
1561
+			), $attach_id, $local_filepath, $guid));
1562
+			return $attach_id;
1563
+		}
1564
+		$metadata_save_result = wp_update_attachment_metadata($attach_id, $attach_data);
1565
+		if (! $metadata_save_result) {
1566
+			$migration_stage->add_error(sprintf(esc_html__(
1567
+				"Could not update attachment metadata for attachment %d with data %s",
1568
+				"event_espresso"
1569
+			), $attach_id, $this->_json_encode($attach_data)));
1570
+		}
1571
+		return $attach_id;
1572
+	}
1573
+
1574
+
1575
+
1576
+	/**
1577
+	 * Finds the attachment post containing info about an image attachment given the GUID (link to the image itself),
1578
+	 * and returns its ID.
1579
+	 *
1580
+	 * @global type  $wpdb
1581
+	 * @param string $guid
1582
+	 * @return int
1583
+	 */
1584
+	private function _get_image_attachment_id_by_GUID($guid)
1585
+	{
1586
+		global $wpdb;
1587
+		$attachment_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid=%s LIMIT 1", $guid));
1588
+		return $attachment_id;
1589
+	}
1590
+
1591
+
1592
+
1593
+	/**
1594
+	 * Returns a mysql-formatted DATETIME in UTC time, given a $DATETIME_string
1595
+	 * (and optionally a timezone; if none is given, the wp default is used)
1596
+	 *
1597
+	 * @param EE_Data_Migration_Script_base $stage
1598
+	 * @param array                         $row_of_data , the row from the DB (as an array) we're trying to find the
1599
+	 *                                                   UTC time for
1600
+	 * @param string                        $DATETIME_string
1601
+	 * @param string                        $timezone
1602
+	 * @return string
1603
+	 */
1604
+	public function convert_date_string_to_utc(
1605
+		EE_Data_Migration_Script_Stage $stage,
1606
+		$row_of_data,
1607
+		$DATETIME_string,
1608
+		$timezone = null
1609
+	) {
1610
+		$original_tz = $timezone;
1611
+		if (! $timezone) {
1612
+			$timezone = $this->_get_wp_timezone();
1613
+		}
1614
+		if (! $timezone) {
1615
+			$stage->add_error(sprintf(
1616
+				esc_html__("Could not find timezone given %s for %s", "event_espresso"),
1617
+				$original_tz,
1618
+				$row_of_data
1619
+			));
1620
+			$timezone = 'UTC';
1621
+		}
1622
+		try {
1623
+			$date_obj = new DateTime($DATETIME_string, new DateTimeZone($timezone));
1624
+			EEH_DTT_Helper::setTimezone($date_obj, new DateTimeZone('UTC'));
1625
+		} catch (Exception $e) {
1626
+			$stage->add_error(sprintf(esc_html__(
1627
+				"Could not convert time string '%s' using timezone '%s' into a proper DATETIME. Using current time instead.",
1628
+				"event_espresso"
1629
+			), $DATETIME_string, $timezone));
1630
+			$date_obj = new DateTime();
1631
+		}
1632
+		return $date_obj->format('Y-m-d H:i:s');
1633
+	}
1634
+
1635
+
1636
+
1637
+	/**
1638
+	 * Gets the default timezone string from wordpress (even if they set a gmt offset)
1639
+	 *
1640
+	 * @return string
1641
+	 */
1642
+	private function _get_wp_timezone()
1643
+	{
1644
+		$timezone = empty($timezone) ? get_option('timezone_string') : $timezone;
1645
+		// if timezone is STILL empty then let's get the GMT offset and then set the timezone_string using our converter
1646
+		if (empty($timezone)) {
1647
+			// let's get a the WordPress UTC offset
1648
+			$offset = get_option('gmt_offset');
1649
+			$timezone = $this->timezone_convert_to_string_from_offset($offset);
1650
+		}
1651
+		return $timezone;
1652
+	}
1653
+
1654
+
1655
+
1656
+	/**
1657
+	 * Gets the wordpress timezone string from a UTC offset
1658
+	 *
1659
+	 * @param int $offset
1660
+	 * @return boolean
1661
+	 */
1662
+	private function timezone_convert_to_string_from_offset($offset)
1663
+	{
1664
+		// shamelessly taken from bottom comment at http://ca1.php.net/manual/en/function.timezone-name-from-abbr.php because timezone_name_from_abbr() did not work as expected - its not reliable
1665
+		$offset *= 3600; // convert hour offset to seconds
1666
+		$abbrarray = timezone_abbreviations_list();
1667
+		foreach ($abbrarray as $abbr) {
1668
+			foreach ($abbr as $city) {
1669
+				if ($city['offset'] == $offset) {
1670
+					return $city['timezone_id'];
1671
+				}
1672
+			}
1673
+		}
1674
+		return false;
1675
+	}
1676
+
1677
+
1678
+
1679
+	public function migration_page_hooks()
1680
+	{
1681
+		add_filter(
1682
+			'FHEE__ee_migration_page__header',
1683
+			array($this, '_migrate_page_hook_simplify_version_strings'),
1684
+			10,
1685
+			3
1686
+		);
1687
+		add_filter(
1688
+			'FHEE__ee_migration_page__p_after_header',
1689
+			array($this, '_migration_page_hook_simplify_next_db_state'),
1690
+			10,
1691
+			2
1692
+		);
1693
+		add_filter(
1694
+			'FHEE__ee_migration_page__option_1_main',
1695
+			array($this, '_migrate_page_hook_simplify_version_strings'),
1696
+			10,
1697
+			3
1698
+		);
1699
+		add_filter(
1700
+			'FHEE__ee_migration_page__option_1_button_text',
1701
+			array($this, '_migrate_page_hook_simplify_version_strings'),
1702
+			10,
1703
+			3
1704
+		);
1705
+		add_action(
1706
+			'AHEE__ee_migration_page__option_1_extra_details',
1707
+			array($this, '_migration_page_hook_option_1_extra_details'),
1708
+			10,
1709
+			3
1710
+		);
1711
+		add_filter(
1712
+			'FHEE__ee_migration_page__option_2_main',
1713
+			array($this, '_migrate_page_hook_simplify_version_strings'),
1714
+			10,
1715
+			4
1716
+		);
1717
+		add_filter(
1718
+			'FHEE__ee_migration_page__option_2_button_text',
1719
+			array($this, '_migration_page_hook_simplify_next_db_state'),
1720
+			10,
1721
+			2
1722
+		);
1723
+		add_filter(
1724
+			'FHEE__ee_migration_page__option_2_details',
1725
+			array($this, '_migration_page_hook_simplify_next_db_state'),
1726
+			10,
1727
+			2
1728
+		);
1729
+		add_action(
1730
+			'AHEE__ee_migration_page__after_migration_options_table',
1731
+			array($this, '_migration_page_hook_after_migration_options_table')
1732
+		);
1733
+		add_filter(
1734
+			'FHEE__ee_migration_page__done_migration_header',
1735
+			array($this, '_migration_page_hook_simplify_next_db_state'),
1736
+			10,
1737
+			2
1738
+		);
1739
+		add_filter(
1740
+			'FHEE__ee_migration_page__p_after_done_migration_header',
1741
+			array($this, '_migration_page_hook_simplify_next_db_state'),
1742
+			10,
1743
+			2
1744
+		);
1745
+		add_filter(
1746
+			'FHEE__ee_migration_page__migration_options_template',
1747
+			array($this,'use_migration_options_from_ee3_template')
1748
+		);
1749
+	}
1750
+
1751
+
1752
+
1753
+	public function _migrate_page_hook_simplify_version_strings(
1754
+		$old_content,
1755
+		$current_db_state,
1756
+		$next_db_state,
1757
+		$ultimate_db_state = null
1758
+	) {
1759
+		return str_replace(
1760
+			array($current_db_state, $next_db_state, $ultimate_db_state),
1761
+			array(esc_html__('EE3', 'event_espresso'), esc_html__('EE4', 'event_espresso'), esc_html__("EE4", 'event_espresso')),
1762
+			$old_content
1763
+		);
1764
+	}
1765
+
1766
+
1767
+
1768
+	public function _migration_page_hook_simplify_next_db_state($old_content, $next_db_state)
1769
+	{
1770
+		return str_replace($next_db_state, esc_html__("EE4", 'event_espresso'), $old_content);
1771
+	}
1772
+
1773
+
1774
+
1775
+	public function _migration_page_hook_option_1_extra_details()
1776
+	{
1777
+		?>
1778 1778
         <p><?php printf(esc_html__(
1779
-            "Note: many of your EE3 shortcodes will be changed to EE4 shortcodes during this migration (among many other things). Should you revert to EE3, then you should restore to your backup or manually change the EE4 shortcodes back to their EE3 equivalents",
1780
-            "event_espresso"
1781
-        )); ?></p><?php
1782
-    }
1779
+			"Note: many of your EE3 shortcodes will be changed to EE4 shortcodes during this migration (among many other things). Should you revert to EE3, then you should restore to your backup or manually change the EE4 shortcodes back to their EE3 equivalents",
1780
+			"event_espresso"
1781
+		)); ?></p><?php
1782
+	}
1783 1783
 
1784 1784
 
1785 1785
 
1786
-    public function _migration_page_hook_after_migration_options_table()
1787
-    {
1788
-        ?><p class="ee-attention">
1786
+	public function _migration_page_hook_after_migration_options_table()
1787
+	{
1788
+		?><p class="ee-attention">
1789 1789
         <strong><span class="reminder-spn">
1790 1790
                 <?php _e(
1791
-                    "Important note to those using Event Espresso 3 addons: ",
1792
-                    "event_espresso"
1793
-                ); ?></span></strong>
1791
+					"Important note to those using Event Espresso 3 addons: ",
1792
+					"event_espresso"
1793
+				); ?></span></strong>
1794 1794
         <br/>
1795 1795
         <?php _e(
1796
-            "Unless an addon's description on our website explicitly states that it is compatible with EE4, you should consider it incompatible and know that it WILL NOT WORK correctly with this new version of Event Espresso 4 (EE4). As well, any data for incompatible addons will NOT BE MIGRATED until an updated EE4 compatible version of the addon is available. If you want, or need to keep using your EE3 addons, you should simply continue using EE3 until EE4 compatible versions of your addons become available. To continue using EE3 for now, just deactivate EE4 and reactivate EE3.",
1797
-            "event_espresso"
1798
-        ); ?>
1796
+			"Unless an addon's description on our website explicitly states that it is compatible with EE4, you should consider it incompatible and know that it WILL NOT WORK correctly with this new version of Event Espresso 4 (EE4). As well, any data for incompatible addons will NOT BE MIGRATED until an updated EE4 compatible version of the addon is available. If you want, or need to keep using your EE3 addons, you should simply continue using EE3 until EE4 compatible versions of your addons become available. To continue using EE3 for now, just deactivate EE4 and reactivate EE3.",
1797
+			"event_espresso"
1798
+		); ?>
1799 1799
         </p><?php
1800
-    }
1800
+	}
1801 1801
 
1802 1802
 
1803 1803
 
1804
-    /**
1805
-     * When showing the migration options, show more options and info than normal (ie, give folks the option
1806
-     * to start using EE4 without migrating. From EE3 that's fine, because it doesn't actually remove any data, because
1807
-     * EE4 doesn't have any yet. But when migrating from EE4 it would remove old data, so its not a great idea).
1808
-     * @param $template_filepath
1809
-     * @return string
1810
-     */
1811
-    public function use_migration_options_from_ee3_template($template_filepath)
1812
-    {
1813
-        return EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee3.template.php';
1814
-    }
1804
+	/**
1805
+	 * When showing the migration options, show more options and info than normal (ie, give folks the option
1806
+	 * to start using EE4 without migrating. From EE3 that's fine, because it doesn't actually remove any data, because
1807
+	 * EE4 doesn't have any yet. But when migrating from EE4 it would remove old data, so its not a great idea).
1808
+	 * @param $template_filepath
1809
+	 * @return string
1810
+	 */
1811
+	public function use_migration_options_from_ee3_template($template_filepath)
1812
+	{
1813
+		return EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee3.template.php';
1814
+	}
1815 1815
 }
Please login to merge, or discard this patch.
reg_steps/attendee_information/attendee_info_single.template.php 2 patches
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -6,16 +6,16 @@  discard block
 block discarded – undo
6 6
 <?php if (!is_admin()) : ?>
7 7
     <p id="spco-attendee_information-pg" class="spco-steps-pg small-text drk-grey-text">
8 8
         <?php echo apply_filters(
9
-            'FHEE__registration_page_attendee_information__attendee_information_pg',
10
-            sprintf(
11
-                __(
12
-                    'In order to process your registration, we ask you to provide the following information.%1$sPlease note that all fields marked with an asterisk (%2$s) are required.',
13
-                    'event_espresso'
14
-                ),
15
-                '<br />',
16
-                '<span class="asterisk">*</span>'
17
-            )
18
-        ); ?>
9
+			'FHEE__registration_page_attendee_information__attendee_information_pg',
10
+			sprintf(
11
+				__(
12
+					'In order to process your registration, we ask you to provide the following information.%1$sPlease note that all fields marked with an asterisk (%2$s) are required.',
13
+					'event_espresso'
14
+				),
15
+				'<br />',
16
+				'<span class="asterisk">*</span>'
17
+			)
18
+		); ?>
19 19
 </p>
20 20
 <?php endif; ?>
21 21
 
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
 $prev_ticket = 0;
26 26
 
27 27
 if (count($registrations) > 0) {
28
-    ?>
28
+	?>
29 29
 
30 30
     <div id="spco-attendee-panel-dv-single"
31 31
         class="spco-attendee-panel-dv spco-attendee-ticket-single">
@@ -40,52 +40,52 @@  discard block
 block discarded – undo
40 40
                     <th scope="col" width="" class="jst-left"><?php _e('Name and Description', 'event_espresso'); ?></th>
41 41
                     <th scope="col" width="7.5%" class="jst-rght">
42 42
                         <?php _e(
43
-                            'Qty',
44
-                            'event_espresso'
45
-                        ); ?></th>
43
+							'Qty',
44
+							'event_espresso'
45
+						); ?></th>
46 46
                     <th scope="col" width="17.5%" class="jst-rght">
47 47
                         <?php _e(
48
-                            'Price',
49
-                            'event_espresso'
50
-                        ); ?></th>
48
+							'Price',
49
+							'event_espresso'
50
+						); ?></th>
51 51
                     <th scope="col" width="17.5%" class="jst-rght">
52 52
                         <?php _e(
53
-                            'Total',
54
-                            'event_espresso'
55
-                        ); ?></th>
53
+							'Total',
54
+							'event_espresso'
55
+						); ?></th>
56 56
                 </tr>
57 57
                 </thead>
58 58
                 <tbody>
59 59
                 <?php
60
-                // Store previous values to avoid duplicated rows.
61
-                $prev_ticket = 0;
62
-                // Display all tickets inside.
63
-                foreach ($registrations as $registration) {
64
-                    if ($registration instanceof EE_Registration) {
65
-                        if ($registration->ticket()->ID() !== $prev_ticket) {
66
-                            echo $ticket_line_item[ $registration->ticket()->ID() ];
67
-                        }
60
+				// Store previous values to avoid duplicated rows.
61
+				$prev_ticket = 0;
62
+				// Display all tickets inside.
63
+				foreach ($registrations as $registration) {
64
+					if ($registration instanceof EE_Registration) {
65
+						if ($registration->ticket()->ID() !== $prev_ticket) {
66
+							echo $ticket_line_item[ $registration->ticket()->ID() ];
67
+						}
68 68
 
69
-                        $prev_ticket = $registration->ticket()->ID();
70
-                    }
71
-                }
72
-                ?>
69
+						$prev_ticket = $registration->ticket()->ID();
70
+					}
71
+				}
72
+				?>
73 73
                 </tbody>
74 74
             </table>
75 75
         </div>
76 76
     </div>
77 77
 
78 78
     <?php
79
-    // Display the forms below the table.
80
-    foreach ($registrations as $registration) {
81
-        if ($registration instanceof EE_Registration) {
82
-            // Attendee Questions.
83
-            $reg_form = EE_Template_Layout::get_subform_name($registration->reg_url_link());
84
-            echo ${$reg_form};
85
-        } // if ( $registration instanceof EE_Registration )
86
-    } // end foreach ( $registrations as $registration )
79
+	// Display the forms below the table.
80
+	foreach ($registrations as $registration) {
81
+		if ($registration instanceof EE_Registration) {
82
+			// Attendee Questions.
83
+			$reg_form = EE_Template_Layout::get_subform_name($registration->reg_url_link());
84
+			echo ${$reg_form};
85
+		} // if ( $registration instanceof EE_Registration )
86
+	} // end foreach ( $registrations as $registration )
87 87
 
88
-    echo $default_hidden_inputs;
88
+	echo $default_hidden_inputs;
89 89
 } // end if ( count( $registrations ) > 0 )
90 90
 
91 91
 ?>
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@  discard block
 block discarded – undo
3 3
 /** @var array $ticket_line_item */
4 4
 /** @var string $default_hidden_inputs */
5 5
 ?>
6
-<?php if (!is_admin()) : ?>
6
+<?php if ( ! is_admin()) : ?>
7 7
     <p id="spco-attendee_information-pg" class="spco-steps-pg small-text drk-grey-text">
8 8
         <?php echo apply_filters(
9 9
             'FHEE__registration_page_attendee_information__attendee_information_pg',
@@ -31,7 +31,7 @@  discard block
 block discarded – undo
31 31
         class="spco-attendee-panel-dv spco-attendee-ticket-single">
32 32
 
33 33
         <div class="spco-ticket-info-dv small-text">
34
-            <?php if (!is_admin()) : ?>
34
+            <?php if ( ! is_admin()) : ?>
35 35
                 <h5><?php _e('Details', 'event_espresso'); ?></h5>
36 36
             <?php endif; ?>
37 37
             <table class="spco-ticket-details">
@@ -63,7 +63,7 @@  discard block
 block discarded – undo
63 63
                 foreach ($registrations as $registration) {
64 64
                     if ($registration instanceof EE_Registration) {
65 65
                         if ($registration->ticket()->ID() !== $prev_ticket) {
66
-                            echo $ticket_line_item[ $registration->ticket()->ID() ];
66
+                            echo $ticket_line_item[$registration->ticket()->ID()];
67 67
                         }
68 68
 
69 69
                         $prev_ticket = $registration->ticket()->ID();
Please login to merge, or discard this patch.
core/services/assets/AssetManager.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -270,7 +270,7 @@
 block discarded – undo
270 270
      * @param string $asset_type
271 271
      * @param string $handle
272 272
      * @param array  $extra_dependencies
273
-     * @return array
273
+     * @return string
274 274
      * @since 4.10.2.p
275 275
      */
276 276
     private function getAssetDetails($asset_type, $handle, $extra_dependencies = [])
Please login to merge, or discard this patch.
Indentation   +255 added lines, -255 removed lines patch added patch discarded remove patch
@@ -23,284 +23,284 @@
 block discarded – undo
23 23
 abstract class AssetManager implements AssetManagerInterface
24 24
 {
25 25
 
26
-    /**
27
-     * @var AssetCollection $assets
28
-     */
29
-    protected $assets;
26
+	/**
27
+	 * @var AssetCollection $assets
28
+	 */
29
+	protected $assets;
30 30
 
31
-    /**
32
-     * @var DomainInterface
33
-     */
34
-    protected $domain;
31
+	/**
32
+	 * @var DomainInterface
33
+	 */
34
+	protected $domain;
35 35
 
36
-    /**
37
-     * @var Registry $registry
38
-     */
39
-    protected $registry;
36
+	/**
37
+	 * @var Registry $registry
38
+	 */
39
+	protected $registry;
40 40
 
41 41
 
42
-    /**
43
-     * AssetRegister constructor.
44
-     *
45
-     * @param DomainInterface $domain
46
-     * @param AssetCollection $assets
47
-     * @param Registry        $registry
48
-     */
49
-    public function __construct(DomainInterface $domain, AssetCollection $assets, Registry $registry)
50
-    {
51
-        $this->domain = $domain;
52
-        $this->assets = $assets;
53
-        $this->registry = $registry;
54
-        add_action('wp_enqueue_scripts', array($this, 'addManifestFile'), 0);
55
-        add_action('admin_enqueue_scripts', array($this, 'addManifestFile'), 0);
56
-        add_action('wp_enqueue_scripts', array($this, 'addAssets'), 2);
57
-        add_action('admin_enqueue_scripts', array($this, 'addAssets'), 2);
58
-    }
42
+	/**
43
+	 * AssetRegister constructor.
44
+	 *
45
+	 * @param DomainInterface $domain
46
+	 * @param AssetCollection $assets
47
+	 * @param Registry        $registry
48
+	 */
49
+	public function __construct(DomainInterface $domain, AssetCollection $assets, Registry $registry)
50
+	{
51
+		$this->domain = $domain;
52
+		$this->assets = $assets;
53
+		$this->registry = $registry;
54
+		add_action('wp_enqueue_scripts', array($this, 'addManifestFile'), 0);
55
+		add_action('admin_enqueue_scripts', array($this, 'addManifestFile'), 0);
56
+		add_action('wp_enqueue_scripts', array($this, 'addAssets'), 2);
57
+		add_action('admin_enqueue_scripts', array($this, 'addAssets'), 2);
58
+	}
59 59
 
60 60
 
61
-    /**
62
-     * @since 4.9.71.p
63
-     * @return string
64
-     */
65
-    public function assetNamespace()
66
-    {
67
-        return $this->domain->assetNamespace();
68
-    }
61
+	/**
62
+	 * @since 4.9.71.p
63
+	 * @return string
64
+	 */
65
+	public function assetNamespace()
66
+	{
67
+		return $this->domain->assetNamespace();
68
+	}
69 69
 
70 70
 
71
-    /**
72
-     * @return void
73
-     * @throws DuplicateCollectionIdentifierException
74
-     * @throws InvalidDataTypeException
75
-     * @throws InvalidEntityException
76
-     * @since 4.9.62.p
77
-     */
78
-    public function addManifestFile()
79
-    {
80
-        // if a manifest file has already been added for this domain, then just return
81
-        if ($this->assets->has($this->domain->assetNamespace())) {
82
-            return;
83
-        }
84
-        $asset = new ManifestFile($this->domain);
85
-        $this->assets->add($asset, $this->domain->assetNamespace());
86
-    }
71
+	/**
72
+	 * @return void
73
+	 * @throws DuplicateCollectionIdentifierException
74
+	 * @throws InvalidDataTypeException
75
+	 * @throws InvalidEntityException
76
+	 * @since 4.9.62.p
77
+	 */
78
+	public function addManifestFile()
79
+	{
80
+		// if a manifest file has already been added for this domain, then just return
81
+		if ($this->assets->has($this->domain->assetNamespace())) {
82
+			return;
83
+		}
84
+		$asset = new ManifestFile($this->domain);
85
+		$this->assets->add($asset, $this->domain->assetNamespace());
86
+	}
87 87
 
88 88
 
89
-    /**
90
-     * @return ManifestFile[]
91
-     * @since 4.9.62.p
92
-     */
93
-    public function getManifestFile()
94
-    {
95
-        return $this->assets->getManifestFiles();
96
-    }
89
+	/**
90
+	 * @return ManifestFile[]
91
+	 * @since 4.9.62.p
92
+	 */
93
+	public function getManifestFile()
94
+	{
95
+		return $this->assets->getManifestFiles();
96
+	}
97 97
 
98 98
 
99
-    /**
100
-     * @param string $handle
101
-     * @param string $source
102
-     * @param array  $dependencies
103
-     * @param bool   $load_in_footer
104
-     * @param string $version
105
-     * @return JavascriptAsset
106
-     * @throws DuplicateCollectionIdentifierException
107
-     * @throws InvalidDataTypeException
108
-     * @throws InvalidEntityException
109
-     * @throws DomainException
110
-     * @since 4.9.62.p
111
-     */
112
-    public function addJavascript(
113
-        $handle,
114
-        $source,
115
-        array $dependencies = array(),
116
-        $load_in_footer = true,
117
-        $version = ''
118
-    ) {
119
-        $asset = new JavascriptAsset(
120
-            $handle,
121
-            $source,
122
-            array_unique($dependencies),
123
-            $load_in_footer,
124
-            $this->domain,
125
-            $version
126
-        );
127
-        $this->assets->add($asset, $handle);
128
-        return $asset;
129
-    }
99
+	/**
100
+	 * @param string $handle
101
+	 * @param string $source
102
+	 * @param array  $dependencies
103
+	 * @param bool   $load_in_footer
104
+	 * @param string $version
105
+	 * @return JavascriptAsset
106
+	 * @throws DuplicateCollectionIdentifierException
107
+	 * @throws InvalidDataTypeException
108
+	 * @throws InvalidEntityException
109
+	 * @throws DomainException
110
+	 * @since 4.9.62.p
111
+	 */
112
+	public function addJavascript(
113
+		$handle,
114
+		$source,
115
+		array $dependencies = array(),
116
+		$load_in_footer = true,
117
+		$version = ''
118
+	) {
119
+		$asset = new JavascriptAsset(
120
+			$handle,
121
+			$source,
122
+			array_unique($dependencies),
123
+			$load_in_footer,
124
+			$this->domain,
125
+			$version
126
+		);
127
+		$this->assets->add($asset, $handle);
128
+		return $asset;
129
+	}
130 130
 
131 131
 
132
-    /**
133
-     * Used to register a javascript asset where everything is dynamically derived from the given handle.
134
-     *
135
-     * @param string       $handle
136
-     * @param string|array $extra_dependencies
137
-     * @return JavascriptAsset
138
-     * @throws DuplicateCollectionIdentifierException
139
-     * @throws InvalidDataTypeException
140
-     * @throws InvalidEntityException
141
-     * @throws DomainException
142
-     */
143
-    public function addJs($handle, $extra_dependencies = [])
144
-    {
145
-        $details = $this->getAssetDetails(
146
-            Asset::TYPE_JS,
147
-            $handle,
148
-            $extra_dependencies
149
-        );
150
-        return $this->addJavascript(
151
-            $handle,
152
-            $this->registry->getJsUrl($this->domain->assetNamespace(), $handle),
153
-            $details['dependencies'],
154
-            true,
155
-            $details['version']
156
-        );
157
-    }
132
+	/**
133
+	 * Used to register a javascript asset where everything is dynamically derived from the given handle.
134
+	 *
135
+	 * @param string       $handle
136
+	 * @param string|array $extra_dependencies
137
+	 * @return JavascriptAsset
138
+	 * @throws DuplicateCollectionIdentifierException
139
+	 * @throws InvalidDataTypeException
140
+	 * @throws InvalidEntityException
141
+	 * @throws DomainException
142
+	 */
143
+	public function addJs($handle, $extra_dependencies = [])
144
+	{
145
+		$details = $this->getAssetDetails(
146
+			Asset::TYPE_JS,
147
+			$handle,
148
+			$extra_dependencies
149
+		);
150
+		return $this->addJavascript(
151
+			$handle,
152
+			$this->registry->getJsUrl($this->domain->assetNamespace(), $handle),
153
+			$details['dependencies'],
154
+			true,
155
+			$details['version']
156
+		);
157
+	}
158 158
 
159 159
 
160
-    /**
161
-     * @param string $handle
162
-     * @param array  $dependencies
163
-     * @param bool   $load_in_footer
164
-     * @param string $version
165
-     * @return JavascriptAsset
166
-     * @throws DomainException
167
-     * @throws DuplicateCollectionIdentifierException
168
-     * @throws InvalidDataTypeException
169
-     * @throws InvalidEntityException
170
-     * @since 4.9.71.p
171
-     */
172
-    public function addVendorJavascript(
173
-        $handle,
174
-        array $dependencies = array(),
175
-        $load_in_footer = true,
176
-        $version = ''
177
-    ) {
178
-        $dev_suffix = wp_scripts_get_suffix('dev');
179
-        $vendor_path = $this->domain->pluginUrl() . 'assets/vendor/';
180
-        return $this->addJavascript(
181
-            $handle,
182
-            "{$vendor_path}{$handle}{$dev_suffix}.js",
183
-            $dependencies,
184
-            $load_in_footer,
185
-            $version
186
-        );
187
-    }
160
+	/**
161
+	 * @param string $handle
162
+	 * @param array  $dependencies
163
+	 * @param bool   $load_in_footer
164
+	 * @param string $version
165
+	 * @return JavascriptAsset
166
+	 * @throws DomainException
167
+	 * @throws DuplicateCollectionIdentifierException
168
+	 * @throws InvalidDataTypeException
169
+	 * @throws InvalidEntityException
170
+	 * @since 4.9.71.p
171
+	 */
172
+	public function addVendorJavascript(
173
+		$handle,
174
+		array $dependencies = array(),
175
+		$load_in_footer = true,
176
+		$version = ''
177
+	) {
178
+		$dev_suffix = wp_scripts_get_suffix('dev');
179
+		$vendor_path = $this->domain->pluginUrl() . 'assets/vendor/';
180
+		return $this->addJavascript(
181
+			$handle,
182
+			"{$vendor_path}{$handle}{$dev_suffix}.js",
183
+			$dependencies,
184
+			$load_in_footer,
185
+			$version
186
+		);
187
+	}
188 188
 
189 189
 
190
-    /**
191
-     * @param string $handle
192
-     * @param string $source
193
-     * @param array  $dependencies
194
-     * @param string $media
195
-     * @param string $version
196
-     * @return StylesheetAsset
197
-     * @throws DomainException
198
-     * @throws DuplicateCollectionIdentifierException
199
-     * @throws InvalidDataTypeException
200
-     * @throws InvalidEntityException
201
-     * @since 4.9.62.p
202
-     */
203
-    public function addStylesheet(
204
-        $handle,
205
-        $source,
206
-        array $dependencies = array(),
207
-        $media = 'all',
208
-        $version = ''
209
-    ) {
210
-        $asset = new StylesheetAsset(
211
-            $handle,
212
-            $source,
213
-            array_unique($dependencies),
214
-            $this->domain,
215
-            $media,
216
-            $version
217
-        );
218
-        $this->assets->add($asset, $handle);
219
-        return $asset;
220
-    }
190
+	/**
191
+	 * @param string $handle
192
+	 * @param string $source
193
+	 * @param array  $dependencies
194
+	 * @param string $media
195
+	 * @param string $version
196
+	 * @return StylesheetAsset
197
+	 * @throws DomainException
198
+	 * @throws DuplicateCollectionIdentifierException
199
+	 * @throws InvalidDataTypeException
200
+	 * @throws InvalidEntityException
201
+	 * @since 4.9.62.p
202
+	 */
203
+	public function addStylesheet(
204
+		$handle,
205
+		$source,
206
+		array $dependencies = array(),
207
+		$media = 'all',
208
+		$version = ''
209
+	) {
210
+		$asset = new StylesheetAsset(
211
+			$handle,
212
+			$source,
213
+			array_unique($dependencies),
214
+			$this->domain,
215
+			$media,
216
+			$version
217
+		);
218
+		$this->assets->add($asset, $handle);
219
+		return $asset;
220
+	}
221 221
 
222 222
 
223
-    /**
224
-     * Used to register a css asset where everything is dynamically derived from the given handle.
225
-     *
226
-     * @param string       $handle
227
-     * @param string|array $extra_dependencies
228
-     * @return StylesheetAsset
229
-     * @throws DuplicateCollectionIdentifierException
230
-     * @throws InvalidDataTypeException
231
-     * @throws InvalidEntityException
232
-     * @throws DomainException
233
-     */
234
-    public function addCss($handle, $extra_dependencies = [])
235
-    {
236
-        $details = $this->getAssetDetails(
237
-            Asset::TYPE_CSS,
238
-            $handle,
239
-            $extra_dependencies
240
-        );
241
-        return $this->addStylesheet(
242
-            $handle,
243
-            $this->registry->getCssUrl($this->domain->assetNamespace(), $handle),
244
-            $details['dependencies'],
245
-            'all',
246
-            $details['version']
247
-        );
248
-    }
223
+	/**
224
+	 * Used to register a css asset where everything is dynamically derived from the given handle.
225
+	 *
226
+	 * @param string       $handle
227
+	 * @param string|array $extra_dependencies
228
+	 * @return StylesheetAsset
229
+	 * @throws DuplicateCollectionIdentifierException
230
+	 * @throws InvalidDataTypeException
231
+	 * @throws InvalidEntityException
232
+	 * @throws DomainException
233
+	 */
234
+	public function addCss($handle, $extra_dependencies = [])
235
+	{
236
+		$details = $this->getAssetDetails(
237
+			Asset::TYPE_CSS,
238
+			$handle,
239
+			$extra_dependencies
240
+		);
241
+		return $this->addStylesheet(
242
+			$handle,
243
+			$this->registry->getCssUrl($this->domain->assetNamespace(), $handle),
244
+			$details['dependencies'],
245
+			'all',
246
+			$details['version']
247
+		);
248
+	}
249 249
 
250 250
 
251
-    /**
252
-     * @param string $handle
253
-     * @return bool
254
-     * @since 4.9.62.p
255
-     */
256
-    public function enqueueAsset($handle)
257
-    {
258
-        if ($this->assets->has($handle)) {
259
-            $asset = $this->assets->get($handle);
260
-            if ($asset->isRegistered()) {
261
-                $asset->enqueueAsset();
262
-                return true;
263
-            }
264
-        }
265
-        return false;
266
-    }
251
+	/**
252
+	 * @param string $handle
253
+	 * @return bool
254
+	 * @since 4.9.62.p
255
+	 */
256
+	public function enqueueAsset($handle)
257
+	{
258
+		if ($this->assets->has($handle)) {
259
+			$asset = $this->assets->get($handle);
260
+			if ($asset->isRegistered()) {
261
+				$asset->enqueueAsset();
262
+				return true;
263
+			}
264
+		}
265
+		return false;
266
+	}
267 267
 
268 268
 
269
-    /**
270
-     * @param string $asset_type
271
-     * @param string $handle
272
-     * @param array  $extra_dependencies
273
-     * @return array
274
-     * @since 4.10.2.p
275
-     */
276
-    private function getAssetDetails($asset_type, $handle, $extra_dependencies = [])
277
-    {
278
-        $getAssetDetails = '';
279
-        switch ($asset_type) {
280
-            case Asset::TYPE_JS :
281
-                $getAssetDetails = 'getJsAssetDetails';
282
-                break;
283
-            case Asset::TYPE_CSS :
284
-                $getAssetDetails = 'getCssAssetDetails';
285
-                break;
286
-        }
287
-        if ($getAssetDetails === '') {
288
-            return ['dependencies' => [], 'version' => ''];
289
-        }
290
-        $details = $this->registry->$getAssetDetails(
291
-            $this->domain->assetNamespace(),
292
-            $handle
293
-        );
294
-        $details['dependencies'] = isset($details['dependencies'])
295
-            ? $details['dependencies']
296
-            : [];
297
-        $details['version'] = isset($details['version'])
298
-            ? $details['version']
299
-            : '';
300
-        $details['dependencies'] = ! empty($extra_dependencies)
301
-            ? array_merge($details['dependencies'], (array) $extra_dependencies)
302
-            : $details['dependencies'];
303
-        return $details;
269
+	/**
270
+	 * @param string $asset_type
271
+	 * @param string $handle
272
+	 * @param array  $extra_dependencies
273
+	 * @return array
274
+	 * @since 4.10.2.p
275
+	 */
276
+	private function getAssetDetails($asset_type, $handle, $extra_dependencies = [])
277
+	{
278
+		$getAssetDetails = '';
279
+		switch ($asset_type) {
280
+			case Asset::TYPE_JS :
281
+				$getAssetDetails = 'getJsAssetDetails';
282
+				break;
283
+			case Asset::TYPE_CSS :
284
+				$getAssetDetails = 'getCssAssetDetails';
285
+				break;
286
+		}
287
+		if ($getAssetDetails === '') {
288
+			return ['dependencies' => [], 'version' => ''];
289
+		}
290
+		$details = $this->registry->$getAssetDetails(
291
+			$this->domain->assetNamespace(),
292
+			$handle
293
+		);
294
+		$details['dependencies'] = isset($details['dependencies'])
295
+			? $details['dependencies']
296
+			: [];
297
+		$details['version'] = isset($details['version'])
298
+			? $details['version']
299
+			: '';
300
+		$details['dependencies'] = ! empty($extra_dependencies)
301
+			? array_merge($details['dependencies'], (array) $extra_dependencies)
302
+			: $details['dependencies'];
303
+		return $details;
304 304
 
305
-    }
305
+	}
306 306
 }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.3.rc.000');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.3.rc.000');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 1 patch
Indentation   +3690 added lines, -3690 removed lines patch added patch discarded remove patch
@@ -18,2227 +18,2227 @@  discard block
 block discarded – undo
18 18
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
19 19
 {
20 20
 
21
-    /**
22
-     * @var EE_Registration
23
-     */
24
-    private $_registration;
25
-
26
-    /**
27
-     * @var EE_Event
28
-     */
29
-    private $_reg_event;
30
-
31
-    /**
32
-     * @var EE_Session
33
-     */
34
-    private $_session;
35
-
36
-    private static $_reg_status;
37
-
38
-    /**
39
-     * Form for displaying the custom questions for this registration.
40
-     * This gets used a few times throughout the request so its best to cache it
41
-     *
42
-     * @var EE_Registration_Custom_Questions_Form
43
-     */
44
-    protected $_reg_custom_questions_form = null;
45
-
46
-    /**
47
-     * @var EEM_Registration $registration_model
48
-     */
49
-    private $registration_model;
50
-
51
-    /**
52
-     * @var EEM_Attendee $attendee_model
53
-     */
54
-    private $attendee_model;
55
-
56
-    /**
57
-     * @var EEM_Event $event_model
58
-     */
59
-    private $event_model;
60
-
61
-    /**
62
-     * @var EEM_Status $status_model
63
-     */
64
-    private $status_model;
65
-
66
-
67
-    /**
68
-     * @param bool $routing
69
-     * @throws EE_Error
70
-     * @throws InvalidArgumentException
71
-     * @throws InvalidDataTypeException
72
-     * @throws InvalidInterfaceException
73
-     * @throws ReflectionException
74
-     */
75
-    public function __construct($routing = true)
76
-    {
77
-        parent::__construct($routing);
78
-        add_action('wp_loaded', array($this, 'wp_loaded'));
79
-    }
80
-
81
-    /**
82
-     * @return EEM_Registration
83
-     * @throws InvalidArgumentException
84
-     * @throws InvalidDataTypeException
85
-     * @throws InvalidInterfaceException
86
-     * @since 4.10.2.p
87
-     */
88
-    protected function getRegistrationModel()
89
-    {
90
-        if (! $this->registration_model instanceof EEM_Registration) {
91
-            $this->registration_model = $this->getLoader()->getShared('EEM_Registration');
92
-        }
93
-        return $this->registration_model;
94
-    }
95
-
96
-    /**
97
-     * @return EEM_Attendee
98
-     * @throws InvalidArgumentException
99
-     * @throws InvalidDataTypeException
100
-     * @throws InvalidInterfaceException
101
-     * @since 4.10.2.p
102
-     */
103
-    protected function getAttendeeModel()
104
-    {
105
-        if (! $this->attendee_model instanceof EEM_Attendee) {
106
-            $this->attendee_model = $this->getLoader()->getShared('EEM_Attendee');
107
-        }
108
-        return $this->attendee_model;
109
-    }
110
-
111
-
112
-    /**
113
-     * @return EEM_Event
114
-     * @throws InvalidArgumentException
115
-     * @throws InvalidDataTypeException
116
-     * @throws InvalidInterfaceException
117
-     * @since 4.10.2.p
118
-     */
119
-    protected function getEventModel()
120
-    {
121
-        if (! $this->event_model instanceof EEM_Event) {
122
-            $this->event_model = $this->getLoader()->getShared('EEM_Event');
123
-        }
124
-        return $this->event_model;
125
-    }
126
-
127
-    /**
128
-     * @return EEM_Status
129
-     * @throws InvalidArgumentException
130
-     * @throws InvalidDataTypeException
131
-     * @throws InvalidInterfaceException
132
-     * @since 4.10.2.p
133
-     */
134
-    protected function getStatusModel()
135
-    {
136
-        if (! $this->status_model instanceof EEM_Status) {
137
-            $this->status_model = $this->getLoader()->getShared('EEM_Status');
138
-        }
139
-        return $this->status_model;
140
-    }
141
-
142
-
143
-    public function wp_loaded()
144
-    {
145
-        // when adding a new registration...
146
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
147
-            EE_System::do_not_cache();
148
-            if (! isset($this->_req_data['processing_registration'])
149
-                || absint($this->_req_data['processing_registration']) !== 1
150
-            ) {
151
-                // and it's NOT the attendee information reg step
152
-                // force cookie expiration by setting time to last week
153
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
154
-                // and update the global
155
-                $_COOKIE['ee_registration_added'] = 0;
156
-            }
157
-        }
158
-    }
159
-
160
-
161
-    protected function _init_page_props()
162
-    {
163
-        $this->page_slug = REG_PG_SLUG;
164
-        $this->_admin_base_url = REG_ADMIN_URL;
165
-        $this->_admin_base_path = REG_ADMIN;
166
-        $this->page_label = esc_html__('Registrations', 'event_espresso');
167
-        $this->_cpt_routes = array(
168
-            'add_new_attendee' => 'espresso_attendees',
169
-            'edit_attendee'    => 'espresso_attendees',
170
-            'insert_attendee'  => 'espresso_attendees',
171
-            'update_attendee'  => 'espresso_attendees',
172
-        );
173
-        $this->_cpt_model_names = array(
174
-            'add_new_attendee' => 'EEM_Attendee',
175
-            'edit_attendee'    => 'EEM_Attendee',
176
-        );
177
-        $this->_cpt_edit_routes = array(
178
-            'espresso_attendees' => 'edit_attendee',
179
-        );
180
-        $this->_pagenow_map = array(
181
-            'add_new_attendee' => 'post-new.php',
182
-            'edit_attendee'    => 'post.php',
183
-            'trash'            => 'post.php',
184
-        );
185
-        add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
186
-        // add filters so that the comment urls don't take users to a confusing 404 page
187
-        add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
188
-    }
189
-
190
-
191
-    public function clear_comment_link($link, $comment, $args)
192
-    {
193
-        // gotta make sure this only happens on this route
194
-        $post_type = get_post_type($comment->comment_post_ID);
195
-        if ($post_type === 'espresso_attendees') {
196
-            return '#commentsdiv';
197
-        }
198
-        return $link;
199
-    }
200
-
201
-
202
-    protected function _ajax_hooks()
203
-    {
204
-        // todo: all hooks for registrations ajax goes in here
205
-        add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
206
-    }
207
-
208
-
209
-    protected function _define_page_props()
210
-    {
211
-        $this->_admin_page_title = $this->page_label;
212
-        $this->_labels = array(
213
-            'buttons'                      => array(
214
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
215
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
216
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
217
-                'report'              => esc_html__('Event Registrations CSV Report', 'event_espresso'),
218
-                'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
219
-                'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
220
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
221
-                'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
222
-            ),
223
-            'publishbox'                   => array(
224
-                'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
225
-                'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
226
-            ),
227
-            'hide_add_button_on_cpt_route' => array(
228
-                'edit_attendee' => true,
229
-            ),
230
-        );
231
-    }
232
-
233
-
234
-    /**
235
-     *        grab url requests and route them
236
-     *
237
-     * @access private
238
-     * @return void
239
-     * @throws EE_Error
240
-     */
241
-    public function _set_page_routes()
242
-    {
243
-        $this->_get_registration_status_array();
244
-        $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
245
-            ? $this->_req_data['_REG_ID'] : 0;
246
-        $reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
247
-            ? $this->_req_data['reg_status_change_form']['REG_ID']
248
-            : $reg_id;
249
-        $att_id = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
250
-            ? $this->_req_data['ATT_ID'] : 0;
251
-        $att_id = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
252
-            ? $this->_req_data['post']
253
-            : $att_id;
254
-        $this->_page_routes = array(
255
-            'default'                             => array(
256
-                'func'       => '_registrations_overview_list_table',
257
-                'capability' => 'ee_read_registrations',
258
-            ),
259
-            'view_registration'                   => array(
260
-                'func'       => '_registration_details',
261
-                'capability' => 'ee_read_registration',
262
-                'obj_id'     => $reg_id,
263
-            ),
264
-            'edit_registration'                   => array(
265
-                'func'               => '_update_attendee_registration_form',
266
-                'noheader'           => true,
267
-                'headers_sent_route' => 'view_registration',
268
-                'capability'         => 'ee_edit_registration',
269
-                'obj_id'             => $reg_id,
270
-                '_REG_ID'            => $reg_id,
271
-            ),
272
-            'trash_registrations'                 => array(
273
-                'func'       => '_trash_or_restore_registrations',
274
-                'args'       => array('trash' => true),
275
-                'noheader'   => true,
276
-                'capability' => 'ee_delete_registrations',
277
-            ),
278
-            'restore_registrations'               => array(
279
-                'func'       => '_trash_or_restore_registrations',
280
-                'args'       => array('trash' => false),
281
-                'noheader'   => true,
282
-                'capability' => 'ee_delete_registrations',
283
-            ),
284
-            'delete_registrations'                => array(
285
-                'func'       => '_delete_registrations',
286
-                'noheader'   => true,
287
-                'capability' => 'ee_delete_registrations',
288
-            ),
289
-            'new_registration'                    => array(
290
-                'func'       => 'new_registration',
291
-                'capability' => 'ee_edit_registrations',
292
-            ),
293
-            'process_reg_step'                    => array(
294
-                'func'       => 'process_reg_step',
295
-                'noheader'   => true,
296
-                'capability' => 'ee_edit_registrations',
297
-            ),
298
-            'redirect_to_txn'                     => array(
299
-                'func'       => 'redirect_to_txn',
300
-                'noheader'   => true,
301
-                'capability' => 'ee_edit_registrations',
302
-            ),
303
-            'change_reg_status'                   => array(
304
-                'func'       => '_change_reg_status',
305
-                'noheader'   => true,
306
-                'capability' => 'ee_edit_registration',
307
-                'obj_id'     => $reg_id,
308
-            ),
309
-            'approve_registration'                => array(
310
-                'func'       => 'approve_registration',
311
-                'noheader'   => true,
312
-                'capability' => 'ee_edit_registration',
313
-                'obj_id'     => $reg_id,
314
-            ),
315
-            'approve_and_notify_registration'     => array(
316
-                'func'       => 'approve_registration',
317
-                'noheader'   => true,
318
-                'args'       => array(true),
319
-                'capability' => 'ee_edit_registration',
320
-                'obj_id'     => $reg_id,
321
-            ),
322
-            'approve_registrations'               => array(
323
-                'func'       => 'bulk_action_on_registrations',
324
-                'noheader'   => true,
325
-                'capability' => 'ee_edit_registrations',
326
-                'args'       => array('approve'),
327
-            ),
328
-            'approve_and_notify_registrations'    => array(
329
-                'func'       => 'bulk_action_on_registrations',
330
-                'noheader'   => true,
331
-                'capability' => 'ee_edit_registrations',
332
-                'args'       => array('approve', true),
333
-            ),
334
-            'decline_registration'                => array(
335
-                'func'       => 'decline_registration',
336
-                'noheader'   => true,
337
-                'capability' => 'ee_edit_registration',
338
-                'obj_id'     => $reg_id,
339
-            ),
340
-            'decline_and_notify_registration'     => array(
341
-                'func'       => 'decline_registration',
342
-                'noheader'   => true,
343
-                'args'       => array(true),
344
-                'capability' => 'ee_edit_registration',
345
-                'obj_id'     => $reg_id,
346
-            ),
347
-            'decline_registrations'               => array(
348
-                'func'       => 'bulk_action_on_registrations',
349
-                'noheader'   => true,
350
-                'capability' => 'ee_edit_registrations',
351
-                'args'       => array('decline'),
352
-            ),
353
-            'decline_and_notify_registrations'    => array(
354
-                'func'       => 'bulk_action_on_registrations',
355
-                'noheader'   => true,
356
-                'capability' => 'ee_edit_registrations',
357
-                'args'       => array('decline', true),
358
-            ),
359
-            'pending_registration'                => array(
360
-                'func'       => 'pending_registration',
361
-                'noheader'   => true,
362
-                'capability' => 'ee_edit_registration',
363
-                'obj_id'     => $reg_id,
364
-            ),
365
-            'pending_and_notify_registration'     => array(
366
-                'func'       => 'pending_registration',
367
-                'noheader'   => true,
368
-                'args'       => array(true),
369
-                'capability' => 'ee_edit_registration',
370
-                'obj_id'     => $reg_id,
371
-            ),
372
-            'pending_registrations'               => array(
373
-                'func'       => 'bulk_action_on_registrations',
374
-                'noheader'   => true,
375
-                'capability' => 'ee_edit_registrations',
376
-                'args'       => array('pending'),
377
-            ),
378
-            'pending_and_notify_registrations'    => array(
379
-                'func'       => 'bulk_action_on_registrations',
380
-                'noheader'   => true,
381
-                'capability' => 'ee_edit_registrations',
382
-                'args'       => array('pending', true),
383
-            ),
384
-            'no_approve_registration'             => array(
385
-                'func'       => 'not_approve_registration',
386
-                'noheader'   => true,
387
-                'capability' => 'ee_edit_registration',
388
-                'obj_id'     => $reg_id,
389
-            ),
390
-            'no_approve_and_notify_registration'  => array(
391
-                'func'       => 'not_approve_registration',
392
-                'noheader'   => true,
393
-                'args'       => array(true),
394
-                'capability' => 'ee_edit_registration',
395
-                'obj_id'     => $reg_id,
396
-            ),
397
-            'no_approve_registrations'            => array(
398
-                'func'       => 'bulk_action_on_registrations',
399
-                'noheader'   => true,
400
-                'capability' => 'ee_edit_registrations',
401
-                'args'       => array('not_approve'),
402
-            ),
403
-            'no_approve_and_notify_registrations' => array(
404
-                'func'       => 'bulk_action_on_registrations',
405
-                'noheader'   => true,
406
-                'capability' => 'ee_edit_registrations',
407
-                'args'       => array('not_approve', true),
408
-            ),
409
-            'cancel_registration'                 => array(
410
-                'func'       => 'cancel_registration',
411
-                'noheader'   => true,
412
-                'capability' => 'ee_edit_registration',
413
-                'obj_id'     => $reg_id,
414
-            ),
415
-            'cancel_and_notify_registration'      => array(
416
-                'func'       => 'cancel_registration',
417
-                'noheader'   => true,
418
-                'args'       => array(true),
419
-                'capability' => 'ee_edit_registration',
420
-                'obj_id'     => $reg_id,
421
-            ),
422
-            'cancel_registrations'                => array(
423
-                'func'       => 'bulk_action_on_registrations',
424
-                'noheader'   => true,
425
-                'capability' => 'ee_edit_registrations',
426
-                'args'       => array('cancel'),
427
-            ),
428
-            'cancel_and_notify_registrations'     => array(
429
-                'func'       => 'bulk_action_on_registrations',
430
-                'noheader'   => true,
431
-                'capability' => 'ee_edit_registrations',
432
-                'args'       => array('cancel', true),
433
-            ),
434
-            'wait_list_registration'              => array(
435
-                'func'       => 'wait_list_registration',
436
-                'noheader'   => true,
437
-                'capability' => 'ee_edit_registration',
438
-                'obj_id'     => $reg_id,
439
-            ),
440
-            'wait_list_and_notify_registration'   => array(
441
-                'func'       => 'wait_list_registration',
442
-                'noheader'   => true,
443
-                'args'       => array(true),
444
-                'capability' => 'ee_edit_registration',
445
-                'obj_id'     => $reg_id,
446
-            ),
447
-            'contact_list'                        => array(
448
-                'func'       => '_attendee_contact_list_table',
449
-                'capability' => 'ee_read_contacts',
450
-            ),
451
-            'add_new_attendee'                    => array(
452
-                'func' => '_create_new_cpt_item',
453
-                'args' => array(
454
-                    'new_attendee' => true,
455
-                    'capability'   => 'ee_edit_contacts',
456
-                ),
457
-            ),
458
-            'edit_attendee'                       => array(
459
-                'func'       => '_edit_cpt_item',
460
-                'capability' => 'ee_edit_contacts',
461
-                'obj_id'     => $att_id,
462
-            ),
463
-            'duplicate_attendee'                  => array(
464
-                'func'       => '_duplicate_attendee',
465
-                'noheader'   => true,
466
-                'capability' => 'ee_edit_contacts',
467
-                'obj_id'     => $att_id,
468
-            ),
469
-            'insert_attendee'                     => array(
470
-                'func'       => '_insert_or_update_attendee',
471
-                'args'       => array(
472
-                    'new_attendee' => true,
473
-                ),
474
-                'noheader'   => true,
475
-                'capability' => 'ee_edit_contacts',
476
-            ),
477
-            'update_attendee'                     => array(
478
-                'func'       => '_insert_or_update_attendee',
479
-                'args'       => array(
480
-                    'new_attendee' => false,
481
-                ),
482
-                'noheader'   => true,
483
-                'capability' => 'ee_edit_contacts',
484
-                'obj_id'     => $att_id,
485
-            ),
486
-            'trash_attendees'                     => array(
487
-                'func'       => '_trash_or_restore_attendees',
488
-                'args'       => array(
489
-                    'trash' => 'true',
490
-                ),
491
-                'noheader'   => true,
492
-                'capability' => 'ee_delete_contacts',
493
-            ),
494
-            'trash_attendee'                      => array(
495
-                'func'       => '_trash_or_restore_attendees',
496
-                'args'       => array(
497
-                    'trash' => true,
498
-                ),
499
-                'noheader'   => true,
500
-                'capability' => 'ee_delete_contacts',
501
-                'obj_id'     => $att_id,
502
-            ),
503
-            'restore_attendees'                   => array(
504
-                'func'       => '_trash_or_restore_attendees',
505
-                'args'       => array(
506
-                    'trash' => false,
507
-                ),
508
-                'noheader'   => true,
509
-                'capability' => 'ee_delete_contacts',
510
-                'obj_id'     => $att_id,
511
-            ),
512
-            'resend_registration'                 => array(
513
-                'func'       => '_resend_registration',
514
-                'noheader'   => true,
515
-                'capability' => 'ee_send_message',
516
-            ),
517
-            'registrations_report'                => array(
518
-                'func'       => '_registrations_report',
519
-                'noheader'   => true,
520
-                'capability' => 'ee_read_registrations',
521
-            ),
522
-            'contact_list_export'                 => array(
523
-                'func'       => '_contact_list_export',
524
-                'noheader'   => true,
525
-                'capability' => 'export',
526
-            ),
527
-            'contact_list_report'                 => array(
528
-                'func'       => '_contact_list_report',
529
-                'noheader'   => true,
530
-                'capability' => 'ee_read_contacts',
531
-            ),
532
-        );
533
-    }
534
-
535
-
536
-    protected function _set_page_config()
537
-    {
538
-        $this->_page_config = array(
539
-            'default'           => array(
540
-                'nav'           => array(
541
-                    'label' => esc_html__('Overview', 'event_espresso'),
542
-                    'order' => 5,
543
-                ),
544
-                'help_tabs'     => array(
545
-                    'registrations_overview_help_tab'                       => array(
546
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
547
-                        'filename' => 'registrations_overview',
548
-                    ),
549
-                    'registrations_overview_table_column_headings_help_tab' => array(
550
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
551
-                        'filename' => 'registrations_overview_table_column_headings',
552
-                    ),
553
-                    'registrations_overview_filters_help_tab'               => array(
554
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
555
-                        'filename' => 'registrations_overview_filters',
556
-                    ),
557
-                    'registrations_overview_views_help_tab'                 => array(
558
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
559
-                        'filename' => 'registrations_overview_views',
560
-                    ),
561
-                    'registrations_regoverview_other_help_tab'              => array(
562
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
563
-                        'filename' => 'registrations_overview_other',
564
-                    ),
565
-                ),
566
-                'help_tour'     => array('Registration_Overview_Help_Tour'),
567
-                'qtips'         => array('Registration_List_Table_Tips'),
568
-                'list_table'    => 'EE_Registrations_List_Table',
569
-                'require_nonce' => false,
570
-            ),
571
-            'view_registration' => array(
572
-                'nav'           => array(
573
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
574
-                    'order'      => 15,
575
-                    'url'        => isset($this->_req_data['_REG_ID'])
576
-                        ? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
577
-                        : $this->_admin_base_url,
578
-                    'persistent' => false,
579
-                ),
580
-                'help_tabs'     => array(
581
-                    'registrations_details_help_tab'                    => array(
582
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
583
-                        'filename' => 'registrations_details',
584
-                    ),
585
-                    'registrations_details_table_help_tab'              => array(
586
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
587
-                        'filename' => 'registrations_details_table',
588
-                    ),
589
-                    'registrations_details_form_answers_help_tab'       => array(
590
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
591
-                        'filename' => 'registrations_details_form_answers',
592
-                    ),
593
-                    'registrations_details_registrant_details_help_tab' => array(
594
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
595
-                        'filename' => 'registrations_details_registrant_details',
596
-                    ),
597
-                ),
598
-                'help_tour'     => array('Registration_Details_Help_Tour'),
599
-                'metaboxes'     => array_merge(
600
-                    $this->_default_espresso_metaboxes,
601
-                    array('_registration_details_metaboxes')
602
-                ),
603
-                'require_nonce' => false,
604
-            ),
605
-            'new_registration'  => array(
606
-                'nav'           => array(
607
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
608
-                    'url'        => '#',
609
-                    'order'      => 15,
610
-                    'persistent' => false,
611
-                ),
612
-                'metaboxes'     => $this->_default_espresso_metaboxes,
613
-                'labels'        => array(
614
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
615
-                ),
616
-                'require_nonce' => false,
617
-            ),
618
-            'add_new_attendee'  => array(
619
-                'nav'           => array(
620
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
621
-                    'order'      => 15,
622
-                    'persistent' => false,
623
-                ),
624
-                'metaboxes'     => array_merge(
625
-                    $this->_default_espresso_metaboxes,
626
-                    array('_publish_post_box', 'attendee_editor_metaboxes')
627
-                ),
628
-                'require_nonce' => false,
629
-            ),
630
-            'edit_attendee'     => array(
631
-                'nav'           => array(
632
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
633
-                    'order'      => 15,
634
-                    'persistent' => false,
635
-                    'url'        => isset($this->_req_data['ATT_ID'])
636
-                        ? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
637
-                        : $this->_admin_base_url,
638
-                ),
639
-                'metaboxes'     => array('attendee_editor_metaboxes'),
640
-                'require_nonce' => false,
641
-            ),
642
-            'contact_list'      => array(
643
-                'nav'           => array(
644
-                    'label' => esc_html__('Contact List', 'event_espresso'),
645
-                    'order' => 20,
646
-                ),
647
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
648
-                'help_tabs'     => array(
649
-                    'registrations_contact_list_help_tab'                       => array(
650
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
651
-                        'filename' => 'registrations_contact_list',
652
-                    ),
653
-                    'registrations_contact-list_table_column_headings_help_tab' => array(
654
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
655
-                        'filename' => 'registrations_contact_list_table_column_headings',
656
-                    ),
657
-                    'registrations_contact_list_views_help_tab'                 => array(
658
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
659
-                        'filename' => 'registrations_contact_list_views',
660
-                    ),
661
-                    'registrations_contact_list_other_help_tab'                 => array(
662
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
663
-                        'filename' => 'registrations_contact_list_other',
664
-                    ),
665
-                ),
666
-                'help_tour'     => array('Contact_List_Help_Tour'),
667
-                'metaboxes'     => array(),
668
-                'require_nonce' => false,
669
-            ),
670
-            // override default cpt routes
671
-            'create_new'        => '',
672
-            'edit'              => '',
673
-        );
674
-    }
675
-
676
-
677
-    /**
678
-     * The below methods aren't used by this class currently
679
-     */
680
-    protected function _add_screen_options()
681
-    {
682
-    }
683
-
684
-
685
-    protected function _add_feature_pointers()
686
-    {
687
-    }
688
-
689
-
690
-    public function admin_init()
691
-    {
692
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
693
-            'click "Update Registration Questions" to save your changes',
694
-            'event_espresso'
695
-        );
696
-    }
697
-
698
-
699
-    public function admin_notices()
700
-    {
701
-    }
702
-
703
-
704
-    public function admin_footer_scripts()
705
-    {
706
-    }
707
-
708
-
709
-    /**
710
-     *        get list of registration statuses
711
-     *
712
-     * @access private
713
-     * @return void
714
-     * @throws EE_Error
715
-     */
716
-    private function _get_registration_status_array()
717
-    {
718
-        self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
719
-    }
720
-
721
-
722
-    /**
723
-     * @throws InvalidArgumentException
724
-     * @throws InvalidDataTypeException
725
-     * @throws InvalidInterfaceException
726
-     * @since 4.10.2.p
727
-     */
728
-    protected function _add_screen_options_default()
729
-    {
730
-        $this->_per_page_screen_option();
731
-    }
732
-
733
-
734
-    /**
735
-     * @throws InvalidArgumentException
736
-     * @throws InvalidDataTypeException
737
-     * @throws InvalidInterfaceException
738
-     * @since 4.10.2.p
739
-     */
740
-    protected function _add_screen_options_contact_list()
741
-    {
742
-        $page_title = $this->_admin_page_title;
743
-        $this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
744
-        $this->_per_page_screen_option();
745
-        $this->_admin_page_title = $page_title;
746
-    }
747
-
748
-
749
-    public function load_scripts_styles()
750
-    {
751
-        // style
752
-        wp_register_style(
753
-            'espresso_reg',
754
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
755
-            array('ee-admin-css'),
756
-            EVENT_ESPRESSO_VERSION
757
-        );
758
-        wp_enqueue_style('espresso_reg');
759
-        // script
760
-        wp_register_script(
761
-            'espresso_reg',
762
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
763
-            array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
764
-            EVENT_ESPRESSO_VERSION,
765
-            true
766
-        );
767
-        wp_enqueue_script('espresso_reg');
768
-    }
769
-
770
-
771
-    /**
772
-     * @throws EE_Error
773
-     * @throws InvalidArgumentException
774
-     * @throws InvalidDataTypeException
775
-     * @throws InvalidInterfaceException
776
-     * @throws ReflectionException
777
-     * @since 4.10.2.p
778
-     */
779
-    public function load_scripts_styles_edit_attendee()
780
-    {
781
-        // stuff to only show up on our attendee edit details page.
782
-        $attendee_details_translations = array(
783
-            'att_publish_text' => sprintf(
784
-                /* translators: The date and time */
785
-                wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
786
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
787
-            ),
788
-        );
789
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
790
-        wp_enqueue_script('jquery-validate');
791
-    }
792
-
793
-
794
-    /**
795
-     * @throws EE_Error
796
-     * @throws InvalidArgumentException
797
-     * @throws InvalidDataTypeException
798
-     * @throws InvalidInterfaceException
799
-     * @throws ReflectionException
800
-     * @since 4.10.2.p
801
-     */
802
-    public function load_scripts_styles_view_registration()
803
-    {
804
-        // styles
805
-        wp_enqueue_style('espresso-ui-theme');
806
-        // scripts
807
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
808
-        $this->_reg_custom_questions_form->wp_enqueue_scripts(true);
809
-    }
810
-
811
-
812
-    public function load_scripts_styles_contact_list()
813
-    {
814
-        wp_dequeue_style('espresso_reg');
815
-        wp_register_style(
816
-            'espresso_att',
817
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
818
-            array('ee-admin-css'),
819
-            EVENT_ESPRESSO_VERSION
820
-        );
821
-        wp_enqueue_style('espresso_att');
822
-    }
823
-
824
-
825
-    public function load_scripts_styles_new_registration()
826
-    {
827
-        wp_register_script(
828
-            'ee-spco-for-admin',
829
-            REG_ASSETS_URL . 'spco_for_admin.js',
830
-            array('underscore', 'jquery'),
831
-            EVENT_ESPRESSO_VERSION,
832
-            true
833
-        );
834
-        wp_enqueue_script('ee-spco-for-admin');
835
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
836
-        EE_Form_Section_Proper::wp_enqueue_scripts();
837
-        EED_Ticket_Selector::load_tckt_slctr_assets();
838
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
839
-    }
840
-
841
-
842
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
843
-    {
844
-        add_filter('FHEE_load_EE_messages', '__return_true');
845
-    }
846
-
847
-
848
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
849
-    {
850
-        add_filter('FHEE_load_EE_messages', '__return_true');
851
-    }
852
-
853
-
854
-    /**
855
-     * @throws EE_Error
856
-     * @throws InvalidArgumentException
857
-     * @throws InvalidDataTypeException
858
-     * @throws InvalidInterfaceException
859
-     * @throws ReflectionException
860
-     * @since 4.10.2.p
861
-     */
862
-    protected function _set_list_table_views_default()
863
-    {
864
-        // for notification related bulk actions we need to make sure only active messengers have an option.
865
-        EED_Messages::set_autoloaders();
866
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
867
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
868
-        $active_mts = $message_resource_manager->list_of_active_message_types();
869
-        // key= bulk_action_slug, value= message type.
870
-        $match_array = array(
871
-            'approve_registrations'    => 'registration',
872
-            'decline_registrations'    => 'declined_registration',
873
-            'pending_registrations'    => 'pending_approval',
874
-            'no_approve_registrations' => 'not_approved_registration',
875
-            'cancel_registrations'     => 'cancelled_registration',
876
-        );
877
-        $can_send = EE_Registry::instance()->CAP->current_user_can(
878
-            'ee_send_message',
879
-            'batch_send_messages'
880
-        );
881
-        /** setup reg status bulk actions **/
882
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
883
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
884
-            $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
885
-                'Approve and Notify Registrations',
886
-                'event_espresso'
887
-            );
888
-        }
889
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
890
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
891
-            $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
892
-                'Decline and Notify Registrations',
893
-                'event_espresso'
894
-            );
895
-        }
896
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
897
-            'Set Registrations to Pending Payment',
898
-            'event_espresso'
899
-        );
900
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
901
-            $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
902
-                'Set Registrations to Pending Payment and Notify',
903
-                'event_espresso'
904
-            );
905
-        }
906
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
907
-            'Set Registrations to Not Approved',
908
-            'event_espresso'
909
-        );
910
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
911
-            $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
912
-                'Set Registrations to Not Approved and Notify',
913
-                'event_espresso'
914
-            );
915
-        }
916
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
917
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
918
-            $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
919
-                'Cancel Registrations and Notify',
920
-                'event_espresso'
921
-            );
922
-        }
923
-        $def_reg_status_actions = apply_filters(
924
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
925
-            $def_reg_status_actions,
926
-            $active_mts,
927
-            $can_send
928
-        );
929
-
930
-        $this->_views = array(
931
-            'all'   => array(
932
-                'slug'        => 'all',
933
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
934
-                'count'       => 0,
935
-                'bulk_action' => array_merge(
936
-                    $def_reg_status_actions,
937
-                    array(
938
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
939
-                    )
940
-                ),
941
-            ),
942
-            'month' => array(
943
-                'slug'        => 'month',
944
-                'label'       => esc_html__('This Month', 'event_espresso'),
945
-                'count'       => 0,
946
-                'bulk_action' => array_merge(
947
-                    $def_reg_status_actions,
948
-                    array(
949
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
950
-                    )
951
-                ),
952
-            ),
953
-            'today' => array(
954
-                'slug'        => 'today',
955
-                'label'       => sprintf(
956
-                    esc_html__('Today - %s', 'event_espresso'),
957
-                    date('M d, Y', current_time('timestamp'))
958
-                ),
959
-                'count'       => 0,
960
-                'bulk_action' => array_merge(
961
-                    $def_reg_status_actions,
962
-                    array(
963
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
964
-                    )
965
-                ),
966
-            ),
967
-        );
968
-        if (EE_Registry::instance()->CAP->current_user_can(
969
-            'ee_delete_registrations',
970
-            'espresso_registrations_delete_registration'
971
-        )) {
972
-            $this->_views['incomplete'] = array(
973
-                'slug'        => 'incomplete',
974
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
975
-                'count'       => 0,
976
-                'bulk_action' => array(
977
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
978
-                ),
979
-            );
980
-            $this->_views['trash'] = array(
981
-                'slug'        => 'trash',
982
-                'label'       => esc_html__('Trash', 'event_espresso'),
983
-                'count'       => 0,
984
-                'bulk_action' => array(
985
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
986
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
987
-                ),
988
-            );
989
-        }
990
-    }
991
-
992
-
993
-    protected function _set_list_table_views_contact_list()
994
-    {
995
-        $this->_views = array(
996
-            'in_use' => array(
997
-                'slug'        => 'in_use',
998
-                'label'       => esc_html__('In Use', 'event_espresso'),
999
-                'count'       => 0,
1000
-                'bulk_action' => array(
1001
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1002
-                ),
1003
-            ),
1004
-        );
1005
-        if (EE_Registry::instance()->CAP->current_user_can(
1006
-            'ee_delete_contacts',
1007
-            'espresso_registrations_trash_attendees'
1008
-        )
1009
-        ) {
1010
-            $this->_views['trash'] = array(
1011
-                'slug'        => 'trash',
1012
-                'label'       => esc_html__('Trash', 'event_espresso'),
1013
-                'count'       => 0,
1014
-                'bulk_action' => array(
1015
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1016
-                ),
1017
-            );
1018
-        }
1019
-    }
1020
-
1021
-
1022
-    protected function _registration_legend_items()
1023
-    {
1024
-        $fc_items = array(
1025
-            'star-icon'        => array(
1026
-                'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
1027
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1028
-            ),
1029
-            'view_details'     => array(
1030
-                'class' => 'dashicons dashicons-clipboard',
1031
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1032
-            ),
1033
-            'edit_attendee'    => array(
1034
-                'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
1035
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1036
-            ),
1037
-            'view_transaction' => array(
1038
-                'class' => 'dashicons dashicons-cart',
1039
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1040
-            ),
1041
-            'view_invoice'     => array(
1042
-                'class' => 'dashicons dashicons-media-spreadsheet',
1043
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1044
-            ),
1045
-        );
1046
-        if (EE_Registry::instance()->CAP->current_user_can(
1047
-            'ee_send_message',
1048
-            'espresso_registrations_resend_registration'
1049
-        )) {
1050
-            $fc_items['resend_registration'] = array(
1051
-                'class' => 'dashicons dashicons-email-alt',
1052
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1053
-            );
1054
-        } else {
1055
-            $fc_items['blank'] = array('class' => 'blank', 'desc' => '');
1056
-        }
1057
-        if (EE_Registry::instance()->CAP->current_user_can(
1058
-            'ee_read_global_messages',
1059
-            'view_filtered_messages'
1060
-        )) {
1061
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1062
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1063
-                $fc_items['view_related_messages'] = array(
1064
-                    'class' => $related_for_icon['css_class'],
1065
-                    'desc'  => $related_for_icon['label'],
1066
-                );
1067
-            }
1068
-        }
1069
-        $sc_items = array(
1070
-            'approved_status'   => array(
1071
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
1072
-                'desc'  => EEH_Template::pretty_status(
1073
-                    EEM_Registration::status_id_approved,
1074
-                    false,
1075
-                    'sentence'
1076
-                ),
1077
-            ),
1078
-            'pending_status'    => array(
1079
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
1080
-                'desc'  => EEH_Template::pretty_status(
1081
-                    EEM_Registration::status_id_pending_payment,
1082
-                    false,
1083
-                    'sentence'
1084
-                ),
1085
-            ),
1086
-            'wait_list'         => array(
1087
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
1088
-                'desc'  => EEH_Template::pretty_status(
1089
-                    EEM_Registration::status_id_wait_list,
1090
-                    false,
1091
-                    'sentence'
1092
-                ),
1093
-            ),
1094
-            'incomplete_status' => array(
1095
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
1096
-                'desc'  => EEH_Template::pretty_status(
1097
-                    EEM_Registration::status_id_incomplete,
1098
-                    false,
1099
-                    'sentence'
1100
-                ),
1101
-            ),
1102
-            'not_approved'      => array(
1103
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
1104
-                'desc'  => EEH_Template::pretty_status(
1105
-                    EEM_Registration::status_id_not_approved,
1106
-                    false,
1107
-                    'sentence'
1108
-                ),
1109
-            ),
1110
-            'declined_status'   => array(
1111
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
1112
-                'desc'  => EEH_Template::pretty_status(
1113
-                    EEM_Registration::status_id_declined,
1114
-                    false,
1115
-                    'sentence'
1116
-                ),
1117
-            ),
1118
-            'cancelled_status'  => array(
1119
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1120
-                'desc'  => EEH_Template::pretty_status(
1121
-                    EEM_Registration::status_id_cancelled,
1122
-                    false,
1123
-                    'sentence'
1124
-                ),
1125
-            ),
1126
-        );
1127
-        return array_merge($fc_items, $sc_items);
1128
-    }
1129
-
1130
-
1131
-
1132
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1133
-
1134
-
1135
-
1136
-    /**
1137
-     * @throws DomainException
1138
-     * @throws EE_Error
1139
-     * @throws InvalidArgumentException
1140
-     * @throws InvalidDataTypeException
1141
-     * @throws InvalidInterfaceException
1142
-     * @throws ReflectionException
1143
-     */
1144
-    protected function _registrations_overview_list_table()
1145
-    {
1146
-        $this->appendAddNewRegistrationButtonToPageTitle();
1147
-        $header_text = '';
1148
-        $admin_page_header_decorators = [
1149
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1150
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1151
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1152
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1153
-        ];
1154
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1155
-            $filter_header_decorator = $this->getLoader()->getNew($admin_page_header_decorator);
1156
-            $header_text = $filter_header_decorator->getHeaderText($header_text);
1157
-        }
1158
-        $this->_template_args['admin_page_header'] = $header_text;
1159
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1160
-        $this->display_admin_list_table_page_with_no_sidebar();
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     * @throws EE_Error
1166
-     * @throws InvalidArgumentException
1167
-     * @throws InvalidDataTypeException
1168
-     * @throws InvalidInterfaceException
1169
-     */
1170
-    private function appendAddNewRegistrationButtonToPageTitle()
1171
-    {
1172
-        $EVT_ID = ! empty($this->_req_data['event_id'])
1173
-            ? absint($this->_req_data['event_id'])
1174
-            : 0;
1175
-        if ($EVT_ID
1176
-            && EE_Registry::instance()->CAP->current_user_can(
1177
-                'ee_edit_registrations',
1178
-                'espresso_registrations_new_registration',
1179
-                $EVT_ID
1180
-            )
1181
-        ) {
1182
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1183
-                'new_registration',
1184
-                'add-registrant',
1185
-                array('event_id' => $EVT_ID),
1186
-                'add-new-h2'
1187
-            );
1188
-        }
1189
-    }
1190
-
1191
-
1192
-    /**
1193
-     * This sets the _registration property for the registration details screen
1194
-     *
1195
-     * @access private
1196
-     * @return bool
1197
-     * @throws EE_Error
1198
-     * @throws InvalidArgumentException
1199
-     * @throws InvalidDataTypeException
1200
-     * @throws InvalidInterfaceException
1201
-     */
1202
-    private function _set_registration_object()
1203
-    {
1204
-        // get out if we've already set the object
1205
-        if ($this->_registration instanceof EE_Registration) {
1206
-            return true;
1207
-        }
1208
-        $REG_ID = (! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1209
-        if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1210
-            return true;
1211
-        }
1212
-        $error_msg = sprintf(
1213
-            esc_html__(
1214
-                'An error occurred and the details for Registration ID #%s could not be retrieved.',
1215
-                'event_espresso'
1216
-            ),
1217
-            $REG_ID
1218
-        );
1219
-        EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1220
-        $this->_registration = null;
1221
-        return false;
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     * Used to retrieve registrations for the list table.
1227
-     *
1228
-     * @param int  $per_page
1229
-     * @param bool $count
1230
-     * @param bool $this_month
1231
-     * @param bool $today
1232
-     * @return EE_Registration[]|int
1233
-     * @throws EE_Error
1234
-     * @throws InvalidArgumentException
1235
-     * @throws InvalidDataTypeException
1236
-     * @throws InvalidInterfaceException
1237
-     */
1238
-    public function get_registrations(
1239
-        $per_page = 10,
1240
-        $count = false,
1241
-        $this_month = false,
1242
-        $today = false
1243
-    ) {
1244
-        if ($this_month) {
1245
-            $this->_req_data['status'] = 'month';
1246
-        }
1247
-        if ($today) {
1248
-            $this->_req_data['status'] = 'today';
1249
-        }
1250
-        $query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1251
-        /**
1252
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1253
-         *
1254
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1255
-         * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1256
-         *                             or if you have the development copy of EE you can view this at the path:
1257
-         *                             /docs/G--Model-System/model-query-params.md
1258
-         */
1259
-        $query_params['group_by'] = '';
1260
-
1261
-        return $count
1262
-            ? $this->getRegistrationModel()->count($query_params)
1263
-            /** @type EE_Registration[] */
1264
-            : $this->getRegistrationModel()->get_all($query_params);
1265
-    }
1266
-
1267
-
1268
-    /**
1269
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1270
-     * Note: this listens to values on the request for some of the query parameters.
1271
-     *
1272
-     * @param array $request
1273
-     * @param int   $per_page
1274
-     * @param bool  $count
1275
-     * @return array
1276
-     * @throws EE_Error
1277
-     * @throws InvalidArgumentException
1278
-     * @throws InvalidDataTypeException
1279
-     * @throws InvalidInterfaceException
1280
-     */
1281
-    protected function _get_registration_query_parameters(
1282
-        $request = array(),
1283
-        $per_page = 10,
1284
-        $count = false
1285
-    ) {
1286
-        /** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1287
-        $list_table_query_builder = $this->getLoader()->getNew(
1288
-            'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1289
-            [ $request ]
1290
-        );
1291
-        return $list_table_query_builder->getQueryParams($per_page, $count);
1292
-    }
1293
-
1294
-
1295
-    public function get_registration_status_array()
1296
-    {
1297
-        return self::$_reg_status;
1298
-    }
1299
-
1300
-
1301
-
1302
-
1303
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1304
-    /**
1305
-     *        generates HTML for the View Registration Details Admin page
1306
-     *
1307
-     * @access protected
1308
-     * @return void
1309
-     * @throws DomainException
1310
-     * @throws EE_Error
1311
-     * @throws InvalidArgumentException
1312
-     * @throws InvalidDataTypeException
1313
-     * @throws InvalidInterfaceException
1314
-     * @throws EntityNotFoundException
1315
-     * @throws ReflectionException
1316
-     */
1317
-    protected function _registration_details()
1318
-    {
1319
-        $this->_template_args = array();
1320
-        $this->_set_registration_object();
1321
-        if (is_object($this->_registration)) {
1322
-            $transaction = $this->_registration->transaction()
1323
-                ? $this->_registration->transaction()
1324
-                : EE_Transaction::new_instance();
1325
-            $this->_session = $transaction->session_data();
1326
-            $event_id = $this->_registration->event_ID();
1327
-            $this->_template_args['reg_nmbr']['value'] = $this->_registration->ID();
1328
-            $this->_template_args['reg_nmbr']['label'] = esc_html__('Registration Number', 'event_espresso');
1329
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1330
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1331
-            $this->_template_args['grand_total'] = $transaction->total();
1332
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
1333
-            // link back to overview
1334
-            $this->_template_args['reg_overview_url'] = REG_ADMIN_URL;
1335
-            $this->_template_args['registration'] = $this->_registration;
1336
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1337
-                array(
1338
-                    'action'   => 'default',
1339
-                    'event_id' => $event_id,
1340
-                ),
1341
-                REG_ADMIN_URL
1342
-            );
1343
-            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1344
-                array(
1345
-                    'action' => 'default',
1346
-                    'EVT_ID' => $event_id,
1347
-                    'page'   => 'espresso_transactions',
1348
-                ),
1349
-                admin_url('admin.php')
1350
-            );
1351
-            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1352
-                array(
1353
-                    'page'   => 'espresso_events',
1354
-                    'action' => 'edit',
1355
-                    'post'   => $event_id,
1356
-                ),
1357
-                admin_url('admin.php')
1358
-            );
1359
-            // next and previous links
1360
-            $next_reg = $this->_registration->next(
1361
-                null,
1362
-                array(),
1363
-                'REG_ID'
1364
-            );
1365
-            $this->_template_args['next_registration'] = $next_reg
1366
-                ? $this->_next_link(
1367
-                    EE_Admin_Page::add_query_args_and_nonce(
1368
-                        array(
1369
-                            'action'  => 'view_registration',
1370
-                            '_REG_ID' => $next_reg['REG_ID'],
1371
-                        ),
1372
-                        REG_ADMIN_URL
1373
-                    ),
1374
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1375
-                )
1376
-                : '';
1377
-            $previous_reg = $this->_registration->previous(
1378
-                null,
1379
-                array(),
1380
-                'REG_ID'
1381
-            );
1382
-            $this->_template_args['previous_registration'] = $previous_reg
1383
-                ? $this->_previous_link(
1384
-                    EE_Admin_Page::add_query_args_and_nonce(
1385
-                        array(
1386
-                            'action'  => 'view_registration',
1387
-                            '_REG_ID' => $previous_reg['REG_ID'],
1388
-                        ),
1389
-                        REG_ADMIN_URL
1390
-                    ),
1391
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1392
-                )
1393
-                : '';
1394
-            // grab header
1395
-            $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1396
-            $this->_template_args['REG_ID'] = $this->_registration->ID();
1397
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1398
-                $template_path,
1399
-                $this->_template_args,
1400
-                true
1401
-            );
1402
-        } else {
1403
-            $this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1404
-        }
1405
-        // the details template wrapper
1406
-        $this->display_admin_page_with_sidebar();
1407
-    }
1408
-
1409
-
1410
-    /**
1411
-     * @throws EE_Error
1412
-     * @throws InvalidArgumentException
1413
-     * @throws InvalidDataTypeException
1414
-     * @throws InvalidInterfaceException
1415
-     * @throws ReflectionException
1416
-     * @since 4.10.2.p
1417
-     */
1418
-    protected function _registration_details_metaboxes()
1419
-    {
1420
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1421
-        $this->_set_registration_object();
1422
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1423
-        add_meta_box(
1424
-            'edit-reg-status-mbox',
1425
-            esc_html__('Registration Status', 'event_espresso'),
1426
-            array($this, 'set_reg_status_buttons_metabox'),
1427
-            $this->wp_page_slug,
1428
-            'normal',
1429
-            'high'
1430
-        );
1431
-        add_meta_box(
1432
-            'edit-reg-details-mbox',
1433
-            esc_html__('Registration Details', 'event_espresso'),
1434
-            array($this, '_reg_details_meta_box'),
1435
-            $this->wp_page_slug,
1436
-            'normal',
1437
-            'high'
1438
-        );
1439
-        if ($attendee instanceof EE_Attendee
1440
-            && EE_Registry::instance()->CAP->current_user_can(
1441
-                'ee_read_registration',
1442
-                'edit-reg-questions-mbox',
1443
-                $this->_registration->ID()
1444
-            )
1445
-        ) {
1446
-            add_meta_box(
1447
-                'edit-reg-questions-mbox',
1448
-                esc_html__('Registration Form Answers', 'event_espresso'),
1449
-                array($this, '_reg_questions_meta_box'),
1450
-                $this->wp_page_slug,
1451
-                'normal',
1452
-                'high'
1453
-            );
1454
-        }
1455
-        add_meta_box(
1456
-            'edit-reg-registrant-mbox',
1457
-            esc_html__('Contact Details', 'event_espresso'),
1458
-            array($this, '_reg_registrant_side_meta_box'),
1459
-            $this->wp_page_slug,
1460
-            'side',
1461
-            'high'
1462
-        );
1463
-        if ($this->_registration->group_size() > 1) {
1464
-            add_meta_box(
1465
-                'edit-reg-attendees-mbox',
1466
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1467
-                array($this, '_reg_attendees_meta_box'),
1468
-                $this->wp_page_slug,
1469
-                'normal',
1470
-                'high'
1471
-            );
1472
-        }
1473
-    }
1474
-
1475
-
1476
-    /**
1477
-     * set_reg_status_buttons_metabox
1478
-     *
1479
-     * @access protected
1480
-     * @return string
1481
-     * @throws EE_Error
1482
-     * @throws EntityNotFoundException
1483
-     * @throws InvalidArgumentException
1484
-     * @throws InvalidDataTypeException
1485
-     * @throws InvalidInterfaceException
1486
-     * @throws ReflectionException
1487
-     */
1488
-    public function set_reg_status_buttons_metabox()
1489
-    {
1490
-        $this->_set_registration_object();
1491
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1492
-        echo $change_reg_status_form->form_open(
1493
-            self::add_query_args_and_nonce(
1494
-                array(
1495
-                    'action' => 'change_reg_status',
1496
-                ),
1497
-                REG_ADMIN_URL
1498
-            )
1499
-        );
1500
-        echo $change_reg_status_form->get_html();
1501
-        echo $change_reg_status_form->form_close();
1502
-    }
1503
-
1504
-
1505
-    /**
1506
-     * @return EE_Form_Section_Proper
1507
-     * @throws EE_Error
1508
-     * @throws InvalidArgumentException
1509
-     * @throws InvalidDataTypeException
1510
-     * @throws InvalidInterfaceException
1511
-     * @throws EntityNotFoundException
1512
-     * @throws ReflectionException
1513
-     */
1514
-    protected function _generate_reg_status_change_form()
1515
-    {
1516
-        $reg_status_change_form_array = array(
1517
-            'name'            => 'reg_status_change_form',
1518
-            'html_id'         => 'reg-status-change-form',
1519
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1520
-            'subsections'     => array(
1521
-                'return'             => new EE_Hidden_Input(
1522
-                    array(
1523
-                        'name'    => 'return',
1524
-                        'default' => 'view_registration',
1525
-                    )
1526
-                ),
1527
-                'REG_ID'             => new EE_Hidden_Input(
1528
-                    array(
1529
-                        'name'    => 'REG_ID',
1530
-                        'default' => $this->_registration->ID(),
1531
-                    )
1532
-                ),
1533
-                'current_status'     => new EE_Form_Section_HTML(
1534
-                    EEH_HTML::table(
1535
-                        EEH_HTML::tr(
1536
-                            EEH_HTML::th(
1537
-                                EEH_HTML::label(
1538
-                                    EEH_HTML::strong(
1539
-                                        esc_html__('Current Registration Status', 'event_espresso')
1540
-                                    )
1541
-                                )
1542
-                            )
1543
-                            . EEH_HTML::td(
1544
-                                EEH_HTML::strong(
1545
-                                    $this->_registration->pretty_status(),
1546
-                                    '',
1547
-                                    'status-' . $this->_registration->status_ID(),
1548
-                                    'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1549
-                                )
1550
-                            )
1551
-                        )
1552
-                    )
1553
-                )
1554
-            )
1555
-        );
1556
-        if (EE_Registry::instance()->CAP->current_user_can(
1557
-            'ee_edit_registration',
1558
-            'toggle_registration_status',
1559
-            $this->_registration->ID()
1560
-        )) {
1561
-            $reg_status_change_form_array['subsections']['reg_status'] = new EE_Select_Input(
1562
-                $this->_get_reg_statuses(),
1563
-                array(
1564
-                    'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1565
-                    'default'         => $this->_registration->status_ID(),
1566
-                )
1567
-            );
1568
-            $reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1569
-                array(
1570
-                    'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1571
-                    'default'         => false,
1572
-                    'html_help_text'  => esc_html__(
1573
-                        'If set to "Yes", then the related messages will be sent to the registrant.',
1574
-                        'event_espresso'
1575
-                    )
1576
-                )
1577
-            );
1578
-            $reg_status_change_form_array['subsections']['submit'] = new EE_Submit_Input(
1579
-                array(
1580
-                    'html_class'      => 'button-primary',
1581
-                    'html_label_text' => '&nbsp;',
1582
-                    'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1583
-                )
1584
-            );
1585
-        }
1586
-        return new EE_Form_Section_Proper($reg_status_change_form_array);
1587
-    }
1588
-
1589
-
1590
-    /**
1591
-     * Returns an array of all the buttons for the various statuses and switch status actions
1592
-     *
1593
-     * @return array
1594
-     * @throws EE_Error
1595
-     * @throws InvalidArgumentException
1596
-     * @throws InvalidDataTypeException
1597
-     * @throws InvalidInterfaceException
1598
-     * @throws EntityNotFoundException
1599
-     */
1600
-    protected function _get_reg_statuses()
1601
-    {
1602
-        $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1603
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1604
-        // get current reg status
1605
-        $current_status = $this->_registration->status_ID();
1606
-        // is registration for free event? This will determine whether to display the pending payment option
1607
-        if ($current_status !== EEM_Registration::status_id_pending_payment
1608
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1609
-        ) {
1610
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1611
-        }
1612
-        return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1613
-    }
1614
-
1615
-
1616
-    /**
1617
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1618
-     *
1619
-     * @param bool $status REG status given for changing registrations to.
1620
-     * @param bool $notify Whether to send messages notifications or not.
1621
-     * @return array (array with reg_id(s) updated and whether update was successful.
1622
-     * @throws DomainException
1623
-     * @throws EE_Error
1624
-     * @throws EntityNotFoundException
1625
-     * @throws InvalidArgumentException
1626
-     * @throws InvalidDataTypeException
1627
-     * @throws InvalidInterfaceException
1628
-     * @throws ReflectionException
1629
-     * @throws RuntimeException
1630
-     */
1631
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1632
-    {
1633
-        if (isset($this->_req_data['reg_status_change_form'])) {
1634
-            $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1635
-                ? (array) $this->_req_data['reg_status_change_form']['REG_ID']
1636
-                : array();
1637
-        } else {
1638
-            $REG_IDs = isset($this->_req_data['_REG_ID'])
1639
-                ? (array) $this->_req_data['_REG_ID']
1640
-                : array();
1641
-        }
1642
-        // sanitize $REG_IDs
1643
-        $REG_IDs = array_map('absint', $REG_IDs);
1644
-        // and remove empty entries
1645
-        $REG_IDs = array_filter($REG_IDs);
1646
-
1647
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1648
-
1649
-        /**
1650
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1651
-         * Currently this value is used downstream by the _process_resend_registration method.
1652
-         *
1653
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1654
-         * @param bool                     $status           The status registrations were changed to.
1655
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1656
-         * @param Registrations_Admin_Page $admin_page_object
1657
-         */
1658
-        $this->_req_data['_REG_ID'] = apply_filters(
1659
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1660
-            $result['REG_ID'],
1661
-            $status,
1662
-            $result['success'],
1663
-            $this
1664
-        );
1665
-
1666
-        // notify?
1667
-        if ($notify
1668
-            && $result['success']
1669
-            && ! empty($this->_req_data['_REG_ID'])
1670
-            && EE_Registry::instance()->CAP->current_user_can(
1671
-                'ee_send_message',
1672
-                'espresso_registrations_resend_registration'
1673
-            )
1674
-        ) {
1675
-            $this->_process_resend_registration();
1676
-        }
1677
-        return $result;
1678
-    }
1679
-
1680
-
1681
-    /**
1682
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1683
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1684
-     *
1685
-     * @param array  $REG_IDs
1686
-     * @param string $status
1687
-     * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1688
-     *                        slug sent with setting the registration status.
1689
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1690
-     * @throws EE_Error
1691
-     * @throws InvalidArgumentException
1692
-     * @throws InvalidDataTypeException
1693
-     * @throws InvalidInterfaceException
1694
-     * @throws ReflectionException
1695
-     * @throws RuntimeException
1696
-     * @throws EntityNotFoundException
1697
-     * @throws DomainException
1698
-     */
1699
-    protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1700
-    {
1701
-        $success = false;
1702
-        // typecast $REG_IDs
1703
-        $REG_IDs = (array) $REG_IDs;
1704
-        if (! empty($REG_IDs)) {
1705
-            $success = true;
1706
-            // set default status if none is passed
1707
-            $status = $status ? $status : EEM_Registration::status_id_pending_payment;
1708
-            $status_context = $notify
1709
-                ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1710
-                : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1711
-            // loop through REG_ID's and change status
1712
-            foreach ($REG_IDs as $REG_ID) {
1713
-                $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1714
-                if ($registration instanceof EE_Registration) {
1715
-                    $registration->set_status(
1716
-                        $status,
1717
-                        false,
1718
-                        new Context(
1719
-                            $status_context,
1720
-                            esc_html__(
1721
-                                'Manually triggered status change on a Registration Admin Page route.',
1722
-                                'event_espresso'
1723
-                            )
1724
-                        )
1725
-                    );
1726
-                    $result = $registration->save();
1727
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1728
-                    $success = $result !== false ? $success : false;
1729
-                }
1730
-            }
1731
-        }
1732
-
1733
-        // return $success and processed registrations
1734
-        return array('REG_ID' => $REG_IDs, 'success' => $success);
1735
-    }
1736
-
1737
-
1738
-    /**
1739
-     * Common logic for setting up success message and redirecting to appropriate route
1740
-     *
1741
-     * @param string $STS_ID status id for the registration changed to
1742
-     * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1743
-     * @return void
1744
-     * @throws DomainException
1745
-     * @throws EE_Error
1746
-     * @throws EntityNotFoundException
1747
-     * @throws InvalidArgumentException
1748
-     * @throws InvalidDataTypeException
1749
-     * @throws InvalidInterfaceException
1750
-     * @throws ReflectionException
1751
-     * @throws RuntimeException
1752
-     */
1753
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1754
-    {
1755
-        $result = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1756
-            : array('success' => false);
1757
-        $success = isset($result['success']) && $result['success'];
1758
-        // setup success message
1759
-        if ($success) {
1760
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1761
-                $msg = sprintf(
1762
-                    esc_html__('Registration status has been set to %s', 'event_espresso'),
1763
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1764
-                );
1765
-            } else {
1766
-                $msg = sprintf(
1767
-                    esc_html__('Registrations have been set to %s.', 'event_espresso'),
1768
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1769
-                );
1770
-            }
1771
-            EE_Error::add_success($msg);
1772
-        } else {
1773
-            EE_Error::add_error(
1774
-                esc_html__(
1775
-                    'Something went wrong, and the status was not changed',
1776
-                    'event_espresso'
1777
-                ),
1778
-                __FILE__,
1779
-                __LINE__,
1780
-                __FUNCTION__
1781
-            );
1782
-        }
1783
-        if (isset($this->_req_data['return']) && $this->_req_data['return'] === 'view_registration') {
1784
-            $route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1785
-        } else {
1786
-            $route = array('action' => 'default');
1787
-        }
1788
-        $route = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1789
-        $this->_redirect_after_action($success, '', '', $route, true);
1790
-    }
1791
-
1792
-
1793
-    /**
1794
-     * incoming reg status change from reg details page.
1795
-     *
1796
-     * @return void
1797
-     * @throws EE_Error
1798
-     * @throws EntityNotFoundException
1799
-     * @throws InvalidArgumentException
1800
-     * @throws InvalidDataTypeException
1801
-     * @throws InvalidInterfaceException
1802
-     * @throws ReflectionException
1803
-     * @throws RuntimeException
1804
-     * @throws DomainException
1805
-     */
1806
-    protected function _change_reg_status()
1807
-    {
1808
-        $this->_req_data['return'] = 'view_registration';
1809
-        // set notify based on whether the send notifications toggle is set or not
1810
-        $notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1811
-        // $notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1812
-        $this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1813
-            ? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1814
-        switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1815
-            case EEM_Registration::status_id_approved:
1816
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1817
-                $this->approve_registration($notify);
1818
-                break;
1819
-            case EEM_Registration::status_id_pending_payment:
1820
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1821
-                $this->pending_registration($notify);
1822
-                break;
1823
-            case EEM_Registration::status_id_not_approved:
1824
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1825
-                $this->not_approve_registration($notify);
1826
-                break;
1827
-            case EEM_Registration::status_id_declined:
1828
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1829
-                $this->decline_registration($notify);
1830
-                break;
1831
-            case EEM_Registration::status_id_cancelled:
1832
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1833
-                $this->cancel_registration($notify);
1834
-                break;
1835
-            case EEM_Registration::status_id_wait_list:
1836
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1837
-                $this->wait_list_registration($notify);
1838
-                break;
1839
-            case EEM_Registration::status_id_incomplete:
1840
-            default:
1841
-                $result['success'] = false;
1842
-                unset($this->_req_data['return']);
1843
-                $this->_reg_status_change_return('', false);
1844
-                break;
1845
-        }
1846
-    }
1847
-
1848
-
1849
-    /**
1850
-     * Callback for bulk action routes.
1851
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1852
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
1853
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1854
-     * when an action is happening on just a single registration).
1855
-     *
1856
-     * @param      $action
1857
-     * @param bool $notify
1858
-     */
1859
-    protected function bulk_action_on_registrations($action, $notify = false)
1860
-    {
1861
-        do_action(
1862
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1863
-            $this,
1864
-            $action,
1865
-            $notify
1866
-        );
1867
-        $method = $action . '_registration';
1868
-        if (method_exists($this, $method)) {
1869
-            $this->$method($notify);
1870
-        }
1871
-    }
1872
-
1873
-
1874
-    /**
1875
-     * approve_registration
1876
-     *
1877
-     * @access protected
1878
-     * @param bool $notify whether or not to notify the registrant about their approval.
1879
-     * @return void
1880
-     * @throws EE_Error
1881
-     * @throws EntityNotFoundException
1882
-     * @throws InvalidArgumentException
1883
-     * @throws InvalidDataTypeException
1884
-     * @throws InvalidInterfaceException
1885
-     * @throws ReflectionException
1886
-     * @throws RuntimeException
1887
-     * @throws DomainException
1888
-     */
1889
-    protected function approve_registration($notify = false)
1890
-    {
1891
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1892
-    }
1893
-
1894
-
1895
-    /**
1896
-     *        decline_registration
1897
-     *
1898
-     * @access protected
1899
-     * @param bool $notify whether or not to notify the registrant about their status change.
1900
-     * @return void
1901
-     * @throws EE_Error
1902
-     * @throws EntityNotFoundException
1903
-     * @throws InvalidArgumentException
1904
-     * @throws InvalidDataTypeException
1905
-     * @throws InvalidInterfaceException
1906
-     * @throws ReflectionException
1907
-     * @throws RuntimeException
1908
-     * @throws DomainException
1909
-     */
1910
-    protected function decline_registration($notify = false)
1911
-    {
1912
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1913
-    }
1914
-
1915
-
1916
-    /**
1917
-     *        cancel_registration
1918
-     *
1919
-     * @access protected
1920
-     * @param bool $notify whether or not to notify the registrant about their status change.
1921
-     * @return void
1922
-     * @throws EE_Error
1923
-     * @throws EntityNotFoundException
1924
-     * @throws InvalidArgumentException
1925
-     * @throws InvalidDataTypeException
1926
-     * @throws InvalidInterfaceException
1927
-     * @throws ReflectionException
1928
-     * @throws RuntimeException
1929
-     * @throws DomainException
1930
-     */
1931
-    protected function cancel_registration($notify = false)
1932
-    {
1933
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1934
-    }
1935
-
1936
-
1937
-    /**
1938
-     *        not_approve_registration
1939
-     *
1940
-     * @access protected
1941
-     * @param bool $notify whether or not to notify the registrant about their status change.
1942
-     * @return void
1943
-     * @throws EE_Error
1944
-     * @throws EntityNotFoundException
1945
-     * @throws InvalidArgumentException
1946
-     * @throws InvalidDataTypeException
1947
-     * @throws InvalidInterfaceException
1948
-     * @throws ReflectionException
1949
-     * @throws RuntimeException
1950
-     * @throws DomainException
1951
-     */
1952
-    protected function not_approve_registration($notify = false)
1953
-    {
1954
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1955
-    }
1956
-
1957
-
1958
-    /**
1959
-     *        decline_registration
1960
-     *
1961
-     * @access protected
1962
-     * @param bool $notify whether or not to notify the registrant about their status change.
1963
-     * @return void
1964
-     * @throws EE_Error
1965
-     * @throws EntityNotFoundException
1966
-     * @throws InvalidArgumentException
1967
-     * @throws InvalidDataTypeException
1968
-     * @throws InvalidInterfaceException
1969
-     * @throws ReflectionException
1970
-     * @throws RuntimeException
1971
-     * @throws DomainException
1972
-     */
1973
-    protected function pending_registration($notify = false)
1974
-    {
1975
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1976
-    }
1977
-
1978
-
1979
-    /**
1980
-     * waitlist_registration
1981
-     *
1982
-     * @access protected
1983
-     * @param bool $notify whether or not to notify the registrant about their status change.
1984
-     * @return void
1985
-     * @throws EE_Error
1986
-     * @throws EntityNotFoundException
1987
-     * @throws InvalidArgumentException
1988
-     * @throws InvalidDataTypeException
1989
-     * @throws InvalidInterfaceException
1990
-     * @throws ReflectionException
1991
-     * @throws RuntimeException
1992
-     * @throws DomainException
1993
-     */
1994
-    protected function wait_list_registration($notify = false)
1995
-    {
1996
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1997
-    }
1998
-
1999
-
2000
-    /**
2001
-     *        generates HTML for the Registration main meta box
2002
-     *
2003
-     * @access public
2004
-     * @return void
2005
-     * @throws DomainException
2006
-     * @throws EE_Error
2007
-     * @throws InvalidArgumentException
2008
-     * @throws InvalidDataTypeException
2009
-     * @throws InvalidInterfaceException
2010
-     * @throws ReflectionException
2011
-     * @throws EntityNotFoundException
2012
-     */
2013
-    public function _reg_details_meta_box()
2014
-    {
2015
-        EEH_Autoloader::register_line_item_display_autoloaders();
2016
-        EEH_Autoloader::register_line_item_filter_autoloaders();
2017
-        EE_Registry::instance()->load_helper('Line_Item');
2018
-        $transaction = $this->_registration->transaction() ? $this->_registration->transaction()
2019
-            : EE_Transaction::new_instance();
2020
-        $this->_session = $transaction->session_data();
2021
-        $filters = new EE_Line_Item_Filter_Collection();
2022
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2023
-        $filters->add(new EE_Non_Zero_Line_Item_Filter());
2024
-        $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2025
-            $filters,
2026
-            $transaction->total_line_item()
2027
-        );
2028
-        $filtered_line_item_tree = $line_item_filter_processor->process();
2029
-        $line_item_display = new EE_Line_Item_Display(
2030
-            'reg_admin_table',
2031
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2032
-        );
2033
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2034
-            $filtered_line_item_tree,
2035
-            array('EE_Registration' => $this->_registration)
2036
-        );
2037
-        $attendee = $this->_registration->attendee();
2038
-        if (EE_Registry::instance()->CAP->current_user_can(
2039
-            'ee_read_transaction',
2040
-            'espresso_transactions_view_transaction'
2041
-        )) {
2042
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2043
-                EE_Admin_Page::add_query_args_and_nonce(
2044
-                    array(
2045
-                        'action' => 'view_transaction',
2046
-                        'TXN_ID' => $transaction->ID(),
2047
-                    ),
2048
-                    TXN_ADMIN_URL
2049
-                ),
2050
-                esc_html__(' View Transaction', 'event_espresso'),
2051
-                'button secondary-button right',
2052
-                'dashicons dashicons-cart'
2053
-            );
2054
-        } else {
2055
-            $this->_template_args['view_transaction_button'] = '';
2056
-        }
2057
-        if ($attendee instanceof EE_Attendee
2058
-            && EE_Registry::instance()->CAP->current_user_can(
2059
-                'ee_send_message',
2060
-                'espresso_registrations_resend_registration'
2061
-            )
2062
-        ) {
2063
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2064
-                EE_Admin_Page::add_query_args_and_nonce(
2065
-                    array(
2066
-                        'action'      => 'resend_registration',
2067
-                        '_REG_ID'     => $this->_registration->ID(),
2068
-                        'redirect_to' => 'view_registration',
2069
-                    ),
2070
-                    REG_ADMIN_URL
2071
-                ),
2072
-                esc_html__(' Resend Registration', 'event_espresso'),
2073
-                'button secondary-button right',
2074
-                'dashicons dashicons-email-alt'
2075
-            );
2076
-        } else {
2077
-            $this->_template_args['resend_registration_button'] = '';
2078
-        }
2079
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2080
-        $payment = $transaction->get_first_related('Payment');
2081
-        $payment = ! $payment instanceof EE_Payment
2082
-            ? EE_Payment::new_instance()
2083
-            : $payment;
2084
-        $payment_method = $payment->get_first_related('Payment_Method');
2085
-        $payment_method = ! $payment_method instanceof EE_Payment_Method
2086
-            ? EE_Payment_Method::new_instance()
2087
-            : $payment_method;
2088
-        $reg_details = array(
2089
-            'payment_method'       => $payment_method->name(),
2090
-            'response_msg'         => $payment->gateway_response(),
2091
-            'registration_id'      => $this->_registration->get('REG_code'),
2092
-            'registration_session' => $this->_registration->session_ID(),
2093
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2094
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2095
-        );
2096
-        if (isset($reg_details['registration_id'])) {
2097
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2098
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2099
-                'Registration ID',
2100
-                'event_espresso'
2101
-            );
2102
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2103
-        }
2104
-        if (isset($reg_details['payment_method'])) {
2105
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2106
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2107
-                'Most Recent Payment Method',
2108
-                'event_espresso'
2109
-            );
2110
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2111
-            $this->_template_args['reg_details']['response_msg']['value'] = $reg_details['response_msg'];
2112
-            $this->_template_args['reg_details']['response_msg']['label'] = esc_html__(
2113
-                'Payment method response',
2114
-                'event_espresso'
2115
-            );
2116
-            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2117
-        }
2118
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2119
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2120
-            'Registration Session',
2121
-            'event_espresso'
2122
-        );
2123
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2124
-        $this->_template_args['reg_details']['ip_address']['value'] = $reg_details['ip_address'];
2125
-        $this->_template_args['reg_details']['ip_address']['label'] = esc_html__(
2126
-            'Registration placed from IP',
2127
-            'event_espresso'
2128
-        );
2129
-        $this->_template_args['reg_details']['ip_address']['class'] = 'regular-text';
2130
-        $this->_template_args['reg_details']['user_agent']['value'] = $reg_details['user_agent'];
2131
-        $this->_template_args['reg_details']['user_agent']['label'] = esc_html__(
2132
-            'Registrant User Agent',
2133
-            'event_espresso'
2134
-        );
2135
-        $this->_template_args['reg_details']['user_agent']['class'] = 'large-text';
2136
-        $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
2137
-            array(
2138
-                'action'   => 'default',
2139
-                'event_id' => $this->_registration->event_ID(),
2140
-            ),
2141
-            REG_ADMIN_URL
2142
-        );
2143
-        $this->_template_args['REG_ID'] = $this->_registration->ID();
2144
-        $this->_template_args['event_id'] = $this->_registration->event_ID();
2145
-        $template_path =
2146
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2147
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2148
-    }
2149
-
2150
-
2151
-    /**
2152
-     * generates HTML for the Registration Questions meta box.
2153
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2154
-     * otherwise uses new forms system
2155
-     *
2156
-     * @access public
2157
-     * @return void
2158
-     * @throws DomainException
2159
-     * @throws EE_Error
2160
-     * @throws InvalidArgumentException
2161
-     * @throws InvalidDataTypeException
2162
-     * @throws InvalidInterfaceException
2163
-     * @throws ReflectionException
2164
-     */
2165
-    public function _reg_questions_meta_box()
2166
-    {
2167
-        // allow someone to override this method entirely
2168
-        if (apply_filters(
2169
-            'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2170
-            true,
2171
-            $this,
2172
-            $this->_registration
2173
-        )) {
2174
-            $form = $this->_get_reg_custom_questions_form(
2175
-                $this->_registration->ID()
2176
-            );
2177
-            $this->_template_args['att_questions'] = count($form->subforms()) > 0
2178
-                ? $form->get_html_and_js()
2179
-                : '';
2180
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2181
-            $this->_template_args['REG_ID'] = $this->_registration->ID();
2182
-            $template_path =
2183
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2184
-            echo EEH_Template::display_template($template_path, $this->_template_args, true);
2185
-        }
2186
-    }
2187
-
2188
-
2189
-    /**
2190
-     * form_before_question_group
2191
-     *
2192
-     * @deprecated    as of 4.8.32.rc.000
2193
-     * @access        public
2194
-     * @param        string $output
2195
-     * @return        string
2196
-     */
2197
-    public function form_before_question_group($output)
2198
-    {
2199
-        EE_Error::doing_it_wrong(
2200
-            __CLASS__ . '::' . __FUNCTION__,
2201
-            esc_html__(
2202
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2203
-                'event_espresso'
2204
-            ),
2205
-            '4.8.32.rc.000'
2206
-        );
2207
-        return '
21
+	/**
22
+	 * @var EE_Registration
23
+	 */
24
+	private $_registration;
25
+
26
+	/**
27
+	 * @var EE_Event
28
+	 */
29
+	private $_reg_event;
30
+
31
+	/**
32
+	 * @var EE_Session
33
+	 */
34
+	private $_session;
35
+
36
+	private static $_reg_status;
37
+
38
+	/**
39
+	 * Form for displaying the custom questions for this registration.
40
+	 * This gets used a few times throughout the request so its best to cache it
41
+	 *
42
+	 * @var EE_Registration_Custom_Questions_Form
43
+	 */
44
+	protected $_reg_custom_questions_form = null;
45
+
46
+	/**
47
+	 * @var EEM_Registration $registration_model
48
+	 */
49
+	private $registration_model;
50
+
51
+	/**
52
+	 * @var EEM_Attendee $attendee_model
53
+	 */
54
+	private $attendee_model;
55
+
56
+	/**
57
+	 * @var EEM_Event $event_model
58
+	 */
59
+	private $event_model;
60
+
61
+	/**
62
+	 * @var EEM_Status $status_model
63
+	 */
64
+	private $status_model;
65
+
66
+
67
+	/**
68
+	 * @param bool $routing
69
+	 * @throws EE_Error
70
+	 * @throws InvalidArgumentException
71
+	 * @throws InvalidDataTypeException
72
+	 * @throws InvalidInterfaceException
73
+	 * @throws ReflectionException
74
+	 */
75
+	public function __construct($routing = true)
76
+	{
77
+		parent::__construct($routing);
78
+		add_action('wp_loaded', array($this, 'wp_loaded'));
79
+	}
80
+
81
+	/**
82
+	 * @return EEM_Registration
83
+	 * @throws InvalidArgumentException
84
+	 * @throws InvalidDataTypeException
85
+	 * @throws InvalidInterfaceException
86
+	 * @since 4.10.2.p
87
+	 */
88
+	protected function getRegistrationModel()
89
+	{
90
+		if (! $this->registration_model instanceof EEM_Registration) {
91
+			$this->registration_model = $this->getLoader()->getShared('EEM_Registration');
92
+		}
93
+		return $this->registration_model;
94
+	}
95
+
96
+	/**
97
+	 * @return EEM_Attendee
98
+	 * @throws InvalidArgumentException
99
+	 * @throws InvalidDataTypeException
100
+	 * @throws InvalidInterfaceException
101
+	 * @since 4.10.2.p
102
+	 */
103
+	protected function getAttendeeModel()
104
+	{
105
+		if (! $this->attendee_model instanceof EEM_Attendee) {
106
+			$this->attendee_model = $this->getLoader()->getShared('EEM_Attendee');
107
+		}
108
+		return $this->attendee_model;
109
+	}
110
+
111
+
112
+	/**
113
+	 * @return EEM_Event
114
+	 * @throws InvalidArgumentException
115
+	 * @throws InvalidDataTypeException
116
+	 * @throws InvalidInterfaceException
117
+	 * @since 4.10.2.p
118
+	 */
119
+	protected function getEventModel()
120
+	{
121
+		if (! $this->event_model instanceof EEM_Event) {
122
+			$this->event_model = $this->getLoader()->getShared('EEM_Event');
123
+		}
124
+		return $this->event_model;
125
+	}
126
+
127
+	/**
128
+	 * @return EEM_Status
129
+	 * @throws InvalidArgumentException
130
+	 * @throws InvalidDataTypeException
131
+	 * @throws InvalidInterfaceException
132
+	 * @since 4.10.2.p
133
+	 */
134
+	protected function getStatusModel()
135
+	{
136
+		if (! $this->status_model instanceof EEM_Status) {
137
+			$this->status_model = $this->getLoader()->getShared('EEM_Status');
138
+		}
139
+		return $this->status_model;
140
+	}
141
+
142
+
143
+	public function wp_loaded()
144
+	{
145
+		// when adding a new registration...
146
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
147
+			EE_System::do_not_cache();
148
+			if (! isset($this->_req_data['processing_registration'])
149
+				|| absint($this->_req_data['processing_registration']) !== 1
150
+			) {
151
+				// and it's NOT the attendee information reg step
152
+				// force cookie expiration by setting time to last week
153
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
154
+				// and update the global
155
+				$_COOKIE['ee_registration_added'] = 0;
156
+			}
157
+		}
158
+	}
159
+
160
+
161
+	protected function _init_page_props()
162
+	{
163
+		$this->page_slug = REG_PG_SLUG;
164
+		$this->_admin_base_url = REG_ADMIN_URL;
165
+		$this->_admin_base_path = REG_ADMIN;
166
+		$this->page_label = esc_html__('Registrations', 'event_espresso');
167
+		$this->_cpt_routes = array(
168
+			'add_new_attendee' => 'espresso_attendees',
169
+			'edit_attendee'    => 'espresso_attendees',
170
+			'insert_attendee'  => 'espresso_attendees',
171
+			'update_attendee'  => 'espresso_attendees',
172
+		);
173
+		$this->_cpt_model_names = array(
174
+			'add_new_attendee' => 'EEM_Attendee',
175
+			'edit_attendee'    => 'EEM_Attendee',
176
+		);
177
+		$this->_cpt_edit_routes = array(
178
+			'espresso_attendees' => 'edit_attendee',
179
+		);
180
+		$this->_pagenow_map = array(
181
+			'add_new_attendee' => 'post-new.php',
182
+			'edit_attendee'    => 'post.php',
183
+			'trash'            => 'post.php',
184
+		);
185
+		add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
186
+		// add filters so that the comment urls don't take users to a confusing 404 page
187
+		add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
188
+	}
189
+
190
+
191
+	public function clear_comment_link($link, $comment, $args)
192
+	{
193
+		// gotta make sure this only happens on this route
194
+		$post_type = get_post_type($comment->comment_post_ID);
195
+		if ($post_type === 'espresso_attendees') {
196
+			return '#commentsdiv';
197
+		}
198
+		return $link;
199
+	}
200
+
201
+
202
+	protected function _ajax_hooks()
203
+	{
204
+		// todo: all hooks for registrations ajax goes in here
205
+		add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
206
+	}
207
+
208
+
209
+	protected function _define_page_props()
210
+	{
211
+		$this->_admin_page_title = $this->page_label;
212
+		$this->_labels = array(
213
+			'buttons'                      => array(
214
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
215
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
216
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
217
+				'report'              => esc_html__('Event Registrations CSV Report', 'event_espresso'),
218
+				'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
219
+				'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
220
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
221
+				'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
222
+			),
223
+			'publishbox'                   => array(
224
+				'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
225
+				'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
226
+			),
227
+			'hide_add_button_on_cpt_route' => array(
228
+				'edit_attendee' => true,
229
+			),
230
+		);
231
+	}
232
+
233
+
234
+	/**
235
+	 *        grab url requests and route them
236
+	 *
237
+	 * @access private
238
+	 * @return void
239
+	 * @throws EE_Error
240
+	 */
241
+	public function _set_page_routes()
242
+	{
243
+		$this->_get_registration_status_array();
244
+		$reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
245
+			? $this->_req_data['_REG_ID'] : 0;
246
+		$reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
247
+			? $this->_req_data['reg_status_change_form']['REG_ID']
248
+			: $reg_id;
249
+		$att_id = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
250
+			? $this->_req_data['ATT_ID'] : 0;
251
+		$att_id = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
252
+			? $this->_req_data['post']
253
+			: $att_id;
254
+		$this->_page_routes = array(
255
+			'default'                             => array(
256
+				'func'       => '_registrations_overview_list_table',
257
+				'capability' => 'ee_read_registrations',
258
+			),
259
+			'view_registration'                   => array(
260
+				'func'       => '_registration_details',
261
+				'capability' => 'ee_read_registration',
262
+				'obj_id'     => $reg_id,
263
+			),
264
+			'edit_registration'                   => array(
265
+				'func'               => '_update_attendee_registration_form',
266
+				'noheader'           => true,
267
+				'headers_sent_route' => 'view_registration',
268
+				'capability'         => 'ee_edit_registration',
269
+				'obj_id'             => $reg_id,
270
+				'_REG_ID'            => $reg_id,
271
+			),
272
+			'trash_registrations'                 => array(
273
+				'func'       => '_trash_or_restore_registrations',
274
+				'args'       => array('trash' => true),
275
+				'noheader'   => true,
276
+				'capability' => 'ee_delete_registrations',
277
+			),
278
+			'restore_registrations'               => array(
279
+				'func'       => '_trash_or_restore_registrations',
280
+				'args'       => array('trash' => false),
281
+				'noheader'   => true,
282
+				'capability' => 'ee_delete_registrations',
283
+			),
284
+			'delete_registrations'                => array(
285
+				'func'       => '_delete_registrations',
286
+				'noheader'   => true,
287
+				'capability' => 'ee_delete_registrations',
288
+			),
289
+			'new_registration'                    => array(
290
+				'func'       => 'new_registration',
291
+				'capability' => 'ee_edit_registrations',
292
+			),
293
+			'process_reg_step'                    => array(
294
+				'func'       => 'process_reg_step',
295
+				'noheader'   => true,
296
+				'capability' => 'ee_edit_registrations',
297
+			),
298
+			'redirect_to_txn'                     => array(
299
+				'func'       => 'redirect_to_txn',
300
+				'noheader'   => true,
301
+				'capability' => 'ee_edit_registrations',
302
+			),
303
+			'change_reg_status'                   => array(
304
+				'func'       => '_change_reg_status',
305
+				'noheader'   => true,
306
+				'capability' => 'ee_edit_registration',
307
+				'obj_id'     => $reg_id,
308
+			),
309
+			'approve_registration'                => array(
310
+				'func'       => 'approve_registration',
311
+				'noheader'   => true,
312
+				'capability' => 'ee_edit_registration',
313
+				'obj_id'     => $reg_id,
314
+			),
315
+			'approve_and_notify_registration'     => array(
316
+				'func'       => 'approve_registration',
317
+				'noheader'   => true,
318
+				'args'       => array(true),
319
+				'capability' => 'ee_edit_registration',
320
+				'obj_id'     => $reg_id,
321
+			),
322
+			'approve_registrations'               => array(
323
+				'func'       => 'bulk_action_on_registrations',
324
+				'noheader'   => true,
325
+				'capability' => 'ee_edit_registrations',
326
+				'args'       => array('approve'),
327
+			),
328
+			'approve_and_notify_registrations'    => array(
329
+				'func'       => 'bulk_action_on_registrations',
330
+				'noheader'   => true,
331
+				'capability' => 'ee_edit_registrations',
332
+				'args'       => array('approve', true),
333
+			),
334
+			'decline_registration'                => array(
335
+				'func'       => 'decline_registration',
336
+				'noheader'   => true,
337
+				'capability' => 'ee_edit_registration',
338
+				'obj_id'     => $reg_id,
339
+			),
340
+			'decline_and_notify_registration'     => array(
341
+				'func'       => 'decline_registration',
342
+				'noheader'   => true,
343
+				'args'       => array(true),
344
+				'capability' => 'ee_edit_registration',
345
+				'obj_id'     => $reg_id,
346
+			),
347
+			'decline_registrations'               => array(
348
+				'func'       => 'bulk_action_on_registrations',
349
+				'noheader'   => true,
350
+				'capability' => 'ee_edit_registrations',
351
+				'args'       => array('decline'),
352
+			),
353
+			'decline_and_notify_registrations'    => array(
354
+				'func'       => 'bulk_action_on_registrations',
355
+				'noheader'   => true,
356
+				'capability' => 'ee_edit_registrations',
357
+				'args'       => array('decline', true),
358
+			),
359
+			'pending_registration'                => array(
360
+				'func'       => 'pending_registration',
361
+				'noheader'   => true,
362
+				'capability' => 'ee_edit_registration',
363
+				'obj_id'     => $reg_id,
364
+			),
365
+			'pending_and_notify_registration'     => array(
366
+				'func'       => 'pending_registration',
367
+				'noheader'   => true,
368
+				'args'       => array(true),
369
+				'capability' => 'ee_edit_registration',
370
+				'obj_id'     => $reg_id,
371
+			),
372
+			'pending_registrations'               => array(
373
+				'func'       => 'bulk_action_on_registrations',
374
+				'noheader'   => true,
375
+				'capability' => 'ee_edit_registrations',
376
+				'args'       => array('pending'),
377
+			),
378
+			'pending_and_notify_registrations'    => array(
379
+				'func'       => 'bulk_action_on_registrations',
380
+				'noheader'   => true,
381
+				'capability' => 'ee_edit_registrations',
382
+				'args'       => array('pending', true),
383
+			),
384
+			'no_approve_registration'             => array(
385
+				'func'       => 'not_approve_registration',
386
+				'noheader'   => true,
387
+				'capability' => 'ee_edit_registration',
388
+				'obj_id'     => $reg_id,
389
+			),
390
+			'no_approve_and_notify_registration'  => array(
391
+				'func'       => 'not_approve_registration',
392
+				'noheader'   => true,
393
+				'args'       => array(true),
394
+				'capability' => 'ee_edit_registration',
395
+				'obj_id'     => $reg_id,
396
+			),
397
+			'no_approve_registrations'            => array(
398
+				'func'       => 'bulk_action_on_registrations',
399
+				'noheader'   => true,
400
+				'capability' => 'ee_edit_registrations',
401
+				'args'       => array('not_approve'),
402
+			),
403
+			'no_approve_and_notify_registrations' => array(
404
+				'func'       => 'bulk_action_on_registrations',
405
+				'noheader'   => true,
406
+				'capability' => 'ee_edit_registrations',
407
+				'args'       => array('not_approve', true),
408
+			),
409
+			'cancel_registration'                 => array(
410
+				'func'       => 'cancel_registration',
411
+				'noheader'   => true,
412
+				'capability' => 'ee_edit_registration',
413
+				'obj_id'     => $reg_id,
414
+			),
415
+			'cancel_and_notify_registration'      => array(
416
+				'func'       => 'cancel_registration',
417
+				'noheader'   => true,
418
+				'args'       => array(true),
419
+				'capability' => 'ee_edit_registration',
420
+				'obj_id'     => $reg_id,
421
+			),
422
+			'cancel_registrations'                => array(
423
+				'func'       => 'bulk_action_on_registrations',
424
+				'noheader'   => true,
425
+				'capability' => 'ee_edit_registrations',
426
+				'args'       => array('cancel'),
427
+			),
428
+			'cancel_and_notify_registrations'     => array(
429
+				'func'       => 'bulk_action_on_registrations',
430
+				'noheader'   => true,
431
+				'capability' => 'ee_edit_registrations',
432
+				'args'       => array('cancel', true),
433
+			),
434
+			'wait_list_registration'              => array(
435
+				'func'       => 'wait_list_registration',
436
+				'noheader'   => true,
437
+				'capability' => 'ee_edit_registration',
438
+				'obj_id'     => $reg_id,
439
+			),
440
+			'wait_list_and_notify_registration'   => array(
441
+				'func'       => 'wait_list_registration',
442
+				'noheader'   => true,
443
+				'args'       => array(true),
444
+				'capability' => 'ee_edit_registration',
445
+				'obj_id'     => $reg_id,
446
+			),
447
+			'contact_list'                        => array(
448
+				'func'       => '_attendee_contact_list_table',
449
+				'capability' => 'ee_read_contacts',
450
+			),
451
+			'add_new_attendee'                    => array(
452
+				'func' => '_create_new_cpt_item',
453
+				'args' => array(
454
+					'new_attendee' => true,
455
+					'capability'   => 'ee_edit_contacts',
456
+				),
457
+			),
458
+			'edit_attendee'                       => array(
459
+				'func'       => '_edit_cpt_item',
460
+				'capability' => 'ee_edit_contacts',
461
+				'obj_id'     => $att_id,
462
+			),
463
+			'duplicate_attendee'                  => array(
464
+				'func'       => '_duplicate_attendee',
465
+				'noheader'   => true,
466
+				'capability' => 'ee_edit_contacts',
467
+				'obj_id'     => $att_id,
468
+			),
469
+			'insert_attendee'                     => array(
470
+				'func'       => '_insert_or_update_attendee',
471
+				'args'       => array(
472
+					'new_attendee' => true,
473
+				),
474
+				'noheader'   => true,
475
+				'capability' => 'ee_edit_contacts',
476
+			),
477
+			'update_attendee'                     => array(
478
+				'func'       => '_insert_or_update_attendee',
479
+				'args'       => array(
480
+					'new_attendee' => false,
481
+				),
482
+				'noheader'   => true,
483
+				'capability' => 'ee_edit_contacts',
484
+				'obj_id'     => $att_id,
485
+			),
486
+			'trash_attendees'                     => array(
487
+				'func'       => '_trash_or_restore_attendees',
488
+				'args'       => array(
489
+					'trash' => 'true',
490
+				),
491
+				'noheader'   => true,
492
+				'capability' => 'ee_delete_contacts',
493
+			),
494
+			'trash_attendee'                      => array(
495
+				'func'       => '_trash_or_restore_attendees',
496
+				'args'       => array(
497
+					'trash' => true,
498
+				),
499
+				'noheader'   => true,
500
+				'capability' => 'ee_delete_contacts',
501
+				'obj_id'     => $att_id,
502
+			),
503
+			'restore_attendees'                   => array(
504
+				'func'       => '_trash_or_restore_attendees',
505
+				'args'       => array(
506
+					'trash' => false,
507
+				),
508
+				'noheader'   => true,
509
+				'capability' => 'ee_delete_contacts',
510
+				'obj_id'     => $att_id,
511
+			),
512
+			'resend_registration'                 => array(
513
+				'func'       => '_resend_registration',
514
+				'noheader'   => true,
515
+				'capability' => 'ee_send_message',
516
+			),
517
+			'registrations_report'                => array(
518
+				'func'       => '_registrations_report',
519
+				'noheader'   => true,
520
+				'capability' => 'ee_read_registrations',
521
+			),
522
+			'contact_list_export'                 => array(
523
+				'func'       => '_contact_list_export',
524
+				'noheader'   => true,
525
+				'capability' => 'export',
526
+			),
527
+			'contact_list_report'                 => array(
528
+				'func'       => '_contact_list_report',
529
+				'noheader'   => true,
530
+				'capability' => 'ee_read_contacts',
531
+			),
532
+		);
533
+	}
534
+
535
+
536
+	protected function _set_page_config()
537
+	{
538
+		$this->_page_config = array(
539
+			'default'           => array(
540
+				'nav'           => array(
541
+					'label' => esc_html__('Overview', 'event_espresso'),
542
+					'order' => 5,
543
+				),
544
+				'help_tabs'     => array(
545
+					'registrations_overview_help_tab'                       => array(
546
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
547
+						'filename' => 'registrations_overview',
548
+					),
549
+					'registrations_overview_table_column_headings_help_tab' => array(
550
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
551
+						'filename' => 'registrations_overview_table_column_headings',
552
+					),
553
+					'registrations_overview_filters_help_tab'               => array(
554
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
555
+						'filename' => 'registrations_overview_filters',
556
+					),
557
+					'registrations_overview_views_help_tab'                 => array(
558
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
559
+						'filename' => 'registrations_overview_views',
560
+					),
561
+					'registrations_regoverview_other_help_tab'              => array(
562
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
563
+						'filename' => 'registrations_overview_other',
564
+					),
565
+				),
566
+				'help_tour'     => array('Registration_Overview_Help_Tour'),
567
+				'qtips'         => array('Registration_List_Table_Tips'),
568
+				'list_table'    => 'EE_Registrations_List_Table',
569
+				'require_nonce' => false,
570
+			),
571
+			'view_registration' => array(
572
+				'nav'           => array(
573
+					'label'      => esc_html__('REG Details', 'event_espresso'),
574
+					'order'      => 15,
575
+					'url'        => isset($this->_req_data['_REG_ID'])
576
+						? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
577
+						: $this->_admin_base_url,
578
+					'persistent' => false,
579
+				),
580
+				'help_tabs'     => array(
581
+					'registrations_details_help_tab'                    => array(
582
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
583
+						'filename' => 'registrations_details',
584
+					),
585
+					'registrations_details_table_help_tab'              => array(
586
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
587
+						'filename' => 'registrations_details_table',
588
+					),
589
+					'registrations_details_form_answers_help_tab'       => array(
590
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
591
+						'filename' => 'registrations_details_form_answers',
592
+					),
593
+					'registrations_details_registrant_details_help_tab' => array(
594
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
595
+						'filename' => 'registrations_details_registrant_details',
596
+					),
597
+				),
598
+				'help_tour'     => array('Registration_Details_Help_Tour'),
599
+				'metaboxes'     => array_merge(
600
+					$this->_default_espresso_metaboxes,
601
+					array('_registration_details_metaboxes')
602
+				),
603
+				'require_nonce' => false,
604
+			),
605
+			'new_registration'  => array(
606
+				'nav'           => array(
607
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
608
+					'url'        => '#',
609
+					'order'      => 15,
610
+					'persistent' => false,
611
+				),
612
+				'metaboxes'     => $this->_default_espresso_metaboxes,
613
+				'labels'        => array(
614
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
615
+				),
616
+				'require_nonce' => false,
617
+			),
618
+			'add_new_attendee'  => array(
619
+				'nav'           => array(
620
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
621
+					'order'      => 15,
622
+					'persistent' => false,
623
+				),
624
+				'metaboxes'     => array_merge(
625
+					$this->_default_espresso_metaboxes,
626
+					array('_publish_post_box', 'attendee_editor_metaboxes')
627
+				),
628
+				'require_nonce' => false,
629
+			),
630
+			'edit_attendee'     => array(
631
+				'nav'           => array(
632
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
633
+					'order'      => 15,
634
+					'persistent' => false,
635
+					'url'        => isset($this->_req_data['ATT_ID'])
636
+						? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
637
+						: $this->_admin_base_url,
638
+				),
639
+				'metaboxes'     => array('attendee_editor_metaboxes'),
640
+				'require_nonce' => false,
641
+			),
642
+			'contact_list'      => array(
643
+				'nav'           => array(
644
+					'label' => esc_html__('Contact List', 'event_espresso'),
645
+					'order' => 20,
646
+				),
647
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
648
+				'help_tabs'     => array(
649
+					'registrations_contact_list_help_tab'                       => array(
650
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
651
+						'filename' => 'registrations_contact_list',
652
+					),
653
+					'registrations_contact-list_table_column_headings_help_tab' => array(
654
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
655
+						'filename' => 'registrations_contact_list_table_column_headings',
656
+					),
657
+					'registrations_contact_list_views_help_tab'                 => array(
658
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
659
+						'filename' => 'registrations_contact_list_views',
660
+					),
661
+					'registrations_contact_list_other_help_tab'                 => array(
662
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
663
+						'filename' => 'registrations_contact_list_other',
664
+					),
665
+				),
666
+				'help_tour'     => array('Contact_List_Help_Tour'),
667
+				'metaboxes'     => array(),
668
+				'require_nonce' => false,
669
+			),
670
+			// override default cpt routes
671
+			'create_new'        => '',
672
+			'edit'              => '',
673
+		);
674
+	}
675
+
676
+
677
+	/**
678
+	 * The below methods aren't used by this class currently
679
+	 */
680
+	protected function _add_screen_options()
681
+	{
682
+	}
683
+
684
+
685
+	protected function _add_feature_pointers()
686
+	{
687
+	}
688
+
689
+
690
+	public function admin_init()
691
+	{
692
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
693
+			'click "Update Registration Questions" to save your changes',
694
+			'event_espresso'
695
+		);
696
+	}
697
+
698
+
699
+	public function admin_notices()
700
+	{
701
+	}
702
+
703
+
704
+	public function admin_footer_scripts()
705
+	{
706
+	}
707
+
708
+
709
+	/**
710
+	 *        get list of registration statuses
711
+	 *
712
+	 * @access private
713
+	 * @return void
714
+	 * @throws EE_Error
715
+	 */
716
+	private function _get_registration_status_array()
717
+	{
718
+		self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
719
+	}
720
+
721
+
722
+	/**
723
+	 * @throws InvalidArgumentException
724
+	 * @throws InvalidDataTypeException
725
+	 * @throws InvalidInterfaceException
726
+	 * @since 4.10.2.p
727
+	 */
728
+	protected function _add_screen_options_default()
729
+	{
730
+		$this->_per_page_screen_option();
731
+	}
732
+
733
+
734
+	/**
735
+	 * @throws InvalidArgumentException
736
+	 * @throws InvalidDataTypeException
737
+	 * @throws InvalidInterfaceException
738
+	 * @since 4.10.2.p
739
+	 */
740
+	protected function _add_screen_options_contact_list()
741
+	{
742
+		$page_title = $this->_admin_page_title;
743
+		$this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
744
+		$this->_per_page_screen_option();
745
+		$this->_admin_page_title = $page_title;
746
+	}
747
+
748
+
749
+	public function load_scripts_styles()
750
+	{
751
+		// style
752
+		wp_register_style(
753
+			'espresso_reg',
754
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
755
+			array('ee-admin-css'),
756
+			EVENT_ESPRESSO_VERSION
757
+		);
758
+		wp_enqueue_style('espresso_reg');
759
+		// script
760
+		wp_register_script(
761
+			'espresso_reg',
762
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
763
+			array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
764
+			EVENT_ESPRESSO_VERSION,
765
+			true
766
+		);
767
+		wp_enqueue_script('espresso_reg');
768
+	}
769
+
770
+
771
+	/**
772
+	 * @throws EE_Error
773
+	 * @throws InvalidArgumentException
774
+	 * @throws InvalidDataTypeException
775
+	 * @throws InvalidInterfaceException
776
+	 * @throws ReflectionException
777
+	 * @since 4.10.2.p
778
+	 */
779
+	public function load_scripts_styles_edit_attendee()
780
+	{
781
+		// stuff to only show up on our attendee edit details page.
782
+		$attendee_details_translations = array(
783
+			'att_publish_text' => sprintf(
784
+				/* translators: The date and time */
785
+				wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
786
+				'<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
787
+			),
788
+		);
789
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
790
+		wp_enqueue_script('jquery-validate');
791
+	}
792
+
793
+
794
+	/**
795
+	 * @throws EE_Error
796
+	 * @throws InvalidArgumentException
797
+	 * @throws InvalidDataTypeException
798
+	 * @throws InvalidInterfaceException
799
+	 * @throws ReflectionException
800
+	 * @since 4.10.2.p
801
+	 */
802
+	public function load_scripts_styles_view_registration()
803
+	{
804
+		// styles
805
+		wp_enqueue_style('espresso-ui-theme');
806
+		// scripts
807
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
808
+		$this->_reg_custom_questions_form->wp_enqueue_scripts(true);
809
+	}
810
+
811
+
812
+	public function load_scripts_styles_contact_list()
813
+	{
814
+		wp_dequeue_style('espresso_reg');
815
+		wp_register_style(
816
+			'espresso_att',
817
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
818
+			array('ee-admin-css'),
819
+			EVENT_ESPRESSO_VERSION
820
+		);
821
+		wp_enqueue_style('espresso_att');
822
+	}
823
+
824
+
825
+	public function load_scripts_styles_new_registration()
826
+	{
827
+		wp_register_script(
828
+			'ee-spco-for-admin',
829
+			REG_ASSETS_URL . 'spco_for_admin.js',
830
+			array('underscore', 'jquery'),
831
+			EVENT_ESPRESSO_VERSION,
832
+			true
833
+		);
834
+		wp_enqueue_script('ee-spco-for-admin');
835
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
836
+		EE_Form_Section_Proper::wp_enqueue_scripts();
837
+		EED_Ticket_Selector::load_tckt_slctr_assets();
838
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
839
+	}
840
+
841
+
842
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
843
+	{
844
+		add_filter('FHEE_load_EE_messages', '__return_true');
845
+	}
846
+
847
+
848
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
849
+	{
850
+		add_filter('FHEE_load_EE_messages', '__return_true');
851
+	}
852
+
853
+
854
+	/**
855
+	 * @throws EE_Error
856
+	 * @throws InvalidArgumentException
857
+	 * @throws InvalidDataTypeException
858
+	 * @throws InvalidInterfaceException
859
+	 * @throws ReflectionException
860
+	 * @since 4.10.2.p
861
+	 */
862
+	protected function _set_list_table_views_default()
863
+	{
864
+		// for notification related bulk actions we need to make sure only active messengers have an option.
865
+		EED_Messages::set_autoloaders();
866
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
867
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
868
+		$active_mts = $message_resource_manager->list_of_active_message_types();
869
+		// key= bulk_action_slug, value= message type.
870
+		$match_array = array(
871
+			'approve_registrations'    => 'registration',
872
+			'decline_registrations'    => 'declined_registration',
873
+			'pending_registrations'    => 'pending_approval',
874
+			'no_approve_registrations' => 'not_approved_registration',
875
+			'cancel_registrations'     => 'cancelled_registration',
876
+		);
877
+		$can_send = EE_Registry::instance()->CAP->current_user_can(
878
+			'ee_send_message',
879
+			'batch_send_messages'
880
+		);
881
+		/** setup reg status bulk actions **/
882
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
883
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
884
+			$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
885
+				'Approve and Notify Registrations',
886
+				'event_espresso'
887
+			);
888
+		}
889
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
890
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
891
+			$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
892
+				'Decline and Notify Registrations',
893
+				'event_espresso'
894
+			);
895
+		}
896
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
897
+			'Set Registrations to Pending Payment',
898
+			'event_espresso'
899
+		);
900
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
901
+			$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
902
+				'Set Registrations to Pending Payment and Notify',
903
+				'event_espresso'
904
+			);
905
+		}
906
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
907
+			'Set Registrations to Not Approved',
908
+			'event_espresso'
909
+		);
910
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
911
+			$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
912
+				'Set Registrations to Not Approved and Notify',
913
+				'event_espresso'
914
+			);
915
+		}
916
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
917
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
918
+			$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
919
+				'Cancel Registrations and Notify',
920
+				'event_espresso'
921
+			);
922
+		}
923
+		$def_reg_status_actions = apply_filters(
924
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
925
+			$def_reg_status_actions,
926
+			$active_mts,
927
+			$can_send
928
+		);
929
+
930
+		$this->_views = array(
931
+			'all'   => array(
932
+				'slug'        => 'all',
933
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
934
+				'count'       => 0,
935
+				'bulk_action' => array_merge(
936
+					$def_reg_status_actions,
937
+					array(
938
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
939
+					)
940
+				),
941
+			),
942
+			'month' => array(
943
+				'slug'        => 'month',
944
+				'label'       => esc_html__('This Month', 'event_espresso'),
945
+				'count'       => 0,
946
+				'bulk_action' => array_merge(
947
+					$def_reg_status_actions,
948
+					array(
949
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
950
+					)
951
+				),
952
+			),
953
+			'today' => array(
954
+				'slug'        => 'today',
955
+				'label'       => sprintf(
956
+					esc_html__('Today - %s', 'event_espresso'),
957
+					date('M d, Y', current_time('timestamp'))
958
+				),
959
+				'count'       => 0,
960
+				'bulk_action' => array_merge(
961
+					$def_reg_status_actions,
962
+					array(
963
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
964
+					)
965
+				),
966
+			),
967
+		);
968
+		if (EE_Registry::instance()->CAP->current_user_can(
969
+			'ee_delete_registrations',
970
+			'espresso_registrations_delete_registration'
971
+		)) {
972
+			$this->_views['incomplete'] = array(
973
+				'slug'        => 'incomplete',
974
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
975
+				'count'       => 0,
976
+				'bulk_action' => array(
977
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
978
+				),
979
+			);
980
+			$this->_views['trash'] = array(
981
+				'slug'        => 'trash',
982
+				'label'       => esc_html__('Trash', 'event_espresso'),
983
+				'count'       => 0,
984
+				'bulk_action' => array(
985
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
986
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
987
+				),
988
+			);
989
+		}
990
+	}
991
+
992
+
993
+	protected function _set_list_table_views_contact_list()
994
+	{
995
+		$this->_views = array(
996
+			'in_use' => array(
997
+				'slug'        => 'in_use',
998
+				'label'       => esc_html__('In Use', 'event_espresso'),
999
+				'count'       => 0,
1000
+				'bulk_action' => array(
1001
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1002
+				),
1003
+			),
1004
+		);
1005
+		if (EE_Registry::instance()->CAP->current_user_can(
1006
+			'ee_delete_contacts',
1007
+			'espresso_registrations_trash_attendees'
1008
+		)
1009
+		) {
1010
+			$this->_views['trash'] = array(
1011
+				'slug'        => 'trash',
1012
+				'label'       => esc_html__('Trash', 'event_espresso'),
1013
+				'count'       => 0,
1014
+				'bulk_action' => array(
1015
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1016
+				),
1017
+			);
1018
+		}
1019
+	}
1020
+
1021
+
1022
+	protected function _registration_legend_items()
1023
+	{
1024
+		$fc_items = array(
1025
+			'star-icon'        => array(
1026
+				'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
1027
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1028
+			),
1029
+			'view_details'     => array(
1030
+				'class' => 'dashicons dashicons-clipboard',
1031
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1032
+			),
1033
+			'edit_attendee'    => array(
1034
+				'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
1035
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1036
+			),
1037
+			'view_transaction' => array(
1038
+				'class' => 'dashicons dashicons-cart',
1039
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1040
+			),
1041
+			'view_invoice'     => array(
1042
+				'class' => 'dashicons dashicons-media-spreadsheet',
1043
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1044
+			),
1045
+		);
1046
+		if (EE_Registry::instance()->CAP->current_user_can(
1047
+			'ee_send_message',
1048
+			'espresso_registrations_resend_registration'
1049
+		)) {
1050
+			$fc_items['resend_registration'] = array(
1051
+				'class' => 'dashicons dashicons-email-alt',
1052
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1053
+			);
1054
+		} else {
1055
+			$fc_items['blank'] = array('class' => 'blank', 'desc' => '');
1056
+		}
1057
+		if (EE_Registry::instance()->CAP->current_user_can(
1058
+			'ee_read_global_messages',
1059
+			'view_filtered_messages'
1060
+		)) {
1061
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1062
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1063
+				$fc_items['view_related_messages'] = array(
1064
+					'class' => $related_for_icon['css_class'],
1065
+					'desc'  => $related_for_icon['label'],
1066
+				);
1067
+			}
1068
+		}
1069
+		$sc_items = array(
1070
+			'approved_status'   => array(
1071
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
1072
+				'desc'  => EEH_Template::pretty_status(
1073
+					EEM_Registration::status_id_approved,
1074
+					false,
1075
+					'sentence'
1076
+				),
1077
+			),
1078
+			'pending_status'    => array(
1079
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
1080
+				'desc'  => EEH_Template::pretty_status(
1081
+					EEM_Registration::status_id_pending_payment,
1082
+					false,
1083
+					'sentence'
1084
+				),
1085
+			),
1086
+			'wait_list'         => array(
1087
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
1088
+				'desc'  => EEH_Template::pretty_status(
1089
+					EEM_Registration::status_id_wait_list,
1090
+					false,
1091
+					'sentence'
1092
+				),
1093
+			),
1094
+			'incomplete_status' => array(
1095
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
1096
+				'desc'  => EEH_Template::pretty_status(
1097
+					EEM_Registration::status_id_incomplete,
1098
+					false,
1099
+					'sentence'
1100
+				),
1101
+			),
1102
+			'not_approved'      => array(
1103
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
1104
+				'desc'  => EEH_Template::pretty_status(
1105
+					EEM_Registration::status_id_not_approved,
1106
+					false,
1107
+					'sentence'
1108
+				),
1109
+			),
1110
+			'declined_status'   => array(
1111
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
1112
+				'desc'  => EEH_Template::pretty_status(
1113
+					EEM_Registration::status_id_declined,
1114
+					false,
1115
+					'sentence'
1116
+				),
1117
+			),
1118
+			'cancelled_status'  => array(
1119
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1120
+				'desc'  => EEH_Template::pretty_status(
1121
+					EEM_Registration::status_id_cancelled,
1122
+					false,
1123
+					'sentence'
1124
+				),
1125
+			),
1126
+		);
1127
+		return array_merge($fc_items, $sc_items);
1128
+	}
1129
+
1130
+
1131
+
1132
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1133
+
1134
+
1135
+
1136
+	/**
1137
+	 * @throws DomainException
1138
+	 * @throws EE_Error
1139
+	 * @throws InvalidArgumentException
1140
+	 * @throws InvalidDataTypeException
1141
+	 * @throws InvalidInterfaceException
1142
+	 * @throws ReflectionException
1143
+	 */
1144
+	protected function _registrations_overview_list_table()
1145
+	{
1146
+		$this->appendAddNewRegistrationButtonToPageTitle();
1147
+		$header_text = '';
1148
+		$admin_page_header_decorators = [
1149
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1150
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1151
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1152
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1153
+		];
1154
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1155
+			$filter_header_decorator = $this->getLoader()->getNew($admin_page_header_decorator);
1156
+			$header_text = $filter_header_decorator->getHeaderText($header_text);
1157
+		}
1158
+		$this->_template_args['admin_page_header'] = $header_text;
1159
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1160
+		$this->display_admin_list_table_page_with_no_sidebar();
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 * @throws EE_Error
1166
+	 * @throws InvalidArgumentException
1167
+	 * @throws InvalidDataTypeException
1168
+	 * @throws InvalidInterfaceException
1169
+	 */
1170
+	private function appendAddNewRegistrationButtonToPageTitle()
1171
+	{
1172
+		$EVT_ID = ! empty($this->_req_data['event_id'])
1173
+			? absint($this->_req_data['event_id'])
1174
+			: 0;
1175
+		if ($EVT_ID
1176
+			&& EE_Registry::instance()->CAP->current_user_can(
1177
+				'ee_edit_registrations',
1178
+				'espresso_registrations_new_registration',
1179
+				$EVT_ID
1180
+			)
1181
+		) {
1182
+			$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1183
+				'new_registration',
1184
+				'add-registrant',
1185
+				array('event_id' => $EVT_ID),
1186
+				'add-new-h2'
1187
+			);
1188
+		}
1189
+	}
1190
+
1191
+
1192
+	/**
1193
+	 * This sets the _registration property for the registration details screen
1194
+	 *
1195
+	 * @access private
1196
+	 * @return bool
1197
+	 * @throws EE_Error
1198
+	 * @throws InvalidArgumentException
1199
+	 * @throws InvalidDataTypeException
1200
+	 * @throws InvalidInterfaceException
1201
+	 */
1202
+	private function _set_registration_object()
1203
+	{
1204
+		// get out if we've already set the object
1205
+		if ($this->_registration instanceof EE_Registration) {
1206
+			return true;
1207
+		}
1208
+		$REG_ID = (! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1209
+		if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1210
+			return true;
1211
+		}
1212
+		$error_msg = sprintf(
1213
+			esc_html__(
1214
+				'An error occurred and the details for Registration ID #%s could not be retrieved.',
1215
+				'event_espresso'
1216
+			),
1217
+			$REG_ID
1218
+		);
1219
+		EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1220
+		$this->_registration = null;
1221
+		return false;
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 * Used to retrieve registrations for the list table.
1227
+	 *
1228
+	 * @param int  $per_page
1229
+	 * @param bool $count
1230
+	 * @param bool $this_month
1231
+	 * @param bool $today
1232
+	 * @return EE_Registration[]|int
1233
+	 * @throws EE_Error
1234
+	 * @throws InvalidArgumentException
1235
+	 * @throws InvalidDataTypeException
1236
+	 * @throws InvalidInterfaceException
1237
+	 */
1238
+	public function get_registrations(
1239
+		$per_page = 10,
1240
+		$count = false,
1241
+		$this_month = false,
1242
+		$today = false
1243
+	) {
1244
+		if ($this_month) {
1245
+			$this->_req_data['status'] = 'month';
1246
+		}
1247
+		if ($today) {
1248
+			$this->_req_data['status'] = 'today';
1249
+		}
1250
+		$query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1251
+		/**
1252
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1253
+		 *
1254
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1255
+		 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1256
+		 *                             or if you have the development copy of EE you can view this at the path:
1257
+		 *                             /docs/G--Model-System/model-query-params.md
1258
+		 */
1259
+		$query_params['group_by'] = '';
1260
+
1261
+		return $count
1262
+			? $this->getRegistrationModel()->count($query_params)
1263
+			/** @type EE_Registration[] */
1264
+			: $this->getRegistrationModel()->get_all($query_params);
1265
+	}
1266
+
1267
+
1268
+	/**
1269
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1270
+	 * Note: this listens to values on the request for some of the query parameters.
1271
+	 *
1272
+	 * @param array $request
1273
+	 * @param int   $per_page
1274
+	 * @param bool  $count
1275
+	 * @return array
1276
+	 * @throws EE_Error
1277
+	 * @throws InvalidArgumentException
1278
+	 * @throws InvalidDataTypeException
1279
+	 * @throws InvalidInterfaceException
1280
+	 */
1281
+	protected function _get_registration_query_parameters(
1282
+		$request = array(),
1283
+		$per_page = 10,
1284
+		$count = false
1285
+	) {
1286
+		/** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1287
+		$list_table_query_builder = $this->getLoader()->getNew(
1288
+			'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1289
+			[ $request ]
1290
+		);
1291
+		return $list_table_query_builder->getQueryParams($per_page, $count);
1292
+	}
1293
+
1294
+
1295
+	public function get_registration_status_array()
1296
+	{
1297
+		return self::$_reg_status;
1298
+	}
1299
+
1300
+
1301
+
1302
+
1303
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1304
+	/**
1305
+	 *        generates HTML for the View Registration Details Admin page
1306
+	 *
1307
+	 * @access protected
1308
+	 * @return void
1309
+	 * @throws DomainException
1310
+	 * @throws EE_Error
1311
+	 * @throws InvalidArgumentException
1312
+	 * @throws InvalidDataTypeException
1313
+	 * @throws InvalidInterfaceException
1314
+	 * @throws EntityNotFoundException
1315
+	 * @throws ReflectionException
1316
+	 */
1317
+	protected function _registration_details()
1318
+	{
1319
+		$this->_template_args = array();
1320
+		$this->_set_registration_object();
1321
+		if (is_object($this->_registration)) {
1322
+			$transaction = $this->_registration->transaction()
1323
+				? $this->_registration->transaction()
1324
+				: EE_Transaction::new_instance();
1325
+			$this->_session = $transaction->session_data();
1326
+			$event_id = $this->_registration->event_ID();
1327
+			$this->_template_args['reg_nmbr']['value'] = $this->_registration->ID();
1328
+			$this->_template_args['reg_nmbr']['label'] = esc_html__('Registration Number', 'event_espresso');
1329
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1330
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1331
+			$this->_template_args['grand_total'] = $transaction->total();
1332
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
1333
+			// link back to overview
1334
+			$this->_template_args['reg_overview_url'] = REG_ADMIN_URL;
1335
+			$this->_template_args['registration'] = $this->_registration;
1336
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1337
+				array(
1338
+					'action'   => 'default',
1339
+					'event_id' => $event_id,
1340
+				),
1341
+				REG_ADMIN_URL
1342
+			);
1343
+			$this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1344
+				array(
1345
+					'action' => 'default',
1346
+					'EVT_ID' => $event_id,
1347
+					'page'   => 'espresso_transactions',
1348
+				),
1349
+				admin_url('admin.php')
1350
+			);
1351
+			$this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1352
+				array(
1353
+					'page'   => 'espresso_events',
1354
+					'action' => 'edit',
1355
+					'post'   => $event_id,
1356
+				),
1357
+				admin_url('admin.php')
1358
+			);
1359
+			// next and previous links
1360
+			$next_reg = $this->_registration->next(
1361
+				null,
1362
+				array(),
1363
+				'REG_ID'
1364
+			);
1365
+			$this->_template_args['next_registration'] = $next_reg
1366
+				? $this->_next_link(
1367
+					EE_Admin_Page::add_query_args_and_nonce(
1368
+						array(
1369
+							'action'  => 'view_registration',
1370
+							'_REG_ID' => $next_reg['REG_ID'],
1371
+						),
1372
+						REG_ADMIN_URL
1373
+					),
1374
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1375
+				)
1376
+				: '';
1377
+			$previous_reg = $this->_registration->previous(
1378
+				null,
1379
+				array(),
1380
+				'REG_ID'
1381
+			);
1382
+			$this->_template_args['previous_registration'] = $previous_reg
1383
+				? $this->_previous_link(
1384
+					EE_Admin_Page::add_query_args_and_nonce(
1385
+						array(
1386
+							'action'  => 'view_registration',
1387
+							'_REG_ID' => $previous_reg['REG_ID'],
1388
+						),
1389
+						REG_ADMIN_URL
1390
+					),
1391
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1392
+				)
1393
+				: '';
1394
+			// grab header
1395
+			$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1396
+			$this->_template_args['REG_ID'] = $this->_registration->ID();
1397
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1398
+				$template_path,
1399
+				$this->_template_args,
1400
+				true
1401
+			);
1402
+		} else {
1403
+			$this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1404
+		}
1405
+		// the details template wrapper
1406
+		$this->display_admin_page_with_sidebar();
1407
+	}
1408
+
1409
+
1410
+	/**
1411
+	 * @throws EE_Error
1412
+	 * @throws InvalidArgumentException
1413
+	 * @throws InvalidDataTypeException
1414
+	 * @throws InvalidInterfaceException
1415
+	 * @throws ReflectionException
1416
+	 * @since 4.10.2.p
1417
+	 */
1418
+	protected function _registration_details_metaboxes()
1419
+	{
1420
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1421
+		$this->_set_registration_object();
1422
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1423
+		add_meta_box(
1424
+			'edit-reg-status-mbox',
1425
+			esc_html__('Registration Status', 'event_espresso'),
1426
+			array($this, 'set_reg_status_buttons_metabox'),
1427
+			$this->wp_page_slug,
1428
+			'normal',
1429
+			'high'
1430
+		);
1431
+		add_meta_box(
1432
+			'edit-reg-details-mbox',
1433
+			esc_html__('Registration Details', 'event_espresso'),
1434
+			array($this, '_reg_details_meta_box'),
1435
+			$this->wp_page_slug,
1436
+			'normal',
1437
+			'high'
1438
+		);
1439
+		if ($attendee instanceof EE_Attendee
1440
+			&& EE_Registry::instance()->CAP->current_user_can(
1441
+				'ee_read_registration',
1442
+				'edit-reg-questions-mbox',
1443
+				$this->_registration->ID()
1444
+			)
1445
+		) {
1446
+			add_meta_box(
1447
+				'edit-reg-questions-mbox',
1448
+				esc_html__('Registration Form Answers', 'event_espresso'),
1449
+				array($this, '_reg_questions_meta_box'),
1450
+				$this->wp_page_slug,
1451
+				'normal',
1452
+				'high'
1453
+			);
1454
+		}
1455
+		add_meta_box(
1456
+			'edit-reg-registrant-mbox',
1457
+			esc_html__('Contact Details', 'event_espresso'),
1458
+			array($this, '_reg_registrant_side_meta_box'),
1459
+			$this->wp_page_slug,
1460
+			'side',
1461
+			'high'
1462
+		);
1463
+		if ($this->_registration->group_size() > 1) {
1464
+			add_meta_box(
1465
+				'edit-reg-attendees-mbox',
1466
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1467
+				array($this, '_reg_attendees_meta_box'),
1468
+				$this->wp_page_slug,
1469
+				'normal',
1470
+				'high'
1471
+			);
1472
+		}
1473
+	}
1474
+
1475
+
1476
+	/**
1477
+	 * set_reg_status_buttons_metabox
1478
+	 *
1479
+	 * @access protected
1480
+	 * @return string
1481
+	 * @throws EE_Error
1482
+	 * @throws EntityNotFoundException
1483
+	 * @throws InvalidArgumentException
1484
+	 * @throws InvalidDataTypeException
1485
+	 * @throws InvalidInterfaceException
1486
+	 * @throws ReflectionException
1487
+	 */
1488
+	public function set_reg_status_buttons_metabox()
1489
+	{
1490
+		$this->_set_registration_object();
1491
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1492
+		echo $change_reg_status_form->form_open(
1493
+			self::add_query_args_and_nonce(
1494
+				array(
1495
+					'action' => 'change_reg_status',
1496
+				),
1497
+				REG_ADMIN_URL
1498
+			)
1499
+		);
1500
+		echo $change_reg_status_form->get_html();
1501
+		echo $change_reg_status_form->form_close();
1502
+	}
1503
+
1504
+
1505
+	/**
1506
+	 * @return EE_Form_Section_Proper
1507
+	 * @throws EE_Error
1508
+	 * @throws InvalidArgumentException
1509
+	 * @throws InvalidDataTypeException
1510
+	 * @throws InvalidInterfaceException
1511
+	 * @throws EntityNotFoundException
1512
+	 * @throws ReflectionException
1513
+	 */
1514
+	protected function _generate_reg_status_change_form()
1515
+	{
1516
+		$reg_status_change_form_array = array(
1517
+			'name'            => 'reg_status_change_form',
1518
+			'html_id'         => 'reg-status-change-form',
1519
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1520
+			'subsections'     => array(
1521
+				'return'             => new EE_Hidden_Input(
1522
+					array(
1523
+						'name'    => 'return',
1524
+						'default' => 'view_registration',
1525
+					)
1526
+				),
1527
+				'REG_ID'             => new EE_Hidden_Input(
1528
+					array(
1529
+						'name'    => 'REG_ID',
1530
+						'default' => $this->_registration->ID(),
1531
+					)
1532
+				),
1533
+				'current_status'     => new EE_Form_Section_HTML(
1534
+					EEH_HTML::table(
1535
+						EEH_HTML::tr(
1536
+							EEH_HTML::th(
1537
+								EEH_HTML::label(
1538
+									EEH_HTML::strong(
1539
+										esc_html__('Current Registration Status', 'event_espresso')
1540
+									)
1541
+								)
1542
+							)
1543
+							. EEH_HTML::td(
1544
+								EEH_HTML::strong(
1545
+									$this->_registration->pretty_status(),
1546
+									'',
1547
+									'status-' . $this->_registration->status_ID(),
1548
+									'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1549
+								)
1550
+							)
1551
+						)
1552
+					)
1553
+				)
1554
+			)
1555
+		);
1556
+		if (EE_Registry::instance()->CAP->current_user_can(
1557
+			'ee_edit_registration',
1558
+			'toggle_registration_status',
1559
+			$this->_registration->ID()
1560
+		)) {
1561
+			$reg_status_change_form_array['subsections']['reg_status'] = new EE_Select_Input(
1562
+				$this->_get_reg_statuses(),
1563
+				array(
1564
+					'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1565
+					'default'         => $this->_registration->status_ID(),
1566
+				)
1567
+			);
1568
+			$reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1569
+				array(
1570
+					'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1571
+					'default'         => false,
1572
+					'html_help_text'  => esc_html__(
1573
+						'If set to "Yes", then the related messages will be sent to the registrant.',
1574
+						'event_espresso'
1575
+					)
1576
+				)
1577
+			);
1578
+			$reg_status_change_form_array['subsections']['submit'] = new EE_Submit_Input(
1579
+				array(
1580
+					'html_class'      => 'button-primary',
1581
+					'html_label_text' => '&nbsp;',
1582
+					'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1583
+				)
1584
+			);
1585
+		}
1586
+		return new EE_Form_Section_Proper($reg_status_change_form_array);
1587
+	}
1588
+
1589
+
1590
+	/**
1591
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1592
+	 *
1593
+	 * @return array
1594
+	 * @throws EE_Error
1595
+	 * @throws InvalidArgumentException
1596
+	 * @throws InvalidDataTypeException
1597
+	 * @throws InvalidInterfaceException
1598
+	 * @throws EntityNotFoundException
1599
+	 */
1600
+	protected function _get_reg_statuses()
1601
+	{
1602
+		$reg_status_array = $this->getRegistrationModel()->reg_status_array();
1603
+		unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1604
+		// get current reg status
1605
+		$current_status = $this->_registration->status_ID();
1606
+		// is registration for free event? This will determine whether to display the pending payment option
1607
+		if ($current_status !== EEM_Registration::status_id_pending_payment
1608
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1609
+		) {
1610
+			unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1611
+		}
1612
+		return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1613
+	}
1614
+
1615
+
1616
+	/**
1617
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1618
+	 *
1619
+	 * @param bool $status REG status given for changing registrations to.
1620
+	 * @param bool $notify Whether to send messages notifications or not.
1621
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1622
+	 * @throws DomainException
1623
+	 * @throws EE_Error
1624
+	 * @throws EntityNotFoundException
1625
+	 * @throws InvalidArgumentException
1626
+	 * @throws InvalidDataTypeException
1627
+	 * @throws InvalidInterfaceException
1628
+	 * @throws ReflectionException
1629
+	 * @throws RuntimeException
1630
+	 */
1631
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1632
+	{
1633
+		if (isset($this->_req_data['reg_status_change_form'])) {
1634
+			$REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1635
+				? (array) $this->_req_data['reg_status_change_form']['REG_ID']
1636
+				: array();
1637
+		} else {
1638
+			$REG_IDs = isset($this->_req_data['_REG_ID'])
1639
+				? (array) $this->_req_data['_REG_ID']
1640
+				: array();
1641
+		}
1642
+		// sanitize $REG_IDs
1643
+		$REG_IDs = array_map('absint', $REG_IDs);
1644
+		// and remove empty entries
1645
+		$REG_IDs = array_filter($REG_IDs);
1646
+
1647
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1648
+
1649
+		/**
1650
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1651
+		 * Currently this value is used downstream by the _process_resend_registration method.
1652
+		 *
1653
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1654
+		 * @param bool                     $status           The status registrations were changed to.
1655
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1656
+		 * @param Registrations_Admin_Page $admin_page_object
1657
+		 */
1658
+		$this->_req_data['_REG_ID'] = apply_filters(
1659
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1660
+			$result['REG_ID'],
1661
+			$status,
1662
+			$result['success'],
1663
+			$this
1664
+		);
1665
+
1666
+		// notify?
1667
+		if ($notify
1668
+			&& $result['success']
1669
+			&& ! empty($this->_req_data['_REG_ID'])
1670
+			&& EE_Registry::instance()->CAP->current_user_can(
1671
+				'ee_send_message',
1672
+				'espresso_registrations_resend_registration'
1673
+			)
1674
+		) {
1675
+			$this->_process_resend_registration();
1676
+		}
1677
+		return $result;
1678
+	}
1679
+
1680
+
1681
+	/**
1682
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1683
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1684
+	 *
1685
+	 * @param array  $REG_IDs
1686
+	 * @param string $status
1687
+	 * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1688
+	 *                        slug sent with setting the registration status.
1689
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1690
+	 * @throws EE_Error
1691
+	 * @throws InvalidArgumentException
1692
+	 * @throws InvalidDataTypeException
1693
+	 * @throws InvalidInterfaceException
1694
+	 * @throws ReflectionException
1695
+	 * @throws RuntimeException
1696
+	 * @throws EntityNotFoundException
1697
+	 * @throws DomainException
1698
+	 */
1699
+	protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1700
+	{
1701
+		$success = false;
1702
+		// typecast $REG_IDs
1703
+		$REG_IDs = (array) $REG_IDs;
1704
+		if (! empty($REG_IDs)) {
1705
+			$success = true;
1706
+			// set default status if none is passed
1707
+			$status = $status ? $status : EEM_Registration::status_id_pending_payment;
1708
+			$status_context = $notify
1709
+				? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1710
+				: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1711
+			// loop through REG_ID's and change status
1712
+			foreach ($REG_IDs as $REG_ID) {
1713
+				$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1714
+				if ($registration instanceof EE_Registration) {
1715
+					$registration->set_status(
1716
+						$status,
1717
+						false,
1718
+						new Context(
1719
+							$status_context,
1720
+							esc_html__(
1721
+								'Manually triggered status change on a Registration Admin Page route.',
1722
+								'event_espresso'
1723
+							)
1724
+						)
1725
+					);
1726
+					$result = $registration->save();
1727
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1728
+					$success = $result !== false ? $success : false;
1729
+				}
1730
+			}
1731
+		}
1732
+
1733
+		// return $success and processed registrations
1734
+		return array('REG_ID' => $REG_IDs, 'success' => $success);
1735
+	}
1736
+
1737
+
1738
+	/**
1739
+	 * Common logic for setting up success message and redirecting to appropriate route
1740
+	 *
1741
+	 * @param string $STS_ID status id for the registration changed to
1742
+	 * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1743
+	 * @return void
1744
+	 * @throws DomainException
1745
+	 * @throws EE_Error
1746
+	 * @throws EntityNotFoundException
1747
+	 * @throws InvalidArgumentException
1748
+	 * @throws InvalidDataTypeException
1749
+	 * @throws InvalidInterfaceException
1750
+	 * @throws ReflectionException
1751
+	 * @throws RuntimeException
1752
+	 */
1753
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1754
+	{
1755
+		$result = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1756
+			: array('success' => false);
1757
+		$success = isset($result['success']) && $result['success'];
1758
+		// setup success message
1759
+		if ($success) {
1760
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1761
+				$msg = sprintf(
1762
+					esc_html__('Registration status has been set to %s', 'event_espresso'),
1763
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1764
+				);
1765
+			} else {
1766
+				$msg = sprintf(
1767
+					esc_html__('Registrations have been set to %s.', 'event_espresso'),
1768
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1769
+				);
1770
+			}
1771
+			EE_Error::add_success($msg);
1772
+		} else {
1773
+			EE_Error::add_error(
1774
+				esc_html__(
1775
+					'Something went wrong, and the status was not changed',
1776
+					'event_espresso'
1777
+				),
1778
+				__FILE__,
1779
+				__LINE__,
1780
+				__FUNCTION__
1781
+			);
1782
+		}
1783
+		if (isset($this->_req_data['return']) && $this->_req_data['return'] === 'view_registration') {
1784
+			$route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1785
+		} else {
1786
+			$route = array('action' => 'default');
1787
+		}
1788
+		$route = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1789
+		$this->_redirect_after_action($success, '', '', $route, true);
1790
+	}
1791
+
1792
+
1793
+	/**
1794
+	 * incoming reg status change from reg details page.
1795
+	 *
1796
+	 * @return void
1797
+	 * @throws EE_Error
1798
+	 * @throws EntityNotFoundException
1799
+	 * @throws InvalidArgumentException
1800
+	 * @throws InvalidDataTypeException
1801
+	 * @throws InvalidInterfaceException
1802
+	 * @throws ReflectionException
1803
+	 * @throws RuntimeException
1804
+	 * @throws DomainException
1805
+	 */
1806
+	protected function _change_reg_status()
1807
+	{
1808
+		$this->_req_data['return'] = 'view_registration';
1809
+		// set notify based on whether the send notifications toggle is set or not
1810
+		$notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1811
+		// $notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1812
+		$this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1813
+			? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1814
+		switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1815
+			case EEM_Registration::status_id_approved:
1816
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1817
+				$this->approve_registration($notify);
1818
+				break;
1819
+			case EEM_Registration::status_id_pending_payment:
1820
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1821
+				$this->pending_registration($notify);
1822
+				break;
1823
+			case EEM_Registration::status_id_not_approved:
1824
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1825
+				$this->not_approve_registration($notify);
1826
+				break;
1827
+			case EEM_Registration::status_id_declined:
1828
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1829
+				$this->decline_registration($notify);
1830
+				break;
1831
+			case EEM_Registration::status_id_cancelled:
1832
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1833
+				$this->cancel_registration($notify);
1834
+				break;
1835
+			case EEM_Registration::status_id_wait_list:
1836
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1837
+				$this->wait_list_registration($notify);
1838
+				break;
1839
+			case EEM_Registration::status_id_incomplete:
1840
+			default:
1841
+				$result['success'] = false;
1842
+				unset($this->_req_data['return']);
1843
+				$this->_reg_status_change_return('', false);
1844
+				break;
1845
+		}
1846
+	}
1847
+
1848
+
1849
+	/**
1850
+	 * Callback for bulk action routes.
1851
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1852
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
1853
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1854
+	 * when an action is happening on just a single registration).
1855
+	 *
1856
+	 * @param      $action
1857
+	 * @param bool $notify
1858
+	 */
1859
+	protected function bulk_action_on_registrations($action, $notify = false)
1860
+	{
1861
+		do_action(
1862
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1863
+			$this,
1864
+			$action,
1865
+			$notify
1866
+		);
1867
+		$method = $action . '_registration';
1868
+		if (method_exists($this, $method)) {
1869
+			$this->$method($notify);
1870
+		}
1871
+	}
1872
+
1873
+
1874
+	/**
1875
+	 * approve_registration
1876
+	 *
1877
+	 * @access protected
1878
+	 * @param bool $notify whether or not to notify the registrant about their approval.
1879
+	 * @return void
1880
+	 * @throws EE_Error
1881
+	 * @throws EntityNotFoundException
1882
+	 * @throws InvalidArgumentException
1883
+	 * @throws InvalidDataTypeException
1884
+	 * @throws InvalidInterfaceException
1885
+	 * @throws ReflectionException
1886
+	 * @throws RuntimeException
1887
+	 * @throws DomainException
1888
+	 */
1889
+	protected function approve_registration($notify = false)
1890
+	{
1891
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1892
+	}
1893
+
1894
+
1895
+	/**
1896
+	 *        decline_registration
1897
+	 *
1898
+	 * @access protected
1899
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1900
+	 * @return void
1901
+	 * @throws EE_Error
1902
+	 * @throws EntityNotFoundException
1903
+	 * @throws InvalidArgumentException
1904
+	 * @throws InvalidDataTypeException
1905
+	 * @throws InvalidInterfaceException
1906
+	 * @throws ReflectionException
1907
+	 * @throws RuntimeException
1908
+	 * @throws DomainException
1909
+	 */
1910
+	protected function decline_registration($notify = false)
1911
+	{
1912
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1913
+	}
1914
+
1915
+
1916
+	/**
1917
+	 *        cancel_registration
1918
+	 *
1919
+	 * @access protected
1920
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1921
+	 * @return void
1922
+	 * @throws EE_Error
1923
+	 * @throws EntityNotFoundException
1924
+	 * @throws InvalidArgumentException
1925
+	 * @throws InvalidDataTypeException
1926
+	 * @throws InvalidInterfaceException
1927
+	 * @throws ReflectionException
1928
+	 * @throws RuntimeException
1929
+	 * @throws DomainException
1930
+	 */
1931
+	protected function cancel_registration($notify = false)
1932
+	{
1933
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1934
+	}
1935
+
1936
+
1937
+	/**
1938
+	 *        not_approve_registration
1939
+	 *
1940
+	 * @access protected
1941
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1942
+	 * @return void
1943
+	 * @throws EE_Error
1944
+	 * @throws EntityNotFoundException
1945
+	 * @throws InvalidArgumentException
1946
+	 * @throws InvalidDataTypeException
1947
+	 * @throws InvalidInterfaceException
1948
+	 * @throws ReflectionException
1949
+	 * @throws RuntimeException
1950
+	 * @throws DomainException
1951
+	 */
1952
+	protected function not_approve_registration($notify = false)
1953
+	{
1954
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1955
+	}
1956
+
1957
+
1958
+	/**
1959
+	 *        decline_registration
1960
+	 *
1961
+	 * @access protected
1962
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1963
+	 * @return void
1964
+	 * @throws EE_Error
1965
+	 * @throws EntityNotFoundException
1966
+	 * @throws InvalidArgumentException
1967
+	 * @throws InvalidDataTypeException
1968
+	 * @throws InvalidInterfaceException
1969
+	 * @throws ReflectionException
1970
+	 * @throws RuntimeException
1971
+	 * @throws DomainException
1972
+	 */
1973
+	protected function pending_registration($notify = false)
1974
+	{
1975
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1976
+	}
1977
+
1978
+
1979
+	/**
1980
+	 * waitlist_registration
1981
+	 *
1982
+	 * @access protected
1983
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1984
+	 * @return void
1985
+	 * @throws EE_Error
1986
+	 * @throws EntityNotFoundException
1987
+	 * @throws InvalidArgumentException
1988
+	 * @throws InvalidDataTypeException
1989
+	 * @throws InvalidInterfaceException
1990
+	 * @throws ReflectionException
1991
+	 * @throws RuntimeException
1992
+	 * @throws DomainException
1993
+	 */
1994
+	protected function wait_list_registration($notify = false)
1995
+	{
1996
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1997
+	}
1998
+
1999
+
2000
+	/**
2001
+	 *        generates HTML for the Registration main meta box
2002
+	 *
2003
+	 * @access public
2004
+	 * @return void
2005
+	 * @throws DomainException
2006
+	 * @throws EE_Error
2007
+	 * @throws InvalidArgumentException
2008
+	 * @throws InvalidDataTypeException
2009
+	 * @throws InvalidInterfaceException
2010
+	 * @throws ReflectionException
2011
+	 * @throws EntityNotFoundException
2012
+	 */
2013
+	public function _reg_details_meta_box()
2014
+	{
2015
+		EEH_Autoloader::register_line_item_display_autoloaders();
2016
+		EEH_Autoloader::register_line_item_filter_autoloaders();
2017
+		EE_Registry::instance()->load_helper('Line_Item');
2018
+		$transaction = $this->_registration->transaction() ? $this->_registration->transaction()
2019
+			: EE_Transaction::new_instance();
2020
+		$this->_session = $transaction->session_data();
2021
+		$filters = new EE_Line_Item_Filter_Collection();
2022
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2023
+		$filters->add(new EE_Non_Zero_Line_Item_Filter());
2024
+		$line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2025
+			$filters,
2026
+			$transaction->total_line_item()
2027
+		);
2028
+		$filtered_line_item_tree = $line_item_filter_processor->process();
2029
+		$line_item_display = new EE_Line_Item_Display(
2030
+			'reg_admin_table',
2031
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2032
+		);
2033
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2034
+			$filtered_line_item_tree,
2035
+			array('EE_Registration' => $this->_registration)
2036
+		);
2037
+		$attendee = $this->_registration->attendee();
2038
+		if (EE_Registry::instance()->CAP->current_user_can(
2039
+			'ee_read_transaction',
2040
+			'espresso_transactions_view_transaction'
2041
+		)) {
2042
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2043
+				EE_Admin_Page::add_query_args_and_nonce(
2044
+					array(
2045
+						'action' => 'view_transaction',
2046
+						'TXN_ID' => $transaction->ID(),
2047
+					),
2048
+					TXN_ADMIN_URL
2049
+				),
2050
+				esc_html__(' View Transaction', 'event_espresso'),
2051
+				'button secondary-button right',
2052
+				'dashicons dashicons-cart'
2053
+			);
2054
+		} else {
2055
+			$this->_template_args['view_transaction_button'] = '';
2056
+		}
2057
+		if ($attendee instanceof EE_Attendee
2058
+			&& EE_Registry::instance()->CAP->current_user_can(
2059
+				'ee_send_message',
2060
+				'espresso_registrations_resend_registration'
2061
+			)
2062
+		) {
2063
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2064
+				EE_Admin_Page::add_query_args_and_nonce(
2065
+					array(
2066
+						'action'      => 'resend_registration',
2067
+						'_REG_ID'     => $this->_registration->ID(),
2068
+						'redirect_to' => 'view_registration',
2069
+					),
2070
+					REG_ADMIN_URL
2071
+				),
2072
+				esc_html__(' Resend Registration', 'event_espresso'),
2073
+				'button secondary-button right',
2074
+				'dashicons dashicons-email-alt'
2075
+			);
2076
+		} else {
2077
+			$this->_template_args['resend_registration_button'] = '';
2078
+		}
2079
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2080
+		$payment = $transaction->get_first_related('Payment');
2081
+		$payment = ! $payment instanceof EE_Payment
2082
+			? EE_Payment::new_instance()
2083
+			: $payment;
2084
+		$payment_method = $payment->get_first_related('Payment_Method');
2085
+		$payment_method = ! $payment_method instanceof EE_Payment_Method
2086
+			? EE_Payment_Method::new_instance()
2087
+			: $payment_method;
2088
+		$reg_details = array(
2089
+			'payment_method'       => $payment_method->name(),
2090
+			'response_msg'         => $payment->gateway_response(),
2091
+			'registration_id'      => $this->_registration->get('REG_code'),
2092
+			'registration_session' => $this->_registration->session_ID(),
2093
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2094
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2095
+		);
2096
+		if (isset($reg_details['registration_id'])) {
2097
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2098
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2099
+				'Registration ID',
2100
+				'event_espresso'
2101
+			);
2102
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2103
+		}
2104
+		if (isset($reg_details['payment_method'])) {
2105
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2106
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2107
+				'Most Recent Payment Method',
2108
+				'event_espresso'
2109
+			);
2110
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2111
+			$this->_template_args['reg_details']['response_msg']['value'] = $reg_details['response_msg'];
2112
+			$this->_template_args['reg_details']['response_msg']['label'] = esc_html__(
2113
+				'Payment method response',
2114
+				'event_espresso'
2115
+			);
2116
+			$this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2117
+		}
2118
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2119
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2120
+			'Registration Session',
2121
+			'event_espresso'
2122
+		);
2123
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2124
+		$this->_template_args['reg_details']['ip_address']['value'] = $reg_details['ip_address'];
2125
+		$this->_template_args['reg_details']['ip_address']['label'] = esc_html__(
2126
+			'Registration placed from IP',
2127
+			'event_espresso'
2128
+		);
2129
+		$this->_template_args['reg_details']['ip_address']['class'] = 'regular-text';
2130
+		$this->_template_args['reg_details']['user_agent']['value'] = $reg_details['user_agent'];
2131
+		$this->_template_args['reg_details']['user_agent']['label'] = esc_html__(
2132
+			'Registrant User Agent',
2133
+			'event_espresso'
2134
+		);
2135
+		$this->_template_args['reg_details']['user_agent']['class'] = 'large-text';
2136
+		$this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
2137
+			array(
2138
+				'action'   => 'default',
2139
+				'event_id' => $this->_registration->event_ID(),
2140
+			),
2141
+			REG_ADMIN_URL
2142
+		);
2143
+		$this->_template_args['REG_ID'] = $this->_registration->ID();
2144
+		$this->_template_args['event_id'] = $this->_registration->event_ID();
2145
+		$template_path =
2146
+			REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2147
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2148
+	}
2149
+
2150
+
2151
+	/**
2152
+	 * generates HTML for the Registration Questions meta box.
2153
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2154
+	 * otherwise uses new forms system
2155
+	 *
2156
+	 * @access public
2157
+	 * @return void
2158
+	 * @throws DomainException
2159
+	 * @throws EE_Error
2160
+	 * @throws InvalidArgumentException
2161
+	 * @throws InvalidDataTypeException
2162
+	 * @throws InvalidInterfaceException
2163
+	 * @throws ReflectionException
2164
+	 */
2165
+	public function _reg_questions_meta_box()
2166
+	{
2167
+		// allow someone to override this method entirely
2168
+		if (apply_filters(
2169
+			'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2170
+			true,
2171
+			$this,
2172
+			$this->_registration
2173
+		)) {
2174
+			$form = $this->_get_reg_custom_questions_form(
2175
+				$this->_registration->ID()
2176
+			);
2177
+			$this->_template_args['att_questions'] = count($form->subforms()) > 0
2178
+				? $form->get_html_and_js()
2179
+				: '';
2180
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2181
+			$this->_template_args['REG_ID'] = $this->_registration->ID();
2182
+			$template_path =
2183
+				REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2184
+			echo EEH_Template::display_template($template_path, $this->_template_args, true);
2185
+		}
2186
+	}
2187
+
2188
+
2189
+	/**
2190
+	 * form_before_question_group
2191
+	 *
2192
+	 * @deprecated    as of 4.8.32.rc.000
2193
+	 * @access        public
2194
+	 * @param        string $output
2195
+	 * @return        string
2196
+	 */
2197
+	public function form_before_question_group($output)
2198
+	{
2199
+		EE_Error::doing_it_wrong(
2200
+			__CLASS__ . '::' . __FUNCTION__,
2201
+			esc_html__(
2202
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2203
+				'event_espresso'
2204
+			),
2205
+			'4.8.32.rc.000'
2206
+		);
2207
+		return '
2208 2208
 	<table class="form-table ee-width-100">
2209 2209
 		<tbody>
2210 2210
 			';
2211
-    }
2212
-
2213
-
2214
-    /**
2215
-     * form_after_question_group
2216
-     *
2217
-     * @deprecated    as of 4.8.32.rc.000
2218
-     * @access        public
2219
-     * @param        string $output
2220
-     * @return        string
2221
-     */
2222
-    public function form_after_question_group($output)
2223
-    {
2224
-        EE_Error::doing_it_wrong(
2225
-            __CLASS__ . '::' . __FUNCTION__,
2226
-            esc_html__(
2227
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2228
-                'event_espresso'
2229
-            ),
2230
-            '4.8.32.rc.000'
2231
-        );
2232
-        return '
2211
+	}
2212
+
2213
+
2214
+	/**
2215
+	 * form_after_question_group
2216
+	 *
2217
+	 * @deprecated    as of 4.8.32.rc.000
2218
+	 * @access        public
2219
+	 * @param        string $output
2220
+	 * @return        string
2221
+	 */
2222
+	public function form_after_question_group($output)
2223
+	{
2224
+		EE_Error::doing_it_wrong(
2225
+			__CLASS__ . '::' . __FUNCTION__,
2226
+			esc_html__(
2227
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2228
+				'event_espresso'
2229
+			),
2230
+			'4.8.32.rc.000'
2231
+		);
2232
+		return '
2233 2233
 			<tr class="hide-if-no-js">
2234 2234
 				<th> </th>
2235 2235
 				<td class="reg-admin-edit-attendee-question-td">
2236 2236
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" title="'
2237
-               . esc_attr__('click to edit question', 'event_espresso')
2238
-               . '">
2237
+			   . esc_attr__('click to edit question', 'event_espresso')
2238
+			   . '">
2239 2239
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2240
-               . esc_html__('edit the above question group', 'event_espresso')
2241
-               . '</span>
2240
+			   . esc_html__('edit the above question group', 'event_espresso')
2241
+			   . '</span>
2242 2242
 						<div class="dashicons dashicons-edit"></div>
2243 2243
 					</a>
2244 2244
 				</td>
@@ -2246,627 +2246,627 @@  discard block
 block discarded – undo
2246 2246
 		</tbody>
2247 2247
 	</table>
2248 2248
 ';
2249
-    }
2250
-
2251
-
2252
-    /**
2253
-     * form_form_field_label_wrap
2254
-     *
2255
-     * @deprecated    as of 4.8.32.rc.000
2256
-     * @access        public
2257
-     * @param        string $label
2258
-     * @return        string
2259
-     */
2260
-    public function form_form_field_label_wrap($label)
2261
-    {
2262
-        EE_Error::doing_it_wrong(
2263
-            __CLASS__ . '::' . __FUNCTION__,
2264
-            esc_html__(
2265
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2266
-                'event_espresso'
2267
-            ),
2268
-            '4.8.32.rc.000'
2269
-        );
2270
-        return '
2249
+	}
2250
+
2251
+
2252
+	/**
2253
+	 * form_form_field_label_wrap
2254
+	 *
2255
+	 * @deprecated    as of 4.8.32.rc.000
2256
+	 * @access        public
2257
+	 * @param        string $label
2258
+	 * @return        string
2259
+	 */
2260
+	public function form_form_field_label_wrap($label)
2261
+	{
2262
+		EE_Error::doing_it_wrong(
2263
+			__CLASS__ . '::' . __FUNCTION__,
2264
+			esc_html__(
2265
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2266
+				'event_espresso'
2267
+			),
2268
+			'4.8.32.rc.000'
2269
+		);
2270
+		return '
2271 2271
 			<tr>
2272 2272
 				<th>
2273 2273
 					' . $label . '
2274 2274
 				</th>';
2275
-    }
2276
-
2277
-
2278
-    /**
2279
-     * form_form_field_input__wrap
2280
-     *
2281
-     * @deprecated    as of 4.8.32.rc.000
2282
-     * @access        public
2283
-     * @param        string $input
2284
-     * @return        string
2285
-     */
2286
-    public function form_form_field_input__wrap($input)
2287
-    {
2288
-        EE_Error::doing_it_wrong(
2289
-            __CLASS__ . '::' . __FUNCTION__,
2290
-            esc_html__(
2291
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2292
-                'event_espresso'
2293
-            ),
2294
-            '4.8.32.rc.000'
2295
-        );
2296
-        return '
2275
+	}
2276
+
2277
+
2278
+	/**
2279
+	 * form_form_field_input__wrap
2280
+	 *
2281
+	 * @deprecated    as of 4.8.32.rc.000
2282
+	 * @access        public
2283
+	 * @param        string $input
2284
+	 * @return        string
2285
+	 */
2286
+	public function form_form_field_input__wrap($input)
2287
+	{
2288
+		EE_Error::doing_it_wrong(
2289
+			__CLASS__ . '::' . __FUNCTION__,
2290
+			esc_html__(
2291
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2292
+				'event_espresso'
2293
+			),
2294
+			'4.8.32.rc.000'
2295
+		);
2296
+		return '
2297 2297
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2298 2298
 					' . $input . '
2299 2299
 				</td>
2300 2300
 			</tr>';
2301
-    }
2302
-
2303
-
2304
-    /**
2305
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2306
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2307
-     * to display the page
2308
-     *
2309
-     * @access protected
2310
-     * @return void
2311
-     * @throws EE_Error
2312
-     * @throws InvalidArgumentException
2313
-     * @throws InvalidDataTypeException
2314
-     * @throws InvalidInterfaceException
2315
-     * @throws ReflectionException
2316
-     */
2317
-    protected function _update_attendee_registration_form()
2318
-    {
2319
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2320
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2321
-            $REG_ID = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2322
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2323
-            if ($success) {
2324
-                $what = esc_html__('Registration Form', 'event_espresso');
2325
-                $route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2326
-                    : array('action' => 'default');
2327
-                $this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2328
-            }
2329
-        }
2330
-    }
2331
-
2332
-
2333
-    /**
2334
-     * Gets the form for saving registrations custom questions (if done
2335
-     * previously retrieves the cached form object, which may have validation errors in it)
2336
-     *
2337
-     * @param int $REG_ID
2338
-     * @return EE_Registration_Custom_Questions_Form
2339
-     * @throws EE_Error
2340
-     * @throws InvalidArgumentException
2341
-     * @throws InvalidDataTypeException
2342
-     * @throws InvalidInterfaceException
2343
-     */
2344
-    protected function _get_reg_custom_questions_form($REG_ID)
2345
-    {
2346
-        if (! $this->_reg_custom_questions_form) {
2347
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2348
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2349
-                $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2350
-            );
2351
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2352
-        }
2353
-        return $this->_reg_custom_questions_form;
2354
-    }
2355
-
2356
-
2357
-    /**
2358
-     * Saves
2359
-     *
2360
-     * @access private
2361
-     * @param bool $REG_ID
2362
-     * @return bool
2363
-     * @throws EE_Error
2364
-     * @throws InvalidArgumentException
2365
-     * @throws InvalidDataTypeException
2366
-     * @throws InvalidInterfaceException
2367
-     * @throws ReflectionException
2368
-     */
2369
-    private function _save_reg_custom_questions_form($REG_ID = false)
2370
-    {
2371
-        if (! $REG_ID) {
2372
-            EE_Error::add_error(
2373
-                esc_html__(
2374
-                    'An error occurred. No registration ID was received.',
2375
-                    'event_espresso'
2376
-                ),
2377
-                __FILE__,
2378
-                __FUNCTION__,
2379
-                __LINE__
2380
-            );
2381
-        }
2382
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2383
-        $form->receive_form_submission($this->_req_data);
2384
-        $success = false;
2385
-        if ($form->is_valid()) {
2386
-            foreach ($form->subforms() as $question_group_id => $question_group_form) {
2387
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2388
-                    $where_conditions = array(
2389
-                        'QST_ID' => $question_id,
2390
-                        'REG_ID' => $REG_ID,
2391
-                    );
2392
-                    $possibly_new_values = array(
2393
-                        'ANS_value' => $input->normalized_value(),
2394
-                    );
2395
-                    $answer = EEM_Answer::instance()->get_one(array($where_conditions));
2396
-                    if ($answer instanceof EE_Answer) {
2397
-                        $success = $answer->save($possibly_new_values);
2398
-                    } else {
2399
-                        // insert it then
2400
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2401
-                        $answer = EE_Answer::new_instance($cols_n_vals);
2402
-                        $success = $answer->save();
2403
-                    }
2404
-                }
2405
-            }
2406
-        } else {
2407
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2408
-        }
2409
-        return $success;
2410
-    }
2411
-
2412
-
2413
-    /**
2414
-     *        generates HTML for the Registration main meta box
2415
-     *
2416
-     * @access public
2417
-     * @return void
2418
-     * @throws DomainException
2419
-     * @throws EE_Error
2420
-     * @throws InvalidArgumentException
2421
-     * @throws InvalidDataTypeException
2422
-     * @throws InvalidInterfaceException
2423
-     * @throws ReflectionException
2424
-     */
2425
-    public function _reg_attendees_meta_box()
2426
-    {
2427
-        $REG = $this->getRegistrationModel();
2428
-        // get all other registrations on this transaction, and cache
2429
-        // the attendees for them so we don't have to run another query using force_join
2430
-        $registrations = $REG->get_all(
2431
-            array(
2432
-                array(
2433
-                    'TXN_ID' => $this->_registration->transaction_ID(),
2434
-                    'REG_ID' => array('!=', $this->_registration->ID()),
2435
-                ),
2436
-                'force_join' => array('Attendee'),
2437
-                'default_where_conditions' => 'other_models_only',
2438
-            )
2439
-        );
2440
-        $this->_template_args['attendees'] = array();
2441
-        $this->_template_args['attendee_notice'] = '';
2442
-        if (empty($registrations)
2443
-            || (is_array($registrations)
2444
-                && ! EEH_Array::get_one_item_from_array($registrations))
2445
-        ) {
2446
-            EE_Error::add_error(
2447
-                esc_html__(
2448
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2449
-                    'event_espresso'
2450
-                ),
2451
-                __FILE__,
2452
-                __FUNCTION__,
2453
-                __LINE__
2454
-            );
2455
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2456
-        } else {
2457
-            $att_nmbr = 1;
2458
-            foreach ($registrations as $registration) {
2459
-                /* @var $registration EE_Registration */
2460
-                $attendee = $registration->attendee()
2461
-                    ? $registration->attendee()
2462
-                    : $this->getAttendeeModel()->create_default_object();
2463
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID'] = $registration->status_ID();
2464
-                $this->_template_args['attendees'][ $att_nmbr ]['fname'] = $attendee->fname();
2465
-                $this->_template_args['attendees'][ $att_nmbr ]['lname'] = $attendee->lname();
2466
-                $this->_template_args['attendees'][ $att_nmbr ]['email'] = $attendee->email();
2467
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
-                $this->_template_args['attendees'][ $att_nmbr ]['address'] = implode(
2469
-                    ', ',
2470
-                    $attendee->full_address_as_array()
2471
-                );
2472
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link'] = self::add_query_args_and_nonce(
2473
-                    array(
2474
-                        'action' => 'edit_attendee',
2475
-                        'post'   => $attendee->ID(),
2476
-                    ),
2477
-                    REG_ADMIN_URL
2478
-                );
2479
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name'] = $registration->event_obj() instanceof EE_Event
2480
-                    ? $registration->event_obj()->name()
2481
-                    : '';
2482
-                $att_nmbr++;
2483
-            }
2484
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2485
-        }
2486
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2487
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2488
-    }
2489
-
2490
-
2491
-    /**
2492
-     *        generates HTML for the Edit Registration side meta box
2493
-     *
2494
-     * @access public
2495
-     * @return void
2496
-     * @throws DomainException
2497
-     * @throws EE_Error
2498
-     * @throws InvalidArgumentException
2499
-     * @throws InvalidDataTypeException
2500
-     * @throws InvalidInterfaceException
2501
-     * @throws ReflectionException
2502
-     */
2503
-    public function _reg_registrant_side_meta_box()
2504
-    {
2505
-        /*@var $attendee EE_Attendee */
2506
-        $att_check = $this->_registration->attendee();
2507
-        $attendee = $att_check instanceof EE_Attendee
2508
-            ? $att_check
2509
-            : $this->getAttendeeModel()->create_default_object();
2510
-        // now let's determine if this is not the primary registration.  If it isn't then we set the
2511
-        // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512
-        // primary registration object (that way we know if we need to show create button or not)
2513
-        if (! $this->_registration->is_primary_registrant()) {
2514
-            $primary_registration = $this->_registration->get_primary_registration();
2515
-            $primary_attendee = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516
-                : null;
2517
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518
-                // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519
-                // custom attendee object so let's not worry about the primary reg.
2520
-                $primary_registration = null;
2521
-            }
2522
-        } else {
2523
-            $primary_registration = null;
2524
-        }
2525
-        $this->_template_args['ATT_ID'] = $attendee->ID();
2526
-        $this->_template_args['fname'] = $attendee->fname();
2527
-        $this->_template_args['lname'] = $attendee->lname();
2528
-        $this->_template_args['email'] = $attendee->email();
2529
-        $this->_template_args['phone'] = $attendee->phone();
2530
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2531
-        // edit link
2532
-        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2533
-            array(
2534
-                'action' => 'edit_attendee',
2535
-                'post'   => $attendee->ID(),
2536
-            ),
2537
-            REG_ADMIN_URL
2538
-        );
2539
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2540
-        // create link
2541
-        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2542
-            ? EE_Admin_Page::add_query_args_and_nonce(
2543
-                array(
2544
-                    'action'  => 'duplicate_attendee',
2545
-                    '_REG_ID' => $this->_registration->ID(),
2546
-                ),
2547
-                REG_ADMIN_URL
2548
-            ) : '';
2549
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2550
-        $this->_template_args['att_check'] = $att_check;
2551
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2552
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2553
-    }
2554
-
2555
-
2556
-    /**
2557
-     * trash or restore registrations
2558
-     *
2559
-     * @param  boolean $trash whether to archive or restore
2560
-     * @return void
2561
-     * @throws EE_Error
2562
-     * @throws InvalidArgumentException
2563
-     * @throws InvalidDataTypeException
2564
-     * @throws InvalidInterfaceException
2565
-     * @throws RuntimeException
2566
-     * @access protected
2567
-     */
2568
-    protected function _trash_or_restore_registrations($trash = true)
2569
-    {
2570
-        // if empty _REG_ID then get out because there's nothing to do
2571
-        if (empty($this->_req_data['_REG_ID'])) {
2572
-            EE_Error::add_error(
2573
-                sprintf(
2574
-                    esc_html__(
2575
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2576
-                        'event_espresso'
2577
-                    ),
2578
-                    $trash ? 'trash' : 'restore'
2579
-                ),
2580
-                __FILE__,
2581
-                __LINE__,
2582
-                __FUNCTION__
2583
-            );
2584
-            $this->_redirect_after_action(false, '', '', array(), true);
2585
-        }
2586
-        $success = 0;
2587
-        $overwrite_msgs = false;
2588
-        // Checkboxes
2589
-        if (! is_array($this->_req_data['_REG_ID'])) {
2590
-            $this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2591
-        }
2592
-        $reg_count = count($this->_req_data['_REG_ID']);
2593
-        // cycle thru checkboxes
2594
-        foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2595
-            /** @var EE_Registration $REG */
2596
-            $REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2597
-            $payments = $REG->registration_payments();
2598
-            if (! empty($payments)) {
2599
-                $name = $REG->attendee() instanceof EE_Attendee
2600
-                    ? $REG->attendee()->full_name()
2601
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2602
-                $overwrite_msgs = true;
2603
-                EE_Error::add_error(
2604
-                    sprintf(
2605
-                        esc_html__(
2606
-                            'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2607
-                            'event_espresso'
2608
-                        ),
2609
-                        $name
2610
-                    ),
2611
-                    __FILE__,
2612
-                    __FUNCTION__,
2613
-                    __LINE__
2614
-                );
2615
-                // can't trash this registration because it has payments.
2616
-                continue;
2617
-            }
2618
-            $updated = $trash ? $REG->delete() : $REG->restore();
2619
-            if ($updated) {
2620
-                $success++;
2621
-            }
2622
-        }
2623
-        $this->_redirect_after_action(
2624
-            $success === $reg_count, // were ALL registrations affected?
2625
-            $success > 1
2626
-                ? esc_html__('Registrations', 'event_espresso')
2627
-                : esc_html__('Registration', 'event_espresso'),
2628
-            $trash
2629
-                ? esc_html__('moved to the trash', 'event_espresso')
2630
-                : esc_html__('restored', 'event_espresso'),
2631
-            $this->mergeExistingRequestParamsWithRedirectArgs(array('action' => 'default')),
2632
-            $overwrite_msgs
2633
-        );
2634
-    }
2635
-
2636
-
2637
-    /**
2638
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2639
-     * registration but also.
2640
-     * 1. Removing relations to EE_Attendee
2641
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2642
-     * ALSO trashed.
2643
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2644
-     * 4. Removing relationships between all tickets and the related registrations
2645
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2646
-     * 6. Deleting permanently any related Checkins.
2647
-     *
2648
-     * @return void
2649
-     * @throws EE_Error
2650
-     * @throws InvalidArgumentException
2651
-     * @throws InvalidDataTypeException
2652
-     * @throws InvalidInterfaceException
2653
-     * @throws ReflectionException
2654
-     */
2655
-    protected function _delete_registrations()
2656
-    {
2657
-        $REG_MDL = $this->getRegistrationModel();
2658
-        $success = 1;
2659
-        // Checkboxes
2660
-        if (! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2661
-            // if array has more than one element than success message should be plural
2662
-            $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2663
-            // cycle thru checkboxes
2664
-            foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2665
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
-                if (! $REG instanceof EE_Registration) {
2667
-                    continue;
2668
-                }
2669
-                $deleted = $this->_delete_registration($REG);
2670
-                if (! $deleted) {
2671
-                    $success = 0;
2672
-                }
2673
-            }
2674
-        } else {
2675
-            // grab single id and delete
2676
-            $REG_ID = $this->_req_data['_REG_ID'];
2677
-            /** @var EE_Registration $REG */
2678
-            $REG = $REG_MDL->get_one_by_ID($REG_ID);
2679
-            $deleted = $this->_delete_registration($REG);
2680
-            if (! $deleted) {
2681
-                $success = 0;
2682
-            }
2683
-        }
2684
-        $what = $success > 1
2685
-            ? esc_html__('Registrations', 'event_espresso')
2686
-            : esc_html__('Registration', 'event_espresso');
2687
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2688
-        $this->_redirect_after_action(
2689
-            $success,
2690
-            $what,
2691
-            $action_desc,
2692
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2693
-            true
2694
-        );
2695
-    }
2696
-
2697
-
2698
-    /**
2699
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2700
-     * models get affected.
2701
-     *
2702
-     * @param EE_Registration $REG registration to be deleted permanently
2703
-     * @return bool true = successful deletion, false = fail.
2704
-     * @throws EE_Error
2705
-     * @throws InvalidArgumentException
2706
-     * @throws InvalidDataTypeException
2707
-     * @throws InvalidInterfaceException
2708
-     * @throws ReflectionException
2709
-     */
2710
-    protected function _delete_registration(EE_Registration $REG)
2711
-    {
2712
-        // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2713
-        // registrations on the transaction that are NOT trashed.
2714
-        $TXN = $REG->get_first_related('Transaction');
2715
-        $REGS = $TXN->get_many_related('Registration');
2716
-        $all_trashed = true;
2717
-        foreach ($REGS as $registration) {
2718
-            if (! $registration->get('REG_deleted')) {
2719
-                $all_trashed = false;
2720
-            }
2721
-        }
2722
-        if (! $all_trashed) {
2723
-            EE_Error::add_error(
2724
-                esc_html__(
2725
-                    'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2726
-                    'event_espresso'
2727
-                ),
2728
-                __FILE__,
2729
-                __FUNCTION__,
2730
-                __LINE__
2731
-            );
2732
-            return false;
2733
-        }
2734
-        // k made it here so that means we can delete all the related transactions and their answers (but let's do them
2735
-        // separately from THIS one).
2736
-        foreach ($REGS as $registration) {
2737
-            // delete related answers
2738
-            $registration->delete_related_permanently('Answer');
2739
-            // remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2740
-            $attendee = $registration->get_first_related('Attendee');
2741
-            if ($attendee instanceof EE_Attendee) {
2742
-                $registration->_remove_relation_to($attendee, 'Attendee');
2743
-            }
2744
-            // now remove relationships to tickets on this registration.
2745
-            $registration->_remove_relations('Ticket');
2746
-            // now delete permanently the checkins related to this registration.
2747
-            $registration->delete_related_permanently('Checkin');
2748
-            if ($registration->ID() === $REG->ID()) {
2749
-                continue;
2750
-            } //we don't want to delete permanently the existing registration just yet.
2751
-            // remove relation to transaction for these registrations if NOT the existing registrations
2752
-            $registration->_remove_relations('Transaction');
2753
-            // delete permanently any related messages.
2754
-            $registration->delete_related_permanently('Message');
2755
-            // now delete this registration permanently
2756
-            $registration->delete_permanently();
2757
-        }
2758
-        // now all related registrations on the transaction are handled.  So let's just handle this registration itself
2759
-        // (the transaction and line items should be all that's left).
2760
-        // delete the line items related to the transaction for this registration.
2761
-        $TXN->delete_related_permanently('Line_Item');
2762
-        // we need to remove all the relationships on the transaction
2763
-        $TXN->delete_related_permanently('Payment');
2764
-        $TXN->delete_related_permanently('Extra_Meta');
2765
-        $TXN->delete_related_permanently('Message');
2766
-        // now we can delete this REG permanently (and the transaction of course)
2767
-        $REG->delete_related_permanently('Transaction');
2768
-        return $REG->delete_permanently();
2769
-    }
2770
-
2771
-
2772
-    /**
2773
-     *    generates HTML for the Register New Attendee Admin page
2774
-     *
2775
-     * @access private
2776
-     * @throws DomainException
2777
-     * @throws EE_Error
2778
-     * @throws InvalidArgumentException
2779
-     * @throws InvalidDataTypeException
2780
-     * @throws InvalidInterfaceException
2781
-     * @throws ReflectionException
2782
-     */
2783
-    public function new_registration()
2784
-    {
2785
-        if (! $this->_set_reg_event()) {
2786
-            throw new EE_Error(
2787
-                esc_html__(
2788
-                    'Unable to continue with registering because there is no Event ID in the request',
2789
-                    'event_espresso'
2790
-                )
2791
-            );
2792
-        }
2793
-        EE_Registry::instance()->REQ->set_espresso_page(true);
2794
-        // gotta start with a clean slate if we're not coming here via ajax
2795
-        if (! defined('DOING_AJAX')
2796
-            && (! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2797
-        ) {
2798
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2799
-        }
2800
-        $this->_template_args['event_name'] = '';
2801
-        // event name
2802
-        if ($this->_reg_event) {
2803
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2804
-            $edit_event_url = self::add_query_args_and_nonce(
2805
-                array(
2806
-                    'action' => 'edit',
2807
-                    'post'   => $this->_reg_event->ID(),
2808
-                ),
2809
-                EVENTS_ADMIN_URL
2810
-            );
2811
-            $edit_event_lnk = '<a href="'
2812
-                              . $edit_event_url
2813
-                              . '" title="'
2814
-                              . esc_attr__('Edit ', 'event_espresso')
2815
-                              . $this->_reg_event->name()
2816
-                              . '">'
2817
-                              . esc_html__('Edit Event', 'event_espresso')
2818
-                              . '</a>';
2819
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2820
-                                                   . $edit_event_lnk
2821
-                                                   . '</span>';
2822
-        }
2823
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2824
-        if (defined('DOING_AJAX')) {
2825
-            $this->_return_json();
2826
-        }
2827
-        // grab header
2828
-        $template_path =
2829
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2830
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2831
-            $template_path,
2832
-            $this->_template_args,
2833
-            true
2834
-        );
2835
-        // $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2836
-        // the details template wrapper
2837
-        $this->display_admin_page_with_sidebar();
2838
-    }
2839
-
2840
-
2841
-    /**
2842
-     * This returns the content for a registration step
2843
-     *
2844
-     * @access protected
2845
-     * @return string html
2846
-     * @throws DomainException
2847
-     * @throws EE_Error
2848
-     * @throws InvalidArgumentException
2849
-     * @throws InvalidDataTypeException
2850
-     * @throws InvalidInterfaceException
2851
-     */
2852
-    protected function _get_registration_step_content()
2853
-    {
2854
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2855
-            $warning_msg = sprintf(
2856
-                esc_html__(
2857
-                    '%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2858
-                    'event_espresso'
2859
-                ),
2860
-                '<br />',
2861
-                '<h3 class="important-notice">',
2862
-                '</h3>',
2863
-                '<div class="float-right">',
2864
-                '<span id="redirect_timer" class="important-notice">30</span>',
2865
-                '</div>',
2866
-                '<b>',
2867
-                '</b>'
2868
-            );
2869
-            return '
2301
+	}
2302
+
2303
+
2304
+	/**
2305
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2306
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2307
+	 * to display the page
2308
+	 *
2309
+	 * @access protected
2310
+	 * @return void
2311
+	 * @throws EE_Error
2312
+	 * @throws InvalidArgumentException
2313
+	 * @throws InvalidDataTypeException
2314
+	 * @throws InvalidInterfaceException
2315
+	 * @throws ReflectionException
2316
+	 */
2317
+	protected function _update_attendee_registration_form()
2318
+	{
2319
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2320
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2321
+			$REG_ID = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2322
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2323
+			if ($success) {
2324
+				$what = esc_html__('Registration Form', 'event_espresso');
2325
+				$route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2326
+					: array('action' => 'default');
2327
+				$this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2328
+			}
2329
+		}
2330
+	}
2331
+
2332
+
2333
+	/**
2334
+	 * Gets the form for saving registrations custom questions (if done
2335
+	 * previously retrieves the cached form object, which may have validation errors in it)
2336
+	 *
2337
+	 * @param int $REG_ID
2338
+	 * @return EE_Registration_Custom_Questions_Form
2339
+	 * @throws EE_Error
2340
+	 * @throws InvalidArgumentException
2341
+	 * @throws InvalidDataTypeException
2342
+	 * @throws InvalidInterfaceException
2343
+	 */
2344
+	protected function _get_reg_custom_questions_form($REG_ID)
2345
+	{
2346
+		if (! $this->_reg_custom_questions_form) {
2347
+			require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2348
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2349
+				$this->getRegistrationModel()->get_one_by_ID($REG_ID)
2350
+			);
2351
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2352
+		}
2353
+		return $this->_reg_custom_questions_form;
2354
+	}
2355
+
2356
+
2357
+	/**
2358
+	 * Saves
2359
+	 *
2360
+	 * @access private
2361
+	 * @param bool $REG_ID
2362
+	 * @return bool
2363
+	 * @throws EE_Error
2364
+	 * @throws InvalidArgumentException
2365
+	 * @throws InvalidDataTypeException
2366
+	 * @throws InvalidInterfaceException
2367
+	 * @throws ReflectionException
2368
+	 */
2369
+	private function _save_reg_custom_questions_form($REG_ID = false)
2370
+	{
2371
+		if (! $REG_ID) {
2372
+			EE_Error::add_error(
2373
+				esc_html__(
2374
+					'An error occurred. No registration ID was received.',
2375
+					'event_espresso'
2376
+				),
2377
+				__FILE__,
2378
+				__FUNCTION__,
2379
+				__LINE__
2380
+			);
2381
+		}
2382
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2383
+		$form->receive_form_submission($this->_req_data);
2384
+		$success = false;
2385
+		if ($form->is_valid()) {
2386
+			foreach ($form->subforms() as $question_group_id => $question_group_form) {
2387
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2388
+					$where_conditions = array(
2389
+						'QST_ID' => $question_id,
2390
+						'REG_ID' => $REG_ID,
2391
+					);
2392
+					$possibly_new_values = array(
2393
+						'ANS_value' => $input->normalized_value(),
2394
+					);
2395
+					$answer = EEM_Answer::instance()->get_one(array($where_conditions));
2396
+					if ($answer instanceof EE_Answer) {
2397
+						$success = $answer->save($possibly_new_values);
2398
+					} else {
2399
+						// insert it then
2400
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2401
+						$answer = EE_Answer::new_instance($cols_n_vals);
2402
+						$success = $answer->save();
2403
+					}
2404
+				}
2405
+			}
2406
+		} else {
2407
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2408
+		}
2409
+		return $success;
2410
+	}
2411
+
2412
+
2413
+	/**
2414
+	 *        generates HTML for the Registration main meta box
2415
+	 *
2416
+	 * @access public
2417
+	 * @return void
2418
+	 * @throws DomainException
2419
+	 * @throws EE_Error
2420
+	 * @throws InvalidArgumentException
2421
+	 * @throws InvalidDataTypeException
2422
+	 * @throws InvalidInterfaceException
2423
+	 * @throws ReflectionException
2424
+	 */
2425
+	public function _reg_attendees_meta_box()
2426
+	{
2427
+		$REG = $this->getRegistrationModel();
2428
+		// get all other registrations on this transaction, and cache
2429
+		// the attendees for them so we don't have to run another query using force_join
2430
+		$registrations = $REG->get_all(
2431
+			array(
2432
+				array(
2433
+					'TXN_ID' => $this->_registration->transaction_ID(),
2434
+					'REG_ID' => array('!=', $this->_registration->ID()),
2435
+				),
2436
+				'force_join' => array('Attendee'),
2437
+				'default_where_conditions' => 'other_models_only',
2438
+			)
2439
+		);
2440
+		$this->_template_args['attendees'] = array();
2441
+		$this->_template_args['attendee_notice'] = '';
2442
+		if (empty($registrations)
2443
+			|| (is_array($registrations)
2444
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2445
+		) {
2446
+			EE_Error::add_error(
2447
+				esc_html__(
2448
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2449
+					'event_espresso'
2450
+				),
2451
+				__FILE__,
2452
+				__FUNCTION__,
2453
+				__LINE__
2454
+			);
2455
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2456
+		} else {
2457
+			$att_nmbr = 1;
2458
+			foreach ($registrations as $registration) {
2459
+				/* @var $registration EE_Registration */
2460
+				$attendee = $registration->attendee()
2461
+					? $registration->attendee()
2462
+					: $this->getAttendeeModel()->create_default_object();
2463
+				$this->_template_args['attendees'][ $att_nmbr ]['STS_ID'] = $registration->status_ID();
2464
+				$this->_template_args['attendees'][ $att_nmbr ]['fname'] = $attendee->fname();
2465
+				$this->_template_args['attendees'][ $att_nmbr ]['lname'] = $attendee->lname();
2466
+				$this->_template_args['attendees'][ $att_nmbr ]['email'] = $attendee->email();
2467
+				$this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
+				$this->_template_args['attendees'][ $att_nmbr ]['address'] = implode(
2469
+					', ',
2470
+					$attendee->full_address_as_array()
2471
+				);
2472
+				$this->_template_args['attendees'][ $att_nmbr ]['att_link'] = self::add_query_args_and_nonce(
2473
+					array(
2474
+						'action' => 'edit_attendee',
2475
+						'post'   => $attendee->ID(),
2476
+					),
2477
+					REG_ADMIN_URL
2478
+				);
2479
+				$this->_template_args['attendees'][ $att_nmbr ]['event_name'] = $registration->event_obj() instanceof EE_Event
2480
+					? $registration->event_obj()->name()
2481
+					: '';
2482
+				$att_nmbr++;
2483
+			}
2484
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2485
+		}
2486
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2487
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2488
+	}
2489
+
2490
+
2491
+	/**
2492
+	 *        generates HTML for the Edit Registration side meta box
2493
+	 *
2494
+	 * @access public
2495
+	 * @return void
2496
+	 * @throws DomainException
2497
+	 * @throws EE_Error
2498
+	 * @throws InvalidArgumentException
2499
+	 * @throws InvalidDataTypeException
2500
+	 * @throws InvalidInterfaceException
2501
+	 * @throws ReflectionException
2502
+	 */
2503
+	public function _reg_registrant_side_meta_box()
2504
+	{
2505
+		/*@var $attendee EE_Attendee */
2506
+		$att_check = $this->_registration->attendee();
2507
+		$attendee = $att_check instanceof EE_Attendee
2508
+			? $att_check
2509
+			: $this->getAttendeeModel()->create_default_object();
2510
+		// now let's determine if this is not the primary registration.  If it isn't then we set the
2511
+		// primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512
+		// primary registration object (that way we know if we need to show create button or not)
2513
+		if (! $this->_registration->is_primary_registrant()) {
2514
+			$primary_registration = $this->_registration->get_primary_registration();
2515
+			$primary_attendee = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516
+				: null;
2517
+			if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518
+				// in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519
+				// custom attendee object so let's not worry about the primary reg.
2520
+				$primary_registration = null;
2521
+			}
2522
+		} else {
2523
+			$primary_registration = null;
2524
+		}
2525
+		$this->_template_args['ATT_ID'] = $attendee->ID();
2526
+		$this->_template_args['fname'] = $attendee->fname();
2527
+		$this->_template_args['lname'] = $attendee->lname();
2528
+		$this->_template_args['email'] = $attendee->email();
2529
+		$this->_template_args['phone'] = $attendee->phone();
2530
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2531
+		// edit link
2532
+		$this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2533
+			array(
2534
+				'action' => 'edit_attendee',
2535
+				'post'   => $attendee->ID(),
2536
+			),
2537
+			REG_ADMIN_URL
2538
+		);
2539
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2540
+		// create link
2541
+		$this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2542
+			? EE_Admin_Page::add_query_args_and_nonce(
2543
+				array(
2544
+					'action'  => 'duplicate_attendee',
2545
+					'_REG_ID' => $this->_registration->ID(),
2546
+				),
2547
+				REG_ADMIN_URL
2548
+			) : '';
2549
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2550
+		$this->_template_args['att_check'] = $att_check;
2551
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2552
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2553
+	}
2554
+
2555
+
2556
+	/**
2557
+	 * trash or restore registrations
2558
+	 *
2559
+	 * @param  boolean $trash whether to archive or restore
2560
+	 * @return void
2561
+	 * @throws EE_Error
2562
+	 * @throws InvalidArgumentException
2563
+	 * @throws InvalidDataTypeException
2564
+	 * @throws InvalidInterfaceException
2565
+	 * @throws RuntimeException
2566
+	 * @access protected
2567
+	 */
2568
+	protected function _trash_or_restore_registrations($trash = true)
2569
+	{
2570
+		// if empty _REG_ID then get out because there's nothing to do
2571
+		if (empty($this->_req_data['_REG_ID'])) {
2572
+			EE_Error::add_error(
2573
+				sprintf(
2574
+					esc_html__(
2575
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2576
+						'event_espresso'
2577
+					),
2578
+					$trash ? 'trash' : 'restore'
2579
+				),
2580
+				__FILE__,
2581
+				__LINE__,
2582
+				__FUNCTION__
2583
+			);
2584
+			$this->_redirect_after_action(false, '', '', array(), true);
2585
+		}
2586
+		$success = 0;
2587
+		$overwrite_msgs = false;
2588
+		// Checkboxes
2589
+		if (! is_array($this->_req_data['_REG_ID'])) {
2590
+			$this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2591
+		}
2592
+		$reg_count = count($this->_req_data['_REG_ID']);
2593
+		// cycle thru checkboxes
2594
+		foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2595
+			/** @var EE_Registration $REG */
2596
+			$REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2597
+			$payments = $REG->registration_payments();
2598
+			if (! empty($payments)) {
2599
+				$name = $REG->attendee() instanceof EE_Attendee
2600
+					? $REG->attendee()->full_name()
2601
+					: esc_html__('Unknown Attendee', 'event_espresso');
2602
+				$overwrite_msgs = true;
2603
+				EE_Error::add_error(
2604
+					sprintf(
2605
+						esc_html__(
2606
+							'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2607
+							'event_espresso'
2608
+						),
2609
+						$name
2610
+					),
2611
+					__FILE__,
2612
+					__FUNCTION__,
2613
+					__LINE__
2614
+				);
2615
+				// can't trash this registration because it has payments.
2616
+				continue;
2617
+			}
2618
+			$updated = $trash ? $REG->delete() : $REG->restore();
2619
+			if ($updated) {
2620
+				$success++;
2621
+			}
2622
+		}
2623
+		$this->_redirect_after_action(
2624
+			$success === $reg_count, // were ALL registrations affected?
2625
+			$success > 1
2626
+				? esc_html__('Registrations', 'event_espresso')
2627
+				: esc_html__('Registration', 'event_espresso'),
2628
+			$trash
2629
+				? esc_html__('moved to the trash', 'event_espresso')
2630
+				: esc_html__('restored', 'event_espresso'),
2631
+			$this->mergeExistingRequestParamsWithRedirectArgs(array('action' => 'default')),
2632
+			$overwrite_msgs
2633
+		);
2634
+	}
2635
+
2636
+
2637
+	/**
2638
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2639
+	 * registration but also.
2640
+	 * 1. Removing relations to EE_Attendee
2641
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2642
+	 * ALSO trashed.
2643
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2644
+	 * 4. Removing relationships between all tickets and the related registrations
2645
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2646
+	 * 6. Deleting permanently any related Checkins.
2647
+	 *
2648
+	 * @return void
2649
+	 * @throws EE_Error
2650
+	 * @throws InvalidArgumentException
2651
+	 * @throws InvalidDataTypeException
2652
+	 * @throws InvalidInterfaceException
2653
+	 * @throws ReflectionException
2654
+	 */
2655
+	protected function _delete_registrations()
2656
+	{
2657
+		$REG_MDL = $this->getRegistrationModel();
2658
+		$success = 1;
2659
+		// Checkboxes
2660
+		if (! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2661
+			// if array has more than one element than success message should be plural
2662
+			$success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2663
+			// cycle thru checkboxes
2664
+			foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2665
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
+				if (! $REG instanceof EE_Registration) {
2667
+					continue;
2668
+				}
2669
+				$deleted = $this->_delete_registration($REG);
2670
+				if (! $deleted) {
2671
+					$success = 0;
2672
+				}
2673
+			}
2674
+		} else {
2675
+			// grab single id and delete
2676
+			$REG_ID = $this->_req_data['_REG_ID'];
2677
+			/** @var EE_Registration $REG */
2678
+			$REG = $REG_MDL->get_one_by_ID($REG_ID);
2679
+			$deleted = $this->_delete_registration($REG);
2680
+			if (! $deleted) {
2681
+				$success = 0;
2682
+			}
2683
+		}
2684
+		$what = $success > 1
2685
+			? esc_html__('Registrations', 'event_espresso')
2686
+			: esc_html__('Registration', 'event_espresso');
2687
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2688
+		$this->_redirect_after_action(
2689
+			$success,
2690
+			$what,
2691
+			$action_desc,
2692
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2693
+			true
2694
+		);
2695
+	}
2696
+
2697
+
2698
+	/**
2699
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2700
+	 * models get affected.
2701
+	 *
2702
+	 * @param EE_Registration $REG registration to be deleted permanently
2703
+	 * @return bool true = successful deletion, false = fail.
2704
+	 * @throws EE_Error
2705
+	 * @throws InvalidArgumentException
2706
+	 * @throws InvalidDataTypeException
2707
+	 * @throws InvalidInterfaceException
2708
+	 * @throws ReflectionException
2709
+	 */
2710
+	protected function _delete_registration(EE_Registration $REG)
2711
+	{
2712
+		// first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2713
+		// registrations on the transaction that are NOT trashed.
2714
+		$TXN = $REG->get_first_related('Transaction');
2715
+		$REGS = $TXN->get_many_related('Registration');
2716
+		$all_trashed = true;
2717
+		foreach ($REGS as $registration) {
2718
+			if (! $registration->get('REG_deleted')) {
2719
+				$all_trashed = false;
2720
+			}
2721
+		}
2722
+		if (! $all_trashed) {
2723
+			EE_Error::add_error(
2724
+				esc_html__(
2725
+					'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2726
+					'event_espresso'
2727
+				),
2728
+				__FILE__,
2729
+				__FUNCTION__,
2730
+				__LINE__
2731
+			);
2732
+			return false;
2733
+		}
2734
+		// k made it here so that means we can delete all the related transactions and their answers (but let's do them
2735
+		// separately from THIS one).
2736
+		foreach ($REGS as $registration) {
2737
+			// delete related answers
2738
+			$registration->delete_related_permanently('Answer');
2739
+			// remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2740
+			$attendee = $registration->get_first_related('Attendee');
2741
+			if ($attendee instanceof EE_Attendee) {
2742
+				$registration->_remove_relation_to($attendee, 'Attendee');
2743
+			}
2744
+			// now remove relationships to tickets on this registration.
2745
+			$registration->_remove_relations('Ticket');
2746
+			// now delete permanently the checkins related to this registration.
2747
+			$registration->delete_related_permanently('Checkin');
2748
+			if ($registration->ID() === $REG->ID()) {
2749
+				continue;
2750
+			} //we don't want to delete permanently the existing registration just yet.
2751
+			// remove relation to transaction for these registrations if NOT the existing registrations
2752
+			$registration->_remove_relations('Transaction');
2753
+			// delete permanently any related messages.
2754
+			$registration->delete_related_permanently('Message');
2755
+			// now delete this registration permanently
2756
+			$registration->delete_permanently();
2757
+		}
2758
+		// now all related registrations on the transaction are handled.  So let's just handle this registration itself
2759
+		// (the transaction and line items should be all that's left).
2760
+		// delete the line items related to the transaction for this registration.
2761
+		$TXN->delete_related_permanently('Line_Item');
2762
+		// we need to remove all the relationships on the transaction
2763
+		$TXN->delete_related_permanently('Payment');
2764
+		$TXN->delete_related_permanently('Extra_Meta');
2765
+		$TXN->delete_related_permanently('Message');
2766
+		// now we can delete this REG permanently (and the transaction of course)
2767
+		$REG->delete_related_permanently('Transaction');
2768
+		return $REG->delete_permanently();
2769
+	}
2770
+
2771
+
2772
+	/**
2773
+	 *    generates HTML for the Register New Attendee Admin page
2774
+	 *
2775
+	 * @access private
2776
+	 * @throws DomainException
2777
+	 * @throws EE_Error
2778
+	 * @throws InvalidArgumentException
2779
+	 * @throws InvalidDataTypeException
2780
+	 * @throws InvalidInterfaceException
2781
+	 * @throws ReflectionException
2782
+	 */
2783
+	public function new_registration()
2784
+	{
2785
+		if (! $this->_set_reg_event()) {
2786
+			throw new EE_Error(
2787
+				esc_html__(
2788
+					'Unable to continue with registering because there is no Event ID in the request',
2789
+					'event_espresso'
2790
+				)
2791
+			);
2792
+		}
2793
+		EE_Registry::instance()->REQ->set_espresso_page(true);
2794
+		// gotta start with a clean slate if we're not coming here via ajax
2795
+		if (! defined('DOING_AJAX')
2796
+			&& (! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2797
+		) {
2798
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2799
+		}
2800
+		$this->_template_args['event_name'] = '';
2801
+		// event name
2802
+		if ($this->_reg_event) {
2803
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2804
+			$edit_event_url = self::add_query_args_and_nonce(
2805
+				array(
2806
+					'action' => 'edit',
2807
+					'post'   => $this->_reg_event->ID(),
2808
+				),
2809
+				EVENTS_ADMIN_URL
2810
+			);
2811
+			$edit_event_lnk = '<a href="'
2812
+							  . $edit_event_url
2813
+							  . '" title="'
2814
+							  . esc_attr__('Edit ', 'event_espresso')
2815
+							  . $this->_reg_event->name()
2816
+							  . '">'
2817
+							  . esc_html__('Edit Event', 'event_espresso')
2818
+							  . '</a>';
2819
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2820
+												   . $edit_event_lnk
2821
+												   . '</span>';
2822
+		}
2823
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2824
+		if (defined('DOING_AJAX')) {
2825
+			$this->_return_json();
2826
+		}
2827
+		// grab header
2828
+		$template_path =
2829
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2830
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2831
+			$template_path,
2832
+			$this->_template_args,
2833
+			true
2834
+		);
2835
+		// $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2836
+		// the details template wrapper
2837
+		$this->display_admin_page_with_sidebar();
2838
+	}
2839
+
2840
+
2841
+	/**
2842
+	 * This returns the content for a registration step
2843
+	 *
2844
+	 * @access protected
2845
+	 * @return string html
2846
+	 * @throws DomainException
2847
+	 * @throws EE_Error
2848
+	 * @throws InvalidArgumentException
2849
+	 * @throws InvalidDataTypeException
2850
+	 * @throws InvalidInterfaceException
2851
+	 */
2852
+	protected function _get_registration_step_content()
2853
+	{
2854
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2855
+			$warning_msg = sprintf(
2856
+				esc_html__(
2857
+					'%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2858
+					'event_espresso'
2859
+				),
2860
+				'<br />',
2861
+				'<h3 class="important-notice">',
2862
+				'</h3>',
2863
+				'<div class="float-right">',
2864
+				'<span id="redirect_timer" class="important-notice">30</span>',
2865
+				'</div>',
2866
+				'<b>',
2867
+				'</b>'
2868
+			);
2869
+			return '
2870 2870
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2871 2871
 	<script >
2872 2872
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2879,868 +2879,868 @@  discard block
 block discarded – undo
2879 2879
 	        }
2880 2880
 	    }, 800 );
2881 2881
 	</script >';
2882
-        }
2883
-        $template_args = array(
2884
-            'title'                    => '',
2885
-            'content'                  => '',
2886
-            'step_button_text'         => '',
2887
-            'show_notification_toggle' => false,
2888
-        );
2889
-        // to indicate we're processing a new registration
2890
-        $hidden_fields = array(
2891
-            'processing_registration' => array(
2892
-                'type'  => 'hidden',
2893
-                'value' => 0,
2894
-            ),
2895
-            'event_id'                => array(
2896
-                'type'  => 'hidden',
2897
-                'value' => $this->_reg_event->ID(),
2898
-            ),
2899
-        );
2900
-        // if the cart is empty then we know we're at step one so we'll display ticket selector
2901
-        $cart = EE_Registry::instance()->SSN->cart();
2902
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2903
-        switch ($step) {
2904
-            case 'ticket':
2905
-                $hidden_fields['processing_registration']['value'] = 1;
2906
-                $template_args['title'] = esc_html__(
2907
-                    'Step One: Select the Ticket for this registration',
2908
-                    'event_espresso'
2909
-                );
2910
-                $template_args['content'] =
2911
-                    EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2912
-                $template_args['content'] .= '</div>';
2913
-                $template_args['step_button_text'] = esc_html__(
2914
-                    'Add Tickets and Continue to Registrant Details',
2915
-                    'event_espresso'
2916
-                );
2917
-                $template_args['show_notification_toggle'] = false;
2918
-                break;
2919
-            case 'questions':
2920
-                $hidden_fields['processing_registration']['value'] = 2;
2921
-                $template_args['title'] = esc_html__(
2922
-                    'Step Two: Add Registrant Details for this Registration',
2923
-                    'event_espresso'
2924
-                );
2925
-                // in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2926
-                // properly by the first process_reg_step run.
2927
-                $template_args['content'] =
2928
-                    EED_Single_Page_Checkout::registration_checkout_for_admin();
2929
-                $template_args['step_button_text'] = esc_html__(
2930
-                    'Save Registration and Continue to Details',
2931
-                    'event_espresso'
2932
-                );
2933
-                $template_args['show_notification_toggle'] = true;
2934
-                break;
2935
-        }
2936
-        // we come back to the process_registration_step route.
2937
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2938
-        return EEH_Template::display_template(
2939
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2940
-            $template_args,
2941
-            true
2942
-        );
2943
-    }
2944
-
2945
-
2946
-    /**
2947
-     *        set_reg_event
2948
-     *
2949
-     * @access private
2950
-     * @return bool
2951
-     * @throws EE_Error
2952
-     * @throws InvalidArgumentException
2953
-     * @throws InvalidDataTypeException
2954
-     * @throws InvalidInterfaceException
2955
-     */
2956
-    private function _set_reg_event()
2957
-    {
2958
-        if (is_object($this->_reg_event)) {
2959
-            return true;
2960
-        }
2961
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2962
-        if (! $EVT_ID) {
2963
-            return false;
2964
-        }
2965
-        $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2966
-        return true;
2967
-    }
2968
-
2969
-
2970
-    /**
2971
-     * process_reg_step
2972
-     *
2973
-     * @access        public
2974
-     * @return string
2975
-     * @throws DomainException
2976
-     * @throws EE_Error
2977
-     * @throws InvalidArgumentException
2978
-     * @throws InvalidDataTypeException
2979
-     * @throws InvalidInterfaceException
2980
-     * @throws ReflectionException
2981
-     * @throws RuntimeException
2982
-     */
2983
-    public function process_reg_step()
2984
-    {
2985
-        EE_System::do_not_cache();
2986
-        $this->_set_reg_event();
2987
-        EE_Registry::instance()->REQ->set_espresso_page(true);
2988
-        EE_Registry::instance()->REQ->set('uts', time());
2989
-        // what step are we on?
2990
-        $cart = EE_Registry::instance()->SSN->cart();
2991
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2992
-        // if doing ajax then we need to verify the nonce
2993
-        if (defined('DOING_AJAX')) {
2994
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
2995
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) : '';
2996
-            $this->_verify_nonce($nonce, $this->_req_nonce);
2997
-        }
2998
-        switch ($step) {
2999
-            case 'ticket':
3000
-                // process ticket selection
3001
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
3002
-                if ($success) {
3003
-                    EE_Error::add_success(
3004
-                        esc_html__(
3005
-                            'Tickets Selected. Now complete the registration.',
3006
-                            'event_espresso'
3007
-                        )
3008
-                    );
3009
-                } else {
3010
-                    $query_args['step_error'] = $this->_req_data['step_error'] = true;
3011
-                }
3012
-                if (defined('DOING_AJAX')) {
3013
-                    $this->new_registration(); // display next step
3014
-                } else {
3015
-                    $query_args = array(
3016
-                        'action'                  => 'new_registration',
3017
-                        'processing_registration' => 1,
3018
-                        'event_id'                => $this->_reg_event->ID(),
3019
-                        'uts'                     => time(),
3020
-                    );
3021
-                    $this->_redirect_after_action(
3022
-                        false,
3023
-                        '',
3024
-                        '',
3025
-                        $query_args,
3026
-                        true
3027
-                    );
3028
-                }
3029
-                break;
3030
-            case 'questions':
3031
-                if (! isset(
3032
-                    $this->_req_data['txn_reg_status_change'],
3033
-                    $this->_req_data['txn_reg_status_change']['send_notifications']
3034
-                )
3035
-                ) {
3036
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3037
-                }
3038
-                // process registration
3039
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3040
-                if ($cart instanceof EE_Cart) {
3041
-                    $grand_total = $cart->get_cart_grand_total();
3042
-                    if ($grand_total instanceof EE_Line_Item) {
3043
-                        $grand_total->save_this_and_descendants_to_txn();
3044
-                    }
3045
-                }
3046
-                if (! $transaction instanceof EE_Transaction) {
3047
-                    $query_args = array(
3048
-                        'action'                  => 'new_registration',
3049
-                        'processing_registration' => 2,
3050
-                        'event_id'                => $this->_reg_event->ID(),
3051
-                        'uts'                     => time(),
3052
-                    );
3053
-                    if (defined('DOING_AJAX')) {
3054
-                        // display registration form again because there are errors (maybe validation?)
3055
-                        $this->new_registration();
3056
-                        return;
3057
-                    }
3058
-                    $this->_redirect_after_action(
3059
-                        false,
3060
-                        '',
3061
-                        '',
3062
-                        $query_args,
3063
-                        true
3064
-                    );
3065
-                    return;
3066
-                }
3067
-                // maybe update status, and make sure to save transaction if not done already
3068
-                if (! $transaction->update_status_based_on_total_paid()) {
3069
-                    $transaction->save();
3070
-                }
3071
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3072
-                $this->_req_data = array();
3073
-                $query_args = array(
3074
-                    'action'        => 'redirect_to_txn',
3075
-                    'TXN_ID'        => $transaction->ID(),
3076
-                    'EVT_ID'        => $this->_reg_event->ID(),
3077
-                    'event_name'    => urlencode($this->_reg_event->name()),
3078
-                    'redirect_from' => 'new_registration',
3079
-                );
3080
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3081
-                break;
3082
-        }
3083
-        // what are you looking here for?  Should be nothing to do at this point.
3084
-    }
3085
-
3086
-
3087
-    /**
3088
-     * redirect_to_txn
3089
-     *
3090
-     * @access public
3091
-     * @return void
3092
-     * @throws EE_Error
3093
-     * @throws InvalidArgumentException
3094
-     * @throws InvalidDataTypeException
3095
-     * @throws InvalidInterfaceException
3096
-     * @throws ReflectionException
3097
-     */
3098
-    public function redirect_to_txn()
3099
-    {
3100
-        EE_System::do_not_cache();
3101
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3102
-        $query_args = array(
3103
-            'action' => 'view_transaction',
3104
-            'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3105
-            'page'   => 'espresso_transactions',
3106
-        );
3107
-        if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3108
-            $query_args['EVT_ID'] = $this->_req_data['EVT_ID'];
3109
-            $query_args['event_name'] = urlencode($this->_req_data['event_name']);
3110
-            $query_args['redirect_from'] = $this->_req_data['redirect_from'];
3111
-        }
3112
-        EE_Error::add_success(
3113
-            esc_html__(
3114
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3115
-                'event_espresso'
3116
-            )
3117
-        );
3118
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3119
-    }
3120
-
3121
-
3122
-    /**
3123
-     *        generates HTML for the Attendee Contact List
3124
-     *
3125
-     * @access protected
3126
-     * @return void
3127
-     * @throws DomainException
3128
-     * @throws EE_Error
3129
-     */
3130
-    protected function _attendee_contact_list_table()
3131
-    {
3132
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3133
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3134
-        $this->display_admin_list_table_page_with_no_sidebar();
3135
-    }
3136
-
3137
-
3138
-    /**
3139
-     *        get_attendees
3140
-     *
3141
-     * @param      $per_page
3142
-     * @param bool $count whether to return count or data.
3143
-     * @param bool $trash
3144
-     * @return array
3145
-     * @throws EE_Error
3146
-     * @throws InvalidArgumentException
3147
-     * @throws InvalidDataTypeException
3148
-     * @throws InvalidInterfaceException
3149
-     * @access public
3150
-     */
3151
-    public function get_attendees($per_page, $count = false, $trash = false)
3152
-    {
3153
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3154
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3155
-        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3156
-        switch ($this->_req_data['orderby']) {
3157
-            case 'ATT_ID':
3158
-                $orderby = 'ATT_ID';
3159
-                break;
3160
-            case 'ATT_fname':
3161
-                $orderby = 'ATT_fname';
3162
-                break;
3163
-            case 'ATT_email':
3164
-                $orderby = 'ATT_email';
3165
-                break;
3166
-            case 'ATT_city':
3167
-                $orderby = 'ATT_city';
3168
-                break;
3169
-            case 'STA_ID':
3170
-                $orderby = 'STA_ID';
3171
-                break;
3172
-            case 'CNT_ID':
3173
-                $orderby = 'CNT_ID';
3174
-                break;
3175
-            case 'Registration_Count':
3176
-                $orderby = 'Registration_Count';
3177
-                break;
3178
-            default:
3179
-                $orderby = 'ATT_lname';
3180
-        }
3181
-        $sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3182
-            ? $this->_req_data['order']
3183
-            : 'ASC';
3184
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3185
-            ? $this->_req_data['paged']
3186
-            : 1;
3187
-        $per_page = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3188
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3189
-            ? $this->_req_data['perpage']
3190
-            : $per_page;
3191
-        $_where = array();
3192
-        if (! empty($this->_req_data['s'])) {
3193
-            $sstr = '%' . $this->_req_data['s'] . '%';
3194
-            $_where['OR'] = array(
3195
-                'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3196
-                'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3197
-                'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3198
-                'ATT_fname'                         => array('LIKE', $sstr),
3199
-                'ATT_lname'                         => array('LIKE', $sstr),
3200
-                'ATT_short_bio'                     => array('LIKE', $sstr),
3201
-                'ATT_email'                         => array('LIKE', $sstr),
3202
-                'ATT_address'                       => array('LIKE', $sstr),
3203
-                'ATT_address2'                      => array('LIKE', $sstr),
3204
-                'ATT_city'                          => array('LIKE', $sstr),
3205
-                'Country.CNT_name'                  => array('LIKE', $sstr),
3206
-                'State.STA_name'                    => array('LIKE', $sstr),
3207
-                'ATT_phone'                         => array('LIKE', $sstr),
3208
-                'Registration.REG_final_price'      => array('LIKE', $sstr),
3209
-                'Registration.REG_code'             => array('LIKE', $sstr),
3210
-                'Registration.REG_group_size'       => array('LIKE', $sstr),
3211
-            );
3212
-        }
3213
-        $offset = ($current_page - 1) * $per_page;
3214
-        $limit = $count ? null : array($offset, $per_page);
3215
-        $query_args = array(
3216
-            $_where,
3217
-            'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3218
-            'limit'         => $limit,
3219
-        );
3220
-        if (! $count) {
3221
-            $query_args['order_by'] = array($orderby => $sort);
3222
-        }
3223
-        if ($trash) {
3224
-            $query_args[0]['status'] = array('!=', 'publish');
3225
-            $all_attendees = $count
3226
-                ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3227
-                : $this->getAttendeeModel()->get_all($query_args);
3228
-        } else {
3229
-            $query_args[0]['status'] = array('IN', array('publish'));
3230
-            $all_attendees = $count
3231
-                ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3232
-                : $this->getAttendeeModel()->get_all($query_args);
3233
-        }
3234
-        return $all_attendees;
3235
-    }
3236
-
3237
-
3238
-    /**
3239
-     * This is just taking care of resending the registration confirmation
3240
-     *
3241
-     * @access protected
3242
-     * @return void
3243
-     * @throws EE_Error
3244
-     * @throws InvalidArgumentException
3245
-     * @throws InvalidDataTypeException
3246
-     * @throws InvalidInterfaceException
3247
-     * @throws ReflectionException
3248
-     */
3249
-    protected function _resend_registration()
3250
-    {
3251
-        $this->_process_resend_registration();
3252
-        $query_args = isset($this->_req_data['redirect_to'])
3253
-            ? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3254
-            : array('action' => 'default');
3255
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3256
-    }
3257
-
3258
-    /**
3259
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3260
-     * to use when selecting registrations
3261
-     *
3262
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3263
-     *                                                     the query parameters from the request
3264
-     * @return void ends the request with a redirect or download
3265
-     */
3266
-    public function _registrations_report_base($method_name_for_getting_query_params)
3267
-    {
3268
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3269
-            wp_redirect(
3270
-                EE_Admin_Page::add_query_args_and_nonce(
3271
-                    array(
3272
-                        'page'        => 'espresso_batch',
3273
-                        'batch'       => 'file',
3274
-                        'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3275
-                        'filters'     => urlencode(
3276
-                            serialize(
3277
-                                $this->$method_name_for_getting_query_params(
3278
-                                    EEH_Array::is_set(
3279
-                                        $this->_req_data,
3280
-                                        'filters',
3281
-                                        array()
3282
-                                    )
3283
-                                )
3284
-                            )
3285
-                        ),
3286
-                        'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3287
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3288
-                        'return_url'  => urlencode($this->_req_data['return_url']),
3289
-                    )
3290
-                )
3291
-            );
3292
-        } else {
3293
-            $new_request_args = array(
3294
-                'export' => 'report',
3295
-                'action' => 'registrations_report_for_event',
3296
-                'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3297
-            );
3298
-            $this->_req_data = array_merge($this->_req_data, $new_request_args);
3299
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3300
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3301
-                $EE_Export = EE_Export::instance($this->_req_data);
3302
-                $EE_Export->export();
3303
-            }
3304
-        }
3305
-    }
3306
-
3307
-
3308
-    /**
3309
-     * Creates a registration report using only query parameters in the request
3310
-     *
3311
-     * @return void
3312
-     */
3313
-    public function _registrations_report()
3314
-    {
3315
-        $this->_registrations_report_base('_get_registration_query_parameters');
3316
-    }
3317
-
3318
-
3319
-    public function _contact_list_export()
3320
-    {
3321
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3322
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3323
-            $EE_Export = EE_Export::instance($this->_req_data);
3324
-            $EE_Export->export_attendees();
3325
-        }
3326
-    }
3327
-
3328
-
3329
-    public function _contact_list_report()
3330
-    {
3331
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3332
-            wp_redirect(
3333
-                EE_Admin_Page::add_query_args_and_nonce(
3334
-                    array(
3335
-                        'page'        => 'espresso_batch',
3336
-                        'batch'       => 'file',
3337
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3338
-                        'return_url'  => urlencode($this->_req_data['return_url']),
3339
-                    )
3340
-                )
3341
-            );
3342
-        } else {
3343
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3344
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3345
-                $EE_Export = EE_Export::instance($this->_req_data);
3346
-                $EE_Export->report_attendees();
3347
-            }
3348
-        }
3349
-    }
3350
-
3351
-
3352
-
3353
-
3354
-
3355
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3356
-    /**
3357
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3358
-     *
3359
-     * @return void
3360
-     * @throws EE_Error
3361
-     * @throws InvalidArgumentException
3362
-     * @throws InvalidDataTypeException
3363
-     * @throws InvalidInterfaceException
3364
-     * @throws ReflectionException
3365
-     */
3366
-    protected function _duplicate_attendee()
3367
-    {
3368
-        $action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3369
-        // verify we have necessary info
3370
-        if (empty($this->_req_data['_REG_ID'])) {
3371
-            EE_Error::add_error(
3372
-                esc_html__(
3373
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3374
-                    'event_espresso'
3375
-                ),
3376
-                __FILE__,
3377
-                __LINE__,
3378
-                __FUNCTION__
3379
-            );
3380
-            $query_args = array('action' => $action);
3381
-            $this->_redirect_after_action('', '', '', $query_args, true);
3382
-        }
3383
-        // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3384
-        $registration = $this->getRegistrationModel()->get_one_by_ID($this->_req_data['_REG_ID']);
3385
-        $attendee = $registration->attendee();
3386
-        // remove relation of existing attendee on registration
3387
-        $registration->_remove_relation_to($attendee, 'Attendee');
3388
-        // new attendee
3389
-        $new_attendee = clone $attendee;
3390
-        $new_attendee->set('ATT_ID', 0);
3391
-        $new_attendee->save();
3392
-        // add new attendee to reg
3393
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3394
-        EE_Error::add_success(
3395
-            esc_html__(
3396
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3397
-                'event_espresso'
3398
-            )
3399
-        );
3400
-        // redirect to edit page for attendee
3401
-        $query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3402
-        $this->_redirect_after_action('', '', '', $query_args, true);
3403
-    }
3404
-
3405
-
3406
-    /**
3407
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3408
-     *
3409
-     * @param int     $post_id
3410
-     * @param WP_POST $post
3411
-     * @throws DomainException
3412
-     * @throws EE_Error
3413
-     * @throws InvalidArgumentException
3414
-     * @throws InvalidDataTypeException
3415
-     * @throws InvalidInterfaceException
3416
-     * @throws LogicException
3417
-     * @throws InvalidFormSubmissionException
3418
-     * @throws ReflectionException
3419
-     */
3420
-    protected function _insert_update_cpt_item($post_id, $post)
3421
-    {
3422
-        $success = true;
3423
-        $attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3424
-            ? $this->getAttendeeModel()->get_one_by_ID($post_id)
3425
-            : null;
3426
-        // for attendee updates
3427
-        if ($attendee instanceof EE_Attendee) {
3428
-            // note we should only be UPDATING attendees at this point.
3429
-            $updated_fields = array(
3430
-                'ATT_fname'     => $this->_req_data['ATT_fname'],
3431
-                'ATT_lname'     => $this->_req_data['ATT_lname'],
3432
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3433
-                'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3434
-                'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3435
-                'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3436
-                'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3437
-                'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3438
-                'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3439
-            );
3440
-            foreach ($updated_fields as $field => $value) {
3441
-                $attendee->set($field, $value);
3442
-            }
3443
-
3444
-            // process contact details metabox form handler (which will also save the attendee)
3445
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3446
-            $success = $contact_details_form->process($this->_req_data);
3447
-
3448
-            $attendee_update_callbacks = apply_filters(
3449
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3450
-                array()
3451
-            );
3452
-            foreach ($attendee_update_callbacks as $a_callback) {
3453
-                if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3454
-                    throw new EE_Error(
3455
-                        sprintf(
3456
-                            esc_html__(
3457
-                                'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3458
-                                'event_espresso'
3459
-                            ),
3460
-                            $a_callback
3461
-                        )
3462
-                    );
3463
-                }
3464
-            }
3465
-        }
3466
-
3467
-        if ($success === false) {
3468
-            EE_Error::add_error(
3469
-                esc_html__(
3470
-                    'Something went wrong with updating the meta table data for the registration.',
3471
-                    'event_espresso'
3472
-                ),
3473
-                __FILE__,
3474
-                __FUNCTION__,
3475
-                __LINE__
3476
-            );
3477
-        }
3478
-    }
3479
-
3480
-
3481
-    public function trash_cpt_item($post_id)
3482
-    {
3483
-    }
3484
-
3485
-
3486
-    public function delete_cpt_item($post_id)
3487
-    {
3488
-    }
3489
-
3490
-
3491
-    public function restore_cpt_item($post_id)
3492
-    {
3493
-    }
3494
-
3495
-
3496
-    protected function _restore_cpt_item($post_id, $revision_id)
3497
-    {
3498
-    }
3499
-
3500
-
3501
-    /**
3502
-     * @throws EE_Error
3503
-     * @since 4.10.2.p
3504
-     */
3505
-    public function attendee_editor_metaboxes()
3506
-    {
3507
-        $this->verify_cpt_object();
3508
-        remove_meta_box(
3509
-            'postexcerpt',
3510
-            $this->_cpt_routes[ $this->_req_action ],
3511
-            'normal'
3512
-        );
3513
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal', 'core');
3514
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3515
-            add_meta_box(
3516
-                'postexcerpt',
3517
-                esc_html__('Short Biography', 'event_espresso'),
3518
-                'post_excerpt_meta_box',
3519
-                $this->_cpt_routes[ $this->_req_action ],
3520
-                'normal'
3521
-            );
3522
-        }
3523
-        if (post_type_supports('espresso_attendees', 'comments')) {
3524
-            add_meta_box(
3525
-                'commentsdiv',
3526
-                esc_html__('Notes on the Contact', 'event_espresso'),
3527
-                'post_comment_meta_box',
3528
-                $this->_cpt_routes[ $this->_req_action ],
3529
-                'normal',
3530
-                'core'
3531
-            );
3532
-        }
3533
-        add_meta_box(
3534
-            'attendee_contact_info',
3535
-            esc_html__('Contact Info', 'event_espresso'),
3536
-            array($this, 'attendee_contact_info'),
3537
-            $this->_cpt_routes[ $this->_req_action ],
3538
-            'side',
3539
-            'core'
3540
-        );
3541
-        add_meta_box(
3542
-            'attendee_details_address',
3543
-            esc_html__('Address Details', 'event_espresso'),
3544
-            array($this, 'attendee_address_details'),
3545
-            $this->_cpt_routes[ $this->_req_action ],
3546
-            'normal',
3547
-            'core'
3548
-        );
3549
-        add_meta_box(
3550
-            'attendee_registrations',
3551
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3552
-            array($this, 'attendee_registrations_meta_box'),
3553
-            $this->_cpt_routes[ $this->_req_action ],
3554
-            'normal',
3555
-            'high'
3556
-        );
3557
-    }
3558
-
3559
-
3560
-    /**
3561
-     * Metabox for attendee contact info
3562
-     *
3563
-     * @param  WP_Post $post wp post object
3564
-     * @return string attendee contact info ( and form )
3565
-     * @throws EE_Error
3566
-     * @throws InvalidArgumentException
3567
-     * @throws InvalidDataTypeException
3568
-     * @throws InvalidInterfaceException
3569
-     * @throws LogicException
3570
-     * @throws DomainException
3571
-     */
3572
-    public function attendee_contact_info($post)
3573
-    {
3574
-        // get attendee object ( should already have it )
3575
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3576
-        $form->enqueueStylesAndScripts();
3577
-        echo $form->display();
3578
-    }
3579
-
3580
-
3581
-    /**
3582
-     * Return form handler for the contact details metabox
3583
-     *
3584
-     * @param EE_Attendee $attendee
3585
-     * @return AttendeeContactDetailsMetaboxFormHandler
3586
-     * @throws DomainException
3587
-     * @throws InvalidArgumentException
3588
-     * @throws InvalidDataTypeException
3589
-     * @throws InvalidInterfaceException
3590
-     */
3591
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3592
-    {
3593
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3594
-    }
3595
-
3596
-
3597
-    /**
3598
-     * Metabox for attendee details
3599
-     *
3600
-     * @param  WP_Post $post wp post object
3601
-     * @throws DomainException
3602
-     */
3603
-    public function attendee_address_details($post)
3604
-    {
3605
-        // get attendee object (should already have it)
3606
-        $this->_template_args['attendee'] = $this->_cpt_model_obj;
3607
-        $this->_template_args['state_html'] = EEH_Form_Fields::generate_form_input(
3608
-            new EE_Question_Form_Input(
3609
-                EE_Question::new_instance(
3610
-                    array(
3611
-                        'QST_ID'           => 0,
3612
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3613
-                        'QST_system'       => 'admin-state',
3614
-                    )
3615
-                ),
3616
-                EE_Answer::new_instance(
3617
-                    array(
3618
-                        'ANS_ID'    => 0,
3619
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3620
-                    )
3621
-                ),
3622
-                array(
3623
-                    'input_id'       => 'STA_ID',
3624
-                    'input_name'     => 'STA_ID',
3625
-                    'input_prefix'   => '',
3626
-                    'append_qstn_id' => false,
3627
-                )
3628
-            )
3629
-        );
3630
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3631
-            new EE_Question_Form_Input(
3632
-                EE_Question::new_instance(
3633
-                    array(
3634
-                        'QST_ID'           => 0,
3635
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3636
-                        'QST_system'       => 'admin-country',
3637
-                    )
3638
-                ),
3639
-                EE_Answer::new_instance(
3640
-                    array(
3641
-                        'ANS_ID'    => 0,
3642
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3643
-                    )
3644
-                ),
3645
-                array(
3646
-                    'input_id'       => 'CNT_ISO',
3647
-                    'input_name'     => 'CNT_ISO',
3648
-                    'input_prefix'   => '',
3649
-                    'append_qstn_id' => false,
3650
-                )
3651
-            )
3652
-        );
3653
-        $template =
3654
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3655
-        EEH_Template::display_template($template, $this->_template_args);
3656
-    }
3657
-
3658
-
3659
-    /**
3660
-     *        _attendee_details
3661
-     *
3662
-     * @access protected
3663
-     * @param $post
3664
-     * @return void
3665
-     * @throws DomainException
3666
-     * @throws EE_Error
3667
-     * @throws InvalidArgumentException
3668
-     * @throws InvalidDataTypeException
3669
-     * @throws InvalidInterfaceException
3670
-     * @throws ReflectionException
3671
-     */
3672
-    public function attendee_registrations_meta_box($post)
3673
-    {
3674
-        $this->_template_args['attendee'] = $this->_cpt_model_obj;
3675
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3676
-        $template =
3677
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3678
-        EEH_Template::display_template($template, $this->_template_args);
3679
-    }
3680
-
3681
-
3682
-    /**
3683
-     * add in the form fields for the attendee edit
3684
-     *
3685
-     * @param  WP_Post $post wp post object
3686
-     * @return string html for new form.
3687
-     * @throws DomainException
3688
-     */
3689
-    public function after_title_form_fields($post)
3690
-    {
3691
-        if ($post->post_type === 'espresso_attendees') {
3692
-            $template = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3693
-            $template_args['attendee'] = $this->_cpt_model_obj;
3694
-            EEH_Template::display_template($template, $template_args);
3695
-        }
3696
-    }
3697
-
3698
-
3699
-    /**
3700
-     *        _trash_or_restore_attendee
3701
-     *
3702
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3703
-     * @return void
3704
-     * @throws EE_Error
3705
-     * @throws InvalidArgumentException
3706
-     * @throws InvalidDataTypeException
3707
-     * @throws InvalidInterfaceException
3708
-     * @throws ReflectionException
3709
-     * @access protected
3710
-     */
3711
-    protected function _trash_or_restore_attendees($trash = true)
3712
-    {
3713
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3714
-        $success = 1;
3715
-        // Checkboxes
3716
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3717
-            // if array has more than one element than success message should be plural
3718
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3719
-            // cycle thru checkboxes
3720
-            foreach ($this->_req_data['checkbox'] as $ATT_ID) {
3721
-                $updated = $trash ? $this->getAttendeeModel()->update_by_ID(array('status' => 'trash'), $ATT_ID)
3722
-                    : $this->getAttendeeModel()->update_by_ID(array('status' => 'publish'), $ATT_ID);
3723
-                if (! $updated) {
3724
-                    $success = 0;
3725
-                }
3726
-            }
3727
-        } else {
3728
-            // grab single id and delete
3729
-            $ATT_ID = absint($this->_req_data['ATT_ID']);
3730
-            // get attendee
3731
-            $att = $this->getAttendeeModel()->get_one_by_ID($ATT_ID);
3732
-            $updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3733
-            $updated = $att->save() && $updated;
3734
-            if (! $updated) {
3735
-                $success = 0;
3736
-            }
3737
-        }
3738
-        $what = $success > 1
3739
-            ? esc_html__('Contacts', 'event_espresso')
3740
-            : esc_html__('Contact', 'event_espresso');
3741
-        $action_desc = $trash
3742
-            ? esc_html__('moved to the trash', 'event_espresso')
3743
-            : esc_html__('restored', 'event_espresso');
3744
-        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3745
-    }
2882
+		}
2883
+		$template_args = array(
2884
+			'title'                    => '',
2885
+			'content'                  => '',
2886
+			'step_button_text'         => '',
2887
+			'show_notification_toggle' => false,
2888
+		);
2889
+		// to indicate we're processing a new registration
2890
+		$hidden_fields = array(
2891
+			'processing_registration' => array(
2892
+				'type'  => 'hidden',
2893
+				'value' => 0,
2894
+			),
2895
+			'event_id'                => array(
2896
+				'type'  => 'hidden',
2897
+				'value' => $this->_reg_event->ID(),
2898
+			),
2899
+		);
2900
+		// if the cart is empty then we know we're at step one so we'll display ticket selector
2901
+		$cart = EE_Registry::instance()->SSN->cart();
2902
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2903
+		switch ($step) {
2904
+			case 'ticket':
2905
+				$hidden_fields['processing_registration']['value'] = 1;
2906
+				$template_args['title'] = esc_html__(
2907
+					'Step One: Select the Ticket for this registration',
2908
+					'event_espresso'
2909
+				);
2910
+				$template_args['content'] =
2911
+					EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2912
+				$template_args['content'] .= '</div>';
2913
+				$template_args['step_button_text'] = esc_html__(
2914
+					'Add Tickets and Continue to Registrant Details',
2915
+					'event_espresso'
2916
+				);
2917
+				$template_args['show_notification_toggle'] = false;
2918
+				break;
2919
+			case 'questions':
2920
+				$hidden_fields['processing_registration']['value'] = 2;
2921
+				$template_args['title'] = esc_html__(
2922
+					'Step Two: Add Registrant Details for this Registration',
2923
+					'event_espresso'
2924
+				);
2925
+				// in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2926
+				// properly by the first process_reg_step run.
2927
+				$template_args['content'] =
2928
+					EED_Single_Page_Checkout::registration_checkout_for_admin();
2929
+				$template_args['step_button_text'] = esc_html__(
2930
+					'Save Registration and Continue to Details',
2931
+					'event_espresso'
2932
+				);
2933
+				$template_args['show_notification_toggle'] = true;
2934
+				break;
2935
+		}
2936
+		// we come back to the process_registration_step route.
2937
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2938
+		return EEH_Template::display_template(
2939
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2940
+			$template_args,
2941
+			true
2942
+		);
2943
+	}
2944
+
2945
+
2946
+	/**
2947
+	 *        set_reg_event
2948
+	 *
2949
+	 * @access private
2950
+	 * @return bool
2951
+	 * @throws EE_Error
2952
+	 * @throws InvalidArgumentException
2953
+	 * @throws InvalidDataTypeException
2954
+	 * @throws InvalidInterfaceException
2955
+	 */
2956
+	private function _set_reg_event()
2957
+	{
2958
+		if (is_object($this->_reg_event)) {
2959
+			return true;
2960
+		}
2961
+		$EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2962
+		if (! $EVT_ID) {
2963
+			return false;
2964
+		}
2965
+		$this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2966
+		return true;
2967
+	}
2968
+
2969
+
2970
+	/**
2971
+	 * process_reg_step
2972
+	 *
2973
+	 * @access        public
2974
+	 * @return string
2975
+	 * @throws DomainException
2976
+	 * @throws EE_Error
2977
+	 * @throws InvalidArgumentException
2978
+	 * @throws InvalidDataTypeException
2979
+	 * @throws InvalidInterfaceException
2980
+	 * @throws ReflectionException
2981
+	 * @throws RuntimeException
2982
+	 */
2983
+	public function process_reg_step()
2984
+	{
2985
+		EE_System::do_not_cache();
2986
+		$this->_set_reg_event();
2987
+		EE_Registry::instance()->REQ->set_espresso_page(true);
2988
+		EE_Registry::instance()->REQ->set('uts', time());
2989
+		// what step are we on?
2990
+		$cart = EE_Registry::instance()->SSN->cart();
2991
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2992
+		// if doing ajax then we need to verify the nonce
2993
+		if (defined('DOING_AJAX')) {
2994
+			$nonce = isset($this->_req_data[ $this->_req_nonce ])
2995
+				? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) : '';
2996
+			$this->_verify_nonce($nonce, $this->_req_nonce);
2997
+		}
2998
+		switch ($step) {
2999
+			case 'ticket':
3000
+				// process ticket selection
3001
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
3002
+				if ($success) {
3003
+					EE_Error::add_success(
3004
+						esc_html__(
3005
+							'Tickets Selected. Now complete the registration.',
3006
+							'event_espresso'
3007
+						)
3008
+					);
3009
+				} else {
3010
+					$query_args['step_error'] = $this->_req_data['step_error'] = true;
3011
+				}
3012
+				if (defined('DOING_AJAX')) {
3013
+					$this->new_registration(); // display next step
3014
+				} else {
3015
+					$query_args = array(
3016
+						'action'                  => 'new_registration',
3017
+						'processing_registration' => 1,
3018
+						'event_id'                => $this->_reg_event->ID(),
3019
+						'uts'                     => time(),
3020
+					);
3021
+					$this->_redirect_after_action(
3022
+						false,
3023
+						'',
3024
+						'',
3025
+						$query_args,
3026
+						true
3027
+					);
3028
+				}
3029
+				break;
3030
+			case 'questions':
3031
+				if (! isset(
3032
+					$this->_req_data['txn_reg_status_change'],
3033
+					$this->_req_data['txn_reg_status_change']['send_notifications']
3034
+				)
3035
+				) {
3036
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3037
+				}
3038
+				// process registration
3039
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3040
+				if ($cart instanceof EE_Cart) {
3041
+					$grand_total = $cart->get_cart_grand_total();
3042
+					if ($grand_total instanceof EE_Line_Item) {
3043
+						$grand_total->save_this_and_descendants_to_txn();
3044
+					}
3045
+				}
3046
+				if (! $transaction instanceof EE_Transaction) {
3047
+					$query_args = array(
3048
+						'action'                  => 'new_registration',
3049
+						'processing_registration' => 2,
3050
+						'event_id'                => $this->_reg_event->ID(),
3051
+						'uts'                     => time(),
3052
+					);
3053
+					if (defined('DOING_AJAX')) {
3054
+						// display registration form again because there are errors (maybe validation?)
3055
+						$this->new_registration();
3056
+						return;
3057
+					}
3058
+					$this->_redirect_after_action(
3059
+						false,
3060
+						'',
3061
+						'',
3062
+						$query_args,
3063
+						true
3064
+					);
3065
+					return;
3066
+				}
3067
+				// maybe update status, and make sure to save transaction if not done already
3068
+				if (! $transaction->update_status_based_on_total_paid()) {
3069
+					$transaction->save();
3070
+				}
3071
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3072
+				$this->_req_data = array();
3073
+				$query_args = array(
3074
+					'action'        => 'redirect_to_txn',
3075
+					'TXN_ID'        => $transaction->ID(),
3076
+					'EVT_ID'        => $this->_reg_event->ID(),
3077
+					'event_name'    => urlencode($this->_reg_event->name()),
3078
+					'redirect_from' => 'new_registration',
3079
+				);
3080
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3081
+				break;
3082
+		}
3083
+		// what are you looking here for?  Should be nothing to do at this point.
3084
+	}
3085
+
3086
+
3087
+	/**
3088
+	 * redirect_to_txn
3089
+	 *
3090
+	 * @access public
3091
+	 * @return void
3092
+	 * @throws EE_Error
3093
+	 * @throws InvalidArgumentException
3094
+	 * @throws InvalidDataTypeException
3095
+	 * @throws InvalidInterfaceException
3096
+	 * @throws ReflectionException
3097
+	 */
3098
+	public function redirect_to_txn()
3099
+	{
3100
+		EE_System::do_not_cache();
3101
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3102
+		$query_args = array(
3103
+			'action' => 'view_transaction',
3104
+			'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3105
+			'page'   => 'espresso_transactions',
3106
+		);
3107
+		if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3108
+			$query_args['EVT_ID'] = $this->_req_data['EVT_ID'];
3109
+			$query_args['event_name'] = urlencode($this->_req_data['event_name']);
3110
+			$query_args['redirect_from'] = $this->_req_data['redirect_from'];
3111
+		}
3112
+		EE_Error::add_success(
3113
+			esc_html__(
3114
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3115
+				'event_espresso'
3116
+			)
3117
+		);
3118
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3119
+	}
3120
+
3121
+
3122
+	/**
3123
+	 *        generates HTML for the Attendee Contact List
3124
+	 *
3125
+	 * @access protected
3126
+	 * @return void
3127
+	 * @throws DomainException
3128
+	 * @throws EE_Error
3129
+	 */
3130
+	protected function _attendee_contact_list_table()
3131
+	{
3132
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3133
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3134
+		$this->display_admin_list_table_page_with_no_sidebar();
3135
+	}
3136
+
3137
+
3138
+	/**
3139
+	 *        get_attendees
3140
+	 *
3141
+	 * @param      $per_page
3142
+	 * @param bool $count whether to return count or data.
3143
+	 * @param bool $trash
3144
+	 * @return array
3145
+	 * @throws EE_Error
3146
+	 * @throws InvalidArgumentException
3147
+	 * @throws InvalidDataTypeException
3148
+	 * @throws InvalidInterfaceException
3149
+	 * @access public
3150
+	 */
3151
+	public function get_attendees($per_page, $count = false, $trash = false)
3152
+	{
3153
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3154
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3155
+		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3156
+		switch ($this->_req_data['orderby']) {
3157
+			case 'ATT_ID':
3158
+				$orderby = 'ATT_ID';
3159
+				break;
3160
+			case 'ATT_fname':
3161
+				$orderby = 'ATT_fname';
3162
+				break;
3163
+			case 'ATT_email':
3164
+				$orderby = 'ATT_email';
3165
+				break;
3166
+			case 'ATT_city':
3167
+				$orderby = 'ATT_city';
3168
+				break;
3169
+			case 'STA_ID':
3170
+				$orderby = 'STA_ID';
3171
+				break;
3172
+			case 'CNT_ID':
3173
+				$orderby = 'CNT_ID';
3174
+				break;
3175
+			case 'Registration_Count':
3176
+				$orderby = 'Registration_Count';
3177
+				break;
3178
+			default:
3179
+				$orderby = 'ATT_lname';
3180
+		}
3181
+		$sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3182
+			? $this->_req_data['order']
3183
+			: 'ASC';
3184
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3185
+			? $this->_req_data['paged']
3186
+			: 1;
3187
+		$per_page = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3188
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3189
+			? $this->_req_data['perpage']
3190
+			: $per_page;
3191
+		$_where = array();
3192
+		if (! empty($this->_req_data['s'])) {
3193
+			$sstr = '%' . $this->_req_data['s'] . '%';
3194
+			$_where['OR'] = array(
3195
+				'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3196
+				'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3197
+				'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3198
+				'ATT_fname'                         => array('LIKE', $sstr),
3199
+				'ATT_lname'                         => array('LIKE', $sstr),
3200
+				'ATT_short_bio'                     => array('LIKE', $sstr),
3201
+				'ATT_email'                         => array('LIKE', $sstr),
3202
+				'ATT_address'                       => array('LIKE', $sstr),
3203
+				'ATT_address2'                      => array('LIKE', $sstr),
3204
+				'ATT_city'                          => array('LIKE', $sstr),
3205
+				'Country.CNT_name'                  => array('LIKE', $sstr),
3206
+				'State.STA_name'                    => array('LIKE', $sstr),
3207
+				'ATT_phone'                         => array('LIKE', $sstr),
3208
+				'Registration.REG_final_price'      => array('LIKE', $sstr),
3209
+				'Registration.REG_code'             => array('LIKE', $sstr),
3210
+				'Registration.REG_group_size'       => array('LIKE', $sstr),
3211
+			);
3212
+		}
3213
+		$offset = ($current_page - 1) * $per_page;
3214
+		$limit = $count ? null : array($offset, $per_page);
3215
+		$query_args = array(
3216
+			$_where,
3217
+			'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3218
+			'limit'         => $limit,
3219
+		);
3220
+		if (! $count) {
3221
+			$query_args['order_by'] = array($orderby => $sort);
3222
+		}
3223
+		if ($trash) {
3224
+			$query_args[0]['status'] = array('!=', 'publish');
3225
+			$all_attendees = $count
3226
+				? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3227
+				: $this->getAttendeeModel()->get_all($query_args);
3228
+		} else {
3229
+			$query_args[0]['status'] = array('IN', array('publish'));
3230
+			$all_attendees = $count
3231
+				? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3232
+				: $this->getAttendeeModel()->get_all($query_args);
3233
+		}
3234
+		return $all_attendees;
3235
+	}
3236
+
3237
+
3238
+	/**
3239
+	 * This is just taking care of resending the registration confirmation
3240
+	 *
3241
+	 * @access protected
3242
+	 * @return void
3243
+	 * @throws EE_Error
3244
+	 * @throws InvalidArgumentException
3245
+	 * @throws InvalidDataTypeException
3246
+	 * @throws InvalidInterfaceException
3247
+	 * @throws ReflectionException
3248
+	 */
3249
+	protected function _resend_registration()
3250
+	{
3251
+		$this->_process_resend_registration();
3252
+		$query_args = isset($this->_req_data['redirect_to'])
3253
+			? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3254
+			: array('action' => 'default');
3255
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3256
+	}
3257
+
3258
+	/**
3259
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3260
+	 * to use when selecting registrations
3261
+	 *
3262
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3263
+	 *                                                     the query parameters from the request
3264
+	 * @return void ends the request with a redirect or download
3265
+	 */
3266
+	public function _registrations_report_base($method_name_for_getting_query_params)
3267
+	{
3268
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3269
+			wp_redirect(
3270
+				EE_Admin_Page::add_query_args_and_nonce(
3271
+					array(
3272
+						'page'        => 'espresso_batch',
3273
+						'batch'       => 'file',
3274
+						'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3275
+						'filters'     => urlencode(
3276
+							serialize(
3277
+								$this->$method_name_for_getting_query_params(
3278
+									EEH_Array::is_set(
3279
+										$this->_req_data,
3280
+										'filters',
3281
+										array()
3282
+									)
3283
+								)
3284
+							)
3285
+						),
3286
+						'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3287
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3288
+						'return_url'  => urlencode($this->_req_data['return_url']),
3289
+					)
3290
+				)
3291
+			);
3292
+		} else {
3293
+			$new_request_args = array(
3294
+				'export' => 'report',
3295
+				'action' => 'registrations_report_for_event',
3296
+				'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3297
+			);
3298
+			$this->_req_data = array_merge($this->_req_data, $new_request_args);
3299
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3300
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3301
+				$EE_Export = EE_Export::instance($this->_req_data);
3302
+				$EE_Export->export();
3303
+			}
3304
+		}
3305
+	}
3306
+
3307
+
3308
+	/**
3309
+	 * Creates a registration report using only query parameters in the request
3310
+	 *
3311
+	 * @return void
3312
+	 */
3313
+	public function _registrations_report()
3314
+	{
3315
+		$this->_registrations_report_base('_get_registration_query_parameters');
3316
+	}
3317
+
3318
+
3319
+	public function _contact_list_export()
3320
+	{
3321
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3322
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3323
+			$EE_Export = EE_Export::instance($this->_req_data);
3324
+			$EE_Export->export_attendees();
3325
+		}
3326
+	}
3327
+
3328
+
3329
+	public function _contact_list_report()
3330
+	{
3331
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3332
+			wp_redirect(
3333
+				EE_Admin_Page::add_query_args_and_nonce(
3334
+					array(
3335
+						'page'        => 'espresso_batch',
3336
+						'batch'       => 'file',
3337
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3338
+						'return_url'  => urlencode($this->_req_data['return_url']),
3339
+					)
3340
+				)
3341
+			);
3342
+		} else {
3343
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3344
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3345
+				$EE_Export = EE_Export::instance($this->_req_data);
3346
+				$EE_Export->report_attendees();
3347
+			}
3348
+		}
3349
+	}
3350
+
3351
+
3352
+
3353
+
3354
+
3355
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3356
+	/**
3357
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3358
+	 *
3359
+	 * @return void
3360
+	 * @throws EE_Error
3361
+	 * @throws InvalidArgumentException
3362
+	 * @throws InvalidDataTypeException
3363
+	 * @throws InvalidInterfaceException
3364
+	 * @throws ReflectionException
3365
+	 */
3366
+	protected function _duplicate_attendee()
3367
+	{
3368
+		$action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3369
+		// verify we have necessary info
3370
+		if (empty($this->_req_data['_REG_ID'])) {
3371
+			EE_Error::add_error(
3372
+				esc_html__(
3373
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3374
+					'event_espresso'
3375
+				),
3376
+				__FILE__,
3377
+				__LINE__,
3378
+				__FUNCTION__
3379
+			);
3380
+			$query_args = array('action' => $action);
3381
+			$this->_redirect_after_action('', '', '', $query_args, true);
3382
+		}
3383
+		// okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3384
+		$registration = $this->getRegistrationModel()->get_one_by_ID($this->_req_data['_REG_ID']);
3385
+		$attendee = $registration->attendee();
3386
+		// remove relation of existing attendee on registration
3387
+		$registration->_remove_relation_to($attendee, 'Attendee');
3388
+		// new attendee
3389
+		$new_attendee = clone $attendee;
3390
+		$new_attendee->set('ATT_ID', 0);
3391
+		$new_attendee->save();
3392
+		// add new attendee to reg
3393
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3394
+		EE_Error::add_success(
3395
+			esc_html__(
3396
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3397
+				'event_espresso'
3398
+			)
3399
+		);
3400
+		// redirect to edit page for attendee
3401
+		$query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3402
+		$this->_redirect_after_action('', '', '', $query_args, true);
3403
+	}
3404
+
3405
+
3406
+	/**
3407
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3408
+	 *
3409
+	 * @param int     $post_id
3410
+	 * @param WP_POST $post
3411
+	 * @throws DomainException
3412
+	 * @throws EE_Error
3413
+	 * @throws InvalidArgumentException
3414
+	 * @throws InvalidDataTypeException
3415
+	 * @throws InvalidInterfaceException
3416
+	 * @throws LogicException
3417
+	 * @throws InvalidFormSubmissionException
3418
+	 * @throws ReflectionException
3419
+	 */
3420
+	protected function _insert_update_cpt_item($post_id, $post)
3421
+	{
3422
+		$success = true;
3423
+		$attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3424
+			? $this->getAttendeeModel()->get_one_by_ID($post_id)
3425
+			: null;
3426
+		// for attendee updates
3427
+		if ($attendee instanceof EE_Attendee) {
3428
+			// note we should only be UPDATING attendees at this point.
3429
+			$updated_fields = array(
3430
+				'ATT_fname'     => $this->_req_data['ATT_fname'],
3431
+				'ATT_lname'     => $this->_req_data['ATT_lname'],
3432
+				'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3433
+				'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3434
+				'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3435
+				'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3436
+				'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3437
+				'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3438
+				'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3439
+			);
3440
+			foreach ($updated_fields as $field => $value) {
3441
+				$attendee->set($field, $value);
3442
+			}
3443
+
3444
+			// process contact details metabox form handler (which will also save the attendee)
3445
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3446
+			$success = $contact_details_form->process($this->_req_data);
3447
+
3448
+			$attendee_update_callbacks = apply_filters(
3449
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3450
+				array()
3451
+			);
3452
+			foreach ($attendee_update_callbacks as $a_callback) {
3453
+				if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3454
+					throw new EE_Error(
3455
+						sprintf(
3456
+							esc_html__(
3457
+								'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3458
+								'event_espresso'
3459
+							),
3460
+							$a_callback
3461
+						)
3462
+					);
3463
+				}
3464
+			}
3465
+		}
3466
+
3467
+		if ($success === false) {
3468
+			EE_Error::add_error(
3469
+				esc_html__(
3470
+					'Something went wrong with updating the meta table data for the registration.',
3471
+					'event_espresso'
3472
+				),
3473
+				__FILE__,
3474
+				__FUNCTION__,
3475
+				__LINE__
3476
+			);
3477
+		}
3478
+	}
3479
+
3480
+
3481
+	public function trash_cpt_item($post_id)
3482
+	{
3483
+	}
3484
+
3485
+
3486
+	public function delete_cpt_item($post_id)
3487
+	{
3488
+	}
3489
+
3490
+
3491
+	public function restore_cpt_item($post_id)
3492
+	{
3493
+	}
3494
+
3495
+
3496
+	protected function _restore_cpt_item($post_id, $revision_id)
3497
+	{
3498
+	}
3499
+
3500
+
3501
+	/**
3502
+	 * @throws EE_Error
3503
+	 * @since 4.10.2.p
3504
+	 */
3505
+	public function attendee_editor_metaboxes()
3506
+	{
3507
+		$this->verify_cpt_object();
3508
+		remove_meta_box(
3509
+			'postexcerpt',
3510
+			$this->_cpt_routes[ $this->_req_action ],
3511
+			'normal'
3512
+		);
3513
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal', 'core');
3514
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3515
+			add_meta_box(
3516
+				'postexcerpt',
3517
+				esc_html__('Short Biography', 'event_espresso'),
3518
+				'post_excerpt_meta_box',
3519
+				$this->_cpt_routes[ $this->_req_action ],
3520
+				'normal'
3521
+			);
3522
+		}
3523
+		if (post_type_supports('espresso_attendees', 'comments')) {
3524
+			add_meta_box(
3525
+				'commentsdiv',
3526
+				esc_html__('Notes on the Contact', 'event_espresso'),
3527
+				'post_comment_meta_box',
3528
+				$this->_cpt_routes[ $this->_req_action ],
3529
+				'normal',
3530
+				'core'
3531
+			);
3532
+		}
3533
+		add_meta_box(
3534
+			'attendee_contact_info',
3535
+			esc_html__('Contact Info', 'event_espresso'),
3536
+			array($this, 'attendee_contact_info'),
3537
+			$this->_cpt_routes[ $this->_req_action ],
3538
+			'side',
3539
+			'core'
3540
+		);
3541
+		add_meta_box(
3542
+			'attendee_details_address',
3543
+			esc_html__('Address Details', 'event_espresso'),
3544
+			array($this, 'attendee_address_details'),
3545
+			$this->_cpt_routes[ $this->_req_action ],
3546
+			'normal',
3547
+			'core'
3548
+		);
3549
+		add_meta_box(
3550
+			'attendee_registrations',
3551
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3552
+			array($this, 'attendee_registrations_meta_box'),
3553
+			$this->_cpt_routes[ $this->_req_action ],
3554
+			'normal',
3555
+			'high'
3556
+		);
3557
+	}
3558
+
3559
+
3560
+	/**
3561
+	 * Metabox for attendee contact info
3562
+	 *
3563
+	 * @param  WP_Post $post wp post object
3564
+	 * @return string attendee contact info ( and form )
3565
+	 * @throws EE_Error
3566
+	 * @throws InvalidArgumentException
3567
+	 * @throws InvalidDataTypeException
3568
+	 * @throws InvalidInterfaceException
3569
+	 * @throws LogicException
3570
+	 * @throws DomainException
3571
+	 */
3572
+	public function attendee_contact_info($post)
3573
+	{
3574
+		// get attendee object ( should already have it )
3575
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3576
+		$form->enqueueStylesAndScripts();
3577
+		echo $form->display();
3578
+	}
3579
+
3580
+
3581
+	/**
3582
+	 * Return form handler for the contact details metabox
3583
+	 *
3584
+	 * @param EE_Attendee $attendee
3585
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3586
+	 * @throws DomainException
3587
+	 * @throws InvalidArgumentException
3588
+	 * @throws InvalidDataTypeException
3589
+	 * @throws InvalidInterfaceException
3590
+	 */
3591
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3592
+	{
3593
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3594
+	}
3595
+
3596
+
3597
+	/**
3598
+	 * Metabox for attendee details
3599
+	 *
3600
+	 * @param  WP_Post $post wp post object
3601
+	 * @throws DomainException
3602
+	 */
3603
+	public function attendee_address_details($post)
3604
+	{
3605
+		// get attendee object (should already have it)
3606
+		$this->_template_args['attendee'] = $this->_cpt_model_obj;
3607
+		$this->_template_args['state_html'] = EEH_Form_Fields::generate_form_input(
3608
+			new EE_Question_Form_Input(
3609
+				EE_Question::new_instance(
3610
+					array(
3611
+						'QST_ID'           => 0,
3612
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3613
+						'QST_system'       => 'admin-state',
3614
+					)
3615
+				),
3616
+				EE_Answer::new_instance(
3617
+					array(
3618
+						'ANS_ID'    => 0,
3619
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3620
+					)
3621
+				),
3622
+				array(
3623
+					'input_id'       => 'STA_ID',
3624
+					'input_name'     => 'STA_ID',
3625
+					'input_prefix'   => '',
3626
+					'append_qstn_id' => false,
3627
+				)
3628
+			)
3629
+		);
3630
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3631
+			new EE_Question_Form_Input(
3632
+				EE_Question::new_instance(
3633
+					array(
3634
+						'QST_ID'           => 0,
3635
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3636
+						'QST_system'       => 'admin-country',
3637
+					)
3638
+				),
3639
+				EE_Answer::new_instance(
3640
+					array(
3641
+						'ANS_ID'    => 0,
3642
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3643
+					)
3644
+				),
3645
+				array(
3646
+					'input_id'       => 'CNT_ISO',
3647
+					'input_name'     => 'CNT_ISO',
3648
+					'input_prefix'   => '',
3649
+					'append_qstn_id' => false,
3650
+				)
3651
+			)
3652
+		);
3653
+		$template =
3654
+			REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3655
+		EEH_Template::display_template($template, $this->_template_args);
3656
+	}
3657
+
3658
+
3659
+	/**
3660
+	 *        _attendee_details
3661
+	 *
3662
+	 * @access protected
3663
+	 * @param $post
3664
+	 * @return void
3665
+	 * @throws DomainException
3666
+	 * @throws EE_Error
3667
+	 * @throws InvalidArgumentException
3668
+	 * @throws InvalidDataTypeException
3669
+	 * @throws InvalidInterfaceException
3670
+	 * @throws ReflectionException
3671
+	 */
3672
+	public function attendee_registrations_meta_box($post)
3673
+	{
3674
+		$this->_template_args['attendee'] = $this->_cpt_model_obj;
3675
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3676
+		$template =
3677
+			REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3678
+		EEH_Template::display_template($template, $this->_template_args);
3679
+	}
3680
+
3681
+
3682
+	/**
3683
+	 * add in the form fields for the attendee edit
3684
+	 *
3685
+	 * @param  WP_Post $post wp post object
3686
+	 * @return string html for new form.
3687
+	 * @throws DomainException
3688
+	 */
3689
+	public function after_title_form_fields($post)
3690
+	{
3691
+		if ($post->post_type === 'espresso_attendees') {
3692
+			$template = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3693
+			$template_args['attendee'] = $this->_cpt_model_obj;
3694
+			EEH_Template::display_template($template, $template_args);
3695
+		}
3696
+	}
3697
+
3698
+
3699
+	/**
3700
+	 *        _trash_or_restore_attendee
3701
+	 *
3702
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3703
+	 * @return void
3704
+	 * @throws EE_Error
3705
+	 * @throws InvalidArgumentException
3706
+	 * @throws InvalidDataTypeException
3707
+	 * @throws InvalidInterfaceException
3708
+	 * @throws ReflectionException
3709
+	 * @access protected
3710
+	 */
3711
+	protected function _trash_or_restore_attendees($trash = true)
3712
+	{
3713
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3714
+		$success = 1;
3715
+		// Checkboxes
3716
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3717
+			// if array has more than one element than success message should be plural
3718
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3719
+			// cycle thru checkboxes
3720
+			foreach ($this->_req_data['checkbox'] as $ATT_ID) {
3721
+				$updated = $trash ? $this->getAttendeeModel()->update_by_ID(array('status' => 'trash'), $ATT_ID)
3722
+					: $this->getAttendeeModel()->update_by_ID(array('status' => 'publish'), $ATT_ID);
3723
+				if (! $updated) {
3724
+					$success = 0;
3725
+				}
3726
+			}
3727
+		} else {
3728
+			// grab single id and delete
3729
+			$ATT_ID = absint($this->_req_data['ATT_ID']);
3730
+			// get attendee
3731
+			$att = $this->getAttendeeModel()->get_one_by_ID($ATT_ID);
3732
+			$updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3733
+			$updated = $att->save() && $updated;
3734
+			if (! $updated) {
3735
+				$success = 0;
3736
+			}
3737
+		}
3738
+		$what = $success > 1
3739
+			? esc_html__('Contacts', 'event_espresso')
3740
+			: esc_html__('Contact', 'event_espresso');
3741
+		$action_desc = $trash
3742
+			? esc_html__('moved to the trash', 'event_espresso')
3743
+			: esc_html__('restored', 'event_espresso');
3744
+		$this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3745
+	}
3746 3746
 }
Please login to merge, or discard this patch.
core/services/assets/Registry.php 1 patch
Indentation   +773 added lines, -773 removed lines patch added patch discarded remove patch
@@ -26,784 +26,784 @@
 block discarded – undo
26 26
 class Registry
27 27
 {
28 28
 
29
-    const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json';
30
-
31
-    /**
32
-     * @var AssetCollection $assets
33
-     */
34
-    protected $assets;
35
-
36
-    /**
37
-     * @var I18nRegistry
38
-     */
39
-    private $i18n_registry;
40
-
41
-    /**
42
-     * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
43
-     *
44
-     * @var array
45
-     */
46
-    protected $jsdata = array();
47
-
48
-    /**
49
-     * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
50
-     * page source.
51
-     *
52
-     * @var array
53
-     */
54
-    private $script_handles_with_data = array();
55
-
56
-
57
-    /**
58
-     * Holds the manifest data obtained from registered manifest files.
59
-     * Manifests are maps of asset chunk name to actual built asset file names.
60
-     * Shape of this array is:
61
-     * array(
62
-     *  'some_namespace_slug' => array(
63
-     *      'some_chunk_name' => array(
64
-     *          'js' => 'filename.js'
65
-     *          'css' => 'filename.js'
66
-     *      ),
67
-     *      'url_base' => 'https://baseurl.com/to/assets
68
-     *  )
69
-     * )
70
-     *
71
-     * @var array
72
-     */
73
-    private $manifest_data = array();
74
-
75
-
76
-    /**
77
-     * Holds any dependency data obtained from registered dependency map json.
78
-     * Dependency map json is generated via the @wordpress/dependency-extraction-webpack-plugin via the webpack config.
79
-     * @see https://github.com/WordPress/gutenberg/tree/master/packages/dependency-extraction-webpack-plugin
80
-     *
81
-     * @var array
82
-     */
83
-    private $dependencies_data = [];
84
-
85
-
86
-    /**
87
-     * This is a known array of possible wp css handles that correspond to what may be exposed as dependencies in our
88
-     * build process.  Currently the dependency export process in webpack does not consider css imports, so we derive
89
-     * them via the js dependencies (WP uses the same handle for both js and css). This is a list of known handles that
90
-     * are used for both js and css.
91
-     * @var array
92
-     */
93
-    private $wp_css_handle_dependencies = [
94
-        'wp-components',
95
-        'wp-block-editor',
96
-        'wp-block-library',
97
-        'wp-edit-post',
98
-        'wp-edit-widgets',
99
-        'wp-editor',
100
-        'wp-format-library',
101
-        'wp-list-reusable-blocks',
102
-        'wp-nux',
103
-    ];
104
-
105
-
106
-    /**
107
-     * Registry constructor.
108
-     * Hooking into WP actions for script registry.
109
-     *
110
-     * @param AssetCollection      $assets
111
-     * @param I18nRegistry         $i18n_registry
112
-     * @throws InvalidArgumentException
113
-     * @throws InvalidDataTypeException
114
-     * @throws InvalidInterfaceException
115
-     */
116
-    public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry)
117
-    {
118
-        $this->assets = $assets;
119
-        $this->i18n_registry = $i18n_registry;
120
-        add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
121
-        add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
122
-        add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
123
-        add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
124
-        add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4);
125
-        add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4);
126
-        add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
127
-        add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
128
-    }
129
-
130
-
131
-    /**
132
-     * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n
133
-     * translation handling.
134
-     *
135
-     * @return I18nRegistry
136
-     */
137
-    public function getI18nRegistry()
138
-    {
139
-        return $this->i18n_registry;
140
-    }
141
-
142
-
143
-    /**
144
-     * Callback for the wp_enqueue_scripts actions used to register assets.
145
-     *
146
-     * @since 4.9.62.p
147
-     * @throws Exception
148
-     */
149
-    public function registerScriptsAndStyles()
150
-    {
151
-        try {
152
-            $this->registerScripts($this->assets->getJavascriptAssets());
153
-            $this->registerStyles($this->assets->getStylesheetAssets());
154
-        } catch (Exception $exception) {
155
-            new ExceptionStackTraceDisplay($exception);
156
-        }
157
-    }
158
-
159
-
160
-    /**
161
-     * Registers JS assets with WP core
162
-     *
163
-     * @param JavascriptAsset[] $scripts
164
-     * @throws AssetRegistrationException
165
-     * @throws InvalidDataTypeException
166
-     * @throws DomainException
167
-     * @since 4.9.62.p
168
-     */
169
-    public function registerScripts(array $scripts)
170
-    {
171
-        foreach ($scripts as $script) {
172
-            // skip to next script if this has already been done
173
-            if ($script->isRegistered()) {
174
-                continue;
175
-            }
176
-            do_action(
177
-                'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
178
-                $script
179
-            );
180
-            $registered = wp_register_script(
181
-                $script->handle(),
182
-                $script->source(),
183
-                $script->dependencies(),
184
-                $script->version(),
185
-                $script->loadInFooter()
186
-            );
187
-            if (! $registered && $this->debug()) {
188
-                throw new AssetRegistrationException($script->handle());
189
-            }
190
-            $script->setRegistered($registered);
191
-            if ($script->requiresTranslation()) {
192
-                $this->registerTranslation($script->handle());
193
-            }
194
-            do_action(
195
-                'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script',
196
-                $script
197
-            );
198
-        }
199
-    }
200
-
201
-
202
-    /**
203
-     * Registers CSS assets with WP core
204
-     *
205
-     * @param StylesheetAsset[] $styles
206
-     * @throws InvalidDataTypeException
207
-     * @throws DomainException
208
-     * @since 4.9.62.p
209
-     */
210
-    public function registerStyles(array $styles)
211
-    {
212
-        foreach ($styles as $style) {
213
-            // skip to next style if this has already been done
214
-            if ($style->isRegistered()) {
215
-                continue;
216
-            }
217
-            do_action(
218
-                'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style',
219
-                $style
220
-            );
221
-            wp_register_style(
222
-                $style->handle(),
223
-                $style->source(),
224
-                $style->dependencies(),
225
-                $style->version(),
226
-                $style->media()
227
-            );
228
-            $style->setRegistered();
229
-            do_action(
230
-                'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style',
231
-                $style
232
-            );
233
-        }
234
-    }
235
-
236
-
237
-    /**
238
-     * Call back for the script print in frontend and backend.
239
-     * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
240
-     *
241
-     * @since 4.9.31.rc.015
242
-     */
243
-    public function enqueueData()
244
-    {
245
-        $this->removeAlreadyRegisteredDataForScriptHandles();
246
-        wp_add_inline_script(
247
-            'eejs-core',
248
-            'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)),
249
-            'before'
250
-        );
251
-        $scripts = $this->assets->getJavascriptAssetsWithData();
252
-        foreach ($scripts as $script) {
253
-            $this->addRegisteredScriptHandlesWithData($script->handle());
254
-            if ($script->hasInlineDataCallback()) {
255
-                $localize = $script->inlineDataCallback();
256
-                $localize();
257
-            }
258
-        }
259
-    }
260
-
261
-
262
-    /**
263
-     * Used to add data to eejs.data object.
264
-     * Note:  Overriding existing data is not allowed.
265
-     * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
266
-     * If the data you add is something like this:
267
-     *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
268
-     * It will be exposed in the page source as:
269
-     *  eejs.data.my_plugin_data.foo == gar
270
-     *
271
-     * @param string       $key   Key used to access your data
272
-     * @param string|array $value Value to attach to key
273
-     * @throws InvalidArgumentException
274
-     */
275
-    public function addData($key, $value)
276
-    {
277
-        if ($this->verifyDataNotExisting($key)) {
278
-            $this->jsdata[ $key ] = $value;
279
-        }
280
-    }
281
-
282
-
283
-    /**
284
-     * Similar to addData except this allows for users to push values to an existing key where the values on key are
285
-     * elements in an array.
286
-     *
287
-     * When you use this method, the value you include will be merged with the array on $key.
288
-     * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript
289
-     * object like this, eejs.data.test = [ my_data,
290
-     * ]
291
-     * If there has already been a scalar value attached to the data object given key (via addData for instance), then
292
-     * this will throw an exception.
293
-     *
294
-     * Caution: Only add data using this method if you are okay with the potential for additional data added on the same
295
-     * key potentially overriding the existing data on merge (specifically with associative arrays).
296
-     *
297
-     * @param string       $key   Key to attach data to.
298
-     * @param string|array $value Value being registered.
299
-     * @throws InvalidArgumentException
300
-     */
301
-    public function pushData($key, $value)
302
-    {
303
-        if (isset($this->jsdata[ $key ])
304
-            && ! is_array($this->jsdata[ $key ])
305
-        ) {
306
-            if (! $this->debug()) {
307
-                return;
308
-            }
309
-            throw new InvalidArgumentException(
310
-                sprintf(
311
-                    __(
312
-                        'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
29
+	const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json';
30
+
31
+	/**
32
+	 * @var AssetCollection $assets
33
+	 */
34
+	protected $assets;
35
+
36
+	/**
37
+	 * @var I18nRegistry
38
+	 */
39
+	private $i18n_registry;
40
+
41
+	/**
42
+	 * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
43
+	 *
44
+	 * @var array
45
+	 */
46
+	protected $jsdata = array();
47
+
48
+	/**
49
+	 * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
50
+	 * page source.
51
+	 *
52
+	 * @var array
53
+	 */
54
+	private $script_handles_with_data = array();
55
+
56
+
57
+	/**
58
+	 * Holds the manifest data obtained from registered manifest files.
59
+	 * Manifests are maps of asset chunk name to actual built asset file names.
60
+	 * Shape of this array is:
61
+	 * array(
62
+	 *  'some_namespace_slug' => array(
63
+	 *      'some_chunk_name' => array(
64
+	 *          'js' => 'filename.js'
65
+	 *          'css' => 'filename.js'
66
+	 *      ),
67
+	 *      'url_base' => 'https://baseurl.com/to/assets
68
+	 *  )
69
+	 * )
70
+	 *
71
+	 * @var array
72
+	 */
73
+	private $manifest_data = array();
74
+
75
+
76
+	/**
77
+	 * Holds any dependency data obtained from registered dependency map json.
78
+	 * Dependency map json is generated via the @wordpress/dependency-extraction-webpack-plugin via the webpack config.
79
+	 * @see https://github.com/WordPress/gutenberg/tree/master/packages/dependency-extraction-webpack-plugin
80
+	 *
81
+	 * @var array
82
+	 */
83
+	private $dependencies_data = [];
84
+
85
+
86
+	/**
87
+	 * This is a known array of possible wp css handles that correspond to what may be exposed as dependencies in our
88
+	 * build process.  Currently the dependency export process in webpack does not consider css imports, so we derive
89
+	 * them via the js dependencies (WP uses the same handle for both js and css). This is a list of known handles that
90
+	 * are used for both js and css.
91
+	 * @var array
92
+	 */
93
+	private $wp_css_handle_dependencies = [
94
+		'wp-components',
95
+		'wp-block-editor',
96
+		'wp-block-library',
97
+		'wp-edit-post',
98
+		'wp-edit-widgets',
99
+		'wp-editor',
100
+		'wp-format-library',
101
+		'wp-list-reusable-blocks',
102
+		'wp-nux',
103
+	];
104
+
105
+
106
+	/**
107
+	 * Registry constructor.
108
+	 * Hooking into WP actions for script registry.
109
+	 *
110
+	 * @param AssetCollection      $assets
111
+	 * @param I18nRegistry         $i18n_registry
112
+	 * @throws InvalidArgumentException
113
+	 * @throws InvalidDataTypeException
114
+	 * @throws InvalidInterfaceException
115
+	 */
116
+	public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry)
117
+	{
118
+		$this->assets = $assets;
119
+		$this->i18n_registry = $i18n_registry;
120
+		add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
121
+		add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
122
+		add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
123
+		add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
124
+		add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4);
125
+		add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4);
126
+		add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
127
+		add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
128
+	}
129
+
130
+
131
+	/**
132
+	 * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n
133
+	 * translation handling.
134
+	 *
135
+	 * @return I18nRegistry
136
+	 */
137
+	public function getI18nRegistry()
138
+	{
139
+		return $this->i18n_registry;
140
+	}
141
+
142
+
143
+	/**
144
+	 * Callback for the wp_enqueue_scripts actions used to register assets.
145
+	 *
146
+	 * @since 4.9.62.p
147
+	 * @throws Exception
148
+	 */
149
+	public function registerScriptsAndStyles()
150
+	{
151
+		try {
152
+			$this->registerScripts($this->assets->getJavascriptAssets());
153
+			$this->registerStyles($this->assets->getStylesheetAssets());
154
+		} catch (Exception $exception) {
155
+			new ExceptionStackTraceDisplay($exception);
156
+		}
157
+	}
158
+
159
+
160
+	/**
161
+	 * Registers JS assets with WP core
162
+	 *
163
+	 * @param JavascriptAsset[] $scripts
164
+	 * @throws AssetRegistrationException
165
+	 * @throws InvalidDataTypeException
166
+	 * @throws DomainException
167
+	 * @since 4.9.62.p
168
+	 */
169
+	public function registerScripts(array $scripts)
170
+	{
171
+		foreach ($scripts as $script) {
172
+			// skip to next script if this has already been done
173
+			if ($script->isRegistered()) {
174
+				continue;
175
+			}
176
+			do_action(
177
+				'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
178
+				$script
179
+			);
180
+			$registered = wp_register_script(
181
+				$script->handle(),
182
+				$script->source(),
183
+				$script->dependencies(),
184
+				$script->version(),
185
+				$script->loadInFooter()
186
+			);
187
+			if (! $registered && $this->debug()) {
188
+				throw new AssetRegistrationException($script->handle());
189
+			}
190
+			$script->setRegistered($registered);
191
+			if ($script->requiresTranslation()) {
192
+				$this->registerTranslation($script->handle());
193
+			}
194
+			do_action(
195
+				'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script',
196
+				$script
197
+			);
198
+		}
199
+	}
200
+
201
+
202
+	/**
203
+	 * Registers CSS assets with WP core
204
+	 *
205
+	 * @param StylesheetAsset[] $styles
206
+	 * @throws InvalidDataTypeException
207
+	 * @throws DomainException
208
+	 * @since 4.9.62.p
209
+	 */
210
+	public function registerStyles(array $styles)
211
+	{
212
+		foreach ($styles as $style) {
213
+			// skip to next style if this has already been done
214
+			if ($style->isRegistered()) {
215
+				continue;
216
+			}
217
+			do_action(
218
+				'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style',
219
+				$style
220
+			);
221
+			wp_register_style(
222
+				$style->handle(),
223
+				$style->source(),
224
+				$style->dependencies(),
225
+				$style->version(),
226
+				$style->media()
227
+			);
228
+			$style->setRegistered();
229
+			do_action(
230
+				'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style',
231
+				$style
232
+			);
233
+		}
234
+	}
235
+
236
+
237
+	/**
238
+	 * Call back for the script print in frontend and backend.
239
+	 * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
240
+	 *
241
+	 * @since 4.9.31.rc.015
242
+	 */
243
+	public function enqueueData()
244
+	{
245
+		$this->removeAlreadyRegisteredDataForScriptHandles();
246
+		wp_add_inline_script(
247
+			'eejs-core',
248
+			'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)),
249
+			'before'
250
+		);
251
+		$scripts = $this->assets->getJavascriptAssetsWithData();
252
+		foreach ($scripts as $script) {
253
+			$this->addRegisteredScriptHandlesWithData($script->handle());
254
+			if ($script->hasInlineDataCallback()) {
255
+				$localize = $script->inlineDataCallback();
256
+				$localize();
257
+			}
258
+		}
259
+	}
260
+
261
+
262
+	/**
263
+	 * Used to add data to eejs.data object.
264
+	 * Note:  Overriding existing data is not allowed.
265
+	 * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
266
+	 * If the data you add is something like this:
267
+	 *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
268
+	 * It will be exposed in the page source as:
269
+	 *  eejs.data.my_plugin_data.foo == gar
270
+	 *
271
+	 * @param string       $key   Key used to access your data
272
+	 * @param string|array $value Value to attach to key
273
+	 * @throws InvalidArgumentException
274
+	 */
275
+	public function addData($key, $value)
276
+	{
277
+		if ($this->verifyDataNotExisting($key)) {
278
+			$this->jsdata[ $key ] = $value;
279
+		}
280
+	}
281
+
282
+
283
+	/**
284
+	 * Similar to addData except this allows for users to push values to an existing key where the values on key are
285
+	 * elements in an array.
286
+	 *
287
+	 * When you use this method, the value you include will be merged with the array on $key.
288
+	 * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript
289
+	 * object like this, eejs.data.test = [ my_data,
290
+	 * ]
291
+	 * If there has already been a scalar value attached to the data object given key (via addData for instance), then
292
+	 * this will throw an exception.
293
+	 *
294
+	 * Caution: Only add data using this method if you are okay with the potential for additional data added on the same
295
+	 * key potentially overriding the existing data on merge (specifically with associative arrays).
296
+	 *
297
+	 * @param string       $key   Key to attach data to.
298
+	 * @param string|array $value Value being registered.
299
+	 * @throws InvalidArgumentException
300
+	 */
301
+	public function pushData($key, $value)
302
+	{
303
+		if (isset($this->jsdata[ $key ])
304
+			&& ! is_array($this->jsdata[ $key ])
305
+		) {
306
+			if (! $this->debug()) {
307
+				return;
308
+			}
309
+			throw new InvalidArgumentException(
310
+				sprintf(
311
+					__(
312
+						'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
313 313
                          push values to this data element when it is an array.',
314
-                        'event_espresso'
315
-                    ),
316
-                    $key,
317
-                    __METHOD__
318
-                )
319
-            );
320
-        }
321
-        if ( ! isset( $this->jsdata[ $key ] ) ) {
322
-            $this->jsdata[ $key ] = is_array($value) ? $value : [$value];
323
-        } else {
324
-            $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value);
325
-        }
326
-    }
327
-
328
-
329
-    /**
330
-     * Used to set content used by javascript for a template.
331
-     * Note: Overrides of existing registered templates are not allowed.
332
-     *
333
-     * @param string $template_reference
334
-     * @param string $template_content
335
-     * @throws InvalidArgumentException
336
-     */
337
-    public function addTemplate($template_reference, $template_content)
338
-    {
339
-        if (! isset($this->jsdata['templates'])) {
340
-            $this->jsdata['templates'] = array();
341
-        }
342
-        //no overrides allowed.
343
-        if (isset($this->jsdata['templates'][ $template_reference ])) {
344
-            if (! $this->debug()) {
345
-                return;
346
-            }
347
-            throw new InvalidArgumentException(
348
-                sprintf(
349
-                    __(
350
-                        'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
351
-                        'event_espresso'
352
-                    ),
353
-                    $template_reference
354
-                )
355
-            );
356
-        }
357
-        $this->jsdata['templates'][ $template_reference ] = $template_content;
358
-    }
359
-
360
-
361
-    /**
362
-     * Retrieve the template content already registered for the given reference.
363
-     *
364
-     * @param string $template_reference
365
-     * @return string
366
-     */
367
-    public function getTemplate($template_reference)
368
-    {
369
-        return isset($this->jsdata['templates'][ $template_reference ])
370
-            ? $this->jsdata['templates'][ $template_reference ]
371
-            : '';
372
-    }
373
-
374
-
375
-    /**
376
-     * Retrieve registered data.
377
-     *
378
-     * @param string $key Name of key to attach data to.
379
-     * @return mixed                If there is no for the given key, then false is returned.
380
-     */
381
-    public function getData($key)
382
-    {
383
-        return isset($this->jsdata[ $key ])
384
-            ? $this->jsdata[ $key ]
385
-            : false;
386
-    }
387
-
388
-
389
-    /**
390
-     * Verifies whether the given data exists already on the jsdata array.
391
-     * Overriding data is not allowed.
392
-     *
393
-     * @param string $key Index for data.
394
-     * @return bool        If valid then return true.
395
-     * @throws InvalidArgumentException if data already exists.
396
-     */
397
-    protected function verifyDataNotExisting($key)
398
-    {
399
-        if (isset($this->jsdata[ $key ])) {
400
-            if (! $this->debug()) {
401
-                return false;
402
-            }
403
-            if (is_array($this->jsdata[ $key ])) {
404
-                throw new InvalidArgumentException(
405
-                    sprintf(
406
-                        __(
407
-                            'The value for %1$s already exists in the Registry::eejs object.
314
+						'event_espresso'
315
+					),
316
+					$key,
317
+					__METHOD__
318
+				)
319
+			);
320
+		}
321
+		if ( ! isset( $this->jsdata[ $key ] ) ) {
322
+			$this->jsdata[ $key ] = is_array($value) ? $value : [$value];
323
+		} else {
324
+			$this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value);
325
+		}
326
+	}
327
+
328
+
329
+	/**
330
+	 * Used to set content used by javascript for a template.
331
+	 * Note: Overrides of existing registered templates are not allowed.
332
+	 *
333
+	 * @param string $template_reference
334
+	 * @param string $template_content
335
+	 * @throws InvalidArgumentException
336
+	 */
337
+	public function addTemplate($template_reference, $template_content)
338
+	{
339
+		if (! isset($this->jsdata['templates'])) {
340
+			$this->jsdata['templates'] = array();
341
+		}
342
+		//no overrides allowed.
343
+		if (isset($this->jsdata['templates'][ $template_reference ])) {
344
+			if (! $this->debug()) {
345
+				return;
346
+			}
347
+			throw new InvalidArgumentException(
348
+				sprintf(
349
+					__(
350
+						'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
351
+						'event_espresso'
352
+					),
353
+					$template_reference
354
+				)
355
+			);
356
+		}
357
+		$this->jsdata['templates'][ $template_reference ] = $template_content;
358
+	}
359
+
360
+
361
+	/**
362
+	 * Retrieve the template content already registered for the given reference.
363
+	 *
364
+	 * @param string $template_reference
365
+	 * @return string
366
+	 */
367
+	public function getTemplate($template_reference)
368
+	{
369
+		return isset($this->jsdata['templates'][ $template_reference ])
370
+			? $this->jsdata['templates'][ $template_reference ]
371
+			: '';
372
+	}
373
+
374
+
375
+	/**
376
+	 * Retrieve registered data.
377
+	 *
378
+	 * @param string $key Name of key to attach data to.
379
+	 * @return mixed                If there is no for the given key, then false is returned.
380
+	 */
381
+	public function getData($key)
382
+	{
383
+		return isset($this->jsdata[ $key ])
384
+			? $this->jsdata[ $key ]
385
+			: false;
386
+	}
387
+
388
+
389
+	/**
390
+	 * Verifies whether the given data exists already on the jsdata array.
391
+	 * Overriding data is not allowed.
392
+	 *
393
+	 * @param string $key Index for data.
394
+	 * @return bool        If valid then return true.
395
+	 * @throws InvalidArgumentException if data already exists.
396
+	 */
397
+	protected function verifyDataNotExisting($key)
398
+	{
399
+		if (isset($this->jsdata[ $key ])) {
400
+			if (! $this->debug()) {
401
+				return false;
402
+			}
403
+			if (is_array($this->jsdata[ $key ])) {
404
+				throw new InvalidArgumentException(
405
+					sprintf(
406
+						__(
407
+							'The value for %1$s already exists in the Registry::eejs object.
408 408
                             Overrides are not allowed. Since the value of this data is an array, you may want to use the
409 409
                             %2$s method to push your value to the array.',
410
-                            'event_espresso'
411
-                        ),
412
-                        $key,
413
-                        'pushData()'
414
-                    )
415
-                );
416
-            }
417
-            throw new InvalidArgumentException(
418
-                sprintf(
419
-                    __(
420
-                        'The value for %1$s already exists in the Registry::eejs object. Overrides are not
410
+							'event_espresso'
411
+						),
412
+						$key,
413
+						'pushData()'
414
+					)
415
+				);
416
+			}
417
+			throw new InvalidArgumentException(
418
+				sprintf(
419
+					__(
420
+						'The value for %1$s already exists in the Registry::eejs object. Overrides are not
421 421
                         allowed.  Consider attaching your value to a different key',
422
-                        'event_espresso'
423
-                    ),
424
-                    $key
425
-                )
426
-            );
427
-        }
428
-        return true;
429
-    }
430
-
431
-
432
-    /**
433
-     * Get the actual asset path for asset manifests.
434
-     * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned.
435
-     *
436
-     * @param string $namespace  The namespace associated with the manifest file hosting the map of chunk_name to actual
437
-     *                           asset file location.
438
-     * @param string $chunk_name
439
-     * @param string $asset_type
440
-     * @return string
441
-     * @since 4.9.59.p
442
-     */
443
-    public function getAssetUrl($namespace, $chunk_name, $asset_type)
444
-    {
445
-        $url = isset(
446
-            $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ],
447
-            $this->manifest_data[ $namespace ]['url_base']
448
-        )
449
-            ? $this->manifest_data[ $namespace ]['url_base']
450
-              . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ]
451
-            : $chunk_name;
452
-
453
-        return apply_filters(
454
-            'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl',
455
-            $url,
456
-            $namespace,
457
-            $chunk_name,
458
-            $asset_type
459
-        );
460
-    }
461
-
462
-
463
-
464
-    /**
465
-     * Return the url to a js file for the given namespace and chunk name.
466
-     *
467
-     * @param string $namespace
468
-     * @param string $chunk_name
469
-     * @return string
470
-     */
471
-    public function getJsUrl($namespace, $chunk_name)
472
-    {
473
-        return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS);
474
-    }
475
-
476
-
477
-    /**
478
-     * Return the url to a css file for the given namespace and chunk name.
479
-     *
480
-     * @param string $namespace
481
-     * @param string $chunk_name
482
-     * @return string
483
-     */
484
-    public function getCssUrl($namespace, $chunk_name)
485
-    {
486
-        return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS);
487
-    }
488
-
489
-
490
-    /**
491
-     * Return the dependencies array and version string for a given asset $chunk_name
492
-     *
493
-     * @param string $namespace
494
-     * @param string $chunk_name
495
-     * @param string $asset_type
496
-     * @return array
497
-     * @since 4.9.82.p
498
-     */
499
-    private function getDetailsForAsset($namespace, $chunk_name, $asset_type)
500
-    {
501
-        $asset_index = $chunk_name . '.' . $asset_type;
502
-        if (! isset( $this->dependencies_data[ $namespace ][ $asset_index ])) {
503
-            $path = isset($this->manifest_data[ $namespace ]['path'])
504
-                ? $this->manifest_data[ $namespace ]['path']
505
-                : '';
506
-            $dependencies_index = $chunk_name . '.' . Asset::TYPE_PHP;
507
-            $file_path = isset($this->manifest_data[ $namespace ][ $dependencies_index ])
508
-                ? $path . $this->manifest_data[ $namespace ][ $dependencies_index ]
509
-                :
510
-                '';
511
-            $this->dependencies_data[ $namespace ][ $asset_index ] = $file_path !== '' && file_exists($file_path)
512
-                ? $this->getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name)
513
-                : [];
514
-        }
515
-        $details = $this->dependencies_data[ $namespace ][ $asset_index ];
516
-        return $details;
517
-    }
518
-
519
-
520
-    /**
521
-     * Return dependencies array and version string according to asset type.
522
-     * For css assets, this filters the auto generated dependencies by css type.
523
-     *
524
-     * @param string $namespace
525
-     * @param string $asset_type
526
-     * @param string $file_path
527
-     * @param string $chunk_name
528
-     * @return array
529
-     * @since 4.9.82.p
530
-     */
531
-    private function getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name)
532
-    {
533
-        // $asset_dependencies = json_decode(file_get_contents($file_path), true);
534
-        $asset_details = require($file_path);
535
-        $asset_details['dependencies'] = isset($asset_details['dependencies'])
536
-            ? $asset_details['dependencies']
537
-            : [];
538
-        $asset_details['version'] = isset($asset_details['version'])
539
-            ? $asset_details['version']
540
-            : '';
541
-        if ($asset_type === Asset::TYPE_JS) {
542
-            $asset_details['dependencies'] =  $chunk_name === 'eejs-core'
543
-                ? $asset_details['dependencies']
544
-                : $asset_details['dependencies'] + [ CoreAssetManager::JS_HANDLE_JS_CORE ];
545
-            return $asset_details;
546
-        }
547
-        // for css we need to make sure there is actually a css file related to this chunk.
548
-        if (isset($this->manifest_data[ $namespace ])) {
549
-            // array of css chunk files for ee.
550
-            $css_chunks = array_map(
551
-                static function ($value) {
552
-                    return str_replace('.css', '', $value);
553
-                },
554
-                array_filter(
555
-                    array_keys($this->manifest_data[ $namespace ]),
556
-                    static function ($value) {
557
-                        return strpos($value, '.css') !== false;
558
-                    }
559
-                )
560
-            );
561
-            // add known wp chunks with css
562
-            $css_chunks = array_merge( $css_chunks, $this->wp_css_handle_dependencies);
563
-            // flip for easier search
564
-            $css_chunks = array_flip($css_chunks);
565
-            // now let's filter the dependencies for the incoming chunk to actual chunks that have styles
566
-            $asset_details['dependencies'] = array_filter(
567
-                $asset_details['dependencies'],
568
-                static function ($chunk_name) use ($css_chunks) {
569
-                    return isset($css_chunks[ $chunk_name ]);
570
-                }
571
-            );
572
-            return $asset_details;
573
-        }
574
-        return ['dependencies' => [], 'version' => ''];
575
-    }
576
-
577
-
578
-    /**
579
-     * Get the dependencies array and version string for the given js asset chunk name
580
-     *
581
-     * @param string $namespace
582
-     * @param string $chunk_name
583
-     * @return array
584
-     * @since 4.10.2.p
585
-     */
586
-    public function getJsAssetDetails($namespace, $chunk_name)
587
-    {
588
-        return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_JS);
589
-    }
590
-
591
-
592
-    /**
593
-     * Get the dependencies array and version string for the given css asset chunk name
594
-     *
595
-     * @param string $namespace
596
-     * @param string $chunk_name
597
-     * @return array
598
-     * @since 4.10.2.p
599
-     */
600
-    public function getCssAssetDetails($namespace, $chunk_name)
601
-    {
602
-        return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_CSS);
603
-    }
604
-
605
-
606
-    /**
607
-     * @since 4.9.62.p
608
-     * @throws InvalidArgumentException
609
-     * @throws InvalidFilePathException
610
-     */
611
-    public function registerManifestFiles()
612
-    {
613
-        $manifest_files = $this->assets->getManifestFiles();
614
-        foreach ($manifest_files as $manifest_file) {
615
-            $this->registerManifestFile(
616
-                $manifest_file->assetNamespace(),
617
-                $manifest_file->urlBase(),
618
-                $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST,
619
-                $manifest_file->filepath()
620
-            );
621
-        }
622
-    }
623
-
624
-
625
-    /**
626
-     * Used to register a js/css manifest file with the registered_manifest_files property.
627
-     *
628
-     * @param string $namespace     Provided to associate the manifest file with a specific namespace.
629
-     * @param string $url_base      The url base for the manifest file location.
630
-     * @param string $manifest_file The absolute path to the manifest file.
631
-     * @param string $manifest_file_path  The path to the folder containing the manifest file. If not provided will be
632
-     *                                    default to `plugin_root/assets/dist`.
633
-     * @throws InvalidArgumentException
634
-     * @throws InvalidFilePathException
635
-     * @since 4.9.59.p
636
-     */
637
-    public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '')
638
-    {
639
-        if (isset($this->manifest_data[ $namespace ])) {
640
-            if (! $this->debug()) {
641
-                return;
642
-            }
643
-            throw new InvalidArgumentException(
644
-                sprintf(
645
-                    esc_html__(
646
-                        'The namespace for this manifest file has already been registered, choose a namespace other than %s',
647
-                        'event_espresso'
648
-                    ),
649
-                    $namespace
650
-                )
651
-            );
652
-        }
653
-        if (filter_var($url_base, FILTER_VALIDATE_URL) === false) {
654
-            if (is_admin()) {
655
-                EE_Error::add_error(
656
-                    sprintf(
657
-                        esc_html__(
658
-                            'The url given for %1$s assets is invalid.  The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant',
659
-                            'event_espresso'
660
-                        ),
661
-                        'Event Espresso',
662
-                        $url_base,
663
-                        'plugins_url',
664
-                        'WP_PLUGIN_URL'
665
-                    ),
666
-                    __FILE__,
667
-                    __FUNCTION__,
668
-                    __LINE__
669
-                );
670
-            }
671
-            return;
672
-        }
673
-        $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file);
674
-        if (! isset($this->manifest_data[ $namespace ]['url_base'])) {
675
-            $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base);
676
-        }
677
-        if (! isset($this->manifest_data[ $namespace ]['path'])) {
678
-            $this->manifest_data[ $namespace ]['path'] = $manifest_file_path;
679
-        }
680
-    }
681
-
682
-
683
-    /**
684
-     * Decodes json from the provided manifest file.
685
-     *
686
-     * @since 4.9.59.p
687
-     * @param string $manifest_file Path to manifest file.
688
-     * @return array
689
-     * @throws InvalidFilePathException
690
-     */
691
-    private function decodeManifestFile($manifest_file)
692
-    {
693
-        if (! file_exists($manifest_file)) {
694
-            throw new InvalidFilePathException($manifest_file);
695
-        }
696
-        return json_decode(file_get_contents($manifest_file), true);
697
-    }
698
-
699
-
700
-    /**
701
-     * This is used to set registered script handles that have data.
702
-     *
703
-     * @param string $script_handle
704
-     */
705
-    private function addRegisteredScriptHandlesWithData($script_handle)
706
-    {
707
-        $this->script_handles_with_data[ $script_handle ] = $script_handle;
708
-    }
709
-
710
-
711
-    /**i
422
+						'event_espresso'
423
+					),
424
+					$key
425
+				)
426
+			);
427
+		}
428
+		return true;
429
+	}
430
+
431
+
432
+	/**
433
+	 * Get the actual asset path for asset manifests.
434
+	 * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned.
435
+	 *
436
+	 * @param string $namespace  The namespace associated with the manifest file hosting the map of chunk_name to actual
437
+	 *                           asset file location.
438
+	 * @param string $chunk_name
439
+	 * @param string $asset_type
440
+	 * @return string
441
+	 * @since 4.9.59.p
442
+	 */
443
+	public function getAssetUrl($namespace, $chunk_name, $asset_type)
444
+	{
445
+		$url = isset(
446
+			$this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ],
447
+			$this->manifest_data[ $namespace ]['url_base']
448
+		)
449
+			? $this->manifest_data[ $namespace ]['url_base']
450
+			  . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ]
451
+			: $chunk_name;
452
+
453
+		return apply_filters(
454
+			'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl',
455
+			$url,
456
+			$namespace,
457
+			$chunk_name,
458
+			$asset_type
459
+		);
460
+	}
461
+
462
+
463
+
464
+	/**
465
+	 * Return the url to a js file for the given namespace and chunk name.
466
+	 *
467
+	 * @param string $namespace
468
+	 * @param string $chunk_name
469
+	 * @return string
470
+	 */
471
+	public function getJsUrl($namespace, $chunk_name)
472
+	{
473
+		return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS);
474
+	}
475
+
476
+
477
+	/**
478
+	 * Return the url to a css file for the given namespace and chunk name.
479
+	 *
480
+	 * @param string $namespace
481
+	 * @param string $chunk_name
482
+	 * @return string
483
+	 */
484
+	public function getCssUrl($namespace, $chunk_name)
485
+	{
486
+		return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS);
487
+	}
488
+
489
+
490
+	/**
491
+	 * Return the dependencies array and version string for a given asset $chunk_name
492
+	 *
493
+	 * @param string $namespace
494
+	 * @param string $chunk_name
495
+	 * @param string $asset_type
496
+	 * @return array
497
+	 * @since 4.9.82.p
498
+	 */
499
+	private function getDetailsForAsset($namespace, $chunk_name, $asset_type)
500
+	{
501
+		$asset_index = $chunk_name . '.' . $asset_type;
502
+		if (! isset( $this->dependencies_data[ $namespace ][ $asset_index ])) {
503
+			$path = isset($this->manifest_data[ $namespace ]['path'])
504
+				? $this->manifest_data[ $namespace ]['path']
505
+				: '';
506
+			$dependencies_index = $chunk_name . '.' . Asset::TYPE_PHP;
507
+			$file_path = isset($this->manifest_data[ $namespace ][ $dependencies_index ])
508
+				? $path . $this->manifest_data[ $namespace ][ $dependencies_index ]
509
+				:
510
+				'';
511
+			$this->dependencies_data[ $namespace ][ $asset_index ] = $file_path !== '' && file_exists($file_path)
512
+				? $this->getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name)
513
+				: [];
514
+		}
515
+		$details = $this->dependencies_data[ $namespace ][ $asset_index ];
516
+		return $details;
517
+	}
518
+
519
+
520
+	/**
521
+	 * Return dependencies array and version string according to asset type.
522
+	 * For css assets, this filters the auto generated dependencies by css type.
523
+	 *
524
+	 * @param string $namespace
525
+	 * @param string $asset_type
526
+	 * @param string $file_path
527
+	 * @param string $chunk_name
528
+	 * @return array
529
+	 * @since 4.9.82.p
530
+	 */
531
+	private function getDetailsForAssetType($namespace, $asset_type, $file_path, $chunk_name)
532
+	{
533
+		// $asset_dependencies = json_decode(file_get_contents($file_path), true);
534
+		$asset_details = require($file_path);
535
+		$asset_details['dependencies'] = isset($asset_details['dependencies'])
536
+			? $asset_details['dependencies']
537
+			: [];
538
+		$asset_details['version'] = isset($asset_details['version'])
539
+			? $asset_details['version']
540
+			: '';
541
+		if ($asset_type === Asset::TYPE_JS) {
542
+			$asset_details['dependencies'] =  $chunk_name === 'eejs-core'
543
+				? $asset_details['dependencies']
544
+				: $asset_details['dependencies'] + [ CoreAssetManager::JS_HANDLE_JS_CORE ];
545
+			return $asset_details;
546
+		}
547
+		// for css we need to make sure there is actually a css file related to this chunk.
548
+		if (isset($this->manifest_data[ $namespace ])) {
549
+			// array of css chunk files for ee.
550
+			$css_chunks = array_map(
551
+				static function ($value) {
552
+					return str_replace('.css', '', $value);
553
+				},
554
+				array_filter(
555
+					array_keys($this->manifest_data[ $namespace ]),
556
+					static function ($value) {
557
+						return strpos($value, '.css') !== false;
558
+					}
559
+				)
560
+			);
561
+			// add known wp chunks with css
562
+			$css_chunks = array_merge( $css_chunks, $this->wp_css_handle_dependencies);
563
+			// flip for easier search
564
+			$css_chunks = array_flip($css_chunks);
565
+			// now let's filter the dependencies for the incoming chunk to actual chunks that have styles
566
+			$asset_details['dependencies'] = array_filter(
567
+				$asset_details['dependencies'],
568
+				static function ($chunk_name) use ($css_chunks) {
569
+					return isset($css_chunks[ $chunk_name ]);
570
+				}
571
+			);
572
+			return $asset_details;
573
+		}
574
+		return ['dependencies' => [], 'version' => ''];
575
+	}
576
+
577
+
578
+	/**
579
+	 * Get the dependencies array and version string for the given js asset chunk name
580
+	 *
581
+	 * @param string $namespace
582
+	 * @param string $chunk_name
583
+	 * @return array
584
+	 * @since 4.10.2.p
585
+	 */
586
+	public function getJsAssetDetails($namespace, $chunk_name)
587
+	{
588
+		return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_JS);
589
+	}
590
+
591
+
592
+	/**
593
+	 * Get the dependencies array and version string for the given css asset chunk name
594
+	 *
595
+	 * @param string $namespace
596
+	 * @param string $chunk_name
597
+	 * @return array
598
+	 * @since 4.10.2.p
599
+	 */
600
+	public function getCssAssetDetails($namespace, $chunk_name)
601
+	{
602
+		return $this->getDetailsForAsset($namespace, $chunk_name, Asset::TYPE_CSS);
603
+	}
604
+
605
+
606
+	/**
607
+	 * @since 4.9.62.p
608
+	 * @throws InvalidArgumentException
609
+	 * @throws InvalidFilePathException
610
+	 */
611
+	public function registerManifestFiles()
612
+	{
613
+		$manifest_files = $this->assets->getManifestFiles();
614
+		foreach ($manifest_files as $manifest_file) {
615
+			$this->registerManifestFile(
616
+				$manifest_file->assetNamespace(),
617
+				$manifest_file->urlBase(),
618
+				$manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST,
619
+				$manifest_file->filepath()
620
+			);
621
+		}
622
+	}
623
+
624
+
625
+	/**
626
+	 * Used to register a js/css manifest file with the registered_manifest_files property.
627
+	 *
628
+	 * @param string $namespace     Provided to associate the manifest file with a specific namespace.
629
+	 * @param string $url_base      The url base for the manifest file location.
630
+	 * @param string $manifest_file The absolute path to the manifest file.
631
+	 * @param string $manifest_file_path  The path to the folder containing the manifest file. If not provided will be
632
+	 *                                    default to `plugin_root/assets/dist`.
633
+	 * @throws InvalidArgumentException
634
+	 * @throws InvalidFilePathException
635
+	 * @since 4.9.59.p
636
+	 */
637
+	public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '')
638
+	{
639
+		if (isset($this->manifest_data[ $namespace ])) {
640
+			if (! $this->debug()) {
641
+				return;
642
+			}
643
+			throw new InvalidArgumentException(
644
+				sprintf(
645
+					esc_html__(
646
+						'The namespace for this manifest file has already been registered, choose a namespace other than %s',
647
+						'event_espresso'
648
+					),
649
+					$namespace
650
+				)
651
+			);
652
+		}
653
+		if (filter_var($url_base, FILTER_VALIDATE_URL) === false) {
654
+			if (is_admin()) {
655
+				EE_Error::add_error(
656
+					sprintf(
657
+						esc_html__(
658
+							'The url given for %1$s assets is invalid.  The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant',
659
+							'event_espresso'
660
+						),
661
+						'Event Espresso',
662
+						$url_base,
663
+						'plugins_url',
664
+						'WP_PLUGIN_URL'
665
+					),
666
+					__FILE__,
667
+					__FUNCTION__,
668
+					__LINE__
669
+				);
670
+			}
671
+			return;
672
+		}
673
+		$this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file);
674
+		if (! isset($this->manifest_data[ $namespace ]['url_base'])) {
675
+			$this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base);
676
+		}
677
+		if (! isset($this->manifest_data[ $namespace ]['path'])) {
678
+			$this->manifest_data[ $namespace ]['path'] = $manifest_file_path;
679
+		}
680
+	}
681
+
682
+
683
+	/**
684
+	 * Decodes json from the provided manifest file.
685
+	 *
686
+	 * @since 4.9.59.p
687
+	 * @param string $manifest_file Path to manifest file.
688
+	 * @return array
689
+	 * @throws InvalidFilePathException
690
+	 */
691
+	private function decodeManifestFile($manifest_file)
692
+	{
693
+		if (! file_exists($manifest_file)) {
694
+			throw new InvalidFilePathException($manifest_file);
695
+		}
696
+		return json_decode(file_get_contents($manifest_file), true);
697
+	}
698
+
699
+
700
+	/**
701
+	 * This is used to set registered script handles that have data.
702
+	 *
703
+	 * @param string $script_handle
704
+	 */
705
+	private function addRegisteredScriptHandlesWithData($script_handle)
706
+	{
707
+		$this->script_handles_with_data[ $script_handle ] = $script_handle;
708
+	}
709
+
710
+
711
+	/**i
712 712
      * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the
713 713
      * Dependency stored in WP_Scripts if its set.
714 714
      */
715
-    private function removeAlreadyRegisteredDataForScriptHandles()
716
-    {
717
-        if (empty($this->script_handles_with_data)) {
718
-            return;
719
-        }
720
-        foreach ($this->script_handles_with_data as $script_handle) {
721
-            $this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
722
-        }
723
-    }
724
-
725
-
726
-    /**
727
-     * Removes any data dependency registered in WP_Scripts if its set.
728
-     *
729
-     * @param string $script_handle
730
-     */
731
-    private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
732
-    {
733
-        if (isset($this->script_handles_with_data[ $script_handle ])) {
734
-            global $wp_scripts;
735
-            $unset_handle = false;
736
-            if ($wp_scripts->get_data($script_handle, 'data')) {
737
-                unset($wp_scripts->registered[ $script_handle ]->extra['data']);
738
-                $unset_handle = true;
739
-            }
740
-            //deal with inline_scripts
741
-            if ($wp_scripts->get_data($script_handle, 'before')) {
742
-                unset($wp_scripts->registered[ $script_handle ]->extra['before']);
743
-                $unset_handle = true;
744
-            }
745
-            if ($wp_scripts->get_data($script_handle, 'after')) {
746
-                unset($wp_scripts->registered[ $script_handle ]->extra['after']);
747
-            }
748
-            if ($unset_handle) {
749
-                unset($this->script_handles_with_data[ $script_handle ]);
750
-            }
751
-        }
752
-    }
753
-
754
-
755
-    /**
756
-     * register translations for a registered script
757
-     *
758
-     * @param string $handle
759
-     */
760
-    public function registerTranslation($handle)
761
-    {
762
-        $this->i18n_registry->registerScriptI18n($handle);
763
-    }
764
-
765
-
766
-    /**
767
-     * @since 4.9.63.p
768
-     * @return bool
769
-     */
770
-    private function debug()
771
-    {
772
-        return apply_filters(
773
-            'FHEE__EventEspresso_core_services_assets_Registry__debug',
774
-            defined('EE_DEBUG') && EE_DEBUG
775
-        );
776
-    }
777
-
778
-
779
-    /**
780
-     * Get the dependencies array for the given js asset chunk name
781
-     *
782
-     * @param string $namespace
783
-     * @param string $chunk_name
784
-     * @return array
785
-     * @deprecated 4.10.2.p
786
-     * @since 4.9.82.p
787
-     */
788
-    public function getJsDependencies($namespace, $chunk_name)
789
-    {
790
-        $details = $this->getJsAssetDetails($namespace, $chunk_name);
791
-        return isset($details['dependencies']) ? $details['dependencies'] : [];
792
-    }
793
-
794
-
795
-    /**
796
-     * Get the dependencies array for the given css asset chunk name
797
-     *
798
-     * @param string $namespace
799
-     * @param string $chunk_name
800
-     * @return array
801
-     * @deprecated 4.10.2.p
802
-     * @since      4.9.82.p
803
-     */
804
-    public function getCssDependencies($namespace, $chunk_name)
805
-    {
806
-        $details = $this->getCssAssetDetails($namespace, $chunk_name);
807
-        return isset($details['dependencies']) ? $details['dependencies'] : [];
808
-    }
715
+	private function removeAlreadyRegisteredDataForScriptHandles()
716
+	{
717
+		if (empty($this->script_handles_with_data)) {
718
+			return;
719
+		}
720
+		foreach ($this->script_handles_with_data as $script_handle) {
721
+			$this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
722
+		}
723
+	}
724
+
725
+
726
+	/**
727
+	 * Removes any data dependency registered in WP_Scripts if its set.
728
+	 *
729
+	 * @param string $script_handle
730
+	 */
731
+	private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
732
+	{
733
+		if (isset($this->script_handles_with_data[ $script_handle ])) {
734
+			global $wp_scripts;
735
+			$unset_handle = false;
736
+			if ($wp_scripts->get_data($script_handle, 'data')) {
737
+				unset($wp_scripts->registered[ $script_handle ]->extra['data']);
738
+				$unset_handle = true;
739
+			}
740
+			//deal with inline_scripts
741
+			if ($wp_scripts->get_data($script_handle, 'before')) {
742
+				unset($wp_scripts->registered[ $script_handle ]->extra['before']);
743
+				$unset_handle = true;
744
+			}
745
+			if ($wp_scripts->get_data($script_handle, 'after')) {
746
+				unset($wp_scripts->registered[ $script_handle ]->extra['after']);
747
+			}
748
+			if ($unset_handle) {
749
+				unset($this->script_handles_with_data[ $script_handle ]);
750
+			}
751
+		}
752
+	}
753
+
754
+
755
+	/**
756
+	 * register translations for a registered script
757
+	 *
758
+	 * @param string $handle
759
+	 */
760
+	public function registerTranslation($handle)
761
+	{
762
+		$this->i18n_registry->registerScriptI18n($handle);
763
+	}
764
+
765
+
766
+	/**
767
+	 * @since 4.9.63.p
768
+	 * @return bool
769
+	 */
770
+	private function debug()
771
+	{
772
+		return apply_filters(
773
+			'FHEE__EventEspresso_core_services_assets_Registry__debug',
774
+			defined('EE_DEBUG') && EE_DEBUG
775
+		);
776
+	}
777
+
778
+
779
+	/**
780
+	 * Get the dependencies array for the given js asset chunk name
781
+	 *
782
+	 * @param string $namespace
783
+	 * @param string $chunk_name
784
+	 * @return array
785
+	 * @deprecated 4.10.2.p
786
+	 * @since 4.9.82.p
787
+	 */
788
+	public function getJsDependencies($namespace, $chunk_name)
789
+	{
790
+		$details = $this->getJsAssetDetails($namespace, $chunk_name);
791
+		return isset($details['dependencies']) ? $details['dependencies'] : [];
792
+	}
793
+
794
+
795
+	/**
796
+	 * Get the dependencies array for the given css asset chunk name
797
+	 *
798
+	 * @param string $namespace
799
+	 * @param string $chunk_name
800
+	 * @return array
801
+	 * @deprecated 4.10.2.p
802
+	 * @since      4.9.82.p
803
+	 */
804
+	public function getCssDependencies($namespace, $chunk_name)
805
+	{
806
+		$details = $this->getCssAssetDetails($namespace, $chunk_name);
807
+		return isset($details['dependencies']) ? $details['dependencies'] : [];
808
+	}
809 809
 }
Please login to merge, or discard this patch.
core/services/admin/AdminPageHeaderDecoratorInterface.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -13,10 +13,10 @@
 block discarded – undo
13 13
 interface AdminPageHeaderDecoratorInterface
14 14
 {
15 15
 
16
-    /**
17
-     * @param string $text
18
-     * @return string
19
-     * @since 4.10.2.p
20
-     */
21
-    public function getHeaderText($text = '');
16
+	/**
17
+	 * @param string $text
18
+	 * @return string
19
+	 * @since 4.10.2.p
20
+	 */
21
+	public function getHeaderText($text = '');
22 22
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Form_Input_Base.input.php 1 patch
Indentation   +1253 added lines, -1253 removed lines patch added patch discarded remove patch
@@ -11,1257 +11,1257 @@
 block discarded – undo
11 11
 abstract class EE_Form_Input_Base extends EE_Form_Section_Validatable
12 12
 {
13 13
 
14
-    /**
15
-     * the input's name attribute
16
-     *
17
-     * @var string
18
-     */
19
-    protected $_html_name;
20
-
21
-    /**
22
-     * id for the html label tag
23
-     *
24
-     * @var string
25
-     */
26
-    protected $_html_label_id;
27
-
28
-    /**
29
-     * class for teh html label tag
30
-     *
31
-     * @var string
32
-     */
33
-    protected $_html_label_class;
34
-
35
-    /**
36
-     * style for teh html label tag
37
-     *
38
-     * @var string
39
-     */
40
-    protected $_html_label_style;
41
-
42
-    /**
43
-     * text to be placed in the html label
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_html_label_text;
48
-
49
-    /**
50
-     * the full html label. If used, all other html_label_* properties are invalid
51
-     *
52
-     * @var string
53
-     */
54
-    protected $_html_label;
55
-
56
-    /**
57
-     * HTML to use for help text (normally placed below form input), in a span which normally
58
-     * has a class of 'description'
59
-     *
60
-     * @var string
61
-     */
62
-    protected $_html_help_text;
63
-
64
-    /**
65
-     * CSS classes for displaying the help span
66
-     *
67
-     * @var string
68
-     */
69
-    protected $_html_help_class = 'description';
70
-
71
-    /**
72
-     * CSS to put in the style attribute on the help span
73
-     *
74
-     * @var string
75
-     */
76
-    protected $_html_help_style;
77
-
78
-    /**
79
-     * Stores whether or not this input's response is required.
80
-     * Because certain styling elements may also want to know that this
81
-     * input is required etc.
82
-     *
83
-     * @var boolean
84
-     */
85
-    protected $_required;
86
-
87
-    /**
88
-     * css class added to required inputs
89
-     *
90
-     * @var string
91
-     */
92
-    protected $_required_css_class = 'ee-required';
93
-
94
-    /**
95
-     * css styles applied to button type inputs
96
-     *
97
-     * @var string
98
-     */
99
-    protected $_button_css_attributes;
100
-
101
-    /**
102
-     * The raw data submitted for this, like in the $_POST super global.
103
-     * Generally unsafe for usage in client code
104
-     *
105
-     * @var mixed string or array
106
-     */
107
-    protected $_raw_value;
108
-
109
-    /**
110
-     * Value normalized according to the input's normalization strategy.
111
-     * The normalization strategy dictates whether this is a string, int, float,
112
-     * boolean, or array of any of those.
113
-     *
114
-     * @var mixed
115
-     */
116
-    protected $_normalized_value;
117
-
118
-
119
-    /**
120
-     * Normalized default value either initially set on the input, or provided by calling
121
-     * set_default().
122
-     * @var mixed
123
-     */
124
-    protected $_default;
125
-
126
-    /**
127
-     * Strategy used for displaying this field.
128
-     * Child classes must use _get_display_strategy to access it.
129
-     *
130
-     * @var EE_Display_Strategy_Base
131
-     */
132
-    private $_display_strategy;
133
-
134
-    /**
135
-     * Gets all the validation strategies used on this field
136
-     *
137
-     * @var EE_Validation_Strategy_Base[]
138
-     */
139
-    private $_validation_strategies = array();
140
-
141
-    /**
142
-     * The normalization strategy for this field
143
-     *
144
-     * @var EE_Normalization_Strategy_Base
145
-     */
146
-    private $_normalization_strategy;
147
-
148
-    /**
149
-     * Strategy for removing sensitive data after we're done with the form input
150
-     *
151
-     * @var EE_Sensitive_Data_Removal_Base
152
-     */
153
-    protected $_sensitive_data_removal_strategy;
154
-
155
-    /**
156
-     * Whether this input has been disabled or not.
157
-     * If it's disabled while rendering, an extra hidden input is added that indicates it has been knowingly disabled.
158
-     * (Client-side code that wants to dynamically disable it must also add this hidden input).
159
-     * When the form is submitted, if the input is disabled in the PHP formsection, then input is ignored.
160
-     * If the input is missing from the $_REQUEST data but the hidden input indicating the input is disabled, then the input is again ignored.
161
-     *
162
-     * @var boolean
163
-     */
164
-    protected $disabled = false;
165
-
166
-
167
-
168
-    /**
169
-     * @param array                         $input_args       {
170
-     * @type string                         $html_name        the html name for the input
171
-     * @type string                         $html_label_id    the id attribute to give to the html label tag
172
-     * @type string                         $html_label_class the class attribute to give to the html label tag
173
-     * @type string                         $html_label_style the style attribute to give ot teh label tag
174
-     * @type string                         $html_label_text  the text to put in the label tag
175
-     * @type string                         $html_label       the full html label. If used,
176
-     *                                                        all other html_label_* args are invalid
177
-     * @type string                         $html_help_text   text to put in help element
178
-     * @type string                         $html_help_style  style attribute to give to teh help element
179
-     * @type string                         $html_help_class  class attribute to give to the help element
180
-     * @type string                         $default          default value NORMALIZED (eg, if providing the default
181
-     *       for a Yes_No_Input, you should provide TRUE or FALSE, not '1' or '0')
182
-     * @type EE_Display_Strategy_Base       $display          strategy
183
-     * @type EE_Normalization_Strategy_Base $normalization_strategy
184
-     * @type EE_Validation_Strategy_Base[]  $validation_strategies
185
-     * @type boolean                        $ignore_input special argument which can be used to avoid adding any validation strategies,
186
-     *                                                    and sets the normalization strategy to the Null normalization. This is good
187
-     *                                                    when you want the input to be totally ignored server-side (like when using
188
-     *                                                    React.js form inputs)
189
-     *                                                        }
190
-     */
191
-    public function __construct($input_args = array())
192
-    {
193
-        $input_args = (array) apply_filters('FHEE__EE_Form_Input_Base___construct__input_args', $input_args, $this);
194
-        // the following properties must be cast as arrays
195
-        if (isset($input_args['validation_strategies'])) {
196
-            foreach ((array) $input_args['validation_strategies'] as $validation_strategy) {
197
-                if ($validation_strategy instanceof EE_Validation_Strategy_Base && empty($input_args['ignore_input'])) {
198
-                    $this->_validation_strategies[ get_class($validation_strategy) ] = $validation_strategy;
199
-                }
200
-            }
201
-            unset($input_args['validation_strategies']);
202
-        }
203
-        if (isset($input_args['ignore_input'])) {
204
-            $this->_validation_strategies = array();
205
-        }
206
-        // loop thru incoming options
207
-        foreach ($input_args as $key => $value) {
208
-            // add underscore to $key to match property names
209
-            $_key = '_' . $key;
210
-            if (property_exists($this, $_key)) {
211
-                $this->{$_key} = $value;
212
-            }
213
-        }
214
-        // ensure that "required" is set correctly
215
-        $this->set_required(
216
-            $this->_required,
217
-            isset($input_args['required_validation_error_message'])
218
-            ? $input_args['required_validation_error_message']
219
-            : null
220
-        );
221
-        // $this->_html_name_specified = isset( $input_args['html_name'] ) ? TRUE : FALSE;
222
-        $this->_display_strategy->_construct_finalize($this);
223
-        foreach ($this->_validation_strategies as $validation_strategy) {
224
-            $validation_strategy->_construct_finalize($this);
225
-        }
226
-        if (isset($input_args['ignore_input'])) {
227
-            $this->_normalization_strategy = new EE_Null_Normalization();
228
-        }
229
-        if (! $this->_normalization_strategy) {
230
-                $this->_normalization_strategy = new EE_Text_Normalization();
231
-        }
232
-        $this->_normalization_strategy->_construct_finalize($this);
233
-        // at least we can use the normalization strategy to populate the default
234
-        if (isset($input_args['default'])) {
235
-            $this->set_default($input_args['default']);
236
-            unset($input_args['default']);
237
-        }
238
-        if (! $this->_sensitive_data_removal_strategy) {
239
-            $this->_sensitive_data_removal_strategy = new EE_No_Sensitive_Data_Removal();
240
-        }
241
-        $this->_sensitive_data_removal_strategy->_construct_finalize($this);
242
-        parent::__construct($input_args);
243
-    }
244
-
245
-
246
-
247
-    /**
248
-     * Sets the html_name to its default value, if none was specified in teh constructor.
249
-     * Calculation involves using the name and the parent's html_name
250
-     *
251
-     * @throws \EE_Error
252
-     */
253
-    protected function _set_default_html_name_if_empty()
254
-    {
255
-        if (! $this->_html_name) {
256
-            $this->_html_name = $this->name();
257
-            if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
258
-                $this->_html_name = $this->_parent_section->html_name_prefix() . "[{$this->name()}]";
259
-            }
260
-        }
261
-    }
262
-
263
-
264
-
265
-    /**
266
-     * @param $parent_form_section
267
-     * @param $name
268
-     * @throws \EE_Error
269
-     */
270
-    public function _construct_finalize($parent_form_section, $name)
271
-    {
272
-        parent::_construct_finalize($parent_form_section, $name);
273
-        if ($this->_html_label === null && $this->_html_label_text === null) {
274
-            $this->_html_label_text = ucwords(str_replace("_", " ", $name));
275
-        }
276
-        do_action('AHEE__EE_Form_Input_Base___construct_finalize__end', $this, $parent_form_section, $name);
277
-    }
278
-
279
-
280
-
281
-    /**
282
-     * Returns the strategy for displaying this form input. If none is set, throws an exception.
283
-     *
284
-     * @return EE_Display_Strategy_Base
285
-     * @throws EE_Error
286
-     */
287
-    protected function _get_display_strategy()
288
-    {
289
-        $this->ensure_construct_finalized_called();
290
-        if (! $this->_display_strategy || ! $this->_display_strategy instanceof EE_Display_Strategy_Base) {
291
-            throw new EE_Error(
292
-                sprintf(
293
-                    __(
294
-                        "Cannot get display strategy for form input with name %s and id %s, because it has not been set in the constructor",
295
-                        "event_espresso"
296
-                    ),
297
-                    $this->html_name(),
298
-                    $this->html_id()
299
-                )
300
-            );
301
-        } else {
302
-            return $this->_display_strategy;
303
-        }
304
-    }
305
-
306
-
307
-
308
-    /**
309
-     * Sets the display strategy.
310
-     *
311
-     * @param EE_Display_Strategy_Base $strategy
312
-     */
313
-    protected function _set_display_strategy(EE_Display_Strategy_Base $strategy)
314
-    {
315
-        $this->_display_strategy = $strategy;
316
-    }
317
-
318
-
319
-
320
-    /**
321
-     * Sets the sanitization strategy
322
-     *
323
-     * @param EE_Normalization_Strategy_Base $strategy
324
-     */
325
-    protected function _set_normalization_strategy(EE_Normalization_Strategy_Base $strategy)
326
-    {
327
-        $this->_normalization_strategy = $strategy;
328
-    }
329
-
330
-
331
-
332
-    /**
333
-     * Gets sensitive_data_removal_strategy
334
-     *
335
-     * @return EE_Sensitive_Data_Removal_Base
336
-     */
337
-    public function get_sensitive_data_removal_strategy()
338
-    {
339
-        return $this->_sensitive_data_removal_strategy;
340
-    }
341
-
342
-
343
-
344
-    /**
345
-     * Sets sensitive_data_removal_strategy
346
-     *
347
-     * @param EE_Sensitive_Data_Removal_Base $sensitive_data_removal_strategy
348
-     * @return boolean
349
-     */
350
-    public function set_sensitive_data_removal_strategy($sensitive_data_removal_strategy)
351
-    {
352
-        $this->_sensitive_data_removal_strategy = $sensitive_data_removal_strategy;
353
-    }
354
-
355
-
356
-
357
-    /**
358
-     * Gets the display strategy for this input
359
-     *
360
-     * @return EE_Display_Strategy_Base
361
-     */
362
-    public function get_display_strategy()
363
-    {
364
-        return $this->_display_strategy;
365
-    }
366
-
367
-
368
-
369
-    /**
370
-     * Overwrites the display strategy
371
-     *
372
-     * @param EE_Display_Strategy_Base $display_strategy
373
-     */
374
-    public function set_display_strategy($display_strategy)
375
-    {
376
-        $this->_display_strategy = $display_strategy;
377
-        $this->_display_strategy->_construct_finalize($this);
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     * Gets the normalization strategy set on this input
384
-     *
385
-     * @return EE_Normalization_Strategy_Base
386
-     */
387
-    public function get_normalization_strategy()
388
-    {
389
-        return $this->_normalization_strategy;
390
-    }
391
-
392
-
393
-
394
-    /**
395
-     * Overwrites the normalization strategy
396
-     *
397
-     * @param EE_Normalization_Strategy_Base $normalization_strategy
398
-     */
399
-    public function set_normalization_strategy($normalization_strategy)
400
-    {
401
-        $this->_normalization_strategy = $normalization_strategy;
402
-        $this->_normalization_strategy->_construct_finalize($this);
403
-    }
404
-
405
-
406
-
407
-    /**
408
-     * Returns all teh validation strategies which apply to this field, numerically indexed
409
-     *
410
-     * @return EE_Validation_Strategy_Base[]
411
-     */
412
-    public function get_validation_strategies()
413
-    {
414
-        return $this->_validation_strategies;
415
-    }
416
-
417
-
418
-
419
-    /**
420
-     * Adds this strategy to the field so it will be used in both JS validation and server-side validation
421
-     *
422
-     * @param EE_Validation_Strategy_Base $validation_strategy
423
-     * @return void
424
-     */
425
-    protected function _add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
426
-    {
427
-        $validation_strategy->_construct_finalize($this);
428
-        $this->_validation_strategies[] = $validation_strategy;
429
-    }
430
-
431
-
432
-
433
-    /**
434
-     * Adds a new validation strategy onto the form input
435
-     *
436
-     * @param EE_Validation_Strategy_Base $validation_strategy
437
-     * @return void
438
-     */
439
-    public function add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
440
-    {
441
-        $this->_add_validation_strategy($validation_strategy);
442
-    }
443
-
444
-
445
-
446
-    /**
447
-     * The classname of the validation strategy to remove
448
-     *
449
-     * @param string $validation_strategy_classname
450
-     */
451
-    public function remove_validation_strategy($validation_strategy_classname)
452
-    {
453
-        foreach ($this->_validation_strategies as $key => $validation_strategy) {
454
-            if ($validation_strategy instanceof $validation_strategy_classname
455
-                || is_subclass_of($validation_strategy, $validation_strategy_classname)
456
-            ) {
457
-                unset($this->_validation_strategies[ $key ]);
458
-            }
459
-        }
460
-    }
461
-
462
-
463
-
464
-    /**
465
-     * returns true if input employs any of the validation strategy defined by the supplied array of classnames
466
-     *
467
-     * @param array $validation_strategy_classnames
468
-     * @return bool
469
-     */
470
-    public function has_validation_strategy($validation_strategy_classnames)
471
-    {
472
-        $validation_strategy_classnames = is_array($validation_strategy_classnames)
473
-            ? $validation_strategy_classnames
474
-            : array($validation_strategy_classnames);
475
-        foreach ($this->_validation_strategies as $key => $validation_strategy) {
476
-            if (in_array($key, $validation_strategy_classnames)) {
477
-                return true;
478
-            }
479
-        }
480
-        return false;
481
-    }
482
-
483
-
484
-
485
-    /**
486
-     * Gets the HTML
487
-     *
488
-     * @return string
489
-     */
490
-    public function get_html()
491
-    {
492
-        return $this->_parent_section->get_html_for_input($this);
493
-    }
494
-
495
-
496
-
497
-    /**
498
-     * Gets the HTML for the input itself (no label or errors) according to the
499
-     * input's display strategy
500
-     * Makes sure the JS and CSS are enqueued for it
501
-     *
502
-     * @return string
503
-     * @throws \EE_Error
504
-     */
505
-    public function get_html_for_input()
506
-    {
507
-        return $this->_form_html_filter
508
-            ? $this->_form_html_filter->filterHtml(
509
-                $this->_get_display_strategy()->display(),
510
-                $this
511
-            )
512
-            : $this->_get_display_strategy()->display();
513
-    }
514
-
515
-
516
-
517
-    /**
518
-     * @return string
519
-     */
520
-    public function html_other_attributes()
521
-    {
522
-        EE_Error::doing_it_wrong(
523
-            __METHOD__,
524
-            sprintf(
525
-                esc_html__(
526
-                    'This method is no longer in use. You should replace it by %s',
527
-                    'event_espresso'
528
-                ),
529
-                'EE_Form_Section_Base::other_html_attributes()'
530
-            ),
531
-            '4.10.2.p'
532
-        );
533
-
534
-        return $this->other_html_attributes();
535
-    }
536
-
537
-
538
-
539
-    /**
540
-     * @param string $html_other_attributes
541
-     */
542
-    public function set_html_other_attributes($html_other_attributes)
543
-    {
544
-        EE_Error::doing_it_wrong(
545
-            __METHOD__,
546
-            sprintf(
547
-                esc_html__(
548
-                    'This method is no longer in use. You should replace it by %s',
549
-                    'event_espresso'
550
-                ),
551
-                'EE_Form_Section_Base::set_other_html_attributes()'
552
-            ),
553
-            '4.10.2.p'
554
-        );
555
-
556
-        $this->set_other_html_attributes($html_other_attributes);
557
-    }
558
-
559
-
560
-
561
-    /**
562
-     * Gets the HTML for displaying the label for this form input
563
-     * according to the form section's layout strategy
564
-     *
565
-     * @return string
566
-     */
567
-    public function get_html_for_label()
568
-    {
569
-        return $this->_parent_section->get_layout_strategy()->display_label($this);
570
-    }
571
-
572
-
573
-
574
-    /**
575
-     * Gets the HTML for displaying the errors section for this form input
576
-     * according to the form section's layout strategy
577
-     *
578
-     * @return string
579
-     */
580
-    public function get_html_for_errors()
581
-    {
582
-        return $this->_parent_section->get_layout_strategy()->display_errors($this);
583
-    }
584
-
585
-
586
-
587
-    /**
588
-     * Gets the HTML for displaying the help text for this form input
589
-     * according to the form section's layout strategy
590
-     *
591
-     * @return string
592
-     */
593
-    public function get_html_for_help()
594
-    {
595
-        return $this->_parent_section->get_layout_strategy()->display_help_text($this);
596
-    }
597
-
598
-
599
-
600
-    /**
601
-     * Validates the input's sanitized value (assumes _sanitize() has already been called)
602
-     * and returns whether or not the form input's submitted value is value
603
-     *
604
-     * @return boolean
605
-     */
606
-    protected function _validate()
607
-    {
608
-        if ($this->isDisabled()) {
609
-            return true;
610
-        }
611
-        foreach ($this->_validation_strategies as $validation_strategy) {
612
-            if ($validation_strategy instanceof EE_Validation_Strategy_Base) {
613
-                try {
614
-                    $validation_strategy->validate($this->normalized_value());
615
-                } catch (EE_Validation_Error $e) {
616
-                    $this->add_validation_error($e);
617
-                }
618
-            }
619
-        }
620
-        if ($this->get_validation_errors()) {
621
-            return false;
622
-        } else {
623
-            return true;
624
-        }
625
-    }
626
-
627
-
628
-
629
-    /**
630
-     * Performs basic sanitization on this value. But what sanitization can be performed anyways?
631
-     * This value MIGHT be allowed to have tags, so we can't really remove them.
632
-     *
633
-     * @param string $value
634
-     * @return null|string
635
-     */
636
-    protected function _sanitize($value)
637
-    {
638
-        return $value !== null ? stripslashes(html_entity_decode(trim($value))) : null;
639
-    }
640
-
641
-
642
-
643
-    /**
644
-     * Picks out the form value that relates to this form input,
645
-     * and stores it as the sanitized value on the form input, and sets the normalized value.
646
-     * Returns whether or not any validation errors occurred
647
-     *
648
-     * @param array $req_data like $_POST
649
-     * @return boolean whether or not there was an error
650
-     * @throws \EE_Error
651
-     */
652
-    protected function _normalize($req_data)
653
-    {
654
-        // any existing validation errors don't apply so clear them
655
-        $this->_validation_errors = array();
656
-        // if the input is disabled, ignore whatever input was sent in
657
-        if ($this->isDisabled()) {
658
-            $this->_set_raw_value(null);
659
-            $this->_set_normalized_value($this->get_default());
660
-            return false;
661
-        }
662
-        try {
663
-            $raw_input = $this->find_form_data_for_this_section($req_data);
664
-            // super simple sanitization for now
665
-            if (is_array($raw_input)) {
666
-                $raw_value = array();
667
-                foreach ($raw_input as $key => $value) {
668
-                    $raw_value[ $key ] = $this->_sanitize($value);
669
-                }
670
-                $this->_set_raw_value($raw_value);
671
-            } else {
672
-                $this->_set_raw_value($this->_sanitize($raw_input));
673
-            }
674
-            // we want to mostly leave the input alone in case we need to re-display it to the user
675
-            $this->_set_normalized_value($this->_normalization_strategy->normalize($this->raw_value()));
676
-            return false;
677
-        } catch (EE_Validation_Error $e) {
678
-            $this->add_validation_error($e);
679
-            return true;
680
-        }
681
-    }
682
-
683
-
684
-
685
-    /**
686
-     * @return string
687
-     */
688
-    public function html_name()
689
-    {
690
-        $this->_set_default_html_name_if_empty();
691
-        return $this->_html_name;
692
-    }
693
-
694
-
695
-
696
-    /**
697
-     * @return string
698
-     */
699
-    public function html_label_id()
700
-    {
701
-        return ! empty($this->_html_label_id) ? $this->_html_label_id : $this->html_id() . '-lbl';
702
-    }
703
-
704
-
705
-
706
-    /**
707
-     * @return string
708
-     */
709
-    public function html_label_class()
710
-    {
711
-        return $this->_html_label_class;
712
-    }
713
-
714
-
715
-
716
-    /**
717
-     * @return string
718
-     */
719
-    public function html_label_style()
720
-    {
721
-        return $this->_html_label_style;
722
-    }
723
-
724
-
725
-
726
-    /**
727
-     * @return string
728
-     */
729
-    public function html_label_text()
730
-    {
731
-        return $this->_html_label_text;
732
-    }
733
-
734
-
735
-
736
-    /**
737
-     * @return string
738
-     */
739
-    public function html_help_text()
740
-    {
741
-        return $this->_html_help_text;
742
-    }
743
-
744
-
745
-
746
-    /**
747
-     * @return string
748
-     */
749
-    public function html_help_class()
750
-    {
751
-        return $this->_html_help_class;
752
-    }
753
-
754
-
755
-
756
-    /**
757
-     * @return string
758
-     */
759
-    public function html_help_style()
760
-    {
761
-        return $this->_html_style;
762
-    }
763
-
764
-
765
-
766
-    /**
767
-     * returns the raw, UNSAFE, input, almost exactly as the user submitted it.
768
-     * Please note that almost all client code should instead use the normalized_value;
769
-     * or possibly raw_value_in_form (which prepares the string for displaying in an HTML attribute on a tag,
770
-     * mostly by escaping quotes)
771
-     * Note, we do not store the exact original value sent in the user's request because
772
-     * it may have malicious content, and we MIGHT want to store the form input in a transient or something...
773
-     * in which case, we would have stored the malicious content to our database.
774
-     *
775
-     * @return string
776
-     */
777
-    public function raw_value()
778
-    {
779
-        return $this->_raw_value;
780
-    }
781
-
782
-
783
-
784
-    /**
785
-     * Returns a string safe to usage in form inputs when displaying, because
786
-     * it escapes all html entities
787
-     *
788
-     * @return string
789
-     */
790
-    public function raw_value_in_form()
791
-    {
792
-        return htmlentities($this->raw_value(), ENT_QUOTES, 'UTF-8');
793
-    }
794
-
795
-
796
-
797
-    /**
798
-     * returns the value after it's been sanitized, and then converted into it's proper type
799
-     * in PHP. Eg, a string, an int, an array,
800
-     *
801
-     * @return mixed
802
-     */
803
-    public function normalized_value()
804
-    {
805
-        return $this->_normalized_value;
806
-    }
807
-
808
-
809
-
810
-    /**
811
-     * Returns the normalized value is a presentable way. By default this is just
812
-     * the normalized value by itself, but it can be overridden for when that's not
813
-     * the best thing to display
814
-     *
815
-     * @return string
816
-     */
817
-    public function pretty_value()
818
-    {
819
-        return $this->_normalized_value;
820
-    }
821
-
822
-
823
-
824
-    /**
825
-     * When generating the JS for the jquery validation rules like<br>
826
-     * <code>$( "#myform" ).validate({
827
-     * rules: {
828
-     * password: "required",
829
-     * password_again: {
830
-     * equalTo: "#password"
831
-     * }
832
-     * }
833
-     * });</code>
834
-     * if this field had the name 'password_again', it should return
835
-     * <br><code>password_again: {
836
-     * equalTo: "#password"
837
-     * }</code>
838
-     *
839
-     * @return array
840
-     */
841
-    public function get_jquery_validation_rules()
842
-    {
843
-        $jquery_validation_js = array();
844
-        $jquery_validation_rules = array();
845
-        foreach ($this->get_validation_strategies() as $validation_strategy) {
846
-            $jquery_validation_rules = array_replace_recursive(
847
-                $jquery_validation_rules,
848
-                $validation_strategy->get_jquery_validation_rule_array()
849
-            );
850
-        }
851
-        if (! empty($jquery_validation_rules)) {
852
-            foreach ($this->get_display_strategy()->get_html_input_ids(true) as $html_id_with_pound_sign) {
853
-                $jquery_validation_js[ $html_id_with_pound_sign ] = $jquery_validation_rules;
854
-            }
855
-        }
856
-        return $jquery_validation_js;
857
-    }
858
-
859
-
860
-
861
-    /**
862
-     * Sets the input's default value for use in displaying in the form. Note: value should be
863
-     * normalized (Eg, if providing a default of ra Yes_NO_Input you would provide TRUE or FALSE, not '1' or '0')
864
-     *
865
-     * @param mixed $value
866
-     * @return void
867
-     */
868
-    public function set_default($value)
869
-    {
870
-        $this->_default = $value;
871
-        $this->_set_normalized_value($value);
872
-        $this->_set_raw_value($value);
873
-    }
874
-
875
-
876
-
877
-    /**
878
-     * Sets the normalized value on this input
879
-     *
880
-     * @param mixed $value
881
-     */
882
-    protected function _set_normalized_value($value)
883
-    {
884
-        $this->_normalized_value = $value;
885
-    }
886
-
887
-
888
-
889
-    /**
890
-     * Sets the raw value on this input (ie, exactly as the user submitted it)
891
-     *
892
-     * @param mixed $value
893
-     */
894
-    protected function _set_raw_value($value)
895
-    {
896
-        $this->_raw_value = $this->_normalization_strategy->unnormalize($value);
897
-    }
898
-
899
-
900
-
901
-    /**
902
-     * Sets the HTML label text after it has already been defined
903
-     *
904
-     * @param string $label
905
-     * @return void
906
-     */
907
-    public function set_html_label_text($label)
908
-    {
909
-        $this->_html_label_text = $label;
910
-    }
911
-
912
-
913
-
914
-    /**
915
-     * Sets whether or not this field is required, and adjusts the validation strategy.
916
-     * If you want to use the EE_Conditionally_Required_Validation_Strategy,
917
-     * please add it as a validation strategy using add_validation_strategy as normal
918
-     *
919
-     * @param boolean $required boolean
920
-     * @param null    $required_text
921
-     */
922
-    public function set_required($required = true, $required_text = null)
923
-    {
924
-        $required = filter_var($required, FILTER_VALIDATE_BOOLEAN);
925
-        // whether $required is a string or a boolean, we want to add a required validation strategy
926
-        if ($required) {
927
-            $this->_add_validation_strategy(new EE_Required_Validation_Strategy($required_text));
928
-        } else {
929
-            $this->remove_validation_strategy('EE_Required_Validation_Strategy');
930
-        }
931
-        $this->_required = $required;
932
-    }
933
-
934
-
935
-
936
-    /**
937
-     * Returns whether or not this field is required
938
-     *
939
-     * @return boolean
940
-     */
941
-    public function required()
942
-    {
943
-        return $this->_required;
944
-    }
945
-
946
-
947
-
948
-    /**
949
-     * @param string $required_css_class
950
-     */
951
-    public function set_required_css_class($required_css_class)
952
-    {
953
-        $this->_required_css_class = $required_css_class;
954
-    }
955
-
956
-
957
-
958
-    /**
959
-     * @return string
960
-     */
961
-    public function required_css_class()
962
-    {
963
-        return $this->_required_css_class;
964
-    }
965
-
966
-
967
-
968
-    /**
969
-     * @param bool $add_required
970
-     * @return string
971
-     */
972
-    public function html_class($add_required = false)
973
-    {
974
-        return $add_required && $this->required()
975
-            ? $this->required_css_class() . ' ' . $this->_html_class
976
-            : $this->_html_class;
977
-    }
978
-
979
-
980
-    /**
981
-     * Sets the help text, in case
982
-     *
983
-     * @param string $text
984
-     */
985
-    public function set_html_help_text($text)
986
-    {
987
-        $this->_html_help_text = $text;
988
-    }
989
-
990
-
991
-
992
-    /**
993
-     * Uses the sensitive data removal strategy to remove the sensitive data from this
994
-     * input. If there is any kind of sensitive data removal on this input, we clear
995
-     * out the raw value completely
996
-     *
997
-     * @return void
998
-     */
999
-    public function clean_sensitive_data()
1000
-    {
1001
-        // if we do ANY kind of sensitive data removal on this, then just clear out the raw value
1002
-        // if we need more logic than this we'll make a strategy for it
1003
-        if ($this->_sensitive_data_removal_strategy
1004
-            && ! $this->_sensitive_data_removal_strategy instanceof EE_No_Sensitive_Data_Removal
1005
-        ) {
1006
-            $this->_set_raw_value(null);
1007
-        }
1008
-        // and clean the normalized value according to the appropriate strategy
1009
-        $this->_set_normalized_value(
1010
-            $this->get_sensitive_data_removal_strategy()->remove_sensitive_data(
1011
-                $this->_normalized_value
1012
-            )
1013
-        );
1014
-    }
1015
-
1016
-
1017
-
1018
-    /**
1019
-     * @param bool   $primary
1020
-     * @param string $button_size
1021
-     * @param string $other_attributes
1022
-     */
1023
-    public function set_button_css_attributes($primary = true, $button_size = '', $other_attributes = '')
1024
-    {
1025
-        $button_css_attributes = 'button';
1026
-        $button_css_attributes .= $primary === true ? ' button-primary' : ' button-secondary';
1027
-        switch ($button_size) {
1028
-            case 'xs':
1029
-            case 'extra-small':
1030
-                $button_css_attributes .= ' button-xs';
1031
-                break;
1032
-            case 'sm':
1033
-            case 'small':
1034
-                $button_css_attributes .= ' button-sm';
1035
-                break;
1036
-            case 'lg':
1037
-            case 'large':
1038
-                $button_css_attributes .= ' button-lg';
1039
-                break;
1040
-            case 'block':
1041
-                $button_css_attributes .= ' button-block';
1042
-                break;
1043
-            case 'md':
1044
-            case 'medium':
1045
-            default:
1046
-                $button_css_attributes .= '';
1047
-        }
1048
-        $this->_button_css_attributes .= ! empty($other_attributes)
1049
-            ? $button_css_attributes . ' ' . $other_attributes
1050
-            : $button_css_attributes;
1051
-    }
1052
-
1053
-
1054
-
1055
-    /**
1056
-     * @return string
1057
-     */
1058
-    public function button_css_attributes()
1059
-    {
1060
-        if (empty($this->_button_css_attributes)) {
1061
-            $this->set_button_css_attributes();
1062
-        }
1063
-        return $this->_button_css_attributes;
1064
-    }
1065
-
1066
-
1067
-
1068
-    /**
1069
-     * find_form_data_for_this_section
1070
-     * using this section's name and its parents, finds the value of the form data that corresponds to it.
1071
-     * For example, if this form section's HTML name is my_form[subform][form_input_1],
1072
-     * then it's value should be in $_REQUEST at $_REQUEST['my_form']['subform']['form_input_1'].
1073
-     * (If that doesn't exist, we also check for this subsection's name
1074
-     * at the TOP LEVEL of the request data. Eg $_REQUEST['form_input_1'].)
1075
-     * This function finds its value in the form.
1076
-     *
1077
-     * @param array $req_data
1078
-     * @return mixed whatever the raw value of this form section is in the request data
1079
-     * @throws \EE_Error
1080
-     */
1081
-    public function find_form_data_for_this_section($req_data)
1082
-    {
1083
-        $name_parts = $this->getInputNameParts();
1084
-        // now get the value for the input
1085
-        $value = $this->findRequestForSectionUsingNameParts($name_parts, $req_data);
1086
-        // check if this thing's name is at the TOP level of the request data
1087
-        if ($value === null && isset($req_data[ $this->name() ])) {
1088
-            $value = $req_data[ $this->name() ];
1089
-        }
1090
-        return $value;
1091
-    }
1092
-
1093
-
1094
-
1095
-    /**
1096
-     * If this input's name is something like "foo[bar][baz]"
1097
-     * returns an array like `array('foo','bar',baz')`
1098
-     * @return array
1099
-     */
1100
-    protected function getInputNameParts()
1101
-    {
1102
-        // break up the html name by "[]"
1103
-        if (strpos($this->html_name(), '[') !== false) {
1104
-            $before_any_brackets = substr($this->html_name(), 0, strpos($this->html_name(), '['));
1105
-        } else {
1106
-            $before_any_brackets = $this->html_name();
1107
-        }
1108
-        // grab all of the segments
1109
-        preg_match_all('~\[([^]]*)\]~', $this->html_name(), $matches);
1110
-        if (isset($matches[1]) && is_array($matches[1])) {
1111
-            $name_parts = $matches[1];
1112
-            array_unshift($name_parts, $before_any_brackets);
1113
-        } else {
1114
-            $name_parts = array($before_any_brackets);
1115
-        }
1116
-        return $name_parts;
1117
-    }
1118
-
1119
-
1120
-
1121
-    /**
1122
-     * @param array $html_name_parts
1123
-     * @param array $req_data
1124
-     * @return array | NULL
1125
-     */
1126
-    public function findRequestForSectionUsingNameParts($html_name_parts, $req_data)
1127
-    {
1128
-        $first_part_to_consider = array_shift($html_name_parts);
1129
-        if (isset($req_data[ $first_part_to_consider ])) {
1130
-            if (empty($html_name_parts)) {
1131
-                return $req_data[ $first_part_to_consider ];
1132
-            } else {
1133
-                return $this->findRequestForSectionUsingNameParts(
1134
-                    $html_name_parts,
1135
-                    $req_data[ $first_part_to_consider ]
1136
-                );
1137
-            }
1138
-        } else {
1139
-            return null;
1140
-        }
1141
-    }
1142
-
1143
-
1144
-
1145
-    /**
1146
-     * Checks if this form input's data is in the request data
1147
-     *
1148
-     * @param array $req_data like $_POST
1149
-     * @return boolean
1150
-     * @throws \EE_Error
1151
-     */
1152
-    public function form_data_present_in($req_data = null)
1153
-    {
1154
-        if ($req_data === null) {
1155
-            $req_data = $_POST;
1156
-        }
1157
-        $checked_value = $this->find_form_data_for_this_section($req_data);
1158
-        if ($checked_value !== null) {
1159
-            return true;
1160
-        } else {
1161
-            return false;
1162
-        }
1163
-    }
1164
-
1165
-
1166
-
1167
-    /**
1168
-     * Overrides parent to add js data from validation and display strategies
1169
-     *
1170
-     * @param array $form_other_js_data
1171
-     * @return array
1172
-     */
1173
-    public function get_other_js_data($form_other_js_data = array())
1174
-    {
1175
-        $form_other_js_data = $this->get_other_js_data_from_strategies($form_other_js_data);
1176
-        return $form_other_js_data;
1177
-    }
1178
-
1179
-
1180
-
1181
-    /**
1182
-     * Gets other JS data for localization from this input's strategies, like
1183
-     * the validation strategies and the display strategy
1184
-     *
1185
-     * @param array $form_other_js_data
1186
-     * @return array
1187
-     */
1188
-    public function get_other_js_data_from_strategies($form_other_js_data = array())
1189
-    {
1190
-        $form_other_js_data = $this->get_display_strategy()->get_other_js_data($form_other_js_data);
1191
-        foreach ($this->get_validation_strategies() as $validation_strategy) {
1192
-            $form_other_js_data = $validation_strategy->get_other_js_data($form_other_js_data);
1193
-        }
1194
-        return $form_other_js_data;
1195
-    }
1196
-
1197
-
1198
-
1199
-    /**
1200
-     * Override parent because we want to give our strategies an opportunity to enqueue some js and css
1201
-     *
1202
-     * @return void
1203
-     */
1204
-    public function enqueue_js()
1205
-    {
1206
-        // ask our display strategy and validation strategies if they have js to enqueue
1207
-        $this->enqueue_js_from_strategies();
1208
-    }
1209
-
1210
-
1211
-
1212
-    /**
1213
-     * Tells strategies when its ok to enqueue their js and css
1214
-     *
1215
-     * @return void
1216
-     */
1217
-    public function enqueue_js_from_strategies()
1218
-    {
1219
-        $this->get_display_strategy()->enqueue_js();
1220
-        foreach ($this->get_validation_strategies() as $validation_strategy) {
1221
-            $validation_strategy->enqueue_js();
1222
-        }
1223
-    }
1224
-
1225
-
1226
-
1227
-    /**
1228
-     * Gets the default value set on the input (not the current value, which may have been
1229
-     * changed because of a form submission). If no default was set, this us null.
1230
-     * @return mixed
1231
-     */
1232
-    public function get_default()
1233
-    {
1234
-        return $this->_default;
1235
-    }
1236
-
1237
-
1238
-
1239
-    /**
1240
-     * Makes this input disabled. That means it will have the HTML attribute 'disabled="disabled"',
1241
-     * and server-side if any input was received it will be ignored
1242
-     */
1243
-    public function disable($disable = true)
1244
-    {
1245
-        $disabled_attribute = ' disabled="disabled"';
1246
-        $this->disabled = filter_var($disable, FILTER_VALIDATE_BOOLEAN);
1247
-        if ($this->disabled) {
1248
-            if (strpos($this->_other_html_attributes, $disabled_attribute) === false) {
1249
-                $this->_other_html_attributes .= $disabled_attribute;
1250
-            }
1251
-            $this->_set_normalized_value($this->get_default());
1252
-        } else {
1253
-            $this->_other_html_attributes = str_replace($disabled_attribute, '', $this->_other_html_attributes);
1254
-        }
1255
-    }
1256
-
1257
-
1258
-
1259
-    /**
1260
-     * Returns whether or not this input is currently disabled.
1261
-     * @return bool
1262
-     */
1263
-    public function isDisabled()
1264
-    {
1265
-        return $this->disabled;
1266
-    }
14
+	/**
15
+	 * the input's name attribute
16
+	 *
17
+	 * @var string
18
+	 */
19
+	protected $_html_name;
20
+
21
+	/**
22
+	 * id for the html label tag
23
+	 *
24
+	 * @var string
25
+	 */
26
+	protected $_html_label_id;
27
+
28
+	/**
29
+	 * class for teh html label tag
30
+	 *
31
+	 * @var string
32
+	 */
33
+	protected $_html_label_class;
34
+
35
+	/**
36
+	 * style for teh html label tag
37
+	 *
38
+	 * @var string
39
+	 */
40
+	protected $_html_label_style;
41
+
42
+	/**
43
+	 * text to be placed in the html label
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_html_label_text;
48
+
49
+	/**
50
+	 * the full html label. If used, all other html_label_* properties are invalid
51
+	 *
52
+	 * @var string
53
+	 */
54
+	protected $_html_label;
55
+
56
+	/**
57
+	 * HTML to use for help text (normally placed below form input), in a span which normally
58
+	 * has a class of 'description'
59
+	 *
60
+	 * @var string
61
+	 */
62
+	protected $_html_help_text;
63
+
64
+	/**
65
+	 * CSS classes for displaying the help span
66
+	 *
67
+	 * @var string
68
+	 */
69
+	protected $_html_help_class = 'description';
70
+
71
+	/**
72
+	 * CSS to put in the style attribute on the help span
73
+	 *
74
+	 * @var string
75
+	 */
76
+	protected $_html_help_style;
77
+
78
+	/**
79
+	 * Stores whether or not this input's response is required.
80
+	 * Because certain styling elements may also want to know that this
81
+	 * input is required etc.
82
+	 *
83
+	 * @var boolean
84
+	 */
85
+	protected $_required;
86
+
87
+	/**
88
+	 * css class added to required inputs
89
+	 *
90
+	 * @var string
91
+	 */
92
+	protected $_required_css_class = 'ee-required';
93
+
94
+	/**
95
+	 * css styles applied to button type inputs
96
+	 *
97
+	 * @var string
98
+	 */
99
+	protected $_button_css_attributes;
100
+
101
+	/**
102
+	 * The raw data submitted for this, like in the $_POST super global.
103
+	 * Generally unsafe for usage in client code
104
+	 *
105
+	 * @var mixed string or array
106
+	 */
107
+	protected $_raw_value;
108
+
109
+	/**
110
+	 * Value normalized according to the input's normalization strategy.
111
+	 * The normalization strategy dictates whether this is a string, int, float,
112
+	 * boolean, or array of any of those.
113
+	 *
114
+	 * @var mixed
115
+	 */
116
+	protected $_normalized_value;
117
+
118
+
119
+	/**
120
+	 * Normalized default value either initially set on the input, or provided by calling
121
+	 * set_default().
122
+	 * @var mixed
123
+	 */
124
+	protected $_default;
125
+
126
+	/**
127
+	 * Strategy used for displaying this field.
128
+	 * Child classes must use _get_display_strategy to access it.
129
+	 *
130
+	 * @var EE_Display_Strategy_Base
131
+	 */
132
+	private $_display_strategy;
133
+
134
+	/**
135
+	 * Gets all the validation strategies used on this field
136
+	 *
137
+	 * @var EE_Validation_Strategy_Base[]
138
+	 */
139
+	private $_validation_strategies = array();
140
+
141
+	/**
142
+	 * The normalization strategy for this field
143
+	 *
144
+	 * @var EE_Normalization_Strategy_Base
145
+	 */
146
+	private $_normalization_strategy;
147
+
148
+	/**
149
+	 * Strategy for removing sensitive data after we're done with the form input
150
+	 *
151
+	 * @var EE_Sensitive_Data_Removal_Base
152
+	 */
153
+	protected $_sensitive_data_removal_strategy;
154
+
155
+	/**
156
+	 * Whether this input has been disabled or not.
157
+	 * If it's disabled while rendering, an extra hidden input is added that indicates it has been knowingly disabled.
158
+	 * (Client-side code that wants to dynamically disable it must also add this hidden input).
159
+	 * When the form is submitted, if the input is disabled in the PHP formsection, then input is ignored.
160
+	 * If the input is missing from the $_REQUEST data but the hidden input indicating the input is disabled, then the input is again ignored.
161
+	 *
162
+	 * @var boolean
163
+	 */
164
+	protected $disabled = false;
165
+
166
+
167
+
168
+	/**
169
+	 * @param array                         $input_args       {
170
+	 * @type string                         $html_name        the html name for the input
171
+	 * @type string                         $html_label_id    the id attribute to give to the html label tag
172
+	 * @type string                         $html_label_class the class attribute to give to the html label tag
173
+	 * @type string                         $html_label_style the style attribute to give ot teh label tag
174
+	 * @type string                         $html_label_text  the text to put in the label tag
175
+	 * @type string                         $html_label       the full html label. If used,
176
+	 *                                                        all other html_label_* args are invalid
177
+	 * @type string                         $html_help_text   text to put in help element
178
+	 * @type string                         $html_help_style  style attribute to give to teh help element
179
+	 * @type string                         $html_help_class  class attribute to give to the help element
180
+	 * @type string                         $default          default value NORMALIZED (eg, if providing the default
181
+	 *       for a Yes_No_Input, you should provide TRUE or FALSE, not '1' or '0')
182
+	 * @type EE_Display_Strategy_Base       $display          strategy
183
+	 * @type EE_Normalization_Strategy_Base $normalization_strategy
184
+	 * @type EE_Validation_Strategy_Base[]  $validation_strategies
185
+	 * @type boolean                        $ignore_input special argument which can be used to avoid adding any validation strategies,
186
+	 *                                                    and sets the normalization strategy to the Null normalization. This is good
187
+	 *                                                    when you want the input to be totally ignored server-side (like when using
188
+	 *                                                    React.js form inputs)
189
+	 *                                                        }
190
+	 */
191
+	public function __construct($input_args = array())
192
+	{
193
+		$input_args = (array) apply_filters('FHEE__EE_Form_Input_Base___construct__input_args', $input_args, $this);
194
+		// the following properties must be cast as arrays
195
+		if (isset($input_args['validation_strategies'])) {
196
+			foreach ((array) $input_args['validation_strategies'] as $validation_strategy) {
197
+				if ($validation_strategy instanceof EE_Validation_Strategy_Base && empty($input_args['ignore_input'])) {
198
+					$this->_validation_strategies[ get_class($validation_strategy) ] = $validation_strategy;
199
+				}
200
+			}
201
+			unset($input_args['validation_strategies']);
202
+		}
203
+		if (isset($input_args['ignore_input'])) {
204
+			$this->_validation_strategies = array();
205
+		}
206
+		// loop thru incoming options
207
+		foreach ($input_args as $key => $value) {
208
+			// add underscore to $key to match property names
209
+			$_key = '_' . $key;
210
+			if (property_exists($this, $_key)) {
211
+				$this->{$_key} = $value;
212
+			}
213
+		}
214
+		// ensure that "required" is set correctly
215
+		$this->set_required(
216
+			$this->_required,
217
+			isset($input_args['required_validation_error_message'])
218
+			? $input_args['required_validation_error_message']
219
+			: null
220
+		);
221
+		// $this->_html_name_specified = isset( $input_args['html_name'] ) ? TRUE : FALSE;
222
+		$this->_display_strategy->_construct_finalize($this);
223
+		foreach ($this->_validation_strategies as $validation_strategy) {
224
+			$validation_strategy->_construct_finalize($this);
225
+		}
226
+		if (isset($input_args['ignore_input'])) {
227
+			$this->_normalization_strategy = new EE_Null_Normalization();
228
+		}
229
+		if (! $this->_normalization_strategy) {
230
+				$this->_normalization_strategy = new EE_Text_Normalization();
231
+		}
232
+		$this->_normalization_strategy->_construct_finalize($this);
233
+		// at least we can use the normalization strategy to populate the default
234
+		if (isset($input_args['default'])) {
235
+			$this->set_default($input_args['default']);
236
+			unset($input_args['default']);
237
+		}
238
+		if (! $this->_sensitive_data_removal_strategy) {
239
+			$this->_sensitive_data_removal_strategy = new EE_No_Sensitive_Data_Removal();
240
+		}
241
+		$this->_sensitive_data_removal_strategy->_construct_finalize($this);
242
+		parent::__construct($input_args);
243
+	}
244
+
245
+
246
+
247
+	/**
248
+	 * Sets the html_name to its default value, if none was specified in teh constructor.
249
+	 * Calculation involves using the name and the parent's html_name
250
+	 *
251
+	 * @throws \EE_Error
252
+	 */
253
+	protected function _set_default_html_name_if_empty()
254
+	{
255
+		if (! $this->_html_name) {
256
+			$this->_html_name = $this->name();
257
+			if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
258
+				$this->_html_name = $this->_parent_section->html_name_prefix() . "[{$this->name()}]";
259
+			}
260
+		}
261
+	}
262
+
263
+
264
+
265
+	/**
266
+	 * @param $parent_form_section
267
+	 * @param $name
268
+	 * @throws \EE_Error
269
+	 */
270
+	public function _construct_finalize($parent_form_section, $name)
271
+	{
272
+		parent::_construct_finalize($parent_form_section, $name);
273
+		if ($this->_html_label === null && $this->_html_label_text === null) {
274
+			$this->_html_label_text = ucwords(str_replace("_", " ", $name));
275
+		}
276
+		do_action('AHEE__EE_Form_Input_Base___construct_finalize__end', $this, $parent_form_section, $name);
277
+	}
278
+
279
+
280
+
281
+	/**
282
+	 * Returns the strategy for displaying this form input. If none is set, throws an exception.
283
+	 *
284
+	 * @return EE_Display_Strategy_Base
285
+	 * @throws EE_Error
286
+	 */
287
+	protected function _get_display_strategy()
288
+	{
289
+		$this->ensure_construct_finalized_called();
290
+		if (! $this->_display_strategy || ! $this->_display_strategy instanceof EE_Display_Strategy_Base) {
291
+			throw new EE_Error(
292
+				sprintf(
293
+					__(
294
+						"Cannot get display strategy for form input with name %s and id %s, because it has not been set in the constructor",
295
+						"event_espresso"
296
+					),
297
+					$this->html_name(),
298
+					$this->html_id()
299
+				)
300
+			);
301
+		} else {
302
+			return $this->_display_strategy;
303
+		}
304
+	}
305
+
306
+
307
+
308
+	/**
309
+	 * Sets the display strategy.
310
+	 *
311
+	 * @param EE_Display_Strategy_Base $strategy
312
+	 */
313
+	protected function _set_display_strategy(EE_Display_Strategy_Base $strategy)
314
+	{
315
+		$this->_display_strategy = $strategy;
316
+	}
317
+
318
+
319
+
320
+	/**
321
+	 * Sets the sanitization strategy
322
+	 *
323
+	 * @param EE_Normalization_Strategy_Base $strategy
324
+	 */
325
+	protected function _set_normalization_strategy(EE_Normalization_Strategy_Base $strategy)
326
+	{
327
+		$this->_normalization_strategy = $strategy;
328
+	}
329
+
330
+
331
+
332
+	/**
333
+	 * Gets sensitive_data_removal_strategy
334
+	 *
335
+	 * @return EE_Sensitive_Data_Removal_Base
336
+	 */
337
+	public function get_sensitive_data_removal_strategy()
338
+	{
339
+		return $this->_sensitive_data_removal_strategy;
340
+	}
341
+
342
+
343
+
344
+	/**
345
+	 * Sets sensitive_data_removal_strategy
346
+	 *
347
+	 * @param EE_Sensitive_Data_Removal_Base $sensitive_data_removal_strategy
348
+	 * @return boolean
349
+	 */
350
+	public function set_sensitive_data_removal_strategy($sensitive_data_removal_strategy)
351
+	{
352
+		$this->_sensitive_data_removal_strategy = $sensitive_data_removal_strategy;
353
+	}
354
+
355
+
356
+
357
+	/**
358
+	 * Gets the display strategy for this input
359
+	 *
360
+	 * @return EE_Display_Strategy_Base
361
+	 */
362
+	public function get_display_strategy()
363
+	{
364
+		return $this->_display_strategy;
365
+	}
366
+
367
+
368
+
369
+	/**
370
+	 * Overwrites the display strategy
371
+	 *
372
+	 * @param EE_Display_Strategy_Base $display_strategy
373
+	 */
374
+	public function set_display_strategy($display_strategy)
375
+	{
376
+		$this->_display_strategy = $display_strategy;
377
+		$this->_display_strategy->_construct_finalize($this);
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 * Gets the normalization strategy set on this input
384
+	 *
385
+	 * @return EE_Normalization_Strategy_Base
386
+	 */
387
+	public function get_normalization_strategy()
388
+	{
389
+		return $this->_normalization_strategy;
390
+	}
391
+
392
+
393
+
394
+	/**
395
+	 * Overwrites the normalization strategy
396
+	 *
397
+	 * @param EE_Normalization_Strategy_Base $normalization_strategy
398
+	 */
399
+	public function set_normalization_strategy($normalization_strategy)
400
+	{
401
+		$this->_normalization_strategy = $normalization_strategy;
402
+		$this->_normalization_strategy->_construct_finalize($this);
403
+	}
404
+
405
+
406
+
407
+	/**
408
+	 * Returns all teh validation strategies which apply to this field, numerically indexed
409
+	 *
410
+	 * @return EE_Validation_Strategy_Base[]
411
+	 */
412
+	public function get_validation_strategies()
413
+	{
414
+		return $this->_validation_strategies;
415
+	}
416
+
417
+
418
+
419
+	/**
420
+	 * Adds this strategy to the field so it will be used in both JS validation and server-side validation
421
+	 *
422
+	 * @param EE_Validation_Strategy_Base $validation_strategy
423
+	 * @return void
424
+	 */
425
+	protected function _add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
426
+	{
427
+		$validation_strategy->_construct_finalize($this);
428
+		$this->_validation_strategies[] = $validation_strategy;
429
+	}
430
+
431
+
432
+
433
+	/**
434
+	 * Adds a new validation strategy onto the form input
435
+	 *
436
+	 * @param EE_Validation_Strategy_Base $validation_strategy
437
+	 * @return void
438
+	 */
439
+	public function add_validation_strategy(EE_Validation_Strategy_Base $validation_strategy)
440
+	{
441
+		$this->_add_validation_strategy($validation_strategy);
442
+	}
443
+
444
+
445
+
446
+	/**
447
+	 * The classname of the validation strategy to remove
448
+	 *
449
+	 * @param string $validation_strategy_classname
450
+	 */
451
+	public function remove_validation_strategy($validation_strategy_classname)
452
+	{
453
+		foreach ($this->_validation_strategies as $key => $validation_strategy) {
454
+			if ($validation_strategy instanceof $validation_strategy_classname
455
+				|| is_subclass_of($validation_strategy, $validation_strategy_classname)
456
+			) {
457
+				unset($this->_validation_strategies[ $key ]);
458
+			}
459
+		}
460
+	}
461
+
462
+
463
+
464
+	/**
465
+	 * returns true if input employs any of the validation strategy defined by the supplied array of classnames
466
+	 *
467
+	 * @param array $validation_strategy_classnames
468
+	 * @return bool
469
+	 */
470
+	public function has_validation_strategy($validation_strategy_classnames)
471
+	{
472
+		$validation_strategy_classnames = is_array($validation_strategy_classnames)
473
+			? $validation_strategy_classnames
474
+			: array($validation_strategy_classnames);
475
+		foreach ($this->_validation_strategies as $key => $validation_strategy) {
476
+			if (in_array($key, $validation_strategy_classnames)) {
477
+				return true;
478
+			}
479
+		}
480
+		return false;
481
+	}
482
+
483
+
484
+
485
+	/**
486
+	 * Gets the HTML
487
+	 *
488
+	 * @return string
489
+	 */
490
+	public function get_html()
491
+	{
492
+		return $this->_parent_section->get_html_for_input($this);
493
+	}
494
+
495
+
496
+
497
+	/**
498
+	 * Gets the HTML for the input itself (no label or errors) according to the
499
+	 * input's display strategy
500
+	 * Makes sure the JS and CSS are enqueued for it
501
+	 *
502
+	 * @return string
503
+	 * @throws \EE_Error
504
+	 */
505
+	public function get_html_for_input()
506
+	{
507
+		return $this->_form_html_filter
508
+			? $this->_form_html_filter->filterHtml(
509
+				$this->_get_display_strategy()->display(),
510
+				$this
511
+			)
512
+			: $this->_get_display_strategy()->display();
513
+	}
514
+
515
+
516
+
517
+	/**
518
+	 * @return string
519
+	 */
520
+	public function html_other_attributes()
521
+	{
522
+		EE_Error::doing_it_wrong(
523
+			__METHOD__,
524
+			sprintf(
525
+				esc_html__(
526
+					'This method is no longer in use. You should replace it by %s',
527
+					'event_espresso'
528
+				),
529
+				'EE_Form_Section_Base::other_html_attributes()'
530
+			),
531
+			'4.10.2.p'
532
+		);
533
+
534
+		return $this->other_html_attributes();
535
+	}
536
+
537
+
538
+
539
+	/**
540
+	 * @param string $html_other_attributes
541
+	 */
542
+	public function set_html_other_attributes($html_other_attributes)
543
+	{
544
+		EE_Error::doing_it_wrong(
545
+			__METHOD__,
546
+			sprintf(
547
+				esc_html__(
548
+					'This method is no longer in use. You should replace it by %s',
549
+					'event_espresso'
550
+				),
551
+				'EE_Form_Section_Base::set_other_html_attributes()'
552
+			),
553
+			'4.10.2.p'
554
+		);
555
+
556
+		$this->set_other_html_attributes($html_other_attributes);
557
+	}
558
+
559
+
560
+
561
+	/**
562
+	 * Gets the HTML for displaying the label for this form input
563
+	 * according to the form section's layout strategy
564
+	 *
565
+	 * @return string
566
+	 */
567
+	public function get_html_for_label()
568
+	{
569
+		return $this->_parent_section->get_layout_strategy()->display_label($this);
570
+	}
571
+
572
+
573
+
574
+	/**
575
+	 * Gets the HTML for displaying the errors section for this form input
576
+	 * according to the form section's layout strategy
577
+	 *
578
+	 * @return string
579
+	 */
580
+	public function get_html_for_errors()
581
+	{
582
+		return $this->_parent_section->get_layout_strategy()->display_errors($this);
583
+	}
584
+
585
+
586
+
587
+	/**
588
+	 * Gets the HTML for displaying the help text for this form input
589
+	 * according to the form section's layout strategy
590
+	 *
591
+	 * @return string
592
+	 */
593
+	public function get_html_for_help()
594
+	{
595
+		return $this->_parent_section->get_layout_strategy()->display_help_text($this);
596
+	}
597
+
598
+
599
+
600
+	/**
601
+	 * Validates the input's sanitized value (assumes _sanitize() has already been called)
602
+	 * and returns whether or not the form input's submitted value is value
603
+	 *
604
+	 * @return boolean
605
+	 */
606
+	protected function _validate()
607
+	{
608
+		if ($this->isDisabled()) {
609
+			return true;
610
+		}
611
+		foreach ($this->_validation_strategies as $validation_strategy) {
612
+			if ($validation_strategy instanceof EE_Validation_Strategy_Base) {
613
+				try {
614
+					$validation_strategy->validate($this->normalized_value());
615
+				} catch (EE_Validation_Error $e) {
616
+					$this->add_validation_error($e);
617
+				}
618
+			}
619
+		}
620
+		if ($this->get_validation_errors()) {
621
+			return false;
622
+		} else {
623
+			return true;
624
+		}
625
+	}
626
+
627
+
628
+
629
+	/**
630
+	 * Performs basic sanitization on this value. But what sanitization can be performed anyways?
631
+	 * This value MIGHT be allowed to have tags, so we can't really remove them.
632
+	 *
633
+	 * @param string $value
634
+	 * @return null|string
635
+	 */
636
+	protected function _sanitize($value)
637
+	{
638
+		return $value !== null ? stripslashes(html_entity_decode(trim($value))) : null;
639
+	}
640
+
641
+
642
+
643
+	/**
644
+	 * Picks out the form value that relates to this form input,
645
+	 * and stores it as the sanitized value on the form input, and sets the normalized value.
646
+	 * Returns whether or not any validation errors occurred
647
+	 *
648
+	 * @param array $req_data like $_POST
649
+	 * @return boolean whether or not there was an error
650
+	 * @throws \EE_Error
651
+	 */
652
+	protected function _normalize($req_data)
653
+	{
654
+		// any existing validation errors don't apply so clear them
655
+		$this->_validation_errors = array();
656
+		// if the input is disabled, ignore whatever input was sent in
657
+		if ($this->isDisabled()) {
658
+			$this->_set_raw_value(null);
659
+			$this->_set_normalized_value($this->get_default());
660
+			return false;
661
+		}
662
+		try {
663
+			$raw_input = $this->find_form_data_for_this_section($req_data);
664
+			// super simple sanitization for now
665
+			if (is_array($raw_input)) {
666
+				$raw_value = array();
667
+				foreach ($raw_input as $key => $value) {
668
+					$raw_value[ $key ] = $this->_sanitize($value);
669
+				}
670
+				$this->_set_raw_value($raw_value);
671
+			} else {
672
+				$this->_set_raw_value($this->_sanitize($raw_input));
673
+			}
674
+			// we want to mostly leave the input alone in case we need to re-display it to the user
675
+			$this->_set_normalized_value($this->_normalization_strategy->normalize($this->raw_value()));
676
+			return false;
677
+		} catch (EE_Validation_Error $e) {
678
+			$this->add_validation_error($e);
679
+			return true;
680
+		}
681
+	}
682
+
683
+
684
+
685
+	/**
686
+	 * @return string
687
+	 */
688
+	public function html_name()
689
+	{
690
+		$this->_set_default_html_name_if_empty();
691
+		return $this->_html_name;
692
+	}
693
+
694
+
695
+
696
+	/**
697
+	 * @return string
698
+	 */
699
+	public function html_label_id()
700
+	{
701
+		return ! empty($this->_html_label_id) ? $this->_html_label_id : $this->html_id() . '-lbl';
702
+	}
703
+
704
+
705
+
706
+	/**
707
+	 * @return string
708
+	 */
709
+	public function html_label_class()
710
+	{
711
+		return $this->_html_label_class;
712
+	}
713
+
714
+
715
+
716
+	/**
717
+	 * @return string
718
+	 */
719
+	public function html_label_style()
720
+	{
721
+		return $this->_html_label_style;
722
+	}
723
+
724
+
725
+
726
+	/**
727
+	 * @return string
728
+	 */
729
+	public function html_label_text()
730
+	{
731
+		return $this->_html_label_text;
732
+	}
733
+
734
+
735
+
736
+	/**
737
+	 * @return string
738
+	 */
739
+	public function html_help_text()
740
+	{
741
+		return $this->_html_help_text;
742
+	}
743
+
744
+
745
+
746
+	/**
747
+	 * @return string
748
+	 */
749
+	public function html_help_class()
750
+	{
751
+		return $this->_html_help_class;
752
+	}
753
+
754
+
755
+
756
+	/**
757
+	 * @return string
758
+	 */
759
+	public function html_help_style()
760
+	{
761
+		return $this->_html_style;
762
+	}
763
+
764
+
765
+
766
+	/**
767
+	 * returns the raw, UNSAFE, input, almost exactly as the user submitted it.
768
+	 * Please note that almost all client code should instead use the normalized_value;
769
+	 * or possibly raw_value_in_form (which prepares the string for displaying in an HTML attribute on a tag,
770
+	 * mostly by escaping quotes)
771
+	 * Note, we do not store the exact original value sent in the user's request because
772
+	 * it may have malicious content, and we MIGHT want to store the form input in a transient or something...
773
+	 * in which case, we would have stored the malicious content to our database.
774
+	 *
775
+	 * @return string
776
+	 */
777
+	public function raw_value()
778
+	{
779
+		return $this->_raw_value;
780
+	}
781
+
782
+
783
+
784
+	/**
785
+	 * Returns a string safe to usage in form inputs when displaying, because
786
+	 * it escapes all html entities
787
+	 *
788
+	 * @return string
789
+	 */
790
+	public function raw_value_in_form()
791
+	{
792
+		return htmlentities($this->raw_value(), ENT_QUOTES, 'UTF-8');
793
+	}
794
+
795
+
796
+
797
+	/**
798
+	 * returns the value after it's been sanitized, and then converted into it's proper type
799
+	 * in PHP. Eg, a string, an int, an array,
800
+	 *
801
+	 * @return mixed
802
+	 */
803
+	public function normalized_value()
804
+	{
805
+		return $this->_normalized_value;
806
+	}
807
+
808
+
809
+
810
+	/**
811
+	 * Returns the normalized value is a presentable way. By default this is just
812
+	 * the normalized value by itself, but it can be overridden for when that's not
813
+	 * the best thing to display
814
+	 *
815
+	 * @return string
816
+	 */
817
+	public function pretty_value()
818
+	{
819
+		return $this->_normalized_value;
820
+	}
821
+
822
+
823
+
824
+	/**
825
+	 * When generating the JS for the jquery validation rules like<br>
826
+	 * <code>$( "#myform" ).validate({
827
+	 * rules: {
828
+	 * password: "required",
829
+	 * password_again: {
830
+	 * equalTo: "#password"
831
+	 * }
832
+	 * }
833
+	 * });</code>
834
+	 * if this field had the name 'password_again', it should return
835
+	 * <br><code>password_again: {
836
+	 * equalTo: "#password"
837
+	 * }</code>
838
+	 *
839
+	 * @return array
840
+	 */
841
+	public function get_jquery_validation_rules()
842
+	{
843
+		$jquery_validation_js = array();
844
+		$jquery_validation_rules = array();
845
+		foreach ($this->get_validation_strategies() as $validation_strategy) {
846
+			$jquery_validation_rules = array_replace_recursive(
847
+				$jquery_validation_rules,
848
+				$validation_strategy->get_jquery_validation_rule_array()
849
+			);
850
+		}
851
+		if (! empty($jquery_validation_rules)) {
852
+			foreach ($this->get_display_strategy()->get_html_input_ids(true) as $html_id_with_pound_sign) {
853
+				$jquery_validation_js[ $html_id_with_pound_sign ] = $jquery_validation_rules;
854
+			}
855
+		}
856
+		return $jquery_validation_js;
857
+	}
858
+
859
+
860
+
861
+	/**
862
+	 * Sets the input's default value for use in displaying in the form. Note: value should be
863
+	 * normalized (Eg, if providing a default of ra Yes_NO_Input you would provide TRUE or FALSE, not '1' or '0')
864
+	 *
865
+	 * @param mixed $value
866
+	 * @return void
867
+	 */
868
+	public function set_default($value)
869
+	{
870
+		$this->_default = $value;
871
+		$this->_set_normalized_value($value);
872
+		$this->_set_raw_value($value);
873
+	}
874
+
875
+
876
+
877
+	/**
878
+	 * Sets the normalized value on this input
879
+	 *
880
+	 * @param mixed $value
881
+	 */
882
+	protected function _set_normalized_value($value)
883
+	{
884
+		$this->_normalized_value = $value;
885
+	}
886
+
887
+
888
+
889
+	/**
890
+	 * Sets the raw value on this input (ie, exactly as the user submitted it)
891
+	 *
892
+	 * @param mixed $value
893
+	 */
894
+	protected function _set_raw_value($value)
895
+	{
896
+		$this->_raw_value = $this->_normalization_strategy->unnormalize($value);
897
+	}
898
+
899
+
900
+
901
+	/**
902
+	 * Sets the HTML label text after it has already been defined
903
+	 *
904
+	 * @param string $label
905
+	 * @return void
906
+	 */
907
+	public function set_html_label_text($label)
908
+	{
909
+		$this->_html_label_text = $label;
910
+	}
911
+
912
+
913
+
914
+	/**
915
+	 * Sets whether or not this field is required, and adjusts the validation strategy.
916
+	 * If you want to use the EE_Conditionally_Required_Validation_Strategy,
917
+	 * please add it as a validation strategy using add_validation_strategy as normal
918
+	 *
919
+	 * @param boolean $required boolean
920
+	 * @param null    $required_text
921
+	 */
922
+	public function set_required($required = true, $required_text = null)
923
+	{
924
+		$required = filter_var($required, FILTER_VALIDATE_BOOLEAN);
925
+		// whether $required is a string or a boolean, we want to add a required validation strategy
926
+		if ($required) {
927
+			$this->_add_validation_strategy(new EE_Required_Validation_Strategy($required_text));
928
+		} else {
929
+			$this->remove_validation_strategy('EE_Required_Validation_Strategy');
930
+		}
931
+		$this->_required = $required;
932
+	}
933
+
934
+
935
+
936
+	/**
937
+	 * Returns whether or not this field is required
938
+	 *
939
+	 * @return boolean
940
+	 */
941
+	public function required()
942
+	{
943
+		return $this->_required;
944
+	}
945
+
946
+
947
+
948
+	/**
949
+	 * @param string $required_css_class
950
+	 */
951
+	public function set_required_css_class($required_css_class)
952
+	{
953
+		$this->_required_css_class = $required_css_class;
954
+	}
955
+
956
+
957
+
958
+	/**
959
+	 * @return string
960
+	 */
961
+	public function required_css_class()
962
+	{
963
+		return $this->_required_css_class;
964
+	}
965
+
966
+
967
+
968
+	/**
969
+	 * @param bool $add_required
970
+	 * @return string
971
+	 */
972
+	public function html_class($add_required = false)
973
+	{
974
+		return $add_required && $this->required()
975
+			? $this->required_css_class() . ' ' . $this->_html_class
976
+			: $this->_html_class;
977
+	}
978
+
979
+
980
+	/**
981
+	 * Sets the help text, in case
982
+	 *
983
+	 * @param string $text
984
+	 */
985
+	public function set_html_help_text($text)
986
+	{
987
+		$this->_html_help_text = $text;
988
+	}
989
+
990
+
991
+
992
+	/**
993
+	 * Uses the sensitive data removal strategy to remove the sensitive data from this
994
+	 * input. If there is any kind of sensitive data removal on this input, we clear
995
+	 * out the raw value completely
996
+	 *
997
+	 * @return void
998
+	 */
999
+	public function clean_sensitive_data()
1000
+	{
1001
+		// if we do ANY kind of sensitive data removal on this, then just clear out the raw value
1002
+		// if we need more logic than this we'll make a strategy for it
1003
+		if ($this->_sensitive_data_removal_strategy
1004
+			&& ! $this->_sensitive_data_removal_strategy instanceof EE_No_Sensitive_Data_Removal
1005
+		) {
1006
+			$this->_set_raw_value(null);
1007
+		}
1008
+		// and clean the normalized value according to the appropriate strategy
1009
+		$this->_set_normalized_value(
1010
+			$this->get_sensitive_data_removal_strategy()->remove_sensitive_data(
1011
+				$this->_normalized_value
1012
+			)
1013
+		);
1014
+	}
1015
+
1016
+
1017
+
1018
+	/**
1019
+	 * @param bool   $primary
1020
+	 * @param string $button_size
1021
+	 * @param string $other_attributes
1022
+	 */
1023
+	public function set_button_css_attributes($primary = true, $button_size = '', $other_attributes = '')
1024
+	{
1025
+		$button_css_attributes = 'button';
1026
+		$button_css_attributes .= $primary === true ? ' button-primary' : ' button-secondary';
1027
+		switch ($button_size) {
1028
+			case 'xs':
1029
+			case 'extra-small':
1030
+				$button_css_attributes .= ' button-xs';
1031
+				break;
1032
+			case 'sm':
1033
+			case 'small':
1034
+				$button_css_attributes .= ' button-sm';
1035
+				break;
1036
+			case 'lg':
1037
+			case 'large':
1038
+				$button_css_attributes .= ' button-lg';
1039
+				break;
1040
+			case 'block':
1041
+				$button_css_attributes .= ' button-block';
1042
+				break;
1043
+			case 'md':
1044
+			case 'medium':
1045
+			default:
1046
+				$button_css_attributes .= '';
1047
+		}
1048
+		$this->_button_css_attributes .= ! empty($other_attributes)
1049
+			? $button_css_attributes . ' ' . $other_attributes
1050
+			: $button_css_attributes;
1051
+	}
1052
+
1053
+
1054
+
1055
+	/**
1056
+	 * @return string
1057
+	 */
1058
+	public function button_css_attributes()
1059
+	{
1060
+		if (empty($this->_button_css_attributes)) {
1061
+			$this->set_button_css_attributes();
1062
+		}
1063
+		return $this->_button_css_attributes;
1064
+	}
1065
+
1066
+
1067
+
1068
+	/**
1069
+	 * find_form_data_for_this_section
1070
+	 * using this section's name and its parents, finds the value of the form data that corresponds to it.
1071
+	 * For example, if this form section's HTML name is my_form[subform][form_input_1],
1072
+	 * then it's value should be in $_REQUEST at $_REQUEST['my_form']['subform']['form_input_1'].
1073
+	 * (If that doesn't exist, we also check for this subsection's name
1074
+	 * at the TOP LEVEL of the request data. Eg $_REQUEST['form_input_1'].)
1075
+	 * This function finds its value in the form.
1076
+	 *
1077
+	 * @param array $req_data
1078
+	 * @return mixed whatever the raw value of this form section is in the request data
1079
+	 * @throws \EE_Error
1080
+	 */
1081
+	public function find_form_data_for_this_section($req_data)
1082
+	{
1083
+		$name_parts = $this->getInputNameParts();
1084
+		// now get the value for the input
1085
+		$value = $this->findRequestForSectionUsingNameParts($name_parts, $req_data);
1086
+		// check if this thing's name is at the TOP level of the request data
1087
+		if ($value === null && isset($req_data[ $this->name() ])) {
1088
+			$value = $req_data[ $this->name() ];
1089
+		}
1090
+		return $value;
1091
+	}
1092
+
1093
+
1094
+
1095
+	/**
1096
+	 * If this input's name is something like "foo[bar][baz]"
1097
+	 * returns an array like `array('foo','bar',baz')`
1098
+	 * @return array
1099
+	 */
1100
+	protected function getInputNameParts()
1101
+	{
1102
+		// break up the html name by "[]"
1103
+		if (strpos($this->html_name(), '[') !== false) {
1104
+			$before_any_brackets = substr($this->html_name(), 0, strpos($this->html_name(), '['));
1105
+		} else {
1106
+			$before_any_brackets = $this->html_name();
1107
+		}
1108
+		// grab all of the segments
1109
+		preg_match_all('~\[([^]]*)\]~', $this->html_name(), $matches);
1110
+		if (isset($matches[1]) && is_array($matches[1])) {
1111
+			$name_parts = $matches[1];
1112
+			array_unshift($name_parts, $before_any_brackets);
1113
+		} else {
1114
+			$name_parts = array($before_any_brackets);
1115
+		}
1116
+		return $name_parts;
1117
+	}
1118
+
1119
+
1120
+
1121
+	/**
1122
+	 * @param array $html_name_parts
1123
+	 * @param array $req_data
1124
+	 * @return array | NULL
1125
+	 */
1126
+	public function findRequestForSectionUsingNameParts($html_name_parts, $req_data)
1127
+	{
1128
+		$first_part_to_consider = array_shift($html_name_parts);
1129
+		if (isset($req_data[ $first_part_to_consider ])) {
1130
+			if (empty($html_name_parts)) {
1131
+				return $req_data[ $first_part_to_consider ];
1132
+			} else {
1133
+				return $this->findRequestForSectionUsingNameParts(
1134
+					$html_name_parts,
1135
+					$req_data[ $first_part_to_consider ]
1136
+				);
1137
+			}
1138
+		} else {
1139
+			return null;
1140
+		}
1141
+	}
1142
+
1143
+
1144
+
1145
+	/**
1146
+	 * Checks if this form input's data is in the request data
1147
+	 *
1148
+	 * @param array $req_data like $_POST
1149
+	 * @return boolean
1150
+	 * @throws \EE_Error
1151
+	 */
1152
+	public function form_data_present_in($req_data = null)
1153
+	{
1154
+		if ($req_data === null) {
1155
+			$req_data = $_POST;
1156
+		}
1157
+		$checked_value = $this->find_form_data_for_this_section($req_data);
1158
+		if ($checked_value !== null) {
1159
+			return true;
1160
+		} else {
1161
+			return false;
1162
+		}
1163
+	}
1164
+
1165
+
1166
+
1167
+	/**
1168
+	 * Overrides parent to add js data from validation and display strategies
1169
+	 *
1170
+	 * @param array $form_other_js_data
1171
+	 * @return array
1172
+	 */
1173
+	public function get_other_js_data($form_other_js_data = array())
1174
+	{
1175
+		$form_other_js_data = $this->get_other_js_data_from_strategies($form_other_js_data);
1176
+		return $form_other_js_data;
1177
+	}
1178
+
1179
+
1180
+
1181
+	/**
1182
+	 * Gets other JS data for localization from this input's strategies, like
1183
+	 * the validation strategies and the display strategy
1184
+	 *
1185
+	 * @param array $form_other_js_data
1186
+	 * @return array
1187
+	 */
1188
+	public function get_other_js_data_from_strategies($form_other_js_data = array())
1189
+	{
1190
+		$form_other_js_data = $this->get_display_strategy()->get_other_js_data($form_other_js_data);
1191
+		foreach ($this->get_validation_strategies() as $validation_strategy) {
1192
+			$form_other_js_data = $validation_strategy->get_other_js_data($form_other_js_data);
1193
+		}
1194
+		return $form_other_js_data;
1195
+	}
1196
+
1197
+
1198
+
1199
+	/**
1200
+	 * Override parent because we want to give our strategies an opportunity to enqueue some js and css
1201
+	 *
1202
+	 * @return void
1203
+	 */
1204
+	public function enqueue_js()
1205
+	{
1206
+		// ask our display strategy and validation strategies if they have js to enqueue
1207
+		$this->enqueue_js_from_strategies();
1208
+	}
1209
+
1210
+
1211
+
1212
+	/**
1213
+	 * Tells strategies when its ok to enqueue their js and css
1214
+	 *
1215
+	 * @return void
1216
+	 */
1217
+	public function enqueue_js_from_strategies()
1218
+	{
1219
+		$this->get_display_strategy()->enqueue_js();
1220
+		foreach ($this->get_validation_strategies() as $validation_strategy) {
1221
+			$validation_strategy->enqueue_js();
1222
+		}
1223
+	}
1224
+
1225
+
1226
+
1227
+	/**
1228
+	 * Gets the default value set on the input (not the current value, which may have been
1229
+	 * changed because of a form submission). If no default was set, this us null.
1230
+	 * @return mixed
1231
+	 */
1232
+	public function get_default()
1233
+	{
1234
+		return $this->_default;
1235
+	}
1236
+
1237
+
1238
+
1239
+	/**
1240
+	 * Makes this input disabled. That means it will have the HTML attribute 'disabled="disabled"',
1241
+	 * and server-side if any input was received it will be ignored
1242
+	 */
1243
+	public function disable($disable = true)
1244
+	{
1245
+		$disabled_attribute = ' disabled="disabled"';
1246
+		$this->disabled = filter_var($disable, FILTER_VALIDATE_BOOLEAN);
1247
+		if ($this->disabled) {
1248
+			if (strpos($this->_other_html_attributes, $disabled_attribute) === false) {
1249
+				$this->_other_html_attributes .= $disabled_attribute;
1250
+			}
1251
+			$this->_set_normalized_value($this->get_default());
1252
+		} else {
1253
+			$this->_other_html_attributes = str_replace($disabled_attribute, '', $this->_other_html_attributes);
1254
+		}
1255
+	}
1256
+
1257
+
1258
+
1259
+	/**
1260
+	 * Returns whether or not this input is currently disabled.
1261
+	 * @return bool
1262
+	 */
1263
+	public function isDisabled()
1264
+	{
1265
+		return $this->disabled;
1266
+	}
1267 1267
 }
Please login to merge, or discard this patch.