Completed
Branch dev (97838e)
by
unknown
18:15 queued 10:24
created
core/db_models/EEM_WP_User.model.php 1 patch
Indentation   +122 added lines, -122 removed lines patch added patch discarded remove patch
@@ -12,132 +12,132 @@
 block discarded – undo
12 12
  */
13 13
 class EEM_WP_User extends EEM_Base
14 14
 {
15
-    /**
16
-     * private instance of the EEM_WP_User object
17
-     *
18
-     * @type EEM_WP_User
19
-     */
20
-    protected static $_instance;
15
+	/**
16
+	 * private instance of the EEM_WP_User object
17
+	 *
18
+	 * @type EEM_WP_User
19
+	 */
20
+	protected static $_instance;
21 21
 
22 22
 
23
-    /**
24
-     *    constructor
25
-     *
26
-     * @param null              $timezone
27
-     * @param ModelFieldFactory $model_field_factory
28
-     * @throws EE_Error
29
-     * @throws InvalidArgumentException
30
-     */
31
-    protected function __construct($timezone, ModelFieldFactory $model_field_factory)
32
-    {
33
-        $this->singular_item = esc_html__('WP_User', 'event_espresso');
34
-        $this->plural_item = esc_html__('WP_Users', 'event_espresso');
35
-        global $wpdb;
36
-        $this->_tables = array(
37
-            'WP_User' => new EE_Primary_Table($wpdb->users, 'ID', true),
38
-        );
39
-        $this->_fields = array(
40
-            'WP_User' => array(
41
-                'ID'                  => $model_field_factory->createPrimaryKeyIntField(
42
-                    'ID',
43
-                    esc_html__('WP_User ID', 'event_espresso')
44
-                ),
45
-                'user_login'          => $model_field_factory->createPlainTextField(
46
-                    'user_login',
47
-                    esc_html__('User Login', 'event_espresso'),
48
-                    false
49
-                ),
50
-                'user_pass'           => $model_field_factory->createPlainTextField(
51
-                    'user_pass',
52
-                    esc_html__('User Password', 'event_espresso'),
53
-                    false
54
-                ),
55
-                'user_nicename'       => $model_field_factory->createPlainTextField(
56
-                    'user_nicename',
57
-                    esc_html__(' User Nice Name', 'event_espresso'),
58
-                    false
59
-                ),
60
-                'user_email'          => $model_field_factory->createEmailField(
61
-                    'user_email',
62
-                    esc_html__('User Email', 'event_espresso'),
63
-                    false
64
-                ),
65
-                'user_registered'     => $model_field_factory->createDatetimeField(
66
-                    'user_registered',
67
-                    esc_html__('Date User Registered', 'event_espresso'),
68
-                    $timezone
69
-                ),
70
-                'user_activation_key' => $model_field_factory->createPlainTextField(
71
-                    'user_activation_key',
72
-                    esc_html__('User Activation Key', 'event_espresso'),
73
-                    false
74
-                ),
75
-                'user_status'         => $model_field_factory->createIntegerField(
76
-                    'user_status',
77
-                    esc_html__('User Status', 'event_espresso')
78
-                ),
79
-                'display_name'        => $model_field_factory->createPlainTextField(
80
-                    'display_name',
81
-                    esc_html__('Display Name', 'event_espresso'),
82
-                    false
83
-                ),
84
-            ),
85
-        );
86
-        $this->_model_relations = array(
87
-            'Attendee'       => new EE_Has_Many_Relation(),
88
-            // all models are related to the change log
89
-            // 'Change_Log'     => new EE_Has_Many_Relation(),
90
-            'Event'          => new EE_Has_Many_Relation(),
91
-            'Message'        => new EE_Has_Many_Relation(),
92
-            'Payment_Method' => new EE_Has_Many_Relation(),
93
-            'Price'          => new EE_Has_Many_Relation(),
94
-            'Price_Type'     => new EE_Has_Many_Relation(),
95
-            'Question'       => new EE_Has_Many_Relation(),
96
-            'Question_Group' => new EE_Has_Many_Relation(),
97
-            'Ticket'         => new EE_Has_Many_Relation(),
98
-            'Venue'          => new EE_Has_Many_Relation(),
99
-        );
100
-        $this->foreign_key_aliases = [
101
-            'Event.EVT_wp_user'          => 'WP_User.ID',
102
-            'Payment_Method.PMD_wp_user' => 'WP_User.ID',
103
-            'Price.PRC_wp_user'          => 'WP_User.ID',
104
-            'Price_Type.PRT_wp_user'     => 'WP_User.ID',
105
-            'Question.QST_wp_user'       => 'WP_User.ID',
106
-            'Question_Group.QSG_wp_user' => 'WP_User.ID',
107
-            'Ticket.VNU_wp_user'         => 'WP_User.ID',
108
-            'Venue.TKT_wp_user'          => 'WP_User.ID',
109
-        ];
110
-        $this->_wp_core_model = true;
111
-        $this->_caps_slug = 'users';
112
-        $this->_cap_contexts_to_cap_action_map[ EEM_Base::caps_read ] = 'list';
113
-        $this->_cap_contexts_to_cap_action_map[ EEM_Base::caps_read_admin ] = 'list';
114
-        foreach ($this->_cap_contexts_to_cap_action_map as $context => $action) {
115
-            $this->_cap_restriction_generators[ $context ] = new EE_Restriction_Generator_WP_User();
116
-        }
117
-        // @todo: account for create_users controls whether they can create users at all
118
-        parent::__construct($timezone);
119
-    }
23
+	/**
24
+	 *    constructor
25
+	 *
26
+	 * @param null              $timezone
27
+	 * @param ModelFieldFactory $model_field_factory
28
+	 * @throws EE_Error
29
+	 * @throws InvalidArgumentException
30
+	 */
31
+	protected function __construct($timezone, ModelFieldFactory $model_field_factory)
32
+	{
33
+		$this->singular_item = esc_html__('WP_User', 'event_espresso');
34
+		$this->plural_item = esc_html__('WP_Users', 'event_espresso');
35
+		global $wpdb;
36
+		$this->_tables = array(
37
+			'WP_User' => new EE_Primary_Table($wpdb->users, 'ID', true),
38
+		);
39
+		$this->_fields = array(
40
+			'WP_User' => array(
41
+				'ID'                  => $model_field_factory->createPrimaryKeyIntField(
42
+					'ID',
43
+					esc_html__('WP_User ID', 'event_espresso')
44
+				),
45
+				'user_login'          => $model_field_factory->createPlainTextField(
46
+					'user_login',
47
+					esc_html__('User Login', 'event_espresso'),
48
+					false
49
+				),
50
+				'user_pass'           => $model_field_factory->createPlainTextField(
51
+					'user_pass',
52
+					esc_html__('User Password', 'event_espresso'),
53
+					false
54
+				),
55
+				'user_nicename'       => $model_field_factory->createPlainTextField(
56
+					'user_nicename',
57
+					esc_html__(' User Nice Name', 'event_espresso'),
58
+					false
59
+				),
60
+				'user_email'          => $model_field_factory->createEmailField(
61
+					'user_email',
62
+					esc_html__('User Email', 'event_espresso'),
63
+					false
64
+				),
65
+				'user_registered'     => $model_field_factory->createDatetimeField(
66
+					'user_registered',
67
+					esc_html__('Date User Registered', 'event_espresso'),
68
+					$timezone
69
+				),
70
+				'user_activation_key' => $model_field_factory->createPlainTextField(
71
+					'user_activation_key',
72
+					esc_html__('User Activation Key', 'event_espresso'),
73
+					false
74
+				),
75
+				'user_status'         => $model_field_factory->createIntegerField(
76
+					'user_status',
77
+					esc_html__('User Status', 'event_espresso')
78
+				),
79
+				'display_name'        => $model_field_factory->createPlainTextField(
80
+					'display_name',
81
+					esc_html__('Display Name', 'event_espresso'),
82
+					false
83
+				),
84
+			),
85
+		);
86
+		$this->_model_relations = array(
87
+			'Attendee'       => new EE_Has_Many_Relation(),
88
+			// all models are related to the change log
89
+			// 'Change_Log'     => new EE_Has_Many_Relation(),
90
+			'Event'          => new EE_Has_Many_Relation(),
91
+			'Message'        => new EE_Has_Many_Relation(),
92
+			'Payment_Method' => new EE_Has_Many_Relation(),
93
+			'Price'          => new EE_Has_Many_Relation(),
94
+			'Price_Type'     => new EE_Has_Many_Relation(),
95
+			'Question'       => new EE_Has_Many_Relation(),
96
+			'Question_Group' => new EE_Has_Many_Relation(),
97
+			'Ticket'         => new EE_Has_Many_Relation(),
98
+			'Venue'          => new EE_Has_Many_Relation(),
99
+		);
100
+		$this->foreign_key_aliases = [
101
+			'Event.EVT_wp_user'          => 'WP_User.ID',
102
+			'Payment_Method.PMD_wp_user' => 'WP_User.ID',
103
+			'Price.PRC_wp_user'          => 'WP_User.ID',
104
+			'Price_Type.PRT_wp_user'     => 'WP_User.ID',
105
+			'Question.QST_wp_user'       => 'WP_User.ID',
106
+			'Question_Group.QSG_wp_user' => 'WP_User.ID',
107
+			'Ticket.VNU_wp_user'         => 'WP_User.ID',
108
+			'Venue.TKT_wp_user'          => 'WP_User.ID',
109
+		];
110
+		$this->_wp_core_model = true;
111
+		$this->_caps_slug = 'users';
112
+		$this->_cap_contexts_to_cap_action_map[ EEM_Base::caps_read ] = 'list';
113
+		$this->_cap_contexts_to_cap_action_map[ EEM_Base::caps_read_admin ] = 'list';
114
+		foreach ($this->_cap_contexts_to_cap_action_map as $context => $action) {
115
+			$this->_cap_restriction_generators[ $context ] = new EE_Restriction_Generator_WP_User();
116
+		}
117
+		// @todo: account for create_users controls whether they can create users at all
118
+		parent::__construct($timezone);
119
+	}
120 120
 
121 121
 
122
-    /**
123
-     * We don't need a foreign key to the WP_User model, we just need its primary key
124
-     *
125
-     * @return string
126
-     * @throws EE_Error
127
-     */
128
-    public function wp_user_field_name()
129
-    {
130
-        return $this->primary_key_name();
131
-    }
122
+	/**
123
+	 * We don't need a foreign key to the WP_User model, we just need its primary key
124
+	 *
125
+	 * @return string
126
+	 * @throws EE_Error
127
+	 */
128
+	public function wp_user_field_name()
129
+	{
130
+		return $this->primary_key_name();
131
+	}
132 132
 
133 133
 
134
-    /**
135
-     * This WP_User model IS owned, even though it doesn't have a foreign key to itself
136
-     *
137
-     * @return boolean
138
-     */
139
-    public function is_owned()
140
-    {
141
-        return true;
142
-    }
134
+	/**
135
+	 * This WP_User model IS owned, even though it doesn't have a foreign key to itself
136
+	 *
137
+	 * @return boolean
138
+	 */
139
+	public function is_owned()
140
+	{
141
+		return true;
142
+	}
143 143
 }
Please login to merge, or discard this patch.
core/libraries/messages/messenger/EE_Html_messenger.class.php 1 patch
Indentation   +546 added lines, -546 removed lines patch added patch discarded remove patch
@@ -12,550 +12,550 @@
 block discarded – undo
12 12
  */
13 13
 class EE_Html_messenger extends EE_messenger
14 14
 {
15
-    /**
16
-     * The following are the properties that this messenger requires for displaying the html
17
-     */
18
-    /**
19
-     * This is the html body generated by the template via the message type.
20
-     *
21
-     * @var string
22
-     */
23
-    protected $_content;
24
-
25
-
26
-    /**
27
-     * This is for the page title that gets displayed.  (Why use "subject"?  Because the "title" tag in html is
28
-     * equivalent to the "subject" of the page.
29
-     *
30
-     * @var string
31
-     */
32
-    protected $_subject;
33
-
34
-
35
-    /**
36
-     * EE_Html_messenger constructor.
37
-     */
38
-    public function __construct()
39
-    {
40
-        // set properties
41
-        $this->name = 'html';
42
-        $this->description = esc_html__('This messenger outputs a message to a browser for display.', 'event_espresso');
43
-        $this->label = array(
44
-            'singular' => esc_html__('html', 'event_espresso'),
45
-            'plural' => esc_html__('html', 'event_espresso'),
46
-        );
47
-        $this->activate_on_install = true;
48
-        // add the "powered by EE" credit link to the HTML receipt and invoice
49
-        add_filter(
50
-            'FHEE__EE_Html_messenger___send_message__main_body',
51
-            array($this, 'add_powered_by_credit_link_to_receipt_and_invoice'),
52
-            10,
53
-            3
54
-        );
55
-        parent::__construct();
56
-    }
57
-
58
-
59
-    /**
60
-     * HTML Messenger desires execution immediately.
61
-     *
62
-     * @see    parent::send_now() for documentation.
63
-     * @since  4.9.0
64
-     * @return bool
65
-     */
66
-    public function send_now()
67
-    {
68
-        return true;
69
-    }
70
-
71
-
72
-    /**
73
-     * HTML Messenger allows an empty to field.
74
-     *
75
-     * @see    parent::allow_empty_to_field() for documentation
76
-     * @since  4.9.0
77
-     * @return bool
78
-     */
79
-    public function allow_empty_to_field()
80
-    {
81
-        return true;
82
-    }
83
-
84
-
85
-    /**
86
-     * @see abstract declaration in EE_messenger for details.
87
-     */
88
-    protected function _set_admin_pages()
89
-    {
90
-        $this->admin_registered_pages = array('events_edit' => true);
91
-    }
92
-
93
-
94
-    /**
95
-     * @see abstract declaration in EE_messenger for details.
96
-     */
97
-    protected function _set_valid_shortcodes()
98
-    {
99
-        $this->_valid_shortcodes = array();
100
-    }
101
-
102
-
103
-    /**
104
-     * @see abstract declaration in EE_messenger for details.
105
-     */
106
-    protected function _set_validator_config()
107
-    {
108
-        $this->_validator_config = array(
109
-            'subject' => array(
110
-                'shortcodes' => array('organization', 'primary_registration_details', 'email', 'transaction'),
111
-            ),
112
-            'content' => array(
113
-                'shortcodes' => array(
114
-                    'organization',
115
-                    'primary_registration_list',
116
-                    'primary_registration_details',
117
-                    'email',
118
-                    'transaction',
119
-                    'event_list',
120
-                    'payment_list',
121
-                    'venue',
122
-                    'line_item_list',
123
-                    'messenger',
124
-                    'ticket_list',
125
-                ),
126
-            ),
127
-            'event_list' => array(
128
-                'shortcodes' => array(
129
-                    'event',
130
-                    'ticket_list',
131
-                    'venue',
132
-                    'primary_registration_details',
133
-                    'primary_registration_list',
134
-                    'event_author',
135
-                ),
136
-                'required' => array('[EVENT_LIST]'),
137
-            ),
138
-            'ticket_list' => array(
139
-                'shortcodes' => array(
140
-                    'attendee_list',
141
-                    'ticket',
142
-                    'datetime_list',
143
-                    'primary_registration_details',
144
-                    'line_item_list',
145
-                    'venue',
146
-                ),
147
-                'required' => array('[TICKET_LIST]'),
148
-            ),
149
-            'ticket_line_item_no_pms' => array(
150
-                'shortcodes' => array('line_item', 'ticket'),
151
-                'required' => array('[TICKET_LINE_ITEM_LIST]'),
152
-            ),
153
-            'ticket_line_item_pms' => array(
154
-                'shortcodes' => array('line_item', 'ticket', 'line_item_list'),
155
-                'required' => array('[TICKET_LINE_ITEM_LIST]'),
156
-            ),
157
-            'price_modifier_line_item_list' => array(
158
-                'shortcodes' => array('line_item'),
159
-                'required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
160
-            ),
161
-            'datetime_list' => array(
162
-                'shortcodes' => array('datetime'),
163
-                'required' => array('[DATETIME_LIST]'),
164
-            ),
165
-            'attendee_list' => array(
166
-                'shortcodes' => array('attendee'),
167
-                'required' => array('[ATTENDEE_LIST]'),
168
-            ),
169
-            'tax_line_item_list' => array(
170
-                'shortcodes' => array('line_item'),
171
-                'required' => array('[TAX_LINE_ITEM_LIST]'),
172
-            ),
173
-            'additional_line_item_list' => array(
174
-                'shortcodes' => array('line_item'),
175
-                'required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
176
-            ),
177
-            'payment_list' => array(
178
-                'shortcodes' => array('payment'),
179
-                'required' => array('[PAYMENT_LIST_*]'),
180
-            ),
181
-        );
182
-    }
183
-
184
-
185
-    /**
186
-     * This is a method called from EE_messages when this messenger is a generating messenger and the sending messenger
187
-     * is a different messenger.  Child messengers can set hooks for the sending messenger to callback on if necessary
188
-     * (i.e. swap out css files or something else).
189
-     *
190
-     * @since 4.5.0
191
-     * @param string $sending_messenger_name the name of the sending messenger so we only set the hooks needed.
192
-     * @return void
193
-     */
194
-    public function do_secondary_messenger_hooks($sending_messenger_name)
195
-    {
196
-        if ($sending_messenger_name === 'pdf') {
197
-            add_filter('EE_messenger__get_variation__variation', array($this, 'add_html_css'), 10, 8);
198
-        }
199
-    }
200
-
201
-
202
-    /**
203
-     * @param                            $variation_path
204
-     * @param \EE_Messages_Template_Pack $template_pack
205
-     * @param                            $messenger_name
206
-     * @param                            $message_type_name
207
-     * @param                            $url
208
-     * @param                            $type
209
-     * @param                            $variation
210
-     * @param                            $skip_filters
211
-     * @return string
212
-     */
213
-    public function add_html_css(
214
-        $variation_path,
215
-        EE_Messages_Template_Pack $template_pack,
216
-        $messenger_name,
217
-        $message_type_name,
218
-        $url,
219
-        $type,
220
-        $variation,
221
-        $skip_filters
222
-    ) {
223
-        $variation = $template_pack->get_variation(
224
-            $this->name,
225
-            $message_type_name,
226
-            $type,
227
-            $variation,
228
-            $url,
229
-            '.css',
230
-            $skip_filters
231
-        );
232
-        return $variation;
233
-    }
234
-
235
-
236
-    /**
237
-     * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this
238
-     * messenger can add their own js.
239
-     *
240
-     * @return void.
241
-     */
242
-    public function enqueue_scripts_styles()
243
-    {
244
-        parent::enqueue_scripts_styles();
245
-        do_action('AHEE__EE_Html_messenger__enqueue_scripts_styles');
246
-    }
247
-
248
-
249
-    /**
250
-     * _set_template_fields
251
-     * This sets up the fields that a messenger requires for the message to go out.
252
-     *
253
-     * @access  protected
254
-     * @return void
255
-     */
256
-    protected function _set_template_fields()
257
-    {
258
-        // any extra template fields that are NOT used by the messenger
259
-        // but will get used by a messenger field for shortcode replacement
260
-        // get added to the 'extra' key in an associated array
261
-        // indexed by the messenger field they relate to.
262
-        // This is important for the Messages_admin to know what fields to display to the user.
263
-        // Also, notice that the "values" are equal to the field type
264
-        // that messages admin will use to know what kind of field to display.
265
-        // The values ALSO have one index labeled "shortcode".
266
-        // The values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE])
267
-        // is required in order for this extra field to be displayed.
268
-        //  If the required shortcode isn't part of the shortcodes array
269
-        // then the field is not needed and will not be displayed/parsed.
270
-        $this->_template_fields = array(
271
-            'subject' => array(
272
-                'input' => 'text',
273
-                'label' => esc_html__('Page Title', 'event_espresso'),
274
-                'type' => 'string',
275
-                'required' => true,
276
-                'validation' => true,
277
-                'css_class' => 'large-text',
278
-                'format' => '%s',
279
-            ),
280
-            'content' => '',
281
-            // left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
282
-            'extra' => array(
283
-                'content' => array(
284
-                    'main' => array(
285
-                        'input' => 'wp_editor',
286
-                        'label' => esc_html__('Main Content', 'event_espresso'),
287
-                        'type' => 'string',
288
-                        'required' => true,
289
-                        'validation' => true,
290
-                        'format' => '%s',
291
-                        'rows' => '15',
292
-                    ),
293
-                    'event_list' => array(
294
-                        'input' => 'wp_editor',
295
-                        'label' => '[EVENT_LIST]',
296
-                        'type' => 'string',
297
-                        'required' => true,
298
-                        'validation' => true,
299
-                        'format' => '%s',
300
-                        'rows' => '15',
301
-                        'shortcodes_required' => array('[EVENT_LIST]'),
302
-                    ),
303
-                    'ticket_list' => array(
304
-                        'input' => 'textarea',
305
-                        'label' => '[TICKET_LIST]',
306
-                        'type' => 'string',
307
-                        'required' => true,
308
-                        'validation' => true,
309
-                        'format' => '%s',
310
-                        'css_class' => 'large-text',
311
-                        'rows' => '10',
312
-                        'shortcodes_required' => array('[TICKET_LIST]'),
313
-                    ),
314
-                    'ticket_line_item_no_pms' => array(
315
-                        'input' => 'textarea',
316
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . esc_html__(
317
-                            'Ticket Line Item List with no Price Modifiers',
318
-                            'event_espresso'
319
-                        ),
320
-                        'type' => 'string',
321
-                        'required' => false,
322
-                        'validation' => true,
323
-                        'format' => '%s',
324
-                        'css_class' => 'large-text',
325
-                        'rows' => '5',
326
-                        'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
327
-                    ),
328
-                    'ticket_line_item_pms' => array(
329
-                        'input' => 'textarea',
330
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . esc_html__(
331
-                            'Ticket Line Item List with Price Modifiers',
332
-                            'event_espresso'
333
-                        ),
334
-                        'type' => 'string',
335
-                        'required' => false,
336
-                        'validation' => true,
337
-                        'format' => '%s',
338
-                        'css_class' => 'large-text',
339
-                        'rows' => '5',
340
-                        'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
341
-                    ),
342
-                    'price_modifier_line_item_list' => array(
343
-                        'input' => 'textarea',
344
-                        'label' => '[PRICE_MODIFIER_LINE_ITEM_LIST]',
345
-                        'type' => 'string',
346
-                        'required' => false,
347
-                        'validation' => true,
348
-                        'format' => '%s',
349
-                        'css_class' => 'large-text',
350
-                        'rows' => '5',
351
-                        'shortcodes_required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
352
-                    ),
353
-                    'datetime_list' => array(
354
-                        'input' => 'textarea',
355
-                        'label' => '[DATETIME_LIST]',
356
-                        'type' => 'string',
357
-                        'required' => true,
358
-                        'validation' => true,
359
-                        'format' => '%s',
360
-                        'css_class' => 'large-text',
361
-                        'rows' => '5',
362
-                        'shortcodes_required' => array('[DATETIME_LIST]'),
363
-                    ),
364
-                    'attendee_list' => array(
365
-                        'input' => 'textarea',
366
-                        'label' => '[ATTENDEE_LIST]',
367
-                        'type' => 'string',
368
-                        'required' => true,
369
-                        'validation' => true,
370
-                        'format' => '%s',
371
-                        'css_class' => 'large-text',
372
-                        'rows' => '5',
373
-                        'shortcodes_required' => array('[ATTENDEE_LIST]'),
374
-                    ),
375
-                    'tax_line_item_list' => array(
376
-                        'input' => 'textarea',
377
-                        'label' => '[TAX_LINE_ITEM_LIST]',
378
-                        'type' => 'string',
379
-                        'required' => false,
380
-                        'validation' => true,
381
-                        'format' => '%s',
382
-                        'css_class' => 'large-text',
383
-                        'rows' => '5',
384
-                        'shortcodes_required' => array('[TAX_LINE_ITEM_LIST]'),
385
-                    ),
386
-                    'additional_line_item_list' => array(
387
-                        'input' => 'textarea',
388
-                        'label' => '[ADDITIONAL_LINE_ITEM_LIST]',
389
-                        'type' => 'string',
390
-                        'required' => false,
391
-                        'validation' => true,
392
-                        'format' => '%s',
393
-                        'css_class' => 'large-text',
394
-                        'rows' => '5',
395
-                        'shortcodes_required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
396
-                    ),
397
-                    'payment_list' => array(
398
-                        'input' => 'textarea',
399
-                        'label' => '[PAYMENT_LIST]',
400
-                        'type' => 'string',
401
-                        'required' => true,
402
-                        'validation' => true,
403
-                        'format' => '%s',
404
-                        'css_class' => 'large-text',
405
-                        'rows' => '5',
406
-                        'shortcodes_required' => array('[PAYMENT_LIST_*]'),
407
-                    ),
408
-                ),
409
-            ),
410
-        );
411
-    }
412
-
413
-
414
-    /**
415
-     * @see   definition of this method in parent
416
-     * @since 4.5.0
417
-     */
418
-    protected function _set_default_message_types()
419
-    {
420
-        $this->_default_message_types = array('receipt', 'invoice');
421
-    }
422
-
423
-
424
-    /**
425
-     * @see   definition of this method in parent
426
-     * @since 4.5.0
427
-     */
428
-    protected function _set_valid_message_types()
429
-    {
430
-        $this->_valid_message_types = array('receipt', 'invoice');
431
-    }
432
-
433
-
434
-    /**
435
-     * Displays the message in the browser.
436
-     *
437
-     * @since 4.5.0
438
-     * @return string.
439
-     */
440
-    protected function _send_message()
441
-    {
442
-        $this->_template_args = array(
443
-            'page_title' => $this->_subject,
444
-            'base_css' => $this->get_variation(
445
-                $this->_tmp_pack,
446
-                $this->_incoming_message_type->name,
447
-                true,
448
-                'base',
449
-                $this->_variation
450
-            ),
451
-            'print_css' => $this->get_variation(
452
-                $this->_tmp_pack,
453
-                $this->_incoming_message_type->name,
454
-                true,
455
-                'print',
456
-                $this->_variation
457
-            ),
458
-            'main_css' => $this->get_variation(
459
-                $this->_tmp_pack,
460
-                $this->_incoming_message_type->name,
461
-                true,
462
-                'main',
463
-                $this->_variation
464
-            ),
465
-            'main_body' => wpautop(
466
-                apply_filters(
467
-                    'FHEE__EE_Html_messenger___send_message__main_body',
468
-                    $this->_content,
469
-                    $this->_content,
470
-                    $this->_incoming_message_type
471
-                )
472
-            )
473
-        );
474
-        $this->_deregister_wp_hooks();
475
-        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
476
-
477
-        echo $this->_get_main_template();
478
-        exit();
479
-    }
480
-
481
-
482
-    /**
483
-     * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't
484
-     * interfere with our templates.  If users want to add any custom styles or scripts they must use the
485
-     * AHEE__EE_Html_messenger__enqueue_scripts_styles hook.
486
-     *
487
-     * @since 4.5.0
488
-     * @return void
489
-     */
490
-    protected function _deregister_wp_hooks()
491
-    {
492
-        remove_all_actions('wp_head');
493
-        remove_all_actions('wp_footer');
494
-        remove_all_actions('wp_print_footer_scripts');
495
-        remove_all_actions('wp_enqueue_scripts');
496
-        global $wp_scripts, $wp_styles;
497
-        $wp_scripts = $wp_styles = array();
498
-        // just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
499
-        add_action('wp_footer', 'wp_print_footer_scripts');
500
-        add_action('wp_print_footer_scripts', '_wp_footer_scripts');
501
-        add_action('wp_head', 'wp_enqueue_scripts');
502
-    }
503
-
504
-
505
-    /**
506
-     * Overwrite parent _get_main_template for display_html purposes.
507
-     *
508
-     * @since  4.5.0
509
-     * @param bool $preview
510
-     * @return string
511
-     */
512
-    protected function _get_main_template($preview = false)
513
-    {
514
-        $wrapper_template = $this->_tmp_pack->get_wrapper($this->name, 'main');
515
-        // include message type as a template arg
516
-        $this->_template_args['message_type'] = $this->_incoming_message_type;
517
-        return EEH_Template::display_template($wrapper_template, $this->_template_args, true);
518
-    }
519
-
520
-
521
-    /**
522
-     * @return string
523
-     */
524
-    protected function _preview()
525
-    {
526
-        return $this->_send_message();
527
-    }
528
-
529
-
530
-    protected function _set_admin_settings_fields()
531
-    {
532
-    }
533
-
534
-
535
-    /**
536
-     * add the "powered by EE" credit link to the HTML receipt and invoice
537
-     *
538
-     * @param string $content
539
-     * @param string $content_again
540
-     * @param \EE_message_type $incoming_message_type
541
-     * @return string
542
-     */
543
-    public function add_powered_by_credit_link_to_receipt_and_invoice(
544
-        $content,
545
-        $content_again,
546
-        EE_message_type $incoming_message_type
547
-    ) {
548
-        if (
549
-            ($incoming_message_type->name === 'invoice' || $incoming_message_type->name === 'receipt')
550
-            && apply_filters('FHEE_EE_Html_messenger__add_powered_by_credit_link_to_receipt_and_invoice', true)
551
-        ) {
552
-            $content .= \EEH_Template::powered_by_event_espresso(
553
-                'aln-cntr',
554
-                '',
555
-                array('utm_content' => 'messages_system')
556
-            )
557
-                . EEH_HTML::div(EEH_HTML::p('&nbsp;'));
558
-        }
559
-        return $content;
560
-    }
15
+	/**
16
+	 * The following are the properties that this messenger requires for displaying the html
17
+	 */
18
+	/**
19
+	 * This is the html body generated by the template via the message type.
20
+	 *
21
+	 * @var string
22
+	 */
23
+	protected $_content;
24
+
25
+
26
+	/**
27
+	 * This is for the page title that gets displayed.  (Why use "subject"?  Because the "title" tag in html is
28
+	 * equivalent to the "subject" of the page.
29
+	 *
30
+	 * @var string
31
+	 */
32
+	protected $_subject;
33
+
34
+
35
+	/**
36
+	 * EE_Html_messenger constructor.
37
+	 */
38
+	public function __construct()
39
+	{
40
+		// set properties
41
+		$this->name = 'html';
42
+		$this->description = esc_html__('This messenger outputs a message to a browser for display.', 'event_espresso');
43
+		$this->label = array(
44
+			'singular' => esc_html__('html', 'event_espresso'),
45
+			'plural' => esc_html__('html', 'event_espresso'),
46
+		);
47
+		$this->activate_on_install = true;
48
+		// add the "powered by EE" credit link to the HTML receipt and invoice
49
+		add_filter(
50
+			'FHEE__EE_Html_messenger___send_message__main_body',
51
+			array($this, 'add_powered_by_credit_link_to_receipt_and_invoice'),
52
+			10,
53
+			3
54
+		);
55
+		parent::__construct();
56
+	}
57
+
58
+
59
+	/**
60
+	 * HTML Messenger desires execution immediately.
61
+	 *
62
+	 * @see    parent::send_now() for documentation.
63
+	 * @since  4.9.0
64
+	 * @return bool
65
+	 */
66
+	public function send_now()
67
+	{
68
+		return true;
69
+	}
70
+
71
+
72
+	/**
73
+	 * HTML Messenger allows an empty to field.
74
+	 *
75
+	 * @see    parent::allow_empty_to_field() for documentation
76
+	 * @since  4.9.0
77
+	 * @return bool
78
+	 */
79
+	public function allow_empty_to_field()
80
+	{
81
+		return true;
82
+	}
83
+
84
+
85
+	/**
86
+	 * @see abstract declaration in EE_messenger for details.
87
+	 */
88
+	protected function _set_admin_pages()
89
+	{
90
+		$this->admin_registered_pages = array('events_edit' => true);
91
+	}
92
+
93
+
94
+	/**
95
+	 * @see abstract declaration in EE_messenger for details.
96
+	 */
97
+	protected function _set_valid_shortcodes()
98
+	{
99
+		$this->_valid_shortcodes = array();
100
+	}
101
+
102
+
103
+	/**
104
+	 * @see abstract declaration in EE_messenger for details.
105
+	 */
106
+	protected function _set_validator_config()
107
+	{
108
+		$this->_validator_config = array(
109
+			'subject' => array(
110
+				'shortcodes' => array('organization', 'primary_registration_details', 'email', 'transaction'),
111
+			),
112
+			'content' => array(
113
+				'shortcodes' => array(
114
+					'organization',
115
+					'primary_registration_list',
116
+					'primary_registration_details',
117
+					'email',
118
+					'transaction',
119
+					'event_list',
120
+					'payment_list',
121
+					'venue',
122
+					'line_item_list',
123
+					'messenger',
124
+					'ticket_list',
125
+				),
126
+			),
127
+			'event_list' => array(
128
+				'shortcodes' => array(
129
+					'event',
130
+					'ticket_list',
131
+					'venue',
132
+					'primary_registration_details',
133
+					'primary_registration_list',
134
+					'event_author',
135
+				),
136
+				'required' => array('[EVENT_LIST]'),
137
+			),
138
+			'ticket_list' => array(
139
+				'shortcodes' => array(
140
+					'attendee_list',
141
+					'ticket',
142
+					'datetime_list',
143
+					'primary_registration_details',
144
+					'line_item_list',
145
+					'venue',
146
+				),
147
+				'required' => array('[TICKET_LIST]'),
148
+			),
149
+			'ticket_line_item_no_pms' => array(
150
+				'shortcodes' => array('line_item', 'ticket'),
151
+				'required' => array('[TICKET_LINE_ITEM_LIST]'),
152
+			),
153
+			'ticket_line_item_pms' => array(
154
+				'shortcodes' => array('line_item', 'ticket', 'line_item_list'),
155
+				'required' => array('[TICKET_LINE_ITEM_LIST]'),
156
+			),
157
+			'price_modifier_line_item_list' => array(
158
+				'shortcodes' => array('line_item'),
159
+				'required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
160
+			),
161
+			'datetime_list' => array(
162
+				'shortcodes' => array('datetime'),
163
+				'required' => array('[DATETIME_LIST]'),
164
+			),
165
+			'attendee_list' => array(
166
+				'shortcodes' => array('attendee'),
167
+				'required' => array('[ATTENDEE_LIST]'),
168
+			),
169
+			'tax_line_item_list' => array(
170
+				'shortcodes' => array('line_item'),
171
+				'required' => array('[TAX_LINE_ITEM_LIST]'),
172
+			),
173
+			'additional_line_item_list' => array(
174
+				'shortcodes' => array('line_item'),
175
+				'required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
176
+			),
177
+			'payment_list' => array(
178
+				'shortcodes' => array('payment'),
179
+				'required' => array('[PAYMENT_LIST_*]'),
180
+			),
181
+		);
182
+	}
183
+
184
+
185
+	/**
186
+	 * This is a method called from EE_messages when this messenger is a generating messenger and the sending messenger
187
+	 * is a different messenger.  Child messengers can set hooks for the sending messenger to callback on if necessary
188
+	 * (i.e. swap out css files or something else).
189
+	 *
190
+	 * @since 4.5.0
191
+	 * @param string $sending_messenger_name the name of the sending messenger so we only set the hooks needed.
192
+	 * @return void
193
+	 */
194
+	public function do_secondary_messenger_hooks($sending_messenger_name)
195
+	{
196
+		if ($sending_messenger_name === 'pdf') {
197
+			add_filter('EE_messenger__get_variation__variation', array($this, 'add_html_css'), 10, 8);
198
+		}
199
+	}
200
+
201
+
202
+	/**
203
+	 * @param                            $variation_path
204
+	 * @param \EE_Messages_Template_Pack $template_pack
205
+	 * @param                            $messenger_name
206
+	 * @param                            $message_type_name
207
+	 * @param                            $url
208
+	 * @param                            $type
209
+	 * @param                            $variation
210
+	 * @param                            $skip_filters
211
+	 * @return string
212
+	 */
213
+	public function add_html_css(
214
+		$variation_path,
215
+		EE_Messages_Template_Pack $template_pack,
216
+		$messenger_name,
217
+		$message_type_name,
218
+		$url,
219
+		$type,
220
+		$variation,
221
+		$skip_filters
222
+	) {
223
+		$variation = $template_pack->get_variation(
224
+			$this->name,
225
+			$message_type_name,
226
+			$type,
227
+			$variation,
228
+			$url,
229
+			'.css',
230
+			$skip_filters
231
+		);
232
+		return $variation;
233
+	}
234
+
235
+
236
+	/**
237
+	 * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this
238
+	 * messenger can add their own js.
239
+	 *
240
+	 * @return void.
241
+	 */
242
+	public function enqueue_scripts_styles()
243
+	{
244
+		parent::enqueue_scripts_styles();
245
+		do_action('AHEE__EE_Html_messenger__enqueue_scripts_styles');
246
+	}
247
+
248
+
249
+	/**
250
+	 * _set_template_fields
251
+	 * This sets up the fields that a messenger requires for the message to go out.
252
+	 *
253
+	 * @access  protected
254
+	 * @return void
255
+	 */
256
+	protected function _set_template_fields()
257
+	{
258
+		// any extra template fields that are NOT used by the messenger
259
+		// but will get used by a messenger field for shortcode replacement
260
+		// get added to the 'extra' key in an associated array
261
+		// indexed by the messenger field they relate to.
262
+		// This is important for the Messages_admin to know what fields to display to the user.
263
+		// Also, notice that the "values" are equal to the field type
264
+		// that messages admin will use to know what kind of field to display.
265
+		// The values ALSO have one index labeled "shortcode".
266
+		// The values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE])
267
+		// is required in order for this extra field to be displayed.
268
+		//  If the required shortcode isn't part of the shortcodes array
269
+		// then the field is not needed and will not be displayed/parsed.
270
+		$this->_template_fields = array(
271
+			'subject' => array(
272
+				'input' => 'text',
273
+				'label' => esc_html__('Page Title', 'event_espresso'),
274
+				'type' => 'string',
275
+				'required' => true,
276
+				'validation' => true,
277
+				'css_class' => 'large-text',
278
+				'format' => '%s',
279
+			),
280
+			'content' => '',
281
+			// left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
282
+			'extra' => array(
283
+				'content' => array(
284
+					'main' => array(
285
+						'input' => 'wp_editor',
286
+						'label' => esc_html__('Main Content', 'event_espresso'),
287
+						'type' => 'string',
288
+						'required' => true,
289
+						'validation' => true,
290
+						'format' => '%s',
291
+						'rows' => '15',
292
+					),
293
+					'event_list' => array(
294
+						'input' => 'wp_editor',
295
+						'label' => '[EVENT_LIST]',
296
+						'type' => 'string',
297
+						'required' => true,
298
+						'validation' => true,
299
+						'format' => '%s',
300
+						'rows' => '15',
301
+						'shortcodes_required' => array('[EVENT_LIST]'),
302
+					),
303
+					'ticket_list' => array(
304
+						'input' => 'textarea',
305
+						'label' => '[TICKET_LIST]',
306
+						'type' => 'string',
307
+						'required' => true,
308
+						'validation' => true,
309
+						'format' => '%s',
310
+						'css_class' => 'large-text',
311
+						'rows' => '10',
312
+						'shortcodes_required' => array('[TICKET_LIST]'),
313
+					),
314
+					'ticket_line_item_no_pms' => array(
315
+						'input' => 'textarea',
316
+						'label' => '[TICKET_LINE_ITEM_LIST] <br>' . esc_html__(
317
+							'Ticket Line Item List with no Price Modifiers',
318
+							'event_espresso'
319
+						),
320
+						'type' => 'string',
321
+						'required' => false,
322
+						'validation' => true,
323
+						'format' => '%s',
324
+						'css_class' => 'large-text',
325
+						'rows' => '5',
326
+						'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
327
+					),
328
+					'ticket_line_item_pms' => array(
329
+						'input' => 'textarea',
330
+						'label' => '[TICKET_LINE_ITEM_LIST] <br>' . esc_html__(
331
+							'Ticket Line Item List with Price Modifiers',
332
+							'event_espresso'
333
+						),
334
+						'type' => 'string',
335
+						'required' => false,
336
+						'validation' => true,
337
+						'format' => '%s',
338
+						'css_class' => 'large-text',
339
+						'rows' => '5',
340
+						'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
341
+					),
342
+					'price_modifier_line_item_list' => array(
343
+						'input' => 'textarea',
344
+						'label' => '[PRICE_MODIFIER_LINE_ITEM_LIST]',
345
+						'type' => 'string',
346
+						'required' => false,
347
+						'validation' => true,
348
+						'format' => '%s',
349
+						'css_class' => 'large-text',
350
+						'rows' => '5',
351
+						'shortcodes_required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
352
+					),
353
+					'datetime_list' => array(
354
+						'input' => 'textarea',
355
+						'label' => '[DATETIME_LIST]',
356
+						'type' => 'string',
357
+						'required' => true,
358
+						'validation' => true,
359
+						'format' => '%s',
360
+						'css_class' => 'large-text',
361
+						'rows' => '5',
362
+						'shortcodes_required' => array('[DATETIME_LIST]'),
363
+					),
364
+					'attendee_list' => array(
365
+						'input' => 'textarea',
366
+						'label' => '[ATTENDEE_LIST]',
367
+						'type' => 'string',
368
+						'required' => true,
369
+						'validation' => true,
370
+						'format' => '%s',
371
+						'css_class' => 'large-text',
372
+						'rows' => '5',
373
+						'shortcodes_required' => array('[ATTENDEE_LIST]'),
374
+					),
375
+					'tax_line_item_list' => array(
376
+						'input' => 'textarea',
377
+						'label' => '[TAX_LINE_ITEM_LIST]',
378
+						'type' => 'string',
379
+						'required' => false,
380
+						'validation' => true,
381
+						'format' => '%s',
382
+						'css_class' => 'large-text',
383
+						'rows' => '5',
384
+						'shortcodes_required' => array('[TAX_LINE_ITEM_LIST]'),
385
+					),
386
+					'additional_line_item_list' => array(
387
+						'input' => 'textarea',
388
+						'label' => '[ADDITIONAL_LINE_ITEM_LIST]',
389
+						'type' => 'string',
390
+						'required' => false,
391
+						'validation' => true,
392
+						'format' => '%s',
393
+						'css_class' => 'large-text',
394
+						'rows' => '5',
395
+						'shortcodes_required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
396
+					),
397
+					'payment_list' => array(
398
+						'input' => 'textarea',
399
+						'label' => '[PAYMENT_LIST]',
400
+						'type' => 'string',
401
+						'required' => true,
402
+						'validation' => true,
403
+						'format' => '%s',
404
+						'css_class' => 'large-text',
405
+						'rows' => '5',
406
+						'shortcodes_required' => array('[PAYMENT_LIST_*]'),
407
+					),
408
+				),
409
+			),
410
+		);
411
+	}
412
+
413
+
414
+	/**
415
+	 * @see   definition of this method in parent
416
+	 * @since 4.5.0
417
+	 */
418
+	protected function _set_default_message_types()
419
+	{
420
+		$this->_default_message_types = array('receipt', 'invoice');
421
+	}
422
+
423
+
424
+	/**
425
+	 * @see   definition of this method in parent
426
+	 * @since 4.5.0
427
+	 */
428
+	protected function _set_valid_message_types()
429
+	{
430
+		$this->_valid_message_types = array('receipt', 'invoice');
431
+	}
432
+
433
+
434
+	/**
435
+	 * Displays the message in the browser.
436
+	 *
437
+	 * @since 4.5.0
438
+	 * @return string.
439
+	 */
440
+	protected function _send_message()
441
+	{
442
+		$this->_template_args = array(
443
+			'page_title' => $this->_subject,
444
+			'base_css' => $this->get_variation(
445
+				$this->_tmp_pack,
446
+				$this->_incoming_message_type->name,
447
+				true,
448
+				'base',
449
+				$this->_variation
450
+			),
451
+			'print_css' => $this->get_variation(
452
+				$this->_tmp_pack,
453
+				$this->_incoming_message_type->name,
454
+				true,
455
+				'print',
456
+				$this->_variation
457
+			),
458
+			'main_css' => $this->get_variation(
459
+				$this->_tmp_pack,
460
+				$this->_incoming_message_type->name,
461
+				true,
462
+				'main',
463
+				$this->_variation
464
+			),
465
+			'main_body' => wpautop(
466
+				apply_filters(
467
+					'FHEE__EE_Html_messenger___send_message__main_body',
468
+					$this->_content,
469
+					$this->_content,
470
+					$this->_incoming_message_type
471
+				)
472
+			)
473
+		);
474
+		$this->_deregister_wp_hooks();
475
+		add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
476
+
477
+		echo $this->_get_main_template();
478
+		exit();
479
+	}
480
+
481
+
482
+	/**
483
+	 * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't
484
+	 * interfere with our templates.  If users want to add any custom styles or scripts they must use the
485
+	 * AHEE__EE_Html_messenger__enqueue_scripts_styles hook.
486
+	 *
487
+	 * @since 4.5.0
488
+	 * @return void
489
+	 */
490
+	protected function _deregister_wp_hooks()
491
+	{
492
+		remove_all_actions('wp_head');
493
+		remove_all_actions('wp_footer');
494
+		remove_all_actions('wp_print_footer_scripts');
495
+		remove_all_actions('wp_enqueue_scripts');
496
+		global $wp_scripts, $wp_styles;
497
+		$wp_scripts = $wp_styles = array();
498
+		// just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
499
+		add_action('wp_footer', 'wp_print_footer_scripts');
500
+		add_action('wp_print_footer_scripts', '_wp_footer_scripts');
501
+		add_action('wp_head', 'wp_enqueue_scripts');
502
+	}
503
+
504
+
505
+	/**
506
+	 * Overwrite parent _get_main_template for display_html purposes.
507
+	 *
508
+	 * @since  4.5.0
509
+	 * @param bool $preview
510
+	 * @return string
511
+	 */
512
+	protected function _get_main_template($preview = false)
513
+	{
514
+		$wrapper_template = $this->_tmp_pack->get_wrapper($this->name, 'main');
515
+		// include message type as a template arg
516
+		$this->_template_args['message_type'] = $this->_incoming_message_type;
517
+		return EEH_Template::display_template($wrapper_template, $this->_template_args, true);
518
+	}
519
+
520
+
521
+	/**
522
+	 * @return string
523
+	 */
524
+	protected function _preview()
525
+	{
526
+		return $this->_send_message();
527
+	}
528
+
529
+
530
+	protected function _set_admin_settings_fields()
531
+	{
532
+	}
533
+
534
+
535
+	/**
536
+	 * add the "powered by EE" credit link to the HTML receipt and invoice
537
+	 *
538
+	 * @param string $content
539
+	 * @param string $content_again
540
+	 * @param \EE_message_type $incoming_message_type
541
+	 * @return string
542
+	 */
543
+	public function add_powered_by_credit_link_to_receipt_and_invoice(
544
+		$content,
545
+		$content_again,
546
+		EE_message_type $incoming_message_type
547
+	) {
548
+		if (
549
+			($incoming_message_type->name === 'invoice' || $incoming_message_type->name === 'receipt')
550
+			&& apply_filters('FHEE_EE_Html_messenger__add_powered_by_credit_link_to_receipt_and_invoice', true)
551
+		) {
552
+			$content .= \EEH_Template::powered_by_event_espresso(
553
+				'aln-cntr',
554
+				'',
555
+				array('utm_content' => 'messages_system')
556
+			)
557
+				. EEH_HTML::div(EEH_HTML::p('&nbsp;'));
558
+		}
559
+		return $content;
560
+	}
561 561
 }
Please login to merge, or discard this patch.
core/libraries/messages/defaults/EE_Messages_Template_Defaults.lib.php 1 patch
Indentation   +228 added lines, -228 removed lines patch added patch discarded remove patch
@@ -13,232 +13,232 @@
 block discarded – undo
13 13
  */
14 14
 class EE_Messages_Template_Defaults extends EE_Base
15 15
 {
16
-    /**
17
-     * Used for holding the EE_Message_Template GRP_ID field value.
18
-     * @var [type]
19
-     */
20
-    protected $_GRP_ID;
21
-
22
-    /**
23
-     * holds the messenger object
24
-     *
25
-     * @var EE_messenger
26
-     */
27
-    protected $_messenger;
28
-
29
-    /**
30
-     * holds the message type object
31
-     *
32
-     * @var EE_message_type
33
-     */
34
-    protected $_message_type;
35
-
36
-    /**
37
-     * holds the fields used (this is retrieved from the messenger)
38
-     *
39
-     * @var array
40
-     */
41
-    protected $_fields;
42
-
43
-    /**
44
-     * holds the assembled template (with defaults) for creation in the database
45
-     *
46
-     * @var array
47
-     */
48
-    protected $_templates;
49
-
50
-    /**
51
-     * holds the contexts used (this is retrieved from the message type)
52
-     *
53
-     * @var array
54
-     */
55
-    protected $_contexts;
56
-
57
-
58
-    /**
59
-     *  @var EEM_Message_Template_Group
60
-     */
61
-    protected $_message_template_group_model;
62
-
63
-
64
-    /**
65
-     * @var EEM_Message_Template
66
-     */
67
-    protected $_message_template_model;
68
-
69
-
70
-    /**
71
-     * EE_Messages_Template_Defaults constructor.
72
-     *
73
-     * @param EE_messenger               $messenger
74
-     * @param EE_message_type            $message_type
75
-     * @param int                        $GRP_ID                      Optional.  If included then we're just regenerating
76
-     *                                                                the template fields for the given group not the
77
-     *                                                                message template group itself
78
-     * @param EEM_Message_Template_Group $message_template_group_model
79
-     * @param EEM_Message_Template       $message_template_model
80
-     * @throws EE_Error
81
-     */
82
-    public function __construct(
83
-        EE_messenger $messenger,
84
-        EE_message_type $message_type,
85
-        $GRP_ID,
86
-        EEM_Message_Template_Group $message_template_group_model,
87
-        EEM_Message_Template $message_template_model
88
-    ) {
89
-        $this->_messenger = $messenger;
90
-        $this->_message_type = $message_type;
91
-        $this->_GRP_ID = $GRP_ID;
92
-        // set the model object
93
-        $this->_message_template_group_model = $message_template_group_model;
94
-        $this->_message_template_model = $message_template_model;
95
-        $this->_fields = $this->_messenger->get_template_fields();
96
-        $this->_contexts = $this->_message_type->get_contexts();
97
-    }
98
-
99
-
100
-    /**
101
-     * Setup the _template_data property.
102
-     * This method sets the _templates property array before templates are created.
103
-     *
104
-     * @param string $template_pack This corresponds to a template pack class reference which will contain information
105
-     *                              about where to obtain the templates.
106
-     *
107
-     */
108
-    private function _set_templates($template_pack)
109
-    {
110
-
111
-        // get the corresponding template pack object (if present.  If not then we just load the default and add a
112
-        // notice).  The class name should be something like 'EE_Messages_Template_Pack_Default' where "default' would be
113
-        // the incoming template pack reference.
114
-        $class_name = 'EE_Messages_Template_Pack_' . str_replace(' ', '_', ucwords(str_replace('_', ' ', $template_pack)));
115
-
116
-        if (! class_exists($class_name)) {
117
-            EE_Error::add_error(
118
-                sprintf(
119
-                    esc_html__(
120
-                        'The template pack represented by a class corresponding to "%1$s" does not exist. Likely the autoloader for this class has the wrong path or the incoming reference is misspelled. The default template pack has been used to generate the templates instead.',
121
-                        'event_espresso'
122
-                    ),
123
-                    $class_name
124
-                ),
125
-                __FILE__,
126
-                __FUNCTION__,
127
-                __LINE__
128
-            );
129
-            $class_name = 'EE_Messages_Template_Pack_Default';
130
-        }
131
-        /** @type EE_Messages_Template_Pack $template_pack */
132
-        $template_pack = new $class_name();
133
-
134
-        // get all the templates from the template pack.
135
-        $this->_templates = $template_pack->get_templates($this->_messenger, $this->_message_type);
136
-    }
137
-
138
-
139
-    /**
140
-     * Return the contexts for the message type as cached on this instance.
141
-     * @return array
142
-     */
143
-    public function get_contexts()
144
-    {
145
-        return $this->_contexts;
146
-    }
147
-
148
-
149
-
150
-
151
-
152
-    /**
153
-     * public facing create new templates method
154
-     *
155
-     * @return mixed (array|bool)            success array or false.
156
-     */
157
-    public function create_new_templates()
158
-    {
159
-        $template_pack = 'default';
160
-        // if we have the GRP_ID then let's use that to see if there is a set template pack and use that for the new templates.
161
-        if (! empty($this->_GRP_ID)) {
162
-            $message_template_group = $this->_message_template_group_model->get_one_by_ID($this->_GRP_ID);
163
-            $template_pack = $message_template_group instanceof EE_Message_Template_Group
164
-                ? $message_template_group->get_template_pack_name()
165
-                : 'default';
166
-            // we also need to reset the template variation to default
167
-            $message_template_group->set_template_pack_variation('default');
168
-        }
169
-        return $this->_create_new_templates($template_pack);
170
-    }
171
-
172
-
173
-
174
-
175
-
176
-    /**
177
-     *  Handles creating new default templates.
178
-     *
179
-     * @param string $template_pack This corresponds to a template pack class reference
180
-     *                              which will contain information about where to obtain the templates.
181
-     * @return mixed (array|bool)   success array or false.
182
-     */
183
-    protected function _create_new_templates($template_pack)
184
-    {
185
-
186
-        $this->_set_templates($template_pack);
187
-
188
-        // necessary properties are set, let's save the default templates
189
-        if (empty($this->_GRP_ID)) {
190
-            $main_template_data = array(
191
-                'MTP_messenger'    => $this->_messenger->name,
192
-                'MTP_message_type' => $this->_message_type->name,
193
-                'MTP_is_override'  => 0,
194
-                'MTP_deleted'      => 0,
195
-                'MTP_is_global'    => 1,
196
-                'MTP_user_id'      => EEH_Activation::get_default_creator_id(),
197
-                'MTP_is_active'    => 1,
198
-            );
199
-            // let's insert the above and get our GRP_ID, then reset the template data array to just include the GRP_ID
200
-            $grp_id = $this->_message_template_group_model->insert($main_template_data);
201
-            if (empty($grp_id)) {
202
-                return $grp_id;
203
-            }
204
-            $this->_GRP_ID = $grp_id;
205
-        }
206
-
207
-        $template_data = array( 'GRP_ID' => $this->_GRP_ID );
208
-
209
-        foreach ($this->_contexts as $context => $details) {
210
-            foreach ($this->_fields as $field => $field_type) {
211
-                if ($field != 'extra') {
212
-                    $template_data['MTP_context'] = $context;
213
-                    $template_data['MTP_template_field'] = $field;
214
-                    $template_data['MTP_content'] = $this->_templates[ $context ][ $field ];
215
-
216
-                    $MTP = $this->_message_template_model->insert($template_data);
217
-                    if (! $MTP) {
218
-                        EE_Error::add_error(
219
-                            sprintf(
220
-                                esc_html__(
221
-                                    'There was an error in saving new template data for %1$s messenger, %2$s message type, %3$s context and %4$s template field.',
222
-                                    'event_espresso'
223
-                                ),
224
-                                $this->_messenger->name,
225
-                                $this->_message_type->name,
226
-                                $context,
227
-                                $field
228
-                            ),
229
-                            __FILE__,
230
-                            __FUNCTION__,
231
-                            __LINE__
232
-                        );
233
-                        return false;
234
-                    }
235
-                }
236
-            }
237
-        }
238
-
239
-        return array(
240
-            'GRP_ID'      => $this->_GRP_ID,
241
-            'MTP_context' => key($this->_contexts)
242
-        );
243
-    }
16
+	/**
17
+	 * Used for holding the EE_Message_Template GRP_ID field value.
18
+	 * @var [type]
19
+	 */
20
+	protected $_GRP_ID;
21
+
22
+	/**
23
+	 * holds the messenger object
24
+	 *
25
+	 * @var EE_messenger
26
+	 */
27
+	protected $_messenger;
28
+
29
+	/**
30
+	 * holds the message type object
31
+	 *
32
+	 * @var EE_message_type
33
+	 */
34
+	protected $_message_type;
35
+
36
+	/**
37
+	 * holds the fields used (this is retrieved from the messenger)
38
+	 *
39
+	 * @var array
40
+	 */
41
+	protected $_fields;
42
+
43
+	/**
44
+	 * holds the assembled template (with defaults) for creation in the database
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $_templates;
49
+
50
+	/**
51
+	 * holds the contexts used (this is retrieved from the message type)
52
+	 *
53
+	 * @var array
54
+	 */
55
+	protected $_contexts;
56
+
57
+
58
+	/**
59
+	 *  @var EEM_Message_Template_Group
60
+	 */
61
+	protected $_message_template_group_model;
62
+
63
+
64
+	/**
65
+	 * @var EEM_Message_Template
66
+	 */
67
+	protected $_message_template_model;
68
+
69
+
70
+	/**
71
+	 * EE_Messages_Template_Defaults constructor.
72
+	 *
73
+	 * @param EE_messenger               $messenger
74
+	 * @param EE_message_type            $message_type
75
+	 * @param int                        $GRP_ID                      Optional.  If included then we're just regenerating
76
+	 *                                                                the template fields for the given group not the
77
+	 *                                                                message template group itself
78
+	 * @param EEM_Message_Template_Group $message_template_group_model
79
+	 * @param EEM_Message_Template       $message_template_model
80
+	 * @throws EE_Error
81
+	 */
82
+	public function __construct(
83
+		EE_messenger $messenger,
84
+		EE_message_type $message_type,
85
+		$GRP_ID,
86
+		EEM_Message_Template_Group $message_template_group_model,
87
+		EEM_Message_Template $message_template_model
88
+	) {
89
+		$this->_messenger = $messenger;
90
+		$this->_message_type = $message_type;
91
+		$this->_GRP_ID = $GRP_ID;
92
+		// set the model object
93
+		$this->_message_template_group_model = $message_template_group_model;
94
+		$this->_message_template_model = $message_template_model;
95
+		$this->_fields = $this->_messenger->get_template_fields();
96
+		$this->_contexts = $this->_message_type->get_contexts();
97
+	}
98
+
99
+
100
+	/**
101
+	 * Setup the _template_data property.
102
+	 * This method sets the _templates property array before templates are created.
103
+	 *
104
+	 * @param string $template_pack This corresponds to a template pack class reference which will contain information
105
+	 *                              about where to obtain the templates.
106
+	 *
107
+	 */
108
+	private function _set_templates($template_pack)
109
+	{
110
+
111
+		// get the corresponding template pack object (if present.  If not then we just load the default and add a
112
+		// notice).  The class name should be something like 'EE_Messages_Template_Pack_Default' where "default' would be
113
+		// the incoming template pack reference.
114
+		$class_name = 'EE_Messages_Template_Pack_' . str_replace(' ', '_', ucwords(str_replace('_', ' ', $template_pack)));
115
+
116
+		if (! class_exists($class_name)) {
117
+			EE_Error::add_error(
118
+				sprintf(
119
+					esc_html__(
120
+						'The template pack represented by a class corresponding to "%1$s" does not exist. Likely the autoloader for this class has the wrong path or the incoming reference is misspelled. The default template pack has been used to generate the templates instead.',
121
+						'event_espresso'
122
+					),
123
+					$class_name
124
+				),
125
+				__FILE__,
126
+				__FUNCTION__,
127
+				__LINE__
128
+			);
129
+			$class_name = 'EE_Messages_Template_Pack_Default';
130
+		}
131
+		/** @type EE_Messages_Template_Pack $template_pack */
132
+		$template_pack = new $class_name();
133
+
134
+		// get all the templates from the template pack.
135
+		$this->_templates = $template_pack->get_templates($this->_messenger, $this->_message_type);
136
+	}
137
+
138
+
139
+	/**
140
+	 * Return the contexts for the message type as cached on this instance.
141
+	 * @return array
142
+	 */
143
+	public function get_contexts()
144
+	{
145
+		return $this->_contexts;
146
+	}
147
+
148
+
149
+
150
+
151
+
152
+	/**
153
+	 * public facing create new templates method
154
+	 *
155
+	 * @return mixed (array|bool)            success array or false.
156
+	 */
157
+	public function create_new_templates()
158
+	{
159
+		$template_pack = 'default';
160
+		// if we have the GRP_ID then let's use that to see if there is a set template pack and use that for the new templates.
161
+		if (! empty($this->_GRP_ID)) {
162
+			$message_template_group = $this->_message_template_group_model->get_one_by_ID($this->_GRP_ID);
163
+			$template_pack = $message_template_group instanceof EE_Message_Template_Group
164
+				? $message_template_group->get_template_pack_name()
165
+				: 'default';
166
+			// we also need to reset the template variation to default
167
+			$message_template_group->set_template_pack_variation('default');
168
+		}
169
+		return $this->_create_new_templates($template_pack);
170
+	}
171
+
172
+
173
+
174
+
175
+
176
+	/**
177
+	 *  Handles creating new default templates.
178
+	 *
179
+	 * @param string $template_pack This corresponds to a template pack class reference
180
+	 *                              which will contain information about where to obtain the templates.
181
+	 * @return mixed (array|bool)   success array or false.
182
+	 */
183
+	protected function _create_new_templates($template_pack)
184
+	{
185
+
186
+		$this->_set_templates($template_pack);
187
+
188
+		// necessary properties are set, let's save the default templates
189
+		if (empty($this->_GRP_ID)) {
190
+			$main_template_data = array(
191
+				'MTP_messenger'    => $this->_messenger->name,
192
+				'MTP_message_type' => $this->_message_type->name,
193
+				'MTP_is_override'  => 0,
194
+				'MTP_deleted'      => 0,
195
+				'MTP_is_global'    => 1,
196
+				'MTP_user_id'      => EEH_Activation::get_default_creator_id(),
197
+				'MTP_is_active'    => 1,
198
+			);
199
+			// let's insert the above and get our GRP_ID, then reset the template data array to just include the GRP_ID
200
+			$grp_id = $this->_message_template_group_model->insert($main_template_data);
201
+			if (empty($grp_id)) {
202
+				return $grp_id;
203
+			}
204
+			$this->_GRP_ID = $grp_id;
205
+		}
206
+
207
+		$template_data = array( 'GRP_ID' => $this->_GRP_ID );
208
+
209
+		foreach ($this->_contexts as $context => $details) {
210
+			foreach ($this->_fields as $field => $field_type) {
211
+				if ($field != 'extra') {
212
+					$template_data['MTP_context'] = $context;
213
+					$template_data['MTP_template_field'] = $field;
214
+					$template_data['MTP_content'] = $this->_templates[ $context ][ $field ];
215
+
216
+					$MTP = $this->_message_template_model->insert($template_data);
217
+					if (! $MTP) {
218
+						EE_Error::add_error(
219
+							sprintf(
220
+								esc_html__(
221
+									'There was an error in saving new template data for %1$s messenger, %2$s message type, %3$s context and %4$s template field.',
222
+									'event_espresso'
223
+								),
224
+								$this->_messenger->name,
225
+								$this->_message_type->name,
226
+								$context,
227
+								$field
228
+							),
229
+							__FILE__,
230
+							__FUNCTION__,
231
+							__LINE__
232
+						);
233
+						return false;
234
+					}
235
+				}
236
+			}
237
+		}
238
+
239
+		return array(
240
+			'GRP_ID'      => $this->_GRP_ID,
241
+			'MTP_context' => key($this->_contexts)
242
+		);
243
+	}
244 244
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Activation.helper.php 1 patch
Indentation   +1590 added lines, -1590 removed lines patch added patch discarded remove patch
@@ -16,239 +16,239 @@  discard block
 block discarded – undo
16 16
  */
17 17
 class EEH_Activation implements ResettableInterface
18 18
 {
19
-    /**
20
-     * constant used to indicate a cron task is no longer in use
21
-     */
22
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
23
-
24
-    /**
25
-     * WP_User->ID
26
-     *
27
-     * @var int
28
-     */
29
-    private static $_default_creator_id;
30
-
31
-    /**
32
-     * indicates whether or not we've already verified core's default data during this request,
33
-     * because after migrations are done, any addons activated while in maintenance mode
34
-     * will want to setup their own default data, and they might hook into core's default data
35
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
36
-     * This prevents doing that for EVERY single addon.
37
-     *
38
-     * @var boolean
39
-     */
40
-    protected static $_initialized_db_content_already_in_this_request = false;
41
-
42
-    /**
43
-     * @var TableAnalysis $table_analysis
44
-     */
45
-    private static $table_analysis;
46
-
47
-    /**
48
-     * @var TableManager $table_manager
49
-     */
50
-    private static $table_manager;
51
-
52
-
53
-    /**
54
-     * @return TableAnalysis
55
-     * @throws EE_Error
56
-     * @throws ReflectionException
57
-     */
58
-    public static function getTableAnalysis()
59
-    {
60
-        if (! self::$table_analysis instanceof TableAnalysis) {
61
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', [], true);
62
-        }
63
-        return self::$table_analysis;
64
-    }
65
-
66
-
67
-    /**
68
-     * @return TableManager
69
-     * @throws EE_Error
70
-     * @throws ReflectionException
71
-     */
72
-    public static function getTableManager()
73
-    {
74
-        if (! self::$table_manager instanceof TableManager) {
75
-            self::$table_manager = EE_Registry::instance()->create('TableManager', [], true);
76
-        }
77
-        return self::$table_manager;
78
-    }
79
-
80
-
81
-    /**
82
-     * @param $table_name
83
-     * @return string
84
-     * @throws EE_Error
85
-     * @throws ReflectionException
86
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
-     */
88
-    public static function ensure_table_name_has_prefix($table_name)
89
-    {
90
-        return EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
91
-    }
92
-
93
-
94
-    /**
95
-     * ensures the EE configuration settings are loaded with at least default options set
96
-     * and that all critical EE pages have been generated with the appropriate shortcodes in place
97
-     *
98
-     * @return void
99
-     */
100
-    public static function system_initialization()
101
-    {
102
-        EEH_Activation::reset_and_update_config();
103
-        // which is fired BEFORE activation of plugin anyways
104
-        EEH_Activation::verify_default_pages_exist();
105
-    }
106
-
107
-
108
-    /**
109
-     * Sets the database schema and creates folders. This should
110
-     * be called on plugin activation and reactivation
111
-     *
112
-     * @return boolean success, whether the database and folders are setup properly
113
-     * @throws EE_Error
114
-     * @throws ReflectionException
115
-     */
116
-    public static function initialize_db_and_folders()
117
-    {
118
-        EEH_File::ensure_folder_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR);
119
-        EEH_File::ensure_folder_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs');
120
-        return EEH_Activation::create_database_tables();
121
-    }
122
-
123
-
124
-    /**
125
-     * assuming we have an up-to-date database schema, this will populate it
126
-     * with default and initial data. This should be called
127
-     * upon activation of a new plugin, reactivation, and at the end
128
-     * of running migration scripts
129
-     *
130
-     * @throws EE_Error
131
-     * @throws ReflectionException
132
-     */
133
-    public static function initialize_db_content()
134
-    {
135
-        // let's avoid doing all this logic repeatedly, especially when addons are requesting it
136
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
137
-            return;
138
-        }
139
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
140
-
141
-        EEH_Activation::initialize_system_questions();
142
-        EEH_Activation::insert_default_status_codes();
143
-        EEH_Activation::generate_default_message_templates();
144
-        EEH_Activation::create_no_ticket_prices_array();
145
-        EEH_Activation::removeEmailConfirmFromAddressGroup();
146
-
147
-        EEH_Activation::validate_messages_system();
148
-        EEH_Activation::insert_default_payment_methods();
149
-        // in case we've
150
-        EEH_Activation::remove_cron_tasks();
151
-        EEH_Activation::create_cron_tasks();
152
-        // remove all TXN locks since that is being done via extra meta now
153
-        delete_option('ee_locked_transactions');
154
-        // also, check for CAF default db content
155
-        do_action('AHEE__EEH_Activation__initialize_db_content');
156
-        // also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
157
-        // which users really won't care about on initial activation
158
-        EE_Error::overwrite_success();
159
-    }
160
-
161
-
162
-    /**
163
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
164
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
165
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
166
-     * (null)
167
-     *
168
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
169
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
170
-     * @return array
171
-     * @throws EE_Error
172
-     */
173
-    public static function get_cron_tasks($which_to_include)
174
-    {
175
-        $cron_tasks = apply_filters(
176
-            'FHEE__EEH_Activation__get_cron_tasks',
177
-            [
178
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
179
-                // 'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' =>
180
-                // EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
181
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
182
-                // there may have been a bug which prevented from these cron tasks from getting unscheduled,
183
-                // so we might want to remove these for a few updates
184
-                'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
185
-            ]
186
-        );
187
-        if ($which_to_include === 'old') {
188
-            $cron_tasks = array_filter(
189
-                $cron_tasks,
190
-                function ($value) {
191
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
192
-                }
193
-            );
194
-        } elseif ($which_to_include === 'current') {
195
-            $cron_tasks = array_filter($cron_tasks);
196
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
197
-            throw new EE_Error(
198
-                sprintf(
199
-                    esc_html__(
200
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
201
-                        'event_espresso'
202
-                    ),
203
-                    $which_to_include
204
-                )
205
-            );
206
-        }
207
-        return $cron_tasks;
208
-    }
209
-
210
-
211
-    /**
212
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
213
-     *
214
-     * @throws EE_Error
215
-     */
216
-    public static function create_cron_tasks()
217
-    {
218
-
219
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
220
-            if (! wp_next_scheduled($hook_name)) {
221
-                /**
222
-                 * This allows client code to define the initial start timestamp for this schedule.
223
-                 */
224
-                if (
225
-                    is_array($frequency)
226
-                    && count($frequency) === 2
227
-                    && isset($frequency[0], $frequency[1])
228
-                ) {
229
-                    $start_timestamp = $frequency[0];
230
-                    $frequency       = $frequency[1];
231
-                } else {
232
-                    $start_timestamp = time();
233
-                }
234
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
235
-            }
236
-        }
237
-    }
238
-
239
-
240
-    /**
241
-     * Remove the currently-existing and now-removed cron tasks.
242
-     *
243
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
244
-     * @throws EE_Error
245
-     */
246
-    public static function remove_cron_tasks($remove_all = true)
247
-    {
248
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
249
-        $crons                = _get_cron_array();
250
-        $crons                = is_array($crons) ? $crons : [];
251
-        /* reminder of what $crons look like:
19
+	/**
20
+	 * constant used to indicate a cron task is no longer in use
21
+	 */
22
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
23
+
24
+	/**
25
+	 * WP_User->ID
26
+	 *
27
+	 * @var int
28
+	 */
29
+	private static $_default_creator_id;
30
+
31
+	/**
32
+	 * indicates whether or not we've already verified core's default data during this request,
33
+	 * because after migrations are done, any addons activated while in maintenance mode
34
+	 * will want to setup their own default data, and they might hook into core's default data
35
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
36
+	 * This prevents doing that for EVERY single addon.
37
+	 *
38
+	 * @var boolean
39
+	 */
40
+	protected static $_initialized_db_content_already_in_this_request = false;
41
+
42
+	/**
43
+	 * @var TableAnalysis $table_analysis
44
+	 */
45
+	private static $table_analysis;
46
+
47
+	/**
48
+	 * @var TableManager $table_manager
49
+	 */
50
+	private static $table_manager;
51
+
52
+
53
+	/**
54
+	 * @return TableAnalysis
55
+	 * @throws EE_Error
56
+	 * @throws ReflectionException
57
+	 */
58
+	public static function getTableAnalysis()
59
+	{
60
+		if (! self::$table_analysis instanceof TableAnalysis) {
61
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', [], true);
62
+		}
63
+		return self::$table_analysis;
64
+	}
65
+
66
+
67
+	/**
68
+	 * @return TableManager
69
+	 * @throws EE_Error
70
+	 * @throws ReflectionException
71
+	 */
72
+	public static function getTableManager()
73
+	{
74
+		if (! self::$table_manager instanceof TableManager) {
75
+			self::$table_manager = EE_Registry::instance()->create('TableManager', [], true);
76
+		}
77
+		return self::$table_manager;
78
+	}
79
+
80
+
81
+	/**
82
+	 * @param $table_name
83
+	 * @return string
84
+	 * @throws EE_Error
85
+	 * @throws ReflectionException
86
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
+	 */
88
+	public static function ensure_table_name_has_prefix($table_name)
89
+	{
90
+		return EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
91
+	}
92
+
93
+
94
+	/**
95
+	 * ensures the EE configuration settings are loaded with at least default options set
96
+	 * and that all critical EE pages have been generated with the appropriate shortcodes in place
97
+	 *
98
+	 * @return void
99
+	 */
100
+	public static function system_initialization()
101
+	{
102
+		EEH_Activation::reset_and_update_config();
103
+		// which is fired BEFORE activation of plugin anyways
104
+		EEH_Activation::verify_default_pages_exist();
105
+	}
106
+
107
+
108
+	/**
109
+	 * Sets the database schema and creates folders. This should
110
+	 * be called on plugin activation and reactivation
111
+	 *
112
+	 * @return boolean success, whether the database and folders are setup properly
113
+	 * @throws EE_Error
114
+	 * @throws ReflectionException
115
+	 */
116
+	public static function initialize_db_and_folders()
117
+	{
118
+		EEH_File::ensure_folder_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR);
119
+		EEH_File::ensure_folder_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs');
120
+		return EEH_Activation::create_database_tables();
121
+	}
122
+
123
+
124
+	/**
125
+	 * assuming we have an up-to-date database schema, this will populate it
126
+	 * with default and initial data. This should be called
127
+	 * upon activation of a new plugin, reactivation, and at the end
128
+	 * of running migration scripts
129
+	 *
130
+	 * @throws EE_Error
131
+	 * @throws ReflectionException
132
+	 */
133
+	public static function initialize_db_content()
134
+	{
135
+		// let's avoid doing all this logic repeatedly, especially when addons are requesting it
136
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
137
+			return;
138
+		}
139
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
140
+
141
+		EEH_Activation::initialize_system_questions();
142
+		EEH_Activation::insert_default_status_codes();
143
+		EEH_Activation::generate_default_message_templates();
144
+		EEH_Activation::create_no_ticket_prices_array();
145
+		EEH_Activation::removeEmailConfirmFromAddressGroup();
146
+
147
+		EEH_Activation::validate_messages_system();
148
+		EEH_Activation::insert_default_payment_methods();
149
+		// in case we've
150
+		EEH_Activation::remove_cron_tasks();
151
+		EEH_Activation::create_cron_tasks();
152
+		// remove all TXN locks since that is being done via extra meta now
153
+		delete_option('ee_locked_transactions');
154
+		// also, check for CAF default db content
155
+		do_action('AHEE__EEH_Activation__initialize_db_content');
156
+		// also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
157
+		// which users really won't care about on initial activation
158
+		EE_Error::overwrite_success();
159
+	}
160
+
161
+
162
+	/**
163
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
164
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
165
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
166
+	 * (null)
167
+	 *
168
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
169
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
170
+	 * @return array
171
+	 * @throws EE_Error
172
+	 */
173
+	public static function get_cron_tasks($which_to_include)
174
+	{
175
+		$cron_tasks = apply_filters(
176
+			'FHEE__EEH_Activation__get_cron_tasks',
177
+			[
178
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
179
+				// 'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' =>
180
+				// EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
181
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
182
+				// there may have been a bug which prevented from these cron tasks from getting unscheduled,
183
+				// so we might want to remove these for a few updates
184
+				'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
185
+			]
186
+		);
187
+		if ($which_to_include === 'old') {
188
+			$cron_tasks = array_filter(
189
+				$cron_tasks,
190
+				function ($value) {
191
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
192
+				}
193
+			);
194
+		} elseif ($which_to_include === 'current') {
195
+			$cron_tasks = array_filter($cron_tasks);
196
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
197
+			throw new EE_Error(
198
+				sprintf(
199
+					esc_html__(
200
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
201
+						'event_espresso'
202
+					),
203
+					$which_to_include
204
+				)
205
+			);
206
+		}
207
+		return $cron_tasks;
208
+	}
209
+
210
+
211
+	/**
212
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
213
+	 *
214
+	 * @throws EE_Error
215
+	 */
216
+	public static function create_cron_tasks()
217
+	{
218
+
219
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
220
+			if (! wp_next_scheduled($hook_name)) {
221
+				/**
222
+				 * This allows client code to define the initial start timestamp for this schedule.
223
+				 */
224
+				if (
225
+					is_array($frequency)
226
+					&& count($frequency) === 2
227
+					&& isset($frequency[0], $frequency[1])
228
+				) {
229
+					$start_timestamp = $frequency[0];
230
+					$frequency       = $frequency[1];
231
+				} else {
232
+					$start_timestamp = time();
233
+				}
234
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
235
+			}
236
+		}
237
+	}
238
+
239
+
240
+	/**
241
+	 * Remove the currently-existing and now-removed cron tasks.
242
+	 *
243
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
244
+	 * @throws EE_Error
245
+	 */
246
+	public static function remove_cron_tasks($remove_all = true)
247
+	{
248
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
249
+		$crons                = _get_cron_array();
250
+		$crons                = is_array($crons) ? $crons : [];
251
+		/* reminder of what $crons look like:
252 252
          * Top-level keys are timestamps, and their values are arrays.
253 253
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
254 254
          * and their values are arrays.
@@ -265,893 +265,893 @@  discard block
 block discarded – undo
265 265
          *                  ...
266 266
          *      ...
267 267
          */
268
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
269
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
270
-            if (is_array($hooks_to_fire_at_time)) {
271
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
272
-                    if (
273
-                        isset($ee_cron_tasks_to_remove[ $hook_name ])
274
-                        && is_array($ee_cron_tasks_to_remove[ $hook_name ])
275
-                    ) {
276
-                        unset($crons[ $timestamp ][ $hook_name ]);
277
-                    }
278
-                }
279
-                // also take care of any empty cron timestamps.
280
-                if (empty($hooks_to_fire_at_time)) {
281
-                    unset($crons[ $timestamp ]);
282
-                }
283
-            }
284
-        }
285
-        _set_cron_array($crons);
286
-    }
287
-
288
-
289
-    /**
290
-     * registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
291
-     *
292
-     * @return void
293
-     * @throws EE_Error
294
-     * @throws ReflectionException
295
-     */
296
-    public static function CPT_initialization()
297
-    {
298
-        // register Custom Post Types
299
-        EE_Registry::instance()->load_core('Register_CPTs');
300
-        flush_rewrite_rules();
301
-    }
302
-
303
-
304
-    /**
305
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
306
-     * If there is old calendar config data saved, then it will get converted on activation.
307
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
308
-     *
309
-     * @return void
310
-     */
311
-    public static function reset_and_update_config()
312
-    {
313
-        do_action('AHEE__EE_Config___load_core_config__start', ['EEH_Activation', 'load_calendar_config']);
314
-        add_filter(
315
-            'FHEE__EE_Config___load_core_config__config_settings',
316
-            ['EEH_Activation', 'migrate_old_config_data'],
317
-            10,
318
-            3
319
-        );
320
-        if (! EE_Config::logging_enabled()) {
321
-            delete_option(EE_Config::LOG_NAME);
322
-        }
323
-    }
324
-
325
-
326
-    /**
327
-     * @return    void
328
-     */
329
-    public static function load_calendar_config()
330
-    {
331
-        // grab array of all plugin folders and loop thru it
332
-        $plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
333
-        if (empty($plugins)) {
334
-            return;
335
-        }
336
-        foreach ($plugins as $plugin_path) {
337
-            // grab plugin folder name from path
338
-            $plugin = basename($plugin_path);
339
-            // drill down to Espresso plugins
340
-            // then to calendar related plugins
341
-            if (
342
-                strpos($plugin, 'espresso') !== false
343
-                || strpos($plugin, 'Espresso') !== false
344
-                || strpos($plugin, 'ee4') !== false
345
-                || strpos($plugin, 'EE4') !== false
346
-                || strpos($plugin, 'calendar') !== false
347
-            ) {
348
-                // this is what we are looking for
349
-                $calendar_config = $plugin_path . '/EE_Calendar_Config.php';
350
-                // does it exist in this folder ?
351
-                if (is_readable($calendar_config)) {
352
-                    // YEAH! let's load it
353
-                    require_once($calendar_config);
354
-                }
355
-            }
356
-        }
357
-    }
358
-
359
-
360
-    /**
361
-     * @param array|stdClass $settings
362
-     * @param int|string         $config
363
-     * @param EE_Config      $EE_Config
364
-     * @return stdClass
365
-     */
366
-    public static function migrate_old_config_data($settings, $config, EE_Config $EE_Config)
367
-    {
368
-        $convert_from_array = ['addons'];
369
-        // in case old settings were saved as an array
370
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
371
-            // convert existing settings to an object
372
-            $config_array = $settings;
373
-            $settings     = new stdClass();
374
-            foreach ($config_array as $key => $value) {
375
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
376
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
377
-                } else {
378
-                    $settings->{$key} = $value;
379
-                }
380
-            }
381
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
382
-        }
383
-        return $settings;
384
-    }
385
-
386
-
387
-    /**
388
-     * @return void
389
-     */
390
-    public static function deactivate_event_espresso()
391
-    {
392
-        // check permissions
393
-        if (current_user_can('activate_plugins')) {
394
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
395
-        }
396
-    }
397
-
398
-
399
-    /**
400
-     * @return void
401
-     * @throws InvalidDataTypeException
402
-     */
403
-    public static function verify_default_pages_exist()
404
-    {
405
-        $critical_page_problem = false;
406
-        $critical_pages        = [
407
-            [
408
-                'id'   => 'reg_page_id',
409
-                'name' => esc_html__('Registration Checkout', 'event_espresso'),
410
-                'post' => null,
411
-                'code' => 'ESPRESSO_CHECKOUT',
412
-            ],
413
-            [
414
-                'id'   => 'txn_page_id',
415
-                'name' => esc_html__('Transactions', 'event_espresso'),
416
-                'post' => null,
417
-                'code' => 'ESPRESSO_TXN_PAGE',
418
-            ],
419
-            [
420
-                'id'   => 'thank_you_page_id',
421
-                'name' => esc_html__('Thank You', 'event_espresso'),
422
-                'post' => null,
423
-                'code' => 'ESPRESSO_THANK_YOU',
424
-            ],
425
-            [
426
-                'id'   => 'cancel_page_id',
427
-                'name' => esc_html__('Registration Cancelled', 'event_espresso'),
428
-                'post' => null,
429
-                'code' => 'ESPRESSO_CANCELLED',
430
-            ],
431
-        ];
432
-        $EE_Core_Config        = EE_Registry::instance()->CFG->core;
433
-        foreach ($critical_pages as $critical_page) {
434
-            // is critical page ID set in config ?
435
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
436
-                // attempt to find post by ID
437
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
438
-            }
439
-            // no dice?
440
-            if ($critical_page['post'] === null) {
441
-                // attempt to find post by title
442
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
443
-                // still nothing?
444
-                if ($critical_page['post'] === null) {
445
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
446
-                    // REALLY? Still nothing ??!?!?
447
-                    if ($critical_page['post'] === null) {
448
-                        $msg = esc_html__(
449
-                            'The Event Espresso critical page configuration settings could not be updated.',
450
-                            'event_espresso'
451
-                        );
452
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
453
-                        break;
454
-                    }
455
-                }
456
-            }
457
-            // check that Post ID matches critical page ID in config
458
-            if (
459
-                isset($critical_page['post']->ID)
460
-                && $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
461
-            ) {
462
-                // update Config with post ID
463
-                $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
464
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
465
-                    $msg = esc_html__(
466
-                        'The Event Espresso critical page configuration settings could not be updated.',
467
-                        'event_espresso'
468
-                    );
469
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
470
-                }
471
-            }
472
-            $critical_page_problem =
473
-                ! isset($critical_page['post']->post_status)
474
-                || $critical_page['post']->post_status !== 'publish'
475
-                || strpos($critical_page['post']->post_content, $critical_page['code']) === false
476
-                    ? true
477
-                    : $critical_page_problem;
478
-        }
479
-        if ($critical_page_problem) {
480
-            new PersistentAdminNotice(
481
-                'critical_page_problem',
482
-                sprintf(
483
-                    esc_html__(
484
-                        'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
485
-                        'event_espresso'
486
-                    ),
487
-                    '<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
488
-                    . esc_html__('Event Espresso Critical Pages Settings', 'event_espresso')
489
-                    . '</a>'
490
-                )
491
-            );
492
-        }
493
-        if (EE_Error::has_notices()) {
494
-            EE_Error::get_notices(false, true);
495
-        }
496
-    }
497
-
498
-
499
-    /**
500
-     * Returns the first post which uses the specified shortcode
501
-     *
502
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
503
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
504
-     *                             "[ESPRESSO_THANK_YOU"
505
-     *                             (we don't search for the closing shortcode bracket because they might have added
506
-     *                             parameter to the shortcode
507
-     * @return WP_Post or NULl
508
-     */
509
-    public static function get_page_by_ee_shortcode($ee_shortcode)
510
-    {
511
-        global $wpdb;
512
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
513
-        $post_id                       =
514
-            $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
515
-        if ($post_id) {
516
-            return get_post($post_id);
517
-        } else {
518
-            return null;
519
-        }
520
-    }
521
-
522
-
523
-    /**
524
-     * This function generates a post for critical espresso pages
525
-     *
526
-     * @param array $critical_page
527
-     * @return array
528
-     */
529
-    public static function create_critical_page($critical_page)
530
-    {
531
-
532
-        $post_args = [
533
-            'post_title'     => $critical_page['name'],
534
-            'post_status'    => 'publish',
535
-            'post_type'      => 'page',
536
-            'comment_status' => 'closed',
537
-            'post_content'   => '[' . $critical_page['code'] . ']',
538
-        ];
539
-
540
-        $post_id = wp_insert_post($post_args);
541
-        if (! $post_id) {
542
-            $msg = sprintf(
543
-                esc_html__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
544
-                $critical_page['name']
545
-            );
546
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
547
-            return $critical_page;
548
-        }
549
-        // get newly created post's details
550
-        if (! $critical_page['post'] = get_post($post_id)) {
551
-            $msg = sprintf(
552
-                esc_html__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
553
-                $critical_page['name']
554
-            );
555
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
556
-        }
557
-
558
-        return $critical_page;
559
-    }
560
-
561
-
562
-    /**
563
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
564
-     * The role being used to check is filterable.
565
-     *
566
-     * @return int|null WP_user ID or NULL
567
-     * @throws EE_Error
568
-     * @throws ReflectionException
569
-     * @since  4.6.0
570
-     * @global WPDB $wpdb
571
-     */
572
-    public static function get_default_creator_id()
573
-    {
574
-        global $wpdb;
575
-        if (! empty(self::$_default_creator_id)) {
576
-            return self::$_default_creator_id;
577
-        }/**/
578
-        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
579
-        // let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
580
-        $pre_filtered_id = apply_filters(
581
-            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
582
-            false,
583
-            $role_to_check
584
-        );
585
-        if ($pre_filtered_id !== false) {
586
-            return (int) $pre_filtered_id;
587
-        }
588
-        $capabilities_key = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
589
-        $query            = $wpdb->prepare(
590
-            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
591
-            '%' . $role_to_check . '%'
592
-        );
593
-        $user_id          = $wpdb->get_var($query);
594
-        $user_id          = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
595
-        if ($user_id && (int) $user_id) {
596
-            self::$_default_creator_id = (int) $user_id;
597
-            return self::$_default_creator_id;
598
-        } else {
599
-            return null;
600
-        }
601
-    }
602
-
603
-
604
-    /**
605
-     * used by EE and EE addons during plugin activation to create tables.
606
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
607
-     * but includes extra logic regarding activations.
608
-     *
609
-     * @param string  $table_name              without the $wpdb->prefix
610
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
611
-     *                                         table query)
612
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
613
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
614
-     *                                         and new once this function is done (ie, you really do want to CREATE a
615
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
616
-     *                                         you just want to verify the table exists and matches this definition
617
-     *                                         (and if it HAS data in it you want to leave it be)
618
-     * @return void
619
-     * @throws EE_Error if there are database errors
620
-     * @throws ReflectionException
621
-     */
622
-    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
623
-    {
624
-        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
625
-            return;
626
-        }
627
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
628
-        if (! function_exists('dbDelta')) {
629
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
630
-        }
631
-        $tableAnalysis = EEH_Activation::getTableAnalysis();
632
-        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
633
-        // do we need to first delete an existing version of this table ?
634
-        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
635
-            // ok, delete the table... but ONLY if it's empty
636
-            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
637
-            // table is NOT empty, are you SURE you want to delete this table ???
638
-            if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
639
-                EEH_Activation::getTableManager()->dropTable($wp_table_name);
640
-            } elseif (! $deleted_safely) {
641
-                // so we should be more cautious rather than just dropping tables so easily
642
-                error_log(
643
-                    sprintf(
644
-                        esc_html__(
645
-                            'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
646
-                            'event_espresso'
647
-                        ),
648
-                        $wp_table_name,
649
-                        '<br/>',
650
-                        'espresso_db_update'
651
-                    )
652
-                );
653
-            }
654
-        }
655
-        $engine = str_replace('ENGINE=', '', $engine);
656
-        EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
657
-    }
658
-
659
-
660
-    /**
661
-     * Checks if this column already exists on the specified table. Handy for addons which want to add a column
662
-     *
663
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
664
-     * @param string $column_name
665
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
666
-     *                            'VARCHAR(10)'
667
-     * @return bool|int
668
-     * @throws EE_Error
669
-     * @throws ReflectionException
670
-     * @deprecated instead use TableManager::addColumn()
671
-     */
672
-    public static function add_column_if_it_doesnt_exist(
673
-        $table_name,
674
-        $column_name,
675
-        $column_info = 'INT UNSIGNED NOT NULL'
676
-    ) {
677
-        return EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
678
-    }
679
-
680
-
681
-    /**
682
-     * Gets all the fields on the database table.
683
-     *
684
-     * @param string $table_name , without prefixed $wpdb->prefix
685
-     * @return array of database column names
686
-     * @throws EE_Error
687
-     * @throws ReflectionException
688
-     * @deprecated instead use TableManager::getTableColumns()
689
-     */
690
-    public static function get_fields_on_table($table_name = null)
691
-    {
692
-        return EEH_Activation::getTableManager()->getTableColumns($table_name);
693
-    }
694
-
695
-
696
-    /**
697
-     * @param string $table_name
698
-     * @return bool
699
-     * @throws EE_Error
700
-     * @throws ReflectionException
701
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
702
-     */
703
-    public static function db_table_is_empty($table_name)
704
-    {
705
-        return EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
706
-    }
707
-
708
-
709
-    /**
710
-     * @param string $table_name
711
-     * @return bool | int
712
-     * @throws EE_Error
713
-     * @throws ReflectionException
714
-     */
715
-    public static function delete_db_table_if_empty($table_name)
716
-    {
717
-        if (EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
718
-            return EEH_Activation::getTableManager()->dropTable($table_name);
719
-        }
720
-        return false;
721
-    }
722
-
723
-
724
-    /**
725
-     * @param string $table_name
726
-     * @return int
727
-     * @throws EE_Error
728
-     * @throws ReflectionException
729
-     * @deprecated instead use TableManager::dropTable()
730
-     */
731
-    public static function delete_unused_db_table($table_name)
732
-    {
733
-        return EEH_Activation::getTableManager()->dropTable($table_name);
734
-    }
735
-
736
-
737
-    /**
738
-     * @param string $table_name
739
-     * @param string $index_name
740
-     * @return int
741
-     * @throws EE_Error
742
-     * @throws ReflectionException
743
-     * @deprecated instead use TableManager::dropIndex()
744
-     */
745
-    public static function drop_index($table_name, $index_name)
746
-    {
747
-        return EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
748
-    }
749
-
750
-
751
-    /**
752
-     * @return boolean success (whether database is setup properly or not)
753
-     * @throws EE_Error
754
-     * @throws ReflectionException
755
-     */
756
-    public static function create_database_tables()
757
-    {
758
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
759
-        // find the migration script that sets the database to be compatible with the code
760
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
761
-        if (! $dms_name) {
762
-            EE_Error::add_error(
763
-                esc_html__(
764
-                    'Could not determine most up-to-date data migration script from which to pull database schema
268
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
269
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
270
+			if (is_array($hooks_to_fire_at_time)) {
271
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
272
+					if (
273
+						isset($ee_cron_tasks_to_remove[ $hook_name ])
274
+						&& is_array($ee_cron_tasks_to_remove[ $hook_name ])
275
+					) {
276
+						unset($crons[ $timestamp ][ $hook_name ]);
277
+					}
278
+				}
279
+				// also take care of any empty cron timestamps.
280
+				if (empty($hooks_to_fire_at_time)) {
281
+					unset($crons[ $timestamp ]);
282
+				}
283
+			}
284
+		}
285
+		_set_cron_array($crons);
286
+	}
287
+
288
+
289
+	/**
290
+	 * registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
291
+	 *
292
+	 * @return void
293
+	 * @throws EE_Error
294
+	 * @throws ReflectionException
295
+	 */
296
+	public static function CPT_initialization()
297
+	{
298
+		// register Custom Post Types
299
+		EE_Registry::instance()->load_core('Register_CPTs');
300
+		flush_rewrite_rules();
301
+	}
302
+
303
+
304
+	/**
305
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
306
+	 * If there is old calendar config data saved, then it will get converted on activation.
307
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
308
+	 *
309
+	 * @return void
310
+	 */
311
+	public static function reset_and_update_config()
312
+	{
313
+		do_action('AHEE__EE_Config___load_core_config__start', ['EEH_Activation', 'load_calendar_config']);
314
+		add_filter(
315
+			'FHEE__EE_Config___load_core_config__config_settings',
316
+			['EEH_Activation', 'migrate_old_config_data'],
317
+			10,
318
+			3
319
+		);
320
+		if (! EE_Config::logging_enabled()) {
321
+			delete_option(EE_Config::LOG_NAME);
322
+		}
323
+	}
324
+
325
+
326
+	/**
327
+	 * @return    void
328
+	 */
329
+	public static function load_calendar_config()
330
+	{
331
+		// grab array of all plugin folders and loop thru it
332
+		$plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
333
+		if (empty($plugins)) {
334
+			return;
335
+		}
336
+		foreach ($plugins as $plugin_path) {
337
+			// grab plugin folder name from path
338
+			$plugin = basename($plugin_path);
339
+			// drill down to Espresso plugins
340
+			// then to calendar related plugins
341
+			if (
342
+				strpos($plugin, 'espresso') !== false
343
+				|| strpos($plugin, 'Espresso') !== false
344
+				|| strpos($plugin, 'ee4') !== false
345
+				|| strpos($plugin, 'EE4') !== false
346
+				|| strpos($plugin, 'calendar') !== false
347
+			) {
348
+				// this is what we are looking for
349
+				$calendar_config = $plugin_path . '/EE_Calendar_Config.php';
350
+				// does it exist in this folder ?
351
+				if (is_readable($calendar_config)) {
352
+					// YEAH! let's load it
353
+					require_once($calendar_config);
354
+				}
355
+			}
356
+		}
357
+	}
358
+
359
+
360
+	/**
361
+	 * @param array|stdClass $settings
362
+	 * @param int|string         $config
363
+	 * @param EE_Config      $EE_Config
364
+	 * @return stdClass
365
+	 */
366
+	public static function migrate_old_config_data($settings, $config, EE_Config $EE_Config)
367
+	{
368
+		$convert_from_array = ['addons'];
369
+		// in case old settings were saved as an array
370
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
371
+			// convert existing settings to an object
372
+			$config_array = $settings;
373
+			$settings     = new stdClass();
374
+			foreach ($config_array as $key => $value) {
375
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
376
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
377
+				} else {
378
+					$settings->{$key} = $value;
379
+				}
380
+			}
381
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
382
+		}
383
+		return $settings;
384
+	}
385
+
386
+
387
+	/**
388
+	 * @return void
389
+	 */
390
+	public static function deactivate_event_espresso()
391
+	{
392
+		// check permissions
393
+		if (current_user_can('activate_plugins')) {
394
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
395
+		}
396
+	}
397
+
398
+
399
+	/**
400
+	 * @return void
401
+	 * @throws InvalidDataTypeException
402
+	 */
403
+	public static function verify_default_pages_exist()
404
+	{
405
+		$critical_page_problem = false;
406
+		$critical_pages        = [
407
+			[
408
+				'id'   => 'reg_page_id',
409
+				'name' => esc_html__('Registration Checkout', 'event_espresso'),
410
+				'post' => null,
411
+				'code' => 'ESPRESSO_CHECKOUT',
412
+			],
413
+			[
414
+				'id'   => 'txn_page_id',
415
+				'name' => esc_html__('Transactions', 'event_espresso'),
416
+				'post' => null,
417
+				'code' => 'ESPRESSO_TXN_PAGE',
418
+			],
419
+			[
420
+				'id'   => 'thank_you_page_id',
421
+				'name' => esc_html__('Thank You', 'event_espresso'),
422
+				'post' => null,
423
+				'code' => 'ESPRESSO_THANK_YOU',
424
+			],
425
+			[
426
+				'id'   => 'cancel_page_id',
427
+				'name' => esc_html__('Registration Cancelled', 'event_espresso'),
428
+				'post' => null,
429
+				'code' => 'ESPRESSO_CANCELLED',
430
+			],
431
+		];
432
+		$EE_Core_Config        = EE_Registry::instance()->CFG->core;
433
+		foreach ($critical_pages as $critical_page) {
434
+			// is critical page ID set in config ?
435
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
436
+				// attempt to find post by ID
437
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
438
+			}
439
+			// no dice?
440
+			if ($critical_page['post'] === null) {
441
+				// attempt to find post by title
442
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
443
+				// still nothing?
444
+				if ($critical_page['post'] === null) {
445
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
446
+					// REALLY? Still nothing ??!?!?
447
+					if ($critical_page['post'] === null) {
448
+						$msg = esc_html__(
449
+							'The Event Espresso critical page configuration settings could not be updated.',
450
+							'event_espresso'
451
+						);
452
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
453
+						break;
454
+					}
455
+				}
456
+			}
457
+			// check that Post ID matches critical page ID in config
458
+			if (
459
+				isset($critical_page['post']->ID)
460
+				&& $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
461
+			) {
462
+				// update Config with post ID
463
+				$EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
464
+				if (! EE_Config::instance()->update_espresso_config(false, false)) {
465
+					$msg = esc_html__(
466
+						'The Event Espresso critical page configuration settings could not be updated.',
467
+						'event_espresso'
468
+					);
469
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
470
+				}
471
+			}
472
+			$critical_page_problem =
473
+				! isset($critical_page['post']->post_status)
474
+				|| $critical_page['post']->post_status !== 'publish'
475
+				|| strpos($critical_page['post']->post_content, $critical_page['code']) === false
476
+					? true
477
+					: $critical_page_problem;
478
+		}
479
+		if ($critical_page_problem) {
480
+			new PersistentAdminNotice(
481
+				'critical_page_problem',
482
+				sprintf(
483
+					esc_html__(
484
+						'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
485
+						'event_espresso'
486
+					),
487
+					'<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
488
+					. esc_html__('Event Espresso Critical Pages Settings', 'event_espresso')
489
+					. '</a>'
490
+				)
491
+			);
492
+		}
493
+		if (EE_Error::has_notices()) {
494
+			EE_Error::get_notices(false, true);
495
+		}
496
+	}
497
+
498
+
499
+	/**
500
+	 * Returns the first post which uses the specified shortcode
501
+	 *
502
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
503
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
504
+	 *                             "[ESPRESSO_THANK_YOU"
505
+	 *                             (we don't search for the closing shortcode bracket because they might have added
506
+	 *                             parameter to the shortcode
507
+	 * @return WP_Post or NULl
508
+	 */
509
+	public static function get_page_by_ee_shortcode($ee_shortcode)
510
+	{
511
+		global $wpdb;
512
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
513
+		$post_id                       =
514
+			$wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
515
+		if ($post_id) {
516
+			return get_post($post_id);
517
+		} else {
518
+			return null;
519
+		}
520
+	}
521
+
522
+
523
+	/**
524
+	 * This function generates a post for critical espresso pages
525
+	 *
526
+	 * @param array $critical_page
527
+	 * @return array
528
+	 */
529
+	public static function create_critical_page($critical_page)
530
+	{
531
+
532
+		$post_args = [
533
+			'post_title'     => $critical_page['name'],
534
+			'post_status'    => 'publish',
535
+			'post_type'      => 'page',
536
+			'comment_status' => 'closed',
537
+			'post_content'   => '[' . $critical_page['code'] . ']',
538
+		];
539
+
540
+		$post_id = wp_insert_post($post_args);
541
+		if (! $post_id) {
542
+			$msg = sprintf(
543
+				esc_html__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
544
+				$critical_page['name']
545
+			);
546
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
547
+			return $critical_page;
548
+		}
549
+		// get newly created post's details
550
+		if (! $critical_page['post'] = get_post($post_id)) {
551
+			$msg = sprintf(
552
+				esc_html__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
553
+				$critical_page['name']
554
+			);
555
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
556
+		}
557
+
558
+		return $critical_page;
559
+	}
560
+
561
+
562
+	/**
563
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
564
+	 * The role being used to check is filterable.
565
+	 *
566
+	 * @return int|null WP_user ID or NULL
567
+	 * @throws EE_Error
568
+	 * @throws ReflectionException
569
+	 * @since  4.6.0
570
+	 * @global WPDB $wpdb
571
+	 */
572
+	public static function get_default_creator_id()
573
+	{
574
+		global $wpdb;
575
+		if (! empty(self::$_default_creator_id)) {
576
+			return self::$_default_creator_id;
577
+		}/**/
578
+		$role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
579
+		// let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
580
+		$pre_filtered_id = apply_filters(
581
+			'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
582
+			false,
583
+			$role_to_check
584
+		);
585
+		if ($pre_filtered_id !== false) {
586
+			return (int) $pre_filtered_id;
587
+		}
588
+		$capabilities_key = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
589
+		$query            = $wpdb->prepare(
590
+			"SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
591
+			'%' . $role_to_check . '%'
592
+		);
593
+		$user_id          = $wpdb->get_var($query);
594
+		$user_id          = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
595
+		if ($user_id && (int) $user_id) {
596
+			self::$_default_creator_id = (int) $user_id;
597
+			return self::$_default_creator_id;
598
+		} else {
599
+			return null;
600
+		}
601
+	}
602
+
603
+
604
+	/**
605
+	 * used by EE and EE addons during plugin activation to create tables.
606
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
607
+	 * but includes extra logic regarding activations.
608
+	 *
609
+	 * @param string  $table_name              without the $wpdb->prefix
610
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
611
+	 *                                         table query)
612
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
613
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
614
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
615
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
616
+	 *                                         you just want to verify the table exists and matches this definition
617
+	 *                                         (and if it HAS data in it you want to leave it be)
618
+	 * @return void
619
+	 * @throws EE_Error if there are database errors
620
+	 * @throws ReflectionException
621
+	 */
622
+	public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
623
+	{
624
+		if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
625
+			return;
626
+		}
627
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
628
+		if (! function_exists('dbDelta')) {
629
+			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
630
+		}
631
+		$tableAnalysis = EEH_Activation::getTableAnalysis();
632
+		$wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
633
+		// do we need to first delete an existing version of this table ?
634
+		if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
635
+			// ok, delete the table... but ONLY if it's empty
636
+			$deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
637
+			// table is NOT empty, are you SURE you want to delete this table ???
638
+			if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
639
+				EEH_Activation::getTableManager()->dropTable($wp_table_name);
640
+			} elseif (! $deleted_safely) {
641
+				// so we should be more cautious rather than just dropping tables so easily
642
+				error_log(
643
+					sprintf(
644
+						esc_html__(
645
+							'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
646
+							'event_espresso'
647
+						),
648
+						$wp_table_name,
649
+						'<br/>',
650
+						'espresso_db_update'
651
+					)
652
+				);
653
+			}
654
+		}
655
+		$engine = str_replace('ENGINE=', '', $engine);
656
+		EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
657
+	}
658
+
659
+
660
+	/**
661
+	 * Checks if this column already exists on the specified table. Handy for addons which want to add a column
662
+	 *
663
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
664
+	 * @param string $column_name
665
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
666
+	 *                            'VARCHAR(10)'
667
+	 * @return bool|int
668
+	 * @throws EE_Error
669
+	 * @throws ReflectionException
670
+	 * @deprecated instead use TableManager::addColumn()
671
+	 */
672
+	public static function add_column_if_it_doesnt_exist(
673
+		$table_name,
674
+		$column_name,
675
+		$column_info = 'INT UNSIGNED NOT NULL'
676
+	) {
677
+		return EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
678
+	}
679
+
680
+
681
+	/**
682
+	 * Gets all the fields on the database table.
683
+	 *
684
+	 * @param string $table_name , without prefixed $wpdb->prefix
685
+	 * @return array of database column names
686
+	 * @throws EE_Error
687
+	 * @throws ReflectionException
688
+	 * @deprecated instead use TableManager::getTableColumns()
689
+	 */
690
+	public static function get_fields_on_table($table_name = null)
691
+	{
692
+		return EEH_Activation::getTableManager()->getTableColumns($table_name);
693
+	}
694
+
695
+
696
+	/**
697
+	 * @param string $table_name
698
+	 * @return bool
699
+	 * @throws EE_Error
700
+	 * @throws ReflectionException
701
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
702
+	 */
703
+	public static function db_table_is_empty($table_name)
704
+	{
705
+		return EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
706
+	}
707
+
708
+
709
+	/**
710
+	 * @param string $table_name
711
+	 * @return bool | int
712
+	 * @throws EE_Error
713
+	 * @throws ReflectionException
714
+	 */
715
+	public static function delete_db_table_if_empty($table_name)
716
+	{
717
+		if (EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
718
+			return EEH_Activation::getTableManager()->dropTable($table_name);
719
+		}
720
+		return false;
721
+	}
722
+
723
+
724
+	/**
725
+	 * @param string $table_name
726
+	 * @return int
727
+	 * @throws EE_Error
728
+	 * @throws ReflectionException
729
+	 * @deprecated instead use TableManager::dropTable()
730
+	 */
731
+	public static function delete_unused_db_table($table_name)
732
+	{
733
+		return EEH_Activation::getTableManager()->dropTable($table_name);
734
+	}
735
+
736
+
737
+	/**
738
+	 * @param string $table_name
739
+	 * @param string $index_name
740
+	 * @return int
741
+	 * @throws EE_Error
742
+	 * @throws ReflectionException
743
+	 * @deprecated instead use TableManager::dropIndex()
744
+	 */
745
+	public static function drop_index($table_name, $index_name)
746
+	{
747
+		return EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
748
+	}
749
+
750
+
751
+	/**
752
+	 * @return boolean success (whether database is setup properly or not)
753
+	 * @throws EE_Error
754
+	 * @throws ReflectionException
755
+	 */
756
+	public static function create_database_tables()
757
+	{
758
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
759
+		// find the migration script that sets the database to be compatible with the code
760
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
761
+		if (! $dms_name) {
762
+			EE_Error::add_error(
763
+				esc_html__(
764
+					'Could not determine most up-to-date data migration script from which to pull database schema
765 765
                      structure. So database is probably not setup properly',
766
-                    'event_espresso'
767
-                ),
768
-                __FILE__,
769
-                __FUNCTION__,
770
-                __LINE__
771
-            );
772
-            return false;
773
-        }
774
-        $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
775
-        $current_data_migration_script->set_migrating(false);
776
-        $current_data_migration_script->schema_changes_before_migration();
777
-        $current_data_migration_script->schema_changes_after_migration();
778
-        if ($current_data_migration_script->get_errors()) {
779
-            if (WP_DEBUG) {
780
-                foreach ($current_data_migration_script->get_errors() as $error) {
781
-                    EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
782
-                }
783
-            } else {
784
-                EE_Error::add_error(
785
-                    esc_html__(
786
-                        'There were errors creating the Event Espresso database tables and Event Espresso has been
766
+					'event_espresso'
767
+				),
768
+				__FILE__,
769
+				__FUNCTION__,
770
+				__LINE__
771
+			);
772
+			return false;
773
+		}
774
+		$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
775
+		$current_data_migration_script->set_migrating(false);
776
+		$current_data_migration_script->schema_changes_before_migration();
777
+		$current_data_migration_script->schema_changes_after_migration();
778
+		if ($current_data_migration_script->get_errors()) {
779
+			if (WP_DEBUG) {
780
+				foreach ($current_data_migration_script->get_errors() as $error) {
781
+					EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
782
+				}
783
+			} else {
784
+				EE_Error::add_error(
785
+					esc_html__(
786
+						'There were errors creating the Event Espresso database tables and Event Espresso has been
787 787
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
788
-                        'event_espresso'
789
-                    )
790
-                );
791
-            }
792
-            return false;
793
-        }
794
-        EE_Data_Migration_Manager::instance()->update_current_database_state_to();
795
-        return true;
796
-    }
797
-
798
-
799
-    /**
800
-     * @return void
801
-     * @throws EE_Error
802
-     * @throws ReflectionException
803
-     */
804
-    public static function initialize_system_questions()
805
-    {
806
-        // QUESTION GROUPS
807
-        global $wpdb;
808
-        $table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
809
-        $SQL        = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
810
-        // what we have
811
-        $question_groups = $wpdb->get_col($SQL);
812
-        // check the response
813
-        $question_groups = is_array($question_groups) ? $question_groups : [];
814
-        // what we should have
815
-        $QSG_systems = [1, 2];
816
-        // loop thru what we should have and compare to what we have
817
-        foreach ($QSG_systems as $QSG_system) {
818
-            // reset values array
819
-            $QSG_values = [];
820
-            // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
821
-            if (! in_array("$QSG_system", $question_groups)) {
822
-                // add it
823
-                switch ($QSG_system) {
824
-                    case 1:
825
-                        $QSG_values = [
826
-                            'QSG_name'            => esc_html__('Personal Information', 'event_espresso'),
827
-                            'QSG_identifier'      => 'personal-information-' . time(),
828
-                            'QSG_desc'            => '',
829
-                            'QSG_order'           => 1,
830
-                            'QSG_show_group_name' => 1,
831
-                            'QSG_show_group_desc' => 1,
832
-                            'QSG_system'          => EEM_Question_Group::system_personal,
833
-                            'QSG_deleted'         => 0,
834
-                        ];
835
-                        break;
836
-                    case 2:
837
-                        $QSG_values = [
838
-                            'QSG_name'            => esc_html__('Address Information', 'event_espresso'),
839
-                            'QSG_identifier'      => 'address-information-' . time(),
840
-                            'QSG_desc'            => '',
841
-                            'QSG_order'           => 2,
842
-                            'QSG_show_group_name' => 1,
843
-                            'QSG_show_group_desc' => 1,
844
-                            'QSG_system'          => EEM_Question_Group::system_address,
845
-                            'QSG_deleted'         => 0,
846
-                        ];
847
-                        break;
848
-                }
849
-                // make sure we have some values before inserting them
850
-                if (! empty($QSG_values)) {
851
-                    // insert system question
852
-                    $wpdb->insert(
853
-                        $table_name,
854
-                        $QSG_values,
855
-                        ['%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d']
856
-                    );
857
-                    $QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
858
-                }
859
-            }
860
-        }
861
-        // QUESTIONS
862
-        global $wpdb;
863
-        $table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
864
-        $SQL        = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
865
-        // what we have
866
-        $questions = $wpdb->get_col($SQL);
867
-        // all system questions
868
-        $personal_system_group_questions = ['fname', 'lname', 'email'];
869
-        $address_system_group_questions  = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
870
-        $system_questions_not_in_group   = ['email_confirm'];
871
-        // merge all of the system questions we should have
872
-        $QST_systems       = array_merge(
873
-            $personal_system_group_questions,
874
-            $address_system_group_questions,
875
-            $system_questions_not_in_group
876
-        );
877
-        $order_for_group_1 = 1;
878
-        $order_for_group_2 = 1;
879
-        // loop thru what we should have and compare to what we have
880
-        foreach ($QST_systems as $QST_system) {
881
-            // reset values array
882
-            $QST_values = [];
883
-            // if we don't have what we should have
884
-            if (! in_array($QST_system, $questions)) {
885
-                // add it
886
-                switch ($QST_system) {
887
-                    case 'fname':
888
-                        $QST_values = [
889
-                            'QST_display_text'  => esc_html__('First Name', 'event_espresso'),
890
-                            'QST_admin_label'   => esc_html__('First Name - System Question', 'event_espresso'),
891
-                            'QST_system'        => 'fname',
892
-                            'QST_type'          => 'TEXT',
893
-                            'QST_required'      => 1,
894
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
895
-                            'QST_order'         => 1,
896
-                            'QST_admin_only'    => 0,
897
-                            'QST_max'           => EEM_Question::instance()
898
-                                                               ->absolute_max_for_system_question($QST_system),
899
-                            'QST_wp_user'       => self::get_default_creator_id(),
900
-                            'QST_deleted'       => 0,
901
-                        ];
902
-                        break;
903
-                    case 'lname':
904
-                        $QST_values = [
905
-                            'QST_display_text'  => esc_html__('Last Name', 'event_espresso'),
906
-                            'QST_admin_label'   => esc_html__('Last Name - System Question', 'event_espresso'),
907
-                            'QST_system'        => 'lname',
908
-                            'QST_type'          => 'TEXT',
909
-                            'QST_required'      => 1,
910
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
911
-                            'QST_order'         => 2,
912
-                            'QST_admin_only'    => 0,
913
-                            'QST_max'           => EEM_Question::instance()
914
-                                                               ->absolute_max_for_system_question($QST_system),
915
-                            'QST_wp_user'       => self::get_default_creator_id(),
916
-                            'QST_deleted'       => 0,
917
-                        ];
918
-                        break;
919
-                    case 'email':
920
-                        $QST_values = [
921
-                            'QST_display_text'  => esc_html__('Email Address', 'event_espresso'),
922
-                            'QST_admin_label'   => esc_html__('Email Address - System Question', 'event_espresso'),
923
-                            'QST_system'        => 'email',
924
-                            'QST_type'          => 'EMAIL',
925
-                            'QST_required'      => 1,
926
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
927
-                            'QST_order'         => 3,
928
-                            'QST_admin_only'    => 0,
929
-                            'QST_max'           => EEM_Question::instance()
930
-                                                               ->absolute_max_for_system_question($QST_system),
931
-                            'QST_wp_user'       => self::get_default_creator_id(),
932
-                            'QST_deleted'       => 0,
933
-                        ];
934
-                        break;
935
-                    case 'email_confirm':
936
-                        $QST_values = [
937
-                            'QST_display_text'  => esc_html__('Confirm Email Address', 'event_espresso'),
938
-                            'QST_admin_label'   => esc_html__('Confirm Email Address - System Question', 'event_espresso'),
939
-                            'QST_system'        => 'email_confirm',
940
-                            'QST_type'          => 'EMAIL_CONFIRM',
941
-                            'QST_required'      => 1,
942
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
943
-                            'QST_order'         => 4,
944
-                            'QST_admin_only'    => 0,
945
-                            'QST_max'           => EEM_Question::instance()
946
-                                                               ->absolute_max_for_system_question($QST_system),
947
-                            'QST_wp_user'       => self::get_default_creator_id(),
948
-                            'QST_deleted'       => 0,
949
-                        ];
950
-                        break;
951
-                    case 'address':
952
-                        $QST_values = [
953
-                            'QST_display_text'  => esc_html__('Address', 'event_espresso'),
954
-                            'QST_admin_label'   => esc_html__('Address - System Question', 'event_espresso'),
955
-                            'QST_system'        => 'address',
956
-                            'QST_type'          => 'TEXT',
957
-                            'QST_required'      => 0,
958
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
959
-                            'QST_order'         => 5,
960
-                            'QST_admin_only'    => 0,
961
-                            'QST_max'           => EEM_Question::instance()
962
-                                                               ->absolute_max_for_system_question($QST_system),
963
-                            'QST_wp_user'       => self::get_default_creator_id(),
964
-                            'QST_deleted'       => 0,
965
-                        ];
966
-                        break;
967
-                    case 'address2':
968
-                        $QST_values = [
969
-                            'QST_display_text'  => esc_html__('Address2', 'event_espresso'),
970
-                            'QST_admin_label'   => esc_html__('Address2 - System Question', 'event_espresso'),
971
-                            'QST_system'        => 'address2',
972
-                            'QST_type'          => 'TEXT',
973
-                            'QST_required'      => 0,
974
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
975
-                            'QST_order'         => 6,
976
-                            'QST_admin_only'    => 0,
977
-                            'QST_max'           => EEM_Question::instance()
978
-                                                               ->absolute_max_for_system_question($QST_system),
979
-                            'QST_wp_user'       => self::get_default_creator_id(),
980
-                            'QST_deleted'       => 0,
981
-                        ];
982
-                        break;
983
-                    case 'city':
984
-                        $QST_values = [
985
-                            'QST_display_text'  => esc_html__('City', 'event_espresso'),
986
-                            'QST_admin_label'   => esc_html__('City - System Question', 'event_espresso'),
987
-                            'QST_system'        => 'city',
988
-                            'QST_type'          => 'TEXT',
989
-                            'QST_required'      => 0,
990
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
991
-                            'QST_order'         => 7,
992
-                            'QST_admin_only'    => 0,
993
-                            'QST_max'           => EEM_Question::instance()
994
-                                                               ->absolute_max_for_system_question($QST_system),
995
-                            'QST_wp_user'       => self::get_default_creator_id(),
996
-                            'QST_deleted'       => 0,
997
-                        ];
998
-                        break;
999
-                    case 'country':
1000
-                        $QST_values = [
1001
-                            'QST_display_text'  => esc_html__('Country', 'event_espresso'),
1002
-                            'QST_admin_label'   => esc_html__('Country - System Question', 'event_espresso'),
1003
-                            'QST_system'        => 'country',
1004
-                            'QST_type'          => 'COUNTRY',
1005
-                            'QST_required'      => 0,
1006
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1007
-                            'QST_order'         => 8,
1008
-                            'QST_admin_only'    => 0,
1009
-                            'QST_wp_user'       => self::get_default_creator_id(),
1010
-                            'QST_deleted'       => 0,
1011
-                        ];
1012
-                        break;
1013
-                    case 'state':
1014
-                        $QST_values = [
1015
-                            'QST_display_text'  => esc_html__('State/Province', 'event_espresso'),
1016
-                            'QST_admin_label'   => esc_html__('State/Province - System Question', 'event_espresso'),
1017
-                            'QST_system'        => 'state',
1018
-                            'QST_type'          => 'STATE',
1019
-                            'QST_required'      => 0,
1020
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1021
-                            'QST_order'         => 9,
1022
-                            'QST_admin_only'    => 0,
1023
-                            'QST_wp_user'       => self::get_default_creator_id(),
1024
-                            'QST_deleted'       => 0,
1025
-                        ];
1026
-                        break;
1027
-                    case 'zip':
1028
-                        $QST_values = [
1029
-                            'QST_display_text'  => esc_html__('Zip/Postal Code', 'event_espresso'),
1030
-                            'QST_admin_label'   => esc_html__('Zip/Postal Code - System Question', 'event_espresso'),
1031
-                            'QST_system'        => 'zip',
1032
-                            'QST_type'          => 'TEXT',
1033
-                            'QST_required'      => 0,
1034
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1035
-                            'QST_order'         => 10,
1036
-                            'QST_admin_only'    => 0,
1037
-                            'QST_max'           => EEM_Question::instance()
1038
-                                                               ->absolute_max_for_system_question($QST_system),
1039
-                            'QST_wp_user'       => self::get_default_creator_id(),
1040
-                            'QST_deleted'       => 0,
1041
-                        ];
1042
-                        break;
1043
-                    case 'phone':
1044
-                        $QST_values = [
1045
-                            'QST_display_text'  => esc_html__('Phone Number', 'event_espresso'),
1046
-                            'QST_admin_label'   => esc_html__('Phone Number - System Question', 'event_espresso'),
1047
-                            'QST_system'        => 'phone',
1048
-                            'QST_type'          => 'TEXT',
1049
-                            'QST_required'      => 0,
1050
-                            'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1051
-                            'QST_order'         => 11,
1052
-                            'QST_admin_only'    => 0,
1053
-                            'QST_max'           => EEM_Question::instance()
1054
-                                                               ->absolute_max_for_system_question($QST_system),
1055
-                            'QST_wp_user'       => self::get_default_creator_id(),
1056
-                            'QST_deleted'       => 0,
1057
-                        ];
1058
-                        break;
1059
-                }
1060
-                if (! empty($QST_values)) {
1061
-                    // insert system question
1062
-                    $wpdb->insert(
1063
-                        $table_name,
1064
-                        $QST_values,
1065
-                        ['%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d']
1066
-                    );
1067
-                    $QST_ID = $wpdb->insert_id;
1068
-
1069
-                    // QUESTION GROUP QUESTIONS
1070
-                    if (in_array($QST_system, $personal_system_group_questions)) {
1071
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1072
-                    } elseif (in_array($QST_system, $address_system_group_questions)) {
1073
-                        $system_question_we_want = EEM_Question_Group::system_address;
1074
-                    } else {
1075
-                        // QST_system should not be assigned to any group
1076
-                        continue;
1077
-                    }
1078
-                    if (isset($QSG_IDs[ $system_question_we_want ])) {
1079
-                        $QSG_ID = $QSG_IDs[ $system_question_we_want ];
1080
-                    } else {
1081
-                        $id_col = EEM_Question_Group::instance()
1082
-                                                    ->get_col([['QSG_system' => $system_question_we_want]]);
1083
-                        if (is_array($id_col)) {
1084
-                            $QSG_ID = reset($id_col);
1085
-                        } else {
1086
-                            // ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1087
-                            EE_Log::instance()->log(
1088
-                                __FILE__,
1089
-                                __FUNCTION__,
1090
-                                sprintf(
1091
-                                    esc_html__(
1092
-                                        'Could not associate question %1$s to a question group because no system question
788
+						'event_espresso'
789
+					)
790
+				);
791
+			}
792
+			return false;
793
+		}
794
+		EE_Data_Migration_Manager::instance()->update_current_database_state_to();
795
+		return true;
796
+	}
797
+
798
+
799
+	/**
800
+	 * @return void
801
+	 * @throws EE_Error
802
+	 * @throws ReflectionException
803
+	 */
804
+	public static function initialize_system_questions()
805
+	{
806
+		// QUESTION GROUPS
807
+		global $wpdb;
808
+		$table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
809
+		$SQL        = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
810
+		// what we have
811
+		$question_groups = $wpdb->get_col($SQL);
812
+		// check the response
813
+		$question_groups = is_array($question_groups) ? $question_groups : [];
814
+		// what we should have
815
+		$QSG_systems = [1, 2];
816
+		// loop thru what we should have and compare to what we have
817
+		foreach ($QSG_systems as $QSG_system) {
818
+			// reset values array
819
+			$QSG_values = [];
820
+			// if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
821
+			if (! in_array("$QSG_system", $question_groups)) {
822
+				// add it
823
+				switch ($QSG_system) {
824
+					case 1:
825
+						$QSG_values = [
826
+							'QSG_name'            => esc_html__('Personal Information', 'event_espresso'),
827
+							'QSG_identifier'      => 'personal-information-' . time(),
828
+							'QSG_desc'            => '',
829
+							'QSG_order'           => 1,
830
+							'QSG_show_group_name' => 1,
831
+							'QSG_show_group_desc' => 1,
832
+							'QSG_system'          => EEM_Question_Group::system_personal,
833
+							'QSG_deleted'         => 0,
834
+						];
835
+						break;
836
+					case 2:
837
+						$QSG_values = [
838
+							'QSG_name'            => esc_html__('Address Information', 'event_espresso'),
839
+							'QSG_identifier'      => 'address-information-' . time(),
840
+							'QSG_desc'            => '',
841
+							'QSG_order'           => 2,
842
+							'QSG_show_group_name' => 1,
843
+							'QSG_show_group_desc' => 1,
844
+							'QSG_system'          => EEM_Question_Group::system_address,
845
+							'QSG_deleted'         => 0,
846
+						];
847
+						break;
848
+				}
849
+				// make sure we have some values before inserting them
850
+				if (! empty($QSG_values)) {
851
+					// insert system question
852
+					$wpdb->insert(
853
+						$table_name,
854
+						$QSG_values,
855
+						['%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d']
856
+					);
857
+					$QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
858
+				}
859
+			}
860
+		}
861
+		// QUESTIONS
862
+		global $wpdb;
863
+		$table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
864
+		$SQL        = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
865
+		// what we have
866
+		$questions = $wpdb->get_col($SQL);
867
+		// all system questions
868
+		$personal_system_group_questions = ['fname', 'lname', 'email'];
869
+		$address_system_group_questions  = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
870
+		$system_questions_not_in_group   = ['email_confirm'];
871
+		// merge all of the system questions we should have
872
+		$QST_systems       = array_merge(
873
+			$personal_system_group_questions,
874
+			$address_system_group_questions,
875
+			$system_questions_not_in_group
876
+		);
877
+		$order_for_group_1 = 1;
878
+		$order_for_group_2 = 1;
879
+		// loop thru what we should have and compare to what we have
880
+		foreach ($QST_systems as $QST_system) {
881
+			// reset values array
882
+			$QST_values = [];
883
+			// if we don't have what we should have
884
+			if (! in_array($QST_system, $questions)) {
885
+				// add it
886
+				switch ($QST_system) {
887
+					case 'fname':
888
+						$QST_values = [
889
+							'QST_display_text'  => esc_html__('First Name', 'event_espresso'),
890
+							'QST_admin_label'   => esc_html__('First Name - System Question', 'event_espresso'),
891
+							'QST_system'        => 'fname',
892
+							'QST_type'          => 'TEXT',
893
+							'QST_required'      => 1,
894
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
895
+							'QST_order'         => 1,
896
+							'QST_admin_only'    => 0,
897
+							'QST_max'           => EEM_Question::instance()
898
+															   ->absolute_max_for_system_question($QST_system),
899
+							'QST_wp_user'       => self::get_default_creator_id(),
900
+							'QST_deleted'       => 0,
901
+						];
902
+						break;
903
+					case 'lname':
904
+						$QST_values = [
905
+							'QST_display_text'  => esc_html__('Last Name', 'event_espresso'),
906
+							'QST_admin_label'   => esc_html__('Last Name - System Question', 'event_espresso'),
907
+							'QST_system'        => 'lname',
908
+							'QST_type'          => 'TEXT',
909
+							'QST_required'      => 1,
910
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
911
+							'QST_order'         => 2,
912
+							'QST_admin_only'    => 0,
913
+							'QST_max'           => EEM_Question::instance()
914
+															   ->absolute_max_for_system_question($QST_system),
915
+							'QST_wp_user'       => self::get_default_creator_id(),
916
+							'QST_deleted'       => 0,
917
+						];
918
+						break;
919
+					case 'email':
920
+						$QST_values = [
921
+							'QST_display_text'  => esc_html__('Email Address', 'event_espresso'),
922
+							'QST_admin_label'   => esc_html__('Email Address - System Question', 'event_espresso'),
923
+							'QST_system'        => 'email',
924
+							'QST_type'          => 'EMAIL',
925
+							'QST_required'      => 1,
926
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
927
+							'QST_order'         => 3,
928
+							'QST_admin_only'    => 0,
929
+							'QST_max'           => EEM_Question::instance()
930
+															   ->absolute_max_for_system_question($QST_system),
931
+							'QST_wp_user'       => self::get_default_creator_id(),
932
+							'QST_deleted'       => 0,
933
+						];
934
+						break;
935
+					case 'email_confirm':
936
+						$QST_values = [
937
+							'QST_display_text'  => esc_html__('Confirm Email Address', 'event_espresso'),
938
+							'QST_admin_label'   => esc_html__('Confirm Email Address - System Question', 'event_espresso'),
939
+							'QST_system'        => 'email_confirm',
940
+							'QST_type'          => 'EMAIL_CONFIRM',
941
+							'QST_required'      => 1,
942
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
943
+							'QST_order'         => 4,
944
+							'QST_admin_only'    => 0,
945
+							'QST_max'           => EEM_Question::instance()
946
+															   ->absolute_max_for_system_question($QST_system),
947
+							'QST_wp_user'       => self::get_default_creator_id(),
948
+							'QST_deleted'       => 0,
949
+						];
950
+						break;
951
+					case 'address':
952
+						$QST_values = [
953
+							'QST_display_text'  => esc_html__('Address', 'event_espresso'),
954
+							'QST_admin_label'   => esc_html__('Address - System Question', 'event_espresso'),
955
+							'QST_system'        => 'address',
956
+							'QST_type'          => 'TEXT',
957
+							'QST_required'      => 0,
958
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
959
+							'QST_order'         => 5,
960
+							'QST_admin_only'    => 0,
961
+							'QST_max'           => EEM_Question::instance()
962
+															   ->absolute_max_for_system_question($QST_system),
963
+							'QST_wp_user'       => self::get_default_creator_id(),
964
+							'QST_deleted'       => 0,
965
+						];
966
+						break;
967
+					case 'address2':
968
+						$QST_values = [
969
+							'QST_display_text'  => esc_html__('Address2', 'event_espresso'),
970
+							'QST_admin_label'   => esc_html__('Address2 - System Question', 'event_espresso'),
971
+							'QST_system'        => 'address2',
972
+							'QST_type'          => 'TEXT',
973
+							'QST_required'      => 0,
974
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
975
+							'QST_order'         => 6,
976
+							'QST_admin_only'    => 0,
977
+							'QST_max'           => EEM_Question::instance()
978
+															   ->absolute_max_for_system_question($QST_system),
979
+							'QST_wp_user'       => self::get_default_creator_id(),
980
+							'QST_deleted'       => 0,
981
+						];
982
+						break;
983
+					case 'city':
984
+						$QST_values = [
985
+							'QST_display_text'  => esc_html__('City', 'event_espresso'),
986
+							'QST_admin_label'   => esc_html__('City - System Question', 'event_espresso'),
987
+							'QST_system'        => 'city',
988
+							'QST_type'          => 'TEXT',
989
+							'QST_required'      => 0,
990
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
991
+							'QST_order'         => 7,
992
+							'QST_admin_only'    => 0,
993
+							'QST_max'           => EEM_Question::instance()
994
+															   ->absolute_max_for_system_question($QST_system),
995
+							'QST_wp_user'       => self::get_default_creator_id(),
996
+							'QST_deleted'       => 0,
997
+						];
998
+						break;
999
+					case 'country':
1000
+						$QST_values = [
1001
+							'QST_display_text'  => esc_html__('Country', 'event_espresso'),
1002
+							'QST_admin_label'   => esc_html__('Country - System Question', 'event_espresso'),
1003
+							'QST_system'        => 'country',
1004
+							'QST_type'          => 'COUNTRY',
1005
+							'QST_required'      => 0,
1006
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1007
+							'QST_order'         => 8,
1008
+							'QST_admin_only'    => 0,
1009
+							'QST_wp_user'       => self::get_default_creator_id(),
1010
+							'QST_deleted'       => 0,
1011
+						];
1012
+						break;
1013
+					case 'state':
1014
+						$QST_values = [
1015
+							'QST_display_text'  => esc_html__('State/Province', 'event_espresso'),
1016
+							'QST_admin_label'   => esc_html__('State/Province - System Question', 'event_espresso'),
1017
+							'QST_system'        => 'state',
1018
+							'QST_type'          => 'STATE',
1019
+							'QST_required'      => 0,
1020
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1021
+							'QST_order'         => 9,
1022
+							'QST_admin_only'    => 0,
1023
+							'QST_wp_user'       => self::get_default_creator_id(),
1024
+							'QST_deleted'       => 0,
1025
+						];
1026
+						break;
1027
+					case 'zip':
1028
+						$QST_values = [
1029
+							'QST_display_text'  => esc_html__('Zip/Postal Code', 'event_espresso'),
1030
+							'QST_admin_label'   => esc_html__('Zip/Postal Code - System Question', 'event_espresso'),
1031
+							'QST_system'        => 'zip',
1032
+							'QST_type'          => 'TEXT',
1033
+							'QST_required'      => 0,
1034
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1035
+							'QST_order'         => 10,
1036
+							'QST_admin_only'    => 0,
1037
+							'QST_max'           => EEM_Question::instance()
1038
+															   ->absolute_max_for_system_question($QST_system),
1039
+							'QST_wp_user'       => self::get_default_creator_id(),
1040
+							'QST_deleted'       => 0,
1041
+						];
1042
+						break;
1043
+					case 'phone':
1044
+						$QST_values = [
1045
+							'QST_display_text'  => esc_html__('Phone Number', 'event_espresso'),
1046
+							'QST_admin_label'   => esc_html__('Phone Number - System Question', 'event_espresso'),
1047
+							'QST_system'        => 'phone',
1048
+							'QST_type'          => 'TEXT',
1049
+							'QST_required'      => 0,
1050
+							'QST_required_text' => esc_html__('This field is required', 'event_espresso'),
1051
+							'QST_order'         => 11,
1052
+							'QST_admin_only'    => 0,
1053
+							'QST_max'           => EEM_Question::instance()
1054
+															   ->absolute_max_for_system_question($QST_system),
1055
+							'QST_wp_user'       => self::get_default_creator_id(),
1056
+							'QST_deleted'       => 0,
1057
+						];
1058
+						break;
1059
+				}
1060
+				if (! empty($QST_values)) {
1061
+					// insert system question
1062
+					$wpdb->insert(
1063
+						$table_name,
1064
+						$QST_values,
1065
+						['%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d']
1066
+					);
1067
+					$QST_ID = $wpdb->insert_id;
1068
+
1069
+					// QUESTION GROUP QUESTIONS
1070
+					if (in_array($QST_system, $personal_system_group_questions)) {
1071
+						$system_question_we_want = EEM_Question_Group::system_personal;
1072
+					} elseif (in_array($QST_system, $address_system_group_questions)) {
1073
+						$system_question_we_want = EEM_Question_Group::system_address;
1074
+					} else {
1075
+						// QST_system should not be assigned to any group
1076
+						continue;
1077
+					}
1078
+					if (isset($QSG_IDs[ $system_question_we_want ])) {
1079
+						$QSG_ID = $QSG_IDs[ $system_question_we_want ];
1080
+					} else {
1081
+						$id_col = EEM_Question_Group::instance()
1082
+													->get_col([['QSG_system' => $system_question_we_want]]);
1083
+						if (is_array($id_col)) {
1084
+							$QSG_ID = reset($id_col);
1085
+						} else {
1086
+							// ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1087
+							EE_Log::instance()->log(
1088
+								__FILE__,
1089
+								__FUNCTION__,
1090
+								sprintf(
1091
+									esc_html__(
1092
+										'Could not associate question %1$s to a question group because no system question
1093 1093
                                          group existed',
1094
-                                        'event_espresso'
1095
-                                    ),
1096
-                                    $QST_ID
1097
-                                ),
1098
-                                'error'
1099
-                            );
1100
-                            continue;
1101
-                        }
1102
-                    }
1103
-                    // add system questions to groups
1104
-                    $wpdb->insert(
1105
-                        EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1106
-                        [
1107
-                            'QSG_ID'    => $QSG_ID,
1108
-                            'QST_ID'    => $QST_ID,
1109
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1110
-                        ],
1111
-                        ['%d', '%d', '%d']
1112
-                    );
1113
-                }
1114
-            }
1115
-        }
1116
-    }
1117
-
1118
-
1119
-    /**
1120
-     * Makes sure the default payment method (Invoice) is active.
1121
-     * This used to be done automatically as part of constructing the old gateways config
1122
-     *
1123
-     * @throws EE_Error
1124
-     * @throws ReflectionException
1125
-     */
1126
-    public static function insert_default_payment_methods()
1127
-    {
1128
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1129
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1130
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1131
-        } else {
1132
-            EEM_Payment_Method::instance()->verify_button_urls();
1133
-        }
1134
-    }
1135
-
1136
-
1137
-    /**
1138
-     * @return void
1139
-     * @throws EE_Error
1140
-     * @throws ReflectionException
1141
-     */
1142
-    public static function insert_default_status_codes()
1143
-    {
1144
-
1145
-        global $wpdb;
1146
-
1147
-        if (EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1148
-            $table_name = EEM_Status::instance()->table();
1149
-
1150
-            $SQL =
1151
-                "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1152
-            $wpdb->query($SQL);
1153
-
1154
-            $SQL = "INSERT INTO $table_name
1094
+										'event_espresso'
1095
+									),
1096
+									$QST_ID
1097
+								),
1098
+								'error'
1099
+							);
1100
+							continue;
1101
+						}
1102
+					}
1103
+					// add system questions to groups
1104
+					$wpdb->insert(
1105
+						EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1106
+						[
1107
+							'QSG_ID'    => $QSG_ID,
1108
+							'QST_ID'    => $QST_ID,
1109
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1110
+						],
1111
+						['%d', '%d', '%d']
1112
+					);
1113
+				}
1114
+			}
1115
+		}
1116
+	}
1117
+
1118
+
1119
+	/**
1120
+	 * Makes sure the default payment method (Invoice) is active.
1121
+	 * This used to be done automatically as part of constructing the old gateways config
1122
+	 *
1123
+	 * @throws EE_Error
1124
+	 * @throws ReflectionException
1125
+	 */
1126
+	public static function insert_default_payment_methods()
1127
+	{
1128
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1129
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1130
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1131
+		} else {
1132
+			EEM_Payment_Method::instance()->verify_button_urls();
1133
+		}
1134
+	}
1135
+
1136
+
1137
+	/**
1138
+	 * @return void
1139
+	 * @throws EE_Error
1140
+	 * @throws ReflectionException
1141
+	 */
1142
+	public static function insert_default_status_codes()
1143
+	{
1144
+
1145
+		global $wpdb;
1146
+
1147
+		if (EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1148
+			$table_name = EEM_Status::instance()->table();
1149
+
1150
+			$SQL =
1151
+				"DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1152
+			$wpdb->query($SQL);
1153
+
1154
+			$SQL = "INSERT INTO $table_name
1155 1155
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1156 1156
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1157 1157
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1191,480 +1191,480 @@  discard block
 block discarded – undo
1191 1191
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1192 1192
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1193 1193
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1194
-            $wpdb->query($SQL);
1195
-        }
1196
-    }
1197
-
1198
-
1199
-    /**
1200
-     * @return bool     true means new templates were created.
1201
-     *                  false means no templates were created.
1202
-     *                  This is NOT an error flag. To check for errors you will want
1203
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1204
-     * @throws EE_Error
1205
-     * @throws ReflectionException
1206
-     */
1207
-    public static function generate_default_message_templates()
1208
-    {
1209
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1210
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1211
-        /*
1194
+			$wpdb->query($SQL);
1195
+		}
1196
+	}
1197
+
1198
+
1199
+	/**
1200
+	 * @return bool     true means new templates were created.
1201
+	 *                  false means no templates were created.
1202
+	 *                  This is NOT an error flag. To check for errors you will want
1203
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1204
+	 * @throws EE_Error
1205
+	 * @throws ReflectionException
1206
+	 */
1207
+	public static function generate_default_message_templates()
1208
+	{
1209
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1210
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1211
+		/*
1212 1212
          * This first method is taking care of ensuring any default messengers
1213 1213
          * that should be made active and have templates generated are done.
1214 1214
          */
1215
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1216
-            $message_resource_manager
1217
-        );
1218
-        /**
1219
-         * This method is verifying there are no NEW default message types
1220
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1221
-         */
1222
-        $new_templates_created_for_message_type =
1223
-            self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1224
-                $message_resource_manager
1225
-            );
1226
-        // after all is done, let's persist these changes to the db.
1227
-        $message_resource_manager->update_has_activated_messengers_option();
1228
-        $message_resource_manager->update_active_messengers_option();
1229
-        // will return true if either of these are true.  Otherwise will return false.
1230
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1231
-    }
1232
-
1233
-
1234
-    /**
1235
-     * @param EE_Message_Resource_Manager $message_resource_manager
1236
-     * @return array|bool
1237
-     * @throws EE_Error
1238
-     * @throws ReflectionException
1239
-     */
1240
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1241
-        EE_Message_Resource_Manager $message_resource_manager
1242
-    ) {
1243
-        $active_messengers       = $message_resource_manager->active_messengers();
1244
-        $installed_message_types = $message_resource_manager->installed_message_types();
1245
-        $templates_created       = false;
1246
-        foreach ($active_messengers as $active_messenger) {
1247
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1248
-            $default_message_type_names_to_activate   = [];
1249
-            // looping through each default message type reported by the messenger
1250
-            // and setup the actual message types to activate.
1251
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1252
-                // if already active or has already been activated before we skip
1253
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1254
-                // we also skip if the message type is not installed.
1255
-                if (
1256
-                    $message_resource_manager->has_message_type_been_activated_for_messenger(
1257
-                        $default_message_type_name_for_messenger,
1258
-                        $active_messenger->name
1259
-                    )
1260
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1261
-                        $active_messenger->name,
1262
-                        $default_message_type_name_for_messenger
1263
-                    )
1264
-                    || ! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1265
-                ) {
1266
-                    continue;
1267
-                }
1268
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1269
-            }
1270
-            // let's activate!
1271
-            $message_resource_manager->ensure_message_types_are_active(
1272
-                $default_message_type_names_to_activate,
1273
-                $active_messenger->name,
1274
-                false
1275
-            );
1276
-            // activate the templates for these message types
1277
-            if (! empty($default_message_type_names_to_activate)) {
1278
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1279
-                    $active_messenger->name,
1280
-                    $default_message_type_names_for_messenger,
1281
-                    '',
1282
-                    true
1283
-                );
1284
-            }
1285
-        }
1286
-        return $templates_created;
1287
-    }
1288
-
1289
-
1290
-    /**
1291
-     * This will activate and generate default messengers and default message types for those messengers.
1292
-     *
1293
-     * @param EE_message_Resource_Manager $message_resource_manager
1294
-     * @return array|bool  True means there were default messengers and message type templates generated.
1295
-     *                     False means that there were no templates generated
1296
-     *                     (which could simply mean there are no default message types for a messenger).
1297
-     * @throws EE_Error
1298
-     * @throws ReflectionException
1299
-     */
1300
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1301
-        EE_Message_Resource_Manager $message_resource_manager
1302
-    ) {
1303
-        $messengers_to_generate  = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1304
-        $installed_message_types = $message_resource_manager->installed_message_types();
1305
-        $templates_generated     = false;
1306
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1307
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1308
-            // verify the default message types match an installed message type.
1309
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1310
-                if (
1311
-                    ! isset($installed_message_types[ $name ])
1312
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1313
-                        $name,
1314
-                        $messenger_to_generate->name
1315
-                    )
1316
-                ) {
1317
-                    unset($default_message_type_names_for_messenger[ $key ]);
1318
-                }
1319
-            }
1320
-            // in previous iterations, the active_messengers option in the db
1321
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1322
-            // This comment is left here just in case we discover that we _do_ need to update before
1323
-            // passing off to create templates (after the refactor is done).
1324
-            // @todo remove this comment when determined not necessary.
1325
-            $message_resource_manager->activate_messenger(
1326
-                $messenger_to_generate,
1327
-                $default_message_type_names_for_messenger,
1328
-                false
1329
-            );
1330
-            // create any templates needing created (or will reactivate templates already generated as necessary).
1331
-            if (! empty($default_message_type_names_for_messenger)) {
1332
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1333
-                    $messenger_to_generate->name,
1334
-                    $default_message_type_names_for_messenger,
1335
-                    '',
1336
-                    true
1337
-                );
1338
-            }
1339
-        }
1340
-        return $templates_generated;
1341
-    }
1342
-
1343
-
1344
-    /**
1345
-     * This returns the default messengers to generate templates for on activation of EE.
1346
-     * It considers:
1347
-     * - whether a messenger is already active in the db.
1348
-     * - whether a messenger has been made active at any time in the past.
1349
-     *
1350
-     * @param EE_Message_Resource_Manager $message_resource_manager
1351
-     * @return EE_messenger[]
1352
-     */
1353
-    protected static function _get_default_messengers_to_generate_on_activation(
1354
-        EE_Message_Resource_Manager $message_resource_manager
1355
-    ) {
1356
-        $active_messengers    = $message_resource_manager->active_messengers();
1357
-        $installed_messengers = $message_resource_manager->installed_messengers();
1358
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1359
-
1360
-        $messengers_to_generate = [];
1361
-        foreach ($installed_messengers as $installed_messenger) {
1362
-            // if installed messenger is a messenger that should be activated on install
1363
-            // and is not already active
1364
-            // and has never been activated
1365
-            if (
1366
-                ! $installed_messenger->activate_on_install
1367
-                || isset($active_messengers[ $installed_messenger->name ])
1368
-                || isset($has_activated[ $installed_messenger->name ])
1369
-            ) {
1370
-                continue;
1371
-            }
1372
-            $messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1373
-        }
1374
-        return $messengers_to_generate;
1375
-    }
1376
-
1377
-
1378
-    /**
1379
-     * This simply validates active message types to ensure they actually match installed
1380
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1381
-     * rows are set inactive.
1382
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1383
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1384
-     * are still handled in here.
1385
-     *
1386
-     * @return void
1387
-     * @throws EE_Error
1388
-     * @throws ReflectionException
1389
-     * @since 4.3.1
1390
-     */
1391
-    public static function validate_messages_system()
1392
-    {
1393
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1394
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1395
-        $message_resource_manager->validate_active_message_types_are_installed();
1396
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1397
-    }
1398
-
1399
-
1400
-    /**
1401
-     * @return void
1402
-     */
1403
-    public static function create_no_ticket_prices_array()
1404
-    {
1405
-        // this creates an array for tracking events that have no active ticket prices created
1406
-        // this allows us to warn admins of the situation so that it can be corrected
1407
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1408
-        if (! $espresso_no_ticket_prices) {
1409
-            add_option('ee_no_ticket_prices', [], '', false);
1410
-        }
1411
-    }
1412
-
1413
-
1414
-    /**
1415
-     * @return void
1416
-     */
1417
-    public static function plugin_deactivation()
1418
-    {
1419
-    }
1420
-
1421
-
1422
-    /**
1423
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1424
-     * (like post meta or term relations)
1425
-     *
1426
-     * @throws EE_Error
1427
-     * @global wpdb $wpdb
1428
-     */
1429
-    public static function delete_all_espresso_cpt_data()
1430
-    {
1431
-        global $wpdb;
1432
-        // get all the CPT post_types
1433
-        $ee_post_types = [];
1434
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1435
-            if (method_exists($model_name, 'instance')) {
1436
-                $model_obj = call_user_func([$model_name, 'instance']);
1437
-                if ($model_obj instanceof EEM_CPT_Base) {
1438
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1439
-                }
1440
-            }
1441
-        }
1442
-        // get all our CPTs
1443
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1444
-        $cpt_ids = $wpdb->get_col($query);
1445
-        // delete each post meta and term relations too
1446
-        foreach ($cpt_ids as $post_id) {
1447
-            wp_delete_post($post_id, true);
1448
-        }
1449
-    }
1450
-
1451
-
1452
-    /**
1453
-     * Deletes all EE custom tables
1454
-     *
1455
-     * @return array
1456
-     * @throws EE_Error
1457
-     * @throws ReflectionException
1458
-     */
1459
-    public static function drop_espresso_tables()
1460
-    {
1461
-        $tables = [];
1462
-        // load registry
1463
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1464
-            if (method_exists($model_name, 'instance')) {
1465
-                $model_obj = call_user_func([$model_name, 'instance']);
1466
-                if ($model_obj instanceof EEM_Base) {
1467
-                    foreach ($model_obj->get_tables() as $table) {
1468
-                        if (
1469
-                            strpos($table->get_table_name(), 'esp_')
1470
-                            && (
1471
-                                is_main_site()// main site? nuke them all
1472
-                                || ! $table->is_global()// not main site,but not global either. nuke it
1473
-                            )
1474
-                        ) {
1475
-                            $tables[ $table->get_table_name() ] = $table->get_table_name();
1476
-                        }
1477
-                    }
1478
-                }
1479
-            }
1480
-        }
1481
-
1482
-        // there are some tables whose models were removed.
1483
-        // they should be removed when removing all EE core's data
1484
-        $tables_without_models = [
1485
-            'esp_promotion',
1486
-            'esp_promotion_applied',
1487
-            'esp_promotion_object',
1488
-            'esp_promotion_rule',
1489
-            'esp_rule',
1490
-        ];
1491
-        foreach ($tables_without_models as $table) {
1492
-            $tables[ $table ] = $table;
1493
-        }
1494
-        return EEH_Activation::getTableManager()->dropTables($tables);
1495
-    }
1496
-
1497
-
1498
-    /**
1499
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1500
-     * each table name provided has a wpdb prefix attached, and that it exists.
1501
-     * Returns the list actually deleted
1502
-     *
1503
-     * @param array $table_names
1504
-     * @return array of table names which we deleted
1505
-     * @throws EE_Error
1506
-     * @throws ReflectionException
1507
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1508
-     * @global WPDB $wpdb
1509
-     */
1510
-    public static function drop_tables($table_names)
1511
-    {
1512
-        return EEH_Activation::getTableManager()->dropTables($table_names);
1513
-    }
1514
-
1515
-
1516
-    /**
1517
-     * plugin_uninstall
1518
-     *
1519
-     * @param bool $remove_all
1520
-     * @return void
1521
-     * @throws EE_Error
1522
-     * @throws ReflectionException
1523
-     */
1524
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1525
-    {
1526
-        global $wpdb;
1527
-        self::drop_espresso_tables();
1528
-        $wp_options_to_delete = [
1529
-            'ee_no_ticket_prices'                        => true,
1530
-            'ee_active_messengers'                       => true,
1531
-            'ee_has_activated_messenger'                 => true,
1532
-            RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1533
-            'ee_config'                                  => false,
1534
-            'ee_data_migration_current_db_state'         => true,
1535
-            'ee_data_migration_mapping_'                 => false,
1536
-            'ee_data_migration_script_'                  => false,
1537
-            'ee_data_migrations'                         => true,
1538
-            'ee_dms_map'                                 => false,
1539
-            'ee_notices'                                 => true,
1540
-            'lang_file_check_'                           => false,
1541
-            'ee_maintenance_mode'                        => true,
1542
-            'ee_ueip_optin'                              => true,
1543
-            'ee_ueip_has_notified'                       => true,
1544
-            'ee_plugin_activation_errors'                => true,
1545
-            'ee_id_mapping_from'                         => false,
1546
-            'espresso_persistent_admin_notices'          => true,
1547
-            'ee_encryption_key'                          => true,
1548
-            'pue_force_upgrade_'                         => false,
1549
-            'pue_json_error_'                            => false,
1550
-            'pue_install_key_'                           => false,
1551
-            'pue_verification_error_'                    => false,
1552
-            'pu_dismissed_upgrade_'                      => false,
1553
-            'external_updates-'                          => false,
1554
-            'ee_extra_data'                              => true,
1555
-            'ee_ssn_'                                    => false,
1556
-            'ee_rss_'                                    => false,
1557
-            'ee_rte_n_tx_'                               => false,
1558
-            'ee_pers_admin_notices'                      => true,
1559
-            'ee_job_parameters_'                         => false,
1560
-            'ee_upload_directories_incomplete'           => true,
1561
-            'ee_verified_db_collations'                  => true,
1562
-        ];
1563
-        if (is_main_site()) {
1564
-            $wp_options_to_delete['ee_network_config'] = true;
1565
-        }
1566
-        $undeleted_options = [];
1567
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1568
-            if ($no_wildcard) {
1569
-                if (! delete_option($option_name)) {
1570
-                    $undeleted_options[] = $option_name;
1571
-                }
1572
-            } else {
1573
-                $option_names_to_delete_from_wildcard =
1574
-                    $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1575
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1576
-                    if (! delete_option($option_name_from_wildcard)) {
1577
-                        $undeleted_options[] = $option_name_from_wildcard;
1578
-                    }
1579
-                }
1580
-            }
1581
-        }
1582
-        // also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1583
-        remove_action('shutdown', [EE_Config::instance(), 'shutdown']);
1584
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1585
-            $db_update_sans_ee4 = [];
1586
-            foreach ($espresso_db_update as $version => $times_activated) {
1587
-                if ((string) $version[0] === '3') {// if its NON EE4
1588
-                    $db_update_sans_ee4[ $version ] = $times_activated;
1589
-                }
1590
-            }
1591
-            update_option('espresso_db_update', $db_update_sans_ee4);
1592
-        }
1593
-        $errors = '';
1594
-        if (! empty($undeleted_options)) {
1595
-            $errors .= sprintf(
1596
-                esc_html__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1597
-                '<br/>',
1598
-                implode(',<br/>', $undeleted_options)
1599
-            );
1600
-        }
1601
-        if (! empty($errors)) {
1602
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1603
-        }
1604
-    }
1605
-
1606
-
1607
-    /**
1608
-     * Gets the mysql error code from the last used query by wpdb
1609
-     *
1610
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1611
-     */
1612
-    public static function last_wpdb_error_code()
1613
-    {
1614
-        // phpcs:disable PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
1615
-        global $wpdb;
1616
-        return $wpdb->use_mysqli ? mysqli_errno($wpdb->dbh) : 0;
1617
-        // phpcs:enable
1618
-    }
1619
-
1620
-
1621
-    /**
1622
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1623
-     *
1624
-     * @param string $table_name with or without $wpdb->prefix
1625
-     * @return boolean
1626
-     * @throws EE_Error
1627
-     * @throws ReflectionException
1628
-     * @global wpdb  $wpdb
1629
-     * @deprecated instead use TableAnalysis::tableExists()
1630
-     */
1631
-    public static function table_exists($table_name)
1632
-    {
1633
-        return EEH_Activation::getTableAnalysis()->tableExists($table_name);
1634
-    }
1635
-
1636
-
1637
-    /**
1638
-     * Resets the cache on EEH_Activation
1639
-     */
1640
-    public static function reset()
1641
-    {
1642
-        self::$_default_creator_id                             = null;
1643
-        self::$_initialized_db_content_already_in_this_request = false;
1644
-    }
1645
-
1646
-
1647
-    /**
1648
-     * Removes 'email_confirm' from the Address info question group on activation
1649
-     *
1650
-     * @return void
1651
-     * @throws EE_Error
1652
-     */
1653
-    public static function removeEmailConfirmFromAddressGroup()
1654
-    {
1655
-
1656
-        // Pull the email_confirm question ID.
1657
-        $email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1658
-            EEM_Attendee::system_question_email_confirm
1659
-        );
1660
-        // Remove the email_confirm question group from the address group questions.
1661
-        EEM_Question_Group_Question::instance()->delete(
1662
-            [
1663
-                [
1664
-                    'QST_ID'                    => $email_confirm_question_id,
1665
-                    'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1666
-                ],
1667
-            ]
1668
-        );
1669
-    }
1215
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1216
+			$message_resource_manager
1217
+		);
1218
+		/**
1219
+		 * This method is verifying there are no NEW default message types
1220
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1221
+		 */
1222
+		$new_templates_created_for_message_type =
1223
+			self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1224
+				$message_resource_manager
1225
+			);
1226
+		// after all is done, let's persist these changes to the db.
1227
+		$message_resource_manager->update_has_activated_messengers_option();
1228
+		$message_resource_manager->update_active_messengers_option();
1229
+		// will return true if either of these are true.  Otherwise will return false.
1230
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1231
+	}
1232
+
1233
+
1234
+	/**
1235
+	 * @param EE_Message_Resource_Manager $message_resource_manager
1236
+	 * @return array|bool
1237
+	 * @throws EE_Error
1238
+	 * @throws ReflectionException
1239
+	 */
1240
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1241
+		EE_Message_Resource_Manager $message_resource_manager
1242
+	) {
1243
+		$active_messengers       = $message_resource_manager->active_messengers();
1244
+		$installed_message_types = $message_resource_manager->installed_message_types();
1245
+		$templates_created       = false;
1246
+		foreach ($active_messengers as $active_messenger) {
1247
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1248
+			$default_message_type_names_to_activate   = [];
1249
+			// looping through each default message type reported by the messenger
1250
+			// and setup the actual message types to activate.
1251
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1252
+				// if already active or has already been activated before we skip
1253
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1254
+				// we also skip if the message type is not installed.
1255
+				if (
1256
+					$message_resource_manager->has_message_type_been_activated_for_messenger(
1257
+						$default_message_type_name_for_messenger,
1258
+						$active_messenger->name
1259
+					)
1260
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1261
+						$active_messenger->name,
1262
+						$default_message_type_name_for_messenger
1263
+					)
1264
+					|| ! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1265
+				) {
1266
+					continue;
1267
+				}
1268
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1269
+			}
1270
+			// let's activate!
1271
+			$message_resource_manager->ensure_message_types_are_active(
1272
+				$default_message_type_names_to_activate,
1273
+				$active_messenger->name,
1274
+				false
1275
+			);
1276
+			// activate the templates for these message types
1277
+			if (! empty($default_message_type_names_to_activate)) {
1278
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1279
+					$active_messenger->name,
1280
+					$default_message_type_names_for_messenger,
1281
+					'',
1282
+					true
1283
+				);
1284
+			}
1285
+		}
1286
+		return $templates_created;
1287
+	}
1288
+
1289
+
1290
+	/**
1291
+	 * This will activate and generate default messengers and default message types for those messengers.
1292
+	 *
1293
+	 * @param EE_message_Resource_Manager $message_resource_manager
1294
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1295
+	 *                     False means that there were no templates generated
1296
+	 *                     (which could simply mean there are no default message types for a messenger).
1297
+	 * @throws EE_Error
1298
+	 * @throws ReflectionException
1299
+	 */
1300
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1301
+		EE_Message_Resource_Manager $message_resource_manager
1302
+	) {
1303
+		$messengers_to_generate  = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1304
+		$installed_message_types = $message_resource_manager->installed_message_types();
1305
+		$templates_generated     = false;
1306
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1307
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1308
+			// verify the default message types match an installed message type.
1309
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1310
+				if (
1311
+					! isset($installed_message_types[ $name ])
1312
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1313
+						$name,
1314
+						$messenger_to_generate->name
1315
+					)
1316
+				) {
1317
+					unset($default_message_type_names_for_messenger[ $key ]);
1318
+				}
1319
+			}
1320
+			// in previous iterations, the active_messengers option in the db
1321
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1322
+			// This comment is left here just in case we discover that we _do_ need to update before
1323
+			// passing off to create templates (after the refactor is done).
1324
+			// @todo remove this comment when determined not necessary.
1325
+			$message_resource_manager->activate_messenger(
1326
+				$messenger_to_generate,
1327
+				$default_message_type_names_for_messenger,
1328
+				false
1329
+			);
1330
+			// create any templates needing created (or will reactivate templates already generated as necessary).
1331
+			if (! empty($default_message_type_names_for_messenger)) {
1332
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1333
+					$messenger_to_generate->name,
1334
+					$default_message_type_names_for_messenger,
1335
+					'',
1336
+					true
1337
+				);
1338
+			}
1339
+		}
1340
+		return $templates_generated;
1341
+	}
1342
+
1343
+
1344
+	/**
1345
+	 * This returns the default messengers to generate templates for on activation of EE.
1346
+	 * It considers:
1347
+	 * - whether a messenger is already active in the db.
1348
+	 * - whether a messenger has been made active at any time in the past.
1349
+	 *
1350
+	 * @param EE_Message_Resource_Manager $message_resource_manager
1351
+	 * @return EE_messenger[]
1352
+	 */
1353
+	protected static function _get_default_messengers_to_generate_on_activation(
1354
+		EE_Message_Resource_Manager $message_resource_manager
1355
+	) {
1356
+		$active_messengers    = $message_resource_manager->active_messengers();
1357
+		$installed_messengers = $message_resource_manager->installed_messengers();
1358
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1359
+
1360
+		$messengers_to_generate = [];
1361
+		foreach ($installed_messengers as $installed_messenger) {
1362
+			// if installed messenger is a messenger that should be activated on install
1363
+			// and is not already active
1364
+			// and has never been activated
1365
+			if (
1366
+				! $installed_messenger->activate_on_install
1367
+				|| isset($active_messengers[ $installed_messenger->name ])
1368
+				|| isset($has_activated[ $installed_messenger->name ])
1369
+			) {
1370
+				continue;
1371
+			}
1372
+			$messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1373
+		}
1374
+		return $messengers_to_generate;
1375
+	}
1376
+
1377
+
1378
+	/**
1379
+	 * This simply validates active message types to ensure they actually match installed
1380
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1381
+	 * rows are set inactive.
1382
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1383
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1384
+	 * are still handled in here.
1385
+	 *
1386
+	 * @return void
1387
+	 * @throws EE_Error
1388
+	 * @throws ReflectionException
1389
+	 * @since 4.3.1
1390
+	 */
1391
+	public static function validate_messages_system()
1392
+	{
1393
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1394
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1395
+		$message_resource_manager->validate_active_message_types_are_installed();
1396
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1397
+	}
1398
+
1399
+
1400
+	/**
1401
+	 * @return void
1402
+	 */
1403
+	public static function create_no_ticket_prices_array()
1404
+	{
1405
+		// this creates an array for tracking events that have no active ticket prices created
1406
+		// this allows us to warn admins of the situation so that it can be corrected
1407
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1408
+		if (! $espresso_no_ticket_prices) {
1409
+			add_option('ee_no_ticket_prices', [], '', false);
1410
+		}
1411
+	}
1412
+
1413
+
1414
+	/**
1415
+	 * @return void
1416
+	 */
1417
+	public static function plugin_deactivation()
1418
+	{
1419
+	}
1420
+
1421
+
1422
+	/**
1423
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1424
+	 * (like post meta or term relations)
1425
+	 *
1426
+	 * @throws EE_Error
1427
+	 * @global wpdb $wpdb
1428
+	 */
1429
+	public static function delete_all_espresso_cpt_data()
1430
+	{
1431
+		global $wpdb;
1432
+		// get all the CPT post_types
1433
+		$ee_post_types = [];
1434
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1435
+			if (method_exists($model_name, 'instance')) {
1436
+				$model_obj = call_user_func([$model_name, 'instance']);
1437
+				if ($model_obj instanceof EEM_CPT_Base) {
1438
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1439
+				}
1440
+			}
1441
+		}
1442
+		// get all our CPTs
1443
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1444
+		$cpt_ids = $wpdb->get_col($query);
1445
+		// delete each post meta and term relations too
1446
+		foreach ($cpt_ids as $post_id) {
1447
+			wp_delete_post($post_id, true);
1448
+		}
1449
+	}
1450
+
1451
+
1452
+	/**
1453
+	 * Deletes all EE custom tables
1454
+	 *
1455
+	 * @return array
1456
+	 * @throws EE_Error
1457
+	 * @throws ReflectionException
1458
+	 */
1459
+	public static function drop_espresso_tables()
1460
+	{
1461
+		$tables = [];
1462
+		// load registry
1463
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1464
+			if (method_exists($model_name, 'instance')) {
1465
+				$model_obj = call_user_func([$model_name, 'instance']);
1466
+				if ($model_obj instanceof EEM_Base) {
1467
+					foreach ($model_obj->get_tables() as $table) {
1468
+						if (
1469
+							strpos($table->get_table_name(), 'esp_')
1470
+							&& (
1471
+								is_main_site()// main site? nuke them all
1472
+								|| ! $table->is_global()// not main site,but not global either. nuke it
1473
+							)
1474
+						) {
1475
+							$tables[ $table->get_table_name() ] = $table->get_table_name();
1476
+						}
1477
+					}
1478
+				}
1479
+			}
1480
+		}
1481
+
1482
+		// there are some tables whose models were removed.
1483
+		// they should be removed when removing all EE core's data
1484
+		$tables_without_models = [
1485
+			'esp_promotion',
1486
+			'esp_promotion_applied',
1487
+			'esp_promotion_object',
1488
+			'esp_promotion_rule',
1489
+			'esp_rule',
1490
+		];
1491
+		foreach ($tables_without_models as $table) {
1492
+			$tables[ $table ] = $table;
1493
+		}
1494
+		return EEH_Activation::getTableManager()->dropTables($tables);
1495
+	}
1496
+
1497
+
1498
+	/**
1499
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1500
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1501
+	 * Returns the list actually deleted
1502
+	 *
1503
+	 * @param array $table_names
1504
+	 * @return array of table names which we deleted
1505
+	 * @throws EE_Error
1506
+	 * @throws ReflectionException
1507
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1508
+	 * @global WPDB $wpdb
1509
+	 */
1510
+	public static function drop_tables($table_names)
1511
+	{
1512
+		return EEH_Activation::getTableManager()->dropTables($table_names);
1513
+	}
1514
+
1515
+
1516
+	/**
1517
+	 * plugin_uninstall
1518
+	 *
1519
+	 * @param bool $remove_all
1520
+	 * @return void
1521
+	 * @throws EE_Error
1522
+	 * @throws ReflectionException
1523
+	 */
1524
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1525
+	{
1526
+		global $wpdb;
1527
+		self::drop_espresso_tables();
1528
+		$wp_options_to_delete = [
1529
+			'ee_no_ticket_prices'                        => true,
1530
+			'ee_active_messengers'                       => true,
1531
+			'ee_has_activated_messenger'                 => true,
1532
+			RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1533
+			'ee_config'                                  => false,
1534
+			'ee_data_migration_current_db_state'         => true,
1535
+			'ee_data_migration_mapping_'                 => false,
1536
+			'ee_data_migration_script_'                  => false,
1537
+			'ee_data_migrations'                         => true,
1538
+			'ee_dms_map'                                 => false,
1539
+			'ee_notices'                                 => true,
1540
+			'lang_file_check_'                           => false,
1541
+			'ee_maintenance_mode'                        => true,
1542
+			'ee_ueip_optin'                              => true,
1543
+			'ee_ueip_has_notified'                       => true,
1544
+			'ee_plugin_activation_errors'                => true,
1545
+			'ee_id_mapping_from'                         => false,
1546
+			'espresso_persistent_admin_notices'          => true,
1547
+			'ee_encryption_key'                          => true,
1548
+			'pue_force_upgrade_'                         => false,
1549
+			'pue_json_error_'                            => false,
1550
+			'pue_install_key_'                           => false,
1551
+			'pue_verification_error_'                    => false,
1552
+			'pu_dismissed_upgrade_'                      => false,
1553
+			'external_updates-'                          => false,
1554
+			'ee_extra_data'                              => true,
1555
+			'ee_ssn_'                                    => false,
1556
+			'ee_rss_'                                    => false,
1557
+			'ee_rte_n_tx_'                               => false,
1558
+			'ee_pers_admin_notices'                      => true,
1559
+			'ee_job_parameters_'                         => false,
1560
+			'ee_upload_directories_incomplete'           => true,
1561
+			'ee_verified_db_collations'                  => true,
1562
+		];
1563
+		if (is_main_site()) {
1564
+			$wp_options_to_delete['ee_network_config'] = true;
1565
+		}
1566
+		$undeleted_options = [];
1567
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1568
+			if ($no_wildcard) {
1569
+				if (! delete_option($option_name)) {
1570
+					$undeleted_options[] = $option_name;
1571
+				}
1572
+			} else {
1573
+				$option_names_to_delete_from_wildcard =
1574
+					$wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1575
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1576
+					if (! delete_option($option_name_from_wildcard)) {
1577
+						$undeleted_options[] = $option_name_from_wildcard;
1578
+					}
1579
+				}
1580
+			}
1581
+		}
1582
+		// also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1583
+		remove_action('shutdown', [EE_Config::instance(), 'shutdown']);
1584
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1585
+			$db_update_sans_ee4 = [];
1586
+			foreach ($espresso_db_update as $version => $times_activated) {
1587
+				if ((string) $version[0] === '3') {// if its NON EE4
1588
+					$db_update_sans_ee4[ $version ] = $times_activated;
1589
+				}
1590
+			}
1591
+			update_option('espresso_db_update', $db_update_sans_ee4);
1592
+		}
1593
+		$errors = '';
1594
+		if (! empty($undeleted_options)) {
1595
+			$errors .= sprintf(
1596
+				esc_html__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1597
+				'<br/>',
1598
+				implode(',<br/>', $undeleted_options)
1599
+			);
1600
+		}
1601
+		if (! empty($errors)) {
1602
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1603
+		}
1604
+	}
1605
+
1606
+
1607
+	/**
1608
+	 * Gets the mysql error code from the last used query by wpdb
1609
+	 *
1610
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1611
+	 */
1612
+	public static function last_wpdb_error_code()
1613
+	{
1614
+		// phpcs:disable PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
1615
+		global $wpdb;
1616
+		return $wpdb->use_mysqli ? mysqli_errno($wpdb->dbh) : 0;
1617
+		// phpcs:enable
1618
+	}
1619
+
1620
+
1621
+	/**
1622
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1623
+	 *
1624
+	 * @param string $table_name with or without $wpdb->prefix
1625
+	 * @return boolean
1626
+	 * @throws EE_Error
1627
+	 * @throws ReflectionException
1628
+	 * @global wpdb  $wpdb
1629
+	 * @deprecated instead use TableAnalysis::tableExists()
1630
+	 */
1631
+	public static function table_exists($table_name)
1632
+	{
1633
+		return EEH_Activation::getTableAnalysis()->tableExists($table_name);
1634
+	}
1635
+
1636
+
1637
+	/**
1638
+	 * Resets the cache on EEH_Activation
1639
+	 */
1640
+	public static function reset()
1641
+	{
1642
+		self::$_default_creator_id                             = null;
1643
+		self::$_initialized_db_content_already_in_this_request = false;
1644
+	}
1645
+
1646
+
1647
+	/**
1648
+	 * Removes 'email_confirm' from the Address info question group on activation
1649
+	 *
1650
+	 * @return void
1651
+	 * @throws EE_Error
1652
+	 */
1653
+	public static function removeEmailConfirmFromAddressGroup()
1654
+	{
1655
+
1656
+		// Pull the email_confirm question ID.
1657
+		$email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1658
+			EEM_Attendee::system_question_email_confirm
1659
+		);
1660
+		// Remove the email_confirm question group from the address group questions.
1661
+		EEM_Question_Group_Question::instance()->delete(
1662
+			[
1663
+				[
1664
+					'QST_ID'                    => $email_confirm_question_id,
1665
+					'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1666
+				],
1667
+			]
1668
+		);
1669
+	}
1670 1670
 }
Please login to merge, or discard this patch.
core/EE_Config.core.php 1 patch
Indentation   +3266 added lines, -3266 removed lines patch added patch discarded remove patch
@@ -18,2590 +18,2590 @@  discard block
 block discarded – undo
18 18
  */
19 19
 final class EE_Config implements ResettableInterface
20 20
 {
21
-    const OPTION_NAME = 'ee_config';
22
-
23
-    const LOG_NAME = 'ee_config_log';
24
-
25
-    const LOG_LENGTH = 100;
26
-
27
-    const ADDON_OPTION_NAMES = 'ee_config_option_names';
28
-
29
-    /**
30
-     *    instance of the EE_Config object
31
-     *
32
-     * @var    EE_Config $_instance
33
-     * @access    private
34
-     */
35
-    private static $_instance;
36
-
37
-    /**
38
-     * @var boolean $_logging_enabled
39
-     */
40
-    private static $_logging_enabled = false;
41
-
42
-    /**
43
-     * @var LegacyShortcodesManager $legacy_shortcodes_manager
44
-     */
45
-    private $legacy_shortcodes_manager;
46
-
47
-    /**
48
-     * An StdClass whose property names are addon slugs,
49
-     * and values are their config classes
50
-     *
51
-     * @var StdClass
52
-     */
53
-    public $addons;
54
-
55
-    /**
56
-     * @var EE_Admin_Config
57
-     */
58
-    public $admin;
59
-
60
-    /**
61
-     * @var EE_Core_Config
62
-     */
63
-    public $core;
64
-
65
-    /**
66
-     * @var EE_Currency_Config
67
-     */
68
-    public $currency;
69
-
70
-    /**
71
-     * @var EE_Organization_Config
72
-     */
73
-    public $organization;
74
-
75
-    /**
76
-     * @var EE_Registration_Config
77
-     */
78
-    public $registration;
79
-
80
-    /**
81
-     * @var EE_Template_Config
82
-     */
83
-    public $template_settings;
84
-
85
-    /**
86
-     * Holds EE environment values.
87
-     *
88
-     * @var EE_Environment_Config
89
-     */
90
-    public $environment;
91
-
92
-    /**
93
-     * settings pertaining to Google maps
94
-     *
95
-     * @var EE_Map_Config
96
-     */
97
-    public $map_settings;
98
-
99
-    /**
100
-     * settings pertaining to Taxes
101
-     *
102
-     * @var EE_Tax_Config
103
-     */
104
-    public $tax_settings;
105
-
106
-    /**
107
-     * Settings pertaining to global messages settings.
108
-     *
109
-     * @var EE_Messages_Config
110
-     */
111
-    public $messages;
112
-
113
-    /**
114
-     * @deprecated
115
-     * @var EE_Gateway_Config
116
-     */
117
-    public $gateway;
118
-
119
-    /**
120
-     * @var array
121
-     */
122
-    private $_addon_option_names = array();
123
-
124
-    /**
125
-     * @var array
126
-     */
127
-    private static $_module_route_map = array();
128
-
129
-    /**
130
-     * @var array
131
-     */
132
-    private static $_module_forward_map = array();
133
-
134
-    /**
135
-     * @var array
136
-     */
137
-    private static $_module_view_map = array();
138
-
139
-    /**
140
-     * @var bool
141
-     */
142
-    private static $initialized = false;
143
-
144
-
145
-    /**
146
-     * @singleton method used to instantiate class object
147
-     * @access    public
148
-     * @return EE_Config instance
149
-     */
150
-    public static function instance()
151
-    {
152
-        // check if class object is instantiated, and instantiated properly
153
-        if (! self::$_instance instanceof EE_Config) {
154
-            self::$_instance = new self();
155
-        }
156
-        return self::$_instance;
157
-    }
158
-
159
-
160
-    /**
161
-     * Resets the config
162
-     *
163
-     * @param bool    $hard_reset    if TRUE, sets EE_CONFig back to its original settings in the database. If FALSE
164
-     *                               (default) leaves the database alone, and merely resets the EE_Config object to
165
-     *                               reflect its state in the database
166
-     * @param boolean $reinstantiate if TRUE (default) call instance() and return it. Otherwise, just leave
167
-     *                               $_instance as NULL. Useful in case you want to forget about the old instance on
168
-     *                               EE_Config, but might not be ready to instantiate EE_Config currently (eg if the
169
-     *                               site was put into maintenance mode)
170
-     * @return EE_Config
171
-     */
172
-    public static function reset($hard_reset = false, $reinstantiate = true)
173
-    {
174
-        if (self::$_instance instanceof EE_Config) {
175
-            if ($hard_reset) {
176
-                self::$_instance->legacy_shortcodes_manager = null;
177
-                self::$_instance->_addon_option_names = array();
178
-                self::$_instance->_initialize_config();
179
-                self::$_instance->update_espresso_config();
180
-            }
181
-            self::$_instance->update_addon_option_names();
182
-        }
183
-        self::$_instance = null;
184
-        self::$initialized = false;
185
-        // we don't need to reset the static properties imo because those should
186
-        // only change when a module is added or removed. Currently we don't
187
-        // support removing a module during a request when it previously existed
188
-        if ($reinstantiate) {
189
-            return self::instance();
190
-        } else {
191
-            return null;
192
-        }
193
-    }
194
-
195
-
196
-    private function __construct()
197
-    {
198
-        if (self::$initialized) {
199
-            return;
200
-        }
201
-        self::$initialized = true;
202
-        do_action('AHEE__EE_Config__construct__begin', $this);
203
-        EE_Config::$_logging_enabled = apply_filters('FHEE__EE_Config___construct__logging_enabled', false);
204
-        // setup empty config classes
205
-        $this->_initialize_config();
206
-        // load existing EE site settings
207
-        $this->_load_core_config();
208
-        // confirm everything loaded correctly and set filtered defaults if not
209
-        $this->_verify_config();
210
-        //  register shortcodes and modules
211
-        add_action(
212
-            'AHEE__EE_System__register_shortcodes_modules_and_widgets',
213
-            [$this, 'register_shortcodes_and_modules'],
214
-            999
215
-        );
216
-        //  initialize shortcodes and modules
217
-        add_action('AHEE__EE_System__core_loaded_and_ready', [$this, 'initialize_shortcodes_and_modules']);
218
-        // register widgets
219
-        add_action('widgets_init', [$this, 'widgets_init'], 10);
220
-        // shutdown
221
-        add_action('shutdown', [$this, 'shutdown'], 10);
222
-        // construct__end hook
223
-        do_action('AHEE__EE_Config__construct__end', $this);
224
-        // hardcoded hack
225
-        $this->template_settings->current_espresso_theme = 'Espresso_Arabica_2014';
226
-    }
227
-
228
-
229
-    /**
230
-     * @return boolean
231
-     */
232
-    public static function logging_enabled()
233
-    {
234
-        return self::$_logging_enabled;
235
-    }
236
-
237
-
238
-    /**
239
-     * use to get the current theme if needed from static context
240
-     *
241
-     * @return string current theme set.
242
-     */
243
-    public static function get_current_theme()
244
-    {
245
-        return self::$_instance->template_settings->current_espresso_theme ?? 'Espresso_Arabica_2014';
246
-    }
247
-
248
-
249
-    /**
250
-     *        _initialize_config
251
-     *
252
-     * @access private
253
-     * @return void
254
-     */
255
-    private function _initialize_config()
256
-    {
257
-        EE_Config::trim_log();
258
-        // set defaults
259
-        $this->_addon_option_names = get_option(EE_Config::ADDON_OPTION_NAMES, array());
260
-        $this->addons = new stdClass();
261
-        // set _module_route_map
262
-        EE_Config::$_module_route_map = array();
263
-        // set _module_forward_map
264
-        EE_Config::$_module_forward_map = array();
265
-        // set _module_view_map
266
-        EE_Config::$_module_view_map = array();
267
-    }
268
-
269
-
270
-    /**
271
-     *        load core plugin configuration
272
-     *
273
-     * @access private
274
-     * @return void
275
-     */
276
-    private function _load_core_config()
277
-    {
278
-        // load_core_config__start hook
279
-        do_action('AHEE__EE_Config___load_core_config__start', $this);
280
-        $espresso_config = (array) $this->get_espresso_config();
281
-        // need to move the "addons" element to the end of the config array
282
-        // in case an addon config references one of the other config classes
283
-        $addons = $espresso_config['addons'] ?? new StdClass();
284
-        unset($espresso_config['addons']);
285
-        $espresso_config['addons'] = $addons;
286
-        foreach ($espresso_config as $config => $settings) {
287
-            // load_core_config__start hook
288
-            $settings = apply_filters(
289
-                'FHEE__EE_Config___load_core_config__config_settings',
290
-                $settings,
291
-                $config,
292
-                $this
293
-            );
294
-            if (is_object($settings) && property_exists($this, $config)) {
295
-                $this->{$config} = apply_filters('FHEE__EE_Config___load_core_config__' . $config, $settings);
296
-                // call configs populate method to ensure any defaults are set for empty values.
297
-                if (method_exists($settings, 'populate')) {
298
-                    $this->{$config}->populate();
299
-                }
300
-                if (method_exists($settings, 'do_hooks')) {
301
-                    $this->{$config}->do_hooks();
302
-                }
303
-            }
304
-        }
305
-        if (apply_filters('FHEE__EE_Config___load_core_config__update_espresso_config', false)) {
306
-            $this->update_espresso_config();
307
-        }
308
-        // load_core_config__end hook
309
-        do_action('AHEE__EE_Config___load_core_config__end', $this);
310
-    }
311
-
312
-
313
-    /**
314
-     *    _verify_config
315
-     *
316
-     * @access    protected
317
-     * @return    void
318
-     */
319
-    protected function _verify_config()
320
-    {
321
-        $this->core = $this->core instanceof EE_Core_Config
322
-            ? $this->core
323
-            : new EE_Core_Config();
324
-        $this->core = apply_filters('FHEE__EE_Config___initialize_config__core', $this->core);
325
-        $this->organization = $this->organization instanceof EE_Organization_Config
326
-            ? $this->organization
327
-            : new EE_Organization_Config();
328
-        $this->organization = apply_filters(
329
-            'FHEE__EE_Config___initialize_config__organization',
330
-            $this->organization
331
-        );
332
-        $this->currency = $this->currency instanceof EE_Currency_Config
333
-            ? $this->currency
334
-            : new EE_Currency_Config();
335
-        $this->currency = apply_filters('FHEE__EE_Config___initialize_config__currency', $this->currency);
336
-        $this->registration = $this->registration instanceof EE_Registration_Config
337
-            ? $this->registration
338
-            : new EE_Registration_Config();
339
-        $this->registration = apply_filters(
340
-            'FHEE__EE_Config___initialize_config__registration',
341
-            $this->registration
342
-        );
343
-        $this->admin = $this->admin instanceof EE_Admin_Config
344
-            ? $this->admin
345
-            : new EE_Admin_Config();
346
-        $this->admin = apply_filters('FHEE__EE_Config___initialize_config__admin', $this->admin);
347
-        $this->template_settings = $this->template_settings instanceof EE_Template_Config
348
-            ? $this->template_settings
349
-            : new EE_Template_Config();
350
-        $this->template_settings = apply_filters(
351
-            'FHEE__EE_Config___initialize_config__template_settings',
352
-            $this->template_settings
353
-        );
354
-        $this->map_settings = $this->map_settings instanceof EE_Map_Config
355
-            ? $this->map_settings
356
-            : new EE_Map_Config();
357
-        $this->map_settings = apply_filters(
358
-            'FHEE__EE_Config___initialize_config__map_settings',
359
-            $this->map_settings
360
-        );
361
-        $this->environment = $this->environment instanceof EE_Environment_Config
362
-            ? $this->environment
363
-            : new EE_Environment_Config();
364
-        $this->environment = apply_filters(
365
-            'FHEE__EE_Config___initialize_config__environment',
366
-            $this->environment
367
-        );
368
-        $this->tax_settings = $this->tax_settings instanceof EE_Tax_Config
369
-            ? $this->tax_settings
370
-            : new EE_Tax_Config();
371
-        $this->tax_settings = apply_filters(
372
-            'FHEE__EE_Config___initialize_config__tax_settings',
373
-            $this->tax_settings
374
-        );
375
-        $this->messages = apply_filters('FHEE__EE_Config__initialize_config__messages', $this->messages);
376
-        $this->messages = $this->messages instanceof EE_Messages_Config
377
-            ? $this->messages
378
-            : new EE_Messages_Config();
379
-        $this->gateway = $this->gateway instanceof EE_Gateway_Config
380
-            ? $this->gateway
381
-            : new EE_Gateway_Config();
382
-        $this->gateway = apply_filters('FHEE__EE_Config___initialize_config__gateway', $this->gateway);
383
-        $this->legacy_shortcodes_manager = null;
384
-    }
385
-
386
-
387
-    /**
388
-     *    get_espresso_config
389
-     *
390
-     * @access    public
391
-     * @return    array of espresso config stuff
392
-     */
393
-    public function get_espresso_config()
394
-    {
395
-        // grab espresso configuration
396
-        return apply_filters(
397
-            'FHEE__EE_Config__get_espresso_config__CFG',
398
-            get_option(EE_Config::OPTION_NAME, array())
399
-        );
400
-    }
401
-
402
-
403
-    /**
404
-     *    double_check_config_comparison
405
-     *
406
-     * @access    public
407
-     * @param string $option
408
-     * @param        $old_value
409
-     * @param        $value
410
-     */
411
-    public function double_check_config_comparison($option, $old_value, $value)
412
-    {
413
-        // make sure we're checking the ee config
414
-        if ($option === EE_Config::OPTION_NAME) {
415
-            // run a loose comparison of the old value against the new value for type and properties,
416
-            // but NOT exact instance like WP update_option does (ie: NOT type safe comparison)
417
-            if ($value != $old_value) {
418
-                // if they are NOT the same, then remove the hook,
419
-                // which means the subsequent update results will be based solely on the update query results
420
-                // the reason we do this is because, as stated above,
421
-                // WP update_option performs an exact instance comparison (===) on any update values passed to it
422
-                // this happens PRIOR to serialization and any subsequent update.
423
-                // If values are found to match their previous old value,
424
-                // then WP bails before performing any update.
425
-                // Since we are passing the EE_Config object, it is comparing the EXACT instance of the saved version
426
-                // it just pulled from the db, with the one being passed to it (which will not match).
427
-                // HOWEVER, once the object is serialized and passed off to MySQL to update,
428
-                // MySQL MAY ALSO NOT perform the update because
429
-                // the string it sees in the db looks the same as the new one it has been passed!!!
430
-                // This results in the query returning an "affected rows" value of ZERO,
431
-                // which gets returned immediately by WP update_option and looks like an error.
432
-                remove_action('update_option', array($this, 'check_config_updated'));
433
-            }
434
-        }
435
-    }
436
-
437
-
438
-    /**
439
-     *    update_espresso_config
440
-     *
441
-     * @access   public
442
-     */
443
-    protected function _reset_espresso_addon_config()
444
-    {
445
-        $this->_addon_option_names = array();
446
-        foreach ($this->addons as $addon_name => $addon_config_obj) {
447
-            $addon_config_obj = maybe_unserialize($addon_config_obj);
448
-            if ($addon_config_obj instanceof EE_Config_Base) {
449
-                $this->update_config('addons', $addon_name, $addon_config_obj, false);
450
-            }
451
-            $this->addons->{$addon_name} = null;
452
-        }
453
-    }
454
-
455
-
456
-    /**
457
-     *    update_espresso_config
458
-     *
459
-     * @access   public
460
-     * @param   bool $add_success
461
-     * @param   bool $add_error
462
-     * @return   bool
463
-     */
464
-    public function update_espresso_config($add_success = false, $add_error = true)
465
-    {
466
-        // don't allow config updates during WP heartbeats
467
-        /** @var RequestInterface $request */
468
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
469
-        if ($request->isWordPressHeartbeat()) {
470
-            return false;
471
-        }
472
-        // commented out the following re: https://events.codebasehq.com/projects/event-espresso/tickets/8197
473
-        // $clone = clone( self::$_instance );
474
-        // self::$_instance = NULL;
475
-        do_action('AHEE__EE_Config__update_espresso_config__begin', $this);
476
-        $this->_reset_espresso_addon_config();
477
-        // hook into update_option because that happens AFTER the ( $value === $old_value ) conditional
478
-        // but BEFORE the actual update occurs
479
-        add_action('update_option', array($this, 'double_check_config_comparison'), 1, 3);
480
-        // don't want to persist legacy_shortcodes_manager, but don't want to lose it either
481
-        $legacy_shortcodes_manager = $this->legacy_shortcodes_manager;
482
-        $this->legacy_shortcodes_manager = null;
483
-        // now update "ee_config"
484
-        $saved = update_option(EE_Config::OPTION_NAME, $this);
485
-        $this->legacy_shortcodes_manager = $legacy_shortcodes_manager;
486
-        EE_Config::log(EE_Config::OPTION_NAME);
487
-        // if not saved... check if the hook we just added still exists;
488
-        // if it does, it means one of two things:
489
-        // that update_option bailed at the($value === $old_value) conditional,
490
-        // or...
491
-        // the db update query returned 0 rows affected
492
-        // (probably because the data  value was the same from it's perspective)
493
-        // so the existence of the hook means that a negative result from update_option is NOT an error,
494
-        // but just means no update occurred, so don't display an error to the user.
495
-        // BUT... if update_option returns FALSE, AND the hook is missing,
496
-        // then it means that something truly went wrong
497
-        $saved = ! $saved ? has_action('update_option', array($this, 'double_check_config_comparison')) : $saved;
498
-        // remove our action since we don't want it in the system anymore
499
-        remove_action('update_option', array($this, 'double_check_config_comparison'), 1);
500
-        do_action('AHEE__EE_Config__update_espresso_config__end', $this, $saved);
501
-        // self::$_instance = $clone;
502
-        // unset( $clone );
503
-        // if config remains the same or was updated successfully
504
-        if ($saved) {
505
-            if ($add_success) {
506
-                EE_Error::add_success(
507
-                    esc_html__('The Event Espresso Configuration Settings have been successfully updated.', 'event_espresso'),
508
-                    __FILE__,
509
-                    __FUNCTION__,
510
-                    __LINE__
511
-                );
512
-            }
513
-            return true;
514
-        } else {
515
-            if ($add_error) {
516
-                EE_Error::add_error(
517
-                    esc_html__('The Event Espresso Configuration Settings were not updated.', 'event_espresso'),
518
-                    __FILE__,
519
-                    __FUNCTION__,
520
-                    __LINE__
521
-                );
522
-            }
523
-            return false;
524
-        }
525
-    }
526
-
527
-
528
-    /**
529
-     *    _verify_config_params
530
-     *
531
-     * @access    private
532
-     * @param    string         $section
533
-     * @param    string         $name
534
-     * @param    string         $config_class
535
-     * @param    EE_Config_Base $config_obj
536
-     * @param    array          $tests_to_run
537
-     * @param    bool           $display_errors
538
-     * @return    bool    TRUE on success, FALSE on fail
539
-     */
540
-    private function _verify_config_params(
541
-        $section = '',
542
-        $name = '',
543
-        $config_class = '',
544
-        $config_obj = null,
545
-        $tests_to_run = array(1, 2, 3, 4, 5, 6, 7, 8),
546
-        $display_errors = true
547
-    ) {
548
-        try {
549
-            foreach ($tests_to_run as $test) {
550
-                switch ($test) {
551
-                    // TEST #1 : check that section was set
552
-                    case 1:
553
-                        if (empty($section)) {
554
-                            if ($display_errors) {
555
-                                throw new EE_Error(
556
-                                    sprintf(
557
-                                        esc_html__(
558
-                                            'No configuration section has been provided while attempting to save "%s".',
559
-                                            'event_espresso'
560
-                                        ),
561
-                                        $config_class
562
-                                    )
563
-                                );
564
-                            }
565
-                            return false;
566
-                        }
567
-                        break;
568
-                    // TEST #2 : check that settings section exists
569
-                    case 2:
570
-                        if (! isset($this->{$section})) {
571
-                            if ($display_errors) {
572
-                                throw new EE_Error(
573
-                                    sprintf(
574
-                                        esc_html__('The "%s" configuration section does not exist.', 'event_espresso'),
575
-                                        $section
576
-                                    )
577
-                                );
578
-                            }
579
-                            return false;
580
-                        }
581
-                        break;
582
-                    // TEST #3 : check that section is the proper format
583
-                    case 3:
584
-                        if (
585
-                            ! ($this->{$section} instanceof EE_Config_Base || $this->{$section} instanceof stdClass)
586
-                        ) {
587
-                            if ($display_errors) {
588
-                                throw new EE_Error(
589
-                                    sprintf(
590
-                                        esc_html__(
591
-                                            'The "%s" configuration settings have not been formatted correctly.',
592
-                                            'event_espresso'
593
-                                        ),
594
-                                        $section
595
-                                    )
596
-                                );
597
-                            }
598
-                            return false;
599
-                        }
600
-                        break;
601
-                    // TEST #4 : check that config section name has been set
602
-                    case 4:
603
-                        if (empty($name)) {
604
-                            if ($display_errors) {
605
-                                throw new EE_Error(
606
-                                    esc_html__(
607
-                                        'No name has been provided for the specific configuration section.',
608
-                                        'event_espresso'
609
-                                    )
610
-                                );
611
-                            }
612
-                            return false;
613
-                        }
614
-                        break;
615
-                    // TEST #5 : check that a config class name has been set
616
-                    case 5:
617
-                        if (empty($config_class)) {
618
-                            if ($display_errors) {
619
-                                throw new EE_Error(
620
-                                    esc_html__(
621
-                                        'No class name has been provided for the specific configuration section.',
622
-                                        'event_espresso'
623
-                                    )
624
-                                );
625
-                            }
626
-                            return false;
627
-                        }
628
-                        break;
629
-                    // TEST #6 : verify config class is accessible
630
-                    case 6:
631
-                        if (! class_exists($config_class)) {
632
-                            if ($display_errors) {
633
-                                throw new EE_Error(
634
-                                    sprintf(
635
-                                        esc_html__(
636
-                                            'The "%s" class does not exist. Please ensure that an autoloader has been set for it.',
637
-                                            'event_espresso'
638
-                                        ),
639
-                                        $config_class
640
-                                    )
641
-                                );
642
-                            }
643
-                            return false;
644
-                        }
645
-                        break;
646
-                    // TEST #7 : check that config has even been set
647
-                    case 7:
648
-                        if (! isset($this->{$section}->{$name})) {
649
-                            if ($display_errors) {
650
-                                throw new EE_Error(
651
-                                    sprintf(
652
-                                        esc_html__('No configuration has been set for "%1$s->%2$s".', 'event_espresso'),
653
-                                        $section,
654
-                                        $name
655
-                                    )
656
-                                );
657
-                            }
658
-                            return false;
659
-                        } else {
660
-                            // and make sure it's not serialized
661
-                            $this->{$section}->{$name} = maybe_unserialize($this->{$section}->{$name});
662
-                        }
663
-                        break;
664
-                    // TEST #8 : check that config is the requested type
665
-                    case 8:
666
-                        if (! $this->{$section}->{$name} instanceof $config_class) {
667
-                            if ($display_errors) {
668
-                                throw new EE_Error(
669
-                                    sprintf(
670
-                                        esc_html__(
671
-                                            'The configuration for "%1$s->%2$s" is not of the "%3$s" class.',
672
-                                            'event_espresso'
673
-                                        ),
674
-                                        $section,
675
-                                        $name,
676
-                                        $config_class
677
-                                    )
678
-                                );
679
-                            }
680
-                            return false;
681
-                        }
682
-                        break;
683
-                    // TEST #9 : verify config object
684
-                    case 9:
685
-                        if (! $config_obj instanceof EE_Config_Base) {
686
-                            if ($display_errors) {
687
-                                throw new EE_Error(
688
-                                    sprintf(
689
-                                        esc_html__('The "%s" class is not an instance of EE_Config_Base.', 'event_espresso'),
690
-                                        print_r($config_obj, true)
691
-                                    )
692
-                                );
693
-                            }
694
-                            return false;
695
-                        }
696
-                        break;
697
-                }
698
-            }
699
-        } catch (EE_Error $e) {
700
-            $e->get_error();
701
-        }
702
-        // you have successfully run the gauntlet
703
-        return true;
704
-    }
705
-
706
-
707
-    /**
708
-     *    _generate_config_option_name
709
-     *
710
-     * @access        protected
711
-     * @param        string $section
712
-     * @param        string $name
713
-     * @return        string
714
-     */
715
-    private function _generate_config_option_name($section = '', $name = '')
716
-    {
717
-        return 'ee_config-' . strtolower($section . '-' . str_replace(array('EE_', 'EED_'), '', $name));
718
-    }
719
-
720
-
721
-    /**
722
-     *    _set_config_class
723
-     * ensures that a config class is set, either from a passed config class or one generated from the config name
724
-     *
725
-     * @access    private
726
-     * @param    string $config_class
727
-     * @param    string $name
728
-     * @return    string
729
-     */
730
-    private function _set_config_class($config_class = '', $name = '')
731
-    {
732
-        return ! empty($config_class)
733
-            ? $config_class
734
-            : str_replace(' ', '_', ucwords(str_replace('_', ' ', $name))) . '_Config';
735
-    }
736
-
737
-
738
-    /**
739
-     *    set_config
740
-     *
741
-     * @access    protected
742
-     * @param    string         $section
743
-     * @param    string         $name
744
-     * @param    string         $config_class
745
-     * @param    EE_Config_Base $config_obj
746
-     * @return    EE_Config_Base
747
-     */
748
-    public function set_config($section = '', $name = '', $config_class = '', EE_Config_Base $config_obj = null)
749
-    {
750
-        // ensure config class is set to something
751
-        $config_class = $this->_set_config_class($config_class, $name);
752
-        // run tests 1-4, 6, and 7 to verify all config params are set and valid
753
-        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
754
-            return null;
755
-        }
756
-        $config_option_name = $this->_generate_config_option_name($section, $name);
757
-        // if the config option name hasn't been added yet to the list of option names we're tracking, then do so now
758
-        if (! isset($this->_addon_option_names[ $config_option_name ])) {
759
-            $this->_addon_option_names[ $config_option_name ] = $config_class;
760
-            $this->update_addon_option_names();
761
-        }
762
-        // verify the incoming config object but suppress errors
763
-        if (! $this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
764
-            $config_obj = new $config_class();
765
-        }
766
-        if (get_option($config_option_name)) {
767
-            EE_Config::log($config_option_name);
768
-            update_option($config_option_name, $config_obj);
769
-            $this->{$section}->{$name} = $config_obj;
770
-            return $this->{$section}->{$name};
771
-        } else {
772
-            // create a wp-option for this config
773
-            if (add_option($config_option_name, $config_obj, '', 'no')) {
774
-                $this->{$section}->{$name} = maybe_unserialize($config_obj);
775
-                return $this->{$section}->{$name};
776
-            } else {
777
-                EE_Error::add_error(
778
-                    sprintf(esc_html__('The "%s" could not be saved to the database.', 'event_espresso'), $config_class),
779
-                    __FILE__,
780
-                    __FUNCTION__,
781
-                    __LINE__
782
-                );
783
-                return null;
784
-            }
785
-        }
786
-    }
787
-
788
-
789
-    /**
790
-     *    update_config
791
-     * Important: the config object must ALREADY be set, otherwise this will produce an error.
792
-     *
793
-     * @access    public
794
-     * @param    string                $section
795
-     * @param    string                $name
796
-     * @param    EE_Config_Base|string $config_obj
797
-     * @param    bool                  $throw_errors
798
-     * @return    bool
799
-     */
800
-    public function update_config($section = '', $name = '', $config_obj = '', $throw_errors = true)
801
-    {
802
-        // don't allow config updates during WP heartbeats
803
-        /** @var RequestInterface $request */
804
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
805
-        if ($request->isWordPressHeartbeat()) {
806
-            return false;
807
-        }
808
-        $config_obj = maybe_unserialize($config_obj);
809
-        // get class name of the incoming object
810
-        $config_class = get_class($config_obj);
811
-        // run tests 1-5 and 9 to verify config
812
-        if (
813
-            ! $this->_verify_config_params(
814
-                $section,
815
-                $name,
816
-                $config_class,
817
-                $config_obj,
818
-                array(1, 2, 3, 4, 7, 9)
819
-            )
820
-        ) {
821
-            return false;
822
-        }
823
-        $config_option_name = $this->_generate_config_option_name($section, $name);
824
-        // check if config object has been added to db by seeing if config option name is in $this->_addon_option_names array
825
-        if (! isset($this->_addon_option_names[ $config_option_name ])) {
826
-            // save new config to db
827
-            if ($this->set_config($section, $name, $config_class, $config_obj)) {
828
-                return true;
829
-            }
830
-        } else {
831
-            // first check if the record already exists
832
-            $existing_config = get_option($config_option_name);
833
-            $config_obj = serialize($config_obj);
834
-            // just return if db record is already up to date (NOT type safe comparison)
835
-            if ($existing_config == $config_obj) {
836
-                $this->{$section}->{$name} = $config_obj;
837
-                return true;
838
-            } elseif (update_option($config_option_name, $config_obj)) {
839
-                EE_Config::log($config_option_name);
840
-                // update wp-option for this config class
841
-                $this->{$section}->{$name} = $config_obj;
842
-                return true;
843
-            } elseif ($throw_errors) {
844
-                EE_Error::add_error(
845
-                    sprintf(
846
-                        esc_html__(
847
-                            'The "%1$s" object stored at"%2$s" was not successfully updated in the database.',
848
-                            'event_espresso'
849
-                        ),
850
-                        $config_class,
851
-                        'EE_Config->' . $section . '->' . $name
852
-                    ),
853
-                    __FILE__,
854
-                    __FUNCTION__,
855
-                    __LINE__
856
-                );
857
-            }
858
-        }
859
-        return false;
860
-    }
861
-
862
-
863
-    /**
864
-     *    get_config
865
-     *
866
-     * @access    public
867
-     * @param    string $section
868
-     * @param    string $name
869
-     * @param    string $config_class
870
-     * @return    mixed EE_Config_Base | NULL
871
-     */
872
-    public function get_config($section = '', $name = '', $config_class = '')
873
-    {
874
-        // ensure config class is set to something
875
-        $config_class = $this->_set_config_class($config_class, $name);
876
-        // run tests 1-4, 6 and 7 to verify that all params have been set
877
-        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
878
-            return null;
879
-        }
880
-        // now test if the requested config object exists, but suppress errors
881
-        if ($this->_verify_config_params($section, $name, $config_class, null, array(7, 8), false)) {
882
-            // config already exists, so pass it back
883
-            return $this->{$section}->{$name};
884
-        }
885
-        // load config option from db if it exists
886
-        $config_obj = $this->get_config_option($this->_generate_config_option_name($section, $name));
887
-        // verify the newly retrieved config object, but suppress errors
888
-        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
889
-            // config is good, so set it and pass it back
890
-            $this->{$section}->{$name} = $config_obj;
891
-            return $this->{$section}->{$name};
892
-        }
893
-        // oops! $config_obj is not already set and does not exist in the db, so create a new one
894
-        $config_obj = $this->set_config($section, $name, $config_class);
895
-        // verify the newly created config object
896
-        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9))) {
897
-            return $this->{$section}->{$name};
898
-        } else {
899
-            EE_Error::add_error(
900
-                sprintf(esc_html__('The "%s" could not be retrieved from the database.', 'event_espresso'), $config_class),
901
-                __FILE__,
902
-                __FUNCTION__,
903
-                __LINE__
904
-            );
905
-        }
906
-        return null;
907
-    }
908
-
909
-
910
-    /**
911
-     *    get_config_option
912
-     *
913
-     * @access    public
914
-     * @param    string $config_option_name
915
-     * @return    mixed EE_Config_Base | FALSE
916
-     */
917
-    public function get_config_option($config_option_name = '')
918
-    {
919
-        // retrieve the wp-option for this config class.
920
-        $config_option = maybe_unserialize(get_option($config_option_name, array()));
921
-        if (empty($config_option)) {
922
-            EE_Config::log($config_option_name . '-NOT-FOUND');
923
-        }
924
-        return $config_option;
925
-    }
926
-
927
-
928
-    /**
929
-     * log
930
-     *
931
-     * @param string $config_option_name
932
-     */
933
-    public static function log($config_option_name = '')
934
-    {
935
-        if (EE_Config::logging_enabled() && ! empty($config_option_name)) {
936
-            $config_log = get_option(EE_Config::LOG_NAME, array());
937
-            /** @var RequestParams $request */
938
-            $request = LoaderFactory::getLoader()->getShared(RequestParams::class);
939
-            $config_log[ (string) microtime(true) ] = array(
940
-                'config_name' => $config_option_name,
941
-                'request'     => $request->requestParams(),
942
-            );
943
-            update_option(EE_Config::LOG_NAME, $config_log);
944
-        }
945
-    }
946
-
947
-
948
-    /**
949
-     * trim_log
950
-     * reduces the size of the config log to the length specified by EE_Config::LOG_LENGTH
951
-     */
952
-    public static function trim_log()
953
-    {
954
-        if (! EE_Config::logging_enabled()) {
955
-            return;
956
-        }
957
-        $config_log = maybe_unserialize(get_option(EE_Config::LOG_NAME, array()));
958
-        $log_length = count($config_log);
959
-        if ($log_length > EE_Config::LOG_LENGTH) {
960
-            ksort($config_log);
961
-            $config_log = array_slice($config_log, $log_length - EE_Config::LOG_LENGTH, null, true);
962
-            update_option(EE_Config::LOG_NAME, $config_log);
963
-        }
964
-    }
965
-
966
-
967
-    /**
968
-     *    get_page_for_posts
969
-     *    if the wp-option "show_on_front" is set to "page", then this is the post_name for the post set in the
970
-     *    wp-option "page_for_posts", or "posts" if no page is selected
971
-     *
972
-     * @access    public
973
-     * @return    string
974
-     */
975
-    public static function get_page_for_posts()
976
-    {
977
-        $page_for_posts = get_option('page_for_posts');
978
-        if (! $page_for_posts) {
979
-            return 'posts';
980
-        }
981
-        global $wpdb;
982
-        $SQL = "SELECT post_name from $wpdb->posts WHERE post_type='posts' OR post_type='page' AND post_status='publish' AND ID=%d";
983
-        return $wpdb->get_var($wpdb->prepare($SQL, $page_for_posts));
984
-    }
985
-
986
-
987
-    /**
988
-     *    register_shortcodes_and_modules.
989
-     *    At this point, it's too early to tell if we're maintenance mode or not.
990
-     *    In fact, this is where we give modules a chance to let core know they exist
991
-     *    so they can help trigger maintenance mode if it's needed
992
-     *
993
-     * @access    public
994
-     * @return    void
995
-     */
996
-    public function register_shortcodes_and_modules()
997
-    {
998
-        // allow modules to set hooks for the rest of the system
999
-        EE_Registry::instance()->modules = $this->_register_modules();
1000
-    }
1001
-
1002
-
1003
-    /**
1004
-     *    initialize_shortcodes_and_modules
1005
-     *    meaning they can start adding their hooks to get stuff done
1006
-     *
1007
-     * @access    public
1008
-     * @return    void
1009
-     */
1010
-    public function initialize_shortcodes_and_modules()
1011
-    {
1012
-        // allow modules to set hooks for the rest of the system
1013
-        $this->_initialize_modules();
1014
-    }
1015
-
1016
-
1017
-    /**
1018
-     *    widgets_init
1019
-     *
1020
-     * @access private
1021
-     * @return void
1022
-     */
1023
-    public function widgets_init()
1024
-    {
1025
-        // only init widgets on admin pages when not in complete maintenance, and
1026
-        // on frontend when not in any maintenance mode
1027
-        if (
1028
-            ! EE_Maintenance_Mode::instance()->level()
1029
-            || (
1030
-                is_admin()
1031
-                && EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance
1032
-            )
1033
-        ) {
1034
-            // grab list of installed widgets
1035
-            $widgets_to_register = glob(EE_WIDGETS . '*', GLOB_ONLYDIR);
1036
-            // filter list of modules to register
1037
-            $widgets_to_register = apply_filters(
1038
-                'FHEE__EE_Config__register_widgets__widgets_to_register',
1039
-                $widgets_to_register
1040
-            );
1041
-            if (! empty($widgets_to_register)) {
1042
-                // cycle thru widget folders
1043
-                foreach ($widgets_to_register as $widget_path) {
1044
-                    // add to list of installed widget modules
1045
-                    EE_Config::register_ee_widget($widget_path);
1046
-                }
1047
-            }
1048
-            // filter list of installed modules
1049
-            EE_Registry::instance()->widgets = apply_filters(
1050
-                'FHEE__EE_Config__register_widgets__installed_widgets',
1051
-                EE_Registry::instance()->widgets
1052
-            );
1053
-        }
1054
-    }
1055
-
1056
-
1057
-    /**
1058
-     *    register_ee_widget - makes core aware of this widget
1059
-     *
1060
-     * @access    public
1061
-     * @param    string $widget_path - full path up to and including widget folder
1062
-     * @return    void
1063
-     */
1064
-    public static function register_ee_widget($widget_path = null)
1065
-    {
1066
-        do_action('AHEE__EE_Config__register_widget__begin', $widget_path);
1067
-        $widget_ext = '.widget.php';
1068
-        // make all separators match
1069
-        $widget_path = rtrim(str_replace('\\', DS, $widget_path), DS);
1070
-        // does the file path INCLUDE the actual file name as part of the path ?
1071
-        if (strpos($widget_path, $widget_ext) !== false) {
1072
-            // grab and shortcode file name from directory name and break apart at dots
1073
-            $file_name = explode('.', basename($widget_path));
1074
-            // take first segment from file name pieces and remove class prefix if it exists
1075
-            $widget = strpos($file_name[0], 'EEW_') === 0 ? substr($file_name[0], 4) : $file_name[0];
1076
-            // sanitize shortcode directory name
1077
-            $widget = sanitize_key($widget);
1078
-            // now we need to rebuild the shortcode path
1079
-            $widget_path = explode('/', $widget_path);
1080
-            // remove last segment
1081
-            array_pop($widget_path);
1082
-            // glue it back together
1083
-            $widget_path = implode(DS, $widget_path);
1084
-        } else {
1085
-            // grab and sanitize widget directory name
1086
-            $widget = sanitize_key(basename($widget_path));
1087
-        }
1088
-        // create classname from widget directory name
1089
-        $widget = str_replace(' ', '_', ucwords(str_replace('_', ' ', $widget)));
1090
-        // add class prefix
1091
-        $widget_class = 'EEW_' . $widget;
1092
-        // does the widget exist ?
1093
-        if (! is_readable($widget_path . '/' . $widget_class . $widget_ext)) {
1094
-            $msg = sprintf(
1095
-                esc_html__(
1096
-                    'The requested %s widget file could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s',
1097
-                    'event_espresso'
1098
-                ),
1099
-                $widget_class,
1100
-                $widget_path . '/' . $widget_class . $widget_ext
1101
-            );
1102
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1103
-            return;
1104
-        }
1105
-        // load the widget class file
1106
-        require_once($widget_path . '/' . $widget_class . $widget_ext);
1107
-        // verify that class exists
1108
-        if (! class_exists($widget_class)) {
1109
-            $msg = sprintf(esc_html__('The requested %s widget class does not exist.', 'event_espresso'), $widget_class);
1110
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1111
-            return;
1112
-        }
1113
-        register_widget($widget_class);
1114
-        // add to array of registered widgets
1115
-        EE_Registry::instance()->widgets->{$widget_class} = $widget_path . '/' . $widget_class . $widget_ext;
1116
-    }
1117
-
1118
-
1119
-    /**
1120
-     *        _register_modules
1121
-     *
1122
-     * @access private
1123
-     * @return array
1124
-     */
1125
-    private function _register_modules()
1126
-    {
1127
-        // grab list of installed modules
1128
-        $modules_to_register = glob(EE_MODULES . '*', GLOB_ONLYDIR);
1129
-        // filter list of modules to register
1130
-        $modules_to_register = apply_filters(
1131
-            'FHEE__EE_Config__register_modules__modules_to_register',
1132
-            $modules_to_register
1133
-        );
1134
-        if (! empty($modules_to_register)) {
1135
-            // loop through folders
1136
-            foreach ($modules_to_register as $module_path) {
1137
-                /**TEMPORARILY EXCLUDE gateways from modules for time being**/
1138
-                if (
1139
-                    $module_path !== EE_MODULES . 'zzz-copy-this-module-template'
1140
-                    && $module_path !== EE_MODULES . 'gateways'
1141
-                ) {
1142
-                    // add to list of installed modules
1143
-                    EE_Config::register_module($module_path);
1144
-                }
1145
-            }
1146
-        }
1147
-        // filter list of installed modules
1148
-        return apply_filters(
1149
-            'FHEE__EE_Config___register_modules__installed_modules',
1150
-            EE_Registry::instance()->modules
1151
-        );
1152
-    }
1153
-
1154
-
1155
-    /**
1156
-     *    register_module - makes core aware of this module
1157
-     *
1158
-     * @access    public
1159
-     * @param    string $module_path - full path up to and including module folder
1160
-     * @return    bool
1161
-     */
1162
-    public static function register_module($module_path = null)
1163
-    {
1164
-        do_action('AHEE__EE_Config__register_module__begin', $module_path);
1165
-        $module_ext = '.module.php';
1166
-        // make all separators match
1167
-        $module_path = str_replace(array('\\', '/'), '/', $module_path);
1168
-        // does the file path INCLUDE the actual file name as part of the path ?
1169
-        if (strpos($module_path, $module_ext) !== false) {
1170
-            // grab and shortcode file name from directory name and break apart at dots
1171
-            $module_file = explode('.', basename($module_path));
1172
-            // now we need to rebuild the shortcode path
1173
-            $module_path = explode('/', $module_path);
1174
-            // remove last segment
1175
-            array_pop($module_path);
1176
-            // glue it back together
1177
-            $module_path = implode('/', $module_path) . '/';
1178
-            // take first segment from file name pieces and sanitize it
1179
-            $module = preg_replace('/[^a-zA-Z0-9_\-]/', '', $module_file[0]);
1180
-            // ensure class prefix is added
1181
-            $module_class = strpos($module, 'EED_') !== 0 ? 'EED_' . $module : $module;
1182
-        } else {
1183
-            // we need to generate the filename based off of the folder name
1184
-            // grab and sanitize module name
1185
-            $module = strtolower(basename($module_path));
1186
-            $module = preg_replace('/[^a-z0-9_\-]/', '', $module);
1187
-            // like trailingslashit()
1188
-            $module_path = rtrim($module_path, '/') . '/';
1189
-            // create classname from module directory name
1190
-            $module = str_replace(' ', '_', ucwords(str_replace('_', ' ', $module)));
1191
-            // add class prefix
1192
-            $module_class = 'EED_' . $module;
1193
-        }
1194
-        // does the module exist ?
1195
-        if (! is_readable($module_path . '/' . $module_class . $module_ext)) {
1196
-            $msg = sprintf(
1197
-                esc_html__(
1198
-                    'The requested %s module file could not be found or is not readable due to file permissions.',
1199
-                    'event_espresso'
1200
-                ),
1201
-                $module
1202
-            );
1203
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1204
-            return false;
1205
-        }
1206
-        // load the module class file
1207
-        require_once($module_path . $module_class . $module_ext);
1208
-        // verify that class exists
1209
-        if (! class_exists($module_class)) {
1210
-            $msg = sprintf(esc_html__('The requested %s module class does not exist.', 'event_espresso'), $module_class);
1211
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1212
-            return false;
1213
-        }
1214
-        // add to array of registered modules
1215
-        EE_Registry::instance()->modules->{$module_class} = $module_path . $module_class . $module_ext;
1216
-        do_action(
1217
-            'AHEE__EE_Config__register_module__complete',
1218
-            $module_class,
1219
-            EE_Registry::instance()->modules->{$module_class}
1220
-        );
1221
-        return true;
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     *    _initialize_modules
1227
-     *    allow modules to set hooks for the rest of the system
1228
-     *
1229
-     * @access private
1230
-     * @return void
1231
-     */
1232
-    private function _initialize_modules()
1233
-    {
1234
-        // cycle thru shortcode folders
1235
-        foreach (EE_Registry::instance()->modules as $module_class => $module_path) {
1236
-            // fire the shortcode class's set_hooks methods in case it needs to hook into other parts of the system
1237
-            // which set hooks ?
1238
-            if (is_admin()) {
1239
-                // fire immediately
1240
-                call_user_func(array($module_class, 'set_hooks_admin'));
1241
-            } else {
1242
-                // delay until other systems are online
1243
-                add_action(
1244
-                    'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons',
1245
-                    array($module_class, 'set_hooks')
1246
-                );
1247
-            }
1248
-        }
1249
-    }
1250
-
1251
-
1252
-    /**
1253
-     *    register_route - adds module method routes to route_map
1254
-     *
1255
-     * @access    public
1256
-     * @param    string $route       - "pretty" public alias for module method
1257
-     * @param    string $module      - module name (classname without EED_ prefix)
1258
-     * @param    string $method_name - the actual module method to be routed to
1259
-     * @param    string $key         - url param key indicating a route is being called
1260
-     * @return    bool
1261
-     */
1262
-    public static function register_route($route = null, $module = null, $method_name = null, $key = 'ee')
1263
-    {
1264
-        do_action('AHEE__EE_Config__register_route__begin', $route, $module, $method_name);
1265
-        $module = str_replace('EED_', '', $module);
1266
-        $module_class = 'EED_' . $module;
1267
-        if (! isset(EE_Registry::instance()->modules->{$module_class})) {
1268
-            $msg = sprintf(esc_html__('The module %s has not been registered.', 'event_espresso'), $module);
1269
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1270
-            return false;
1271
-        }
1272
-        if (empty($route)) {
1273
-            $msg = sprintf(esc_html__('No route has been supplied.', 'event_espresso'), $route);
1274
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1275
-            return false;
1276
-        }
1277
-        if (! method_exists('EED_' . $module, $method_name)) {
1278
-            $msg = sprintf(
1279
-                esc_html__('A valid class method for the %s route has not been supplied.', 'event_espresso'),
1280
-                $route
1281
-            );
1282
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1283
-            return false;
1284
-        }
1285
-        EE_Config::$_module_route_map[ (string) $key ][ (string) $route ] = array('EED_' . $module, $method_name);
1286
-        return true;
1287
-    }
1288
-
1289
-
1290
-    /**
1291
-     *    get_route - get module method route
1292
-     *
1293
-     * @access    public
1294
-     * @param    string $route - "pretty" public alias for module method
1295
-     * @param    string $key   - url param key indicating a route is being called
1296
-     * @return    string
1297
-     */
1298
-    public static function get_route($route = null, $key = 'ee')
1299
-    {
1300
-        do_action('AHEE__EE_Config__get_route__begin', $route);
1301
-        $route = (string) apply_filters('FHEE__EE_Config__get_route', $route);
1302
-        if (isset(EE_Config::$_module_route_map[ $key ][ $route ])) {
1303
-            return EE_Config::$_module_route_map[ $key ][ $route ];
1304
-        }
1305
-        return null;
1306
-    }
1307
-
1308
-
1309
-    /**
1310
-     *    get_routes - get ALL module method routes
1311
-     *
1312
-     * @access    public
1313
-     * @return    array
1314
-     */
1315
-    public static function get_routes()
1316
-    {
1317
-        return EE_Config::$_module_route_map;
1318
-    }
1319
-
1320
-
1321
-    /**
1322
-     *    register_forward - allows modules to forward request to another module for further processing
1323
-     *
1324
-     * @access    public
1325
-     * @param    string       $route   - "pretty" public alias for module method
1326
-     * @param    integer      $status  - integer value corresponding  to status constant strings set in module parent
1327
-     *                                 class, allows different forwards to be served based on status
1328
-     * @param    array|string $forward - function name or array( class, method )
1329
-     * @param    string       $key     - url param key indicating a route is being called
1330
-     * @return    bool
1331
-     */
1332
-    public static function register_forward($route = null, $status = 0, $forward = null, $key = 'ee')
1333
-    {
1334
-        do_action('AHEE__EE_Config__register_forward', $route, $status, $forward);
1335
-        if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1336
-            $msg = sprintf(
1337
-                esc_html__('The module route %s for this forward has not been registered.', 'event_espresso'),
1338
-                $route
1339
-            );
1340
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1341
-            return false;
1342
-        }
1343
-        if (empty($forward)) {
1344
-            $msg = sprintf(esc_html__('No forwarding route has been supplied.', 'event_espresso'), $route);
1345
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1346
-            return false;
1347
-        }
1348
-        if (is_array($forward)) {
1349
-            if (! isset($forward[1])) {
1350
-                $msg = sprintf(
1351
-                    esc_html__('A class method for the %s forwarding route has not been supplied.', 'event_espresso'),
1352
-                    $route
1353
-                );
1354
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1355
-                return false;
1356
-            }
1357
-            if (! method_exists($forward[0], $forward[1])) {
1358
-                $msg = sprintf(
1359
-                    esc_html__('The class method %s for the %s forwarding route is in invalid.', 'event_espresso'),
1360
-                    $forward[1],
1361
-                    $route
1362
-                );
1363
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1364
-                return false;
1365
-            }
1366
-        } elseif (! function_exists($forward)) {
1367
-            $msg = sprintf(
1368
-                esc_html__('The function %s for the %s forwarding route is in invalid.', 'event_espresso'),
1369
-                $forward,
1370
-                $route
1371
-            );
1372
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1373
-            return false;
1374
-        }
1375
-        EE_Config::$_module_forward_map[ $key ][ $route ][ absint($status) ] = $forward;
1376
-        return true;
1377
-    }
1378
-
1379
-
1380
-    /**
1381
-     *    get_forward - get forwarding route
1382
-     *
1383
-     * @access    public
1384
-     * @param    string  $route  - "pretty" public alias for module method
1385
-     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1386
-     *                           allows different forwards to be served based on status
1387
-     * @param    string  $key    - url param key indicating a route is being called
1388
-     * @return    string
1389
-     */
1390
-    public static function get_forward($route = null, $status = 0, $key = 'ee')
1391
-    {
1392
-        do_action('AHEE__EE_Config__get_forward__begin', $route, $status);
1393
-        if (isset(EE_Config::$_module_forward_map[ $key ][ $route ][ $status ])) {
1394
-            return apply_filters(
1395
-                'FHEE__EE_Config__get_forward',
1396
-                EE_Config::$_module_forward_map[ $key ][ $route ][ $status ],
1397
-                $route,
1398
-                $status
1399
-            );
1400
-        }
1401
-        return null;
1402
-    }
1403
-
1404
-
1405
-    /**
1406
-     *    register_forward - allows modules to specify different view templates for different method routes and status
1407
-     *    results
1408
-     *
1409
-     * @access    public
1410
-     * @param    string  $route  - "pretty" public alias for module method
1411
-     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1412
-     *                           allows different views to be served based on status
1413
-     * @param    string  $view
1414
-     * @param    string  $key    - url param key indicating a route is being called
1415
-     * @return    bool
1416
-     */
1417
-    public static function register_view($route = null, $status = 0, $view = null, $key = 'ee')
1418
-    {
1419
-        do_action('AHEE__EE_Config__register_view__begin', $route, $status, $view);
1420
-        if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1421
-            $msg = sprintf(
1422
-                esc_html__('The module route %s for this view has not been registered.', 'event_espresso'),
1423
-                $route
1424
-            );
1425
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1426
-            return false;
1427
-        }
1428
-        if (! is_readable($view)) {
1429
-            $msg = sprintf(
1430
-                esc_html__(
1431
-                    'The %s view file could not be found or is not readable due to file permissions.',
1432
-                    'event_espresso'
1433
-                ),
1434
-                $view
1435
-            );
1436
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1437
-            return false;
1438
-        }
1439
-        EE_Config::$_module_view_map[ $key ][ $route ][ absint($status) ] = $view;
1440
-        return true;
1441
-    }
1442
-
1443
-
1444
-    /**
1445
-     *    get_view - get view for route and status
1446
-     *
1447
-     * @access    public
1448
-     * @param    string  $route  - "pretty" public alias for module method
1449
-     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1450
-     *                           allows different views to be served based on status
1451
-     * @param    string  $key    - url param key indicating a route is being called
1452
-     * @return    string
1453
-     */
1454
-    public static function get_view($route = null, $status = 0, $key = 'ee')
1455
-    {
1456
-        do_action('AHEE__EE_Config__get_view__begin', $route, $status);
1457
-        if (isset(EE_Config::$_module_view_map[ $key ][ $route ][ $status ])) {
1458
-            return apply_filters(
1459
-                'FHEE__EE_Config__get_view',
1460
-                EE_Config::$_module_view_map[ $key ][ $route ][ $status ],
1461
-                $route,
1462
-                $status
1463
-            );
1464
-        }
1465
-        return null;
1466
-    }
1467
-
1468
-
1469
-    public function update_addon_option_names()
1470
-    {
1471
-        update_option(EE_Config::ADDON_OPTION_NAMES, $this->_addon_option_names);
1472
-    }
1473
-
1474
-
1475
-    public function shutdown()
1476
-    {
1477
-        $this->update_addon_option_names();
1478
-    }
1479
-
1480
-
1481
-    /**
1482
-     * @return LegacyShortcodesManager
1483
-     */
1484
-    public static function getLegacyShortcodesManager()
1485
-    {
1486
-        if (! EE_Config::instance()->legacy_shortcodes_manager instanceof LegacyShortcodesManager) {
1487
-            EE_Config::instance()->legacy_shortcodes_manager = LoaderFactory::getLoader()->getShared(
1488
-                LegacyShortcodesManager::class
1489
-            );
1490
-        }
1491
-        return EE_Config::instance()->legacy_shortcodes_manager;
1492
-    }
1493
-
1494
-
1495
-    /**
1496
-     * register_shortcode - makes core aware of this shortcode
1497
-     *
1498
-     * @deprecated 4.9.26
1499
-     * @param    string $shortcode_path - full path up to and including shortcode folder
1500
-     * @return    bool
1501
-     */
1502
-    public static function register_shortcode($shortcode_path = null)
1503
-    {
1504
-        EE_Error::doing_it_wrong(
1505
-            __METHOD__,
1506
-            esc_html__(
1507
-                'Usage is deprecated. Use \EventEspresso\core\services\shortcodes\LegacyShortcodesManager::registerShortcode() as direct replacement, or better yet, please see the new \EventEspresso\core\services\shortcodes\ShortcodesManager class.',
1508
-                'event_espresso'
1509
-            ),
1510
-            '4.9.26'
1511
-        );
1512
-        return EE_Config::instance()->getLegacyShortcodesManager()->registerShortcode($shortcode_path);
1513
-    }
1514
-}
1515
-
1516
-/**
1517
- * Base class used for config classes. These classes should generally not have
1518
- * magic functions in use, except we'll allow them to magically set and get stuff...
1519
- * basically, they should just be well-defined stdClasses
1520
- */
1521
-class EE_Config_Base
1522
-{
1523
-    /**
1524
-     * Utility function for escaping the value of a property and returning.
1525
-     *
1526
-     * @param string $property property name (checks to see if exists).
1527
-     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1528
-     * @throws EE_Error
1529
-     */
1530
-    public function get_pretty($property)
1531
-    {
1532
-        if (! property_exists($this, $property)) {
1533
-            throw new EE_Error(
1534
-                sprintf(
1535
-                    esc_html__(
1536
-                        '%1$s::get_pretty() has been called with the property %2$s which does not exist on the %1$s config class.',
1537
-                        'event_espresso'
1538
-                    ),
1539
-                    get_class($this),
1540
-                    $property
1541
-                )
1542
-            );
1543
-        }
1544
-        // just handling escaping of strings for now.
1545
-        if (is_string($this->{$property})) {
1546
-            return stripslashes($this->{$property});
1547
-        }
1548
-        return $this->{$property};
1549
-    }
1550
-
1551
-
1552
-    public function populate()
1553
-    {
1554
-        // grab defaults via a new instance of this class.
1555
-        $class_name = get_class($this);
1556
-        $defaults = new $class_name();
1557
-        // loop through the properties for this class and see if they are set.  If they are NOT, then grab the
1558
-        // default from our $defaults object.
1559
-        foreach (get_object_vars($defaults) as $property => $value) {
1560
-            if ($this->{$property} === null) {
1561
-                $this->{$property} = $value;
1562
-            }
1563
-        }
1564
-        // cleanup
1565
-        unset($defaults);
1566
-    }
1567
-
1568
-
1569
-    /**
1570
-     *        __isset
1571
-     *
1572
-     * @param $a
1573
-     * @return bool
1574
-     */
1575
-    public function __isset($a)
1576
-    {
1577
-        return false;
1578
-    }
1579
-
1580
-
1581
-    /**
1582
-     *        __unset
1583
-     *
1584
-     * @param $a
1585
-     * @return bool
1586
-     */
1587
-    public function __unset($a)
1588
-    {
1589
-        return false;
1590
-    }
1591
-
1592
-
1593
-    /**
1594
-     *        __clone
1595
-     */
1596
-    public function __clone()
1597
-    {
1598
-    }
1599
-
1600
-
1601
-    /**
1602
-     *        __wakeup
1603
-     */
1604
-    public function __wakeup()
1605
-    {
1606
-    }
1607
-
1608
-
1609
-    /**
1610
-     *        __destruct
1611
-     */
1612
-    public function __destruct()
1613
-    {
1614
-    }
1615
-}
1616
-
1617
-/**
1618
- * Class for defining what's in the EE_Config relating to registration settings
1619
- */
1620
-class EE_Core_Config extends EE_Config_Base
1621
-{
1622
-    const OPTION_NAME_UXIP = 'ee_ueip_optin';
1623
-
1624
-
1625
-    public $current_blog_id;
1626
-
1627
-    public $ee_ueip_optin;
1628
-
1629
-    public $ee_ueip_has_notified;
1630
-
1631
-    /**
1632
-     * Not to be confused with the 4 critical page variables (See
1633
-     * get_critical_pages_array()), this is just an array of wp posts that have EE
1634
-     * shortcodes in them. Keys are slugs, values are arrays with only 1 element: where the key is the shortcode
1635
-     * in the page, and the value is the page's ID. The key 'posts' is basically a duplicate of this same array.
1636
-     *
1637
-     * @var array
1638
-     */
1639
-    public $post_shortcodes;
1640
-
1641
-    public $module_route_map;
1642
-
1643
-    public $module_forward_map;
1644
-
1645
-    public $module_view_map;
1646
-
1647
-    /**
1648
-     * The next 4 vars are the IDs of critical EE pages.
1649
-     *
1650
-     * @var int
1651
-     */
1652
-    public $reg_page_id;
1653
-
1654
-    public $txn_page_id;
1655
-
1656
-    public $thank_you_page_id;
1657
-
1658
-    public $cancel_page_id;
1659
-
1660
-    /**
1661
-     * The next 4 vars are the URLs of critical EE pages.
1662
-     *
1663
-     * @var int
1664
-     */
1665
-    public $reg_page_url;
1666
-
1667
-    public $txn_page_url;
1668
-
1669
-    public $thank_you_page_url;
1670
-
1671
-    public $cancel_page_url;
1672
-
1673
-    /**
1674
-     * The next vars relate to the custom slugs for EE CPT routes
1675
-     */
1676
-    public $event_cpt_slug;
1677
-
1678
-    /**
1679
-     * This caches the _ee_ueip_option in case this config is reset in the same
1680
-     * request across blog switches in a multisite context.
1681
-     * Avoids extra queries to the db for this option.
1682
-     *
1683
-     * @var bool
1684
-     */
1685
-    public static $ee_ueip_option;
1686
-
1687
-
1688
-    /**
1689
-     *    class constructor
1690
-     *
1691
-     * @access    public
1692
-     */
1693
-    public function __construct()
1694
-    {
1695
-        // set default organization settings
1696
-        $this->current_blog_id = get_current_blog_id();
1697
-        $this->current_blog_id = $this->current_blog_id === null ? 1 : $this->current_blog_id;
1698
-        $this->ee_ueip_optin = $this->_get_main_ee_ueip_optin();
1699
-        $this->ee_ueip_has_notified = is_main_site() ? get_option('ee_ueip_has_notified', false) : true;
1700
-        $this->post_shortcodes = array();
1701
-        $this->module_route_map = array();
1702
-        $this->module_forward_map = array();
1703
-        $this->module_view_map = array();
1704
-        // critical EE page IDs
1705
-        $this->reg_page_id = 0;
1706
-        $this->txn_page_id = 0;
1707
-        $this->thank_you_page_id = 0;
1708
-        $this->cancel_page_id = 0;
1709
-        // critical EE page URLs
1710
-        $this->reg_page_url = '';
1711
-        $this->txn_page_url = '';
1712
-        $this->thank_you_page_url = '';
1713
-        $this->cancel_page_url = '';
1714
-        // cpt slugs
1715
-        $this->event_cpt_slug = esc_html__('events', 'event_espresso');
1716
-        // ueip constant check
1717
-        if (defined('EE_DISABLE_UXIP') && EE_DISABLE_UXIP) {
1718
-            $this->ee_ueip_optin = false;
1719
-            $this->ee_ueip_has_notified = true;
1720
-        }
1721
-    }
1722
-
1723
-
1724
-    /**
1725
-     * @return array
1726
-     */
1727
-    public function get_critical_pages_array()
1728
-    {
1729
-        return array(
1730
-            $this->reg_page_id,
1731
-            $this->txn_page_id,
1732
-            $this->thank_you_page_id,
1733
-            $this->cancel_page_id,
1734
-        );
1735
-    }
1736
-
1737
-
1738
-    /**
1739
-     * @return array
1740
-     */
1741
-    public function get_critical_pages_shortcodes_array()
1742
-    {
1743
-        return array(
1744
-            $this->reg_page_id       => 'ESPRESSO_CHECKOUT',
1745
-            $this->txn_page_id       => 'ESPRESSO_TXN_PAGE',
1746
-            $this->thank_you_page_id => 'ESPRESSO_THANK_YOU',
1747
-            $this->cancel_page_id    => 'ESPRESSO_CANCELLED',
1748
-        );
1749
-    }
1750
-
1751
-
1752
-    /**
1753
-     *  gets/returns URL for EE reg_page
1754
-     *
1755
-     * @access    public
1756
-     * @return    string
1757
-     */
1758
-    public function reg_page_url()
1759
-    {
1760
-        if (! $this->reg_page_url) {
1761
-            $this->reg_page_url = add_query_arg(
1762
-                array('uts' => time()),
1763
-                get_permalink($this->reg_page_id)
1764
-            ) . '#checkout';
1765
-        }
1766
-        return $this->reg_page_url;
1767
-    }
1768
-
1769
-
1770
-    /**
1771
-     *  gets/returns URL for EE txn_page
1772
-     *
1773
-     * @param array $query_args like what gets passed to
1774
-     *                          add_query_arg() as the first argument
1775
-     * @access    public
1776
-     * @return    string
1777
-     */
1778
-    public function txn_page_url($query_args = array())
1779
-    {
1780
-        if (! $this->txn_page_url) {
1781
-            $this->txn_page_url = get_permalink($this->txn_page_id);
1782
-        }
1783
-        if ($query_args) {
1784
-            return add_query_arg($query_args, $this->txn_page_url);
1785
-        } else {
1786
-            return $this->txn_page_url;
1787
-        }
1788
-    }
1789
-
1790
-
1791
-    /**
1792
-     *  gets/returns URL for EE thank_you_page
1793
-     *
1794
-     * @param array $query_args like what gets passed to
1795
-     *                          add_query_arg() as the first argument
1796
-     * @access    public
1797
-     * @return    string
1798
-     */
1799
-    public function thank_you_page_url($query_args = array())
1800
-    {
1801
-        if (! $this->thank_you_page_url) {
1802
-            $this->thank_you_page_url = get_permalink($this->thank_you_page_id);
1803
-        }
1804
-        if ($query_args) {
1805
-            return add_query_arg($query_args, $this->thank_you_page_url);
1806
-        } else {
1807
-            return $this->thank_you_page_url;
1808
-        }
1809
-    }
1810
-
1811
-
1812
-    /**
1813
-     *  gets/returns URL for EE cancel_page
1814
-     *
1815
-     * @access    public
1816
-     * @return    string
1817
-     */
1818
-    public function cancel_page_url()
1819
-    {
1820
-        if (! $this->cancel_page_url) {
1821
-            $this->cancel_page_url = get_permalink($this->cancel_page_id);
1822
-        }
1823
-        return $this->cancel_page_url;
1824
-    }
1825
-
1826
-
1827
-    /**
1828
-     * Resets all critical page urls to their original state.  Used primarily by the __sleep() magic method currently.
1829
-     *
1830
-     * @since 4.7.5
1831
-     */
1832
-    protected function _reset_urls()
1833
-    {
1834
-        $this->reg_page_url = '';
1835
-        $this->txn_page_url = '';
1836
-        $this->cancel_page_url = '';
1837
-        $this->thank_you_page_url = '';
1838
-    }
1839
-
1840
-
1841
-    /**
1842
-     * Used to return what the optin value is set for the EE User Experience Program.
1843
-     * This accounts for multisite and this value being requested for a subsite.  In multisite, the value is set
1844
-     * on the main site only.
1845
-     *
1846
-     * @return bool
1847
-     */
1848
-    protected function _get_main_ee_ueip_optin()
1849
-    {
1850
-        // if this is the main site then we can just bypass our direct query.
1851
-        if (is_main_site()) {
1852
-            return get_option(self::OPTION_NAME_UXIP, false);
1853
-        }
1854
-        // is this already cached for this request?  If so use it.
1855
-        if (EE_Core_Config::$ee_ueip_option !== null) {
1856
-            return EE_Core_Config::$ee_ueip_option;
1857
-        }
1858
-        global $wpdb;
1859
-        $current_network_main_site = is_multisite() ? get_current_site() : null;
1860
-        $current_main_site_id = ! empty($current_network_main_site) ? $current_network_main_site->blog_id : 1;
1861
-        $option = self::OPTION_NAME_UXIP;
1862
-        // set correct table for query
1863
-        $table_name = $wpdb->get_blog_prefix($current_main_site_id) . 'options';
1864
-        // rather than getting blog option for the $current_main_site_id, we do a direct $wpdb query because
1865
-        // get_blog_option() does a switch_to_blog an that could cause infinite recursion because EE_Core_Config might be
1866
-        // re-constructed on the blog switch.  Note, we are still executing any core wp filters on this option retrieval.
1867
-        // this bit of code is basically a direct copy of get_option without any caching because we are NOT switched to the blog
1868
-        // for the purpose of caching.
1869
-        $pre = apply_filters('pre_option_' . $option, false, $option);
1870
-        if (false !== $pre) {
1871
-            EE_Core_Config::$ee_ueip_option = $pre;
1872
-            return EE_Core_Config::$ee_ueip_option;
1873
-        }
1874
-        $row = $wpdb->get_row(
1875
-            $wpdb->prepare(
1876
-                "SELECT option_value FROM $table_name WHERE option_name = %s LIMIT 1",
1877
-                $option
1878
-            )
1879
-        );
1880
-        if (is_object($row)) {
1881
-            $value = $row->option_value;
1882
-        } else { // option does not exist so use default.
1883
-            EE_Core_Config::$ee_ueip_option =  apply_filters('default_option_' . $option, false, $option);
1884
-            return EE_Core_Config::$ee_ueip_option;
1885
-        }
1886
-        EE_Core_Config::$ee_ueip_option = apply_filters('option_' . $option, maybe_unserialize($value), $option);
1887
-        return EE_Core_Config::$ee_ueip_option;
1888
-    }
1889
-
1890
-
1891
-    /**
1892
-     * Utility function for escaping the value of a property and returning.
1893
-     *
1894
-     * @param string $property property name (checks to see if exists).
1895
-     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1896
-     * @throws EE_Error
1897
-     */
1898
-    public function get_pretty($property)
1899
-    {
1900
-        if ($property === self::OPTION_NAME_UXIP) {
1901
-            return $this->ee_ueip_optin ? 'yes' : 'no';
1902
-        }
1903
-        return parent::get_pretty($property);
1904
-    }
1905
-
1906
-
1907
-    /**
1908
-     * Currently used to ensure critical page urls have initial values saved to the db instead of any current set values
1909
-     * on the object.
1910
-     *
1911
-     * @return array
1912
-     */
1913
-    public function __sleep()
1914
-    {
1915
-        // reset all url properties
1916
-        $this->_reset_urls();
1917
-        // return what to save to db
1918
-        return array_keys(get_object_vars($this));
1919
-    }
1920
-}
1921
-
1922
-/**
1923
- * Config class for storing info on the Organization
1924
- */
1925
-class EE_Organization_Config extends EE_Config_Base
1926
-{
1927
-    /**
1928
-     * @var string $name
1929
-     * eg EE4.1
1930
-     */
1931
-    public $name;
1932
-
1933
-    /**
1934
-     * @var string $address_1
1935
-     * eg 123 Onna Road
1936
-     */
1937
-    public $address_1 = '';
1938
-
1939
-    /**
1940
-     * @var string $address_2
1941
-     * eg PO Box 123
1942
-     */
1943
-    public $address_2 = '';
1944
-
1945
-    /**
1946
-     * @var string $city
1947
-     * eg Inna City
1948
-     */
1949
-    public $city = '';
1950
-
1951
-    /**
1952
-     * @var int $STA_ID
1953
-     * eg 4
1954
-     */
1955
-    public $STA_ID = 0;
1956
-
1957
-    /**
1958
-     * @var string $CNT_ISO
1959
-     * eg US
1960
-     */
1961
-    public $CNT_ISO = '';
1962
-
1963
-    /**
1964
-     * @var string $zip
1965
-     * eg 12345  or V1A 2B3
1966
-     */
1967
-    public $zip = '';
1968
-
1969
-    /**
1970
-     * @var string $email
1971
-     * eg [email protected]
1972
-     */
1973
-    public $email;
1974
-
1975
-    /**
1976
-     * @var string $phone
1977
-     * eg. 111-111-1111
1978
-     */
1979
-    public $phone = '';
1980
-
1981
-    /**
1982
-     * @var string $vat
1983
-     * VAT/Tax Number
1984
-     */
1985
-    public $vat = '';
1986
-
1987
-    /**
1988
-     * @var string $logo_url
1989
-     * eg http://www.somedomain.com/wp-content/uploads/kittehs.jpg
1990
-     */
1991
-    public $logo_url = '';
1992
-
1993
-    /**
1994
-     * The below are all various properties for holding links to organization social network profiles
1995
-     *
1996
-     * @var string
1997
-     */
1998
-    /**
1999
-     * facebook (facebook.com/profile.name)
2000
-     *
2001
-     * @var string
2002
-     */
2003
-    public $facebook = '';
2004
-
2005
-    /**
2006
-     * twitter (twitter.com/twitter_handle)
2007
-     *
2008
-     * @var string
2009
-     */
2010
-    public $twitter = '';
2011
-
2012
-    /**
2013
-     * linkedin (linkedin.com/in/profile_name)
2014
-     *
2015
-     * @var string
2016
-     */
2017
-    public $linkedin = '';
2018
-
2019
-    /**
2020
-     * pinterest (www.pinterest.com/profile_name)
2021
-     *
2022
-     * @var string
2023
-     */
2024
-    public $pinterest = '';
2025
-
2026
-    /**
2027
-     * google+ (google.com/+profileName)
2028
-     *
2029
-     * @var string
2030
-     */
2031
-    public $google = '';
2032
-
2033
-    /**
2034
-     * instagram (instagram.com/handle)
2035
-     *
2036
-     * @var string
2037
-     */
2038
-    public $instagram = '';
2039
-
2040
-
2041
-    /**
2042
-     *    class constructor
2043
-     *
2044
-     * @access    public
2045
-     */
2046
-    public function __construct()
2047
-    {
2048
-        // set default organization settings
2049
-        // decode HTML entities from the WP blogname, because it's stored in the DB with HTML entities encoded
2050
-        $this->name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
2051
-        $this->email = get_bloginfo('admin_email');
2052
-    }
2053
-}
2054
-
2055
-/**
2056
- * Class for defining what's in the EE_Config relating to currency
2057
- */
2058
-class EE_Currency_Config extends EE_Config_Base
2059
-{
2060
-    /**
2061
-     * @var string $code
2062
-     * eg 'US'
2063
-     */
2064
-    public $code;
2065
-
2066
-    /**
2067
-     * @var string $name
2068
-     * eg 'Dollar'
2069
-     */
2070
-    public $name;
2071
-
2072
-    /**
2073
-     * plural name
2074
-     *
2075
-     * @var string $plural
2076
-     * eg 'Dollars'
2077
-     */
2078
-    public $plural;
2079
-
2080
-    /**
2081
-     * currency sign
2082
-     *
2083
-     * @var string $sign
2084
-     * eg '$'
2085
-     */
2086
-    public $sign;
2087
-
2088
-    /**
2089
-     * Whether the currency sign should come before the number or not
2090
-     *
2091
-     * @var boolean $sign_b4
2092
-     */
2093
-    public $sign_b4;
2094
-
2095
-    /**
2096
-     * How many digits should come after the decimal place
2097
-     *
2098
-     * @var int $dec_plc
2099
-     */
2100
-    public $dec_plc;
2101
-
2102
-    /**
2103
-     * Symbol to use for decimal mark
2104
-     *
2105
-     * @var string $dec_mrk
2106
-     * eg '.'
2107
-     */
2108
-    public $dec_mrk;
2109
-
2110
-    /**
2111
-     * Symbol to use for thousands
2112
-     *
2113
-     * @var string $thsnds
2114
-     * eg ','
2115
-     */
2116
-    public $thsnds;
2117
-
2118
-
2119
-    /**
2120
-     *    class constructor
2121
-     *
2122
-     * @access    public
2123
-     * @param string $CNT_ISO
2124
-     * @throws EE_Error
2125
-     * @throws ReflectionException
2126
-     */
2127
-    public function __construct($CNT_ISO = '')
2128
-    {
2129
-        if ($CNT_ISO && $CNT_ISO === $this->code) {
2130
-            return;
2131
-        }
2132
-        // get country code from organization settings or use default
2133
-        $ORG_CNT = isset(EE_Registry::instance()->CFG->organization)
2134
-                   && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
2135
-            ? EE_Registry::instance()->CFG->organization->CNT_ISO
2136
-            : '';
2137
-        // but override if requested
2138
-        $CNT_ISO = ! empty($CNT_ISO) ? $CNT_ISO : $ORG_CNT;
2139
-        // so if that all went well, and we are not in M-Mode (cuz you can't query the db in M-Mode) and double-check the countries table exists
2140
-        $this->setCurrency($CNT_ISO);
2141
-        // fallback to hardcoded defaults, in case the above failed
2142
-        if (empty($this->code)) {
2143
-            $this->setFallbackCurrency();
2144
-        }
2145
-    }
2146
-
2147
-
2148
-    /**
2149
-     * @param string|null $CNT_ISO
2150
-     * @throws EE_Error
2151
-     * @throws ReflectionException
2152
-     */
2153
-    public function setCurrency(?string $CNT_ISO = '')
2154
-    {
2155
-        if (empty($CNT_ISO) || ! EE_Maintenance_Mode::instance()->models_can_query()) {
2156
-            return;
2157
-        }
2158
-
2159
-        /** @var TableAnalysis $table_analysis */
2160
-        $table_analysis = EE_Registry::instance()->create('TableAnalysis', [], true);
2161
-        if (! $table_analysis->tableExists(EE_Registry::instance()->load_model('Country')->table())) {
2162
-            return;
2163
-        }
2164
-        // retrieve the country settings from the db, just in case they have been customized
2165
-        $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
2166
-        if (! $country instanceof EE_Country) {
2167
-            throw new DomainException(
2168
-                esc_html__('Invalid Country ISO Code.', 'event_espresso')
2169
-            );
2170
-        }
2171
-        $this->code    = $country->currency_code();                  // currency code: USD, CAD, EUR
2172
-        $this->name    = $country->currency_name_single();           // Dollar
2173
-        $this->plural  = $country->currency_name_plural();           // Dollars
2174
-        $this->sign    = $country->currency_sign();                  // currency sign: $
2175
-        $this->sign_b4 = $country->currency_sign_before();           // currency sign before or after
2176
-        $this->dec_plc = $country->currency_decimal_places();        // decimal places: 2 = 0.00  3 = 0.000
2177
-        $this->dec_mrk = $country->currency_decimal_mark();          // decimal mark: ',' = 0,01 or '.' = 0.01
2178
-        $this->thsnds  = $country->currency_thousands_separator();   // thousands sep: ',' = 1,000 or '.' = 1.000
2179
-    }
2180
-
2181
-
2182
-    private function setFallbackCurrency()
2183
-    {
2184
-        // set default currency settings
2185
-        $this->code    = 'USD';
2186
-        $this->name    = esc_html__('Dollar', 'event_espresso');
2187
-        $this->plural  = esc_html__('Dollars', 'event_espresso');
2188
-        $this->sign    = '$';
2189
-        $this->sign_b4 = true;
2190
-        $this->dec_plc = 2;
2191
-        $this->dec_mrk = '.';
2192
-        $this->thsnds  = ',';
2193
-    }
2194
-
2195
-
2196
-    /**
2197
-     * @param string|null $CNT_ISO
2198
-     * @return EE_Currency_Config
2199
-     * @throws EE_Error
2200
-     * @throws ReflectionException
2201
-     */
2202
-    public static function getCurrencyConfig(?string $CNT_ISO = ''): EE_Currency_Config
2203
-    {
2204
-        // if CNT_ISO passed lets try to get currency settings for it.
2205
-        $currency_config = ! empty($CNT_ISO)
2206
-            ? new EE_Currency_Config($CNT_ISO)
2207
-            : null;
2208
-        // default currency settings for site if not set
2209
-        if ($currency_config instanceof EE_Currency_Config) {
2210
-            return $currency_config;
2211
-        }
2212
-        EE_Config::instance()->currency = EE_Config::instance()->currency instanceof EE_Currency_Config
2213
-            ? EE_Config::instance()->currency
2214
-            : new EE_Currency_Config();
2215
-        return EE_Config::instance()->currency;
2216
-    }
2217
-}
2218
-
2219
-/**
2220
- * Class for defining what's in the EE_Config relating to registration settings
2221
- */
2222
-class EE_Registration_Config extends EE_Config_Base
2223
-{
2224
-    /**
2225
-     * Default registration status
2226
-     *
2227
-     * @var string $default_STS_ID
2228
-     * eg 'RPP'
2229
-     */
2230
-    public $default_STS_ID;
2231
-
2232
-    /**
2233
-     * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2234
-     * registrations)
2235
-     *
2236
-     * @var int
2237
-     */
2238
-    public $default_maximum_number_of_tickets;
2239
-
2240
-    /**
2241
-     * level of validation to apply to email addresses
2242
-     *
2243
-     * @var string $email_validation_level
2244
-     * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2245
-     */
2246
-    public $email_validation_level;
2247
-
2248
-    /**
2249
-     *    whether or not to show alternate payment options during the reg process if payment status is pending
2250
-     *
2251
-     * @var boolean $show_pending_payment_options
2252
-     */
2253
-    public $show_pending_payment_options;
2254
-
2255
-    /**
2256
-     * Whether to skip the registration confirmation page
2257
-     *
2258
-     * @var boolean $skip_reg_confirmation
2259
-     */
2260
-    public $skip_reg_confirmation;
2261
-
2262
-    /**
2263
-     * an array of SPCO reg steps where:
2264
-     *        the keys denotes the reg step order
2265
-     *        each element consists of an array with the following elements:
2266
-     *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2267
-     *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2268
-     *            "slug" => the URL param used to trigger the reg step
2269
-     *
2270
-     * @var array $reg_steps
2271
-     */
2272
-    public $reg_steps;
2273
-
2274
-    /**
2275
-     * Whether registration confirmation should be the last page of SPCO
2276
-     *
2277
-     * @var boolean $reg_confirmation_last
2278
-     */
2279
-    public $reg_confirmation_last;
2280
-
2281
-    /**
2282
-     * Whether or not to enable the EE Bot Trap
2283
-     *
2284
-     * @var boolean $use_bot_trap
2285
-     */
2286
-    public $use_bot_trap;
2287
-
2288
-    /**
2289
-     * Whether or not to encrypt some data sent by the EE Bot Trap
2290
-     *
2291
-     * @var boolean $use_encryption
2292
-     */
2293
-    public $use_encryption;
2294
-
2295
-    /**
2296
-     * Whether or not to use ReCaptcha
2297
-     *
2298
-     * @var boolean $use_captcha
2299
-     */
2300
-    public $use_captcha;
2301
-
2302
-    /**
2303
-     * ReCaptcha Theme
2304
-     *
2305
-     * @var string $recaptcha_theme
2306
-     *    options: 'dark', 'light', 'invisible'
2307
-     */
2308
-    public $recaptcha_theme;
2309
-
2310
-    /**
2311
-     * ReCaptcha Badge - determines the position of the reCAPTCHA badge if using Invisible ReCaptcha.
2312
-     *
2313
-     * @var string $recaptcha_badge
2314
-     *    options: 'bottomright', 'bottomleft', 'inline'
2315
-     */
2316
-    public $recaptcha_badge;
2317
-
2318
-    /**
2319
-     * ReCaptcha Type
2320
-     *
2321
-     * @var string $recaptcha_type
2322
-     *    options: 'audio', 'image'
2323
-     */
2324
-    public $recaptcha_type;
2325
-
2326
-    /**
2327
-     * ReCaptcha language
2328
-     *
2329
-     * @var string $recaptcha_language
2330
-     * eg 'en'
2331
-     */
2332
-    public $recaptcha_language;
2333
-
2334
-    /**
2335
-     * ReCaptcha public key
2336
-     *
2337
-     * @var string $recaptcha_publickey
2338
-     */
2339
-    public $recaptcha_publickey;
2340
-
2341
-    /**
2342
-     * ReCaptcha private key
2343
-     *
2344
-     * @var string $recaptcha_privatekey
2345
-     */
2346
-    public $recaptcha_privatekey;
2347
-
2348
-    /**
2349
-     * array of form names protected by ReCaptcha
2350
-     *
2351
-     * @var array $recaptcha_protected_forms
2352
-     */
2353
-    public $recaptcha_protected_forms;
21
+	const OPTION_NAME = 'ee_config';
22
+
23
+	const LOG_NAME = 'ee_config_log';
24
+
25
+	const LOG_LENGTH = 100;
26
+
27
+	const ADDON_OPTION_NAMES = 'ee_config_option_names';
28
+
29
+	/**
30
+	 *    instance of the EE_Config object
31
+	 *
32
+	 * @var    EE_Config $_instance
33
+	 * @access    private
34
+	 */
35
+	private static $_instance;
36
+
37
+	/**
38
+	 * @var boolean $_logging_enabled
39
+	 */
40
+	private static $_logging_enabled = false;
41
+
42
+	/**
43
+	 * @var LegacyShortcodesManager $legacy_shortcodes_manager
44
+	 */
45
+	private $legacy_shortcodes_manager;
46
+
47
+	/**
48
+	 * An StdClass whose property names are addon slugs,
49
+	 * and values are their config classes
50
+	 *
51
+	 * @var StdClass
52
+	 */
53
+	public $addons;
54
+
55
+	/**
56
+	 * @var EE_Admin_Config
57
+	 */
58
+	public $admin;
59
+
60
+	/**
61
+	 * @var EE_Core_Config
62
+	 */
63
+	public $core;
64
+
65
+	/**
66
+	 * @var EE_Currency_Config
67
+	 */
68
+	public $currency;
69
+
70
+	/**
71
+	 * @var EE_Organization_Config
72
+	 */
73
+	public $organization;
74
+
75
+	/**
76
+	 * @var EE_Registration_Config
77
+	 */
78
+	public $registration;
79
+
80
+	/**
81
+	 * @var EE_Template_Config
82
+	 */
83
+	public $template_settings;
84
+
85
+	/**
86
+	 * Holds EE environment values.
87
+	 *
88
+	 * @var EE_Environment_Config
89
+	 */
90
+	public $environment;
91
+
92
+	/**
93
+	 * settings pertaining to Google maps
94
+	 *
95
+	 * @var EE_Map_Config
96
+	 */
97
+	public $map_settings;
98
+
99
+	/**
100
+	 * settings pertaining to Taxes
101
+	 *
102
+	 * @var EE_Tax_Config
103
+	 */
104
+	public $tax_settings;
105
+
106
+	/**
107
+	 * Settings pertaining to global messages settings.
108
+	 *
109
+	 * @var EE_Messages_Config
110
+	 */
111
+	public $messages;
112
+
113
+	/**
114
+	 * @deprecated
115
+	 * @var EE_Gateway_Config
116
+	 */
117
+	public $gateway;
118
+
119
+	/**
120
+	 * @var array
121
+	 */
122
+	private $_addon_option_names = array();
123
+
124
+	/**
125
+	 * @var array
126
+	 */
127
+	private static $_module_route_map = array();
128
+
129
+	/**
130
+	 * @var array
131
+	 */
132
+	private static $_module_forward_map = array();
133
+
134
+	/**
135
+	 * @var array
136
+	 */
137
+	private static $_module_view_map = array();
138
+
139
+	/**
140
+	 * @var bool
141
+	 */
142
+	private static $initialized = false;
143
+
144
+
145
+	/**
146
+	 * @singleton method used to instantiate class object
147
+	 * @access    public
148
+	 * @return EE_Config instance
149
+	 */
150
+	public static function instance()
151
+	{
152
+		// check if class object is instantiated, and instantiated properly
153
+		if (! self::$_instance instanceof EE_Config) {
154
+			self::$_instance = new self();
155
+		}
156
+		return self::$_instance;
157
+	}
158
+
159
+
160
+	/**
161
+	 * Resets the config
162
+	 *
163
+	 * @param bool    $hard_reset    if TRUE, sets EE_CONFig back to its original settings in the database. If FALSE
164
+	 *                               (default) leaves the database alone, and merely resets the EE_Config object to
165
+	 *                               reflect its state in the database
166
+	 * @param boolean $reinstantiate if TRUE (default) call instance() and return it. Otherwise, just leave
167
+	 *                               $_instance as NULL. Useful in case you want to forget about the old instance on
168
+	 *                               EE_Config, but might not be ready to instantiate EE_Config currently (eg if the
169
+	 *                               site was put into maintenance mode)
170
+	 * @return EE_Config
171
+	 */
172
+	public static function reset($hard_reset = false, $reinstantiate = true)
173
+	{
174
+		if (self::$_instance instanceof EE_Config) {
175
+			if ($hard_reset) {
176
+				self::$_instance->legacy_shortcodes_manager = null;
177
+				self::$_instance->_addon_option_names = array();
178
+				self::$_instance->_initialize_config();
179
+				self::$_instance->update_espresso_config();
180
+			}
181
+			self::$_instance->update_addon_option_names();
182
+		}
183
+		self::$_instance = null;
184
+		self::$initialized = false;
185
+		// we don't need to reset the static properties imo because those should
186
+		// only change when a module is added or removed. Currently we don't
187
+		// support removing a module during a request when it previously existed
188
+		if ($reinstantiate) {
189
+			return self::instance();
190
+		} else {
191
+			return null;
192
+		}
193
+	}
194
+
195
+
196
+	private function __construct()
197
+	{
198
+		if (self::$initialized) {
199
+			return;
200
+		}
201
+		self::$initialized = true;
202
+		do_action('AHEE__EE_Config__construct__begin', $this);
203
+		EE_Config::$_logging_enabled = apply_filters('FHEE__EE_Config___construct__logging_enabled', false);
204
+		// setup empty config classes
205
+		$this->_initialize_config();
206
+		// load existing EE site settings
207
+		$this->_load_core_config();
208
+		// confirm everything loaded correctly and set filtered defaults if not
209
+		$this->_verify_config();
210
+		//  register shortcodes and modules
211
+		add_action(
212
+			'AHEE__EE_System__register_shortcodes_modules_and_widgets',
213
+			[$this, 'register_shortcodes_and_modules'],
214
+			999
215
+		);
216
+		//  initialize shortcodes and modules
217
+		add_action('AHEE__EE_System__core_loaded_and_ready', [$this, 'initialize_shortcodes_and_modules']);
218
+		// register widgets
219
+		add_action('widgets_init', [$this, 'widgets_init'], 10);
220
+		// shutdown
221
+		add_action('shutdown', [$this, 'shutdown'], 10);
222
+		// construct__end hook
223
+		do_action('AHEE__EE_Config__construct__end', $this);
224
+		// hardcoded hack
225
+		$this->template_settings->current_espresso_theme = 'Espresso_Arabica_2014';
226
+	}
227
+
228
+
229
+	/**
230
+	 * @return boolean
231
+	 */
232
+	public static function logging_enabled()
233
+	{
234
+		return self::$_logging_enabled;
235
+	}
236
+
237
+
238
+	/**
239
+	 * use to get the current theme if needed from static context
240
+	 *
241
+	 * @return string current theme set.
242
+	 */
243
+	public static function get_current_theme()
244
+	{
245
+		return self::$_instance->template_settings->current_espresso_theme ?? 'Espresso_Arabica_2014';
246
+	}
247
+
248
+
249
+	/**
250
+	 *        _initialize_config
251
+	 *
252
+	 * @access private
253
+	 * @return void
254
+	 */
255
+	private function _initialize_config()
256
+	{
257
+		EE_Config::trim_log();
258
+		// set defaults
259
+		$this->_addon_option_names = get_option(EE_Config::ADDON_OPTION_NAMES, array());
260
+		$this->addons = new stdClass();
261
+		// set _module_route_map
262
+		EE_Config::$_module_route_map = array();
263
+		// set _module_forward_map
264
+		EE_Config::$_module_forward_map = array();
265
+		// set _module_view_map
266
+		EE_Config::$_module_view_map = array();
267
+	}
268
+
269
+
270
+	/**
271
+	 *        load core plugin configuration
272
+	 *
273
+	 * @access private
274
+	 * @return void
275
+	 */
276
+	private function _load_core_config()
277
+	{
278
+		// load_core_config__start hook
279
+		do_action('AHEE__EE_Config___load_core_config__start', $this);
280
+		$espresso_config = (array) $this->get_espresso_config();
281
+		// need to move the "addons" element to the end of the config array
282
+		// in case an addon config references one of the other config classes
283
+		$addons = $espresso_config['addons'] ?? new StdClass();
284
+		unset($espresso_config['addons']);
285
+		$espresso_config['addons'] = $addons;
286
+		foreach ($espresso_config as $config => $settings) {
287
+			// load_core_config__start hook
288
+			$settings = apply_filters(
289
+				'FHEE__EE_Config___load_core_config__config_settings',
290
+				$settings,
291
+				$config,
292
+				$this
293
+			);
294
+			if (is_object($settings) && property_exists($this, $config)) {
295
+				$this->{$config} = apply_filters('FHEE__EE_Config___load_core_config__' . $config, $settings);
296
+				// call configs populate method to ensure any defaults are set for empty values.
297
+				if (method_exists($settings, 'populate')) {
298
+					$this->{$config}->populate();
299
+				}
300
+				if (method_exists($settings, 'do_hooks')) {
301
+					$this->{$config}->do_hooks();
302
+				}
303
+			}
304
+		}
305
+		if (apply_filters('FHEE__EE_Config___load_core_config__update_espresso_config', false)) {
306
+			$this->update_espresso_config();
307
+		}
308
+		// load_core_config__end hook
309
+		do_action('AHEE__EE_Config___load_core_config__end', $this);
310
+	}
311
+
312
+
313
+	/**
314
+	 *    _verify_config
315
+	 *
316
+	 * @access    protected
317
+	 * @return    void
318
+	 */
319
+	protected function _verify_config()
320
+	{
321
+		$this->core = $this->core instanceof EE_Core_Config
322
+			? $this->core
323
+			: new EE_Core_Config();
324
+		$this->core = apply_filters('FHEE__EE_Config___initialize_config__core', $this->core);
325
+		$this->organization = $this->organization instanceof EE_Organization_Config
326
+			? $this->organization
327
+			: new EE_Organization_Config();
328
+		$this->organization = apply_filters(
329
+			'FHEE__EE_Config___initialize_config__organization',
330
+			$this->organization
331
+		);
332
+		$this->currency = $this->currency instanceof EE_Currency_Config
333
+			? $this->currency
334
+			: new EE_Currency_Config();
335
+		$this->currency = apply_filters('FHEE__EE_Config___initialize_config__currency', $this->currency);
336
+		$this->registration = $this->registration instanceof EE_Registration_Config
337
+			? $this->registration
338
+			: new EE_Registration_Config();
339
+		$this->registration = apply_filters(
340
+			'FHEE__EE_Config___initialize_config__registration',
341
+			$this->registration
342
+		);
343
+		$this->admin = $this->admin instanceof EE_Admin_Config
344
+			? $this->admin
345
+			: new EE_Admin_Config();
346
+		$this->admin = apply_filters('FHEE__EE_Config___initialize_config__admin', $this->admin);
347
+		$this->template_settings = $this->template_settings instanceof EE_Template_Config
348
+			? $this->template_settings
349
+			: new EE_Template_Config();
350
+		$this->template_settings = apply_filters(
351
+			'FHEE__EE_Config___initialize_config__template_settings',
352
+			$this->template_settings
353
+		);
354
+		$this->map_settings = $this->map_settings instanceof EE_Map_Config
355
+			? $this->map_settings
356
+			: new EE_Map_Config();
357
+		$this->map_settings = apply_filters(
358
+			'FHEE__EE_Config___initialize_config__map_settings',
359
+			$this->map_settings
360
+		);
361
+		$this->environment = $this->environment instanceof EE_Environment_Config
362
+			? $this->environment
363
+			: new EE_Environment_Config();
364
+		$this->environment = apply_filters(
365
+			'FHEE__EE_Config___initialize_config__environment',
366
+			$this->environment
367
+		);
368
+		$this->tax_settings = $this->tax_settings instanceof EE_Tax_Config
369
+			? $this->tax_settings
370
+			: new EE_Tax_Config();
371
+		$this->tax_settings = apply_filters(
372
+			'FHEE__EE_Config___initialize_config__tax_settings',
373
+			$this->tax_settings
374
+		);
375
+		$this->messages = apply_filters('FHEE__EE_Config__initialize_config__messages', $this->messages);
376
+		$this->messages = $this->messages instanceof EE_Messages_Config
377
+			? $this->messages
378
+			: new EE_Messages_Config();
379
+		$this->gateway = $this->gateway instanceof EE_Gateway_Config
380
+			? $this->gateway
381
+			: new EE_Gateway_Config();
382
+		$this->gateway = apply_filters('FHEE__EE_Config___initialize_config__gateway', $this->gateway);
383
+		$this->legacy_shortcodes_manager = null;
384
+	}
385
+
386
+
387
+	/**
388
+	 *    get_espresso_config
389
+	 *
390
+	 * @access    public
391
+	 * @return    array of espresso config stuff
392
+	 */
393
+	public function get_espresso_config()
394
+	{
395
+		// grab espresso configuration
396
+		return apply_filters(
397
+			'FHEE__EE_Config__get_espresso_config__CFG',
398
+			get_option(EE_Config::OPTION_NAME, array())
399
+		);
400
+	}
401
+
402
+
403
+	/**
404
+	 *    double_check_config_comparison
405
+	 *
406
+	 * @access    public
407
+	 * @param string $option
408
+	 * @param        $old_value
409
+	 * @param        $value
410
+	 */
411
+	public function double_check_config_comparison($option, $old_value, $value)
412
+	{
413
+		// make sure we're checking the ee config
414
+		if ($option === EE_Config::OPTION_NAME) {
415
+			// run a loose comparison of the old value against the new value for type and properties,
416
+			// but NOT exact instance like WP update_option does (ie: NOT type safe comparison)
417
+			if ($value != $old_value) {
418
+				// if they are NOT the same, then remove the hook,
419
+				// which means the subsequent update results will be based solely on the update query results
420
+				// the reason we do this is because, as stated above,
421
+				// WP update_option performs an exact instance comparison (===) on any update values passed to it
422
+				// this happens PRIOR to serialization and any subsequent update.
423
+				// If values are found to match their previous old value,
424
+				// then WP bails before performing any update.
425
+				// Since we are passing the EE_Config object, it is comparing the EXACT instance of the saved version
426
+				// it just pulled from the db, with the one being passed to it (which will not match).
427
+				// HOWEVER, once the object is serialized and passed off to MySQL to update,
428
+				// MySQL MAY ALSO NOT perform the update because
429
+				// the string it sees in the db looks the same as the new one it has been passed!!!
430
+				// This results in the query returning an "affected rows" value of ZERO,
431
+				// which gets returned immediately by WP update_option and looks like an error.
432
+				remove_action('update_option', array($this, 'check_config_updated'));
433
+			}
434
+		}
435
+	}
436
+
437
+
438
+	/**
439
+	 *    update_espresso_config
440
+	 *
441
+	 * @access   public
442
+	 */
443
+	protected function _reset_espresso_addon_config()
444
+	{
445
+		$this->_addon_option_names = array();
446
+		foreach ($this->addons as $addon_name => $addon_config_obj) {
447
+			$addon_config_obj = maybe_unserialize($addon_config_obj);
448
+			if ($addon_config_obj instanceof EE_Config_Base) {
449
+				$this->update_config('addons', $addon_name, $addon_config_obj, false);
450
+			}
451
+			$this->addons->{$addon_name} = null;
452
+		}
453
+	}
454
+
455
+
456
+	/**
457
+	 *    update_espresso_config
458
+	 *
459
+	 * @access   public
460
+	 * @param   bool $add_success
461
+	 * @param   bool $add_error
462
+	 * @return   bool
463
+	 */
464
+	public function update_espresso_config($add_success = false, $add_error = true)
465
+	{
466
+		// don't allow config updates during WP heartbeats
467
+		/** @var RequestInterface $request */
468
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
469
+		if ($request->isWordPressHeartbeat()) {
470
+			return false;
471
+		}
472
+		// commented out the following re: https://events.codebasehq.com/projects/event-espresso/tickets/8197
473
+		// $clone = clone( self::$_instance );
474
+		// self::$_instance = NULL;
475
+		do_action('AHEE__EE_Config__update_espresso_config__begin', $this);
476
+		$this->_reset_espresso_addon_config();
477
+		// hook into update_option because that happens AFTER the ( $value === $old_value ) conditional
478
+		// but BEFORE the actual update occurs
479
+		add_action('update_option', array($this, 'double_check_config_comparison'), 1, 3);
480
+		// don't want to persist legacy_shortcodes_manager, but don't want to lose it either
481
+		$legacy_shortcodes_manager = $this->legacy_shortcodes_manager;
482
+		$this->legacy_shortcodes_manager = null;
483
+		// now update "ee_config"
484
+		$saved = update_option(EE_Config::OPTION_NAME, $this);
485
+		$this->legacy_shortcodes_manager = $legacy_shortcodes_manager;
486
+		EE_Config::log(EE_Config::OPTION_NAME);
487
+		// if not saved... check if the hook we just added still exists;
488
+		// if it does, it means one of two things:
489
+		// that update_option bailed at the($value === $old_value) conditional,
490
+		// or...
491
+		// the db update query returned 0 rows affected
492
+		// (probably because the data  value was the same from it's perspective)
493
+		// so the existence of the hook means that a negative result from update_option is NOT an error,
494
+		// but just means no update occurred, so don't display an error to the user.
495
+		// BUT... if update_option returns FALSE, AND the hook is missing,
496
+		// then it means that something truly went wrong
497
+		$saved = ! $saved ? has_action('update_option', array($this, 'double_check_config_comparison')) : $saved;
498
+		// remove our action since we don't want it in the system anymore
499
+		remove_action('update_option', array($this, 'double_check_config_comparison'), 1);
500
+		do_action('AHEE__EE_Config__update_espresso_config__end', $this, $saved);
501
+		// self::$_instance = $clone;
502
+		// unset( $clone );
503
+		// if config remains the same or was updated successfully
504
+		if ($saved) {
505
+			if ($add_success) {
506
+				EE_Error::add_success(
507
+					esc_html__('The Event Espresso Configuration Settings have been successfully updated.', 'event_espresso'),
508
+					__FILE__,
509
+					__FUNCTION__,
510
+					__LINE__
511
+				);
512
+			}
513
+			return true;
514
+		} else {
515
+			if ($add_error) {
516
+				EE_Error::add_error(
517
+					esc_html__('The Event Espresso Configuration Settings were not updated.', 'event_espresso'),
518
+					__FILE__,
519
+					__FUNCTION__,
520
+					__LINE__
521
+				);
522
+			}
523
+			return false;
524
+		}
525
+	}
526
+
527
+
528
+	/**
529
+	 *    _verify_config_params
530
+	 *
531
+	 * @access    private
532
+	 * @param    string         $section
533
+	 * @param    string         $name
534
+	 * @param    string         $config_class
535
+	 * @param    EE_Config_Base $config_obj
536
+	 * @param    array          $tests_to_run
537
+	 * @param    bool           $display_errors
538
+	 * @return    bool    TRUE on success, FALSE on fail
539
+	 */
540
+	private function _verify_config_params(
541
+		$section = '',
542
+		$name = '',
543
+		$config_class = '',
544
+		$config_obj = null,
545
+		$tests_to_run = array(1, 2, 3, 4, 5, 6, 7, 8),
546
+		$display_errors = true
547
+	) {
548
+		try {
549
+			foreach ($tests_to_run as $test) {
550
+				switch ($test) {
551
+					// TEST #1 : check that section was set
552
+					case 1:
553
+						if (empty($section)) {
554
+							if ($display_errors) {
555
+								throw new EE_Error(
556
+									sprintf(
557
+										esc_html__(
558
+											'No configuration section has been provided while attempting to save "%s".',
559
+											'event_espresso'
560
+										),
561
+										$config_class
562
+									)
563
+								);
564
+							}
565
+							return false;
566
+						}
567
+						break;
568
+					// TEST #2 : check that settings section exists
569
+					case 2:
570
+						if (! isset($this->{$section})) {
571
+							if ($display_errors) {
572
+								throw new EE_Error(
573
+									sprintf(
574
+										esc_html__('The "%s" configuration section does not exist.', 'event_espresso'),
575
+										$section
576
+									)
577
+								);
578
+							}
579
+							return false;
580
+						}
581
+						break;
582
+					// TEST #3 : check that section is the proper format
583
+					case 3:
584
+						if (
585
+							! ($this->{$section} instanceof EE_Config_Base || $this->{$section} instanceof stdClass)
586
+						) {
587
+							if ($display_errors) {
588
+								throw new EE_Error(
589
+									sprintf(
590
+										esc_html__(
591
+											'The "%s" configuration settings have not been formatted correctly.',
592
+											'event_espresso'
593
+										),
594
+										$section
595
+									)
596
+								);
597
+							}
598
+							return false;
599
+						}
600
+						break;
601
+					// TEST #4 : check that config section name has been set
602
+					case 4:
603
+						if (empty($name)) {
604
+							if ($display_errors) {
605
+								throw new EE_Error(
606
+									esc_html__(
607
+										'No name has been provided for the specific configuration section.',
608
+										'event_espresso'
609
+									)
610
+								);
611
+							}
612
+							return false;
613
+						}
614
+						break;
615
+					// TEST #5 : check that a config class name has been set
616
+					case 5:
617
+						if (empty($config_class)) {
618
+							if ($display_errors) {
619
+								throw new EE_Error(
620
+									esc_html__(
621
+										'No class name has been provided for the specific configuration section.',
622
+										'event_espresso'
623
+									)
624
+								);
625
+							}
626
+							return false;
627
+						}
628
+						break;
629
+					// TEST #6 : verify config class is accessible
630
+					case 6:
631
+						if (! class_exists($config_class)) {
632
+							if ($display_errors) {
633
+								throw new EE_Error(
634
+									sprintf(
635
+										esc_html__(
636
+											'The "%s" class does not exist. Please ensure that an autoloader has been set for it.',
637
+											'event_espresso'
638
+										),
639
+										$config_class
640
+									)
641
+								);
642
+							}
643
+							return false;
644
+						}
645
+						break;
646
+					// TEST #7 : check that config has even been set
647
+					case 7:
648
+						if (! isset($this->{$section}->{$name})) {
649
+							if ($display_errors) {
650
+								throw new EE_Error(
651
+									sprintf(
652
+										esc_html__('No configuration has been set for "%1$s->%2$s".', 'event_espresso'),
653
+										$section,
654
+										$name
655
+									)
656
+								);
657
+							}
658
+							return false;
659
+						} else {
660
+							// and make sure it's not serialized
661
+							$this->{$section}->{$name} = maybe_unserialize($this->{$section}->{$name});
662
+						}
663
+						break;
664
+					// TEST #8 : check that config is the requested type
665
+					case 8:
666
+						if (! $this->{$section}->{$name} instanceof $config_class) {
667
+							if ($display_errors) {
668
+								throw new EE_Error(
669
+									sprintf(
670
+										esc_html__(
671
+											'The configuration for "%1$s->%2$s" is not of the "%3$s" class.',
672
+											'event_espresso'
673
+										),
674
+										$section,
675
+										$name,
676
+										$config_class
677
+									)
678
+								);
679
+							}
680
+							return false;
681
+						}
682
+						break;
683
+					// TEST #9 : verify config object
684
+					case 9:
685
+						if (! $config_obj instanceof EE_Config_Base) {
686
+							if ($display_errors) {
687
+								throw new EE_Error(
688
+									sprintf(
689
+										esc_html__('The "%s" class is not an instance of EE_Config_Base.', 'event_espresso'),
690
+										print_r($config_obj, true)
691
+									)
692
+								);
693
+							}
694
+							return false;
695
+						}
696
+						break;
697
+				}
698
+			}
699
+		} catch (EE_Error $e) {
700
+			$e->get_error();
701
+		}
702
+		// you have successfully run the gauntlet
703
+		return true;
704
+	}
705
+
706
+
707
+	/**
708
+	 *    _generate_config_option_name
709
+	 *
710
+	 * @access        protected
711
+	 * @param        string $section
712
+	 * @param        string $name
713
+	 * @return        string
714
+	 */
715
+	private function _generate_config_option_name($section = '', $name = '')
716
+	{
717
+		return 'ee_config-' . strtolower($section . '-' . str_replace(array('EE_', 'EED_'), '', $name));
718
+	}
719
+
720
+
721
+	/**
722
+	 *    _set_config_class
723
+	 * ensures that a config class is set, either from a passed config class or one generated from the config name
724
+	 *
725
+	 * @access    private
726
+	 * @param    string $config_class
727
+	 * @param    string $name
728
+	 * @return    string
729
+	 */
730
+	private function _set_config_class($config_class = '', $name = '')
731
+	{
732
+		return ! empty($config_class)
733
+			? $config_class
734
+			: str_replace(' ', '_', ucwords(str_replace('_', ' ', $name))) . '_Config';
735
+	}
736
+
737
+
738
+	/**
739
+	 *    set_config
740
+	 *
741
+	 * @access    protected
742
+	 * @param    string         $section
743
+	 * @param    string         $name
744
+	 * @param    string         $config_class
745
+	 * @param    EE_Config_Base $config_obj
746
+	 * @return    EE_Config_Base
747
+	 */
748
+	public function set_config($section = '', $name = '', $config_class = '', EE_Config_Base $config_obj = null)
749
+	{
750
+		// ensure config class is set to something
751
+		$config_class = $this->_set_config_class($config_class, $name);
752
+		// run tests 1-4, 6, and 7 to verify all config params are set and valid
753
+		if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
754
+			return null;
755
+		}
756
+		$config_option_name = $this->_generate_config_option_name($section, $name);
757
+		// if the config option name hasn't been added yet to the list of option names we're tracking, then do so now
758
+		if (! isset($this->_addon_option_names[ $config_option_name ])) {
759
+			$this->_addon_option_names[ $config_option_name ] = $config_class;
760
+			$this->update_addon_option_names();
761
+		}
762
+		// verify the incoming config object but suppress errors
763
+		if (! $this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
764
+			$config_obj = new $config_class();
765
+		}
766
+		if (get_option($config_option_name)) {
767
+			EE_Config::log($config_option_name);
768
+			update_option($config_option_name, $config_obj);
769
+			$this->{$section}->{$name} = $config_obj;
770
+			return $this->{$section}->{$name};
771
+		} else {
772
+			// create a wp-option for this config
773
+			if (add_option($config_option_name, $config_obj, '', 'no')) {
774
+				$this->{$section}->{$name} = maybe_unserialize($config_obj);
775
+				return $this->{$section}->{$name};
776
+			} else {
777
+				EE_Error::add_error(
778
+					sprintf(esc_html__('The "%s" could not be saved to the database.', 'event_espresso'), $config_class),
779
+					__FILE__,
780
+					__FUNCTION__,
781
+					__LINE__
782
+				);
783
+				return null;
784
+			}
785
+		}
786
+	}
787
+
788
+
789
+	/**
790
+	 *    update_config
791
+	 * Important: the config object must ALREADY be set, otherwise this will produce an error.
792
+	 *
793
+	 * @access    public
794
+	 * @param    string                $section
795
+	 * @param    string                $name
796
+	 * @param    EE_Config_Base|string $config_obj
797
+	 * @param    bool                  $throw_errors
798
+	 * @return    bool
799
+	 */
800
+	public function update_config($section = '', $name = '', $config_obj = '', $throw_errors = true)
801
+	{
802
+		// don't allow config updates during WP heartbeats
803
+		/** @var RequestInterface $request */
804
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
805
+		if ($request->isWordPressHeartbeat()) {
806
+			return false;
807
+		}
808
+		$config_obj = maybe_unserialize($config_obj);
809
+		// get class name of the incoming object
810
+		$config_class = get_class($config_obj);
811
+		// run tests 1-5 and 9 to verify config
812
+		if (
813
+			! $this->_verify_config_params(
814
+				$section,
815
+				$name,
816
+				$config_class,
817
+				$config_obj,
818
+				array(1, 2, 3, 4, 7, 9)
819
+			)
820
+		) {
821
+			return false;
822
+		}
823
+		$config_option_name = $this->_generate_config_option_name($section, $name);
824
+		// check if config object has been added to db by seeing if config option name is in $this->_addon_option_names array
825
+		if (! isset($this->_addon_option_names[ $config_option_name ])) {
826
+			// save new config to db
827
+			if ($this->set_config($section, $name, $config_class, $config_obj)) {
828
+				return true;
829
+			}
830
+		} else {
831
+			// first check if the record already exists
832
+			$existing_config = get_option($config_option_name);
833
+			$config_obj = serialize($config_obj);
834
+			// just return if db record is already up to date (NOT type safe comparison)
835
+			if ($existing_config == $config_obj) {
836
+				$this->{$section}->{$name} = $config_obj;
837
+				return true;
838
+			} elseif (update_option($config_option_name, $config_obj)) {
839
+				EE_Config::log($config_option_name);
840
+				// update wp-option for this config class
841
+				$this->{$section}->{$name} = $config_obj;
842
+				return true;
843
+			} elseif ($throw_errors) {
844
+				EE_Error::add_error(
845
+					sprintf(
846
+						esc_html__(
847
+							'The "%1$s" object stored at"%2$s" was not successfully updated in the database.',
848
+							'event_espresso'
849
+						),
850
+						$config_class,
851
+						'EE_Config->' . $section . '->' . $name
852
+					),
853
+					__FILE__,
854
+					__FUNCTION__,
855
+					__LINE__
856
+				);
857
+			}
858
+		}
859
+		return false;
860
+	}
861
+
862
+
863
+	/**
864
+	 *    get_config
865
+	 *
866
+	 * @access    public
867
+	 * @param    string $section
868
+	 * @param    string $name
869
+	 * @param    string $config_class
870
+	 * @return    mixed EE_Config_Base | NULL
871
+	 */
872
+	public function get_config($section = '', $name = '', $config_class = '')
873
+	{
874
+		// ensure config class is set to something
875
+		$config_class = $this->_set_config_class($config_class, $name);
876
+		// run tests 1-4, 6 and 7 to verify that all params have been set
877
+		if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
878
+			return null;
879
+		}
880
+		// now test if the requested config object exists, but suppress errors
881
+		if ($this->_verify_config_params($section, $name, $config_class, null, array(7, 8), false)) {
882
+			// config already exists, so pass it back
883
+			return $this->{$section}->{$name};
884
+		}
885
+		// load config option from db if it exists
886
+		$config_obj = $this->get_config_option($this->_generate_config_option_name($section, $name));
887
+		// verify the newly retrieved config object, but suppress errors
888
+		if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
889
+			// config is good, so set it and pass it back
890
+			$this->{$section}->{$name} = $config_obj;
891
+			return $this->{$section}->{$name};
892
+		}
893
+		// oops! $config_obj is not already set and does not exist in the db, so create a new one
894
+		$config_obj = $this->set_config($section, $name, $config_class);
895
+		// verify the newly created config object
896
+		if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9))) {
897
+			return $this->{$section}->{$name};
898
+		} else {
899
+			EE_Error::add_error(
900
+				sprintf(esc_html__('The "%s" could not be retrieved from the database.', 'event_espresso'), $config_class),
901
+				__FILE__,
902
+				__FUNCTION__,
903
+				__LINE__
904
+			);
905
+		}
906
+		return null;
907
+	}
908
+
909
+
910
+	/**
911
+	 *    get_config_option
912
+	 *
913
+	 * @access    public
914
+	 * @param    string $config_option_name
915
+	 * @return    mixed EE_Config_Base | FALSE
916
+	 */
917
+	public function get_config_option($config_option_name = '')
918
+	{
919
+		// retrieve the wp-option for this config class.
920
+		$config_option = maybe_unserialize(get_option($config_option_name, array()));
921
+		if (empty($config_option)) {
922
+			EE_Config::log($config_option_name . '-NOT-FOUND');
923
+		}
924
+		return $config_option;
925
+	}
926
+
927
+
928
+	/**
929
+	 * log
930
+	 *
931
+	 * @param string $config_option_name
932
+	 */
933
+	public static function log($config_option_name = '')
934
+	{
935
+		if (EE_Config::logging_enabled() && ! empty($config_option_name)) {
936
+			$config_log = get_option(EE_Config::LOG_NAME, array());
937
+			/** @var RequestParams $request */
938
+			$request = LoaderFactory::getLoader()->getShared(RequestParams::class);
939
+			$config_log[ (string) microtime(true) ] = array(
940
+				'config_name' => $config_option_name,
941
+				'request'     => $request->requestParams(),
942
+			);
943
+			update_option(EE_Config::LOG_NAME, $config_log);
944
+		}
945
+	}
946
+
947
+
948
+	/**
949
+	 * trim_log
950
+	 * reduces the size of the config log to the length specified by EE_Config::LOG_LENGTH
951
+	 */
952
+	public static function trim_log()
953
+	{
954
+		if (! EE_Config::logging_enabled()) {
955
+			return;
956
+		}
957
+		$config_log = maybe_unserialize(get_option(EE_Config::LOG_NAME, array()));
958
+		$log_length = count($config_log);
959
+		if ($log_length > EE_Config::LOG_LENGTH) {
960
+			ksort($config_log);
961
+			$config_log = array_slice($config_log, $log_length - EE_Config::LOG_LENGTH, null, true);
962
+			update_option(EE_Config::LOG_NAME, $config_log);
963
+		}
964
+	}
965
+
966
+
967
+	/**
968
+	 *    get_page_for_posts
969
+	 *    if the wp-option "show_on_front" is set to "page", then this is the post_name for the post set in the
970
+	 *    wp-option "page_for_posts", or "posts" if no page is selected
971
+	 *
972
+	 * @access    public
973
+	 * @return    string
974
+	 */
975
+	public static function get_page_for_posts()
976
+	{
977
+		$page_for_posts = get_option('page_for_posts');
978
+		if (! $page_for_posts) {
979
+			return 'posts';
980
+		}
981
+		global $wpdb;
982
+		$SQL = "SELECT post_name from $wpdb->posts WHERE post_type='posts' OR post_type='page' AND post_status='publish' AND ID=%d";
983
+		return $wpdb->get_var($wpdb->prepare($SQL, $page_for_posts));
984
+	}
985
+
986
+
987
+	/**
988
+	 *    register_shortcodes_and_modules.
989
+	 *    At this point, it's too early to tell if we're maintenance mode or not.
990
+	 *    In fact, this is where we give modules a chance to let core know they exist
991
+	 *    so they can help trigger maintenance mode if it's needed
992
+	 *
993
+	 * @access    public
994
+	 * @return    void
995
+	 */
996
+	public function register_shortcodes_and_modules()
997
+	{
998
+		// allow modules to set hooks for the rest of the system
999
+		EE_Registry::instance()->modules = $this->_register_modules();
1000
+	}
1001
+
1002
+
1003
+	/**
1004
+	 *    initialize_shortcodes_and_modules
1005
+	 *    meaning they can start adding their hooks to get stuff done
1006
+	 *
1007
+	 * @access    public
1008
+	 * @return    void
1009
+	 */
1010
+	public function initialize_shortcodes_and_modules()
1011
+	{
1012
+		// allow modules to set hooks for the rest of the system
1013
+		$this->_initialize_modules();
1014
+	}
1015
+
1016
+
1017
+	/**
1018
+	 *    widgets_init
1019
+	 *
1020
+	 * @access private
1021
+	 * @return void
1022
+	 */
1023
+	public function widgets_init()
1024
+	{
1025
+		// only init widgets on admin pages when not in complete maintenance, and
1026
+		// on frontend when not in any maintenance mode
1027
+		if (
1028
+			! EE_Maintenance_Mode::instance()->level()
1029
+			|| (
1030
+				is_admin()
1031
+				&& EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance
1032
+			)
1033
+		) {
1034
+			// grab list of installed widgets
1035
+			$widgets_to_register = glob(EE_WIDGETS . '*', GLOB_ONLYDIR);
1036
+			// filter list of modules to register
1037
+			$widgets_to_register = apply_filters(
1038
+				'FHEE__EE_Config__register_widgets__widgets_to_register',
1039
+				$widgets_to_register
1040
+			);
1041
+			if (! empty($widgets_to_register)) {
1042
+				// cycle thru widget folders
1043
+				foreach ($widgets_to_register as $widget_path) {
1044
+					// add to list of installed widget modules
1045
+					EE_Config::register_ee_widget($widget_path);
1046
+				}
1047
+			}
1048
+			// filter list of installed modules
1049
+			EE_Registry::instance()->widgets = apply_filters(
1050
+				'FHEE__EE_Config__register_widgets__installed_widgets',
1051
+				EE_Registry::instance()->widgets
1052
+			);
1053
+		}
1054
+	}
1055
+
1056
+
1057
+	/**
1058
+	 *    register_ee_widget - makes core aware of this widget
1059
+	 *
1060
+	 * @access    public
1061
+	 * @param    string $widget_path - full path up to and including widget folder
1062
+	 * @return    void
1063
+	 */
1064
+	public static function register_ee_widget($widget_path = null)
1065
+	{
1066
+		do_action('AHEE__EE_Config__register_widget__begin', $widget_path);
1067
+		$widget_ext = '.widget.php';
1068
+		// make all separators match
1069
+		$widget_path = rtrim(str_replace('\\', DS, $widget_path), DS);
1070
+		// does the file path INCLUDE the actual file name as part of the path ?
1071
+		if (strpos($widget_path, $widget_ext) !== false) {
1072
+			// grab and shortcode file name from directory name and break apart at dots
1073
+			$file_name = explode('.', basename($widget_path));
1074
+			// take first segment from file name pieces and remove class prefix if it exists
1075
+			$widget = strpos($file_name[0], 'EEW_') === 0 ? substr($file_name[0], 4) : $file_name[0];
1076
+			// sanitize shortcode directory name
1077
+			$widget = sanitize_key($widget);
1078
+			// now we need to rebuild the shortcode path
1079
+			$widget_path = explode('/', $widget_path);
1080
+			// remove last segment
1081
+			array_pop($widget_path);
1082
+			// glue it back together
1083
+			$widget_path = implode(DS, $widget_path);
1084
+		} else {
1085
+			// grab and sanitize widget directory name
1086
+			$widget = sanitize_key(basename($widget_path));
1087
+		}
1088
+		// create classname from widget directory name
1089
+		$widget = str_replace(' ', '_', ucwords(str_replace('_', ' ', $widget)));
1090
+		// add class prefix
1091
+		$widget_class = 'EEW_' . $widget;
1092
+		// does the widget exist ?
1093
+		if (! is_readable($widget_path . '/' . $widget_class . $widget_ext)) {
1094
+			$msg = sprintf(
1095
+				esc_html__(
1096
+					'The requested %s widget file could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s',
1097
+					'event_espresso'
1098
+				),
1099
+				$widget_class,
1100
+				$widget_path . '/' . $widget_class . $widget_ext
1101
+			);
1102
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1103
+			return;
1104
+		}
1105
+		// load the widget class file
1106
+		require_once($widget_path . '/' . $widget_class . $widget_ext);
1107
+		// verify that class exists
1108
+		if (! class_exists($widget_class)) {
1109
+			$msg = sprintf(esc_html__('The requested %s widget class does not exist.', 'event_espresso'), $widget_class);
1110
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1111
+			return;
1112
+		}
1113
+		register_widget($widget_class);
1114
+		// add to array of registered widgets
1115
+		EE_Registry::instance()->widgets->{$widget_class} = $widget_path . '/' . $widget_class . $widget_ext;
1116
+	}
1117
+
1118
+
1119
+	/**
1120
+	 *        _register_modules
1121
+	 *
1122
+	 * @access private
1123
+	 * @return array
1124
+	 */
1125
+	private function _register_modules()
1126
+	{
1127
+		// grab list of installed modules
1128
+		$modules_to_register = glob(EE_MODULES . '*', GLOB_ONLYDIR);
1129
+		// filter list of modules to register
1130
+		$modules_to_register = apply_filters(
1131
+			'FHEE__EE_Config__register_modules__modules_to_register',
1132
+			$modules_to_register
1133
+		);
1134
+		if (! empty($modules_to_register)) {
1135
+			// loop through folders
1136
+			foreach ($modules_to_register as $module_path) {
1137
+				/**TEMPORARILY EXCLUDE gateways from modules for time being**/
1138
+				if (
1139
+					$module_path !== EE_MODULES . 'zzz-copy-this-module-template'
1140
+					&& $module_path !== EE_MODULES . 'gateways'
1141
+				) {
1142
+					// add to list of installed modules
1143
+					EE_Config::register_module($module_path);
1144
+				}
1145
+			}
1146
+		}
1147
+		// filter list of installed modules
1148
+		return apply_filters(
1149
+			'FHEE__EE_Config___register_modules__installed_modules',
1150
+			EE_Registry::instance()->modules
1151
+		);
1152
+	}
1153
+
1154
+
1155
+	/**
1156
+	 *    register_module - makes core aware of this module
1157
+	 *
1158
+	 * @access    public
1159
+	 * @param    string $module_path - full path up to and including module folder
1160
+	 * @return    bool
1161
+	 */
1162
+	public static function register_module($module_path = null)
1163
+	{
1164
+		do_action('AHEE__EE_Config__register_module__begin', $module_path);
1165
+		$module_ext = '.module.php';
1166
+		// make all separators match
1167
+		$module_path = str_replace(array('\\', '/'), '/', $module_path);
1168
+		// does the file path INCLUDE the actual file name as part of the path ?
1169
+		if (strpos($module_path, $module_ext) !== false) {
1170
+			// grab and shortcode file name from directory name and break apart at dots
1171
+			$module_file = explode('.', basename($module_path));
1172
+			// now we need to rebuild the shortcode path
1173
+			$module_path = explode('/', $module_path);
1174
+			// remove last segment
1175
+			array_pop($module_path);
1176
+			// glue it back together
1177
+			$module_path = implode('/', $module_path) . '/';
1178
+			// take first segment from file name pieces and sanitize it
1179
+			$module = preg_replace('/[^a-zA-Z0-9_\-]/', '', $module_file[0]);
1180
+			// ensure class prefix is added
1181
+			$module_class = strpos($module, 'EED_') !== 0 ? 'EED_' . $module : $module;
1182
+		} else {
1183
+			// we need to generate the filename based off of the folder name
1184
+			// grab and sanitize module name
1185
+			$module = strtolower(basename($module_path));
1186
+			$module = preg_replace('/[^a-z0-9_\-]/', '', $module);
1187
+			// like trailingslashit()
1188
+			$module_path = rtrim($module_path, '/') . '/';
1189
+			// create classname from module directory name
1190
+			$module = str_replace(' ', '_', ucwords(str_replace('_', ' ', $module)));
1191
+			// add class prefix
1192
+			$module_class = 'EED_' . $module;
1193
+		}
1194
+		// does the module exist ?
1195
+		if (! is_readable($module_path . '/' . $module_class . $module_ext)) {
1196
+			$msg = sprintf(
1197
+				esc_html__(
1198
+					'The requested %s module file could not be found or is not readable due to file permissions.',
1199
+					'event_espresso'
1200
+				),
1201
+				$module
1202
+			);
1203
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1204
+			return false;
1205
+		}
1206
+		// load the module class file
1207
+		require_once($module_path . $module_class . $module_ext);
1208
+		// verify that class exists
1209
+		if (! class_exists($module_class)) {
1210
+			$msg = sprintf(esc_html__('The requested %s module class does not exist.', 'event_espresso'), $module_class);
1211
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1212
+			return false;
1213
+		}
1214
+		// add to array of registered modules
1215
+		EE_Registry::instance()->modules->{$module_class} = $module_path . $module_class . $module_ext;
1216
+		do_action(
1217
+			'AHEE__EE_Config__register_module__complete',
1218
+			$module_class,
1219
+			EE_Registry::instance()->modules->{$module_class}
1220
+		);
1221
+		return true;
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 *    _initialize_modules
1227
+	 *    allow modules to set hooks for the rest of the system
1228
+	 *
1229
+	 * @access private
1230
+	 * @return void
1231
+	 */
1232
+	private function _initialize_modules()
1233
+	{
1234
+		// cycle thru shortcode folders
1235
+		foreach (EE_Registry::instance()->modules as $module_class => $module_path) {
1236
+			// fire the shortcode class's set_hooks methods in case it needs to hook into other parts of the system
1237
+			// which set hooks ?
1238
+			if (is_admin()) {
1239
+				// fire immediately
1240
+				call_user_func(array($module_class, 'set_hooks_admin'));
1241
+			} else {
1242
+				// delay until other systems are online
1243
+				add_action(
1244
+					'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons',
1245
+					array($module_class, 'set_hooks')
1246
+				);
1247
+			}
1248
+		}
1249
+	}
1250
+
1251
+
1252
+	/**
1253
+	 *    register_route - adds module method routes to route_map
1254
+	 *
1255
+	 * @access    public
1256
+	 * @param    string $route       - "pretty" public alias for module method
1257
+	 * @param    string $module      - module name (classname without EED_ prefix)
1258
+	 * @param    string $method_name - the actual module method to be routed to
1259
+	 * @param    string $key         - url param key indicating a route is being called
1260
+	 * @return    bool
1261
+	 */
1262
+	public static function register_route($route = null, $module = null, $method_name = null, $key = 'ee')
1263
+	{
1264
+		do_action('AHEE__EE_Config__register_route__begin', $route, $module, $method_name);
1265
+		$module = str_replace('EED_', '', $module);
1266
+		$module_class = 'EED_' . $module;
1267
+		if (! isset(EE_Registry::instance()->modules->{$module_class})) {
1268
+			$msg = sprintf(esc_html__('The module %s has not been registered.', 'event_espresso'), $module);
1269
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1270
+			return false;
1271
+		}
1272
+		if (empty($route)) {
1273
+			$msg = sprintf(esc_html__('No route has been supplied.', 'event_espresso'), $route);
1274
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1275
+			return false;
1276
+		}
1277
+		if (! method_exists('EED_' . $module, $method_name)) {
1278
+			$msg = sprintf(
1279
+				esc_html__('A valid class method for the %s route has not been supplied.', 'event_espresso'),
1280
+				$route
1281
+			);
1282
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1283
+			return false;
1284
+		}
1285
+		EE_Config::$_module_route_map[ (string) $key ][ (string) $route ] = array('EED_' . $module, $method_name);
1286
+		return true;
1287
+	}
1288
+
1289
+
1290
+	/**
1291
+	 *    get_route - get module method route
1292
+	 *
1293
+	 * @access    public
1294
+	 * @param    string $route - "pretty" public alias for module method
1295
+	 * @param    string $key   - url param key indicating a route is being called
1296
+	 * @return    string
1297
+	 */
1298
+	public static function get_route($route = null, $key = 'ee')
1299
+	{
1300
+		do_action('AHEE__EE_Config__get_route__begin', $route);
1301
+		$route = (string) apply_filters('FHEE__EE_Config__get_route', $route);
1302
+		if (isset(EE_Config::$_module_route_map[ $key ][ $route ])) {
1303
+			return EE_Config::$_module_route_map[ $key ][ $route ];
1304
+		}
1305
+		return null;
1306
+	}
1307
+
1308
+
1309
+	/**
1310
+	 *    get_routes - get ALL module method routes
1311
+	 *
1312
+	 * @access    public
1313
+	 * @return    array
1314
+	 */
1315
+	public static function get_routes()
1316
+	{
1317
+		return EE_Config::$_module_route_map;
1318
+	}
1319
+
1320
+
1321
+	/**
1322
+	 *    register_forward - allows modules to forward request to another module for further processing
1323
+	 *
1324
+	 * @access    public
1325
+	 * @param    string       $route   - "pretty" public alias for module method
1326
+	 * @param    integer      $status  - integer value corresponding  to status constant strings set in module parent
1327
+	 *                                 class, allows different forwards to be served based on status
1328
+	 * @param    array|string $forward - function name or array( class, method )
1329
+	 * @param    string       $key     - url param key indicating a route is being called
1330
+	 * @return    bool
1331
+	 */
1332
+	public static function register_forward($route = null, $status = 0, $forward = null, $key = 'ee')
1333
+	{
1334
+		do_action('AHEE__EE_Config__register_forward', $route, $status, $forward);
1335
+		if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1336
+			$msg = sprintf(
1337
+				esc_html__('The module route %s for this forward has not been registered.', 'event_espresso'),
1338
+				$route
1339
+			);
1340
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1341
+			return false;
1342
+		}
1343
+		if (empty($forward)) {
1344
+			$msg = sprintf(esc_html__('No forwarding route has been supplied.', 'event_espresso'), $route);
1345
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1346
+			return false;
1347
+		}
1348
+		if (is_array($forward)) {
1349
+			if (! isset($forward[1])) {
1350
+				$msg = sprintf(
1351
+					esc_html__('A class method for the %s forwarding route has not been supplied.', 'event_espresso'),
1352
+					$route
1353
+				);
1354
+				EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1355
+				return false;
1356
+			}
1357
+			if (! method_exists($forward[0], $forward[1])) {
1358
+				$msg = sprintf(
1359
+					esc_html__('The class method %s for the %s forwarding route is in invalid.', 'event_espresso'),
1360
+					$forward[1],
1361
+					$route
1362
+				);
1363
+				EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1364
+				return false;
1365
+			}
1366
+		} elseif (! function_exists($forward)) {
1367
+			$msg = sprintf(
1368
+				esc_html__('The function %s for the %s forwarding route is in invalid.', 'event_espresso'),
1369
+				$forward,
1370
+				$route
1371
+			);
1372
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1373
+			return false;
1374
+		}
1375
+		EE_Config::$_module_forward_map[ $key ][ $route ][ absint($status) ] = $forward;
1376
+		return true;
1377
+	}
1378
+
1379
+
1380
+	/**
1381
+	 *    get_forward - get forwarding route
1382
+	 *
1383
+	 * @access    public
1384
+	 * @param    string  $route  - "pretty" public alias for module method
1385
+	 * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1386
+	 *                           allows different forwards to be served based on status
1387
+	 * @param    string  $key    - url param key indicating a route is being called
1388
+	 * @return    string
1389
+	 */
1390
+	public static function get_forward($route = null, $status = 0, $key = 'ee')
1391
+	{
1392
+		do_action('AHEE__EE_Config__get_forward__begin', $route, $status);
1393
+		if (isset(EE_Config::$_module_forward_map[ $key ][ $route ][ $status ])) {
1394
+			return apply_filters(
1395
+				'FHEE__EE_Config__get_forward',
1396
+				EE_Config::$_module_forward_map[ $key ][ $route ][ $status ],
1397
+				$route,
1398
+				$status
1399
+			);
1400
+		}
1401
+		return null;
1402
+	}
1403
+
1404
+
1405
+	/**
1406
+	 *    register_forward - allows modules to specify different view templates for different method routes and status
1407
+	 *    results
1408
+	 *
1409
+	 * @access    public
1410
+	 * @param    string  $route  - "pretty" public alias for module method
1411
+	 * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1412
+	 *                           allows different views to be served based on status
1413
+	 * @param    string  $view
1414
+	 * @param    string  $key    - url param key indicating a route is being called
1415
+	 * @return    bool
1416
+	 */
1417
+	public static function register_view($route = null, $status = 0, $view = null, $key = 'ee')
1418
+	{
1419
+		do_action('AHEE__EE_Config__register_view__begin', $route, $status, $view);
1420
+		if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1421
+			$msg = sprintf(
1422
+				esc_html__('The module route %s for this view has not been registered.', 'event_espresso'),
1423
+				$route
1424
+			);
1425
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1426
+			return false;
1427
+		}
1428
+		if (! is_readable($view)) {
1429
+			$msg = sprintf(
1430
+				esc_html__(
1431
+					'The %s view file could not be found or is not readable due to file permissions.',
1432
+					'event_espresso'
1433
+				),
1434
+				$view
1435
+			);
1436
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1437
+			return false;
1438
+		}
1439
+		EE_Config::$_module_view_map[ $key ][ $route ][ absint($status) ] = $view;
1440
+		return true;
1441
+	}
1442
+
1443
+
1444
+	/**
1445
+	 *    get_view - get view for route and status
1446
+	 *
1447
+	 * @access    public
1448
+	 * @param    string  $route  - "pretty" public alias for module method
1449
+	 * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1450
+	 *                           allows different views to be served based on status
1451
+	 * @param    string  $key    - url param key indicating a route is being called
1452
+	 * @return    string
1453
+	 */
1454
+	public static function get_view($route = null, $status = 0, $key = 'ee')
1455
+	{
1456
+		do_action('AHEE__EE_Config__get_view__begin', $route, $status);
1457
+		if (isset(EE_Config::$_module_view_map[ $key ][ $route ][ $status ])) {
1458
+			return apply_filters(
1459
+				'FHEE__EE_Config__get_view',
1460
+				EE_Config::$_module_view_map[ $key ][ $route ][ $status ],
1461
+				$route,
1462
+				$status
1463
+			);
1464
+		}
1465
+		return null;
1466
+	}
1467
+
1468
+
1469
+	public function update_addon_option_names()
1470
+	{
1471
+		update_option(EE_Config::ADDON_OPTION_NAMES, $this->_addon_option_names);
1472
+	}
1473
+
1474
+
1475
+	public function shutdown()
1476
+	{
1477
+		$this->update_addon_option_names();
1478
+	}
1479
+
1480
+
1481
+	/**
1482
+	 * @return LegacyShortcodesManager
1483
+	 */
1484
+	public static function getLegacyShortcodesManager()
1485
+	{
1486
+		if (! EE_Config::instance()->legacy_shortcodes_manager instanceof LegacyShortcodesManager) {
1487
+			EE_Config::instance()->legacy_shortcodes_manager = LoaderFactory::getLoader()->getShared(
1488
+				LegacyShortcodesManager::class
1489
+			);
1490
+		}
1491
+		return EE_Config::instance()->legacy_shortcodes_manager;
1492
+	}
1493
+
1494
+
1495
+	/**
1496
+	 * register_shortcode - makes core aware of this shortcode
1497
+	 *
1498
+	 * @deprecated 4.9.26
1499
+	 * @param    string $shortcode_path - full path up to and including shortcode folder
1500
+	 * @return    bool
1501
+	 */
1502
+	public static function register_shortcode($shortcode_path = null)
1503
+	{
1504
+		EE_Error::doing_it_wrong(
1505
+			__METHOD__,
1506
+			esc_html__(
1507
+				'Usage is deprecated. Use \EventEspresso\core\services\shortcodes\LegacyShortcodesManager::registerShortcode() as direct replacement, or better yet, please see the new \EventEspresso\core\services\shortcodes\ShortcodesManager class.',
1508
+				'event_espresso'
1509
+			),
1510
+			'4.9.26'
1511
+		);
1512
+		return EE_Config::instance()->getLegacyShortcodesManager()->registerShortcode($shortcode_path);
1513
+	}
1514
+}
2354 1515
 
2355
-    /**
2356
-     * ReCaptcha width
2357
-     *
2358
-     * @var int $recaptcha_width
2359
-     * @deprecated
2360
-     */
2361
-    public $recaptcha_width;
1516
+/**
1517
+ * Base class used for config classes. These classes should generally not have
1518
+ * magic functions in use, except we'll allow them to magically set and get stuff...
1519
+ * basically, they should just be well-defined stdClasses
1520
+ */
1521
+class EE_Config_Base
1522
+{
1523
+	/**
1524
+	 * Utility function for escaping the value of a property and returning.
1525
+	 *
1526
+	 * @param string $property property name (checks to see if exists).
1527
+	 * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1528
+	 * @throws EE_Error
1529
+	 */
1530
+	public function get_pretty($property)
1531
+	{
1532
+		if (! property_exists($this, $property)) {
1533
+			throw new EE_Error(
1534
+				sprintf(
1535
+					esc_html__(
1536
+						'%1$s::get_pretty() has been called with the property %2$s which does not exist on the %1$s config class.',
1537
+						'event_espresso'
1538
+					),
1539
+					get_class($this),
1540
+					$property
1541
+				)
1542
+			);
1543
+		}
1544
+		// just handling escaping of strings for now.
1545
+		if (is_string($this->{$property})) {
1546
+			return stripslashes($this->{$property});
1547
+		}
1548
+		return $this->{$property};
1549
+	}
1550
+
1551
+
1552
+	public function populate()
1553
+	{
1554
+		// grab defaults via a new instance of this class.
1555
+		$class_name = get_class($this);
1556
+		$defaults = new $class_name();
1557
+		// loop through the properties for this class and see if they are set.  If they are NOT, then grab the
1558
+		// default from our $defaults object.
1559
+		foreach (get_object_vars($defaults) as $property => $value) {
1560
+			if ($this->{$property} === null) {
1561
+				$this->{$property} = $value;
1562
+			}
1563
+		}
1564
+		// cleanup
1565
+		unset($defaults);
1566
+	}
1567
+
1568
+
1569
+	/**
1570
+	 *        __isset
1571
+	 *
1572
+	 * @param $a
1573
+	 * @return bool
1574
+	 */
1575
+	public function __isset($a)
1576
+	{
1577
+		return false;
1578
+	}
1579
+
1580
+
1581
+	/**
1582
+	 *        __unset
1583
+	 *
1584
+	 * @param $a
1585
+	 * @return bool
1586
+	 */
1587
+	public function __unset($a)
1588
+	{
1589
+		return false;
1590
+	}
1591
+
1592
+
1593
+	/**
1594
+	 *        __clone
1595
+	 */
1596
+	public function __clone()
1597
+	{
1598
+	}
1599
+
1600
+
1601
+	/**
1602
+	 *        __wakeup
1603
+	 */
1604
+	public function __wakeup()
1605
+	{
1606
+	}
1607
+
1608
+
1609
+	/**
1610
+	 *        __destruct
1611
+	 */
1612
+	public function __destruct()
1613
+	{
1614
+	}
1615
+}
2362 1616
 
2363
-    /**
2364
-     * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2365
-     *
2366
-     * @var boolean $track_invalid_checkout_access
2367
-     */
2368
-    protected $track_invalid_checkout_access = true;
1617
+/**
1618
+ * Class for defining what's in the EE_Config relating to registration settings
1619
+ */
1620
+class EE_Core_Config extends EE_Config_Base
1621
+{
1622
+	const OPTION_NAME_UXIP = 'ee_ueip_optin';
1623
+
1624
+
1625
+	public $current_blog_id;
1626
+
1627
+	public $ee_ueip_optin;
1628
+
1629
+	public $ee_ueip_has_notified;
1630
+
1631
+	/**
1632
+	 * Not to be confused with the 4 critical page variables (See
1633
+	 * get_critical_pages_array()), this is just an array of wp posts that have EE
1634
+	 * shortcodes in them. Keys are slugs, values are arrays with only 1 element: where the key is the shortcode
1635
+	 * in the page, and the value is the page's ID. The key 'posts' is basically a duplicate of this same array.
1636
+	 *
1637
+	 * @var array
1638
+	 */
1639
+	public $post_shortcodes;
1640
+
1641
+	public $module_route_map;
1642
+
1643
+	public $module_forward_map;
1644
+
1645
+	public $module_view_map;
1646
+
1647
+	/**
1648
+	 * The next 4 vars are the IDs of critical EE pages.
1649
+	 *
1650
+	 * @var int
1651
+	 */
1652
+	public $reg_page_id;
1653
+
1654
+	public $txn_page_id;
1655
+
1656
+	public $thank_you_page_id;
1657
+
1658
+	public $cancel_page_id;
1659
+
1660
+	/**
1661
+	 * The next 4 vars are the URLs of critical EE pages.
1662
+	 *
1663
+	 * @var int
1664
+	 */
1665
+	public $reg_page_url;
1666
+
1667
+	public $txn_page_url;
1668
+
1669
+	public $thank_you_page_url;
1670
+
1671
+	public $cancel_page_url;
1672
+
1673
+	/**
1674
+	 * The next vars relate to the custom slugs for EE CPT routes
1675
+	 */
1676
+	public $event_cpt_slug;
1677
+
1678
+	/**
1679
+	 * This caches the _ee_ueip_option in case this config is reset in the same
1680
+	 * request across blog switches in a multisite context.
1681
+	 * Avoids extra queries to the db for this option.
1682
+	 *
1683
+	 * @var bool
1684
+	 */
1685
+	public static $ee_ueip_option;
1686
+
1687
+
1688
+	/**
1689
+	 *    class constructor
1690
+	 *
1691
+	 * @access    public
1692
+	 */
1693
+	public function __construct()
1694
+	{
1695
+		// set default organization settings
1696
+		$this->current_blog_id = get_current_blog_id();
1697
+		$this->current_blog_id = $this->current_blog_id === null ? 1 : $this->current_blog_id;
1698
+		$this->ee_ueip_optin = $this->_get_main_ee_ueip_optin();
1699
+		$this->ee_ueip_has_notified = is_main_site() ? get_option('ee_ueip_has_notified', false) : true;
1700
+		$this->post_shortcodes = array();
1701
+		$this->module_route_map = array();
1702
+		$this->module_forward_map = array();
1703
+		$this->module_view_map = array();
1704
+		// critical EE page IDs
1705
+		$this->reg_page_id = 0;
1706
+		$this->txn_page_id = 0;
1707
+		$this->thank_you_page_id = 0;
1708
+		$this->cancel_page_id = 0;
1709
+		// critical EE page URLs
1710
+		$this->reg_page_url = '';
1711
+		$this->txn_page_url = '';
1712
+		$this->thank_you_page_url = '';
1713
+		$this->cancel_page_url = '';
1714
+		// cpt slugs
1715
+		$this->event_cpt_slug = esc_html__('events', 'event_espresso');
1716
+		// ueip constant check
1717
+		if (defined('EE_DISABLE_UXIP') && EE_DISABLE_UXIP) {
1718
+			$this->ee_ueip_optin = false;
1719
+			$this->ee_ueip_has_notified = true;
1720
+		}
1721
+	}
1722
+
1723
+
1724
+	/**
1725
+	 * @return array
1726
+	 */
1727
+	public function get_critical_pages_array()
1728
+	{
1729
+		return array(
1730
+			$this->reg_page_id,
1731
+			$this->txn_page_id,
1732
+			$this->thank_you_page_id,
1733
+			$this->cancel_page_id,
1734
+		);
1735
+	}
1736
+
1737
+
1738
+	/**
1739
+	 * @return array
1740
+	 */
1741
+	public function get_critical_pages_shortcodes_array()
1742
+	{
1743
+		return array(
1744
+			$this->reg_page_id       => 'ESPRESSO_CHECKOUT',
1745
+			$this->txn_page_id       => 'ESPRESSO_TXN_PAGE',
1746
+			$this->thank_you_page_id => 'ESPRESSO_THANK_YOU',
1747
+			$this->cancel_page_id    => 'ESPRESSO_CANCELLED',
1748
+		);
1749
+	}
1750
+
1751
+
1752
+	/**
1753
+	 *  gets/returns URL for EE reg_page
1754
+	 *
1755
+	 * @access    public
1756
+	 * @return    string
1757
+	 */
1758
+	public function reg_page_url()
1759
+	{
1760
+		if (! $this->reg_page_url) {
1761
+			$this->reg_page_url = add_query_arg(
1762
+				array('uts' => time()),
1763
+				get_permalink($this->reg_page_id)
1764
+			) . '#checkout';
1765
+		}
1766
+		return $this->reg_page_url;
1767
+	}
1768
+
1769
+
1770
+	/**
1771
+	 *  gets/returns URL for EE txn_page
1772
+	 *
1773
+	 * @param array $query_args like what gets passed to
1774
+	 *                          add_query_arg() as the first argument
1775
+	 * @access    public
1776
+	 * @return    string
1777
+	 */
1778
+	public function txn_page_url($query_args = array())
1779
+	{
1780
+		if (! $this->txn_page_url) {
1781
+			$this->txn_page_url = get_permalink($this->txn_page_id);
1782
+		}
1783
+		if ($query_args) {
1784
+			return add_query_arg($query_args, $this->txn_page_url);
1785
+		} else {
1786
+			return $this->txn_page_url;
1787
+		}
1788
+	}
1789
+
1790
+
1791
+	/**
1792
+	 *  gets/returns URL for EE thank_you_page
1793
+	 *
1794
+	 * @param array $query_args like what gets passed to
1795
+	 *                          add_query_arg() as the first argument
1796
+	 * @access    public
1797
+	 * @return    string
1798
+	 */
1799
+	public function thank_you_page_url($query_args = array())
1800
+	{
1801
+		if (! $this->thank_you_page_url) {
1802
+			$this->thank_you_page_url = get_permalink($this->thank_you_page_id);
1803
+		}
1804
+		if ($query_args) {
1805
+			return add_query_arg($query_args, $this->thank_you_page_url);
1806
+		} else {
1807
+			return $this->thank_you_page_url;
1808
+		}
1809
+	}
1810
+
1811
+
1812
+	/**
1813
+	 *  gets/returns URL for EE cancel_page
1814
+	 *
1815
+	 * @access    public
1816
+	 * @return    string
1817
+	 */
1818
+	public function cancel_page_url()
1819
+	{
1820
+		if (! $this->cancel_page_url) {
1821
+			$this->cancel_page_url = get_permalink($this->cancel_page_id);
1822
+		}
1823
+		return $this->cancel_page_url;
1824
+	}
1825
+
1826
+
1827
+	/**
1828
+	 * Resets all critical page urls to their original state.  Used primarily by the __sleep() magic method currently.
1829
+	 *
1830
+	 * @since 4.7.5
1831
+	 */
1832
+	protected function _reset_urls()
1833
+	{
1834
+		$this->reg_page_url = '';
1835
+		$this->txn_page_url = '';
1836
+		$this->cancel_page_url = '';
1837
+		$this->thank_you_page_url = '';
1838
+	}
1839
+
1840
+
1841
+	/**
1842
+	 * Used to return what the optin value is set for the EE User Experience Program.
1843
+	 * This accounts for multisite and this value being requested for a subsite.  In multisite, the value is set
1844
+	 * on the main site only.
1845
+	 *
1846
+	 * @return bool
1847
+	 */
1848
+	protected function _get_main_ee_ueip_optin()
1849
+	{
1850
+		// if this is the main site then we can just bypass our direct query.
1851
+		if (is_main_site()) {
1852
+			return get_option(self::OPTION_NAME_UXIP, false);
1853
+		}
1854
+		// is this already cached for this request?  If so use it.
1855
+		if (EE_Core_Config::$ee_ueip_option !== null) {
1856
+			return EE_Core_Config::$ee_ueip_option;
1857
+		}
1858
+		global $wpdb;
1859
+		$current_network_main_site = is_multisite() ? get_current_site() : null;
1860
+		$current_main_site_id = ! empty($current_network_main_site) ? $current_network_main_site->blog_id : 1;
1861
+		$option = self::OPTION_NAME_UXIP;
1862
+		// set correct table for query
1863
+		$table_name = $wpdb->get_blog_prefix($current_main_site_id) . 'options';
1864
+		// rather than getting blog option for the $current_main_site_id, we do a direct $wpdb query because
1865
+		// get_blog_option() does a switch_to_blog an that could cause infinite recursion because EE_Core_Config might be
1866
+		// re-constructed on the blog switch.  Note, we are still executing any core wp filters on this option retrieval.
1867
+		// this bit of code is basically a direct copy of get_option without any caching because we are NOT switched to the blog
1868
+		// for the purpose of caching.
1869
+		$pre = apply_filters('pre_option_' . $option, false, $option);
1870
+		if (false !== $pre) {
1871
+			EE_Core_Config::$ee_ueip_option = $pre;
1872
+			return EE_Core_Config::$ee_ueip_option;
1873
+		}
1874
+		$row = $wpdb->get_row(
1875
+			$wpdb->prepare(
1876
+				"SELECT option_value FROM $table_name WHERE option_name = %s LIMIT 1",
1877
+				$option
1878
+			)
1879
+		);
1880
+		if (is_object($row)) {
1881
+			$value = $row->option_value;
1882
+		} else { // option does not exist so use default.
1883
+			EE_Core_Config::$ee_ueip_option =  apply_filters('default_option_' . $option, false, $option);
1884
+			return EE_Core_Config::$ee_ueip_option;
1885
+		}
1886
+		EE_Core_Config::$ee_ueip_option = apply_filters('option_' . $option, maybe_unserialize($value), $option);
1887
+		return EE_Core_Config::$ee_ueip_option;
1888
+	}
1889
+
1890
+
1891
+	/**
1892
+	 * Utility function for escaping the value of a property and returning.
1893
+	 *
1894
+	 * @param string $property property name (checks to see if exists).
1895
+	 * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1896
+	 * @throws EE_Error
1897
+	 */
1898
+	public function get_pretty($property)
1899
+	{
1900
+		if ($property === self::OPTION_NAME_UXIP) {
1901
+			return $this->ee_ueip_optin ? 'yes' : 'no';
1902
+		}
1903
+		return parent::get_pretty($property);
1904
+	}
1905
+
1906
+
1907
+	/**
1908
+	 * Currently used to ensure critical page urls have initial values saved to the db instead of any current set values
1909
+	 * on the object.
1910
+	 *
1911
+	 * @return array
1912
+	 */
1913
+	public function __sleep()
1914
+	{
1915
+		// reset all url properties
1916
+		$this->_reset_urls();
1917
+		// return what to save to db
1918
+		return array_keys(get_object_vars($this));
1919
+	}
1920
+}
2369 1921
 
2370
-    /**
2371
-     * Whether or not to show the privacy policy consent checkbox
2372
-     *
2373
-     * @var bool
2374
-     */
2375
-    public $consent_checkbox_enabled;
1922
+/**
1923
+ * Config class for storing info on the Organization
1924
+ */
1925
+class EE_Organization_Config extends EE_Config_Base
1926
+{
1927
+	/**
1928
+	 * @var string $name
1929
+	 * eg EE4.1
1930
+	 */
1931
+	public $name;
1932
+
1933
+	/**
1934
+	 * @var string $address_1
1935
+	 * eg 123 Onna Road
1936
+	 */
1937
+	public $address_1 = '';
1938
+
1939
+	/**
1940
+	 * @var string $address_2
1941
+	 * eg PO Box 123
1942
+	 */
1943
+	public $address_2 = '';
1944
+
1945
+	/**
1946
+	 * @var string $city
1947
+	 * eg Inna City
1948
+	 */
1949
+	public $city = '';
1950
+
1951
+	/**
1952
+	 * @var int $STA_ID
1953
+	 * eg 4
1954
+	 */
1955
+	public $STA_ID = 0;
1956
+
1957
+	/**
1958
+	 * @var string $CNT_ISO
1959
+	 * eg US
1960
+	 */
1961
+	public $CNT_ISO = '';
1962
+
1963
+	/**
1964
+	 * @var string $zip
1965
+	 * eg 12345  or V1A 2B3
1966
+	 */
1967
+	public $zip = '';
1968
+
1969
+	/**
1970
+	 * @var string $email
1971
+	 * eg [email protected]
1972
+	 */
1973
+	public $email;
1974
+
1975
+	/**
1976
+	 * @var string $phone
1977
+	 * eg. 111-111-1111
1978
+	 */
1979
+	public $phone = '';
1980
+
1981
+	/**
1982
+	 * @var string $vat
1983
+	 * VAT/Tax Number
1984
+	 */
1985
+	public $vat = '';
1986
+
1987
+	/**
1988
+	 * @var string $logo_url
1989
+	 * eg http://www.somedomain.com/wp-content/uploads/kittehs.jpg
1990
+	 */
1991
+	public $logo_url = '';
1992
+
1993
+	/**
1994
+	 * The below are all various properties for holding links to organization social network profiles
1995
+	 *
1996
+	 * @var string
1997
+	 */
1998
+	/**
1999
+	 * facebook (facebook.com/profile.name)
2000
+	 *
2001
+	 * @var string
2002
+	 */
2003
+	public $facebook = '';
2004
+
2005
+	/**
2006
+	 * twitter (twitter.com/twitter_handle)
2007
+	 *
2008
+	 * @var string
2009
+	 */
2010
+	public $twitter = '';
2011
+
2012
+	/**
2013
+	 * linkedin (linkedin.com/in/profile_name)
2014
+	 *
2015
+	 * @var string
2016
+	 */
2017
+	public $linkedin = '';
2018
+
2019
+	/**
2020
+	 * pinterest (www.pinterest.com/profile_name)
2021
+	 *
2022
+	 * @var string
2023
+	 */
2024
+	public $pinterest = '';
2025
+
2026
+	/**
2027
+	 * google+ (google.com/+profileName)
2028
+	 *
2029
+	 * @var string
2030
+	 */
2031
+	public $google = '';
2032
+
2033
+	/**
2034
+	 * instagram (instagram.com/handle)
2035
+	 *
2036
+	 * @var string
2037
+	 */
2038
+	public $instagram = '';
2039
+
2040
+
2041
+	/**
2042
+	 *    class constructor
2043
+	 *
2044
+	 * @access    public
2045
+	 */
2046
+	public function __construct()
2047
+	{
2048
+		// set default organization settings
2049
+		// decode HTML entities from the WP blogname, because it's stored in the DB with HTML entities encoded
2050
+		$this->name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
2051
+		$this->email = get_bloginfo('admin_email');
2052
+	}
2053
+}
2376 2054
 
2377
-    /**
2378
-     * Label text to show on the checkbox
2379
-     *
2380
-     * @var string
2381
-     */
2382
-    public $consent_checkbox_label_text;
2055
+/**
2056
+ * Class for defining what's in the EE_Config relating to currency
2057
+ */
2058
+class EE_Currency_Config extends EE_Config_Base
2059
+{
2060
+	/**
2061
+	 * @var string $code
2062
+	 * eg 'US'
2063
+	 */
2064
+	public $code;
2065
+
2066
+	/**
2067
+	 * @var string $name
2068
+	 * eg 'Dollar'
2069
+	 */
2070
+	public $name;
2071
+
2072
+	/**
2073
+	 * plural name
2074
+	 *
2075
+	 * @var string $plural
2076
+	 * eg 'Dollars'
2077
+	 */
2078
+	public $plural;
2079
+
2080
+	/**
2081
+	 * currency sign
2082
+	 *
2083
+	 * @var string $sign
2084
+	 * eg '$'
2085
+	 */
2086
+	public $sign;
2087
+
2088
+	/**
2089
+	 * Whether the currency sign should come before the number or not
2090
+	 *
2091
+	 * @var boolean $sign_b4
2092
+	 */
2093
+	public $sign_b4;
2094
+
2095
+	/**
2096
+	 * How many digits should come after the decimal place
2097
+	 *
2098
+	 * @var int $dec_plc
2099
+	 */
2100
+	public $dec_plc;
2101
+
2102
+	/**
2103
+	 * Symbol to use for decimal mark
2104
+	 *
2105
+	 * @var string $dec_mrk
2106
+	 * eg '.'
2107
+	 */
2108
+	public $dec_mrk;
2109
+
2110
+	/**
2111
+	 * Symbol to use for thousands
2112
+	 *
2113
+	 * @var string $thsnds
2114
+	 * eg ','
2115
+	 */
2116
+	public $thsnds;
2117
+
2118
+
2119
+	/**
2120
+	 *    class constructor
2121
+	 *
2122
+	 * @access    public
2123
+	 * @param string $CNT_ISO
2124
+	 * @throws EE_Error
2125
+	 * @throws ReflectionException
2126
+	 */
2127
+	public function __construct($CNT_ISO = '')
2128
+	{
2129
+		if ($CNT_ISO && $CNT_ISO === $this->code) {
2130
+			return;
2131
+		}
2132
+		// get country code from organization settings or use default
2133
+		$ORG_CNT = isset(EE_Registry::instance()->CFG->organization)
2134
+				   && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
2135
+			? EE_Registry::instance()->CFG->organization->CNT_ISO
2136
+			: '';
2137
+		// but override if requested
2138
+		$CNT_ISO = ! empty($CNT_ISO) ? $CNT_ISO : $ORG_CNT;
2139
+		// so if that all went well, and we are not in M-Mode (cuz you can't query the db in M-Mode) and double-check the countries table exists
2140
+		$this->setCurrency($CNT_ISO);
2141
+		// fallback to hardcoded defaults, in case the above failed
2142
+		if (empty($this->code)) {
2143
+			$this->setFallbackCurrency();
2144
+		}
2145
+	}
2146
+
2147
+
2148
+	/**
2149
+	 * @param string|null $CNT_ISO
2150
+	 * @throws EE_Error
2151
+	 * @throws ReflectionException
2152
+	 */
2153
+	public function setCurrency(?string $CNT_ISO = '')
2154
+	{
2155
+		if (empty($CNT_ISO) || ! EE_Maintenance_Mode::instance()->models_can_query()) {
2156
+			return;
2157
+		}
2158
+
2159
+		/** @var TableAnalysis $table_analysis */
2160
+		$table_analysis = EE_Registry::instance()->create('TableAnalysis', [], true);
2161
+		if (! $table_analysis->tableExists(EE_Registry::instance()->load_model('Country')->table())) {
2162
+			return;
2163
+		}
2164
+		// retrieve the country settings from the db, just in case they have been customized
2165
+		$country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
2166
+		if (! $country instanceof EE_Country) {
2167
+			throw new DomainException(
2168
+				esc_html__('Invalid Country ISO Code.', 'event_espresso')
2169
+			);
2170
+		}
2171
+		$this->code    = $country->currency_code();                  // currency code: USD, CAD, EUR
2172
+		$this->name    = $country->currency_name_single();           // Dollar
2173
+		$this->plural  = $country->currency_name_plural();           // Dollars
2174
+		$this->sign    = $country->currency_sign();                  // currency sign: $
2175
+		$this->sign_b4 = $country->currency_sign_before();           // currency sign before or after
2176
+		$this->dec_plc = $country->currency_decimal_places();        // decimal places: 2 = 0.00  3 = 0.000
2177
+		$this->dec_mrk = $country->currency_decimal_mark();          // decimal mark: ',' = 0,01 or '.' = 0.01
2178
+		$this->thsnds  = $country->currency_thousands_separator();   // thousands sep: ',' = 1,000 or '.' = 1.000
2179
+	}
2180
+
2181
+
2182
+	private function setFallbackCurrency()
2183
+	{
2184
+		// set default currency settings
2185
+		$this->code    = 'USD';
2186
+		$this->name    = esc_html__('Dollar', 'event_espresso');
2187
+		$this->plural  = esc_html__('Dollars', 'event_espresso');
2188
+		$this->sign    = '$';
2189
+		$this->sign_b4 = true;
2190
+		$this->dec_plc = 2;
2191
+		$this->dec_mrk = '.';
2192
+		$this->thsnds  = ',';
2193
+	}
2194
+
2195
+
2196
+	/**
2197
+	 * @param string|null $CNT_ISO
2198
+	 * @return EE_Currency_Config
2199
+	 * @throws EE_Error
2200
+	 * @throws ReflectionException
2201
+	 */
2202
+	public static function getCurrencyConfig(?string $CNT_ISO = ''): EE_Currency_Config
2203
+	{
2204
+		// if CNT_ISO passed lets try to get currency settings for it.
2205
+		$currency_config = ! empty($CNT_ISO)
2206
+			? new EE_Currency_Config($CNT_ISO)
2207
+			: null;
2208
+		// default currency settings for site if not set
2209
+		if ($currency_config instanceof EE_Currency_Config) {
2210
+			return $currency_config;
2211
+		}
2212
+		EE_Config::instance()->currency = EE_Config::instance()->currency instanceof EE_Currency_Config
2213
+			? EE_Config::instance()->currency
2214
+			: new EE_Currency_Config();
2215
+		return EE_Config::instance()->currency;
2216
+	}
2217
+}
2383 2218
 
2384
-    /*
2219
+/**
2220
+ * Class for defining what's in the EE_Config relating to registration settings
2221
+ */
2222
+class EE_Registration_Config extends EE_Config_Base
2223
+{
2224
+	/**
2225
+	 * Default registration status
2226
+	 *
2227
+	 * @var string $default_STS_ID
2228
+	 * eg 'RPP'
2229
+	 */
2230
+	public $default_STS_ID;
2231
+
2232
+	/**
2233
+	 * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2234
+	 * registrations)
2235
+	 *
2236
+	 * @var int
2237
+	 */
2238
+	public $default_maximum_number_of_tickets;
2239
+
2240
+	/**
2241
+	 * level of validation to apply to email addresses
2242
+	 *
2243
+	 * @var string $email_validation_level
2244
+	 * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2245
+	 */
2246
+	public $email_validation_level;
2247
+
2248
+	/**
2249
+	 *    whether or not to show alternate payment options during the reg process if payment status is pending
2250
+	 *
2251
+	 * @var boolean $show_pending_payment_options
2252
+	 */
2253
+	public $show_pending_payment_options;
2254
+
2255
+	/**
2256
+	 * Whether to skip the registration confirmation page
2257
+	 *
2258
+	 * @var boolean $skip_reg_confirmation
2259
+	 */
2260
+	public $skip_reg_confirmation;
2261
+
2262
+	/**
2263
+	 * an array of SPCO reg steps where:
2264
+	 *        the keys denotes the reg step order
2265
+	 *        each element consists of an array with the following elements:
2266
+	 *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2267
+	 *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2268
+	 *            "slug" => the URL param used to trigger the reg step
2269
+	 *
2270
+	 * @var array $reg_steps
2271
+	 */
2272
+	public $reg_steps;
2273
+
2274
+	/**
2275
+	 * Whether registration confirmation should be the last page of SPCO
2276
+	 *
2277
+	 * @var boolean $reg_confirmation_last
2278
+	 */
2279
+	public $reg_confirmation_last;
2280
+
2281
+	/**
2282
+	 * Whether or not to enable the EE Bot Trap
2283
+	 *
2284
+	 * @var boolean $use_bot_trap
2285
+	 */
2286
+	public $use_bot_trap;
2287
+
2288
+	/**
2289
+	 * Whether or not to encrypt some data sent by the EE Bot Trap
2290
+	 *
2291
+	 * @var boolean $use_encryption
2292
+	 */
2293
+	public $use_encryption;
2294
+
2295
+	/**
2296
+	 * Whether or not to use ReCaptcha
2297
+	 *
2298
+	 * @var boolean $use_captcha
2299
+	 */
2300
+	public $use_captcha;
2301
+
2302
+	/**
2303
+	 * ReCaptcha Theme
2304
+	 *
2305
+	 * @var string $recaptcha_theme
2306
+	 *    options: 'dark', 'light', 'invisible'
2307
+	 */
2308
+	public $recaptcha_theme;
2309
+
2310
+	/**
2311
+	 * ReCaptcha Badge - determines the position of the reCAPTCHA badge if using Invisible ReCaptcha.
2312
+	 *
2313
+	 * @var string $recaptcha_badge
2314
+	 *    options: 'bottomright', 'bottomleft', 'inline'
2315
+	 */
2316
+	public $recaptcha_badge;
2317
+
2318
+	/**
2319
+	 * ReCaptcha Type
2320
+	 *
2321
+	 * @var string $recaptcha_type
2322
+	 *    options: 'audio', 'image'
2323
+	 */
2324
+	public $recaptcha_type;
2325
+
2326
+	/**
2327
+	 * ReCaptcha language
2328
+	 *
2329
+	 * @var string $recaptcha_language
2330
+	 * eg 'en'
2331
+	 */
2332
+	public $recaptcha_language;
2333
+
2334
+	/**
2335
+	 * ReCaptcha public key
2336
+	 *
2337
+	 * @var string $recaptcha_publickey
2338
+	 */
2339
+	public $recaptcha_publickey;
2340
+
2341
+	/**
2342
+	 * ReCaptcha private key
2343
+	 *
2344
+	 * @var string $recaptcha_privatekey
2345
+	 */
2346
+	public $recaptcha_privatekey;
2347
+
2348
+	/**
2349
+	 * array of form names protected by ReCaptcha
2350
+	 *
2351
+	 * @var array $recaptcha_protected_forms
2352
+	 */
2353
+	public $recaptcha_protected_forms;
2354
+
2355
+	/**
2356
+	 * ReCaptcha width
2357
+	 *
2358
+	 * @var int $recaptcha_width
2359
+	 * @deprecated
2360
+	 */
2361
+	public $recaptcha_width;
2362
+
2363
+	/**
2364
+	 * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2365
+	 *
2366
+	 * @var boolean $track_invalid_checkout_access
2367
+	 */
2368
+	protected $track_invalid_checkout_access = true;
2369
+
2370
+	/**
2371
+	 * Whether or not to show the privacy policy consent checkbox
2372
+	 *
2373
+	 * @var bool
2374
+	 */
2375
+	public $consent_checkbox_enabled;
2376
+
2377
+	/**
2378
+	 * Label text to show on the checkbox
2379
+	 *
2380
+	 * @var string
2381
+	 */
2382
+	public $consent_checkbox_label_text;
2383
+
2384
+	/*
2385 2385
      * String describing how long to keep payment logs. Passed into DateTime constructor
2386 2386
      * @var string
2387 2387
      */
2388
-    public $gateway_log_lifespan = '1 week';
2389
-
2390
-    /**
2391
-     * Enable copy attendee info at form
2392
-     *
2393
-     * @var boolean $enable_copy_attendee
2394
-     */
2395
-    protected $copy_attendee_info = true;
2396
-
2397
-
2398
-    /**
2399
-     *    class constructor
2400
-     *
2401
-     * @access    public
2402
-     */
2403
-    public function __construct()
2404
-    {
2405
-        // set default registration settings
2406
-        $this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2407
-        $this->email_validation_level = 'wp_default';
2408
-        $this->show_pending_payment_options = true;
2409
-        $this->skip_reg_confirmation = true;
2410
-        $this->reg_steps = array();
2411
-        $this->reg_confirmation_last = false;
2412
-        $this->use_bot_trap = true;
2413
-        $this->use_encryption = true;
2414
-        $this->use_captcha = false;
2415
-        $this->recaptcha_theme = 'light';
2416
-        $this->recaptcha_badge = 'bottomleft';
2417
-        $this->recaptcha_type = 'image';
2418
-        $this->recaptcha_language = 'en';
2419
-        $this->recaptcha_publickey = null;
2420
-        $this->recaptcha_privatekey = null;
2421
-        $this->recaptcha_protected_forms = array();
2422
-        $this->recaptcha_width = 500;
2423
-        $this->default_maximum_number_of_tickets = 10;
2424
-        $this->consent_checkbox_enabled = false;
2425
-        $this->consent_checkbox_label_text = '';
2426
-        $this->gateway_log_lifespan = '7 days';
2427
-        $this->copy_attendee_info = true;
2428
-    }
2429
-
2430
-
2431
-    /**
2432
-     * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2433
-     *
2434
-     * @since 4.8.8.rc.019
2435
-     */
2436
-    public function do_hooks()
2437
-    {
2438
-        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2439
-        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2440
-        add_action('setup_theme', array($this, 'setDefaultCheckboxLabelText'));
2441
-    }
2442
-
2443
-
2444
-    /**
2445
-     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the
2446
-     * EVT_default_registration_status field matches the config setting for default_STS_ID.
2447
-     */
2448
-    public function set_default_reg_status_on_EEM_Event()
2449
-    {
2450
-        EEM_Event::set_default_reg_status($this->default_STS_ID);
2451
-    }
2452
-
2453
-
2454
-    /**
2455
-     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2456
-     * for Events matches the config setting for default_maximum_number_of_tickets
2457
-     */
2458
-    public function set_default_max_ticket_on_EEM_Event()
2459
-    {
2460
-        EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2461
-    }
2462
-
2463
-
2464
-    /**
2465
-     * Sets the default consent checkbox text. This needs to be done a bit later than when EE_Registration_Config is
2466
-     * constructed because that happens before we can get the privacy policy page's permalink.
2467
-     *
2468
-     * @throws InvalidArgumentException
2469
-     * @throws InvalidDataTypeException
2470
-     * @throws InvalidInterfaceException
2471
-     */
2472
-    public function setDefaultCheckboxLabelText()
2473
-    {
2474
-        if (
2475
-            $this->getConsentCheckboxLabelText() === null
2476
-            || $this->getConsentCheckboxLabelText() === ''
2477
-        ) {
2478
-            $opening_a_tag = '';
2479
-            $closing_a_tag = '';
2480
-            if (function_exists('get_privacy_policy_url')) {
2481
-                $privacy_page_url = get_privacy_policy_url();
2482
-                if (! empty($privacy_page_url)) {
2483
-                    $opening_a_tag = '<a href="' . $privacy_page_url . '" target="_blank">';
2484
-                    $closing_a_tag = '</a>';
2485
-                }
2486
-            }
2487
-            $loader = LoaderFactory::getLoader();
2488
-            $org_config = $loader->getShared('EE_Organization_Config');
2489
-            /**
2490
-             * @var $org_config EE_Organization_Config
2491
-             */
2492
-
2493
-            $this->setConsentCheckboxLabelText(
2494
-                sprintf(
2495
-                    esc_html__(
2496
-                        'I consent to %1$s storing and using my personal information, according to their %2$sprivacy policy%3$s.',
2497
-                        'event_espresso'
2498
-                    ),
2499
-                    $org_config->name,
2500
-                    $opening_a_tag,
2501
-                    $closing_a_tag
2502
-                )
2503
-            );
2504
-        }
2505
-    }
2506
-
2507
-
2508
-    /**
2509
-     * @return boolean
2510
-     */
2511
-    public function track_invalid_checkout_access()
2512
-    {
2513
-        return $this->track_invalid_checkout_access;
2514
-    }
2515
-
2516
-
2517
-    /**
2518
-     * @param boolean $track_invalid_checkout_access
2519
-     */
2520
-    public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2521
-    {
2522
-        $this->track_invalid_checkout_access = filter_var(
2523
-            $track_invalid_checkout_access,
2524
-            FILTER_VALIDATE_BOOLEAN
2525
-        );
2526
-    }
2527
-
2528
-    /**
2529
-     * @return boolean
2530
-     */
2531
-    public function copyAttendeeInfo()
2532
-    {
2533
-        return $this->copy_attendee_info;
2534
-    }
2535
-
2536
-
2537
-    /**
2538
-     * @param boolean $copy_attendee_info
2539
-     */
2540
-    public function setCopyAttendeeInfo($copy_attendee_info)
2541
-    {
2542
-        $this->copy_attendee_info = filter_var(
2543
-            $copy_attendee_info,
2544
-            FILTER_VALIDATE_BOOLEAN
2545
-        );
2546
-    }
2547
-
2548
-
2549
-    /**
2550
-     * Gets the options to make availalbe for the gateway log lifespan
2551
-     * @return array
2552
-     */
2553
-    public function gatewayLogLifespanOptions()
2554
-    {
2555
-        return (array) apply_filters(
2556
-            'FHEE_EE_Admin_Config__gatewayLogLifespanOptions',
2557
-            array(
2558
-                '1 second' => esc_html__('Don\'t Log At All', 'event_espresso'),
2559
-                '1 day' => esc_html__('1 Day', 'event_espresso'),
2560
-                '7 days' => esc_html__('7 Days', 'event_espresso'),
2561
-                '14 days' => esc_html__('14 Days', 'event_espresso'),
2562
-                '30 days' => esc_html__('30 Days', 'event_espresso')
2563
-            )
2564
-        );
2565
-    }
2566
-
2567
-
2568
-    /**
2569
-     * @return bool
2570
-     */
2571
-    public function isConsentCheckboxEnabled()
2572
-    {
2573
-        return $this->consent_checkbox_enabled;
2574
-    }
2575
-
2576
-
2577
-    /**
2578
-     * @param bool $consent_checkbox_enabled
2579
-     */
2580
-    public function setConsentCheckboxEnabled($consent_checkbox_enabled)
2581
-    {
2582
-        $this->consent_checkbox_enabled = filter_var(
2583
-            $consent_checkbox_enabled,
2584
-            FILTER_VALIDATE_BOOLEAN
2585
-        );
2586
-    }
2587
-
2588
-
2589
-    /**
2590
-     * @return string
2591
-     */
2592
-    public function getConsentCheckboxLabelText()
2593
-    {
2594
-        return $this->consent_checkbox_label_text;
2595
-    }
2596
-
2597
-
2598
-    /**
2599
-     * @param string $consent_checkbox_label_text
2600
-     */
2601
-    public function setConsentCheckboxLabelText($consent_checkbox_label_text)
2602
-    {
2603
-        $this->consent_checkbox_label_text = (string) $consent_checkbox_label_text;
2604
-    }
2388
+	public $gateway_log_lifespan = '1 week';
2389
+
2390
+	/**
2391
+	 * Enable copy attendee info at form
2392
+	 *
2393
+	 * @var boolean $enable_copy_attendee
2394
+	 */
2395
+	protected $copy_attendee_info = true;
2396
+
2397
+
2398
+	/**
2399
+	 *    class constructor
2400
+	 *
2401
+	 * @access    public
2402
+	 */
2403
+	public function __construct()
2404
+	{
2405
+		// set default registration settings
2406
+		$this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2407
+		$this->email_validation_level = 'wp_default';
2408
+		$this->show_pending_payment_options = true;
2409
+		$this->skip_reg_confirmation = true;
2410
+		$this->reg_steps = array();
2411
+		$this->reg_confirmation_last = false;
2412
+		$this->use_bot_trap = true;
2413
+		$this->use_encryption = true;
2414
+		$this->use_captcha = false;
2415
+		$this->recaptcha_theme = 'light';
2416
+		$this->recaptcha_badge = 'bottomleft';
2417
+		$this->recaptcha_type = 'image';
2418
+		$this->recaptcha_language = 'en';
2419
+		$this->recaptcha_publickey = null;
2420
+		$this->recaptcha_privatekey = null;
2421
+		$this->recaptcha_protected_forms = array();
2422
+		$this->recaptcha_width = 500;
2423
+		$this->default_maximum_number_of_tickets = 10;
2424
+		$this->consent_checkbox_enabled = false;
2425
+		$this->consent_checkbox_label_text = '';
2426
+		$this->gateway_log_lifespan = '7 days';
2427
+		$this->copy_attendee_info = true;
2428
+	}
2429
+
2430
+
2431
+	/**
2432
+	 * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2433
+	 *
2434
+	 * @since 4.8.8.rc.019
2435
+	 */
2436
+	public function do_hooks()
2437
+	{
2438
+		add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2439
+		add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2440
+		add_action('setup_theme', array($this, 'setDefaultCheckboxLabelText'));
2441
+	}
2442
+
2443
+
2444
+	/**
2445
+	 * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the
2446
+	 * EVT_default_registration_status field matches the config setting for default_STS_ID.
2447
+	 */
2448
+	public function set_default_reg_status_on_EEM_Event()
2449
+	{
2450
+		EEM_Event::set_default_reg_status($this->default_STS_ID);
2451
+	}
2452
+
2453
+
2454
+	/**
2455
+	 * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2456
+	 * for Events matches the config setting for default_maximum_number_of_tickets
2457
+	 */
2458
+	public function set_default_max_ticket_on_EEM_Event()
2459
+	{
2460
+		EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2461
+	}
2462
+
2463
+
2464
+	/**
2465
+	 * Sets the default consent checkbox text. This needs to be done a bit later than when EE_Registration_Config is
2466
+	 * constructed because that happens before we can get the privacy policy page's permalink.
2467
+	 *
2468
+	 * @throws InvalidArgumentException
2469
+	 * @throws InvalidDataTypeException
2470
+	 * @throws InvalidInterfaceException
2471
+	 */
2472
+	public function setDefaultCheckboxLabelText()
2473
+	{
2474
+		if (
2475
+			$this->getConsentCheckboxLabelText() === null
2476
+			|| $this->getConsentCheckboxLabelText() === ''
2477
+		) {
2478
+			$opening_a_tag = '';
2479
+			$closing_a_tag = '';
2480
+			if (function_exists('get_privacy_policy_url')) {
2481
+				$privacy_page_url = get_privacy_policy_url();
2482
+				if (! empty($privacy_page_url)) {
2483
+					$opening_a_tag = '<a href="' . $privacy_page_url . '" target="_blank">';
2484
+					$closing_a_tag = '</a>';
2485
+				}
2486
+			}
2487
+			$loader = LoaderFactory::getLoader();
2488
+			$org_config = $loader->getShared('EE_Organization_Config');
2489
+			/**
2490
+			 * @var $org_config EE_Organization_Config
2491
+			 */
2492
+
2493
+			$this->setConsentCheckboxLabelText(
2494
+				sprintf(
2495
+					esc_html__(
2496
+						'I consent to %1$s storing and using my personal information, according to their %2$sprivacy policy%3$s.',
2497
+						'event_espresso'
2498
+					),
2499
+					$org_config->name,
2500
+					$opening_a_tag,
2501
+					$closing_a_tag
2502
+				)
2503
+			);
2504
+		}
2505
+	}
2506
+
2507
+
2508
+	/**
2509
+	 * @return boolean
2510
+	 */
2511
+	public function track_invalid_checkout_access()
2512
+	{
2513
+		return $this->track_invalid_checkout_access;
2514
+	}
2515
+
2516
+
2517
+	/**
2518
+	 * @param boolean $track_invalid_checkout_access
2519
+	 */
2520
+	public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2521
+	{
2522
+		$this->track_invalid_checkout_access = filter_var(
2523
+			$track_invalid_checkout_access,
2524
+			FILTER_VALIDATE_BOOLEAN
2525
+		);
2526
+	}
2527
+
2528
+	/**
2529
+	 * @return boolean
2530
+	 */
2531
+	public function copyAttendeeInfo()
2532
+	{
2533
+		return $this->copy_attendee_info;
2534
+	}
2535
+
2536
+
2537
+	/**
2538
+	 * @param boolean $copy_attendee_info
2539
+	 */
2540
+	public function setCopyAttendeeInfo($copy_attendee_info)
2541
+	{
2542
+		$this->copy_attendee_info = filter_var(
2543
+			$copy_attendee_info,
2544
+			FILTER_VALIDATE_BOOLEAN
2545
+		);
2546
+	}
2547
+
2548
+
2549
+	/**
2550
+	 * Gets the options to make availalbe for the gateway log lifespan
2551
+	 * @return array
2552
+	 */
2553
+	public function gatewayLogLifespanOptions()
2554
+	{
2555
+		return (array) apply_filters(
2556
+			'FHEE_EE_Admin_Config__gatewayLogLifespanOptions',
2557
+			array(
2558
+				'1 second' => esc_html__('Don\'t Log At All', 'event_espresso'),
2559
+				'1 day' => esc_html__('1 Day', 'event_espresso'),
2560
+				'7 days' => esc_html__('7 Days', 'event_espresso'),
2561
+				'14 days' => esc_html__('14 Days', 'event_espresso'),
2562
+				'30 days' => esc_html__('30 Days', 'event_espresso')
2563
+			)
2564
+		);
2565
+	}
2566
+
2567
+
2568
+	/**
2569
+	 * @return bool
2570
+	 */
2571
+	public function isConsentCheckboxEnabled()
2572
+	{
2573
+		return $this->consent_checkbox_enabled;
2574
+	}
2575
+
2576
+
2577
+	/**
2578
+	 * @param bool $consent_checkbox_enabled
2579
+	 */
2580
+	public function setConsentCheckboxEnabled($consent_checkbox_enabled)
2581
+	{
2582
+		$this->consent_checkbox_enabled = filter_var(
2583
+			$consent_checkbox_enabled,
2584
+			FILTER_VALIDATE_BOOLEAN
2585
+		);
2586
+	}
2587
+
2588
+
2589
+	/**
2590
+	 * @return string
2591
+	 */
2592
+	public function getConsentCheckboxLabelText()
2593
+	{
2594
+		return $this->consent_checkbox_label_text;
2595
+	}
2596
+
2597
+
2598
+	/**
2599
+	 * @param string $consent_checkbox_label_text
2600
+	 */
2601
+	public function setConsentCheckboxLabelText($consent_checkbox_label_text)
2602
+	{
2603
+		$this->consent_checkbox_label_text = (string) $consent_checkbox_label_text;
2604
+	}
2605 2605
 }
2606 2606
 
2607 2607
 /**
@@ -2609,180 +2609,180 @@  discard block
 block discarded – undo
2609 2609
  */
2610 2610
 class EE_Admin_Config extends EE_Config_Base
2611 2611
 {
2612
-    /**
2613
-     * @var boolean $useAdvancedEditor
2614
-     */
2615
-    private $useAdvancedEditor;
2616
-
2617
-    /**
2618
-     * @var boolean $use_personnel_manager
2619
-     */
2620
-    public $use_personnel_manager;
2621
-
2622
-    /**
2623
-     * @var boolean $use_dashboard_widget
2624
-     */
2625
-    public $use_dashboard_widget;
2626
-
2627
-    /**
2628
-     * @var int $events_in_dashboard
2629
-     */
2630
-    public $events_in_dashboard;
2631
-
2632
-    /**
2633
-     * @var boolean $use_event_timezones
2634
-     */
2635
-    public $use_event_timezones;
2636
-
2637
-    /**
2638
-     * @var string $log_file_name
2639
-     */
2640
-    public $log_file_name;
2641
-
2642
-    /**
2643
-     * @var string $debug_file_name
2644
-     */
2645
-    public $debug_file_name;
2646
-
2647
-    /**
2648
-     * @var boolean $use_remote_logging
2649
-     */
2650
-    public $use_remote_logging;
2651
-
2652
-    /**
2653
-     * @var string $remote_logging_url
2654
-     */
2655
-    public $remote_logging_url;
2656
-
2657
-    /**
2658
-     * @var boolean $show_reg_footer
2659
-     */
2660
-    public $show_reg_footer;
2661
-
2662
-    /**
2663
-     * @var string $affiliate_id
2664
-     */
2665
-    public $affiliate_id;
2666
-
2667
-    /**
2668
-     * adds extra layer of encoding to session data to prevent serialization errors
2669
-     * but is incompatible with some server configuration errors
2670
-     * if you get "500 internal server errors" during registration, try turning this on
2671
-     * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2672
-     *
2673
-     * @var boolean $encode_session_data
2674
-     */
2675
-    private $encode_session_data = false;
2676
-
2677
-    /**
2678
-     * @var boolean
2679
-     */
2680
-    private $is_caffeinated;
2681
-
2682
-
2683
-    /**
2684
-     *    class constructor
2685
-     *
2686
-     * @access    public
2687
-     */
2688
-    public function __construct()
2689
-    {
2690
-        // set default general admin settings
2691
-        $this->useAdvancedEditor = true;
2692
-        $this->use_personnel_manager = true;
2693
-        $this->use_dashboard_widget = true;
2694
-        $this->events_in_dashboard = 30;
2695
-        $this->use_event_timezones = false;
2696
-        $this->use_remote_logging = false;
2697
-        $this->remote_logging_url = null;
2698
-        $this->show_reg_footer = apply_filters(
2699
-            'FHEE__EE_Admin_Config__show_reg_footer__default',
2700
-            false
2701
-        );
2702
-        $this->affiliate_id = 'default';
2703
-        $this->encode_session_data = false;
2704
-    }
2705
-
2706
-
2707
-    /**
2708
-     * @param bool $reset
2709
-     * @return string
2710
-     */
2711
-    public function log_file_name($reset = false)
2712
-    {
2713
-        if (empty($this->log_file_name) || $reset) {
2714
-            $this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2715
-            EE_Config::instance()->update_espresso_config(false, false);
2716
-        }
2717
-        return $this->log_file_name;
2718
-    }
2719
-
2720
-
2721
-    /**
2722
-     * @param bool $reset
2723
-     * @return string
2724
-     */
2725
-    public function debug_file_name($reset = false)
2726
-    {
2727
-        if (empty($this->debug_file_name) || $reset) {
2728
-            $this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2729
-            EE_Config::instance()->update_espresso_config(false, false);
2730
-        }
2731
-        return $this->debug_file_name;
2732
-    }
2733
-
2734
-
2735
-    /**
2736
-     * @return string
2737
-     */
2738
-    public function affiliate_id()
2739
-    {
2740
-        return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2741
-    }
2742
-
2743
-
2744
-    /**
2745
-     * @return boolean
2746
-     */
2747
-    public function encode_session_data()
2748
-    {
2749
-        return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2750
-    }
2751
-
2752
-
2753
-    /**
2754
-     * @param boolean $encode_session_data
2755
-     */
2756
-    public function set_encode_session_data($encode_session_data)
2757
-    {
2758
-        $this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2759
-    }
2760
-
2761
-    /**
2762
-     * @return boolean
2763
-     */
2764
-    public function useAdvancedEditor()
2765
-    {
2766
-        if ($this->is_caffeinated === null) {
2767
-            $domain = LoaderFactory::getLoader()->getShared('EventEspresso\core\domain\Domain');
2768
-            $this->is_caffeinated = $domain->isCaffeinated();
2769
-        }
2770
-        return $this->useAdvancedEditor && $this->is_caffeinated;
2771
-    }
2772
-
2773
-    /**
2774
-     * @param boolean $use_advanced_editor
2775
-     */
2776
-    public function setUseAdvancedEditor($use_advanced_editor = true)
2777
-    {
2778
-        $this->useAdvancedEditor = filter_var(
2779
-            apply_filters(
2780
-                'FHEE__EE_Admin_Config__setUseAdvancedEditor__use_advanced_editor',
2781
-                $use_advanced_editor
2782
-            ),
2783
-            FILTER_VALIDATE_BOOLEAN
2784
-        );
2785
-    }
2612
+	/**
2613
+	 * @var boolean $useAdvancedEditor
2614
+	 */
2615
+	private $useAdvancedEditor;
2616
+
2617
+	/**
2618
+	 * @var boolean $use_personnel_manager
2619
+	 */
2620
+	public $use_personnel_manager;
2621
+
2622
+	/**
2623
+	 * @var boolean $use_dashboard_widget
2624
+	 */
2625
+	public $use_dashboard_widget;
2626
+
2627
+	/**
2628
+	 * @var int $events_in_dashboard
2629
+	 */
2630
+	public $events_in_dashboard;
2631
+
2632
+	/**
2633
+	 * @var boolean $use_event_timezones
2634
+	 */
2635
+	public $use_event_timezones;
2636
+
2637
+	/**
2638
+	 * @var string $log_file_name
2639
+	 */
2640
+	public $log_file_name;
2641
+
2642
+	/**
2643
+	 * @var string $debug_file_name
2644
+	 */
2645
+	public $debug_file_name;
2646
+
2647
+	/**
2648
+	 * @var boolean $use_remote_logging
2649
+	 */
2650
+	public $use_remote_logging;
2651
+
2652
+	/**
2653
+	 * @var string $remote_logging_url
2654
+	 */
2655
+	public $remote_logging_url;
2656
+
2657
+	/**
2658
+	 * @var boolean $show_reg_footer
2659
+	 */
2660
+	public $show_reg_footer;
2661
+
2662
+	/**
2663
+	 * @var string $affiliate_id
2664
+	 */
2665
+	public $affiliate_id;
2666
+
2667
+	/**
2668
+	 * adds extra layer of encoding to session data to prevent serialization errors
2669
+	 * but is incompatible with some server configuration errors
2670
+	 * if you get "500 internal server errors" during registration, try turning this on
2671
+	 * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2672
+	 *
2673
+	 * @var boolean $encode_session_data
2674
+	 */
2675
+	private $encode_session_data = false;
2676
+
2677
+	/**
2678
+	 * @var boolean
2679
+	 */
2680
+	private $is_caffeinated;
2681
+
2682
+
2683
+	/**
2684
+	 *    class constructor
2685
+	 *
2686
+	 * @access    public
2687
+	 */
2688
+	public function __construct()
2689
+	{
2690
+		// set default general admin settings
2691
+		$this->useAdvancedEditor = true;
2692
+		$this->use_personnel_manager = true;
2693
+		$this->use_dashboard_widget = true;
2694
+		$this->events_in_dashboard = 30;
2695
+		$this->use_event_timezones = false;
2696
+		$this->use_remote_logging = false;
2697
+		$this->remote_logging_url = null;
2698
+		$this->show_reg_footer = apply_filters(
2699
+			'FHEE__EE_Admin_Config__show_reg_footer__default',
2700
+			false
2701
+		);
2702
+		$this->affiliate_id = 'default';
2703
+		$this->encode_session_data = false;
2704
+	}
2705
+
2706
+
2707
+	/**
2708
+	 * @param bool $reset
2709
+	 * @return string
2710
+	 */
2711
+	public function log_file_name($reset = false)
2712
+	{
2713
+		if (empty($this->log_file_name) || $reset) {
2714
+			$this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2715
+			EE_Config::instance()->update_espresso_config(false, false);
2716
+		}
2717
+		return $this->log_file_name;
2718
+	}
2719
+
2720
+
2721
+	/**
2722
+	 * @param bool $reset
2723
+	 * @return string
2724
+	 */
2725
+	public function debug_file_name($reset = false)
2726
+	{
2727
+		if (empty($this->debug_file_name) || $reset) {
2728
+			$this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2729
+			EE_Config::instance()->update_espresso_config(false, false);
2730
+		}
2731
+		return $this->debug_file_name;
2732
+	}
2733
+
2734
+
2735
+	/**
2736
+	 * @return string
2737
+	 */
2738
+	public function affiliate_id()
2739
+	{
2740
+		return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2741
+	}
2742
+
2743
+
2744
+	/**
2745
+	 * @return boolean
2746
+	 */
2747
+	public function encode_session_data()
2748
+	{
2749
+		return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2750
+	}
2751
+
2752
+
2753
+	/**
2754
+	 * @param boolean $encode_session_data
2755
+	 */
2756
+	public function set_encode_session_data($encode_session_data)
2757
+	{
2758
+		$this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2759
+	}
2760
+
2761
+	/**
2762
+	 * @return boolean
2763
+	 */
2764
+	public function useAdvancedEditor()
2765
+	{
2766
+		if ($this->is_caffeinated === null) {
2767
+			$domain = LoaderFactory::getLoader()->getShared('EventEspresso\core\domain\Domain');
2768
+			$this->is_caffeinated = $domain->isCaffeinated();
2769
+		}
2770
+		return $this->useAdvancedEditor && $this->is_caffeinated;
2771
+	}
2772
+
2773
+	/**
2774
+	 * @param boolean $use_advanced_editor
2775
+	 */
2776
+	public function setUseAdvancedEditor($use_advanced_editor = true)
2777
+	{
2778
+		$this->useAdvancedEditor = filter_var(
2779
+			apply_filters(
2780
+				'FHEE__EE_Admin_Config__setUseAdvancedEditor__use_advanced_editor',
2781
+				$use_advanced_editor
2782
+			),
2783
+			FILTER_VALIDATE_BOOLEAN
2784
+		);
2785
+	}
2786 2786
 }
2787 2787
 
2788 2788
 /**
@@ -2790,70 +2790,70 @@  discard block
 block discarded – undo
2790 2790
  */
2791 2791
 class EE_Template_Config extends EE_Config_Base
2792 2792
 {
2793
-    /**
2794
-     * @var boolean $enable_default_style
2795
-     */
2796
-    public $enable_default_style;
2797
-
2798
-    /**
2799
-     * @var string $custom_style_sheet
2800
-     */
2801
-    public $custom_style_sheet;
2802
-
2803
-    /**
2804
-     * @var boolean $display_address_in_regform
2805
-     */
2806
-    public $display_address_in_regform;
2807
-
2808
-    /**
2809
-     * @var int $display_description_on_multi_reg_page
2810
-     */
2811
-    public $display_description_on_multi_reg_page;
2812
-
2813
-    /**
2814
-     * @var boolean $use_custom_templates
2815
-     */
2816
-    public $use_custom_templates;
2817
-
2818
-    /**
2819
-     * @var string $current_espresso_theme
2820
-     */
2821
-    public $current_espresso_theme;
2822
-
2823
-    /**
2824
-     * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2825
-     */
2826
-    public $EED_Ticket_Selector;
2827
-
2828
-    /**
2829
-     * @var EE_Event_Single_Config $EED_Event_Single
2830
-     */
2831
-    public $EED_Event_Single;
2832
-
2833
-    /**
2834
-     * @var EE_Events_Archive_Config $EED_Events_Archive
2835
-     */
2836
-    public $EED_Events_Archive;
2837
-
2838
-
2839
-    /**
2840
-     *    class constructor
2841
-     *
2842
-     * @access    public
2843
-     */
2844
-    public function __construct()
2845
-    {
2846
-        // set default template settings
2847
-        $this->enable_default_style = true;
2848
-        $this->custom_style_sheet = null;
2849
-        $this->display_address_in_regform = true;
2850
-        $this->display_description_on_multi_reg_page = false;
2851
-        $this->use_custom_templates = false;
2852
-        $this->current_espresso_theme = 'Espresso_Arabica_2014';
2853
-        $this->EED_Event_Single = null;
2854
-        $this->EED_Events_Archive = null;
2855
-        $this->EED_Ticket_Selector = null;
2856
-    }
2793
+	/**
2794
+	 * @var boolean $enable_default_style
2795
+	 */
2796
+	public $enable_default_style;
2797
+
2798
+	/**
2799
+	 * @var string $custom_style_sheet
2800
+	 */
2801
+	public $custom_style_sheet;
2802
+
2803
+	/**
2804
+	 * @var boolean $display_address_in_regform
2805
+	 */
2806
+	public $display_address_in_regform;
2807
+
2808
+	/**
2809
+	 * @var int $display_description_on_multi_reg_page
2810
+	 */
2811
+	public $display_description_on_multi_reg_page;
2812
+
2813
+	/**
2814
+	 * @var boolean $use_custom_templates
2815
+	 */
2816
+	public $use_custom_templates;
2817
+
2818
+	/**
2819
+	 * @var string $current_espresso_theme
2820
+	 */
2821
+	public $current_espresso_theme;
2822
+
2823
+	/**
2824
+	 * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2825
+	 */
2826
+	public $EED_Ticket_Selector;
2827
+
2828
+	/**
2829
+	 * @var EE_Event_Single_Config $EED_Event_Single
2830
+	 */
2831
+	public $EED_Event_Single;
2832
+
2833
+	/**
2834
+	 * @var EE_Events_Archive_Config $EED_Events_Archive
2835
+	 */
2836
+	public $EED_Events_Archive;
2837
+
2838
+
2839
+	/**
2840
+	 *    class constructor
2841
+	 *
2842
+	 * @access    public
2843
+	 */
2844
+	public function __construct()
2845
+	{
2846
+		// set default template settings
2847
+		$this->enable_default_style = true;
2848
+		$this->custom_style_sheet = null;
2849
+		$this->display_address_in_regform = true;
2850
+		$this->display_description_on_multi_reg_page = false;
2851
+		$this->use_custom_templates = false;
2852
+		$this->current_espresso_theme = 'Espresso_Arabica_2014';
2853
+		$this->EED_Event_Single = null;
2854
+		$this->EED_Events_Archive = null;
2855
+		$this->EED_Ticket_Selector = null;
2856
+	}
2857 2857
 }
2858 2858
 
2859 2859
 /**
@@ -2861,114 +2861,114 @@  discard block
 block discarded – undo
2861 2861
  */
2862 2862
 class EE_Map_Config extends EE_Config_Base
2863 2863
 {
2864
-    /**
2865
-     * @var boolean $use_google_maps
2866
-     */
2867
-    public $use_google_maps;
2868
-
2869
-    /**
2870
-     * @var string $api_key
2871
-     */
2872
-    public $google_map_api_key;
2873
-
2874
-    /**
2875
-     * @var int $event_details_map_width
2876
-     */
2877
-    public $event_details_map_width;
2878
-
2879
-    /**
2880
-     * @var int $event_details_map_height
2881
-     */
2882
-    public $event_details_map_height;
2883
-
2884
-    /**
2885
-     * @var int $event_details_map_zoom
2886
-     */
2887
-    public $event_details_map_zoom;
2888
-
2889
-    /**
2890
-     * @var boolean $event_details_display_nav
2891
-     */
2892
-    public $event_details_display_nav;
2893
-
2894
-    /**
2895
-     * @var boolean $event_details_nav_size
2896
-     */
2897
-    public $event_details_nav_size;
2898
-
2899
-    /**
2900
-     * @var string $event_details_control_type
2901
-     */
2902
-    public $event_details_control_type;
2903
-
2904
-    /**
2905
-     * @var string $event_details_map_align
2906
-     */
2907
-    public $event_details_map_align;
2908
-
2909
-    /**
2910
-     * @var int $event_list_map_width
2911
-     */
2912
-    public $event_list_map_width;
2913
-
2914
-    /**
2915
-     * @var int $event_list_map_height
2916
-     */
2917
-    public $event_list_map_height;
2918
-
2919
-    /**
2920
-     * @var int $event_list_map_zoom
2921
-     */
2922
-    public $event_list_map_zoom;
2923
-
2924
-    /**
2925
-     * @var boolean $event_list_display_nav
2926
-     */
2927
-    public $event_list_display_nav;
2928
-
2929
-    /**
2930
-     * @var boolean $event_list_nav_size
2931
-     */
2932
-    public $event_list_nav_size;
2933
-
2934
-    /**
2935
-     * @var string $event_list_control_type
2936
-     */
2937
-    public $event_list_control_type;
2938
-
2939
-    /**
2940
-     * @var string $event_list_map_align
2941
-     */
2942
-    public $event_list_map_align;
2943
-
2944
-
2945
-    /**
2946
-     *    class constructor
2947
-     *
2948
-     * @access    public
2949
-     */
2950
-    public function __construct()
2951
-    {
2952
-        // set default map settings
2953
-        $this->use_google_maps = true;
2954
-        $this->google_map_api_key = '';
2955
-        // for event details pages (reg page)
2956
-        $this->event_details_map_width = 585;            // ee_map_width_single
2957
-        $this->event_details_map_height = 362;            // ee_map_height_single
2958
-        $this->event_details_map_zoom = 14;            // ee_map_zoom_single
2959
-        $this->event_details_display_nav = true;            // ee_map_nav_display_single
2960
-        $this->event_details_nav_size = false;            // ee_map_nav_size_single
2961
-        $this->event_details_control_type = 'default';        // ee_map_type_control_single
2962
-        $this->event_details_map_align = 'center';            // ee_map_align_single
2963
-        // for event list pages
2964
-        $this->event_list_map_width = 300;            // ee_map_width
2965
-        $this->event_list_map_height = 185;        // ee_map_height
2966
-        $this->event_list_map_zoom = 12;            // ee_map_zoom
2967
-        $this->event_list_display_nav = false;        // ee_map_nav_display
2968
-        $this->event_list_nav_size = true;            // ee_map_nav_size
2969
-        $this->event_list_control_type = 'dropdown';        // ee_map_type_control
2970
-        $this->event_list_map_align = 'center';            // ee_map_align
2971
-    }
2864
+	/**
2865
+	 * @var boolean $use_google_maps
2866
+	 */
2867
+	public $use_google_maps;
2868
+
2869
+	/**
2870
+	 * @var string $api_key
2871
+	 */
2872
+	public $google_map_api_key;
2873
+
2874
+	/**
2875
+	 * @var int $event_details_map_width
2876
+	 */
2877
+	public $event_details_map_width;
2878
+
2879
+	/**
2880
+	 * @var int $event_details_map_height
2881
+	 */
2882
+	public $event_details_map_height;
2883
+
2884
+	/**
2885
+	 * @var int $event_details_map_zoom
2886
+	 */
2887
+	public $event_details_map_zoom;
2888
+
2889
+	/**
2890
+	 * @var boolean $event_details_display_nav
2891
+	 */
2892
+	public $event_details_display_nav;
2893
+
2894
+	/**
2895
+	 * @var boolean $event_details_nav_size
2896
+	 */
2897
+	public $event_details_nav_size;
2898
+
2899
+	/**
2900
+	 * @var string $event_details_control_type
2901
+	 */
2902
+	public $event_details_control_type;
2903
+
2904
+	/**
2905
+	 * @var string $event_details_map_align
2906
+	 */
2907
+	public $event_details_map_align;
2908
+
2909
+	/**
2910
+	 * @var int $event_list_map_width
2911
+	 */
2912
+	public $event_list_map_width;
2913
+
2914
+	/**
2915
+	 * @var int $event_list_map_height
2916
+	 */
2917
+	public $event_list_map_height;
2918
+
2919
+	/**
2920
+	 * @var int $event_list_map_zoom
2921
+	 */
2922
+	public $event_list_map_zoom;
2923
+
2924
+	/**
2925
+	 * @var boolean $event_list_display_nav
2926
+	 */
2927
+	public $event_list_display_nav;
2928
+
2929
+	/**
2930
+	 * @var boolean $event_list_nav_size
2931
+	 */
2932
+	public $event_list_nav_size;
2933
+
2934
+	/**
2935
+	 * @var string $event_list_control_type
2936
+	 */
2937
+	public $event_list_control_type;
2938
+
2939
+	/**
2940
+	 * @var string $event_list_map_align
2941
+	 */
2942
+	public $event_list_map_align;
2943
+
2944
+
2945
+	/**
2946
+	 *    class constructor
2947
+	 *
2948
+	 * @access    public
2949
+	 */
2950
+	public function __construct()
2951
+	{
2952
+		// set default map settings
2953
+		$this->use_google_maps = true;
2954
+		$this->google_map_api_key = '';
2955
+		// for event details pages (reg page)
2956
+		$this->event_details_map_width = 585;            // ee_map_width_single
2957
+		$this->event_details_map_height = 362;            // ee_map_height_single
2958
+		$this->event_details_map_zoom = 14;            // ee_map_zoom_single
2959
+		$this->event_details_display_nav = true;            // ee_map_nav_display_single
2960
+		$this->event_details_nav_size = false;            // ee_map_nav_size_single
2961
+		$this->event_details_control_type = 'default';        // ee_map_type_control_single
2962
+		$this->event_details_map_align = 'center';            // ee_map_align_single
2963
+		// for event list pages
2964
+		$this->event_list_map_width = 300;            // ee_map_width
2965
+		$this->event_list_map_height = 185;        // ee_map_height
2966
+		$this->event_list_map_zoom = 12;            // ee_map_zoom
2967
+		$this->event_list_display_nav = false;        // ee_map_nav_display
2968
+		$this->event_list_nav_size = true;            // ee_map_nav_size
2969
+		$this->event_list_control_type = 'dropdown';        // ee_map_type_control
2970
+		$this->event_list_map_align = 'center';            // ee_map_align
2971
+	}
2972 2972
 }
2973 2973
 
2974 2974
 /**
@@ -2976,46 +2976,46 @@  discard block
 block discarded – undo
2976 2976
  */
2977 2977
 class EE_Events_Archive_Config extends EE_Config_Base
2978 2978
 {
2979
-    public $display_status_banner;
2979
+	public $display_status_banner;
2980 2980
 
2981
-    public $display_description;
2981
+	public $display_description;
2982 2982
 
2983
-    public $display_ticket_selector;
2983
+	public $display_ticket_selector;
2984 2984
 
2985
-    public $display_datetimes;
2985
+	public $display_datetimes;
2986 2986
 
2987
-    public $display_venue;
2987
+	public $display_venue;
2988 2988
 
2989
-    public $display_expired_events;
2989
+	public $display_expired_events;
2990 2990
 
2991
-    public $use_sortable_display_order;
2991
+	public $use_sortable_display_order;
2992 2992
 
2993
-    public $display_order_tickets;
2993
+	public $display_order_tickets;
2994 2994
 
2995
-    public $display_order_datetimes;
2995
+	public $display_order_datetimes;
2996 2996
 
2997
-    public $display_order_event;
2997
+	public $display_order_event;
2998 2998
 
2999
-    public $display_order_venue;
2999
+	public $display_order_venue;
3000 3000
 
3001 3001
 
3002
-    /**
3003
-     *    class constructor
3004
-     */
3005
-    public function __construct()
3006
-    {
3007
-        $this->display_status_banner = 0;
3008
-        $this->display_description = 1;
3009
-        $this->display_ticket_selector = 0;
3010
-        $this->display_datetimes = 1;
3011
-        $this->display_venue = 0;
3012
-        $this->display_expired_events = 0;
3013
-        $this->use_sortable_display_order = false;
3014
-        $this->display_order_tickets = 100;
3015
-        $this->display_order_datetimes = 110;
3016
-        $this->display_order_event = 120;
3017
-        $this->display_order_venue = 130;
3018
-    }
3002
+	/**
3003
+	 *    class constructor
3004
+	 */
3005
+	public function __construct()
3006
+	{
3007
+		$this->display_status_banner = 0;
3008
+		$this->display_description = 1;
3009
+		$this->display_ticket_selector = 0;
3010
+		$this->display_datetimes = 1;
3011
+		$this->display_venue = 0;
3012
+		$this->display_expired_events = 0;
3013
+		$this->use_sortable_display_order = false;
3014
+		$this->display_order_tickets = 100;
3015
+		$this->display_order_datetimes = 110;
3016
+		$this->display_order_event = 120;
3017
+		$this->display_order_venue = 130;
3018
+	}
3019 3019
 }
3020 3020
 
3021 3021
 /**
@@ -3023,34 +3023,34 @@  discard block
 block discarded – undo
3023 3023
  */
3024 3024
 class EE_Event_Single_Config extends EE_Config_Base
3025 3025
 {
3026
-    public $display_status_banner_single;
3026
+	public $display_status_banner_single;
3027 3027
 
3028
-    public $display_venue;
3028
+	public $display_venue;
3029 3029
 
3030
-    public $use_sortable_display_order;
3030
+	public $use_sortable_display_order;
3031 3031
 
3032
-    public $display_order_tickets;
3032
+	public $display_order_tickets;
3033 3033
 
3034
-    public $display_order_datetimes;
3034
+	public $display_order_datetimes;
3035 3035
 
3036
-    public $display_order_event;
3036
+	public $display_order_event;
3037 3037
 
3038
-    public $display_order_venue;
3038
+	public $display_order_venue;
3039 3039
 
3040 3040
 
3041
-    /**
3042
-     *    class constructor
3043
-     */
3044
-    public function __construct()
3045
-    {
3046
-        $this->display_status_banner_single = 0;
3047
-        $this->display_venue = 1;
3048
-        $this->use_sortable_display_order = false;
3049
-        $this->display_order_tickets = 100;
3050
-        $this->display_order_datetimes = 110;
3051
-        $this->display_order_event = 120;
3052
-        $this->display_order_venue = 130;
3053
-    }
3041
+	/**
3042
+	 *    class constructor
3043
+	 */
3044
+	public function __construct()
3045
+	{
3046
+		$this->display_status_banner_single = 0;
3047
+		$this->display_venue = 1;
3048
+		$this->use_sortable_display_order = false;
3049
+		$this->display_order_tickets = 100;
3050
+		$this->display_order_datetimes = 110;
3051
+		$this->display_order_event = 120;
3052
+		$this->display_order_venue = 130;
3053
+	}
3054 3054
 }
3055 3055
 
3056 3056
 /**
@@ -3058,172 +3058,172 @@  discard block
 block discarded – undo
3058 3058
  */
3059 3059
 class EE_Ticket_Selector_Config extends EE_Config_Base
3060 3060
 {
3061
-    /**
3062
-     * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
3063
-     */
3064
-    const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
3065
-
3066
-    /**
3067
-     * constant to indicate that a datetime selector should only be shown for ticket selectors
3068
-     * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
3069
-     */
3070
-    const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
3071
-
3072
-    /**
3073
-     * @var boolean $show_ticket_sale_columns
3074
-     */
3075
-    public $show_ticket_sale_columns;
3076
-
3077
-    /**
3078
-     * @var boolean $show_ticket_details
3079
-     */
3080
-    public $show_ticket_details;
3081
-
3082
-    /**
3083
-     * @var boolean $show_expired_tickets
3084
-     */
3085
-    public $show_expired_tickets;
3086
-
3087
-    /**
3088
-     * whether or not to display a dropdown box populated with event datetimes
3089
-     * that toggles which tickets are displayed for a ticket selector.
3090
-     * uses one of the *_DATETIME_SELECTOR constants defined above
3091
-     *
3092
-     * @var string $show_datetime_selector
3093
-     */
3094
-    private $show_datetime_selector = 'no_datetime_selector';
3095
-
3096
-    /**
3097
-     * the number of datetimes an event has to have before conditionally displaying a datetime selector
3098
-     *
3099
-     * @var int $datetime_selector_threshold
3100
-     */
3101
-    private $datetime_selector_threshold = 3;
3102
-
3103
-    /**
3104
-     * determines the maximum number of "checked" dates in the date and time filter
3105
-     *
3106
-     * @var int $datetime_selector_checked
3107
-     */
3108
-    private $datetime_selector_max_checked = 10;
3109
-
3110
-
3111
-    /**
3112
-     *    class constructor
3113
-     */
3114
-    public function __construct()
3115
-    {
3116
-        $this->show_ticket_sale_columns = true;
3117
-        $this->show_ticket_details = true;
3118
-        $this->show_expired_tickets = true;
3119
-        $this->show_datetime_selector = EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3120
-        $this->datetime_selector_threshold = 3;
3121
-        $this->datetime_selector_max_checked = 10;
3122
-    }
3123
-
3124
-
3125
-    /**
3126
-     * returns true if a datetime selector should be displayed
3127
-     *
3128
-     * @param array $datetimes
3129
-     * @return bool
3130
-     */
3131
-    public function showDatetimeSelector(array $datetimes)
3132
-    {
3133
-        // if the settings are NOT: don't show OR below threshold, THEN active = true
3134
-        return ! (
3135
-            $this->getShowDatetimeSelector() === EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3136
-            || (
3137
-                $this->getShowDatetimeSelector() === EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3138
-                && count($datetimes) < $this->getDatetimeSelectorThreshold()
3139
-            )
3140
-        );
3141
-    }
3142
-
3143
-
3144
-    /**
3145
-     * @return string
3146
-     */
3147
-    public function getShowDatetimeSelector()
3148
-    {
3149
-        return $this->show_datetime_selector;
3150
-    }
3151
-
3152
-
3153
-    /**
3154
-     * @param bool $keys_only
3155
-     * @return array
3156
-     */
3157
-    public function getShowDatetimeSelectorOptions($keys_only = true)
3158
-    {
3159
-        return $keys_only
3160
-            ? array(
3161
-                EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3162
-                EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3163
-            )
3164
-            : array(
3165
-                EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3166
-                    'Do not show date & time filter',
3167
-                    'event_espresso'
3168
-                ),
3169
-                EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3170
-                    'Maybe show date & time filter',
3171
-                    'event_espresso'
3172
-                ),
3173
-            );
3174
-    }
3175
-
3176
-
3177
-    /**
3178
-     * @param string $show_datetime_selector
3179
-     */
3180
-    public function setShowDatetimeSelector($show_datetime_selector)
3181
-    {
3182
-        $this->show_datetime_selector = in_array(
3183
-            $show_datetime_selector,
3184
-            $this->getShowDatetimeSelectorOptions(),
3185
-            true
3186
-        )
3187
-            ? $show_datetime_selector
3188
-            : EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3189
-    }
3190
-
3191
-
3192
-    /**
3193
-     * @return int
3194
-     */
3195
-    public function getDatetimeSelectorThreshold()
3196
-    {
3197
-        return $this->datetime_selector_threshold;
3198
-    }
3199
-
3200
-
3201
-    /**
3202
-     * @param int $datetime_selector_threshold
3203
-     */
3204
-    public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3205
-    {
3206
-        $datetime_selector_threshold = absint($datetime_selector_threshold);
3207
-        $this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3208
-    }
3209
-
3210
-
3211
-    /**
3212
-     * @return int
3213
-     */
3214
-    public function getDatetimeSelectorMaxChecked()
3215
-    {
3216
-        return $this->datetime_selector_max_checked;
3217
-    }
3218
-
3219
-
3220
-    /**
3221
-     * @param int $datetime_selector_max_checked
3222
-     */
3223
-    public function setDatetimeSelectorMaxChecked($datetime_selector_max_checked)
3224
-    {
3225
-        $this->datetime_selector_max_checked = absint($datetime_selector_max_checked);
3226
-    }
3061
+	/**
3062
+	 * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
3063
+	 */
3064
+	const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
3065
+
3066
+	/**
3067
+	 * constant to indicate that a datetime selector should only be shown for ticket selectors
3068
+	 * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
3069
+	 */
3070
+	const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
3071
+
3072
+	/**
3073
+	 * @var boolean $show_ticket_sale_columns
3074
+	 */
3075
+	public $show_ticket_sale_columns;
3076
+
3077
+	/**
3078
+	 * @var boolean $show_ticket_details
3079
+	 */
3080
+	public $show_ticket_details;
3081
+
3082
+	/**
3083
+	 * @var boolean $show_expired_tickets
3084
+	 */
3085
+	public $show_expired_tickets;
3086
+
3087
+	/**
3088
+	 * whether or not to display a dropdown box populated with event datetimes
3089
+	 * that toggles which tickets are displayed for a ticket selector.
3090
+	 * uses one of the *_DATETIME_SELECTOR constants defined above
3091
+	 *
3092
+	 * @var string $show_datetime_selector
3093
+	 */
3094
+	private $show_datetime_selector = 'no_datetime_selector';
3095
+
3096
+	/**
3097
+	 * the number of datetimes an event has to have before conditionally displaying a datetime selector
3098
+	 *
3099
+	 * @var int $datetime_selector_threshold
3100
+	 */
3101
+	private $datetime_selector_threshold = 3;
3102
+
3103
+	/**
3104
+	 * determines the maximum number of "checked" dates in the date and time filter
3105
+	 *
3106
+	 * @var int $datetime_selector_checked
3107
+	 */
3108
+	private $datetime_selector_max_checked = 10;
3109
+
3110
+
3111
+	/**
3112
+	 *    class constructor
3113
+	 */
3114
+	public function __construct()
3115
+	{
3116
+		$this->show_ticket_sale_columns = true;
3117
+		$this->show_ticket_details = true;
3118
+		$this->show_expired_tickets = true;
3119
+		$this->show_datetime_selector = EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3120
+		$this->datetime_selector_threshold = 3;
3121
+		$this->datetime_selector_max_checked = 10;
3122
+	}
3123
+
3124
+
3125
+	/**
3126
+	 * returns true if a datetime selector should be displayed
3127
+	 *
3128
+	 * @param array $datetimes
3129
+	 * @return bool
3130
+	 */
3131
+	public function showDatetimeSelector(array $datetimes)
3132
+	{
3133
+		// if the settings are NOT: don't show OR below threshold, THEN active = true
3134
+		return ! (
3135
+			$this->getShowDatetimeSelector() === EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3136
+			|| (
3137
+				$this->getShowDatetimeSelector() === EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3138
+				&& count($datetimes) < $this->getDatetimeSelectorThreshold()
3139
+			)
3140
+		);
3141
+	}
3142
+
3143
+
3144
+	/**
3145
+	 * @return string
3146
+	 */
3147
+	public function getShowDatetimeSelector()
3148
+	{
3149
+		return $this->show_datetime_selector;
3150
+	}
3151
+
3152
+
3153
+	/**
3154
+	 * @param bool $keys_only
3155
+	 * @return array
3156
+	 */
3157
+	public function getShowDatetimeSelectorOptions($keys_only = true)
3158
+	{
3159
+		return $keys_only
3160
+			? array(
3161
+				EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3162
+				EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3163
+			)
3164
+			: array(
3165
+				EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3166
+					'Do not show date & time filter',
3167
+					'event_espresso'
3168
+				),
3169
+				EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3170
+					'Maybe show date & time filter',
3171
+					'event_espresso'
3172
+				),
3173
+			);
3174
+	}
3175
+
3176
+
3177
+	/**
3178
+	 * @param string $show_datetime_selector
3179
+	 */
3180
+	public function setShowDatetimeSelector($show_datetime_selector)
3181
+	{
3182
+		$this->show_datetime_selector = in_array(
3183
+			$show_datetime_selector,
3184
+			$this->getShowDatetimeSelectorOptions(),
3185
+			true
3186
+		)
3187
+			? $show_datetime_selector
3188
+			: EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3189
+	}
3190
+
3191
+
3192
+	/**
3193
+	 * @return int
3194
+	 */
3195
+	public function getDatetimeSelectorThreshold()
3196
+	{
3197
+		return $this->datetime_selector_threshold;
3198
+	}
3199
+
3200
+
3201
+	/**
3202
+	 * @param int $datetime_selector_threshold
3203
+	 */
3204
+	public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3205
+	{
3206
+		$datetime_selector_threshold = absint($datetime_selector_threshold);
3207
+		$this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3208
+	}
3209
+
3210
+
3211
+	/**
3212
+	 * @return int
3213
+	 */
3214
+	public function getDatetimeSelectorMaxChecked()
3215
+	{
3216
+		return $this->datetime_selector_max_checked;
3217
+	}
3218
+
3219
+
3220
+	/**
3221
+	 * @param int $datetime_selector_max_checked
3222
+	 */
3223
+	public function setDatetimeSelectorMaxChecked($datetime_selector_max_checked)
3224
+	{
3225
+		$this->datetime_selector_max_checked = absint($datetime_selector_max_checked);
3226
+	}
3227 3227
 }
3228 3228
 
3229 3229
 /**
@@ -3235,87 +3235,87 @@  discard block
 block discarded – undo
3235 3235
  */
3236 3236
 class EE_Environment_Config extends EE_Config_Base
3237 3237
 {
3238
-    /**
3239
-     * Hold any php environment variables that we want to track.
3240
-     *
3241
-     * @var stdClass;
3242
-     */
3243
-    public $php;
3244
-
3245
-
3246
-    /**
3247
-     *    constructor
3248
-     */
3249
-    public function __construct()
3250
-    {
3251
-        $this->php = new stdClass();
3252
-        $this->_set_php_values();
3253
-    }
3254
-
3255
-
3256
-    /**
3257
-     * This sets the php environment variables.
3258
-     *
3259
-     * @since 4.4.0
3260
-     * @return void
3261
-     */
3262
-    protected function _set_php_values()
3263
-    {
3264
-        $this->php->max_input_vars = ini_get('max_input_vars');
3265
-        $this->php->version = phpversion();
3266
-    }
3267
-
3268
-
3269
-    /**
3270
-     * helper method for determining whether input_count is
3271
-     * reaching the potential maximum the server can handle
3272
-     * according to max_input_vars
3273
-     *
3274
-     * @param int   $input_count the count of input vars.
3275
-     * @return array {
3276
-     *                           An array that represents whether available space and if no available space the error
3277
-     *                           message.
3278
-     * @type bool   $has_space   whether more inputs can be added.
3279
-     * @type string $msg         Any message to be displayed.
3280
-     *                           }
3281
-     */
3282
-    public function max_input_vars_limit_check($input_count = 0)
3283
-    {
3284
-        if (
3285
-            ! empty($this->php->max_input_vars)
3286
-            && ($input_count >= $this->php->max_input_vars)
3287
-        ) {
3288
-            // check the server setting because the config value could be stale
3289
-            $max_input_vars = ini_get('max_input_vars');
3290
-            if ($input_count >= $max_input_vars) {
3291
-                return sprintf(
3292
-                    esc_html__(
3293
-                        'The maximum number of inputs on this page has been exceeded. You cannot make edits to this page because of your server\'s PHP "max_input_vars" setting.%1$sThere are %2$d inputs and the maximum amount currently allowed by your server is %3$d.%1$sPlease contact your web host and ask them to raise the "max_input_vars" limit.',
3294
-                        'event_espresso'
3295
-                    ),
3296
-                    '<br>',
3297
-                    $input_count,
3298
-                    $max_input_vars
3299
-                );
3300
-            } else {
3301
-                return '';
3302
-            }
3303
-        } else {
3304
-            return '';
3305
-        }
3306
-    }
3307
-
3308
-
3309
-    /**
3310
-     * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3311
-     *
3312
-     * @since 4.4.1
3313
-     * @return void
3314
-     */
3315
-    public function recheck_values()
3316
-    {
3317
-        $this->_set_php_values();
3318
-    }
3238
+	/**
3239
+	 * Hold any php environment variables that we want to track.
3240
+	 *
3241
+	 * @var stdClass;
3242
+	 */
3243
+	public $php;
3244
+
3245
+
3246
+	/**
3247
+	 *    constructor
3248
+	 */
3249
+	public function __construct()
3250
+	{
3251
+		$this->php = new stdClass();
3252
+		$this->_set_php_values();
3253
+	}
3254
+
3255
+
3256
+	/**
3257
+	 * This sets the php environment variables.
3258
+	 *
3259
+	 * @since 4.4.0
3260
+	 * @return void
3261
+	 */
3262
+	protected function _set_php_values()
3263
+	{
3264
+		$this->php->max_input_vars = ini_get('max_input_vars');
3265
+		$this->php->version = phpversion();
3266
+	}
3267
+
3268
+
3269
+	/**
3270
+	 * helper method for determining whether input_count is
3271
+	 * reaching the potential maximum the server can handle
3272
+	 * according to max_input_vars
3273
+	 *
3274
+	 * @param int   $input_count the count of input vars.
3275
+	 * @return array {
3276
+	 *                           An array that represents whether available space and if no available space the error
3277
+	 *                           message.
3278
+	 * @type bool   $has_space   whether more inputs can be added.
3279
+	 * @type string $msg         Any message to be displayed.
3280
+	 *                           }
3281
+	 */
3282
+	public function max_input_vars_limit_check($input_count = 0)
3283
+	{
3284
+		if (
3285
+			! empty($this->php->max_input_vars)
3286
+			&& ($input_count >= $this->php->max_input_vars)
3287
+		) {
3288
+			// check the server setting because the config value could be stale
3289
+			$max_input_vars = ini_get('max_input_vars');
3290
+			if ($input_count >= $max_input_vars) {
3291
+				return sprintf(
3292
+					esc_html__(
3293
+						'The maximum number of inputs on this page has been exceeded. You cannot make edits to this page because of your server\'s PHP "max_input_vars" setting.%1$sThere are %2$d inputs and the maximum amount currently allowed by your server is %3$d.%1$sPlease contact your web host and ask them to raise the "max_input_vars" limit.',
3294
+						'event_espresso'
3295
+					),
3296
+					'<br>',
3297
+					$input_count,
3298
+					$max_input_vars
3299
+				);
3300
+			} else {
3301
+				return '';
3302
+			}
3303
+		} else {
3304
+			return '';
3305
+		}
3306
+	}
3307
+
3308
+
3309
+	/**
3310
+	 * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3311
+	 *
3312
+	 * @since 4.4.1
3313
+	 * @return void
3314
+	 */
3315
+	public function recheck_values()
3316
+	{
3317
+		$this->_set_php_values();
3318
+	}
3319 3319
 }
3320 3320
 
3321 3321
 /**
@@ -3327,21 +3327,21 @@  discard block
 block discarded – undo
3327 3327
  */
3328 3328
 class EE_Tax_Config extends EE_Config_Base
3329 3329
 {
3330
-    /*
3330
+	/*
3331 3331
      * flag to indicate whether or not to display ticket prices with the taxes included
3332 3332
      *
3333 3333
      * @var boolean $prices_displayed_including_taxes
3334 3334
      */
3335
-    public $prices_displayed_including_taxes;
3335
+	public $prices_displayed_including_taxes;
3336 3336
 
3337 3337
 
3338
-    /**
3339
-     *    class constructor
3340
-     */
3341
-    public function __construct()
3342
-    {
3343
-        $this->prices_displayed_including_taxes = true;
3344
-    }
3338
+	/**
3339
+	 *    class constructor
3340
+	 */
3341
+	public function __construct()
3342
+	{
3343
+		$this->prices_displayed_including_taxes = true;
3344
+	}
3345 3345
 }
3346 3346
 
3347 3347
 /**
@@ -3354,19 +3354,19 @@  discard block
 block discarded – undo
3354 3354
  */
3355 3355
 class EE_Messages_Config extends EE_Config_Base
3356 3356
 {
3357
-    /**
3358
-     * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3359
-     * A value of 0 represents never deleting.  Default is 0.
3360
-     *
3361
-     * @var integer
3362
-     */
3363
-    public $delete_threshold;
3364
-
3365
-
3366
-    public function __construct()
3367
-    {
3368
-        $this->delete_threshold = 0;
3369
-    }
3357
+	/**
3358
+	 * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3359
+	 * A value of 0 represents never deleting.  Default is 0.
3360
+	 *
3361
+	 * @var integer
3362
+	 */
3363
+	public $delete_threshold;
3364
+
3365
+
3366
+	public function __construct()
3367
+	{
3368
+		$this->delete_threshold = 0;
3369
+	}
3370 3370
 }
3371 3371
 
3372 3372
 /**
@@ -3376,31 +3376,31 @@  discard block
 block discarded – undo
3376 3376
  */
3377 3377
 class EE_Gateway_Config extends EE_Config_Base
3378 3378
 {
3379
-    /**
3380
-     * Array with keys that are payment gateways slugs, and values are arrays
3381
-     * with any config info the gateway wants to store
3382
-     *
3383
-     * @var array
3384
-     */
3385
-    public $payment_settings;
3386
-
3387
-    /**
3388
-     * Where keys are gateway slugs, and values are booleans indicating whether or not
3389
-     * the gateway is stored in the uploads directory
3390
-     *
3391
-     * @var array
3392
-     */
3393
-    public $active_gateways;
3394
-
3395
-
3396
-    /**
3397
-     *    class constructor
3398
-     *
3399
-     * @deprecated
3400
-     */
3401
-    public function __construct()
3402
-    {
3403
-        $this->payment_settings = array();
3404
-        $this->active_gateways = array('Invoice' => false);
3405
-    }
3379
+	/**
3380
+	 * Array with keys that are payment gateways slugs, and values are arrays
3381
+	 * with any config info the gateway wants to store
3382
+	 *
3383
+	 * @var array
3384
+	 */
3385
+	public $payment_settings;
3386
+
3387
+	/**
3388
+	 * Where keys are gateway slugs, and values are booleans indicating whether or not
3389
+	 * the gateway is stored in the uploads directory
3390
+	 *
3391
+	 * @var array
3392
+	 */
3393
+	public $active_gateways;
3394
+
3395
+
3396
+	/**
3397
+	 *    class constructor
3398
+	 *
3399
+	 * @deprecated
3400
+	 */
3401
+	public function __construct()
3402
+	{
3403
+		$this->payment_settings = array();
3404
+		$this->active_gateways = array('Invoice' => false);
3405
+	}
3406 3406
 }
Please login to merge, or discard this patch.
domain/services/graphql/connection_resolvers/AbstractConnectionResolver.php 1 patch
Indentation   +170 added lines, -170 removed lines patch added patch discarded remove patch
@@ -19,174 +19,174 @@
 block discarded – undo
19 19
  */
20 20
 abstract class AbstractConnectionResolver extends WPGraphQLConnectionResolver
21 21
 {
22
-    const MAX_QUERY_LIMIT = 250;
23
-
24
-    /**
25
-     * @var Utilities
26
-     */
27
-    private $utilities;
28
-
29
-
30
-    /**
31
-     * @return Utilities
32
-     */
33
-    public function getUtilities(): Utilities
34
-    {
35
-        if (! $this->utilities instanceof Utilities) {
36
-            $this->utilities = LoaderFactory::getLoader()->getShared(Utilities::class);
37
-        }
38
-        return $this->utilities;
39
-    }
40
-
41
-    /**
42
-     * Determine whether the Query should execute. If it's determined that the query should
43
-     * not be run based on context such as, but not limited to, who the user is, where in the
44
-     * ResolveTree the Query is, the relation to the node the Query is connected to, etc
45
-     * Return false to prevent the query from executing.
46
-     *
47
-     * @return bool
48
-     */
49
-    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
50
-    public function should_execute(): bool
51
-    {
52
-        return $this->should_execute;
53
-    }
54
-
55
-
56
-    /**
57
-     * Set limit the highest value of first and last, with a (filterable) max of 500
58
-     *
59
-     * @return int
60
-     */
61
-    protected function getLimit(): int
62
-    {
63
-        $first = ! empty($this->args['first'])
64
-            ? absint($this->args['first'])
65
-            : null;
66
-        $last  = ! empty($this->args['last'])
67
-            ? absint($this->args['last'])
68
-            : null;
69
-
70
-        $limit = min(
71
-            max($first, $last, self::MAX_QUERY_LIMIT),
72
-            $this->query_amount
73
-        );
74
-        $limit++;
75
-        return $limit;
76
-    }
77
-
78
-    // /**
79
-    //  * Get_amount_requested
80
-    //  *
81
-    //  * This checks the $args to determine the amount requested
82
-    //  *
83
-    //  * @return int|null
84
-    //  * @throws Exception
85
-    //  */
86
-    // // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
87
-    // public function get_amount_requested(): ?int
88
-    // {
89
-    //     $amount_requested = parent::get_amount_requested();
90
-    //
91
-    //     /**
92
-    //      * If both first & last are used in the input args, throw an exception as that won't
93
-    //      * work properly
94
-    //      */
95
-    //     if (empty($this->args['first']) && empty($this->args['last']) && $amount_requested === ConnectionsManager::MAX_AMOUNT_REQUESTED) {
96
-    //         return ConnectionsManager::MAX_AMOUNT_REQUESTED; // default.
97
-    //     }
98
-    //
99
-    //     return $amount_requested;
100
-    // }
101
-
102
-    /**
103
-     * Determine whether or not the the offset is valid, i.e the entity corresponding to the
104
-     * offset exists. Offset is equivalent to entity ID. So this function is equivalent to
105
-     * checking if the entity with the given ID exists.
106
-     *
107
-     * @param int $offset The ID of the node used for the cursor offset
108
-     * @return bool
109
-     */
110
-    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
111
-    public function is_valid_offset($offset): bool
112
-    {
113
-        $entity = $this->get_query()->get_one_by_ID($offset);
114
-
115
-        return $entity instanceof EE_Base_Class;
116
-    }
117
-
118
-    /**
119
-     * Validates Model.
120
-     *
121
-     * @param array $model Entity node.
122
-     * @return bool
123
-     */
124
-    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
125
-    protected function is_valid_model($model): bool
126
-    {
127
-        return $model instanceof EE_Base_Class;
128
-    }
129
-
130
-
131
-    /**
132
-     * This sets up the "allowed" args, and translates the GraphQL-friendly keys to model
133
-     * friendly keys.
134
-     *
135
-     * @param array  $query_args
136
-     * @param array  $where_params
137
-     * @param string $primary_key
138
-     * @return array
139
-     */
140
-    protected function mapOrderbyInputArgs(array $query_args, array $where_params, string $primary_key): array
141
-    {
142
-        // ID of the current offset
143
-        $offset = $this->get_offset();
144
-        /**
145
-         * Map the orderby inputArgs to the WP_Query
146
-         */
147
-        if (! empty($this->args['where']['orderby']) && is_array($this->args['where']['orderby'])) {
148
-            $query_args['order_by'] = [];
149
-            foreach ($this->args['where']['orderby'] as $orderby_input) {
150
-                $query_args['order_by'][ $orderby_input['field'] ] = $orderby_input['order'];
151
-            }
152
-        } elseif ($offset) {
153
-            $compare = $this->args['last'] ? '<' : '>';
154
-            $where_params[ $primary_key ] = [$compare, $offset];
155
-        }
156
-        return [$query_args, $where_params];
157
-    }
158
-
159
-
160
-    /**
161
-     * This sets up the "allowed" args, and translates the GraphQL-friendly keys to model
162
-     * friendly keys.
163
-     *
164
-     * @param array $where_args
165
-     * @param array $arg_mapping
166
-     * @param array $id_fields The fields to convert from global IDs to DB IDs.
167
-     * @return array
168
-     */
169
-    protected function sanitizeWhereArgsForInputFields(array $where_args, array $arg_mapping, array $id_fields = []): array
170
-    {
171
-        $query_args = $this->getUtilities()->sanitizeWhereArgs($where_args, $arg_mapping, $id_fields);
172
-        return ! empty($query_args) && is_array($query_args)
173
-            ? $query_args
174
-            : [];
175
-    }
176
-
177
-
178
-    /**
179
-     * This returns the sanitized "search" keywords from where_args
180
-     *
181
-     * @param array $where_args
182
-     * @return string
183
-     */
184
-    protected function getSearchKeywords(array $where_args): string
185
-    {
186
-        $search = '';
187
-        if (! empty($where_args['search'])) {
188
-            $search = sanitize_text_field($where_args['search']);
189
-        }
190
-        return esc_sql($search);
191
-    }
22
+	const MAX_QUERY_LIMIT = 250;
23
+
24
+	/**
25
+	 * @var Utilities
26
+	 */
27
+	private $utilities;
28
+
29
+
30
+	/**
31
+	 * @return Utilities
32
+	 */
33
+	public function getUtilities(): Utilities
34
+	{
35
+		if (! $this->utilities instanceof Utilities) {
36
+			$this->utilities = LoaderFactory::getLoader()->getShared(Utilities::class);
37
+		}
38
+		return $this->utilities;
39
+	}
40
+
41
+	/**
42
+	 * Determine whether the Query should execute. If it's determined that the query should
43
+	 * not be run based on context such as, but not limited to, who the user is, where in the
44
+	 * ResolveTree the Query is, the relation to the node the Query is connected to, etc
45
+	 * Return false to prevent the query from executing.
46
+	 *
47
+	 * @return bool
48
+	 */
49
+	// phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
50
+	public function should_execute(): bool
51
+	{
52
+		return $this->should_execute;
53
+	}
54
+
55
+
56
+	/**
57
+	 * Set limit the highest value of first and last, with a (filterable) max of 500
58
+	 *
59
+	 * @return int
60
+	 */
61
+	protected function getLimit(): int
62
+	{
63
+		$first = ! empty($this->args['first'])
64
+			? absint($this->args['first'])
65
+			: null;
66
+		$last  = ! empty($this->args['last'])
67
+			? absint($this->args['last'])
68
+			: null;
69
+
70
+		$limit = min(
71
+			max($first, $last, self::MAX_QUERY_LIMIT),
72
+			$this->query_amount
73
+		);
74
+		$limit++;
75
+		return $limit;
76
+	}
77
+
78
+	// /**
79
+	//  * Get_amount_requested
80
+	//  *
81
+	//  * This checks the $args to determine the amount requested
82
+	//  *
83
+	//  * @return int|null
84
+	//  * @throws Exception
85
+	//  */
86
+	// // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
87
+	// public function get_amount_requested(): ?int
88
+	// {
89
+	//     $amount_requested = parent::get_amount_requested();
90
+	//
91
+	//     /**
92
+	//      * If both first & last are used in the input args, throw an exception as that won't
93
+	//      * work properly
94
+	//      */
95
+	//     if (empty($this->args['first']) && empty($this->args['last']) && $amount_requested === ConnectionsManager::MAX_AMOUNT_REQUESTED) {
96
+	//         return ConnectionsManager::MAX_AMOUNT_REQUESTED; // default.
97
+	//     }
98
+	//
99
+	//     return $amount_requested;
100
+	// }
101
+
102
+	/**
103
+	 * Determine whether or not the the offset is valid, i.e the entity corresponding to the
104
+	 * offset exists. Offset is equivalent to entity ID. So this function is equivalent to
105
+	 * checking if the entity with the given ID exists.
106
+	 *
107
+	 * @param int $offset The ID of the node used for the cursor offset
108
+	 * @return bool
109
+	 */
110
+	// phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
111
+	public function is_valid_offset($offset): bool
112
+	{
113
+		$entity = $this->get_query()->get_one_by_ID($offset);
114
+
115
+		return $entity instanceof EE_Base_Class;
116
+	}
117
+
118
+	/**
119
+	 * Validates Model.
120
+	 *
121
+	 * @param array $model Entity node.
122
+	 * @return bool
123
+	 */
124
+	// phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
125
+	protected function is_valid_model($model): bool
126
+	{
127
+		return $model instanceof EE_Base_Class;
128
+	}
129
+
130
+
131
+	/**
132
+	 * This sets up the "allowed" args, and translates the GraphQL-friendly keys to model
133
+	 * friendly keys.
134
+	 *
135
+	 * @param array  $query_args
136
+	 * @param array  $where_params
137
+	 * @param string $primary_key
138
+	 * @return array
139
+	 */
140
+	protected function mapOrderbyInputArgs(array $query_args, array $where_params, string $primary_key): array
141
+	{
142
+		// ID of the current offset
143
+		$offset = $this->get_offset();
144
+		/**
145
+		 * Map the orderby inputArgs to the WP_Query
146
+		 */
147
+		if (! empty($this->args['where']['orderby']) && is_array($this->args['where']['orderby'])) {
148
+			$query_args['order_by'] = [];
149
+			foreach ($this->args['where']['orderby'] as $orderby_input) {
150
+				$query_args['order_by'][ $orderby_input['field'] ] = $orderby_input['order'];
151
+			}
152
+		} elseif ($offset) {
153
+			$compare = $this->args['last'] ? '<' : '>';
154
+			$where_params[ $primary_key ] = [$compare, $offset];
155
+		}
156
+		return [$query_args, $where_params];
157
+	}
158
+
159
+
160
+	/**
161
+	 * This sets up the "allowed" args, and translates the GraphQL-friendly keys to model
162
+	 * friendly keys.
163
+	 *
164
+	 * @param array $where_args
165
+	 * @param array $arg_mapping
166
+	 * @param array $id_fields The fields to convert from global IDs to DB IDs.
167
+	 * @return array
168
+	 */
169
+	protected function sanitizeWhereArgsForInputFields(array $where_args, array $arg_mapping, array $id_fields = []): array
170
+	{
171
+		$query_args = $this->getUtilities()->sanitizeWhereArgs($where_args, $arg_mapping, $id_fields);
172
+		return ! empty($query_args) && is_array($query_args)
173
+			? $query_args
174
+			: [];
175
+	}
176
+
177
+
178
+	/**
179
+	 * This returns the sanitized "search" keywords from where_args
180
+	 *
181
+	 * @param array $where_args
182
+	 * @return string
183
+	 */
184
+	protected function getSearchKeywords(array $where_args): string
185
+	{
186
+		$search = '';
187
+		if (! empty($where_args['search'])) {
188
+			$search = sanitize_text_field($where_args['search']);
189
+		}
190
+		return esc_sql($search);
191
+	}
192 192
 }
Please login to merge, or discard this patch.
core/services/graphql/ConnectionsManager.php 1 patch
Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -17,58 +17,58 @@
 block discarded – undo
17 17
  */
18 18
 class ConnectionsManager implements GQLManagerInterface
19 19
 {
20
-    const MAX_AMOUNT_REQUESTED = 250;
20
+	const MAX_AMOUNT_REQUESTED = 250;
21 21
 
22
-    const MAX_QUERY_AMOUNT = 250;
22
+	const MAX_QUERY_AMOUNT = 250;
23 23
 
24 24
 
25
-    /**
26
-     * @var ConnectionCollection|ConnectionInterface[] $connections
27
-     */
28
-    private $connections;
25
+	/**
26
+	 * @var ConnectionCollection|ConnectionInterface[] $connections
27
+	 */
28
+	private $connections;
29 29
 
30 30
 
31
-    /**
32
-     * ConnectionsManager constructor.
33
-     *
34
-     * @param ConnectionCollection|ConnectionInterface[] $connections
35
-     */
36
-    public function __construct(ConnectionCollection $connections)
37
-    {
38
-        $this->connections = $connections;
39
-    }
31
+	/**
32
+	 * ConnectionsManager constructor.
33
+	 *
34
+	 * @param ConnectionCollection|ConnectionInterface[] $connections
35
+	 */
36
+	public function __construct(ConnectionCollection $connections)
37
+	{
38
+		$this->connections = $connections;
39
+	}
40 40
 
41 41
 
42
-    /**
43
-     * @throws CollectionDetailsException
44
-     * @throws CollectionLoaderException
45
-     * @since $VID:$
46
-     */
47
-    public function init()
48
-    {
49
-        $this->connections->loadConnections();
50
-        add_action('graphql_register_types', [$this, 'registerConnections'], 20);
51
-        add_filter('graphql_connection_amount_requested', [$this, 'setMaxAmountRequested']);
52
-        add_filter('graphql_connection_max_query_amount', [$this, 'setMaxQueryAmount']);
53
-    }
42
+	/**
43
+	 * @throws CollectionDetailsException
44
+	 * @throws CollectionLoaderException
45
+	 * @since $VID:$
46
+	 */
47
+	public function init()
48
+	{
49
+		$this->connections->loadConnections();
50
+		add_action('graphql_register_types', [$this, 'registerConnections'], 20);
51
+		add_filter('graphql_connection_amount_requested', [$this, 'setMaxAmountRequested']);
52
+		add_filter('graphql_connection_max_query_amount', [$this, 'setMaxQueryAmount']);
53
+	}
54 54
 
55 55
 
56
-    public function registerConnections()
57
-    {
58
-        // loop through the collection of types and register their fields
59
-        foreach ($this->connections as $connection) {
60
-            register_graphql_connection($connection->config());
61
-        }
62
-    }
56
+	public function registerConnections()
57
+	{
58
+		// loop through the collection of types and register their fields
59
+		foreach ($this->connections as $connection) {
60
+			register_graphql_connection($connection->config());
61
+		}
62
+	}
63 63
 
64 64
 
65
-    public function setMaxAmountRequested(): int
66
-    {
67
-        return ConnectionsManager::MAX_AMOUNT_REQUESTED;
68
-    }
65
+	public function setMaxAmountRequested(): int
66
+	{
67
+		return ConnectionsManager::MAX_AMOUNT_REQUESTED;
68
+	}
69 69
 
70
-    public function setMaxQueryAmount(): int
71
-    {
72
-        return ConnectionsManager::MAX_QUERY_AMOUNT;
73
-    }
70
+	public function setMaxQueryAmount(): int
71
+	{
72
+		return ConnectionsManager::MAX_QUERY_AMOUNT;
73
+	}
74 74
 }
Please login to merge, or discard this patch.
modules/ticket_sales_monitor/EED_Ticket_Sales_Monitor.module.php 2 patches
Indentation   +1068 added lines, -1068 removed lines patch added patch discarded remove patch
@@ -18,1074 +18,1074 @@
 block discarded – undo
18 18
  */
19 19
 class EED_Ticket_Sales_Monitor extends EED_Module
20 20
 {
21
-    const debug = false;    // true false
22
-
23
-    private static $nl = '';
24
-
25
-    /**
26
-     * an array for tracking names of tickets that have sold out
27
-     *
28
-     * @var array $sold_out_tickets
29
-     */
30
-    protected $sold_out_tickets = array();
31
-
32
-    /**
33
-     * an array for tracking names of tickets that have had their quantities reduced
34
-     *
35
-     * @var array $decremented_tickets
36
-     */
37
-    protected $decremented_tickets = array();
38
-
39
-
40
-    /**
41
-     * set_hooks - for hooking into EE Core, other modules, etc
42
-     *
43
-     * @return    void
44
-     */
45
-    public static function set_hooks()
46
-    {
47
-        self::$nl = defined('EE_TESTS_DIR') ? "\n" : '<br />';
48
-        // release tickets for expired carts
49
-        add_action(
50
-            'EED_Ticket_Selector__process_ticket_selections__before',
51
-            array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
52
-            1
53
-        );
54
-        // check ticket reserves AFTER MER does it's check (hence priority 20)
55
-        add_filter(
56
-            'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
57
-            array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
58
-            20,
59
-            3
60
-        );
61
-        // add notices for sold out tickets
62
-        add_action(
63
-            'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
64
-            array('EED_Ticket_Sales_Monitor', 'post_notices'),
65
-            10
66
-        );
67
-
68
-        // handle tickets deleted from cart
69
-        add_action(
70
-            'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
71
-            array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
72
-            10,
73
-            2
74
-        );
75
-        // handle emptied carts
76
-        add_action(
77
-            'AHEE__EE_Session__reset_cart__before_reset',
78
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
79
-            10,
80
-            1
81
-        );
82
-        add_action(
83
-            'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
84
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
85
-            10,
86
-            1
87
-        );
88
-        // handle cancelled registrations
89
-        add_action(
90
-            'AHEE__EE_Session__reset_checkout__before_reset',
91
-            array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
92
-            10,
93
-            1
94
-        );
95
-        // cron tasks
96
-        add_action(
97
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
98
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
99
-            10,
100
-            1
101
-        );
102
-        add_action(
103
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
104
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
105
-            10,
106
-            1
107
-        );
108
-        add_action(
109
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
110
-            array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
111
-            10,
112
-            1
113
-        );
114
-    }
115
-
116
-
117
-    /**
118
-     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
119
-     *
120
-     * @return void
121
-     */
122
-    public static function set_hooks_admin()
123
-    {
124
-        EED_Ticket_Sales_Monitor::set_hooks();
125
-    }
126
-
127
-
128
-    /**
129
-     * @return EED_Ticket_Sales_Monitor|EED_Module
130
-     * @throws EE_Error
131
-     * @throws ReflectionException
132
-     */
133
-    public static function instance()
134
-    {
135
-        return parent::get_instance(__CLASS__);
136
-    }
137
-
138
-
139
-    /**
140
-     * @param WP_Query $WP
141
-     * @return    void
142
-     */
143
-    public function run($WP)
144
-    {
145
-    }
146
-
147
-
148
-
149
-    /********************************** PRE_TICKET_SALES  **********************************/
150
-
151
-
152
-    /**
153
-     * Retrieves grand totals from the line items that have no TXN ID
154
-     * and timestamps less than the current time minus the session lifespan.
155
-     * These are carts that have been abandoned before the "registrant" even attempted to checkout.
156
-     * We're going to release the tickets for these line items before attempting to add more to the cart.
157
-     *
158
-     * @return void
159
-     * @throws DomainException
160
-     * @throws EE_Error
161
-     * @throws InvalidArgumentException
162
-     * @throws InvalidDataTypeException
163
-     * @throws InvalidInterfaceException
164
-     * @throws UnexpectedEntityException
165
-     * @throws ReflectionException
166
-     */
167
-    public static function release_tickets_for_expired_carts()
168
-    {
169
-        // self::debug hardcoded to false
170
-        if (self::debug) {
171
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
172
-        }
173
-        do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
174
-        $expired_ticket_IDs = array();
175
-        /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
176
-        $session_lifespan = LoaderFactory::getLoader()->getShared(
177
-            'EventEspresso\core\domain\values\session\SessionLifespan'
178
-        );
179
-        $timestamp = $session_lifespan->expiration();
180
-        $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
181
-        if (self::debug) {
182
-            echo self::$nl . ' . time(): ' . time();
183
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
184
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
185
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
186
-            echo self::$nl . ' . timestamp: ' . $timestamp;
187
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
188
-        }
189
-        if (! empty($expired_ticket_line_items)) {
190
-            foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
191
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
192
-                    continue;
193
-                }
194
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
195
-                if (self::debug) {
196
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
197
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
198
-                         . date(
199
-                             'Y-m-d h:i a',
200
-                             $expired_ticket_line_item->timestamp(true)
201
-                         );
202
-                }
203
-            }
204
-            if (! empty($expired_ticket_IDs)) {
205
-                EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
206
-                    EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
207
-                    array(),
208
-                    __FUNCTION__
209
-                );
210
-                // now  let's get rid of expired line items so that they can't interfere with tracking
211
-                EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
212
-            }
213
-        }
214
-        do_action(
215
-            'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
216
-            $expired_ticket_IDs,
217
-            $expired_ticket_line_items
218
-        );
219
-    }
220
-
221
-
222
-
223
-    /********************************** VALIDATE_TICKET_SALE  **********************************/
224
-
225
-
226
-    /**
227
-     * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
228
-     *
229
-     * @param int       $qty
230
-     * @param EE_Ticket $ticket
231
-     * @return int
232
-     * @throws UnexpectedEntityException
233
-     * @throws EE_Error
234
-     * @throws ReflectionException
235
-     */
236
-    public static function validate_ticket_sale(int $qty, EE_Ticket $ticket): int
237
-    {
238
-        $qty = absint($qty);
239
-        if ($qty > 0) {
240
-            $qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
241
-        }
242
-        // self::debug hardcoded to false
243
-        if (self::debug) {
244
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
245
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
246
-        }
247
-        return $qty;
248
-    }
249
-
250
-
251
-    /**
252
-     * checks whether an individual ticket is available for purchase based on datetime, and ticket details
253
-     *
254
-     * @param EE_Ticket|null $ticket
255
-     * @param int       $qty
256
-     * @return int
257
-     * @throws UnexpectedEntityException
258
-     * @throws EE_Error
259
-     * @throws ReflectionException
260
-     */
261
-    protected function _validate_ticket_sale(?EE_Ticket $ticket, int $qty = 1): int
262
-    {
263
-        // self::debug hardcoded to false
264
-        if (self::debug) {
265
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
266
-        }
267
-        if (! $ticket instanceof EE_Ticket) {
268
-            return 0;
269
-        }
270
-        if (self::debug) {
271
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
272
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
273
-        }
274
-        $ticket->refresh_from_db();
275
-        // first let's determine the ticket availability based on sales
276
-        $available = $ticket->qty('saleable');
277
-        if (self::debug) {
278
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
279
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
280
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
281
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
282
-            echo self::$nl . ' . . . available: ' . $available;
283
-        }
284
-        if ($available < 1) {
285
-            $this->_ticket_sold_out($ticket);
286
-            return 0;
287
-        }
288
-        if (self::debug) {
289
-            echo self::$nl . ' . . . qty: ' . $qty;
290
-        }
291
-        if ($available < $qty) {
292
-            $qty = $available;
293
-            if (self::debug) {
294
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
295
-            }
296
-            $this->_ticket_quantity_decremented($ticket);
297
-        }
298
-        if ($this->_reserve_ticket($ticket, $qty)) {
299
-            return $qty;
300
-        }
301
-        return 0;
302
-    }
303
-
304
-
305
-    /**
306
-     * increments ticket reserved based on quantity passed
307
-     *
308
-     * @param EE_Ticket $ticket
309
-     * @param int       $quantity
310
-     * @return bool indicating success or failure
311
-     * @throws EE_Error
312
-     * @throws ReflectionException
313
-     */
314
-    protected function _reserve_ticket(EE_Ticket $ticket, int $quantity = 1): bool
315
-    {
316
-        // self::debug hardcoded to false
317
-        if (self::debug) {
318
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
319
-        }
320
-        return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:' . __LINE__);
321
-    }
322
-
323
-
324
-    /**
325
-     * @param EE_Ticket $ticket
326
-     * @param int       $quantity
327
-     * @return bool
328
-     * @throws EE_Error
329
-     * @throws ReflectionException
330
-     */
331
-    protected function _release_reserved_ticket(EE_Ticket $ticket, int $quantity = 1): bool
332
-    {
333
-        // self::debug hardcoded to false
334
-        if (self::debug) {
335
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
336
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
337
-        }
338
-        $ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
339
-        if (self::debug) {
340
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
341
-        }
342
-        return (bool) $ticket->save();
343
-    }
344
-
345
-
346
-    /**
347
-     * removes quantities within the ticket selector based on zero ticket availability
348
-     *
349
-     * @param EE_Ticket $ticket
350
-     * @return    void
351
-     * @throws UnexpectedEntityException
352
-     * @throws EE_Error
353
-     * @throws ReflectionException
354
-     */
355
-    protected function _ticket_sold_out(EE_Ticket $ticket)
356
-    {
357
-        // self::debug hardcoded to false
358
-        if (self::debug) {
359
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
360
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
361
-        }
362
-        $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
363
-    }
364
-
365
-
366
-    /**
367
-     * adjusts quantities within the ticket selector based on decreased ticket availability
368
-     *
369
-     * @param EE_Ticket $ticket
370
-     * @return void
371
-     * @throws UnexpectedEntityException
372
-     * @throws EE_Error
373
-     * @throws ReflectionException
374
-     */
375
-    protected function _ticket_quantity_decremented(EE_Ticket $ticket)
376
-    {
377
-        // self::debug hardcoded to false
378
-        if (self::debug) {
379
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
380
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
381
-        }
382
-        $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
383
-    }
384
-
385
-
386
-    /**
387
-     * builds string out of ticket and event name
388
-     *
389
-     * @param EE_Ticket $ticket
390
-     * @return string
391
-     * @throws UnexpectedEntityException
392
-     * @throws EE_Error
393
-     * @throws ReflectionException
394
-     */
395
-    protected function _get_ticket_and_event_name(EE_Ticket $ticket): string
396
-    {
397
-        $event = $ticket->get_related_event();
398
-        if ($event instanceof EE_Event) {
399
-            $ticket_name = sprintf(
400
-                _x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
401
-                $ticket->name(),
402
-                $event->name()
403
-            );
404
-        } else {
405
-            $ticket_name = $ticket->name();
406
-        }
407
-        return $ticket_name;
408
-    }
409
-
410
-
411
-
412
-    /********************************** EVENT CART  **********************************/
413
-
414
-
415
-    /**
416
-     * releases or reserves ticket(s) based on quantity passed
417
-     *
418
-     * @param EE_Line_Item $line_item
419
-     * @param int          $quantity
420
-     * @return void
421
-     * @throws EE_Error
422
-     * @throws InvalidArgumentException
423
-     * @throws InvalidDataTypeException
424
-     * @throws InvalidInterfaceException
425
-     * @throws ReflectionException
426
-     */
427
-    public static function ticket_quantity_updated(EE_Line_Item $line_item, int $quantity = 1)
428
-    {
429
-        $ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
430
-        if ($ticket instanceof EE_Ticket) {
431
-            $ticket->add_extra_meta(
432
-                EE_Ticket::META_KEY_TICKET_RESERVATIONS,
433
-                __LINE__ . ') ' . __METHOD__ . '()'
434
-            );
435
-            if ($quantity > 0) {
436
-                EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
437
-            } else {
438
-                EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
439
-            }
440
-        }
441
-    }
442
-
443
-
444
-    /**
445
-     * releases reserved ticket(s) based on quantity passed
446
-     *
447
-     * @param EE_Ticket $ticket
448
-     * @param int       $quantity
449
-     * @return void
450
-     * @throws EE_Error
451
-     * @throws ReflectionException
452
-     */
453
-    public static function ticket_removed_from_cart(EE_Ticket $ticket, int $quantity = 1)
454
-    {
455
-        $ticket->add_extra_meta(
456
-            EE_Ticket::META_KEY_TICKET_RESERVATIONS,
457
-            __LINE__ . ') ' . __METHOD__ . '()'
458
-        );
459
-        EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
460
-    }
461
-
462
-
463
-
464
-    /********************************** POST_NOTICES  **********************************/
465
-
466
-
467
-    /**
468
-     * @return void
469
-     * @throws EE_Error
470
-     * @throws ReflectionException
471
-     */
472
-    public static function post_notices()
473
-    {
474
-        EED_Ticket_Sales_Monitor::instance()->_post_notices();
475
-    }
476
-
477
-
478
-    /**
479
-     * @return void
480
-     * @throws EE_Error
481
-     * @throws InvalidArgumentException
482
-     * @throws ReflectionException
483
-     * @throws InvalidDataTypeException
484
-     * @throws InvalidInterfaceException
485
-     */
486
-    protected function _post_notices()
487
-    {
488
-        // self::debug hardcoded to false
489
-        if (self::debug) {
490
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
491
-        }
492
-        $refresh_msg = '';
493
-        $none_added_msg = '';
494
-        if (defined('DOING_AJAX') && DOING_AJAX) {
495
-            $refresh_msg = esc_html__(
496
-                'Please refresh the page to view updated ticket quantities.',
497
-                'event_espresso'
498
-            );
499
-            $none_added_msg = esc_html__('No tickets were added for the event.', 'event_espresso');
500
-        }
501
-        if (! empty($this->sold_out_tickets)) {
502
-            EE_Error::add_attention(
503
-                sprintf(
504
-                    apply_filters(
505
-                        'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
506
-                        esc_html__(
507
-                            'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
508
-                            'event_espresso'
509
-                        )
510
-                    ),
511
-                    '<br />',
512
-                    implode('<br />', $this->sold_out_tickets),
513
-                    $none_added_msg,
514
-                    $refresh_msg
515
-                )
516
-            );
517
-            // alter code flow in the Ticket Selector for better UX
518
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
519
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
520
-            $this->sold_out_tickets = array();
521
-            // and reset the cart
522
-            EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
523
-        }
524
-        if (! empty($this->decremented_tickets)) {
525
-            EE_Error::add_attention(
526
-                sprintf(
527
-                    apply_filters(
528
-                        'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
529
-                        esc_html__(
530
-                            'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
531
-                            'event_espresso'
532
-                        )
533
-                    ),
534
-                    '<br />',
535
-                    implode('<br />', $this->decremented_tickets),
536
-                    $none_added_msg,
537
-                    $refresh_msg
538
-                )
539
-            );
540
-            $this->decremented_tickets = array();
541
-        }
542
-    }
543
-
544
-
545
-
546
-    /********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
547
-
548
-
549
-    /**
550
-     * releases reserved tickets for all registrations of an EE_Transaction
551
-     * by default, will NOT release tickets for finalized transactions
552
-     *
553
-     * @param EE_Transaction $transaction
554
-     * @return int
555
-     * @throws EE_Error
556
-     * @throws ReflectionException
557
-     */
558
-    protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction): int
559
-    {
560
-        // self::debug hardcoded to false
561
-        if (self::debug) {
562
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
563
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
564
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
565
-        }
566
-        // check if 'finalize_registration' step has been completed...
567
-        $finalized = $transaction->reg_step_completed('finalize_registration');
568
-        if (self::debug) {
569
-            // DEBUG LOG
570
-            EEH_Debug_Tools::log(
571
-                __CLASS__,
572
-                __FUNCTION__,
573
-                __LINE__,
574
-                array('finalized' => $finalized),
575
-                false,
576
-                'EE_Transaction: ' . $transaction->ID()
577
-            );
578
-        }
579
-        // how many tickets were released
580
-        $count = 0;
581
-        if (self::debug) {
582
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
583
-        }
584
-        $release_tickets_with_TXN_status = array(
585
-            EEM_Transaction::failed_status_code,
586
-            EEM_Transaction::abandoned_status_code,
587
-            EEM_Transaction::incomplete_status_code,
588
-        );
589
-        $events = array();
590
-        // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
591
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
592
-            // cancel any reserved tickets for registrations that were not approved
593
-            $registrations = $transaction->registrations();
594
-            if (self::debug) {
595
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
596
-                $reg = reset($registrations);
597
-                $ticket = $reg->ticket();
598
-                if ($ticket instanceof EE_Ticket) {
599
-                    $ticket->add_extra_meta(
600
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
601
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
602
-                    );
603
-                }
604
-            }
605
-            if (! empty($registrations)) {
606
-                foreach ($registrations as $registration) {
607
-                    if (
608
-                        $registration instanceof EE_Registration
609
-                        && $this->_release_reserved_ticket_for_registration($registration, $transaction)
610
-                    ) {
611
-                        $count++;
612
-                        $events[ $registration->event_ID() ] = $registration->event();
613
-                    }
614
-                }
615
-            }
616
-        }
617
-        if ($events !== array()) {
618
-            foreach ($events as $event) {
619
-                /** @var EE_Event $event */
620
-                $event->perform_sold_out_status_check();
621
-            }
622
-        }
623
-        return $count;
624
-    }
625
-
626
-
627
-    /**
628
-     * releases reserved tickets for an EE_Registration
629
-     * by default, will NOT release tickets for APPROVED registrations
630
-     *
631
-     * @param EE_Registration $registration
632
-     * @param EE_Transaction  $transaction
633
-     * @return int
634
-     * @throws EE_Error
635
-     * @throws ReflectionException
636
-     */
637
-    protected function _release_reserved_ticket_for_registration(
638
-        EE_Registration $registration,
639
-        EE_Transaction $transaction
640
-    ): int {
641
-        $STS_ID = $transaction->status_ID();
642
-        // self::debug hardcoded to false
643
-        if (self::debug) {
644
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
645
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
646
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
647
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
648
-        }
649
-        if (
21
+	const debug = false;    // true false
22
+
23
+	private static $nl = '';
24
+
25
+	/**
26
+	 * an array for tracking names of tickets that have sold out
27
+	 *
28
+	 * @var array $sold_out_tickets
29
+	 */
30
+	protected $sold_out_tickets = array();
31
+
32
+	/**
33
+	 * an array for tracking names of tickets that have had their quantities reduced
34
+	 *
35
+	 * @var array $decremented_tickets
36
+	 */
37
+	protected $decremented_tickets = array();
38
+
39
+
40
+	/**
41
+	 * set_hooks - for hooking into EE Core, other modules, etc
42
+	 *
43
+	 * @return    void
44
+	 */
45
+	public static function set_hooks()
46
+	{
47
+		self::$nl = defined('EE_TESTS_DIR') ? "\n" : '<br />';
48
+		// release tickets for expired carts
49
+		add_action(
50
+			'EED_Ticket_Selector__process_ticket_selections__before',
51
+			array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
52
+			1
53
+		);
54
+		// check ticket reserves AFTER MER does it's check (hence priority 20)
55
+		add_filter(
56
+			'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
57
+			array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
58
+			20,
59
+			3
60
+		);
61
+		// add notices for sold out tickets
62
+		add_action(
63
+			'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
64
+			array('EED_Ticket_Sales_Monitor', 'post_notices'),
65
+			10
66
+		);
67
+
68
+		// handle tickets deleted from cart
69
+		add_action(
70
+			'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
71
+			array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
72
+			10,
73
+			2
74
+		);
75
+		// handle emptied carts
76
+		add_action(
77
+			'AHEE__EE_Session__reset_cart__before_reset',
78
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
79
+			10,
80
+			1
81
+		);
82
+		add_action(
83
+			'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
84
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
85
+			10,
86
+			1
87
+		);
88
+		// handle cancelled registrations
89
+		add_action(
90
+			'AHEE__EE_Session__reset_checkout__before_reset',
91
+			array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
92
+			10,
93
+			1
94
+		);
95
+		// cron tasks
96
+		add_action(
97
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
98
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
99
+			10,
100
+			1
101
+		);
102
+		add_action(
103
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
104
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
105
+			10,
106
+			1
107
+		);
108
+		add_action(
109
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
110
+			array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
111
+			10,
112
+			1
113
+		);
114
+	}
115
+
116
+
117
+	/**
118
+	 * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
119
+	 *
120
+	 * @return void
121
+	 */
122
+	public static function set_hooks_admin()
123
+	{
124
+		EED_Ticket_Sales_Monitor::set_hooks();
125
+	}
126
+
127
+
128
+	/**
129
+	 * @return EED_Ticket_Sales_Monitor|EED_Module
130
+	 * @throws EE_Error
131
+	 * @throws ReflectionException
132
+	 */
133
+	public static function instance()
134
+	{
135
+		return parent::get_instance(__CLASS__);
136
+	}
137
+
138
+
139
+	/**
140
+	 * @param WP_Query $WP
141
+	 * @return    void
142
+	 */
143
+	public function run($WP)
144
+	{
145
+	}
146
+
147
+
148
+
149
+	/********************************** PRE_TICKET_SALES  **********************************/
150
+
151
+
152
+	/**
153
+	 * Retrieves grand totals from the line items that have no TXN ID
154
+	 * and timestamps less than the current time minus the session lifespan.
155
+	 * These are carts that have been abandoned before the "registrant" even attempted to checkout.
156
+	 * We're going to release the tickets for these line items before attempting to add more to the cart.
157
+	 *
158
+	 * @return void
159
+	 * @throws DomainException
160
+	 * @throws EE_Error
161
+	 * @throws InvalidArgumentException
162
+	 * @throws InvalidDataTypeException
163
+	 * @throws InvalidInterfaceException
164
+	 * @throws UnexpectedEntityException
165
+	 * @throws ReflectionException
166
+	 */
167
+	public static function release_tickets_for_expired_carts()
168
+	{
169
+		// self::debug hardcoded to false
170
+		if (self::debug) {
171
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
172
+		}
173
+		do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
174
+		$expired_ticket_IDs = array();
175
+		/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
176
+		$session_lifespan = LoaderFactory::getLoader()->getShared(
177
+			'EventEspresso\core\domain\values\session\SessionLifespan'
178
+		);
179
+		$timestamp = $session_lifespan->expiration();
180
+		$expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
181
+		if (self::debug) {
182
+			echo self::$nl . ' . time(): ' . time();
183
+			echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
184
+			echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
185
+			echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
186
+			echo self::$nl . ' . timestamp: ' . $timestamp;
187
+			echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
188
+		}
189
+		if (! empty($expired_ticket_line_items)) {
190
+			foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
191
+				if (! $expired_ticket_line_item instanceof EE_Line_Item) {
192
+					continue;
193
+				}
194
+				$expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
195
+				if (self::debug) {
196
+					echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
197
+					echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
198
+						 . date(
199
+							 'Y-m-d h:i a',
200
+							 $expired_ticket_line_item->timestamp(true)
201
+						 );
202
+				}
203
+			}
204
+			if (! empty($expired_ticket_IDs)) {
205
+				EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
206
+					EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
207
+					array(),
208
+					__FUNCTION__
209
+				);
210
+				// now  let's get rid of expired line items so that they can't interfere with tracking
211
+				EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
212
+			}
213
+		}
214
+		do_action(
215
+			'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
216
+			$expired_ticket_IDs,
217
+			$expired_ticket_line_items
218
+		);
219
+	}
220
+
221
+
222
+
223
+	/********************************** VALIDATE_TICKET_SALE  **********************************/
224
+
225
+
226
+	/**
227
+	 * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
228
+	 *
229
+	 * @param int       $qty
230
+	 * @param EE_Ticket $ticket
231
+	 * @return int
232
+	 * @throws UnexpectedEntityException
233
+	 * @throws EE_Error
234
+	 * @throws ReflectionException
235
+	 */
236
+	public static function validate_ticket_sale(int $qty, EE_Ticket $ticket): int
237
+	{
238
+		$qty = absint($qty);
239
+		if ($qty > 0) {
240
+			$qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
241
+		}
242
+		// self::debug hardcoded to false
243
+		if (self::debug) {
244
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
245
+			echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
246
+		}
247
+		return $qty;
248
+	}
249
+
250
+
251
+	/**
252
+	 * checks whether an individual ticket is available for purchase based on datetime, and ticket details
253
+	 *
254
+	 * @param EE_Ticket|null $ticket
255
+	 * @param int       $qty
256
+	 * @return int
257
+	 * @throws UnexpectedEntityException
258
+	 * @throws EE_Error
259
+	 * @throws ReflectionException
260
+	 */
261
+	protected function _validate_ticket_sale(?EE_Ticket $ticket, int $qty = 1): int
262
+	{
263
+		// self::debug hardcoded to false
264
+		if (self::debug) {
265
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
266
+		}
267
+		if (! $ticket instanceof EE_Ticket) {
268
+			return 0;
269
+		}
270
+		if (self::debug) {
271
+			echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
272
+			echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
273
+		}
274
+		$ticket->refresh_from_db();
275
+		// first let's determine the ticket availability based on sales
276
+		$available = $ticket->qty('saleable');
277
+		if (self::debug) {
278
+			echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
279
+			echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
280
+			echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
281
+			echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
282
+			echo self::$nl . ' . . . available: ' . $available;
283
+		}
284
+		if ($available < 1) {
285
+			$this->_ticket_sold_out($ticket);
286
+			return 0;
287
+		}
288
+		if (self::debug) {
289
+			echo self::$nl . ' . . . qty: ' . $qty;
290
+		}
291
+		if ($available < $qty) {
292
+			$qty = $available;
293
+			if (self::debug) {
294
+				echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
295
+			}
296
+			$this->_ticket_quantity_decremented($ticket);
297
+		}
298
+		if ($this->_reserve_ticket($ticket, $qty)) {
299
+			return $qty;
300
+		}
301
+		return 0;
302
+	}
303
+
304
+
305
+	/**
306
+	 * increments ticket reserved based on quantity passed
307
+	 *
308
+	 * @param EE_Ticket $ticket
309
+	 * @param int       $quantity
310
+	 * @return bool indicating success or failure
311
+	 * @throws EE_Error
312
+	 * @throws ReflectionException
313
+	 */
314
+	protected function _reserve_ticket(EE_Ticket $ticket, int $quantity = 1): bool
315
+	{
316
+		// self::debug hardcoded to false
317
+		if (self::debug) {
318
+			echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
319
+		}
320
+		return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:' . __LINE__);
321
+	}
322
+
323
+
324
+	/**
325
+	 * @param EE_Ticket $ticket
326
+	 * @param int       $quantity
327
+	 * @return bool
328
+	 * @throws EE_Error
329
+	 * @throws ReflectionException
330
+	 */
331
+	protected function _release_reserved_ticket(EE_Ticket $ticket, int $quantity = 1): bool
332
+	{
333
+		// self::debug hardcoded to false
334
+		if (self::debug) {
335
+			echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
336
+			echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
337
+		}
338
+		$ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
339
+		if (self::debug) {
340
+			echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
341
+		}
342
+		return (bool) $ticket->save();
343
+	}
344
+
345
+
346
+	/**
347
+	 * removes quantities within the ticket selector based on zero ticket availability
348
+	 *
349
+	 * @param EE_Ticket $ticket
350
+	 * @return    void
351
+	 * @throws UnexpectedEntityException
352
+	 * @throws EE_Error
353
+	 * @throws ReflectionException
354
+	 */
355
+	protected function _ticket_sold_out(EE_Ticket $ticket)
356
+	{
357
+		// self::debug hardcoded to false
358
+		if (self::debug) {
359
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
360
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
361
+		}
362
+		$this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
363
+	}
364
+
365
+
366
+	/**
367
+	 * adjusts quantities within the ticket selector based on decreased ticket availability
368
+	 *
369
+	 * @param EE_Ticket $ticket
370
+	 * @return void
371
+	 * @throws UnexpectedEntityException
372
+	 * @throws EE_Error
373
+	 * @throws ReflectionException
374
+	 */
375
+	protected function _ticket_quantity_decremented(EE_Ticket $ticket)
376
+	{
377
+		// self::debug hardcoded to false
378
+		if (self::debug) {
379
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
380
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
381
+		}
382
+		$this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
383
+	}
384
+
385
+
386
+	/**
387
+	 * builds string out of ticket and event name
388
+	 *
389
+	 * @param EE_Ticket $ticket
390
+	 * @return string
391
+	 * @throws UnexpectedEntityException
392
+	 * @throws EE_Error
393
+	 * @throws ReflectionException
394
+	 */
395
+	protected function _get_ticket_and_event_name(EE_Ticket $ticket): string
396
+	{
397
+		$event = $ticket->get_related_event();
398
+		if ($event instanceof EE_Event) {
399
+			$ticket_name = sprintf(
400
+				_x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
401
+				$ticket->name(),
402
+				$event->name()
403
+			);
404
+		} else {
405
+			$ticket_name = $ticket->name();
406
+		}
407
+		return $ticket_name;
408
+	}
409
+
410
+
411
+
412
+	/********************************** EVENT CART  **********************************/
413
+
414
+
415
+	/**
416
+	 * releases or reserves ticket(s) based on quantity passed
417
+	 *
418
+	 * @param EE_Line_Item $line_item
419
+	 * @param int          $quantity
420
+	 * @return void
421
+	 * @throws EE_Error
422
+	 * @throws InvalidArgumentException
423
+	 * @throws InvalidDataTypeException
424
+	 * @throws InvalidInterfaceException
425
+	 * @throws ReflectionException
426
+	 */
427
+	public static function ticket_quantity_updated(EE_Line_Item $line_item, int $quantity = 1)
428
+	{
429
+		$ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
430
+		if ($ticket instanceof EE_Ticket) {
431
+			$ticket->add_extra_meta(
432
+				EE_Ticket::META_KEY_TICKET_RESERVATIONS,
433
+				__LINE__ . ') ' . __METHOD__ . '()'
434
+			);
435
+			if ($quantity > 0) {
436
+				EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
437
+			} else {
438
+				EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
439
+			}
440
+		}
441
+	}
442
+
443
+
444
+	/**
445
+	 * releases reserved ticket(s) based on quantity passed
446
+	 *
447
+	 * @param EE_Ticket $ticket
448
+	 * @param int       $quantity
449
+	 * @return void
450
+	 * @throws EE_Error
451
+	 * @throws ReflectionException
452
+	 */
453
+	public static function ticket_removed_from_cart(EE_Ticket $ticket, int $quantity = 1)
454
+	{
455
+		$ticket->add_extra_meta(
456
+			EE_Ticket::META_KEY_TICKET_RESERVATIONS,
457
+			__LINE__ . ') ' . __METHOD__ . '()'
458
+		);
459
+		EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
460
+	}
461
+
462
+
463
+
464
+	/********************************** POST_NOTICES  **********************************/
465
+
466
+
467
+	/**
468
+	 * @return void
469
+	 * @throws EE_Error
470
+	 * @throws ReflectionException
471
+	 */
472
+	public static function post_notices()
473
+	{
474
+		EED_Ticket_Sales_Monitor::instance()->_post_notices();
475
+	}
476
+
477
+
478
+	/**
479
+	 * @return void
480
+	 * @throws EE_Error
481
+	 * @throws InvalidArgumentException
482
+	 * @throws ReflectionException
483
+	 * @throws InvalidDataTypeException
484
+	 * @throws InvalidInterfaceException
485
+	 */
486
+	protected function _post_notices()
487
+	{
488
+		// self::debug hardcoded to false
489
+		if (self::debug) {
490
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
491
+		}
492
+		$refresh_msg = '';
493
+		$none_added_msg = '';
494
+		if (defined('DOING_AJAX') && DOING_AJAX) {
495
+			$refresh_msg = esc_html__(
496
+				'Please refresh the page to view updated ticket quantities.',
497
+				'event_espresso'
498
+			);
499
+			$none_added_msg = esc_html__('No tickets were added for the event.', 'event_espresso');
500
+		}
501
+		if (! empty($this->sold_out_tickets)) {
502
+			EE_Error::add_attention(
503
+				sprintf(
504
+					apply_filters(
505
+						'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
506
+						esc_html__(
507
+							'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
508
+							'event_espresso'
509
+						)
510
+					),
511
+					'<br />',
512
+					implode('<br />', $this->sold_out_tickets),
513
+					$none_added_msg,
514
+					$refresh_msg
515
+				)
516
+			);
517
+			// alter code flow in the Ticket Selector for better UX
518
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
519
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
520
+			$this->sold_out_tickets = array();
521
+			// and reset the cart
522
+			EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
523
+		}
524
+		if (! empty($this->decremented_tickets)) {
525
+			EE_Error::add_attention(
526
+				sprintf(
527
+					apply_filters(
528
+						'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
529
+						esc_html__(
530
+							'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
531
+							'event_espresso'
532
+						)
533
+					),
534
+					'<br />',
535
+					implode('<br />', $this->decremented_tickets),
536
+					$none_added_msg,
537
+					$refresh_msg
538
+				)
539
+			);
540
+			$this->decremented_tickets = array();
541
+		}
542
+	}
543
+
544
+
545
+
546
+	/********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
547
+
548
+
549
+	/**
550
+	 * releases reserved tickets for all registrations of an EE_Transaction
551
+	 * by default, will NOT release tickets for finalized transactions
552
+	 *
553
+	 * @param EE_Transaction $transaction
554
+	 * @return int
555
+	 * @throws EE_Error
556
+	 * @throws ReflectionException
557
+	 */
558
+	protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction): int
559
+	{
560
+		// self::debug hardcoded to false
561
+		if (self::debug) {
562
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
563
+			echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
564
+			echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
565
+		}
566
+		// check if 'finalize_registration' step has been completed...
567
+		$finalized = $transaction->reg_step_completed('finalize_registration');
568
+		if (self::debug) {
569
+			// DEBUG LOG
570
+			EEH_Debug_Tools::log(
571
+				__CLASS__,
572
+				__FUNCTION__,
573
+				__LINE__,
574
+				array('finalized' => $finalized),
575
+				false,
576
+				'EE_Transaction: ' . $transaction->ID()
577
+			);
578
+		}
579
+		// how many tickets were released
580
+		$count = 0;
581
+		if (self::debug) {
582
+			echo self::$nl . ' . . . TXN finalized: ' . $finalized;
583
+		}
584
+		$release_tickets_with_TXN_status = array(
585
+			EEM_Transaction::failed_status_code,
586
+			EEM_Transaction::abandoned_status_code,
587
+			EEM_Transaction::incomplete_status_code,
588
+		);
589
+		$events = array();
590
+		// if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
591
+		if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
592
+			// cancel any reserved tickets for registrations that were not approved
593
+			$registrations = $transaction->registrations();
594
+			if (self::debug) {
595
+				echo self::$nl . ' . . . # registrations: ' . count($registrations);
596
+				$reg = reset($registrations);
597
+				$ticket = $reg->ticket();
598
+				if ($ticket instanceof EE_Ticket) {
599
+					$ticket->add_extra_meta(
600
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
601
+						__LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
602
+					);
603
+				}
604
+			}
605
+			if (! empty($registrations)) {
606
+				foreach ($registrations as $registration) {
607
+					if (
608
+						$registration instanceof EE_Registration
609
+						&& $this->_release_reserved_ticket_for_registration($registration, $transaction)
610
+					) {
611
+						$count++;
612
+						$events[ $registration->event_ID() ] = $registration->event();
613
+					}
614
+				}
615
+			}
616
+		}
617
+		if ($events !== array()) {
618
+			foreach ($events as $event) {
619
+				/** @var EE_Event $event */
620
+				$event->perform_sold_out_status_check();
621
+			}
622
+		}
623
+		return $count;
624
+	}
625
+
626
+
627
+	/**
628
+	 * releases reserved tickets for an EE_Registration
629
+	 * by default, will NOT release tickets for APPROVED registrations
630
+	 *
631
+	 * @param EE_Registration $registration
632
+	 * @param EE_Transaction  $transaction
633
+	 * @return int
634
+	 * @throws EE_Error
635
+	 * @throws ReflectionException
636
+	 */
637
+	protected function _release_reserved_ticket_for_registration(
638
+		EE_Registration $registration,
639
+		EE_Transaction $transaction
640
+	): int {
641
+		$STS_ID = $transaction->status_ID();
642
+		// self::debug hardcoded to false
643
+		if (self::debug) {
644
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
645
+			echo self::$nl . ' . . registration->ID: ' . $registration->ID();
646
+			echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
647
+			echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
648
+		}
649
+		if (
650 650
 // release Tickets for Failed Transactions and Abandoned Transactions
651
-            $STS_ID === EEM_Transaction::failed_status_code
652
-            || $STS_ID === EEM_Transaction::abandoned_status_code
653
-            || (
654
-                // also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
655
-                $STS_ID === EEM_Transaction::incomplete_status_code
656
-                && $registration->status_ID() !== EEM_Registration::status_id_approved
657
-            )
658
-        ) {
659
-            if (self::debug) {
660
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
661
-                $reserved = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
662
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
663
-                var_dump($reserved);
664
-            }
665
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
666
-            return 1;
667
-        }
668
-        return 0;
669
-    }
670
-
671
-
672
-
673
-    /********************************** SESSION_CART_RESET  **********************************/
674
-
675
-
676
-    /**
677
-     * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
678
-     *
679
-     * @param EE_Session $session
680
-     * @return void
681
-     * @throws EE_Error
682
-     * @throws InvalidArgumentException
683
-     * @throws ReflectionException
684
-     * @throws InvalidDataTypeException
685
-     * @throws InvalidInterfaceException
686
-     */
687
-    public static function session_cart_reset(EE_Session $session)
688
-    {
689
-        // don't release tickets if checkout was already reset
690
-        if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
691
-            return;
692
-        }
693
-        // self::debug hardcoded to false
694
-        if (self::debug) {
695
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
696
-        }
697
-        // first check of the session has a valid Checkout object
698
-        $checkout = $session->checkout();
699
-        if ($checkout instanceof EE_Checkout) {
700
-            // and use that to clear ticket reservations because it will update the associated registration meta data
701
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
702
-            return;
703
-        }
704
-        $cart = $session->cart();
705
-        if ($cart instanceof EE_Cart) {
706
-            if (self::debug) {
707
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
708
-            }
709
-            EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
710
-        } else {
711
-            if (self::debug) {
712
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
713
-                var_export($cart, true);
714
-            }
715
-        }
716
-    }
717
-
718
-
719
-    /**
720
-     * releases reserved tickets in the EE_Cart
721
-     *
722
-     * @param EE_Cart $cart
723
-     * @param EE_Session $session
724
-     * @return void
725
-     * @throws EE_Error
726
-     * @throws InvalidArgumentException
727
-     * @throws ReflectionException
728
-     * @throws InvalidDataTypeException
729
-     * @throws InvalidInterfaceException
730
-     */
731
-    protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
732
-    {
733
-        // self::debug hardcoded to false
734
-        if (self::debug) {
735
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
736
-        }
737
-        $ticket_line_items = $cart->get_tickets();
738
-        if (empty($ticket_line_items)) {
739
-            return;
740
-        }
741
-        if (self::debug) {
742
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
743
-        }
744
-        foreach ($ticket_line_items as $ticket_line_item) {
745
-            if (self::debug) {
746
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
747
-            }
748
-            if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
749
-                if (self::debug) {
750
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
751
-                }
752
-                $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
753
-                if ($ticket instanceof EE_Ticket) {
754
-                    if (self::debug) {
755
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
756
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
757
-                    }
758
-                    $ticket->add_extra_meta(
759
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
760
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
761
-                    );
762
-                    $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
763
-                }
764
-            }
765
-        }
766
-        if (self::debug) {
767
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
768
-        }
769
-    }
770
-
771
-
772
-
773
-    /********************************** SESSION_CHECKOUT_RESET  **********************************/
774
-
775
-
776
-    /**
777
-     * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
778
-     *
779
-     * @param EE_Session $session
780
-     * @return void
781
-     * @throws EE_Error
782
-     * @throws ReflectionException
783
-     */
784
-    public static function session_checkout_reset(EE_Session $session)
785
-    {
786
-        // don't release tickets if cart was already reset
787
-        if (did_action('AHEE__EE_Session__reset_cart__before_reset')) {
788
-            return;
789
-        }
790
-        $checkout = $session->checkout();
791
-        if ($checkout instanceof EE_Checkout) {
792
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
793
-        }
794
-    }
795
-
796
-
797
-    /**
798
-     * releases reserved tickets for the EE_Checkout->transaction
799
-     *
800
-     * @param EE_Checkout $checkout
801
-     * @return void
802
-     * @throws EE_Error
803
-     * @throws ReflectionException
804
-     */
805
-    protected function _session_checkout_reset(EE_Checkout $checkout)
806
-    {
807
-        // self::debug hardcoded to false
808
-        if (self::debug) {
809
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
810
-        }
811
-        // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
812
-        if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
813
-            return;
814
-        }
815
-        $this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
816
-    }
817
-
818
-
819
-
820
-    /********************************** SESSION_EXPIRED_RESET  **********************************/
821
-
822
-
823
-    /**
824
-     * @param    EE_Session $session
825
-     * @return    void
826
-     */
827
-    public static function session_expired_reset(EE_Session $session)
828
-    {
829
-    }
830
-
831
-
832
-
833
-    /********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
834
-
835
-
836
-    /**
837
-     * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
838
-     * by default, will NOT release tickets for free transactions, or any that have received a payment
839
-     *
840
-     * @param EE_Transaction $transaction
841
-     * @return void
842
-     * @throws EE_Error
843
-     * @throws ReflectionException
844
-     */
845
-    public static function process_abandoned_transactions(EE_Transaction $transaction)
846
-    {
847
-        // is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
848
-        if ($transaction->is_free() || $transaction->paid() > 0) {
849
-            // self::debug hardcoded to false
850
-            if (self::debug) {
851
-                // DEBUG LOG
852
-                EEH_Debug_Tools::log(
853
-                    __CLASS__,
854
-                    __FUNCTION__,
855
-                    __LINE__,
856
-                    array($transaction),
857
-                    false,
858
-                    'EE_Transaction: ' . $transaction->ID()
859
-                );
860
-            }
861
-            return;
862
-        }
863
-        // have their been any successful payments made ?
864
-        $payments = $transaction->payments();
865
-        foreach ($payments as $payment) {
866
-            if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
867
-                if (self::debug) {
868
-                    // DEBUG LOG
869
-                    EEH_Debug_Tools::log(
870
-                        __CLASS__,
871
-                        __FUNCTION__,
872
-                        __LINE__,
873
-                        array($payment),
874
-                        false,
875
-                        'EE_Transaction: ' . $transaction->ID()
876
-                    );
877
-                }
878
-                return;
879
-            }
880
-        }
881
-        // since you haven't even attempted to pay for your ticket...
882
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
883
-    }
884
-
885
-
886
-
887
-    /********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
888
-
889
-
890
-    /**
891
-     * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
892
-     *
893
-     * @param EE_Transaction $transaction
894
-     * @return void
895
-     * @throws EE_Error
896
-     * @throws ReflectionException
897
-     */
898
-    public static function process_failed_transactions(EE_Transaction $transaction)
899
-    {
900
-        // since you haven't even attempted to pay for your ticket...
901
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
902
-    }
903
-
904
-
905
-
906
-    /********************************** RESET RESERVATION COUNTS  *********************************/
907
-
908
-
909
-    /**
910
-     * Resets the ticket and datetime reserved counts.
911
-     *
912
-     * For all the tickets with reservations, recalculates what their actual reserved counts should be based
913
-     * on the valid transactions.
914
-     *
915
-     * @return int number of tickets whose reservations were released.
916
-     * @throws EE_Error
917
-     * @throws DomainException
918
-     * @throws InvalidDataTypeException
919
-     * @throws InvalidInterfaceException
920
-     * @throws InvalidArgumentException
921
-     * @throws UnexpectedEntityException
922
-     * @throws ReflectionException
923
-     */
924
-    public static function reset_reservation_counts(): int
925
-    {
926
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
927
-        $valid_reserved_tickets = array();
928
-        /** @var EE_Transaction[] $transactions_in_progress */
929
-        $transactions_in_progress = EEM_Transaction::instance()->get_transactions_in_progress();
930
-        foreach ($transactions_in_progress as $transaction) {
931
-            // if this TXN has been fully completed, then skip it
932
-            if ($transaction->reg_step_completed('finalize_registration')) {
933
-                continue;
934
-            }
935
-            $total_line_item = $transaction->total_line_item();
936
-            // $transaction_in_progress->line
937
-            if (! $total_line_item instanceof EE_Line_Item) {
938
-                throw new DomainException(
939
-                    esc_html__(
940
-                        'Transaction does not have a valid Total Line Item associated with it.',
941
-                        'event_espresso'
942
-                    )
943
-                );
944
-            }
945
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
946
-                $total_line_item
947
-            );
948
-        }
949
-        $total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
950
-        foreach ($total_line_items as $total_line_item) {
951
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
952
-                $total_line_item
953
-            );
954
-        }
955
-        $tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
956
-        return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
957
-            $tickets_with_reservations,
958
-            $valid_reserved_tickets,
959
-            __FUNCTION__
960
-        );
961
-    }
962
-
963
-
964
-    /**
965
-     * @param EE_Line_Item $total_line_item
966
-     * @return EE_Line_Item[]
967
-     * @throws EE_Error
968
-     * @throws ReflectionException
969
-     */
970
-    private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item): array
971
-    {
972
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
973
-        $valid_reserved_tickets = array();
974
-        $ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
975
-        foreach ($ticket_line_items as $ticket_line_item) {
976
-            if ($ticket_line_item instanceof EE_Line_Item) {
977
-                $valid_reserved_tickets[ $ticket_line_item->ID() ] = $ticket_line_item;
978
-            }
979
-        }
980
-        return $valid_reserved_tickets;
981
-    }
982
-
983
-
984
-    /**
985
-     * Releases ticket and datetime reservations (ie, reduces the number of reserved spots on them).
986
-     *
987
-     * Given the list of tickets which have reserved spots on them, uses the complete list of line items for tickets
988
-     * whose transactions aren't complete and also aren't yet expired (ie, they're incomplete and younger than the
989
-     * session's expiry time) to update the ticket (and their datetimes') reserved counts.
990
-     *
991
-     * @param EE_Ticket[]    $tickets_with_reservations        all tickets with TKT_reserved > 0
992
-     * @param EE_Line_Item[] $valid_reserved_ticket_line_items all line items for tickets and incomplete transactions
993
-     *                                                         whose session has NOT expired. We will use these to
994
-     *                                                         determine the number of ticket reservations are now
995
-     *                                                         invalid. We don't use the list of invalid ticket line
996
-     *                                                         items because we don't know which of those have already
997
-     *                                                         been taken into account when reducing ticket reservation
998
-     *                                                         counts, and which haven't.
999
-     * @param string $source
1000
-     * @return int
1001
-     * @throws UnexpectedEntityException
1002
-     * @throws DomainException
1003
-     * @throws EE_Error
1004
-     * @throws ReflectionException
1005
-     */
1006
-    protected static function release_reservations_for_tickets(
1007
-        array $tickets_with_reservations,
1008
-        array $valid_reserved_ticket_line_items = [],
1009
-        string $source = ''
1010
-    ): int {
1011
-        $total_tickets_released = 0;
1012
-        $sold_out_events = array();
1013
-        foreach ($tickets_with_reservations as $ticket_with_reservations) {
1014
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
1015
-                continue;
1016
-            }
1017
-            // The $valid_reserved_ticket_line_items tells us what the reserved count on their tickets (and datetimes)
1018
-            // SHOULD be. Instead of just directly updating the list, we're going to use EE_Ticket::decreaseReserved()
1019
-            // to try to avoid race conditions, so instead of just finding the number to update TO, we're going to find
1020
-            // the number to RELEASE. It's the same end result, just different path.
1021
-            // Begin by assuming we're going to release all the reservations on this ticket.
1022
-            $expired_reservations_count = $ticket_with_reservations->reserved();
1023
-            // Now reduce that number using the list of current valid reservations.
1024
-            foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
1025
-                if (
1026
-                    $valid_reserved_ticket_line_item instanceof EE_Line_Item
1027
-                    && $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
1028
-                ) {
1029
-                    $expired_reservations_count -= $valid_reserved_ticket_line_item->quantity();
1030
-                }
1031
-            }
1032
-            // Only bother saving the tickets and datetimes if we're actually going to release some spots.
1033
-            if ($expired_reservations_count > 0) {
1034
-                $ticket_with_reservations->add_extra_meta(
1035
-                    EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1036
-                    __LINE__ . ') ' . $source . '()'
1037
-                );
1038
-                $ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:' . __LINE__);
1039
-                $total_tickets_released += $expired_reservations_count;
1040
-                $event = $ticket_with_reservations->get_related_event();
1041
-                // track sold out events
1042
-                if ($event instanceof EE_Event && $event->is_sold_out()) {
1043
-                    $sold_out_events[] = $event;
1044
-                }
1045
-            }
1046
-        }
1047
-        // Double check whether sold out events should remain sold out after releasing tickets
1048
-        if ($sold_out_events !== array()) {
1049
-            foreach ($sold_out_events as $sold_out_event) {
1050
-                /** @var EE_Event $sold_out_event */
1051
-                $sold_out_event->perform_sold_out_status_check();
1052
-            }
1053
-        }
1054
-        return $total_tickets_released;
1055
-    }
1056
-
1057
-
1058
-
1059
-    /********************************** SHUTDOWN  **********************************/
1060
-
1061
-
1062
-    /**
1063
-     * @param int $timestamp
1064
-     * @return false|int
1065
-     * @throws EE_Error
1066
-     * @throws InvalidArgumentException
1067
-     * @throws InvalidDataTypeException
1068
-     * @throws InvalidInterfaceException
1069
-     * @throws ReflectionException
1070
-     */
1071
-    public static function clear_expired_line_items_with_no_transaction(int $timestamp = 0)
1072
-    {
1073
-        /** @type WPDB $wpdb */
1074
-        global $wpdb;
1075
-        if (! absint($timestamp)) {
1076
-            /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1077
-            $session_lifespan = LoaderFactory::getLoader()->getShared(
1078
-                'EventEspresso\core\domain\values\session\SessionLifespan'
1079
-            );
1080
-            $timestamp = $session_lifespan->expiration();
1081
-        }
1082
-        return $wpdb->query(
1083
-            $wpdb->prepare(
1084
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
651
+			$STS_ID === EEM_Transaction::failed_status_code
652
+			|| $STS_ID === EEM_Transaction::abandoned_status_code
653
+			|| (
654
+				// also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
655
+				$STS_ID === EEM_Transaction::incomplete_status_code
656
+				&& $registration->status_ID() !== EEM_Registration::status_id_approved
657
+			)
658
+		) {
659
+			if (self::debug) {
660
+				echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
661
+				$reserved = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
662
+				echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
663
+				var_dump($reserved);
664
+			}
665
+			$registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
666
+			return 1;
667
+		}
668
+		return 0;
669
+	}
670
+
671
+
672
+
673
+	/********************************** SESSION_CART_RESET  **********************************/
674
+
675
+
676
+	/**
677
+	 * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
678
+	 *
679
+	 * @param EE_Session $session
680
+	 * @return void
681
+	 * @throws EE_Error
682
+	 * @throws InvalidArgumentException
683
+	 * @throws ReflectionException
684
+	 * @throws InvalidDataTypeException
685
+	 * @throws InvalidInterfaceException
686
+	 */
687
+	public static function session_cart_reset(EE_Session $session)
688
+	{
689
+		// don't release tickets if checkout was already reset
690
+		if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
691
+			return;
692
+		}
693
+		// self::debug hardcoded to false
694
+		if (self::debug) {
695
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
696
+		}
697
+		// first check of the session has a valid Checkout object
698
+		$checkout = $session->checkout();
699
+		if ($checkout instanceof EE_Checkout) {
700
+			// and use that to clear ticket reservations because it will update the associated registration meta data
701
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
702
+			return;
703
+		}
704
+		$cart = $session->cart();
705
+		if ($cart instanceof EE_Cart) {
706
+			if (self::debug) {
707
+				echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
708
+			}
709
+			EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
710
+		} else {
711
+			if (self::debug) {
712
+				echo self::$nl . self::$nl . ' invalid EE_Cart: ';
713
+				var_export($cart, true);
714
+			}
715
+		}
716
+	}
717
+
718
+
719
+	/**
720
+	 * releases reserved tickets in the EE_Cart
721
+	 *
722
+	 * @param EE_Cart $cart
723
+	 * @param EE_Session $session
724
+	 * @return void
725
+	 * @throws EE_Error
726
+	 * @throws InvalidArgumentException
727
+	 * @throws ReflectionException
728
+	 * @throws InvalidDataTypeException
729
+	 * @throws InvalidInterfaceException
730
+	 */
731
+	protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
732
+	{
733
+		// self::debug hardcoded to false
734
+		if (self::debug) {
735
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
736
+		}
737
+		$ticket_line_items = $cart->get_tickets();
738
+		if (empty($ticket_line_items)) {
739
+			return;
740
+		}
741
+		if (self::debug) {
742
+			echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
743
+		}
744
+		foreach ($ticket_line_items as $ticket_line_item) {
745
+			if (self::debug) {
746
+				echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
747
+			}
748
+			if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
749
+				if (self::debug) {
750
+					echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
751
+				}
752
+				$ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
753
+				if ($ticket instanceof EE_Ticket) {
754
+					if (self::debug) {
755
+						echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
756
+						echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
757
+					}
758
+					$ticket->add_extra_meta(
759
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
760
+						__LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
761
+					);
762
+					$this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
763
+				}
764
+			}
765
+		}
766
+		if (self::debug) {
767
+			echo self::$nl . self::$nl . ' RESET COMPLETED ';
768
+		}
769
+	}
770
+
771
+
772
+
773
+	/********************************** SESSION_CHECKOUT_RESET  **********************************/
774
+
775
+
776
+	/**
777
+	 * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
778
+	 *
779
+	 * @param EE_Session $session
780
+	 * @return void
781
+	 * @throws EE_Error
782
+	 * @throws ReflectionException
783
+	 */
784
+	public static function session_checkout_reset(EE_Session $session)
785
+	{
786
+		// don't release tickets if cart was already reset
787
+		if (did_action('AHEE__EE_Session__reset_cart__before_reset')) {
788
+			return;
789
+		}
790
+		$checkout = $session->checkout();
791
+		if ($checkout instanceof EE_Checkout) {
792
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
793
+		}
794
+	}
795
+
796
+
797
+	/**
798
+	 * releases reserved tickets for the EE_Checkout->transaction
799
+	 *
800
+	 * @param EE_Checkout $checkout
801
+	 * @return void
802
+	 * @throws EE_Error
803
+	 * @throws ReflectionException
804
+	 */
805
+	protected function _session_checkout_reset(EE_Checkout $checkout)
806
+	{
807
+		// self::debug hardcoded to false
808
+		if (self::debug) {
809
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
810
+		}
811
+		// we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
812
+		if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
813
+			return;
814
+		}
815
+		$this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
816
+	}
817
+
818
+
819
+
820
+	/********************************** SESSION_EXPIRED_RESET  **********************************/
821
+
822
+
823
+	/**
824
+	 * @param    EE_Session $session
825
+	 * @return    void
826
+	 */
827
+	public static function session_expired_reset(EE_Session $session)
828
+	{
829
+	}
830
+
831
+
832
+
833
+	/********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
834
+
835
+
836
+	/**
837
+	 * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
838
+	 * by default, will NOT release tickets for free transactions, or any that have received a payment
839
+	 *
840
+	 * @param EE_Transaction $transaction
841
+	 * @return void
842
+	 * @throws EE_Error
843
+	 * @throws ReflectionException
844
+	 */
845
+	public static function process_abandoned_transactions(EE_Transaction $transaction)
846
+	{
847
+		// is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
848
+		if ($transaction->is_free() || $transaction->paid() > 0) {
849
+			// self::debug hardcoded to false
850
+			if (self::debug) {
851
+				// DEBUG LOG
852
+				EEH_Debug_Tools::log(
853
+					__CLASS__,
854
+					__FUNCTION__,
855
+					__LINE__,
856
+					array($transaction),
857
+					false,
858
+					'EE_Transaction: ' . $transaction->ID()
859
+				);
860
+			}
861
+			return;
862
+		}
863
+		// have their been any successful payments made ?
864
+		$payments = $transaction->payments();
865
+		foreach ($payments as $payment) {
866
+			if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
867
+				if (self::debug) {
868
+					// DEBUG LOG
869
+					EEH_Debug_Tools::log(
870
+						__CLASS__,
871
+						__FUNCTION__,
872
+						__LINE__,
873
+						array($payment),
874
+						false,
875
+						'EE_Transaction: ' . $transaction->ID()
876
+					);
877
+				}
878
+				return;
879
+			}
880
+		}
881
+		// since you haven't even attempted to pay for your ticket...
882
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
883
+	}
884
+
885
+
886
+
887
+	/********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
888
+
889
+
890
+	/**
891
+	 * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
892
+	 *
893
+	 * @param EE_Transaction $transaction
894
+	 * @return void
895
+	 * @throws EE_Error
896
+	 * @throws ReflectionException
897
+	 */
898
+	public static function process_failed_transactions(EE_Transaction $transaction)
899
+	{
900
+		// since you haven't even attempted to pay for your ticket...
901
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
902
+	}
903
+
904
+
905
+
906
+	/********************************** RESET RESERVATION COUNTS  *********************************/
907
+
908
+
909
+	/**
910
+	 * Resets the ticket and datetime reserved counts.
911
+	 *
912
+	 * For all the tickets with reservations, recalculates what their actual reserved counts should be based
913
+	 * on the valid transactions.
914
+	 *
915
+	 * @return int number of tickets whose reservations were released.
916
+	 * @throws EE_Error
917
+	 * @throws DomainException
918
+	 * @throws InvalidDataTypeException
919
+	 * @throws InvalidInterfaceException
920
+	 * @throws InvalidArgumentException
921
+	 * @throws UnexpectedEntityException
922
+	 * @throws ReflectionException
923
+	 */
924
+	public static function reset_reservation_counts(): int
925
+	{
926
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
927
+		$valid_reserved_tickets = array();
928
+		/** @var EE_Transaction[] $transactions_in_progress */
929
+		$transactions_in_progress = EEM_Transaction::instance()->get_transactions_in_progress();
930
+		foreach ($transactions_in_progress as $transaction) {
931
+			// if this TXN has been fully completed, then skip it
932
+			if ($transaction->reg_step_completed('finalize_registration')) {
933
+				continue;
934
+			}
935
+			$total_line_item = $transaction->total_line_item();
936
+			// $transaction_in_progress->line
937
+			if (! $total_line_item instanceof EE_Line_Item) {
938
+				throw new DomainException(
939
+					esc_html__(
940
+						'Transaction does not have a valid Total Line Item associated with it.',
941
+						'event_espresso'
942
+					)
943
+				);
944
+			}
945
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
946
+				$total_line_item
947
+			);
948
+		}
949
+		$total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
950
+		foreach ($total_line_items as $total_line_item) {
951
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
952
+				$total_line_item
953
+			);
954
+		}
955
+		$tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
956
+		return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
957
+			$tickets_with_reservations,
958
+			$valid_reserved_tickets,
959
+			__FUNCTION__
960
+		);
961
+	}
962
+
963
+
964
+	/**
965
+	 * @param EE_Line_Item $total_line_item
966
+	 * @return EE_Line_Item[]
967
+	 * @throws EE_Error
968
+	 * @throws ReflectionException
969
+	 */
970
+	private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item): array
971
+	{
972
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
973
+		$valid_reserved_tickets = array();
974
+		$ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
975
+		foreach ($ticket_line_items as $ticket_line_item) {
976
+			if ($ticket_line_item instanceof EE_Line_Item) {
977
+				$valid_reserved_tickets[ $ticket_line_item->ID() ] = $ticket_line_item;
978
+			}
979
+		}
980
+		return $valid_reserved_tickets;
981
+	}
982
+
983
+
984
+	/**
985
+	 * Releases ticket and datetime reservations (ie, reduces the number of reserved spots on them).
986
+	 *
987
+	 * Given the list of tickets which have reserved spots on them, uses the complete list of line items for tickets
988
+	 * whose transactions aren't complete and also aren't yet expired (ie, they're incomplete and younger than the
989
+	 * session's expiry time) to update the ticket (and their datetimes') reserved counts.
990
+	 *
991
+	 * @param EE_Ticket[]    $tickets_with_reservations        all tickets with TKT_reserved > 0
992
+	 * @param EE_Line_Item[] $valid_reserved_ticket_line_items all line items for tickets and incomplete transactions
993
+	 *                                                         whose session has NOT expired. We will use these to
994
+	 *                                                         determine the number of ticket reservations are now
995
+	 *                                                         invalid. We don't use the list of invalid ticket line
996
+	 *                                                         items because we don't know which of those have already
997
+	 *                                                         been taken into account when reducing ticket reservation
998
+	 *                                                         counts, and which haven't.
999
+	 * @param string $source
1000
+	 * @return int
1001
+	 * @throws UnexpectedEntityException
1002
+	 * @throws DomainException
1003
+	 * @throws EE_Error
1004
+	 * @throws ReflectionException
1005
+	 */
1006
+	protected static function release_reservations_for_tickets(
1007
+		array $tickets_with_reservations,
1008
+		array $valid_reserved_ticket_line_items = [],
1009
+		string $source = ''
1010
+	): int {
1011
+		$total_tickets_released = 0;
1012
+		$sold_out_events = array();
1013
+		foreach ($tickets_with_reservations as $ticket_with_reservations) {
1014
+			if (! $ticket_with_reservations instanceof EE_Ticket) {
1015
+				continue;
1016
+			}
1017
+			// The $valid_reserved_ticket_line_items tells us what the reserved count on their tickets (and datetimes)
1018
+			// SHOULD be. Instead of just directly updating the list, we're going to use EE_Ticket::decreaseReserved()
1019
+			// to try to avoid race conditions, so instead of just finding the number to update TO, we're going to find
1020
+			// the number to RELEASE. It's the same end result, just different path.
1021
+			// Begin by assuming we're going to release all the reservations on this ticket.
1022
+			$expired_reservations_count = $ticket_with_reservations->reserved();
1023
+			// Now reduce that number using the list of current valid reservations.
1024
+			foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
1025
+				if (
1026
+					$valid_reserved_ticket_line_item instanceof EE_Line_Item
1027
+					&& $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
1028
+				) {
1029
+					$expired_reservations_count -= $valid_reserved_ticket_line_item->quantity();
1030
+				}
1031
+			}
1032
+			// Only bother saving the tickets and datetimes if we're actually going to release some spots.
1033
+			if ($expired_reservations_count > 0) {
1034
+				$ticket_with_reservations->add_extra_meta(
1035
+					EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1036
+					__LINE__ . ') ' . $source . '()'
1037
+				);
1038
+				$ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:' . __LINE__);
1039
+				$total_tickets_released += $expired_reservations_count;
1040
+				$event = $ticket_with_reservations->get_related_event();
1041
+				// track sold out events
1042
+				if ($event instanceof EE_Event && $event->is_sold_out()) {
1043
+					$sold_out_events[] = $event;
1044
+				}
1045
+			}
1046
+		}
1047
+		// Double check whether sold out events should remain sold out after releasing tickets
1048
+		if ($sold_out_events !== array()) {
1049
+			foreach ($sold_out_events as $sold_out_event) {
1050
+				/** @var EE_Event $sold_out_event */
1051
+				$sold_out_event->perform_sold_out_status_check();
1052
+			}
1053
+		}
1054
+		return $total_tickets_released;
1055
+	}
1056
+
1057
+
1058
+
1059
+	/********************************** SHUTDOWN  **********************************/
1060
+
1061
+
1062
+	/**
1063
+	 * @param int $timestamp
1064
+	 * @return false|int
1065
+	 * @throws EE_Error
1066
+	 * @throws InvalidArgumentException
1067
+	 * @throws InvalidDataTypeException
1068
+	 * @throws InvalidInterfaceException
1069
+	 * @throws ReflectionException
1070
+	 */
1071
+	public static function clear_expired_line_items_with_no_transaction(int $timestamp = 0)
1072
+	{
1073
+		/** @type WPDB $wpdb */
1074
+		global $wpdb;
1075
+		if (! absint($timestamp)) {
1076
+			/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1077
+			$session_lifespan = LoaderFactory::getLoader()->getShared(
1078
+				'EventEspresso\core\domain\values\session\SessionLifespan'
1079
+			);
1080
+			$timestamp = $session_lifespan->expiration();
1081
+		}
1082
+		return $wpdb->query(
1083
+			$wpdb->prepare(
1084
+				'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1085 1085
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1086
-                // use GMT time because that's what LIN_timestamps are in
1087
-                date('Y-m-d H:i:s', $timestamp)
1088
-            )
1089
-        );
1090
-    }
1086
+				// use GMT time because that's what LIN_timestamps are in
1087
+				date('Y-m-d H:i:s', $timestamp)
1088
+			)
1089
+		);
1090
+	}
1091 1091
 }
Please login to merge, or discard this patch.
Spacing   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class EED_Ticket_Sales_Monitor extends EED_Module
20 20
 {
21
-    const debug = false;    // true false
21
+    const debug = false; // true false
22 22
 
23 23
     private static $nl = '';
24 24
 
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
     {
169 169
         // self::debug hardcoded to false
170 170
         if (self::debug) {
171
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
171
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
172 172
         }
173 173
         do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
174 174
         $expired_ticket_IDs = array();
@@ -179,29 +179,29 @@  discard block
 block discarded – undo
179 179
         $timestamp = $session_lifespan->expiration();
180 180
         $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
181 181
         if (self::debug) {
182
-            echo self::$nl . ' . time(): ' . time();
183
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
184
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
185
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
186
-            echo self::$nl . ' . timestamp: ' . $timestamp;
187
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
182
+            echo self::$nl.' . time(): '.time();
183
+            echo self::$nl.' . time() as date: '.date('Y-m-d H:i a');
184
+            echo self::$nl.' . session expiration: '.$session_lifespan->expiration();
185
+            echo self::$nl.' . session expiration as date: '.date('Y-m-d H:i a', $session_lifespan->expiration());
186
+            echo self::$nl.' . timestamp: '.$timestamp;
187
+            echo self::$nl.' . $expired_ticket_line_items: '.count($expired_ticket_line_items);
188 188
         }
189
-        if (! empty($expired_ticket_line_items)) {
189
+        if ( ! empty($expired_ticket_line_items)) {
190 190
             foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
191
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
191
+                if ( ! $expired_ticket_line_item instanceof EE_Line_Item) {
192 192
                     continue;
193 193
                 }
194
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
194
+                $expired_ticket_IDs[$expired_ticket_line_item->OBJ_ID()] = $expired_ticket_line_item->OBJ_ID();
195 195
                 if (self::debug) {
196
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
197
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): '
196
+                    echo self::$nl.' . $expired_ticket_line_item->OBJ_ID(): '.$expired_ticket_line_item->OBJ_ID();
197
+                    echo self::$nl.' . $expired_ticket_line_item->timestamp(): '
198 198
                          . date(
199 199
                              'Y-m-d h:i a',
200 200
                              $expired_ticket_line_item->timestamp(true)
201 201
                          );
202 202
                 }
203 203
             }
204
-            if (! empty($expired_ticket_IDs)) {
204
+            if ( ! empty($expired_ticket_IDs)) {
205 205
                 EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
206 206
                     EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
207 207
                     array(),
@@ -241,8 +241,8 @@  discard block
 block discarded – undo
241 241
         }
242 242
         // self::debug hardcoded to false
243 243
         if (self::debug) {
244
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
245
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
244
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
245
+            echo self::$nl.self::$nl.'<b> RETURNED QTY: '.$qty.'</b>';
246 246
         }
247 247
         return $qty;
248 248
     }
@@ -262,36 +262,36 @@  discard block
 block discarded – undo
262 262
     {
263 263
         // self::debug hardcoded to false
264 264
         if (self::debug) {
265
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
265
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
266 266
         }
267
-        if (! $ticket instanceof EE_Ticket) {
267
+        if ( ! $ticket instanceof EE_Ticket) {
268 268
             return 0;
269 269
         }
270 270
         if (self::debug) {
271
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
272
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
271
+            echo self::$nl.'<b> . ticket->ID: '.$ticket->ID().'</b>';
272
+            echo self::$nl.' . original ticket->reserved: '.$ticket->reserved();
273 273
         }
274 274
         $ticket->refresh_from_db();
275 275
         // first let's determine the ticket availability based on sales
276 276
         $available = $ticket->qty('saleable');
277 277
         if (self::debug) {
278
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
279
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
280
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
281
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
282
-            echo self::$nl . ' . . . available: ' . $available;
278
+            echo self::$nl.' . . . ticket->qty: '.$ticket->qty();
279
+            echo self::$nl.' . . . ticket->sold: '.$ticket->sold();
280
+            echo self::$nl.' . . . ticket->reserved: '.$ticket->reserved();
281
+            echo self::$nl.' . . . ticket->qty(saleable): '.$ticket->qty('saleable');
282
+            echo self::$nl.' . . . available: '.$available;
283 283
         }
284 284
         if ($available < 1) {
285 285
             $this->_ticket_sold_out($ticket);
286 286
             return 0;
287 287
         }
288 288
         if (self::debug) {
289
-            echo self::$nl . ' . . . qty: ' . $qty;
289
+            echo self::$nl.' . . . qty: '.$qty;
290 290
         }
291 291
         if ($available < $qty) {
292 292
             $qty = $available;
293 293
             if (self::debug) {
294
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
294
+                echo self::$nl.' . . . QTY ADJUSTED: '.$qty;
295 295
             }
296 296
             $this->_ticket_quantity_decremented($ticket);
297 297
         }
@@ -315,9 +315,9 @@  discard block
 block discarded – undo
315 315
     {
316 316
         // self::debug hardcoded to false
317 317
         if (self::debug) {
318
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
318
+            echo self::$nl.self::$nl.' . . . INCREASE RESERVED: '.$quantity;
319 319
         }
320
-        return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:' . __LINE__);
320
+        return $ticket->increaseReserved($quantity, 'TicketSalesMonitor:'.__LINE__);
321 321
     }
322 322
 
323 323
 
@@ -332,12 +332,12 @@  discard block
 block discarded – undo
332 332
     {
333 333
         // self::debug hardcoded to false
334 334
         if (self::debug) {
335
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
336
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
335
+            echo self::$nl.' . . . ticket->ID: '.$ticket->ID();
336
+            echo self::$nl.' . . . ticket->reserved before: '.$ticket->reserved();
337 337
         }
338
-        $ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:' . __LINE__);
338
+        $ticket->decreaseReserved($quantity, true, 'TicketSalesMonitor:'.__LINE__);
339 339
         if (self::debug) {
340
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
340
+            echo self::$nl.' . . . ticket->reserved after: '.$ticket->reserved();
341 341
         }
342 342
         return (bool) $ticket->save();
343 343
     }
@@ -356,8 +356,8 @@  discard block
 block discarded – undo
356 356
     {
357 357
         // self::debug hardcoded to false
358 358
         if (self::debug) {
359
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
360
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
359
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
360
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
361 361
         }
362 362
         $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
363 363
     }
@@ -376,8 +376,8 @@  discard block
 block discarded – undo
376 376
     {
377 377
         // self::debug hardcoded to false
378 378
         if (self::debug) {
379
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
380
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
379
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
380
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
381 381
         }
382 382
         $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
383 383
     }
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
         if ($ticket instanceof EE_Ticket) {
431 431
             $ticket->add_extra_meta(
432 432
                 EE_Ticket::META_KEY_TICKET_RESERVATIONS,
433
-                __LINE__ . ') ' . __METHOD__ . '()'
433
+                __LINE__.') '.__METHOD__.'()'
434 434
             );
435 435
             if ($quantity > 0) {
436 436
                 EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
@@ -454,7 +454,7 @@  discard block
 block discarded – undo
454 454
     {
455 455
         $ticket->add_extra_meta(
456 456
             EE_Ticket::META_KEY_TICKET_RESERVATIONS,
457
-            __LINE__ . ') ' . __METHOD__ . '()'
457
+            __LINE__.') '.__METHOD__.'()'
458 458
         );
459 459
         EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
460 460
     }
@@ -487,7 +487,7 @@  discard block
 block discarded – undo
487 487
     {
488 488
         // self::debug hardcoded to false
489 489
         if (self::debug) {
490
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
490
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
491 491
         }
492 492
         $refresh_msg = '';
493 493
         $none_added_msg = '';
@@ -498,7 +498,7 @@  discard block
 block discarded – undo
498 498
             );
499 499
             $none_added_msg = esc_html__('No tickets were added for the event.', 'event_espresso');
500 500
         }
501
-        if (! empty($this->sold_out_tickets)) {
501
+        if ( ! empty($this->sold_out_tickets)) {
502 502
             EE_Error::add_attention(
503 503
                 sprintf(
504 504
                     apply_filters(
@@ -521,7 +521,7 @@  discard block
 block discarded – undo
521 521
             // and reset the cart
522 522
             EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
523 523
         }
524
-        if (! empty($this->decremented_tickets)) {
524
+        if ( ! empty($this->decremented_tickets)) {
525 525
             EE_Error::add_attention(
526 526
                 sprintf(
527 527
                     apply_filters(
@@ -559,9 +559,9 @@  discard block
 block discarded – undo
559 559
     {
560 560
         // self::debug hardcoded to false
561 561
         if (self::debug) {
562
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
563
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
564
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
562
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
563
+            echo self::$nl.' . transaction->ID: '.$transaction->ID();
564
+            echo self::$nl.' . TXN status_ID: '.$transaction->status_ID();
565 565
         }
566 566
         // check if 'finalize_registration' step has been completed...
567 567
         $finalized = $transaction->reg_step_completed('finalize_registration');
@@ -573,13 +573,13 @@  discard block
 block discarded – undo
573 573
                 __LINE__,
574 574
                 array('finalized' => $finalized),
575 575
                 false,
576
-                'EE_Transaction: ' . $transaction->ID()
576
+                'EE_Transaction: '.$transaction->ID()
577 577
             );
578 578
         }
579 579
         // how many tickets were released
580 580
         $count = 0;
581 581
         if (self::debug) {
582
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
582
+            echo self::$nl.' . . . TXN finalized: '.$finalized;
583 583
         }
584 584
         $release_tickets_with_TXN_status = array(
585 585
             EEM_Transaction::failed_status_code,
@@ -588,28 +588,28 @@  discard block
 block discarded – undo
588 588
         );
589 589
         $events = array();
590 590
         // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
591
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
591
+        if ( ! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
592 592
             // cancel any reserved tickets for registrations that were not approved
593 593
             $registrations = $transaction->registrations();
594 594
             if (self::debug) {
595
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
595
+                echo self::$nl.' . . . # registrations: '.count($registrations);
596 596
                 $reg = reset($registrations);
597 597
                 $ticket = $reg->ticket();
598 598
                 if ($ticket instanceof EE_Ticket) {
599 599
                     $ticket->add_extra_meta(
600 600
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
601
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
601
+                        __LINE__.') Release All Tickets TXN:'.$transaction->ID()
602 602
                     );
603 603
                 }
604 604
             }
605
-            if (! empty($registrations)) {
605
+            if ( ! empty($registrations)) {
606 606
                 foreach ($registrations as $registration) {
607 607
                     if (
608 608
                         $registration instanceof EE_Registration
609 609
                         && $this->_release_reserved_ticket_for_registration($registration, $transaction)
610 610
                     ) {
611 611
                         $count++;
612
-                        $events[ $registration->event_ID() ] = $registration->event();
612
+                        $events[$registration->event_ID()] = $registration->event();
613 613
                     }
614 614
                 }
615 615
             }
@@ -641,10 +641,10 @@  discard block
 block discarded – undo
641 641
         $STS_ID = $transaction->status_ID();
642 642
         // self::debug hardcoded to false
643 643
         if (self::debug) {
644
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
645
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
646
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
647
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
644
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
645
+            echo self::$nl.' . . registration->ID: '.$registration->ID();
646
+            echo self::$nl.' . . registration->status_ID: '.$registration->status_ID();
647
+            echo self::$nl.' . . transaction->status_ID(): '.$STS_ID;
648 648
         }
649 649
         if (
650 650
 // release Tickets for Failed Transactions and Abandoned Transactions
@@ -657,12 +657,12 @@  discard block
 block discarded – undo
657 657
             )
658 658
         ) {
659 659
             if (self::debug) {
660
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
660
+                echo self::$nl.self::$nl.' . . RELEASE RESERVED TICKET';
661 661
                 $reserved = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
662
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
662
+                echo self::$nl.' . . . registration HAS_RESERVED_TICKET_KEY: ';
663 663
                 var_dump($reserved);
664 664
             }
665
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:' . __LINE__);
665
+            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:'.__LINE__);
666 666
             return 1;
667 667
         }
668 668
         return 0;
@@ -692,7 +692,7 @@  discard block
 block discarded – undo
692 692
         }
693 693
         // self::debug hardcoded to false
694 694
         if (self::debug) {
695
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
695
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
696 696
         }
697 697
         // first check of the session has a valid Checkout object
698 698
         $checkout = $session->checkout();
@@ -704,12 +704,12 @@  discard block
 block discarded – undo
704 704
         $cart = $session->cart();
705 705
         if ($cart instanceof EE_Cart) {
706 706
             if (self::debug) {
707
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
707
+                echo self::$nl.self::$nl.' cart instance of EE_Cart: ';
708 708
             }
709 709
             EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
710 710
         } else {
711 711
             if (self::debug) {
712
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
712
+                echo self::$nl.self::$nl.' invalid EE_Cart: ';
713 713
                 var_export($cart, true);
714 714
             }
715 715
         }
@@ -732,39 +732,39 @@  discard block
 block discarded – undo
732 732
     {
733 733
         // self::debug hardcoded to false
734 734
         if (self::debug) {
735
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
735
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
736 736
         }
737 737
         $ticket_line_items = $cart->get_tickets();
738 738
         if (empty($ticket_line_items)) {
739 739
             return;
740 740
         }
741 741
         if (self::debug) {
742
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
742
+            echo '<br /> . ticket_line_item count: '.count($ticket_line_items);
743 743
         }
744 744
         foreach ($ticket_line_items as $ticket_line_item) {
745 745
             if (self::debug) {
746
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
746
+                echo self::$nl.' . ticket_line_item->ID(): '.$ticket_line_item->ID();
747 747
             }
748 748
             if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
749 749
                 if (self::debug) {
750
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
750
+                    echo self::$nl.' . . ticket_line_item->OBJ_ID(): '.$ticket_line_item->OBJ_ID();
751 751
                 }
752 752
                 $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
753 753
                 if ($ticket instanceof EE_Ticket) {
754 754
                     if (self::debug) {
755
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
756
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
755
+                        echo self::$nl.' . . ticket->ID(): '.$ticket->ID();
756
+                        echo self::$nl.' . . ticket_line_item->quantity(): '.$ticket_line_item->quantity();
757 757
                     }
758 758
                     $ticket->add_extra_meta(
759 759
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
760
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
760
+                        __LINE__.') '.__METHOD__.'() SID = '.$session->id()
761 761
                     );
762 762
                     $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
763 763
                 }
764 764
             }
765 765
         }
766 766
         if (self::debug) {
767
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
767
+            echo self::$nl.self::$nl.' RESET COMPLETED ';
768 768
         }
769 769
     }
770 770
 
@@ -806,7 +806,7 @@  discard block
 block discarded – undo
806 806
     {
807 807
         // self::debug hardcoded to false
808 808
         if (self::debug) {
809
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
809
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
810 810
         }
811 811
         // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
812 812
         if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
@@ -855,7 +855,7 @@  discard block
 block discarded – undo
855 855
                     __LINE__,
856 856
                     array($transaction),
857 857
                     false,
858
-                    'EE_Transaction: ' . $transaction->ID()
858
+                    'EE_Transaction: '.$transaction->ID()
859 859
                 );
860 860
             }
861 861
             return;
@@ -872,7 +872,7 @@  discard block
 block discarded – undo
872 872
                         __LINE__,
873 873
                         array($payment),
874 874
                         false,
875
-                        'EE_Transaction: ' . $transaction->ID()
875
+                        'EE_Transaction: '.$transaction->ID()
876 876
                     );
877 877
                 }
878 878
                 return;
@@ -934,7 +934,7 @@  discard block
 block discarded – undo
934 934
             }
935 935
             $total_line_item = $transaction->total_line_item();
936 936
             // $transaction_in_progress->line
937
-            if (! $total_line_item instanceof EE_Line_Item) {
937
+            if ( ! $total_line_item instanceof EE_Line_Item) {
938 938
                 throw new DomainException(
939 939
                     esc_html__(
940 940
                         'Transaction does not have a valid Total Line Item associated with it.',
@@ -974,7 +974,7 @@  discard block
 block discarded – undo
974 974
         $ticket_line_items = EEH_Line_Item::get_ticket_line_items($total_line_item);
975 975
         foreach ($ticket_line_items as $ticket_line_item) {
976 976
             if ($ticket_line_item instanceof EE_Line_Item) {
977
-                $valid_reserved_tickets[ $ticket_line_item->ID() ] = $ticket_line_item;
977
+                $valid_reserved_tickets[$ticket_line_item->ID()] = $ticket_line_item;
978 978
             }
979 979
         }
980 980
         return $valid_reserved_tickets;
@@ -1011,7 +1011,7 @@  discard block
 block discarded – undo
1011 1011
         $total_tickets_released = 0;
1012 1012
         $sold_out_events = array();
1013 1013
         foreach ($tickets_with_reservations as $ticket_with_reservations) {
1014
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
1014
+            if ( ! $ticket_with_reservations instanceof EE_Ticket) {
1015 1015
                 continue;
1016 1016
             }
1017 1017
             // The $valid_reserved_ticket_line_items tells us what the reserved count on their tickets (and datetimes)
@@ -1033,9 +1033,9 @@  discard block
 block discarded – undo
1033 1033
             if ($expired_reservations_count > 0) {
1034 1034
                 $ticket_with_reservations->add_extra_meta(
1035 1035
                     EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1036
-                    __LINE__ . ') ' . $source . '()'
1036
+                    __LINE__.') '.$source.'()'
1037 1037
                 );
1038
-                $ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:' . __LINE__);
1038
+                $ticket_with_reservations->decreaseReserved($expired_reservations_count, true, 'TicketSalesMonitor:'.__LINE__);
1039 1039
                 $total_tickets_released += $expired_reservations_count;
1040 1040
                 $event = $ticket_with_reservations->get_related_event();
1041 1041
                 // track sold out events
@@ -1072,7 +1072,7 @@  discard block
 block discarded – undo
1072 1072
     {
1073 1073
         /** @type WPDB $wpdb */
1074 1074
         global $wpdb;
1075
-        if (! absint($timestamp)) {
1075
+        if ( ! absint($timestamp)) {
1076 1076
             /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1077 1077
             $session_lifespan = LoaderFactory::getLoader()->getShared(
1078 1078
                 'EventEspresso\core\domain\values\session\SessionLifespan'
@@ -1081,7 +1081,7 @@  discard block
 block discarded – undo
1081 1081
         }
1082 1082
         return $wpdb->query(
1083 1083
             $wpdb->prepare(
1084
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1084
+                'DELETE FROM '.EEM_Line_Item::instance()->table().'
1085 1085
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1086 1086
                 // use GMT time because that's what LIN_timestamps are in
1087 1087
                 date('Y-m-d H:i:s', $timestamp)
Please login to merge, or discard this patch.
modules/ticket_selector/ProcessTicketSelector.php 2 patches
Indentation   +369 added lines, -369 removed lines patch added patch discarded remove patch
@@ -33,394 +33,394 @@
 block discarded – undo
33 33
  */
34 34
 class ProcessTicketSelector
35 35
 {
36
-    /**
37
-     * @var EE_Cart $cart
38
-     */
39
-    private $cart;
36
+	/**
37
+	 * @var EE_Cart $cart
38
+	 */
39
+	private $cart;
40 40
 
41
-    /**
42
-     * @var EE_Core_Config $core_config
43
-     */
44
-    private $core_config;
41
+	/**
42
+	 * @var EE_Core_Config $core_config
43
+	 */
44
+	private $core_config;
45 45
 
46
-    /**
47
-     * @var RequestInterface $request
48
-     */
49
-    private $request;
46
+	/**
47
+	 * @var RequestInterface $request
48
+	 */
49
+	private $request;
50 50
 
51
-    /**
52
-     * @var EE_Session $session
53
-     */
54
-    private $session;
51
+	/**
52
+	 * @var EE_Session $session
53
+	 */
54
+	private $session;
55 55
 
56
-    /**
57
-     * @var EEM_Ticket $ticket_model
58
-     */
59
-    private $ticket_model;
56
+	/**
57
+	 * @var EEM_Ticket $ticket_model
58
+	 */
59
+	private $ticket_model;
60 60
 
61
-    /**
62
-     * @var TicketDatetimeAvailabilityTracker $tracker
63
-     */
64
-    private $tracker;
61
+	/**
62
+	 * @var TicketDatetimeAvailabilityTracker $tracker
63
+	 */
64
+	private $tracker;
65 65
 
66 66
 
67
-    /**
68
-     * ProcessTicketSelector constructor.
69
-     * NOTE: PLZ use the Loader to instantiate this class if need be
70
-     * so that all dependencies get injected correctly (which will happen automatically)
71
-     * Null values for parameters are only for backwards compatibility but will be removed later on.
72
-     *
73
-     * @param EE_Core_Config|null                    $core_config
74
-     * @param RequestInterface|null                  $request
75
-     * @param EE_Session|null                        $session
76
-     * @param EEM_Ticket|null                        $ticket_model
77
-     * @param TicketDatetimeAvailabilityTracker|null $tracker
78
-     * @throws InvalidArgumentException
79
-     * @throws InvalidDataTypeException
80
-     * @throws InvalidInterfaceException
81
-     */
82
-    public function __construct(
83
-        EE_Core_Config $core_config = null,
84
-        RequestInterface $request = null,
85
-        EE_Session $session = null,
86
-        EEM_Ticket $ticket_model = null,
87
-        TicketDatetimeAvailabilityTracker $tracker = null
88
-    ) {
89
-        $loader = LoaderFactory::getLoader();
90
-        $this->core_config = $core_config instanceof EE_Core_Config
91
-            ? $core_config
92
-            : $loader->getShared('EE_Core_Config');
93
-        $this->request = $request instanceof RequestInterface
94
-            ? $request
95
-            : $loader->getShared('EventEspresso\core\services\request\Request');
96
-        $this->session = $session instanceof EE_Session
97
-            ? $session
98
-            : $loader->getShared('EE_Session');
99
-        $this->ticket_model = $ticket_model instanceof EEM_Ticket
100
-            ? $ticket_model
101
-            : $loader->getShared('EEM_Ticket');
102
-        $this->tracker = $tracker instanceof TicketDatetimeAvailabilityTracker
103
-            ? $tracker
104
-            : $loader->getShared('EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker');
105
-    }
67
+	/**
68
+	 * ProcessTicketSelector constructor.
69
+	 * NOTE: PLZ use the Loader to instantiate this class if need be
70
+	 * so that all dependencies get injected correctly (which will happen automatically)
71
+	 * Null values for parameters are only for backwards compatibility but will be removed later on.
72
+	 *
73
+	 * @param EE_Core_Config|null                    $core_config
74
+	 * @param RequestInterface|null                  $request
75
+	 * @param EE_Session|null                        $session
76
+	 * @param EEM_Ticket|null                        $ticket_model
77
+	 * @param TicketDatetimeAvailabilityTracker|null $tracker
78
+	 * @throws InvalidArgumentException
79
+	 * @throws InvalidDataTypeException
80
+	 * @throws InvalidInterfaceException
81
+	 */
82
+	public function __construct(
83
+		EE_Core_Config $core_config = null,
84
+		RequestInterface $request = null,
85
+		EE_Session $session = null,
86
+		EEM_Ticket $ticket_model = null,
87
+		TicketDatetimeAvailabilityTracker $tracker = null
88
+	) {
89
+		$loader = LoaderFactory::getLoader();
90
+		$this->core_config = $core_config instanceof EE_Core_Config
91
+			? $core_config
92
+			: $loader->getShared('EE_Core_Config');
93
+		$this->request = $request instanceof RequestInterface
94
+			? $request
95
+			: $loader->getShared('EventEspresso\core\services\request\Request');
96
+		$this->session = $session instanceof EE_Session
97
+			? $session
98
+			: $loader->getShared('EE_Session');
99
+		$this->ticket_model = $ticket_model instanceof EEM_Ticket
100
+			? $ticket_model
101
+			: $loader->getShared('EEM_Ticket');
102
+		$this->tracker = $tracker instanceof TicketDatetimeAvailabilityTracker
103
+			? $tracker
104
+			: $loader->getShared('EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker');
105
+	}
106 106
 
107 107
 
108
-    /**
109
-     * cancelTicketSelections
110
-     *
111
-     * @return bool
112
-     * @throws EE_Error
113
-     * @throws InvalidArgumentException
114
-     * @throws InvalidInterfaceException
115
-     * @throws InvalidDataTypeException
116
-     * @throws ReflectionException
117
-     */
118
-    public function cancelTicketSelections(): bool
119
-    {
120
-        // check nonce
121
-        if (! $this->processTicketSelectorNonce()) {
122
-            return false;
123
-        }
124
-        $this->session->clear_session(__CLASS__, __FUNCTION__);
125
-        if ($this->request->requestParamIsSet('event_id')) {
126
-            EEH_URL::safeRedirectAndExit(
127
-                EEH_Event_View::event_link_url(
128
-                    $this->request->getRequestParam('event_id', 0, 'int')
129
-                )
130
-            );
131
-        }
132
-        EEH_URL::safeRedirectAndExit(
133
-            site_url('/' . $this->core_config->event_cpt_slug . '/')
134
-        );
135
-        return true;
136
-    }
108
+	/**
109
+	 * cancelTicketSelections
110
+	 *
111
+	 * @return bool
112
+	 * @throws EE_Error
113
+	 * @throws InvalidArgumentException
114
+	 * @throws InvalidInterfaceException
115
+	 * @throws InvalidDataTypeException
116
+	 * @throws ReflectionException
117
+	 */
118
+	public function cancelTicketSelections(): bool
119
+	{
120
+		// check nonce
121
+		if (! $this->processTicketSelectorNonce()) {
122
+			return false;
123
+		}
124
+		$this->session->clear_session(__CLASS__, __FUNCTION__);
125
+		if ($this->request->requestParamIsSet('event_id')) {
126
+			EEH_URL::safeRedirectAndExit(
127
+				EEH_Event_View::event_link_url(
128
+					$this->request->getRequestParam('event_id', 0, 'int')
129
+				)
130
+			);
131
+		}
132
+		EEH_URL::safeRedirectAndExit(
133
+			site_url('/' . $this->core_config->event_cpt_slug . '/')
134
+		);
135
+		return true;
136
+	}
137 137
 
138 138
 
139
-    /**
140
-     * processTicketSelectorNonce
141
-     *
142
-     * @return bool
143
-     */
144
-    private function processTicketSelectorNonce(): bool
145
-    {
146
-        if (
147
-            ! $this->request->isAdmin()
148
-            && (
149
-                ! $this->request->requestParamIsSet('cancel_ticket_selections_nonce')
150
-                || ! wp_verify_nonce(
151
-                    $this->request->getRequestParam('cancel_ticket_selections_nonce'),
152
-                    'cancel_ticket_selections'
153
-                )
154
-            )
155
-        ) {
156
-            EE_Error::add_error(
157
-                sprintf(
158
-                    esc_html__(
159
-                        'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.',
160
-                        'event_espresso'
161
-                    ),
162
-                    '<br/>'
163
-                ),
164
-                __FILE__,
165
-                __FUNCTION__,
166
-                __LINE__
167
-            );
168
-            return false;
169
-        }
170
-        return true;
171
-    }
139
+	/**
140
+	 * processTicketSelectorNonce
141
+	 *
142
+	 * @return bool
143
+	 */
144
+	private function processTicketSelectorNonce(): bool
145
+	{
146
+		if (
147
+			! $this->request->isAdmin()
148
+			&& (
149
+				! $this->request->requestParamIsSet('cancel_ticket_selections_nonce')
150
+				|| ! wp_verify_nonce(
151
+					$this->request->getRequestParam('cancel_ticket_selections_nonce'),
152
+					'cancel_ticket_selections'
153
+				)
154
+			)
155
+		) {
156
+			EE_Error::add_error(
157
+				sprintf(
158
+					esc_html__(
159
+						'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.',
160
+						'event_espresso'
161
+					),
162
+					'<br/>'
163
+				),
164
+				__FILE__,
165
+				__FUNCTION__,
166
+				__LINE__
167
+			);
168
+			return false;
169
+		}
170
+		return true;
171
+	}
172 172
 
173 173
 
174
-    /**
175
-     * process_ticket_selections
176
-     *
177
-     * @return bool
178
-     * @throws EE_Error
179
-     * @throws InvalidArgumentException
180
-     * @throws InvalidDataTypeException
181
-     * @throws InvalidInterfaceException
182
-     * @throws ReflectionException
183
-     */
184
-    public function processTicketSelections(): bool
185
-    {
186
-        do_action('EED_Ticket_Selector__process_ticket_selections__before');
187
-        if ($this->request->isBot()) {
188
-            EEH_URL::safeRedirectAndExit(
189
-                apply_filters(
190
-                    'FHEE__EE_Ticket_Selector__process_ticket_selections__bot_redirect_url',
191
-                    site_url()
192
-                )
193
-            );
194
-        }
195
-        // we should really only have 1 registration in the works now
196
-        // (ie, no MER) so unless otherwise requested, clear the session
197
-        if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) {
198
-            $this->session->clear_session(__CLASS__, __FUNCTION__);
199
-        }
200
-        // validate/sanitize/filter data
201
-        $id = null;
202
-        $valid = [];
203
-        try {
204
-            $post_data_validator = new ProcessTicketSelectorPostData($this->request);
205
-            $id = $post_data_validator->getEventId();
206
-            $valid               = apply_filters(
207
-                'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data',
208
-                $post_data_validator->validatePostData()
209
-            );
210
-        } catch (Exception $exception) {
211
-            EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__);
212
-        }
213
-        // check total tickets ordered vs max number of attendees that can register
214
-        if (! empty($valid) && $valid['total_tickets'] > $valid['max_atndz']) {
215
-            $this->maxAttendeesViolation($valid);
216
-        } else {
217
-            // all data appears to be valid
218
-            if ($this->processSuccessfulCart($this->addTicketsToCart($valid))) {
219
-                return true;
220
-            }
221
-        }
222
-        // die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT
223
-        // at this point, just return if registration is being made from admin
224
-        if ($this->request->isAdmin() || $this->request->isFrontAjax()) {
225
-            return false;
226
-        }
227
-        if (! empty($valid['return_url'])) {
228
-            EEH_URL::safeRedirectAndExit($valid['return_url']);
229
-        }
230
-        // do we have an event id?
231
-        if ($id) {
232
-            EEH_URL::safeRedirectAndExit(get_permalink($id));
233
-        }
234
-        echo EE_Error::get_notices(); // already escaped
235
-        return false;
236
-    }
174
+	/**
175
+	 * process_ticket_selections
176
+	 *
177
+	 * @return bool
178
+	 * @throws EE_Error
179
+	 * @throws InvalidArgumentException
180
+	 * @throws InvalidDataTypeException
181
+	 * @throws InvalidInterfaceException
182
+	 * @throws ReflectionException
183
+	 */
184
+	public function processTicketSelections(): bool
185
+	{
186
+		do_action('EED_Ticket_Selector__process_ticket_selections__before');
187
+		if ($this->request->isBot()) {
188
+			EEH_URL::safeRedirectAndExit(
189
+				apply_filters(
190
+					'FHEE__EE_Ticket_Selector__process_ticket_selections__bot_redirect_url',
191
+					site_url()
192
+				)
193
+			);
194
+		}
195
+		// we should really only have 1 registration in the works now
196
+		// (ie, no MER) so unless otherwise requested, clear the session
197
+		if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) {
198
+			$this->session->clear_session(__CLASS__, __FUNCTION__);
199
+		}
200
+		// validate/sanitize/filter data
201
+		$id = null;
202
+		$valid = [];
203
+		try {
204
+			$post_data_validator = new ProcessTicketSelectorPostData($this->request);
205
+			$id = $post_data_validator->getEventId();
206
+			$valid               = apply_filters(
207
+				'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data',
208
+				$post_data_validator->validatePostData()
209
+			);
210
+		} catch (Exception $exception) {
211
+			EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__);
212
+		}
213
+		// check total tickets ordered vs max number of attendees that can register
214
+		if (! empty($valid) && $valid['total_tickets'] > $valid['max_atndz']) {
215
+			$this->maxAttendeesViolation($valid);
216
+		} else {
217
+			// all data appears to be valid
218
+			if ($this->processSuccessfulCart($this->addTicketsToCart($valid))) {
219
+				return true;
220
+			}
221
+		}
222
+		// die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT
223
+		// at this point, just return if registration is being made from admin
224
+		if ($this->request->isAdmin() || $this->request->isFrontAjax()) {
225
+			return false;
226
+		}
227
+		if (! empty($valid['return_url'])) {
228
+			EEH_URL::safeRedirectAndExit($valid['return_url']);
229
+		}
230
+		// do we have an event id?
231
+		if ($id) {
232
+			EEH_URL::safeRedirectAndExit(get_permalink($id));
233
+		}
234
+		echo EE_Error::get_notices(); // already escaped
235
+		return false;
236
+	}
237 237
 
238 238
 
239
-    /**
240
-     * @param array $valid
241
-     */
242
-    private function maxAttendeesViolation(array $valid)
243
-    {
244
-        // ordering too many tickets !!!
245
-        $total_tickets_string = esc_html(
246
-            _n(
247
-                'You have attempted to purchase %s ticket.',
248
-                'You have attempted to purchase %s tickets.',
249
-                $valid['total_tickets'],
250
-                'event_espresso'
251
-            )
252
-        );
253
-        $limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']);
254
-        // dev only message
255
-        $max_attendees_string = esc_html(
256
-            _n(
257
-                'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
258
-                'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
259
-                $valid['max_atndz'],
260
-                'event_espresso'
261
-            )
262
-        );
263
-        $limit_error_2 = sprintf($max_attendees_string, $valid['max_atndz'], $valid['max_atndz']);
264
-        EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__);
265
-    }
239
+	/**
240
+	 * @param array $valid
241
+	 */
242
+	private function maxAttendeesViolation(array $valid)
243
+	{
244
+		// ordering too many tickets !!!
245
+		$total_tickets_string = esc_html(
246
+			_n(
247
+				'You have attempted to purchase %s ticket.',
248
+				'You have attempted to purchase %s tickets.',
249
+				$valid['total_tickets'],
250
+				'event_espresso'
251
+			)
252
+		);
253
+		$limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']);
254
+		// dev only message
255
+		$max_attendees_string = esc_html(
256
+			_n(
257
+				'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
258
+				'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.',
259
+				$valid['max_atndz'],
260
+				'event_espresso'
261
+			)
262
+		);
263
+		$limit_error_2 = sprintf($max_attendees_string, $valid['max_atndz'], $valid['max_atndz']);
264
+		EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__);
265
+	}
266 266
 
267 267
 
268
-    /**
269
-     * @param array $valid
270
-     * @return int
271
-     * @throws EE_Error
272
-     * @throws InvalidArgumentException
273
-     * @throws InvalidDataTypeException
274
-     * @throws InvalidInterfaceException
275
-     * @throws ReflectionException
276
-     */
277
-    private function addTicketsToCart(array $valid)
278
-    {
279
-        $tickets_added = 0;
280
-        $tickets_selected = false;
281
-        if (! empty($valid['ticket-selections']) && $valid['total_tickets'] > 0) {
282
-            // load cart using factory because we don't want to do so until actually needed
283
-            $this->cart = CartFactory::getCart();
284
-            // if the user is an admin that can edit registrations,
285
-            // then we'll also allow them to add any tickets, even if they are expired
286
-            $current_user_is_admin = current_user_can('ee_edit_registrations');
287
-            // cycle thru the number of data rows sent from the event listing
288
-            foreach ($valid['ticket-selections'] as $ticket_id => $qty) {
289
-                if ($qty) {
290
-                    // YES we have a ticket quantity
291
-                    $tickets_selected = true;
292
-                    $valid_ticket     = false;
293
-                    // get ticket via the ticket id we put in the form
294
-                    $ticket = $this->ticket_model->get_one_by_ID($ticket_id);
295
-                    if ($ticket instanceof EE_Ticket && ($ticket->is_on_sale() || $current_user_is_admin)) {
296
-                        $valid_ticket  = true;
297
-                        $tickets_added += $this->addTicketToCart($ticket, $qty);
298
-                    }
299
-                    if ($valid_ticket !== true) {
300
-                        // nothing added to cart retrieved
301
-                        EE_Error::add_error(
302
-                            sprintf(
303
-                                esc_html__(
304
-                                    'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.',
305
-                                    'event_espresso'
306
-                                ),
307
-                                '<br/>'
308
-                            ),
309
-                            __FILE__,
310
-                            __FUNCTION__,
311
-                            __LINE__
312
-                        );
313
-                    }
314
-                    if (EE_Error::has_error()) {
315
-                        break;
316
-                    }
317
-                }
318
-            }
319
-        }
320
-        do_action(
321
-            'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
322
-            $this->cart,
323
-            $this
324
-        );
325
-        if (! apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tickets_selected)) {
326
-            // no ticket quantities were selected
327
-            EE_Error::add_error(
328
-                esc_html__('You need to select a ticket quantity before you can proceed.', 'event_espresso'),
329
-                __FILE__,
330
-                __FUNCTION__,
331
-                __LINE__
332
-            );
333
-        }
334
-        return $tickets_added;
335
-    }
268
+	/**
269
+	 * @param array $valid
270
+	 * @return int
271
+	 * @throws EE_Error
272
+	 * @throws InvalidArgumentException
273
+	 * @throws InvalidDataTypeException
274
+	 * @throws InvalidInterfaceException
275
+	 * @throws ReflectionException
276
+	 */
277
+	private function addTicketsToCart(array $valid)
278
+	{
279
+		$tickets_added = 0;
280
+		$tickets_selected = false;
281
+		if (! empty($valid['ticket-selections']) && $valid['total_tickets'] > 0) {
282
+			// load cart using factory because we don't want to do so until actually needed
283
+			$this->cart = CartFactory::getCart();
284
+			// if the user is an admin that can edit registrations,
285
+			// then we'll also allow them to add any tickets, even if they are expired
286
+			$current_user_is_admin = current_user_can('ee_edit_registrations');
287
+			// cycle thru the number of data rows sent from the event listing
288
+			foreach ($valid['ticket-selections'] as $ticket_id => $qty) {
289
+				if ($qty) {
290
+					// YES we have a ticket quantity
291
+					$tickets_selected = true;
292
+					$valid_ticket     = false;
293
+					// get ticket via the ticket id we put in the form
294
+					$ticket = $this->ticket_model->get_one_by_ID($ticket_id);
295
+					if ($ticket instanceof EE_Ticket && ($ticket->is_on_sale() || $current_user_is_admin)) {
296
+						$valid_ticket  = true;
297
+						$tickets_added += $this->addTicketToCart($ticket, $qty);
298
+					}
299
+					if ($valid_ticket !== true) {
300
+						// nothing added to cart retrieved
301
+						EE_Error::add_error(
302
+							sprintf(
303
+								esc_html__(
304
+									'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.',
305
+									'event_espresso'
306
+								),
307
+								'<br/>'
308
+							),
309
+							__FILE__,
310
+							__FUNCTION__,
311
+							__LINE__
312
+						);
313
+					}
314
+					if (EE_Error::has_error()) {
315
+						break;
316
+					}
317
+				}
318
+			}
319
+		}
320
+		do_action(
321
+			'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
322
+			$this->cart,
323
+			$this
324
+		);
325
+		if (! apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tickets_selected)) {
326
+			// no ticket quantities were selected
327
+			EE_Error::add_error(
328
+				esc_html__('You need to select a ticket quantity before you can proceed.', 'event_espresso'),
329
+				__FILE__,
330
+				__FUNCTION__,
331
+				__LINE__
332
+			);
333
+		}
334
+		return $tickets_added;
335
+	}
336 336
 
337 337
 
338
-    /**
339
-     * adds a ticket to the cart
340
-     *
341
-     * @param EE_Ticket $ticket
342
-     * @param int       $qty
343
-     * @return bool TRUE on success, FALSE on fail
344
-     * @throws InvalidArgumentException
345
-     * @throws InvalidInterfaceException
346
-     * @throws InvalidDataTypeException
347
-     * @throws EE_Error
348
-     */
349
-    private function addTicketToCart(EE_Ticket $ticket, int $qty = 1): bool
350
-    {
351
-        // get the number of spaces left for this datetime ticket
352
-        $available_spaces = $this->tracker->ticketDatetimeAvailability($ticket);
353
-        // compare available spaces against the number of tickets being purchased
354
-        if ($available_spaces >= $qty) {
355
-            // allow addons to prevent a ticket from being added to cart
356
-            if (
357
-                ! apply_filters(
358
-                    'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart',
359
-                    true,
360
-                    $ticket,
361
-                    $qty,
362
-                    $available_spaces
363
-                )
364
-            ) {
365
-                return false;
366
-            }
367
-            $qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket));
368
-            // add event to cart
369
-            if ($this->cart->add_ticket_to_cart($ticket, $qty)) {
370
-                $this->tracker->recalculateTicketDatetimeAvailability($ticket, $qty);
371
-                return true;
372
-            }
373
-            return false;
374
-        }
375
-        $this->tracker->processAvailabilityError($ticket, $qty, $this->cart->all_ticket_quantity_count());
376
-        return false;
377
-    }
338
+	/**
339
+	 * adds a ticket to the cart
340
+	 *
341
+	 * @param EE_Ticket $ticket
342
+	 * @param int       $qty
343
+	 * @return bool TRUE on success, FALSE on fail
344
+	 * @throws InvalidArgumentException
345
+	 * @throws InvalidInterfaceException
346
+	 * @throws InvalidDataTypeException
347
+	 * @throws EE_Error
348
+	 */
349
+	private function addTicketToCart(EE_Ticket $ticket, int $qty = 1): bool
350
+	{
351
+		// get the number of spaces left for this datetime ticket
352
+		$available_spaces = $this->tracker->ticketDatetimeAvailability($ticket);
353
+		// compare available spaces against the number of tickets being purchased
354
+		if ($available_spaces >= $qty) {
355
+			// allow addons to prevent a ticket from being added to cart
356
+			if (
357
+				! apply_filters(
358
+					'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart',
359
+					true,
360
+					$ticket,
361
+					$qty,
362
+					$available_spaces
363
+				)
364
+			) {
365
+				return false;
366
+			}
367
+			$qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket));
368
+			// add event to cart
369
+			if ($this->cart->add_ticket_to_cart($ticket, $qty)) {
370
+				$this->tracker->recalculateTicketDatetimeAvailability($ticket, $qty);
371
+				return true;
372
+			}
373
+			return false;
374
+		}
375
+		$this->tracker->processAvailabilityError($ticket, $qty, $this->cart->all_ticket_quantity_count());
376
+		return false;
377
+	}
378 378
 
379 379
 
380
-    /**
381
-     * @param $tickets_added
382
-     * @return bool
383
-     * @throws InvalidInterfaceException
384
-     * @throws InvalidDataTypeException
385
-     * @throws EE_Error
386
-     * @throws InvalidArgumentException
387
-     */
388
-    private function processSuccessfulCart($tickets_added): bool
389
-    {
390
-        // exit('KILL REDIRECT BEFORE CART UPDATE'); // <<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE
391
-        if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) {
392
-            // make sure cart is loaded
393
-            if (! $this->cart instanceof EE_Cart) {
394
-                $this->cart = CartFactory::getCart();
395
-            }
396
-            do_action(
397
-                'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout',
398
-                $this->cart,
399
-                $this
400
-            );
401
-            $this->cart->recalculate_all_cart_totals();
402
-            $this->cart->save_cart(false);
403
-            // exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<<  OR HERE TO KILL REDIRECT AFTER CART UPDATE
404
-            // just return TRUE for registrations being made from admin
405
-            if ($this->request->isAdmin() || $this->request->isFrontAjax()) {
406
-                return true;
407
-            }
408
-            EEH_URL::safeRedirectAndExit(
409
-                apply_filters(
410
-                    'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url',
411
-                    $this->core_config->reg_page_url()
412
-                )
413
-            );
414
-        }
415
-        if (! EE_Error::has_error() && ! EE_Error::has_error(true, 'attention')) {
416
-            // nothing added to cart
417
-            EE_Error::add_attention(
418
-                esc_html__('No tickets were added for the event', 'event_espresso'),
419
-                __FILE__,
420
-                __FUNCTION__,
421
-                __LINE__
422
-            );
423
-        }
424
-        return false;
425
-    }
380
+	/**
381
+	 * @param $tickets_added
382
+	 * @return bool
383
+	 * @throws InvalidInterfaceException
384
+	 * @throws InvalidDataTypeException
385
+	 * @throws EE_Error
386
+	 * @throws InvalidArgumentException
387
+	 */
388
+	private function processSuccessfulCart($tickets_added): bool
389
+	{
390
+		// exit('KILL REDIRECT BEFORE CART UPDATE'); // <<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE
391
+		if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) {
392
+			// make sure cart is loaded
393
+			if (! $this->cart instanceof EE_Cart) {
394
+				$this->cart = CartFactory::getCart();
395
+			}
396
+			do_action(
397
+				'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout',
398
+				$this->cart,
399
+				$this
400
+			);
401
+			$this->cart->recalculate_all_cart_totals();
402
+			$this->cart->save_cart(false);
403
+			// exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<<  OR HERE TO KILL REDIRECT AFTER CART UPDATE
404
+			// just return TRUE for registrations being made from admin
405
+			if ($this->request->isAdmin() || $this->request->isFrontAjax()) {
406
+				return true;
407
+			}
408
+			EEH_URL::safeRedirectAndExit(
409
+				apply_filters(
410
+					'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url',
411
+					$this->core_config->reg_page_url()
412
+				)
413
+			);
414
+		}
415
+		if (! EE_Error::has_error() && ! EE_Error::has_error(true, 'attention')) {
416
+			// nothing added to cart
417
+			EE_Error::add_attention(
418
+				esc_html__('No tickets were added for the event', 'event_espresso'),
419
+				__FILE__,
420
+				__FUNCTION__,
421
+				__LINE__
422
+			);
423
+		}
424
+		return false;
425
+	}
426 426
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -118,7 +118,7 @@  discard block
 block discarded – undo
118 118
     public function cancelTicketSelections(): bool
119 119
     {
120 120
         // check nonce
121
-        if (! $this->processTicketSelectorNonce()) {
121
+        if ( ! $this->processTicketSelectorNonce()) {
122 122
             return false;
123 123
         }
124 124
         $this->session->clear_session(__CLASS__, __FUNCTION__);
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
             );
131 131
         }
132 132
         EEH_URL::safeRedirectAndExit(
133
-            site_url('/' . $this->core_config->event_cpt_slug . '/')
133
+            site_url('/'.$this->core_config->event_cpt_slug.'/')
134 134
         );
135 135
         return true;
136 136
     }
@@ -211,7 +211,7 @@  discard block
 block discarded – undo
211 211
             EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__);
212 212
         }
213 213
         // check total tickets ordered vs max number of attendees that can register
214
-        if (! empty($valid) && $valid['total_tickets'] > $valid['max_atndz']) {
214
+        if ( ! empty($valid) && $valid['total_tickets'] > $valid['max_atndz']) {
215 215
             $this->maxAttendeesViolation($valid);
216 216
         } else {
217 217
             // all data appears to be valid
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
         if ($this->request->isAdmin() || $this->request->isFrontAjax()) {
225 225
             return false;
226 226
         }
227
-        if (! empty($valid['return_url'])) {
227
+        if ( ! empty($valid['return_url'])) {
228 228
             EEH_URL::safeRedirectAndExit($valid['return_url']);
229 229
         }
230 230
         // do we have an event id?
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
             )
262 262
         );
263 263
         $limit_error_2 = sprintf($max_attendees_string, $valid['max_atndz'], $valid['max_atndz']);
264
-        EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__);
264
+        EE_Error::add_error($limit_error_1.'<br/>'.$limit_error_2, __FILE__, __FUNCTION__, __LINE__);
265 265
     }
266 266
 
267 267
 
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
     {
279 279
         $tickets_added = 0;
280 280
         $tickets_selected = false;
281
-        if (! empty($valid['ticket-selections']) && $valid['total_tickets'] > 0) {
281
+        if ( ! empty($valid['ticket-selections']) && $valid['total_tickets'] > 0) {
282 282
             // load cart using factory because we don't want to do so until actually needed
283 283
             $this->cart = CartFactory::getCart();
284 284
             // if the user is an admin that can edit registrations,
@@ -293,7 +293,7 @@  discard block
 block discarded – undo
293 293
                     // get ticket via the ticket id we put in the form
294 294
                     $ticket = $this->ticket_model->get_one_by_ID($ticket_id);
295 295
                     if ($ticket instanceof EE_Ticket && ($ticket->is_on_sale() || $current_user_is_admin)) {
296
-                        $valid_ticket  = true;
296
+                        $valid_ticket = true;
297 297
                         $tickets_added += $this->addTicketToCart($ticket, $qty);
298 298
                     }
299 299
                     if ($valid_ticket !== true) {
@@ -322,7 +322,7 @@  discard block
 block discarded – undo
322 322
             $this->cart,
323 323
             $this
324 324
         );
325
-        if (! apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tickets_selected)) {
325
+        if ( ! apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tickets_selected)) {
326 326
             // no ticket quantities were selected
327 327
             EE_Error::add_error(
328 328
                 esc_html__('You need to select a ticket quantity before you can proceed.', 'event_espresso'),
@@ -390,7 +390,7 @@  discard block
 block discarded – undo
390 390
         // exit('KILL REDIRECT BEFORE CART UPDATE'); // <<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE
391 391
         if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) {
392 392
             // make sure cart is loaded
393
-            if (! $this->cart instanceof EE_Cart) {
393
+            if ( ! $this->cart instanceof EE_Cart) {
394 394
                 $this->cart = CartFactory::getCart();
395 395
             }
396 396
             do_action(
@@ -412,7 +412,7 @@  discard block
 block discarded – undo
412 412
                 )
413 413
             );
414 414
         }
415
-        if (! EE_Error::has_error() && ! EE_Error::has_error(true, 'attention')) {
415
+        if ( ! EE_Error::has_error() && ! EE_Error::has_error(true, 'attention')) {
416 416
             // nothing added to cart
417 417
             EE_Error::add_attention(
418 418
                 esc_html__('No tickets were added for the event', 'event_espresso'),
Please login to merge, or discard this patch.