Completed
Branch BUG-9625-better-us-phone-valid... (e0ce21)
by
unknown
111:51 queued 98:50
created

EEH_Activation   F

Complexity

Total Complexity 216

Size/Duplication

Total Lines 1707
Duplicated Lines 12.77 %

Coupling/Cohesion

Components 2
Dependencies 19

Importance

Changes 0
Metric Value
dl 218
loc 1707
rs 0.6314
c 0
b 0
f 0
wmc 216
lcom 2
cbo 19

38 Methods

Rating   Name   Duplication   Size   Complexity  
A ensure_table_name_has_prefix() 0 4 2
A system_initialization() 0 5 1
A initialize_db_and_folders() 0 5 2
B initialize_db_content() 0 24 2
B get_cron_tasks() 0 24 5
A create_cron_tasks() 0 9 3
D remove_cron_tasks() 0 39 9
A CPT_initialization() 0 5 1
A reset_and_update_config() 0 5 1
C load_calendar_config() 0 24 9
B migrate_old_config_data() 0 18 6
A deactivate_event_espresso() 0 6 2
F verify_default_pages_exist() 9 91 15
A get_page_by_ee_shortcode() 0 12 2
B create_critical_page() 0 31 3
B _track_critical_page_post_shortcodes() 8 31 6
B get_default_creator_id() 0 26 5
C create_table() 0 57 11
A add_column_if_it_doesnt_exist() 0 14 3
A get_fields_on_table() 0 15 4
A db_table_is_empty() 0 9 3
A delete_db_table_if_empty() 0 6 2
A delete_unused_db_table() 0 8 2
A drop_index() 0 15 4
B create_database_tables() 10 26 5
F initialize_system_questions() 172 296 24
A insert_default_payment_methods() 0 8 2
A insert_default_status_codes() 0 48 2
B create_upload_directories() 0 35 3
A upload_directories_incomplete() 0 3 1
F generate_default_message_templates() 19 148 32
D validate_messages_system() 0 45 10
A create_no_ticket_prices_array() 0 8 2
A plugin_deactivation() 0 2 1
B delete_all_espresso_cpt_data() 0 20 5
F delete_all_espresso_tables_and_data() 0 129 23
A table_exists() 0 20 2
A reset() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EEH_Activation often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EEH_Activation, and based on these observations, apply Extract Interface, too.

1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) exit('No direct script access allowed');
2
/**
3
 * Event Espresso
4
 *
5
 * Event Registration and Management Plugin for WordPress
6
 *
7
 * @ package			Event Espresso
8
 * @ author			Seth Shoultes
9
 * @ copyright		(c) 2008-2011 Event Espresso  All Rights Reserved.
10
 * @ license			http://eventespresso.com/support/terms-conditions/   * see Plugin Licensing *
11
 * @ link					http://www.eventespresso.com
12
 * @ version		 	4.0
13
 *
14
 * ------------------------------------------------------------------------
15
 *
16
 * EEH_Activation Helper
17
 *
18
 * @package			Event Espresso
19
 * @subpackage	/helpers/
20
 * @author				Brent Christensen
21
 *
22
 * ------------------------------------------------------------------------
23
 */
24
class EEH_Activation {
25
26
	/**
27
	 * constant used to indicate a cron task is no longer in use
28
	 */
29
	const cron_task_no_longer_in_use = 'no_longer_in_use';
30
31
	/**
32
	 * option name that will indicate whether or not we still
33
	 * need to create EE's folders in the uploads directory
34
	 * (because if EE was installed without file system access,
35
	 * we need to request credentials before we can create them)
36
	 */
37
	const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
38
	private static $_default_creator_id = null;
39
40
	/**
41
	 * indicates whether or not we've already verified core's default data during this request,
42
	 * because after migrations are done, any addons activated while in maintenance mode
43
	 * will want to setup their own default data, and they might hook into core's default data
44
	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
45
	 * This prevents doing that for EVERY single addon.
46
	 * @var boolean
47
	 */
48
	protected static $_initialized_db_content_already_in_this_request = false;
49
50
51
52
	/**
53
	 *    _ensure_table_name_has_prefix
54
	 *
55
	 * @access public
56
	 * @static
57
	 * @param $table_name
58
	 * @return string
59
	 */
60
	public static function ensure_table_name_has_prefix( $table_name ) {
61
		global $wpdb;
62
		return strpos( $table_name, $wpdb->prefix ) === 0 ? $table_name : $wpdb->prefix . $table_name;
63
	}
64
65
66
	/**
67
	 * 	system_initialization
68
	 * 	ensures the EE configuration settings are loaded with at least default options set
69
	 * 	and that all critical EE pages have been generated with the appropriate shortcodes in place
70
	 *
71
	 * 	@access public
72
	 * 	@static
73
	 * 	@return void
74
	 */
75
	public static function system_initialization() {
76
		EEH_Activation::reset_and_update_config();
77
		//which is fired BEFORE activation of plugin anyways
78
		EEH_Activation::verify_default_pages_exist();
79
	}
80
81
82
83
	/**
84
	 * Sets the database schema and creates folders. This should
85
	 * be called on plugin activation and reactivation
86
	 * @return boolean success, whether the database and folders are setup properly
87
	 */
88
	public static function initialize_db_and_folders(){
89
		$good_filesystem = EEH_Activation::create_upload_directories();
90
		$good_db = EEH_Activation::create_database_tables();
91
		return $good_filesystem && $good_db;
92
	}
93
94
95
96
	/**
97
	 * assuming we have an up-to-date database schema, this will populate it
98
	 * with default and initial data. This should be called
99
	 * upon activation of a new plugin, reactivation, and at the end
100
	 * of running migration scripts
101
	 */
102
	public static function initialize_db_content(){
103
		//let's avoid doing all this logic repeatedly, especially when addons are requesting it
104
		if( EEH_Activation::$_initialized_db_content_already_in_this_request ) {
105
			return;
106
		}
107
		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
108
109
		EEH_Activation::initialize_system_questions();
110
		EEH_Activation::insert_default_status_codes();
111
		EEH_Activation::generate_default_message_templates();
112
		EEH_Activation::create_no_ticket_prices_array();
113
		EE_Registry::instance()->CAP->init_caps();
114
115
		EEH_Activation::validate_messages_system();
116
		EEH_Activation::insert_default_payment_methods();
117
		//in case we've
118
		EEH_Activation::remove_cron_tasks();
119
		EEH_Activation::create_cron_tasks();
120
		//also, check for CAF default db content
121
		do_action( 'AHEE__EEH_Activation__initialize_db_content' );
122
		//also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
123
		//which users really won't care about on initial activation
124
		EE_Error::overwrite_success();
125
	}
126
127
128
129
130
	/**
131
	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
132
	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
133
	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use (null)
134
	 *
135
	 * @param string $which_to_include can be 'current' (ones that are currently in use),
136
	 *                          'old' (only returns ones that should no longer be used),or 'all',
137
	 * @return array
138
	 * @throws \EE_Error
139
	 */
140
	public static function get_cron_tasks( $which_to_include ) {
141
		$cron_tasks = apply_filters(
142
			'FHEE__EEH_Activation__get_cron_tasks',
143
			array(
144
				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions' => 'hourly',
145
//				'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
146
				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use, //there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
147
			)
148
		);
149
		if( $which_to_include === 'all' ) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
150
			//leave as-is
151
		}elseif( $which_to_include === 'old' ) {
152
			$cron_tasks = array_filter( $cron_tasks, function ( $value ) {
153
				return $value === EEH_Activation::cron_task_no_longer_in_use;
154
			});
155
		}elseif( $which_to_include === 'current' ) {
156
			$cron_tasks = array_filter( $cron_tasks );
157
		}elseif( WP_DEBUG ) {
158
			throw new EE_Error( sprintf( __( 'Invalidate argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".', 'event_espresso' ), $which_to_include ) );
159
		}else{
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
160
			//leave as-is
161
		}
162
		return $cron_tasks;
163
	}
164
165
	/**
166
	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
167
	 */
168
	public static function create_cron_tasks() {
169
170
		foreach( EEH_Activation::get_cron_tasks( 'current' ) as $hook_name => $frequency ) {
171
			if( ! wp_next_scheduled( $hook_name ) ) {
172
				wp_schedule_event( time(), $frequency, $hook_name );
173
			}
174
		}
175
176
	}
177
178
	/**
179
	 * Remove the currently-existing and now-removed cron tasks.
180
	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
181
	 */
182
	public static function remove_cron_tasks( $remove_all = true ) {
183
		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
184
		$crons = _get_cron_array();
185
		$crons = is_array( $crons ) ? $crons : array();
186
		/* reminder of what $crons look like:
187
		 * Top-level keys are timestamps, and their values are arrays.
188
		 * The 2nd level arrays have keys with each of the cron task hook names to run at that time
189
		 * and their values are arrays.
190
		 * The 3rd level level arrays are keys which are hashes of the cron task's arguments,
191
		 *  and their values are the UN-hashed arguments
192
		 * eg
193
		 * array (size=13)
194
		 *		1429903276 =>
195
		 *		  array (size=1)
196
		 *			'AHEE__EE_Cron_Tasks__update_transaction_with_payment' =>
197
		 *			  array (size=1)
198
		 *				'561299d6e42c8e079285870ade0e47e6' =>
199
		 *				  array (size=2)
200
		 *					...
201
		 *      ...
202
		 */
203
		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks( $cron_tasks_to_remove );
204
		foreach ( $crons as $timestamp => $hooks_to_fire_at_time ) {
205
			if ( is_array( $hooks_to_fire_at_time ) ) {
206
				foreach ( $hooks_to_fire_at_time as $hook_name => $hook_actions ) {
207
					if ( isset( $ee_cron_tasks_to_remove[ $hook_name ] )
208
					     && is_array( $ee_cron_tasks_to_remove[ $hook_name ] )
209
					) {
210
						unset( $crons[ $timestamp ][ $hook_name ] );
211
					}
212
				}
213
				//also take care of any empty cron timestamps.
214
				if ( empty( $hooks_to_fire_at_time ) ) {
215
					unset( $crons[ $timestamp ] );
216
				}
217
			}
218
		}
219
		_set_cron_array( $crons );
220
	}
221
222
223
224
	/**
225
	 * 	CPT_initialization
226
	 *	registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
227
	 *
228
	 * 	@access public
229
	 * 	@static
230
	 * 	@return void
231
	 */
232
	public static function CPT_initialization() {
233
		// register Custom Post Types
234
		EE_Registry::instance()->load_core( 'Register_CPTs' );
235
		flush_rewrite_rules();
236
	}
237
238
239
240
	/**
241
	 * 	reset_and_update_config
242
	 *
243
	 * The following code was moved over from EE_Config so that it will no longer run on every request.
244
	 * If there is old calendar config data saved, then it will get converted on activation.
245
	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
246
	 *
247
	 * 	@access public
248
	 * 	@static
249
	 * 	@return void
250
	 */
251
	public static function reset_and_update_config() {
252
		do_action( 'AHEE__EE_Config___load_core_config__start', array( 'EEH_Activation', 'load_calendar_config' ) );
253
		add_filter( 'FHEE__EE_Config___load_core_config__config_settings', array( 'EEH_Activation', 'migrate_old_config_data' ), 10, 3 );
254
		//EE_Config::reset();
255
	}
256
257
258
	/**
259
	 *    load_calendar_config
260
	 *
261
	 * @access    public
262
	 * @return    stdClass
263
	 */
264
	public static function load_calendar_config() {
265
		// grab array of all plugin folders and loop thru it
266
		$plugins = glob( WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR );
267
		if ( empty( $plugins ) ) {
268
			return;
269
		}
270
		foreach ( $plugins as $plugin_path ) {
271
			// grab plugin folder name from path
272
			$plugin = basename( $plugin_path );
273
			// drill down to Espresso plugins
274
			if ( strpos( $plugin, 'espresso' ) !== FALSE || strpos( $plugin, 'Espresso' ) !== FALSE || strpos( $plugin, 'ee4' ) !== FALSE || strpos( $plugin, 'EE4' ) !== FALSE ) {
275
				// then to calendar related plugins
276
				if ( strpos( $plugin, 'calendar' ) !== FALSE ) {
277
					// this is what we are looking for
278
					$calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
279
					// does it exist in this folder ?
280
					if ( is_readable( $calendar_config )) {
281
						// YEAH! let's load it
282
						require_once( $calendar_config );
283
					}
284
				}
285
			}
286
		}
287
	}
288
289
290
	/**
291
	 *    _migrate_old_config_data
292
	 *
293
	 * @access    public
294
	 * @param array      $settings
295
	 * @param string     $config
296
	 * @param \EE_Config $EE_Config
297
	 * @return \stdClass
298
	 */
299
	public static function migrate_old_config_data( $settings = array(), $config = '', EE_Config $EE_Config ) {
300
		$convert_from_array = array( 'addons' );
301
		// in case old settings were saved as an array
302
		if ( is_array( $settings ) && in_array( $config, $convert_from_array )) {
303
			// convert existing settings to an object
304
			$config_array = $settings;
305
			$settings = new stdClass();
306
			foreach ( $config_array as $key => $value ){
307
				if ( $key == 'calendar' && class_exists( 'EE_Calendar_Config' )) {
308
					$EE_Config->set_config( 'addons', 'EE_Calendar', 'EE_Calendar_Config', $value );
309
				} else {
310
					$settings->{$key} = $value;
311
				}
312
			}
313
			add_filter( 'FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true' );
314
		}
315
		return $settings;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $settings; of type stdClass|array is incompatible with the return type documented by EEH_Activation::migrate_old_config_data of type stdClass as it can also be of type array which is not included in this return type.
Loading history...
316
	}
317
318
319
320
	/**
321
	 * deactivate_event_espresso
322
	 *
323
	 * 	@access public
324
	 * 	@static
325
	 * 	@return void
326
	 */
327
	public static function deactivate_event_espresso() {
328
		// check permissions
329
		if ( current_user_can( 'activate_plugins' )) {
330
			deactivate_plugins( EE_PLUGIN_BASENAME, TRUE );
331
		}
332
	}
333
334
335
336
337
338
	/**
339
	 * verify_default_pages_exist
340
	 *
341
	 * 	@access public
342
	 * 	@static
343
	 * 	@return void
344
	 */
345
	public static function verify_default_pages_exist() {
346
347
		$critical_page_problem = FALSE;
348
349
		$critical_pages = array(
350
			array(
351
				'id' =>'reg_page_id',
352
				'name' => __( 'Registration Checkout', 'event_espresso' ),
353
				'post' => NULL,
354
				'code' => 'ESPRESSO_CHECKOUT'
355
			),
356
			array(
357
				'id' => 'txn_page_id',
358
				'name' => __( 'Transactions', 'event_espresso' ),
359
				'post' => NULL,
360
				'code' => 'ESPRESSO_TXN_PAGE'
361
			),
362
			array(
363
				'id' => 'thank_you_page_id',
364
				'name' => __( 'Thank You', 'event_espresso' ),
365
				'post' => NULL,
366
				'code' => 'ESPRESSO_THANK_YOU'
367
			),
368
			array(
369
				'id' => 'cancel_page_id',
370
				'name' => __( 'Registration Cancelled', 'event_espresso' ),
371
				'post' => NULL,
372
				'code' => 'ESPRESSO_CANCELLED'
373
			),
374
		);
375
376
		$EE_Core_Config = EE_Registry::instance()->CFG->core;
377
378
		foreach ( $critical_pages as $critical_page ) {
379
			// is critical page ID set in config ?
380
			if ( $EE_Core_Config->{$critical_page[ 'id' ]} !== FALSE ) {
381
				// attempt to find post by ID
382
				$critical_page['post'] = get_post( $EE_Core_Config->{$critical_page[ 'id' ]} );
383
			}
384
			// no dice?
385
			if ( $critical_page['post'] == NULL ) {
386
				// attempt to find post by title
387
				$critical_page['post'] = self::get_page_by_ee_shortcode( $critical_page['code'] );
388
				// still nothing?
389
				if ( $critical_page['post'] == NULL ) {
390
					$critical_page = EEH_Activation::create_critical_page( $critical_page );
391
					// REALLY? Still nothing ??!?!?
392 View Code Duplication
					if ( $critical_page['post'] == NULL ) {
393
						$msg = __( 'The Event Espresso critical page configuration settings could not be updated.', 'event_espresso' );
394
						EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
395
						break;
396
					}
397
				}
398
			}
399
			// track post_shortcodes
400
			if ( $critical_page['post'] ) {
401
				EEH_Activation::_track_critical_page_post_shortcodes( $critical_page );
402
			}
403
			// check that Post ID matches critical page ID in config
404
			if (
405
				isset( $critical_page['post']->ID )
406
				&& $critical_page['post']->ID != $EE_Core_Config->{$critical_page[ 'id' ]}
407
			) {
408
				//update Config with post ID
409
				$EE_Core_Config->{$critical_page[ 'id' ]} = $critical_page['post']->ID;
410 View Code Duplication
				if ( ! EE_Config::instance()->update_espresso_config( FALSE, FALSE ) ) {
411
					$msg = __( 'The Event Espresso critical page configuration settings could not be updated.', 'event_espresso' );
412
					EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
413
				}
414
			}
415
416
			$critical_page_problem =
417
				! isset( $critical_page['post']->post_status )
418
				|| $critical_page['post']->post_status != 'publish'
419
				|| strpos( $critical_page['post']->post_content, $critical_page['code'] ) === FALSE
420
					? TRUE
421
					: $critical_page_problem;
422
423
		}
424
425
		if ( $critical_page_problem ) {
426
			$msg = sprintf(
427
				__('A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.', 'event_espresso' ),
428
				'<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">' . __('Event Espresso Critical Pages Settings', 'event_espresso') . '</a>'
429
			);
430
			EE_Error::add_persistent_admin_notice( 'critical_page_problem', $msg );
431
		}
432
		if ( EE_Error::has_notices() ) {
433
			EE_Error::get_notices( FALSE, TRUE, TRUE );
434
		}
435
	}
436
437
	/**
438
	 * Returns the first post which uses the specified shortcode
439
	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
440
	 * ESPRESSO_THANK_YOU. So we will search fora post with the content "[ESPRESSO_THANK_YOU"
441
	 * (we don't search for the closing shortcode bracket because they might have added
442
	 * parameter to the shortcode
443
	 * @return WP_Post or NULl
444
	 */
445
	public static function get_page_by_ee_shortcode($ee_shortcode){
446
		global $wpdb;
447
		$shortcode_and_opening_bracket = '['.$ee_shortcode;
448
		$post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
449
		if($post_id){
450
			return get_post($post_id);
451
		}else{
452
			return NULL;
453
		}
454
455
//		return $post_id;
456
	}
457
458
459
460
	/**
461
	 *    This function generates a post for critical espresso pages
462
	 *
463
	 * @access public
464
	 * @static
465
	 * @param array $critical_page
466
	 * @return array
467
	 */
468
	public static function create_critical_page( $critical_page ) {
469
470
		$post_args = array(
471
			'post_title' => $critical_page['name'],
472
			'post_status' => 'publish',
473
			'post_type' => 'page',
474
			'comment_status' => 'closed',
475
			'post_content' => '[' . $critical_page['code'] . ']'
476
		);
477
478
		$post_id = wp_insert_post( $post_args );
479
		if ( ! $post_id ) {
480
			$msg = sprintf(
481
				__( 'The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso' ),
482
				$critical_page['name']
483
			);
484
			EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
485
			return $critical_page;
486
		}
487
		// get newly created post's details
488
		if ( ! $critical_page['post'] = get_post( $post_id )) {
489
			$msg = sprintf(
490
				__( 'The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso' ),
491
				$critical_page['name']
492
			);
493
			EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
494
		}
495
496
		return $critical_page;
497
498
	}
499
500
501
502
503
504
	/**
505
	 *    This function adds a critical page's shortcode to the post_shortcodes array
506
	 *
507
	 * @access private
508
	 * @static
509
	 * @param array $critical_page
510
	 * @return void
511
	 */
512
	private static function _track_critical_page_post_shortcodes( $critical_page = array() ) {
513
		// check the goods
514 View Code Duplication
		if ( ! $critical_page['post'] instanceof WP_Post ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
515
			$msg = sprintf(
516
				__( 'The Event Espresso critical page shortcode for the page %s can not be tracked because it is not a WP_Post object.', 'event_espresso' ),
517
				$critical_page['name']
518
			);
519
			EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
520
			return;
521
		}
522
		$EE_Core_Config = EE_Registry::instance()->CFG->core;
523
		// map shortcode to post
524
		$EE_Core_Config->post_shortcodes[ $critical_page['post']->post_name ][ $critical_page['code'] ] = $critical_page['post']->ID;
525
		// and make sure it's NOT added to the WP "Posts Page"
526
		// name of the WP Posts Page
527
		$posts_page = EE_Registry::instance()->CFG->get_page_for_posts();
528
		if ( isset( $EE_Core_Config->post_shortcodes[ $posts_page ] )) {
529
			unset( $EE_Core_Config->post_shortcodes[ $posts_page ][ $critical_page['code'] ] );
530
		}
531
		if ( $posts_page != 'posts' && isset( $EE_Core_Config->post_shortcodes['posts'] )) {
532
			unset( $EE_Core_Config->post_shortcodes['posts'][ $critical_page['code'] ] );
533
		}
534
		// update post_shortcode CFG
535
		if ( ! EE_Config::instance()->update_espresso_config( FALSE, FALSE )) {
536
			$msg = sprintf(
537
				__( 'The Event Espresso critical page shortcode for the %s page could not be configured properly.', 'event_espresso' ),
538
				$critical_page['name']
539
			);
540
			EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
541
		}
542
	}
543
544
545
546
	/**
547
	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
548
	 * The role being used to check is filterable.
549
	 *
550
	 * @since  4.6.0
551
	 * @global WPDB $wpdb
552
	 *
553
	 * @return mixed null|int WP_user ID or NULL
554
	 */
555
	public static function get_default_creator_id() {
556
		global $wpdb;
557
558
		if ( ! empty( self::$_default_creator_id ) ) {
559
			return self::$_default_creator_id;
560
		}/**/
561
562
		$role_to_check = apply_filters( 'FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator' );
563
564
		//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.
565
		$pre_filtered_id = apply_filters( 'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id', false, $role_to_check );
566
		if ( $pre_filtered_id !== false ) {
567
			return (int) $pre_filtered_id;
568
		}
569
570
		$capabilities_key = EEH_Activation::ensure_table_name_has_prefix( 'capabilities' );
571
		$query = $wpdb->prepare( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1", '%' . $role_to_check . '%' );
572
		$user_id = $wpdb->get_var( $query );
573
		 $user_id = apply_filters( 'FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id );
574
		 if ( $user_id && intval( $user_id ) ) {
575
		 	self::$_default_creator_id =  intval( $user_id );
576
		 	return self::$_default_creator_id;
577
		 } else {
578
		 	return NULL;
579
		 }
580
	}
581
582
583
584
585
586
	/**
587
	 * 	used by EE and EE addons during plugin activation
588
	 *
589
	 * 	@access public
590
	 * 	@static
591
	 * @param string $table_name without the $wpdb->prefix
592
	 * @param string $sql SQL for creating the table (contents between brackets in an SQL create table query)
593
	 * @param string $engine like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
594
	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
595
	 * and new once this function is done (ie, you really do want to CREATE a table, and
596
	 * expect it to be empty once you're done)
597
	 * leave as FALSE when you just want to verify the table exists and matches this definition (and if it
598
	 * HAS data in it you want to leave it be)
599
	 * 	@return void
600
	 * @throws EE_Error if there are database errors
601
	 */
602
	public static function create_table( $table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false ) {
603
		if( apply_filters( 'FHEE__EEH_Activation__create_table__short_circuit', FALSE, $table_name, $sql ) ){
604
			return;
605
		}
606
		do_action( 'AHEE_log', __FILE__, __FUNCTION__, '' );
607
		if ( ! function_exists( 'dbDelta' )) {
608
			require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
609
		}
610
		/** @var WPDB $wpdb */
611
		global $wpdb;
612
		$wp_table_name = EEH_Activation::ensure_table_name_has_prefix( $table_name );
613
		// do we need to first delete an existing version of this table ?
614
		if ( $drop_pre_existing_table && EEH_Activation::table_exists( $wp_table_name ) ){
615
			// ok, delete the table... but ONLY if it's empty
616
			$deleted_safely = EEH_Activation::delete_db_table_if_empty( $wp_table_name );
617
			// table is NOT empty, are you SURE you want to delete this table ???
618
			if ( ! $deleted_safely && defined( 'EE_DROP_BAD_TABLES' ) && EE_DROP_BAD_TABLES ){
619
				EEH_Activation::delete_unused_db_table( $wp_table_name );
620
			} else if ( ! $deleted_safely ) {
621
				// so we should be more cautious rather than just dropping tables so easily
622
				EE_Error::add_persistent_admin_notice(
623
						'bad_table_' . $wp_table_name . '_detected',
624
						sprintf( __( 'Database table %1$s exists when it shouldn\'t, and may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend adding %2$s to your %3$s file then restore to that backup again. This will clear out the invalid data from %1$s. Afterwards you should undo that change from your %3$s file. %4$sIf you cannot edit %3$s, you should remove the data from %1$s manually then restore to the backup again.', 'event_espresso' ),
625
								$wp_table_name,
626
								"<pre>define( 'EE_DROP_BAD_TABLES', TRUE );</pre>",
627
								'<b>wp-config.php</b>',
628
								'<br/>'),
629
								TRUE );
630
			}
631
		}
632
		// does $sql contain valid column information? ( LPT: https://regex101.com/ is great for working out regex patterns )
633
		if ( preg_match( '((((.*?))(,\s))+)', $sql, $valid_column_data ) ) {
634
			$SQL = "CREATE TABLE $wp_table_name ( $sql ) $engine DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;";
635
			//get $wpdb to echo errors, but buffer them. This way at least WE know an error
636
			//happened. And then we can choose to tell the end user
637
			$old_show_errors_policy = $wpdb->show_errors( TRUE );
638
			$old_error_suppression_policy = $wpdb->suppress_errors( FALSE );
639
			ob_start();
640
			dbDelta( $SQL );
641
			$output = ob_get_contents();
642
			ob_end_clean();
643
			$wpdb->show_errors( $old_show_errors_policy );
644
			$wpdb->suppress_errors( $old_error_suppression_policy );
645
			if( ! empty( $output ) ){
646
				throw new EE_Error( $output	);
647
			}
648
		} else {
649
			throw new EE_Error(
650
				sprintf(
651
					__( 'The following table creation SQL does not contain valid information about the table columns: %1$s %2$s', 'event_espresso' ),
652
					'<br />',
653
					$sql
654
				)
655
			);
656
		}
657
658
	}
659
660
661
662
	/**
663
	 *    add_column_if_it_doesn't_exist
664
	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
665
	 *
666
	 * @access public
667
	 * @static
668
	 * @param string $table_name  (without "wp_", eg "esp_attendee"
669
	 * @param string $column_name
670
	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be 'VARCHAR(10)'
671
	 * @return bool|int
672
	 */
673
	public static function add_column_if_it_doesnt_exist($table_name,$column_name,$column_info='INT UNSIGNED NOT NULL'){
674
		if( apply_filters( 'FHEE__EEH_Activation__add_column_if_it_doesnt_exist__short_circuit', FALSE ) ){
675
			return FALSE;
676
		}
677
		global $wpdb;
678
		$full_table_name= EEH_Activation::ensure_table_name_has_prefix( $table_name );
679
		$fields = self::get_fields_on_table($table_name);
680
		if (!in_array($column_name, $fields)){
681
			$alter_query="ALTER TABLE $full_table_name ADD $column_name $column_info";
682
			//echo "alter query:$alter_query";
683
			return $wpdb->query($alter_query);
684
		}
685
		return TRUE;
686
	}
687
688
689
690
691
	/**
692
	 * get_fields_on_table
693
	 * Gets all the fields on the database table.
694
	 *
695
	 * 	@access public
696
	 * 	@static
697
	 * 	@param string $table_name, without prefixed $wpdb->prefix
0 ignored issues
show
Documentation introduced by
There is no parameter named $table_name,. Did you maybe mean $table_name?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
698
	 * 	@return array of database column names
699
	 */
700
	public static function get_fields_on_table( $table_name = NULL ) {
701
		global $wpdb;
702
		$table_name= EEH_Activation::ensure_table_name_has_prefix( $table_name );
703
		if ( ! empty( $table_name )) {
704
			$columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name ");
705
			if ($columns !== FALSE) {
706
				$field_array = array();
707
				foreach($columns as $column ){
708
					$field_array[] = $column->Field;;
709
				}
710
				return $field_array;
711
			}
712
		}
713
		return FALSE;
714
	}
715
716
717
718
	/**
719
	 * db_table_is_empty
720
	 *
721
	 * @access public
722
	 * @static
723
	 * @param string $table_name
724
	 * @return bool
725
	 */
726
	public static function db_table_is_empty( $table_name ) {
727
		global $wpdb;
728
		$table_name = EEH_Activation::ensure_table_name_has_prefix( $table_name );
729
		if ( EEH_Activation::table_exists( $table_name ) ) {
730
			$count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );
731
			return absint( $count ) === 0 ? true : false;
732
		}
733
		return false;
734
	}
735
736
737
738
	/**
739
	 * delete_db_table_if_empty
740
	 *
741
	 * @access public
742
	 * @static
743
	 * @param string $table_name
744
	 * @return bool | int
745
	 */
746
	public static function delete_db_table_if_empty( $table_name ) {
747
		if ( EEH_Activation::db_table_is_empty( $table_name ) ) {
748
			return EEH_Activation::delete_unused_db_table( $table_name );
749
		}
750
		return false;
751
	}
752
753
754
755
	/**
756
	 * delete_unused_db_table
757
	 *
758
	 * @access public
759
	 * @static
760
	 * @param string $table_name
761
	 * @return bool | int
762
	 */
763
	public static function delete_unused_db_table( $table_name ) {
764
		global $wpdb;
765
		if ( EEH_Activation::table_exists( $table_name ) ) {
766
			$table_name = EEH_Activation::ensure_table_name_has_prefix( $table_name );
767
			return $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
768
		}
769
		return false;
770
	}
771
772
773
774
	/**
775
	 * drop_index
776
	 *
777
	 * @access public
778
	 * @static
779
	 * @param string $table_name
780
	 * @param string $index_name
781
	 * @return bool | int
782
	 */
783
	public static function drop_index( $table_name, $index_name ) {
784
		if( apply_filters( 'FHEE__EEH_Activation__drop_index__short_circuit', FALSE ) ){
785
			return FALSE;
786
		}
787
		global $wpdb;
788
		$table_name = EEH_Activation::ensure_table_name_has_prefix( $table_name );
789
		$index_exists_query = "SHOW INDEX FROM $table_name WHERE Key_name = '$index_name'";
790
		if (
791
			$wpdb->get_var( "SHOW TABLES LIKE '$table_name'" ) == $table_name
792
			&& $wpdb->get_var( $index_exists_query ) == $table_name //using get_var with the $index_exists_query returns the table's name
793
		) {
794
			return $wpdb->query( "ALTER TABLE $table_name DROP INDEX $index_name" );
795
		}
796
		return TRUE;
797
	}
798
799
800
801
	/**
802
	 * create_database_tables
803
	 *
804
	 * @access public
805
	 * @static
806
	 * @throws EE_Error
807
	 * @return boolean success (whether database is setup properly or not)
808
	 */
809
	public static function create_database_tables() {
810
		EE_Registry::instance()->load_core( 'Data_Migration_Manager' );
811
		//find the migration script that sets the database to be compatible with the code
812
		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
813
		if( $dms_name ){
814
			$current_data_migration_script = EE_Registry::instance()->load_dms( $dms_name );
815
			$current_data_migration_script->set_migrating( false );
0 ignored issues
show
Bug introduced by
The method set_migrating cannot be called on $current_data_migration_script (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
816
			$current_data_migration_script->schema_changes_before_migration();
0 ignored issues
show
Bug introduced by
The method schema_changes_before_migration cannot be called on $current_data_migration_script (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
817
			$current_data_migration_script->schema_changes_after_migration();
0 ignored issues
show
Bug introduced by
The method schema_changes_after_migration cannot be called on $current_data_migration_script (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
818 View Code Duplication
			if( $current_data_migration_script->get_errors() ){
0 ignored issues
show
Bug introduced by
The method get_errors cannot be called on $current_data_migration_script (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
819
				if( WP_DEBUG ){
820
					foreach( $current_data_migration_script->get_errors() as $error ){
0 ignored issues
show
Bug introduced by
The method get_errors cannot be called on $current_data_migration_script (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
821
						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__ );
822
					}
823
				}else{
824
					EE_Error::add_error( __( 'There were errors creating the Event Espresso database tables and Event Espresso has been deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.', 'event_espresso' ) );
825
				}
826
				return false;
827
			}
828
			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
829
		}else{
830
			EE_Error::add_error( __( 'Could not determine most up-to-date data migration script from which to pull database schema structure. So database is probably not setup properly', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
831
			return false;
832
		}
833
		return true;
834
	}
835
836
837
838
839
840
	/**
841
	 * initialize_system_questions
842
	 *
843
	 * 	@access public
844
	 * 	@static
845
	 * 	@return void
846
	 */
847
	public static function initialize_system_questions() {
848
		// QUESTION GROUPS
849
		global $wpdb;
850
		$table_name = EEH_Activation::ensure_table_name_has_prefix( 'esp_question_group' );
851
		$SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
852
		// what we have
853
		$question_groups = $wpdb->get_col( $SQL );
854
		// check the response
855
		$question_groups = is_array( $question_groups ) ? $question_groups : array();
856
		// what we should have
857
		$QSG_systems = array( 1, 2 );
858
		// loop thru what we should have and compare to what we have
859
		foreach ( $QSG_systems as $QSG_system ) {
860
			// reset values array
861
			$QSG_values = array();
862
			// 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)
863
			if ( ! in_array( "$QSG_system", $question_groups )) {
864
				// add it
865
				switch ( $QSG_system ) {
866
867 View Code Duplication
					case 1:
868
							$QSG_values = array(
869
									'QSG_name' => __( 'Personal Information', 'event_espresso' ),
870
									'QSG_identifier' => 'personal-information-' . time(),
871
									'QSG_desc' => '',
872
									'QSG_order' => 1,
873
									'QSG_show_group_name' => 1,
874
									'QSG_show_group_desc' => 1,
875
									'QSG_system' => EEM_Question_Group::system_personal,
876
									'QSG_deleted' => 0
877
								);
878
						break;
879
880 View Code Duplication
					case 2:
881
							$QSG_values = array(
882
									'QSG_name' => __( 'Address Information','event_espresso' ),
883
									'QSG_identifier' => 'address-information-' . time(),
884
									'QSG_desc' => '',
885
									'QSG_order' => 2,
886
									'QSG_show_group_name' => 1,
887
									'QSG_show_group_desc' => 1,
888
									'QSG_system' => EEM_Question_Group::system_address,
889
									'QSG_deleted' => 0
890
								);
891
						break;
892
893
				}
894
				// make sure we have some values before inserting them
895
				if ( ! empty( $QSG_values )) {
896
					// insert system question
897
					$wpdb->insert(
898
						$table_name,
899
						$QSG_values,
900
						array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d' )
901
					);
902
					$QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$QSG_IDs was never initialized. Although not strictly required by PHP, it is generally a good practice to add $QSG_IDs = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
903
				}
904
			}
905
		}
906
907
908
909
		// QUESTIONS
910
		global $wpdb;
911
		$table_name = EEH_Activation::ensure_table_name_has_prefix( 'esp_question' );
912
		$SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
913
		// what we have
914
		$questions = $wpdb->get_col( $SQL );
915
		// what we should have
916
		$QST_systems = array(
917
			'fname',
918
			'lname',
919
			'email',
920
			'address',
921
			'address2',
922
			'city',
923
			'state',
924
			'country',
925
			'zip',
926
			'phone'
927
		);
928
		$order_for_group_1 = 1;
929
		$order_for_group_2 = 1;
930
		// loop thru what we should have and compare to what we have
931
		foreach ( $QST_systems as $QST_system ) {
932
			// reset values array
933
			$QST_values = array();
934
			// if we don't have what we should have
935
			if ( ! in_array( $QST_system, $questions )) {
936
				// add it
937
				switch ( $QST_system ) {
938
939 View Code Duplication
					case 'fname':
940
							$QST_values = array(
941
									'QST_display_text' => __( 'First Name', 'event_espresso' ),
942
									'QST_admin_label' => __( 'First Name - System Question', 'event_espresso' ),
943
									'QST_system' => 'fname',
944
									'QST_type' => 'TEXT',
945
									'QST_required' => 1,
946
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
947
									'QST_order' => 1,
948
									'QST_admin_only' => 0,
949
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
950
									'QST_wp_user' => self::get_default_creator_id(),
951
									'QST_deleted' => 0
952
								);
953
						break;
954
955 View Code Duplication
					case 'lname':
956
							$QST_values = array(
957
									'QST_display_text' => __( 'Last Name', 'event_espresso' ),
958
									'QST_admin_label' => __( 'Last Name - System Question', 'event_espresso' ),
959
									'QST_system' => 'lname',
960
									'QST_type' => 'TEXT',
961
									'QST_required' => 1,
962
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
963
									'QST_order' => 2,
964
									'QST_admin_only' => 0,
965
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
966
									'QST_wp_user' => self::get_default_creator_id(),
967
									'QST_deleted' => 0
968
								);
969
						break;
970
971 View Code Duplication
					case 'email':
972
							$QST_values = array(
973
									'QST_display_text' => __( 'Email Address', 'event_espresso' ),
974
									'QST_admin_label' => __( 'Email Address - System Question', 'event_espresso' ),
975
									'QST_system' => 'email',
976
									'QST_type' => 'TEXT',
977
									'QST_required' => 1,
978
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
979
									'QST_order' => 3,
980
									'QST_admin_only' => 0,
981
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
982
									'QST_wp_user' => self::get_default_creator_id(),
983
									'QST_deleted' => 0
984
								);
985
						break;
986
987 View Code Duplication
					case 'address':
988
							$QST_values = array(
989
									'QST_display_text' => __( 'Address', 'event_espresso' ),
990
									'QST_admin_label' => __( 'Address - System Question', 'event_espresso' ),
991
									'QST_system' => 'address',
992
									'QST_type' => 'TEXT',
993
									'QST_required' => 0,
994
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
995
									'QST_order' => 4,
996
									'QST_admin_only' => 0,
997
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
998
									'QST_wp_user' => self::get_default_creator_id(),
999
									'QST_deleted' => 0
1000
								);
1001
						break;
1002
1003 View Code Duplication
					case 'address2':
1004
							$QST_values = array(
1005
									'QST_display_text' => __( 'Address2', 'event_espresso' ),
1006
									'QST_admin_label' => __( 'Address2 - System Question', 'event_espresso' ),
1007
									'QST_system' => 'address2',
1008
									'QST_type' => 'TEXT',
1009
									'QST_required' => 0,
1010
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
1011
									'QST_order' => 5,
1012
									'QST_admin_only' => 0,
1013
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
1014
									'QST_wp_user' => self::get_default_creator_id(),
1015
									'QST_deleted' => 0
1016
								);
1017
						break;
1018
1019 View Code Duplication
					case 'city':
1020
							$QST_values = array(
1021
									'QST_display_text' => __( 'City', 'event_espresso' ),
1022
									'QST_admin_label' => __( 'City - System Question', 'event_espresso' ),
1023
									'QST_system' => 'city',
1024
									'QST_type' => 'TEXT',
1025
									'QST_required' => 0,
1026
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
1027
									'QST_order' => 6,
1028
									'QST_admin_only' => 0,
1029
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
1030
									'QST_wp_user' => self::get_default_creator_id(),
1031
									'QST_deleted' => 0
1032
								);
1033
						break;
1034
1035 View Code Duplication
					case 'state':
1036
							$QST_values = array(
1037
									'QST_display_text' => __( 'State/Province', 'event_espresso' ),
1038
									'QST_admin_label' => __( 'State/Province - System Question', 'event_espresso' ),
1039
									'QST_system' => 'state',
1040
									'QST_type' => 'STATE',
1041
									'QST_required' => 0,
1042
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
1043
									'QST_order' => 7,
1044
									'QST_admin_only' => 0,
1045
									'QST_wp_user' => self::get_default_creator_id(),
1046
									'QST_deleted' => 0
1047
								);
1048
						break;
1049
1050 View Code Duplication
					case 'country' :
1051
							$QST_values = array(
1052
									'QST_display_text' => __( 'Country', 'event_espresso' ),
1053
									'QST_admin_label' => __( 'Country - System Question', 'event_espresso' ),
1054
									'QST_system' => 'country',
1055
									'QST_type' => 'COUNTRY',
1056
									'QST_required' => 0,
1057
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
1058
									'QST_order' => 8,
1059
									'QST_admin_only' => 0,
1060
									'QST_wp_user' => self::get_default_creator_id(),
1061
									'QST_deleted' => 0
1062
								);
1063
						break;
1064
1065 View Code Duplication
					case 'zip':
1066
							$QST_values = array(
1067
									'QST_display_text' => __( 'Zip/Postal Code', 'event_espresso' ),
1068
									'QST_admin_label' => __( 'Zip/Postal Code - System Question', 'event_espresso' ),
1069
									'QST_system' => 'zip',
1070
									'QST_type' => 'TEXT',
1071
									'QST_required' => 0,
1072
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
1073
									'QST_order' => 9,
1074
									'QST_admin_only' => 0,
1075
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
1076
									'QST_wp_user' => self::get_default_creator_id(),
1077
									'QST_deleted' => 0
1078
								);
1079
						break;
1080
1081 View Code Duplication
					case 'phone':
1082
							$QST_values = array(
1083
									'QST_display_text' => __( 'Phone Number', 'event_espresso' ),
1084
									'QST_admin_label' => __( 'Phone Number - System Question', 'event_espresso' ),
1085
									'QST_system' => 'phone',
1086
									'QST_type' => 'TEXT',
1087
									'QST_required' => 0,
1088
									'QST_required_text' => __( 'This field is required', 'event_espresso' ),
1089
									'QST_order' => 10,
1090
									'QST_admin_only' => 0,
1091
									'QST_max' => EEM_Question::instance()->absolute_max_for_system_question( $QST_system ),
1092
									'QST_wp_user' => self::get_default_creator_id(),
1093
									'QST_deleted' => 0
1094
								);
1095
						break;
1096
1097
				}
1098
				if ( ! empty( $QST_values )) {
1099
					// insert system question
1100
					$wpdb->insert(
1101
						$table_name,
1102
						$QST_values,
1103
						array( '%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d' )
1104
					);
1105
					$QST_ID = $wpdb->insert_id;
1106
1107
					// QUESTION GROUP QUESTIONS
1108
					if(  in_array( $QST_system, array( 'fname', 'lname', 'email' ) ) ) {
1109
						$system_question_we_want = EEM_Question_Group::system_personal;
1110
					} else {
1111
						$system_question_we_want = EEM_Question_Group::system_address;
1112
					}
1113
					if( isset( $QSG_IDs[ $system_question_we_want ] ) ) {
1114
						$QSG_ID = $QSG_IDs[ $system_question_we_want ];
1115
					} else {
1116
						$id_col = EEM_Question_Group::instance()->get_col( array( array( 'QSG_system' => $system_question_we_want ) ) );
1117
						if( is_array( $id_col ) ) {
1118
							$QSG_ID = reset( $id_col );
1119
						} else {
1120
							//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
1121
                                                        EE_Log::instance()->log(
1122
                                                                __FILE__,
1123
                                                                __FUNCTION__,
1124
                                                                sprintf(
1125
                                                                        __( 'Could not associate question %1$s to a question group because no system question group existed', 'event_espresso'),
1126
                                                                        $QST_ID ),
1127
                                                                'error' );
1128
                                                        continue;
1129
						}
1130
					}
1131
1132
					// add system questions to groups
1133
					$wpdb->insert(
1134
						EEH_Activation::ensure_table_name_has_prefix( 'esp_question_group_question' ),
1135
						array( 'QSG_ID' => $QSG_ID , 'QST_ID' => $QST_ID, 'QGQ_order'=>($QSG_ID==1)? $order_for_group_1++ : $order_for_group_2++ ),
1136
						array( '%d', '%d','%d' )
1137
					);
1138
				}
1139
			}
1140
		}
1141
1142
	}
1143
1144
	/**
1145
	 * Makes sure the default payment method (Invoice) is active.
1146
	 * This used to be done automatically as part of constructing the old gateways config
1147
	 */
1148
	public static function insert_default_payment_methods(){
1149
		if( ! EEM_Payment_Method::instance()->count_active( EEM_Payment_Method::scope_cart ) ){
1150
			EE_Registry::instance()->load_lib( 'Payment_Method_Manager' );
1151
			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type( 'Invoice' );
1152
		}else{
1153
			EEM_Payment_Method::instance()->verify_button_urls();
1154
		}
1155
	}
1156
1157
	/**
1158
	 * insert_default_status_codes
1159
	 *
1160
	 * 	@access public
1161
	 * 	@static
1162
	 * 	@return void
1163
	 */
1164
	public static function insert_default_status_codes() {
1165
1166
		global $wpdb;
1167
1168
		if ( EEH_Activation::table_exists( EEM_Status::instance()->table() ) ) {
1169
1170
			$table_name = EEM_Status::instance()->table();
1171
1172
			$SQL = "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', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC' );";
1173
			$wpdb->query($SQL);
1174
1175
			$SQL = "INSERT INTO $table_name
1176
					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1177
					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1178
					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
1179
					('NOP', 'REGISTRATION_NOT_OPEN', 'event', 0, NULL, 1),
1180
					('OPN', 'REGISTRATION_OPEN', 'event', 0, NULL, 1),
1181
					('CLS', 'REGISTRATION_CLOSED', 'event', 0, NULL, 0),
1182
					('PND', 'PENDING', 'event', 0, NULL, 1),
1183
					('ONG', 'ONGOING', 'event', 0, NULL, 1),
1184
					('SEC', 'SECONDARY', 'event', 0, NULL, 1),
1185
					('DRF', 'DRAFT', 'event', 0, NULL, 0),
1186
					('DEL', 'DELETED', 'event', 0, NULL, 0),
1187
					('DEN', 'DENIED', 'event', 0, NULL, 0),
1188
					('EXP', 'EXPIRED', 'event', 0, NULL, 0),
1189
					('RPP', 'PENDING_PAYMENT', 'registration', 0, NULL, 1),
1190
					('RAP', 'APPROVED', 'registration', 0, NULL, 1),
1191
					('RCN', 'CANCELLED', 'registration', 0, NULL, 0),
1192
					('RDC', 'DECLINED', 'registration', 0, NULL, 0),
1193
					('RNA', 'NOT_APPROVED', 'registration', 0, NULL, 1),
1194
					('RIC', 'INCOMPLETE', 'registration', 0, NULL, 1),
1195
					('TFL', 'FAILED', 'transaction', 0, NULL, 0),
1196
					('TAB', 'ABANDONED', 'transaction', 0, NULL, 0),
1197
					('TIN', 'INCOMPLETE', 'transaction', 0, NULL, 1),
1198
					('TCM', 'COMPLETE', 'transaction', 0, NULL, 1),
1199
					('TOP',	'OVERPAID', 'transaction', 0, NULL, 1),
1200
					('PAP', 'APPROVED', 'payment', 0, NULL, 1),
1201
					('PPN', 'PENDING', 'payment', 0, NULL, 1),
1202
					('PCN', 'CANCELLED', 'payment', 0, NULL, 0),
1203
					('PFL', 'FAILED', 'payment', 0, NULL, 0),
1204
					('PDC', 'DECLINED', 'payment', 0, NULL, 0),
1205
					('EDR', 'DRAFT', 'email', 0, NULL, 0),
1206
					('ESN', 'SENT', 'email', 0, NULL, 1);";
1207
			$wpdb->query($SQL);
1208
1209
		}
1210
1211
	}
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
	/**
1226
	 * create_upload_directories
1227
	 * Creates folders in the uploads directory to facilitate addons and templates
1228
	 *
1229
	 * 	@access public
1230
	 * 	@static
1231
	 * 	@return boolean success of verifying upload directories exist
1232
	 */
1233
	public static function create_upload_directories() {
1234
		EE_Registry::instance()->load_helper( 'File' );
1235
		// Create the required folders
1236
		$folders = array(
1237
				EVENT_ESPRESSO_TEMPLATE_DIR,
1238
				EVENT_ESPRESSO_GATEWAY_DIR,
1239
				EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1240
				EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1241
				EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/'
1242
		);
1243
		foreach ( $folders as $folder ) {
1244
			try {
1245
				EEH_File::ensure_folder_exists_and_is_writable( $folder );
1246
				@ chmod( $folder, 0755 );
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1247
			} catch( EE_Error $e ){
1248
				EE_Error::add_error(
1249
					sprintf(
1250
						__(  'Could not create the folder at "%1$s" because: %2$s', 'event_espresso' ),
1251
						$folder,
1252
						'<br />' . $e->getMessage()
1253
					),
1254
					__FILE__, __FUNCTION__, __LINE__
1255
				);
1256
				//indicate we'll need to fix this later
1257
				update_option( EEH_Activation::upload_directories_incomplete_option_name, true );
1258
				return FALSE;
1259
			}
1260
		}
1261
		//just add the .htaccess file to the logs directory to begin with. Even if logging
1262
		//is disabled, there might be activation errors recorded in there
1263
		EEH_File::add_htaccess_deny_from_all( EVENT_ESPRESSO_UPLOAD_DIR . 'logs/' );
1264
		//remember EE's folders are all good
1265
		delete_option( EEH_Activation::upload_directories_incomplete_option_name );
1266
		return TRUE;
1267
	}
1268
1269
	/**
1270
	 * Whether the upload directories need to be fixed or not.
1271
	 * If EE is installed but filesystem access isn't initially available,
1272
	 * we need to get the user's filesystem credentials and THEN create them,
1273
	 * so there might be period of time when EE is installed but its
1274
	 * upload directories aren't available. This indicates such a state
1275
	 * @return boolean
1276
	 */
1277
	public static function upload_directories_incomplete() {
1278
		return get_option( EEH_Activation::upload_directories_incomplete_option_name, false );
1279
	}
1280
1281
1282
1283
1284
	/**
1285
	 * generate_default_message_templates
1286
	 *
1287
	 * 	@access public
1288
	 * 	@static
1289
	 * 	@return bool | array
1290
	 */
1291
	public static function generate_default_message_templates() {
1292
1293
		$success = FALSE;
1294
		$installed_messengers = $default_messengers = array();
1295
1296
		//include our helper
1297
		EE_Registry::instance()->load_helper( 'MSG_Template' );
1298
1299
		//get all installed messenger objects
1300
		$installed = EEH_MSG_Template::get_installed_message_objects();
1301
1302
		//let's setup the $installed messengers in an array AND the messengers that are set to be activated on install.
1303
		foreach ( $installed['messengers'] as $msgr ) {
1304
			if ( $msgr instanceof EE_messenger ) {
1305
				$installed_messengers[$msgr->name] = $msgr;
1306
				if ( $msgr->activate_on_install ) {
1307
					$default_messengers[] = $msgr->name;
1308
				}
1309
			}
1310
		}
1311
1312
		//let's determine if we've already got an active messengers option
1313
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
1314
1315
		//things that have already been activated before
1316
		$has_activated = get_option( 'ee_has_activated_messenger' );
1317
1318
		//do an initial loop to determine if we need to continue
1319
		$def_ms = array();
1320
		foreach ( $default_messengers as $msgr ) {
1321
			if ( isset($active_messengers[$msgr] ) || isset( $has_activated[$msgr] ) ) continue;
1322
			$def_ms[] = $msgr;
1323
		}
1324
1325
		//setup the $installed_mts in an array
1326
		foreach ( $installed['message_types'] as $imt ) {
1327
			if ( $imt instanceof EE_message_type ) {
1328
				$installed_mts[$imt->name] = $imt;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$installed_mts was never initialized. Although not strictly required by PHP, it is generally a good practice to add $installed_mts = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1329
			}
1330
		}
1331
1332
		//loop through default array for default messengers (if present)
1333
		if ( ! empty( $def_ms ) ) {
1334
			foreach ( $def_ms as $messenger ) {
1335
				//all is good so let's setup the default stuff. We need to use the given messenger object (if exists) to get the default message type for the messenger.
1336
				if ( ! isset( $installed_messengers[$messenger] )) {
1337
					continue;
1338
				}
1339
				/** @var EE_messenger[] $installed_messengers  */
1340
				$default_mts = $installed_messengers[$messenger]->get_default_message_types();
1341
				$active_messengers[$messenger]['obj'] = $installed_messengers[$messenger];
1342
				foreach ( $default_mts as $index => $mt ) {
1343
					//is there an installed_mt matching the default string?  If not then nothing to do here.
1344
					if ( ! isset( $installed_mts[$mt] ) ) {
1345
						unset( $default_mts[$index] );
1346
						continue;
1347
					}
1348
1349
1350
					//we need to setup any initial settings for message types
1351
					/** @var EE_message_type[] $installed_mts */
1352
					$settings_fields = $installed_mts[$mt]->get_admin_settings_fields();
1353
					$settings = array();
1354 View Code Duplication
					if ( is_array( $settings_fields ) ) {
1355
						foreach ( $settings_fields as $field => $values ) {
1356
							if ( isset( $values['default'] ) ) {
1357
								$settings[$field] = $values['default'];
1358
							}
1359
						}
1360
					}
1361
1362
					$active_messengers[$messenger]['settings'][$messenger . '-message_types'][$mt]['settings'] = $settings;
1363
					$has_activated[$messenger][] = $mt;
1364
				}
1365
1366
				//setup any initial settings for the messenger
1367
				$msgr_settings = $installed_messengers[$messenger]->get_admin_settings_fields();
1368
1369 View Code Duplication
				if ( !empty( $msgr_settings ) ) {
1370
					foreach ( $msgr_settings as $field => $value ) {
1371
						$active_messengers[$messenger]['settings'][$field] = $value;
1372
					}
1373
				}
1374
1375
				//now let's save the settings for this messenger! Must do now because the validator checks the db for active messengers to validate.
1376
				EEH_MSG_Template::update_active_messengers_in_db( $active_messengers );
1377
1378
				//let's generate all the templates but only if the messenger has default_mts (otherwise its just activated).
1379
				if ( !empty( $default_mts ) ) {
1380
					$success = EEH_MSG_Template::generate_new_templates( $messenger, $default_mts, '', TRUE );
1381
				}
1382
			}
1383
		} //end check for empty( $def_ms )
1384
1385
		//still need to see if there are any message types to activate for active messengers
1386
		foreach ( $active_messengers as $messenger => $settings ) {
1387
			$msg_obj = $settings['obj'];
1388
			if ( ! $msg_obj instanceof EE_messenger ) {
1389
				continue;
1390
			}
1391
1392
			$all_default_mts = $msg_obj->get_default_message_types();
1393
			$new_default_mts = array();
1394
1395
			//loop through each default mt reported by the messenger and make sure its set in its active db entry.
1396
			foreach( $all_default_mts as $index => $mt ) {
1397
				//already active? already has generated templates? || has already been activated before (we dont' want to reactivate things users intentionally deactivated).
1398
				if ( ( isset( $has_activated[$messenger] ) && in_array($mt, $has_activated[$messenger]) ) || isset( $active_messengers[$messenger]['settings'][$messenger . '-message_types'][$mt] ) ||  EEH_MSG_Template::already_generated( $messenger, $mt, 0, FALSE ) ) {
1399
					continue;
1400
				}
1401
1402
				//is there an installed_mt matching the default string?  If not then nothing to do here.
1403
				if ( ! isset( $installed_mts[$mt] ) ) {
1404
					unset( $all_default_mts[$mt] );
1405
					continue;
1406
				}
1407
1408
				$settings_fields = $installed_mts[$mt]->get_admin_settings_fields();
1409
				$settings = array();
1410 View Code Duplication
				if ( is_array( $settings_fields ) ) {
1411
					foreach ( $settings_fields as $field => $values ) {
1412
						if ( isset( $values['default'] ) ) {
1413
							$settings[$field] = $values['default'];
1414
						}
1415
					}
1416
				}
1417
1418
				$active_messengers[$messenger]['settings'][$messenger . '-message_types'][$mt]['settings'] = $settings;
1419
				$new_default_mts[] = $mt;
1420
				$has_activated[$messenger][] = $mt;
1421
			}
1422
1423
1424
			if ( ! empty( $new_default_mts ) ) {
1425
				$success = EEH_MSG_Template::generate_new_templates( $messenger, $new_default_mts, '', TRUE );
1426
			}
1427
1428
		}
1429
1430
		//now let's save the settings for this messenger!
1431
		EEH_MSG_Template::update_active_messengers_in_db( $active_messengers );
1432
1433
		//update $has_activated record
1434
		update_option( 'ee_has_activated_messenger', $has_activated );
1435
1436
		//that's it!
1437
		return $success;
1438
	}
1439
1440
1441
1442
1443
1444
1445
	/**
1446
	 * This simply validates active messengers and message types to ensure they actually match installed messengers and message types.  If there's a mismatch then we deactivate the messenger/message type and ensure all related db rows are set inactive.
1447
	 *
1448
	 * @since 4.3.1
1449
	 *
1450
	 * @return void
1451
	 */
1452
	public static function validate_messages_system() {
1453
		//include our helper
1454
		EE_Registry::instance()->load_helper( 'MSG_Template' );
1455
1456
		//get active and installed  messengers/message types.
1457
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
1458
		$installed = EEH_MSG_Template::get_installed_message_objects();
1459
		$installed_messengers = $installed_mts = array();
1460
		//set up the arrays so they can be handled easier.
1461
		foreach( $installed['messengers'] as $im ) {
1462
			if ( $im instanceof EE_messenger ) {
1463
				$installed_messengers[$im->name] = $im;
1464
			}
1465
		}
1466
		foreach( $installed['message_types'] as $imt ) {
1467
			if ( $imt instanceof EE_message_type ) {
1468
				$installed_mts[$imt->name] = $imt;
1469
			}
1470
		}
1471
1472
		//now let's loop through the active array and validate
1473
		foreach( $active_messengers as $messenger => $active_details ) {
1474
			//first let's see if this messenger is installed.
1475
			if ( ! isset( $installed_messengers[$messenger] ) ) {
1476
				//not set so let's just remove from actives and make sure templates are inactive.
1477
				unset( $active_messengers[$messenger] );
1478
				EEH_MSG_Template::update_to_inactive( $messenger );
1479
				continue;
1480
			}
1481
1482
			//messenger is active, so let's just make sure that any active message types not installed are deactivated.
1483
			$mts = ! empty( $active_details['settings'][$messenger . '-message_types'] ) ? $active_details['settings'][$messenger . '-message_types'] : array();
1484
			foreach ( $mts as $mt_name => $mt ) {
1485
				if ( ! isset( $installed_mts[$mt_name] )  ) {
1486
					unset( $active_messengers[$messenger]['settings'][$messenger . '-message_types'][$mt_name] );
1487
					EEH_MSG_Template::update_to_inactive( $messenger, $mt_name );
1488
				}
1489
			}
1490
		}
1491
1492
		//all done! let's update the active_messengers.
1493
		EEH_MSG_Template::update_active_messengers_in_db( $active_messengers );
1494
		do_action( 'AHEE__EEH_Activation__validate_messages_system' );
1495
		return;
1496
	}
1497
1498
1499
1500
1501
	/**
1502
	 * create_no_ticket_prices_array
1503
	 *
1504
	 * 	@access public
1505
	 * 	@static
1506
	 * 	@return void
1507
	 */
1508
	public static function create_no_ticket_prices_array(){
1509
		// this creates an array for tracking events that have no active ticket prices created
1510
		// this allows us to warn admins of the situation so that it can be corrected
1511
		$espresso_no_ticket_prices = get_option( 'ee_no_ticket_prices', FALSE );
1512
		if ( ! $espresso_no_ticket_prices ) {
1513
			add_option( 'ee_no_ticket_prices', array(), '', FALSE );
1514
		}
1515
	}
1516
1517
1518
1519
	/**
1520
	 * plugin_deactivation
1521
	 *
1522
	 * 	@access public
1523
	 * 	@static
1524
	 * 	@return void
1525
	 */
1526
	public static function plugin_deactivation() {
1527
	}
1528
1529
1530
1531
	/**
1532
	 * Finds all our EE4 custom post types, and deletes them and their associated data (like post meta or term relations)/
1533
	 * @global wpdb $wpdb
1534
	 */
1535
	public static function delete_all_espresso_cpt_data(){
1536
		global $wpdb;
1537
		//get all the CPT post_types
1538
		$ee_post_types = array();
1539
		foreach(EE_Registry::instance()->non_abstract_db_models as $model_name){
1540
			if ( method_exists( $model_name, 'instance' )) {
1541
				$model_obj = call_user_func( array( $model_name, 'instance' ));
1542
				if ( $model_obj instanceof EEM_CPT_Base ) {
1543
					$ee_post_types[] = $wpdb->prepare("%s",$model_obj->post_type());
1544
				}
1545
			}
1546
		}
1547
		//get all our CPTs
1548
		$query = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (".implode(",",$ee_post_types).")";
1549
		$cpt_ids = $wpdb->get_col($query);
1550
		//delete each post meta and term relations too
1551
		foreach($cpt_ids as $post_id){
1552
			wp_delete_post($post_id,true);
1553
		}
1554
	}
1555
1556
1557
1558
	/**
1559
	 * plugin_uninstall
1560
	 *
1561
	 * @access public
1562
	 * @static
1563
	 * @param bool $remove_all
1564
	 * @return void
1565
	 */
1566
	public static function delete_all_espresso_tables_and_data( $remove_all = true ) {
1567
		global $wpdb;
1568
		$undeleted_tables = array();
1569
1570
		// load registry
1571
		foreach( EE_Registry::instance()->non_abstract_db_models as $model_name ){
1572
			if ( method_exists( $model_name, 'instance' )) {
1573
				$model_obj = call_user_func( array( $model_name, 'instance' ));
1574
				if ( $model_obj instanceof EEM_Base ) {
1575
					foreach ( $model_obj->get_tables() as $table ) {
1576
						if ( strpos( $table->get_table_name(), 'esp_' )) {
1577
							switch ( EEH_Activation::delete_unused_db_table( $table->get_table_name() )) {
1578
								case false :
1579
									$undeleted_tables[] = $table->get_table_name();
1580
								break;
1581
								case 0 :
1582
									// echo '<h4 style="color:red;">the table : ' . $table->get_table_name() . ' was not deleted  <br /></h4>';
1583
								break;
1584
								default:
1585
									// echo '<h4>the table : ' . $table->get_table_name() . ' was deleted successfully <br /></h4>';
1586
							}
1587
						}
1588
					}
1589
				}
1590
			}
1591
		}
1592
1593
		//there are some tables whose models were removed.
1594
		//they should be removed when removing all EE core's data
1595
		$tables_without_models = array(
1596
			'esp_promotion',
1597
			'esp_promotion_applied',
1598
			'esp_promotion_object',
1599
			'esp_promotion_rule',
1600
			'esp_rule'
1601
		);
1602
		foreach( $tables_without_models as $table ){
1603
			EEH_Activation::delete_db_table_if_empty( $table );
1604
		}
1605
1606
1607
		$wp_options_to_delete = array(
1608
			'ee_no_ticket_prices' => true,
1609
			'ee_active_messengers' => true,
1610
			'ee_has_activated_messenger' => true,
1611
			'ee_flush_rewrite_rules' => true,
1612
			'ee_config' => false,
1613
			'ee_data_migration_current_db_state' => true,
1614
			'ee_data_migration_mapping_' => false,
1615
			'ee_data_migration_script_' => false,
1616
			'ee_data_migrations' => true,
1617
			'ee_dms_map' => false,
1618
			'ee_notices' => true,
1619
			'lang_file_check_' => false,
1620
			'ee_maintenance_mode' => true,
1621
			'ee_ueip_optin' => true,
1622
			'ee_ueip_has_notified' => true,
1623
			'ee_plugin_activation_errors' => true,
1624
			'ee_id_mapping_from' => false,
1625
			'espresso_persistent_admin_notices' => true,
1626
			'ee_encryption_key' => true,
1627
			'pue_force_upgrade_' => false,
1628
			'pue_json_error_' => false,
1629
			'pue_install_key_' => false,
1630
			'pue_verification_error_' => false,
1631
			'pu_dismissed_upgrade_' => false,
1632
			'external_updates-' => false,
1633
			'ee_extra_data' => true,
1634
			'ee_ssn_' => false,
1635
			'ee_rss_' => false,
1636
			'ee_rte_n_tx_' => false,
1637
			'ee_pers_admin_notices' => true,
1638
			'ee_job_parameters_' => false,
1639
			'ee_upload_directories_incomplete' => true,
1640
		);
1641
		if( is_main_site() ) {
1642
			$wp_options_to_delete[ 'ee_network_config' ] = true;
1643
		}
1644
1645
		$undeleted_options = array();
1646
		foreach ( $wp_options_to_delete as $option_name => $no_wildcard ) {
1647
1648
			if( $no_wildcard ){
1649
				if( ! delete_option( $option_name ) ){
1650
					$undeleted_options[] = $option_name;
1651
				}
1652
			}else{
1653
				$option_names_to_delete_from_wildcard = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'" );
1654
				foreach($option_names_to_delete_from_wildcard as $option_name_from_wildcard ){
1655
					if( ! delete_option( $option_name_from_wildcard ) ){
1656
						$undeleted_options[] = $option_name_from_wildcard;
1657
					}
1658
				}
1659
			}
1660
		}
1661
                //also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1662
                remove_action( 'shutdown', array( EE_Config::instance(), 'shutdown' ), 10 );
1663
1664
		if ( $remove_all && $espresso_db_update = get_option( 'espresso_db_update' )) {
1665
			$db_update_sans_ee4 = array();
1666
			foreach($espresso_db_update as $version => $times_activated){
1667
				if( $version[0] =='3'){//if its NON EE4
1668
					$db_update_sans_ee4[$version] = $times_activated;
1669
				}
1670
			}
1671
			update_option( 'espresso_db_update', $db_update_sans_ee4 );
1672
		}
1673
1674
		$errors = '';
1675
		if ( ! empty( $undeleted_tables )) {
1676
			$errors .= sprintf(
1677
				__( 'The following tables could not be deleted: %s%s', 'event_espresso' ),
1678
				'<br/>',
1679
				implode( ',<br/>', $undeleted_tables )
1680
			);
1681
		}
1682
		if ( ! empty( $undeleted_options )) {
1683
			$errors .= ! empty( $undeleted_tables ) ? '<br/>' : '';
1684
			$errors .= sprintf(
1685
				__( 'The following wp-options could not be deleted: %s%s', 'event_espresso' ),
1686
				'<br/>',
1687
				implode( ',<br/>', $undeleted_options )
1688
			);
1689
1690
		}
1691
		if ( $errors != '' ) {
1692
			EE_Error::add_attention( $errors, __FILE__, __FUNCTION__, __LINE__ );
1693
		}
1694
	}
1695
1696
	/**
1697
	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1698
	 * @global wpdb $wpdb
1699
	 * @param string $table_name with or without $wpdb->prefix
1700
	 * @return boolean
1701
	 */
1702
	public static function table_exists( $table_name ){
1703
		global $wpdb, $EZSQL_ERROR;
1704
		$table_name = EEH_Activation::ensure_table_name_has_prefix( $table_name );
1705
		//ignore if this causes an sql error
1706
		$old_error = $wpdb->last_error;
1707
		$old_suppress_errors = $wpdb->suppress_errors();
1708
		$old_show_errors_value = $wpdb->show_errors( FALSE );
1709
		$ezsql_error_cache = $EZSQL_ERROR;
1710
		$wpdb->get_results( "SELECT * from $table_name LIMIT 1");
1711
		$wpdb->show_errors( $old_show_errors_value );
1712
		$wpdb->suppress_errors( $old_suppress_errors );
1713
		$new_error = $wpdb->last_error;
1714
		$wpdb->last_error = $old_error;
1715
		$EZSQL_ERROR = $ezsql_error_cache;
1716
		if( empty( $new_error ) ){
1717
			return TRUE;
1718
		}else{
1719
			return FALSE;
1720
		}
1721
	}
1722
1723
	/**
1724
	 * Resets the cache on EEH_Activation
1725
	 */
1726
	public static function reset(){
1727
		self::$_default_creator_id = NULL;
1728
		self::$_initialized_db_content_already_in_this_request = false;
1729
	}
1730
}
1731
// End of file EEH_Activation.helper.php
1732
// Location: /helpers/EEH_Activation.core.php
1733