Completed
Branch BUG-10434-reg-cancel-shortcode... (f76056)
by
unknown
14:04
created
core/helpers/EEH_Activation.helper.php 1 patch
Indentation   +1711 added lines, -1711 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -14,243 +14,243 @@  discard block
 block discarded – undo
14 14
 class EEH_Activation
15 15
 {
16 16
 
17
-    /**
18
-     * constant used to indicate a cron task is no longer in use
19
-     */
20
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
21
-
22
-    /**
23
-     * option name that will indicate whether or not we still
24
-     * need to create EE's folders in the uploads directory
25
-     * (because if EE was installed without file system access,
26
-     * we need to request credentials before we can create them)
27
-     */
28
-    const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
29
-
30
-    /**
31
-     * WP_User->ID
32
-     *
33
-     * @var int
34
-     */
35
-    private static $_default_creator_id;
36
-
37
-    /**
38
-     * indicates whether or not we've already verified core's default data during this request,
39
-     * because after migrations are done, any addons activated while in maintenance mode
40
-     * will want to setup their own default data, and they might hook into core's default data
41
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
42
-     * This prevents doing that for EVERY single addon.
43
-     *
44
-     * @var boolean
45
-     */
46
-    protected static $_initialized_db_content_already_in_this_request = false;
47
-
48
-    /**
49
-     * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
50
-     */
51
-    private static $table_analysis;
52
-
53
-    /**
54
-     * @var \EventEspresso\core\services\database\TableManager $table_manager
55
-     */
56
-    private static $table_manager;
57
-
58
-
59
-    /**
60
-     * @return \EventEspresso\core\services\database\TableAnalysis
61
-     */
62
-    public static function getTableAnalysis()
63
-    {
64
-        if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
65
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
66
-        }
67
-        return self::$table_analysis;
68
-    }
69
-
70
-
71
-    /**
72
-     * @return \EventEspresso\core\services\database\TableManager
73
-     */
74
-    public static function getTableManager()
75
-    {
76
-        if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
77
-            self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
78
-        }
79
-        return self::$table_manager;
80
-    }
81
-
82
-
83
-    /**
84
-     *    _ensure_table_name_has_prefix
85
-     *
86
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
-     * @access     public
88
-     * @static
89
-     * @param $table_name
90
-     * @return string
91
-     */
92
-    public static function ensure_table_name_has_prefix($table_name)
93
-    {
94
-        return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
95
-    }
96
-
97
-
98
-    /**
99
-     *    system_initialization
100
-     *    ensures the EE configuration settings are loaded with at least default options set
101
-     *    and that all critical EE pages have been generated with the appropriate shortcodes in place
102
-     *
103
-     * @access public
104
-     * @static
105
-     * @return void
106
-     */
107
-    public static function system_initialization()
108
-    {
109
-        EEH_Activation::reset_and_update_config();
110
-        //which is fired BEFORE activation of plugin anyways
111
-        EEH_Activation::verify_default_pages_exist();
112
-    }
113
-
114
-
115
-    /**
116
-     * Sets the database schema and creates folders. This should
117
-     * be called on plugin activation and reactivation
118
-     *
119
-     * @return boolean success, whether the database and folders are setup properly
120
-     * @throws \EE_Error
121
-     */
122
-    public static function initialize_db_and_folders()
123
-    {
124
-        $good_filesystem = EEH_Activation::create_upload_directories();
125
-        $good_db         = EEH_Activation::create_database_tables();
126
-        return $good_filesystem && $good_db;
127
-    }
128
-
129
-
130
-    /**
131
-     * assuming we have an up-to-date database schema, this will populate it
132
-     * with default and initial data. This should be called
133
-     * upon activation of a new plugin, reactivation, and at the end
134
-     * of running migration scripts
135
-     *
136
-     * @throws \EE_Error
137
-     */
138
-    public static function initialize_db_content()
139
-    {
140
-        //let's avoid doing all this logic repeatedly, especially when addons are requesting it
141
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
142
-            return;
143
-        }
144
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
145
-
146
-        EEH_Activation::initialize_system_questions();
147
-        EEH_Activation::insert_default_status_codes();
148
-        EEH_Activation::generate_default_message_templates();
149
-        EEH_Activation::create_no_ticket_prices_array();
150
-        EE_Registry::instance()->CAP->init_caps();
151
-
152
-        EEH_Activation::validate_messages_system();
153
-        EEH_Activation::insert_default_payment_methods();
154
-        //in case we've
155
-        EEH_Activation::remove_cron_tasks();
156
-        EEH_Activation::create_cron_tasks();
157
-        // remove all TXN locks since that is being done via extra meta now
158
-        delete_option('ee_locked_transactions');
159
-        //also, check for CAF default db content
160
-        do_action('AHEE__EEH_Activation__initialize_db_content');
161
-        //also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
162
-        //which users really won't care about on initial activation
163
-        EE_Error::overwrite_success();
164
-    }
165
-
166
-
167
-    /**
168
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
169
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
170
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
171
-     * (null)
172
-     *
173
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
174
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
175
-     * @return array
176
-     * @throws \EE_Error
177
-     */
178
-    public static function get_cron_tasks($which_to_include)
179
-    {
180
-        $cron_tasks = apply_filters(
181
-            'FHEE__EEH_Activation__get_cron_tasks',
182
-            array(
183
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
17
+	/**
18
+	 * constant used to indicate a cron task is no longer in use
19
+	 */
20
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
21
+
22
+	/**
23
+	 * option name that will indicate whether or not we still
24
+	 * need to create EE's folders in the uploads directory
25
+	 * (because if EE was installed without file system access,
26
+	 * we need to request credentials before we can create them)
27
+	 */
28
+	const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
29
+
30
+	/**
31
+	 * WP_User->ID
32
+	 *
33
+	 * @var int
34
+	 */
35
+	private static $_default_creator_id;
36
+
37
+	/**
38
+	 * indicates whether or not we've already verified core's default data during this request,
39
+	 * because after migrations are done, any addons activated while in maintenance mode
40
+	 * will want to setup their own default data, and they might hook into core's default data
41
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
42
+	 * This prevents doing that for EVERY single addon.
43
+	 *
44
+	 * @var boolean
45
+	 */
46
+	protected static $_initialized_db_content_already_in_this_request = false;
47
+
48
+	/**
49
+	 * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
50
+	 */
51
+	private static $table_analysis;
52
+
53
+	/**
54
+	 * @var \EventEspresso\core\services\database\TableManager $table_manager
55
+	 */
56
+	private static $table_manager;
57
+
58
+
59
+	/**
60
+	 * @return \EventEspresso\core\services\database\TableAnalysis
61
+	 */
62
+	public static function getTableAnalysis()
63
+	{
64
+		if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
65
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
66
+		}
67
+		return self::$table_analysis;
68
+	}
69
+
70
+
71
+	/**
72
+	 * @return \EventEspresso\core\services\database\TableManager
73
+	 */
74
+	public static function getTableManager()
75
+	{
76
+		if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
77
+			self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
78
+		}
79
+		return self::$table_manager;
80
+	}
81
+
82
+
83
+	/**
84
+	 *    _ensure_table_name_has_prefix
85
+	 *
86
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
+	 * @access     public
88
+	 * @static
89
+	 * @param $table_name
90
+	 * @return string
91
+	 */
92
+	public static function ensure_table_name_has_prefix($table_name)
93
+	{
94
+		return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
95
+	}
96
+
97
+
98
+	/**
99
+	 *    system_initialization
100
+	 *    ensures the EE configuration settings are loaded with at least default options set
101
+	 *    and that all critical EE pages have been generated with the appropriate shortcodes in place
102
+	 *
103
+	 * @access public
104
+	 * @static
105
+	 * @return void
106
+	 */
107
+	public static function system_initialization()
108
+	{
109
+		EEH_Activation::reset_and_update_config();
110
+		//which is fired BEFORE activation of plugin anyways
111
+		EEH_Activation::verify_default_pages_exist();
112
+	}
113
+
114
+
115
+	/**
116
+	 * Sets the database schema and creates folders. This should
117
+	 * be called on plugin activation and reactivation
118
+	 *
119
+	 * @return boolean success, whether the database and folders are setup properly
120
+	 * @throws \EE_Error
121
+	 */
122
+	public static function initialize_db_and_folders()
123
+	{
124
+		$good_filesystem = EEH_Activation::create_upload_directories();
125
+		$good_db         = EEH_Activation::create_database_tables();
126
+		return $good_filesystem && $good_db;
127
+	}
128
+
129
+
130
+	/**
131
+	 * assuming we have an up-to-date database schema, this will populate it
132
+	 * with default and initial data. This should be called
133
+	 * upon activation of a new plugin, reactivation, and at the end
134
+	 * of running migration scripts
135
+	 *
136
+	 * @throws \EE_Error
137
+	 */
138
+	public static function initialize_db_content()
139
+	{
140
+		//let's avoid doing all this logic repeatedly, especially when addons are requesting it
141
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
142
+			return;
143
+		}
144
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
145
+
146
+		EEH_Activation::initialize_system_questions();
147
+		EEH_Activation::insert_default_status_codes();
148
+		EEH_Activation::generate_default_message_templates();
149
+		EEH_Activation::create_no_ticket_prices_array();
150
+		EE_Registry::instance()->CAP->init_caps();
151
+
152
+		EEH_Activation::validate_messages_system();
153
+		EEH_Activation::insert_default_payment_methods();
154
+		//in case we've
155
+		EEH_Activation::remove_cron_tasks();
156
+		EEH_Activation::create_cron_tasks();
157
+		// remove all TXN locks since that is being done via extra meta now
158
+		delete_option('ee_locked_transactions');
159
+		//also, check for CAF default db content
160
+		do_action('AHEE__EEH_Activation__initialize_db_content');
161
+		//also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
162
+		//which users really won't care about on initial activation
163
+		EE_Error::overwrite_success();
164
+	}
165
+
166
+
167
+	/**
168
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
169
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
170
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
171
+	 * (null)
172
+	 *
173
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
174
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
175
+	 * @return array
176
+	 * @throws \EE_Error
177
+	 */
178
+	public static function get_cron_tasks($which_to_include)
179
+	{
180
+		$cron_tasks = apply_filters(
181
+			'FHEE__EEH_Activation__get_cron_tasks',
182
+			array(
183
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
184 184
 //				'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
185
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
186
-                //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
187
-            )
188
-        );
189
-        if ($which_to_include === 'old') {
190
-            $cron_tasks = array_filter(
191
-                $cron_tasks,
192
-                function ($value) {
193
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
194
-                }
195
-            );
196
-        } elseif ($which_to_include === 'current') {
197
-            $cron_tasks = array_filter($cron_tasks);
198
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
199
-            throw new EE_Error(
200
-                sprintf(
201
-                    __(
202
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
203
-                        'event_espresso'
204
-                    ),
205
-                    $which_to_include
206
-                )
207
-            );
208
-        }
209
-        return $cron_tasks;
210
-    }
211
-
212
-
213
-    /**
214
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
215
-     *
216
-     * @throws \EE_Error
217
-     */
218
-    public static function create_cron_tasks()
219
-    {
220
-
221
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
222
-            if (! wp_next_scheduled($hook_name)) {
223
-                /**
224
-                 * This allows client code to define the initial start timestamp for this schedule.
225
-                 */
226
-                if (is_array($frequency)
227
-                    && count($frequency) === 2
228
-                    && isset($frequency[0], $frequency[1])
229
-                ) {
230
-                    $start_timestamp = $frequency[0];
231
-                    $frequency = $frequency[1];
232
-                } else {
233
-                    $start_timestamp = time();
234
-                }
235
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
236
-            }
237
-        }
238
-
239
-    }
240
-
241
-
242
-    /**
243
-     * Remove the currently-existing and now-removed cron tasks.
244
-     *
245
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
246
-     * @throws \EE_Error
247
-     */
248
-    public static function remove_cron_tasks($remove_all = true)
249
-    {
250
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
251
-        $crons                = _get_cron_array();
252
-        $crons                = is_array($crons) ? $crons : array();
253
-        /* reminder of what $crons look like:
185
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
186
+				//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
187
+			)
188
+		);
189
+		if ($which_to_include === 'old') {
190
+			$cron_tasks = array_filter(
191
+				$cron_tasks,
192
+				function ($value) {
193
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
194
+				}
195
+			);
196
+		} elseif ($which_to_include === 'current') {
197
+			$cron_tasks = array_filter($cron_tasks);
198
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
199
+			throw new EE_Error(
200
+				sprintf(
201
+					__(
202
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
203
+						'event_espresso'
204
+					),
205
+					$which_to_include
206
+				)
207
+			);
208
+		}
209
+		return $cron_tasks;
210
+	}
211
+
212
+
213
+	/**
214
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
215
+	 *
216
+	 * @throws \EE_Error
217
+	 */
218
+	public static function create_cron_tasks()
219
+	{
220
+
221
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
222
+			if (! wp_next_scheduled($hook_name)) {
223
+				/**
224
+				 * This allows client code to define the initial start timestamp for this schedule.
225
+				 */
226
+				if (is_array($frequency)
227
+					&& count($frequency) === 2
228
+					&& isset($frequency[0], $frequency[1])
229
+				) {
230
+					$start_timestamp = $frequency[0];
231
+					$frequency = $frequency[1];
232
+				} else {
233
+					$start_timestamp = time();
234
+				}
235
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
236
+			}
237
+		}
238
+
239
+	}
240
+
241
+
242
+	/**
243
+	 * Remove the currently-existing and now-removed cron tasks.
244
+	 *
245
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
246
+	 * @throws \EE_Error
247
+	 */
248
+	public static function remove_cron_tasks($remove_all = true)
249
+	{
250
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
251
+		$crons                = _get_cron_array();
252
+		$crons                = is_array($crons) ? $crons : array();
253
+		/* reminder of what $crons look like:
254 254
          * Top-level keys are timestamps, and their values are arrays.
255 255
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
256 256
          * and their values are arrays.
@@ -267,971 +267,971 @@  discard block
 block discarded – undo
267 267
          *					...
268 268
          *      ...
269 269
          */
270
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
271
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
272
-            if (is_array($hooks_to_fire_at_time)) {
273
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
274
-                    if (isset($ee_cron_tasks_to_remove[$hook_name])
275
-                        && is_array($ee_cron_tasks_to_remove[$hook_name])
276
-                    ) {
277
-                        unset($crons[$timestamp][$hook_name]);
278
-                    }
279
-                }
280
-                //also take care of any empty cron timestamps.
281
-                if (empty($hooks_to_fire_at_time)) {
282
-                    unset($crons[$timestamp]);
283
-                }
284
-            }
285
-        }
286
-        _set_cron_array($crons);
287
-    }
288
-
289
-
290
-    /**
291
-     *    CPT_initialization
292
-     *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
293
-     *
294
-     * @access public
295
-     * @static
296
-     * @return void
297
-     */
298
-    public static function CPT_initialization()
299
-    {
300
-        // register Custom Post Types
301
-        EE_Registry::instance()->load_core('Register_CPTs');
302
-        flush_rewrite_rules();
303
-    }
304
-
305
-
306
-
307
-    /**
308
-     *    reset_and_update_config
309
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
310
-     * If there is old calendar config data saved, then it will get converted on activation.
311
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
312
-     *
313
-     * @access public
314
-     * @static
315
-     * @return void
316
-     */
317
-    public static function reset_and_update_config()
318
-    {
319
-        do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
320
-        add_filter(
321
-            'FHEE__EE_Config___load_core_config__config_settings',
322
-            array('EEH_Activation', 'migrate_old_config_data'),
323
-            10,
324
-            3
325
-        );
326
-        //EE_Config::reset();
327
-        if (! EE_Config::logging_enabled()) {
328
-            delete_option(EE_Config::LOG_NAME);
329
-        }
330
-    }
331
-
332
-
333
-    /**
334
-     *    load_calendar_config
335
-     *
336
-     * @access    public
337
-     * @return    void
338
-     */
339
-    public static function load_calendar_config()
340
-    {
341
-        // grab array of all plugin folders and loop thru it
342
-        $plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
343
-        if (empty($plugins)) {
344
-            return;
345
-        }
346
-        foreach ($plugins as $plugin_path) {
347
-            // grab plugin folder name from path
348
-            $plugin = basename($plugin_path);
349
-            // drill down to Espresso plugins
350
-            // then to calendar related plugins
351
-            if (
352
-                strpos($plugin, 'espresso') !== false
353
-                || strpos($plugin, 'Espresso') !== false
354
-                || strpos($plugin, 'ee4') !== false
355
-                || strpos($plugin, 'EE4') !== false
356
-                || strpos($plugin, 'calendar') !== false
357
-            ) {
358
-                // this is what we are looking for
359
-                $calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
360
-                // does it exist in this folder ?
361
-                if (is_readable($calendar_config)) {
362
-                    // YEAH! let's load it
363
-                    require_once($calendar_config);
364
-                }
365
-            }
366
-        }
367
-    }
368
-
369
-
370
-
371
-    /**
372
-     *    _migrate_old_config_data
373
-     *
374
-     * @access    public
375
-     * @param array|stdClass $settings
376
-     * @param string         $config
377
-     * @param \EE_Config     $EE_Config
378
-     * @return \stdClass
379
-     */
380
-    public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
381
-    {
382
-        $convert_from_array = array('addons');
383
-        // in case old settings were saved as an array
384
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
385
-            // convert existing settings to an object
386
-            $config_array = $settings;
387
-            $settings = new stdClass();
388
-            foreach ($config_array as $key => $value) {
389
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
390
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
391
-                } else {
392
-                    $settings->{$key} = $value;
393
-                }
394
-            }
395
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
396
-        }
397
-        return $settings;
398
-    }
399
-
400
-
401
-    /**
402
-     * deactivate_event_espresso
403
-     *
404
-     * @access public
405
-     * @static
406
-     * @return void
407
-     */
408
-    public static function deactivate_event_espresso()
409
-    {
410
-        // check permissions
411
-        if (current_user_can('activate_plugins')) {
412
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
413
-        }
414
-    }
415
-
416
-
417
-
418
-
419
-
420
-    /**
421
-     * verify_default_pages_exist
422
-     *
423
-     * @access public
424
-     * @static
425
-     * @return void
426
-     */
427
-    public static function verify_default_pages_exist()
428
-    {
429
-        $critical_page_problem = false;
430
-        $critical_pages = array(
431
-            array(
432
-                'id'   => 'reg_page_id',
433
-                'name' => __('Registration Checkout', 'event_espresso'),
434
-                'post' => null,
435
-                'code' => 'ESPRESSO_CHECKOUT',
436
-            ),
437
-            array(
438
-                'id'   => 'txn_page_id',
439
-                'name' => __('Transactions', 'event_espresso'),
440
-                'post' => null,
441
-                'code' => 'ESPRESSO_TXN_PAGE',
442
-            ),
443
-            array(
444
-                'id'   => 'thank_you_page_id',
445
-                'name' => __('Thank You', 'event_espresso'),
446
-                'post' => null,
447
-                'code' => 'ESPRESSO_THANK_YOU',
448
-            ),
449
-            array(
450
-                'id'   => 'cancel_page_id',
451
-                'name' => __('Registration Cancelled', 'event_espresso'),
452
-                'post' => null,
453
-                'code' => 'ESPRESSO_CANCELLED',
454
-            ),
455
-        );
456
-        $EE_Core_Config = EE_Registry::instance()->CFG->core;
457
-        foreach ($critical_pages as $critical_page) {
458
-            // is critical page ID set in config ?
459
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
460
-                // attempt to find post by ID
461
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
462
-            }
463
-            // no dice?
464
-            if ($critical_page['post'] === null) {
465
-                // attempt to find post by title
466
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
467
-                // still nothing?
468
-                if ($critical_page['post'] === null) {
469
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
470
-                    // REALLY? Still nothing ??!?!?
471
-                    if ($critical_page['post'] === null) {
472
-                        $msg = __(
473
-                            'The Event Espresso critical page configuration settings could not be updated.',
474
-                            'event_espresso'
475
-                        );
476
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
477
-                        break;
478
-                    }
479
-                }
480
-            }
481
-            // track post_shortcodes
482
-            if ($critical_page['post']) {
483
-                EEH_Activation::_track_critical_page_post_shortcodes($critical_page);
484
-            }
485
-            // check that Post ID matches critical page ID in config
486
-            if (
487
-                isset($critical_page['post']->ID)
488
-                && $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
489
-            ) {
490
-                //update Config with post ID
491
-                $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
492
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
493
-                    $msg = __(
494
-                        'The Event Espresso critical page configuration settings could not be updated.',
495
-                        'event_espresso'
496
-                    );
497
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
498
-                }
499
-            }
500
-            $critical_page_problem =
501
-                ! isset($critical_page['post']->post_status)
502
-                || $critical_page['post']->post_status !== 'publish'
503
-                || strpos($critical_page['post']->post_content, $critical_page['code']) === false
504
-                    ? true
505
-                    : $critical_page_problem;
506
-        }
507
-        if ($critical_page_problem) {
508
-            $msg = sprintf(
509
-                __(
510
-                    'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
511
-                    'event_espresso'
512
-                ),
513
-                '<a href="'
514
-                . admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
515
-                . '">'
516
-                . __('Event Espresso Critical Pages Settings', 'event_espresso')
517
-                . '</a>'
518
-            );
519
-            EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
520
-        }
521
-        if (EE_Error::has_notices()) {
522
-            EE_Error::get_notices(false, true, true);
523
-        }
524
-    }
525
-
526
-
527
-
528
-    /**
529
-     * Returns the first post which uses the specified shortcode
530
-     *
531
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
532
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
533
-     *                             "[ESPRESSO_THANK_YOU"
534
-     *                             (we don't search for the closing shortcode bracket because they might have added
535
-     *                             parameter to the shortcode
536
-     * @return WP_Post or NULl
537
-     */
538
-    public static function get_page_by_ee_shortcode($ee_shortcode)
539
-    {
540
-        global $wpdb;
541
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
542
-        $post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
543
-        if ($post_id) {
544
-            return get_post($post_id);
545
-        } else {
546
-            return null;
547
-        }
548
-    }
549
-
550
-
551
-    /**
552
-     *    This function generates a post for critical espresso pages
553
-     *
554
-     * @access public
555
-     * @static
556
-     * @param array $critical_page
557
-     * @return array
558
-     */
559
-    public static function create_critical_page($critical_page)
560
-    {
561
-
562
-        $post_args = array(
563
-            'post_title'     => $critical_page['name'],
564
-            'post_status'    => 'publish',
565
-            'post_type'      => 'page',
566
-            'comment_status' => 'closed',
567
-            'post_content'   => '[' . $critical_page['code'] . ']',
568
-        );
569
-
570
-        $post_id = wp_insert_post($post_args);
571
-        if (! $post_id) {
572
-            $msg = sprintf(
573
-                __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
574
-                $critical_page['name']
575
-            );
576
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
577
-            return $critical_page;
578
-        }
579
-        // get newly created post's details
580
-        if (! $critical_page['post'] = get_post($post_id)) {
581
-            $msg = sprintf(
582
-                __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
583
-                $critical_page['name']
584
-            );
585
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
586
-        }
587
-
588
-        return $critical_page;
589
-
590
-    }
591
-
592
-
593
-
594
-
595
-
596
-    /**
597
-     *    This function adds a critical page's shortcode to the post_shortcodes array
598
-     *
599
-     * @access private
600
-     * @static
601
-     * @param array $critical_page
602
-     * @return void
603
-     */
604
-    private static function _track_critical_page_post_shortcodes($critical_page = array())
605
-    {
606
-        // check the goods
607
-        if ( ! $critical_page['post'] instanceof WP_Post) {
608
-            $msg = sprintf(
609
-                __(
610
-                    'The Event Espresso critical page shortcode for the page %s can not be tracked because it is not a WP_Post object.',
611
-                    'event_espresso'
612
-                ),
613
-                $critical_page['name']
614
-            );
615
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
616
-            return;
617
-        }
618
-        $EE_Core_Config = EE_Registry::instance()->CFG->core;
619
-        // map shortcode to post
620
-        $EE_Core_Config->post_shortcodes[$critical_page['post']->post_name][$critical_page['code']] = $critical_page['post']->ID;
621
-        // and make sure it's NOT added to the WP "Posts Page"
622
-        // name of the WP Posts Page
623
-        $posts_page = EE_Config::get_page_for_posts();
624
-        if (isset($EE_Core_Config->post_shortcodes[$posts_page])) {
625
-            unset($EE_Core_Config->post_shortcodes[$posts_page][$critical_page['code']]);
626
-        }
627
-        if ($posts_page !== 'posts' && isset($EE_Core_Config->post_shortcodes['posts'])) {
628
-            unset($EE_Core_Config->post_shortcodes['posts'][$critical_page['code']]);
629
-        }
630
-        // update post_shortcode CFG
631
-        EE_Config::instance()->update_espresso_config(false, false);
632
-        // verify that saved ID in the config matches the ID for the post the shortcode is on
633
-        if (
634
-            EE_Registry::instance()->CFG->core->post_shortcodes[$critical_page['post']->post_name][$critical_page['code']]
635
-            !== $critical_page['post']->ID
636
-        ) {
637
-            $msg = sprintf(
638
-                __(
639
-                    'The Event Espresso critical page shortcode for the %s page could not be configured properly.',
640
-                    'event_espresso'
641
-                ),
642
-                $critical_page['name']
643
-            );
644
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
645
-        }
646
-    }
647
-
648
-
649
-
650
-    /**
651
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
652
-     * The role being used to check is filterable.
653
-     *
654
-     * @since  4.6.0
655
-     * @global WPDB $wpdb
656
-     * @return mixed null|int WP_user ID or NULL
657
-     */
658
-    public static function get_default_creator_id()
659
-    {
660
-        global $wpdb;
661
-        if ( ! empty(self::$_default_creator_id)) {
662
-            return self::$_default_creator_id;
663
-        }/**/
664
-        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
665
-        //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.
666
-        $pre_filtered_id = apply_filters(
667
-            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
668
-            false,
669
-            $role_to_check
670
-        );
671
-        if ($pre_filtered_id !== false) {
672
-            return (int)$pre_filtered_id;
673
-        }
674
-        $capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
675
-        $query = $wpdb->prepare(
676
-            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
677
-            '%' . $role_to_check . '%'
678
-        );
679
-        $user_id = $wpdb->get_var($query);
680
-        $user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
681
-        if ($user_id && (int)$user_id) {
682
-            self::$_default_creator_id = (int)$user_id;
683
-            return self::$_default_creator_id;
684
-        } else {
685
-            return null;
686
-        }
687
-    }
688
-
689
-
690
-
691
-    /**
692
-     * used by EE and EE addons during plugin activation to create tables.
693
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
694
-     * but includes extra logic regarding activations.
695
-     *
696
-     * @access public
697
-     * @static
698
-     * @param string  $table_name              without the $wpdb->prefix
699
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
700
-     *                                         table query)
701
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
702
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
703
-     *                                         and new once this function is done (ie, you really do want to CREATE a
704
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
705
-     *                                         you just want to verify the table exists and matches this definition
706
-     *                                         (and if it HAS data in it you want to leave it be)
707
-     * @return void
708
-     * @throws EE_Error if there are database errors
709
-     */
710
-    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
711
-    {
712
-        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
713
-            return;
714
-        }
715
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
716
-        if ( ! function_exists('dbDelta')) {
717
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
718
-        }
719
-        $tableAnalysis = \EEH_Activation::getTableAnalysis();
720
-        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
721
-        // do we need to first delete an existing version of this table ?
722
-        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
723
-            // ok, delete the table... but ONLY if it's empty
724
-            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
725
-            // table is NOT empty, are you SURE you want to delete this table ???
726
-            if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
727
-                \EEH_Activation::getTableManager()->dropTable($wp_table_name);
728
-            } else if ( ! $deleted_safely) {
729
-                // so we should be more cautious rather than just dropping tables so easily
730
-                error_log(
731
-                    sprintf(
732
-                        __(
733
-                            '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.',
734
-                            'event_espresso'
735
-                        ),
736
-                        $wp_table_name,
737
-                        '<br/>',
738
-                        'espresso_db_update'
739
-                    )
740
-                );
741
-            }
742
-        }
743
-        $engine = str_replace('ENGINE=', '', $engine);
744
-        \EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
745
-    }
746
-
747
-
748
-
749
-    /**
750
-     *    add_column_if_it_doesn't_exist
751
-     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
752
-     *
753
-     * @access     public
754
-     * @static
755
-     * @deprecated instead use TableManager::addColumn()
756
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
757
-     * @param string $column_name
758
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
759
-     *                            'VARCHAR(10)'
760
-     * @return bool|int
761
-     */
762
-    public static function add_column_if_it_doesnt_exist(
763
-        $table_name,
764
-        $column_name,
765
-        $column_info = 'INT UNSIGNED NOT NULL'
766
-    ) {
767
-        return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
768
-    }
769
-
770
-
771
-    /**
772
-     * get_fields_on_table
773
-     * Gets all the fields on the database table.
774
-     *
775
-     * @access     public
776
-     * @deprecated instead use TableManager::getTableColumns()
777
-     * @static
778
-     * @param string $table_name , without prefixed $wpdb->prefix
779
-     * @return array of database column names
780
-     */
781
-    public static function get_fields_on_table($table_name = null)
782
-    {
783
-        return \EEH_Activation::getTableManager()->getTableColumns($table_name);
784
-    }
785
-
786
-
787
-    /**
788
-     * db_table_is_empty
789
-     *
790
-     * @access     public\
791
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
792
-     * @static
793
-     * @param string $table_name
794
-     * @return bool
795
-     */
796
-    public static function db_table_is_empty($table_name)
797
-    {
798
-        return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
799
-    }
800
-
801
-
802
-    /**
803
-     * delete_db_table_if_empty
804
-     *
805
-     * @access public
806
-     * @static
807
-     * @param string $table_name
808
-     * @return bool | int
809
-     */
810
-    public static function delete_db_table_if_empty($table_name)
811
-    {
812
-        if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
813
-            return \EEH_Activation::getTableManager()->dropTable($table_name);
814
-        }
815
-        return false;
816
-    }
817
-
818
-
819
-    /**
820
-     * delete_unused_db_table
821
-     *
822
-     * @access     public
823
-     * @static
824
-     * @deprecated instead use TableManager::dropTable()
825
-     * @param string $table_name
826
-     * @return bool | int
827
-     */
828
-    public static function delete_unused_db_table($table_name)
829
-    {
830
-        return \EEH_Activation::getTableManager()->dropTable($table_name);
831
-    }
832
-
833
-
834
-    /**
835
-     * drop_index
836
-     *
837
-     * @access     public
838
-     * @static
839
-     * @deprecated instead use TableManager::dropIndex()
840
-     * @param string $table_name
841
-     * @param string $index_name
842
-     * @return bool | int
843
-     */
844
-    public static function drop_index($table_name, $index_name)
845
-    {
846
-        return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
847
-    }
848
-
849
-
850
-
851
-    /**
852
-     * create_database_tables
853
-     *
854
-     * @access public
855
-     * @static
856
-     * @throws EE_Error
857
-     * @return boolean success (whether database is setup properly or not)
858
-     */
859
-    public static function create_database_tables()
860
-    {
861
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
862
-        //find the migration script that sets the database to be compatible with the code
863
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
864
-        if ($dms_name) {
865
-            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
866
-            $current_data_migration_script->set_migrating(false);
867
-            $current_data_migration_script->schema_changes_before_migration();
868
-            $current_data_migration_script->schema_changes_after_migration();
869
-            if ($current_data_migration_script->get_errors()) {
870
-                if (WP_DEBUG) {
871
-                    foreach ($current_data_migration_script->get_errors() as $error) {
872
-                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
873
-                    }
874
-                } else {
875
-                    EE_Error::add_error(
876
-                        __(
877
-                            'There were errors creating the Event Espresso database tables and Event Espresso has been 
270
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
271
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
272
+			if (is_array($hooks_to_fire_at_time)) {
273
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
274
+					if (isset($ee_cron_tasks_to_remove[$hook_name])
275
+						&& is_array($ee_cron_tasks_to_remove[$hook_name])
276
+					) {
277
+						unset($crons[$timestamp][$hook_name]);
278
+					}
279
+				}
280
+				//also take care of any empty cron timestamps.
281
+				if (empty($hooks_to_fire_at_time)) {
282
+					unset($crons[$timestamp]);
283
+				}
284
+			}
285
+		}
286
+		_set_cron_array($crons);
287
+	}
288
+
289
+
290
+	/**
291
+	 *    CPT_initialization
292
+	 *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
293
+	 *
294
+	 * @access public
295
+	 * @static
296
+	 * @return void
297
+	 */
298
+	public static function CPT_initialization()
299
+	{
300
+		// register Custom Post Types
301
+		EE_Registry::instance()->load_core('Register_CPTs');
302
+		flush_rewrite_rules();
303
+	}
304
+
305
+
306
+
307
+	/**
308
+	 *    reset_and_update_config
309
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
310
+	 * If there is old calendar config data saved, then it will get converted on activation.
311
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
312
+	 *
313
+	 * @access public
314
+	 * @static
315
+	 * @return void
316
+	 */
317
+	public static function reset_and_update_config()
318
+	{
319
+		do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
320
+		add_filter(
321
+			'FHEE__EE_Config___load_core_config__config_settings',
322
+			array('EEH_Activation', 'migrate_old_config_data'),
323
+			10,
324
+			3
325
+		);
326
+		//EE_Config::reset();
327
+		if (! EE_Config::logging_enabled()) {
328
+			delete_option(EE_Config::LOG_NAME);
329
+		}
330
+	}
331
+
332
+
333
+	/**
334
+	 *    load_calendar_config
335
+	 *
336
+	 * @access    public
337
+	 * @return    void
338
+	 */
339
+	public static function load_calendar_config()
340
+	{
341
+		// grab array of all plugin folders and loop thru it
342
+		$plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
343
+		if (empty($plugins)) {
344
+			return;
345
+		}
346
+		foreach ($plugins as $plugin_path) {
347
+			// grab plugin folder name from path
348
+			$plugin = basename($plugin_path);
349
+			// drill down to Espresso plugins
350
+			// then to calendar related plugins
351
+			if (
352
+				strpos($plugin, 'espresso') !== false
353
+				|| strpos($plugin, 'Espresso') !== false
354
+				|| strpos($plugin, 'ee4') !== false
355
+				|| strpos($plugin, 'EE4') !== false
356
+				|| strpos($plugin, 'calendar') !== false
357
+			) {
358
+				// this is what we are looking for
359
+				$calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
360
+				// does it exist in this folder ?
361
+				if (is_readable($calendar_config)) {
362
+					// YEAH! let's load it
363
+					require_once($calendar_config);
364
+				}
365
+			}
366
+		}
367
+	}
368
+
369
+
370
+
371
+	/**
372
+	 *    _migrate_old_config_data
373
+	 *
374
+	 * @access    public
375
+	 * @param array|stdClass $settings
376
+	 * @param string         $config
377
+	 * @param \EE_Config     $EE_Config
378
+	 * @return \stdClass
379
+	 */
380
+	public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
381
+	{
382
+		$convert_from_array = array('addons');
383
+		// in case old settings were saved as an array
384
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
385
+			// convert existing settings to an object
386
+			$config_array = $settings;
387
+			$settings = new stdClass();
388
+			foreach ($config_array as $key => $value) {
389
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
390
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
391
+				} else {
392
+					$settings->{$key} = $value;
393
+				}
394
+			}
395
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
396
+		}
397
+		return $settings;
398
+	}
399
+
400
+
401
+	/**
402
+	 * deactivate_event_espresso
403
+	 *
404
+	 * @access public
405
+	 * @static
406
+	 * @return void
407
+	 */
408
+	public static function deactivate_event_espresso()
409
+	{
410
+		// check permissions
411
+		if (current_user_can('activate_plugins')) {
412
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
413
+		}
414
+	}
415
+
416
+
417
+
418
+
419
+
420
+	/**
421
+	 * verify_default_pages_exist
422
+	 *
423
+	 * @access public
424
+	 * @static
425
+	 * @return void
426
+	 */
427
+	public static function verify_default_pages_exist()
428
+	{
429
+		$critical_page_problem = false;
430
+		$critical_pages = array(
431
+			array(
432
+				'id'   => 'reg_page_id',
433
+				'name' => __('Registration Checkout', 'event_espresso'),
434
+				'post' => null,
435
+				'code' => 'ESPRESSO_CHECKOUT',
436
+			),
437
+			array(
438
+				'id'   => 'txn_page_id',
439
+				'name' => __('Transactions', 'event_espresso'),
440
+				'post' => null,
441
+				'code' => 'ESPRESSO_TXN_PAGE',
442
+			),
443
+			array(
444
+				'id'   => 'thank_you_page_id',
445
+				'name' => __('Thank You', 'event_espresso'),
446
+				'post' => null,
447
+				'code' => 'ESPRESSO_THANK_YOU',
448
+			),
449
+			array(
450
+				'id'   => 'cancel_page_id',
451
+				'name' => __('Registration Cancelled', 'event_espresso'),
452
+				'post' => null,
453
+				'code' => 'ESPRESSO_CANCELLED',
454
+			),
455
+		);
456
+		$EE_Core_Config = EE_Registry::instance()->CFG->core;
457
+		foreach ($critical_pages as $critical_page) {
458
+			// is critical page ID set in config ?
459
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
460
+				// attempt to find post by ID
461
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
462
+			}
463
+			// no dice?
464
+			if ($critical_page['post'] === null) {
465
+				// attempt to find post by title
466
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
467
+				// still nothing?
468
+				if ($critical_page['post'] === null) {
469
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
470
+					// REALLY? Still nothing ??!?!?
471
+					if ($critical_page['post'] === null) {
472
+						$msg = __(
473
+							'The Event Espresso critical page configuration settings could not be updated.',
474
+							'event_espresso'
475
+						);
476
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
477
+						break;
478
+					}
479
+				}
480
+			}
481
+			// track post_shortcodes
482
+			if ($critical_page['post']) {
483
+				EEH_Activation::_track_critical_page_post_shortcodes($critical_page);
484
+			}
485
+			// check that Post ID matches critical page ID in config
486
+			if (
487
+				isset($critical_page['post']->ID)
488
+				&& $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
489
+			) {
490
+				//update Config with post ID
491
+				$EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
492
+				if (! EE_Config::instance()->update_espresso_config(false, false)) {
493
+					$msg = __(
494
+						'The Event Espresso critical page configuration settings could not be updated.',
495
+						'event_espresso'
496
+					);
497
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
498
+				}
499
+			}
500
+			$critical_page_problem =
501
+				! isset($critical_page['post']->post_status)
502
+				|| $critical_page['post']->post_status !== 'publish'
503
+				|| strpos($critical_page['post']->post_content, $critical_page['code']) === false
504
+					? true
505
+					: $critical_page_problem;
506
+		}
507
+		if ($critical_page_problem) {
508
+			$msg = sprintf(
509
+				__(
510
+					'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
511
+					'event_espresso'
512
+				),
513
+				'<a href="'
514
+				. admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
515
+				. '">'
516
+				. __('Event Espresso Critical Pages Settings', 'event_espresso')
517
+				. '</a>'
518
+			);
519
+			EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
520
+		}
521
+		if (EE_Error::has_notices()) {
522
+			EE_Error::get_notices(false, true, true);
523
+		}
524
+	}
525
+
526
+
527
+
528
+	/**
529
+	 * Returns the first post which uses the specified shortcode
530
+	 *
531
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
532
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
533
+	 *                             "[ESPRESSO_THANK_YOU"
534
+	 *                             (we don't search for the closing shortcode bracket because they might have added
535
+	 *                             parameter to the shortcode
536
+	 * @return WP_Post or NULl
537
+	 */
538
+	public static function get_page_by_ee_shortcode($ee_shortcode)
539
+	{
540
+		global $wpdb;
541
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
542
+		$post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
543
+		if ($post_id) {
544
+			return get_post($post_id);
545
+		} else {
546
+			return null;
547
+		}
548
+	}
549
+
550
+
551
+	/**
552
+	 *    This function generates a post for critical espresso pages
553
+	 *
554
+	 * @access public
555
+	 * @static
556
+	 * @param array $critical_page
557
+	 * @return array
558
+	 */
559
+	public static function create_critical_page($critical_page)
560
+	{
561
+
562
+		$post_args = array(
563
+			'post_title'     => $critical_page['name'],
564
+			'post_status'    => 'publish',
565
+			'post_type'      => 'page',
566
+			'comment_status' => 'closed',
567
+			'post_content'   => '[' . $critical_page['code'] . ']',
568
+		);
569
+
570
+		$post_id = wp_insert_post($post_args);
571
+		if (! $post_id) {
572
+			$msg = sprintf(
573
+				__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
574
+				$critical_page['name']
575
+			);
576
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
577
+			return $critical_page;
578
+		}
579
+		// get newly created post's details
580
+		if (! $critical_page['post'] = get_post($post_id)) {
581
+			$msg = sprintf(
582
+				__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
583
+				$critical_page['name']
584
+			);
585
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
586
+		}
587
+
588
+		return $critical_page;
589
+
590
+	}
591
+
592
+
593
+
594
+
595
+
596
+	/**
597
+	 *    This function adds a critical page's shortcode to the post_shortcodes array
598
+	 *
599
+	 * @access private
600
+	 * @static
601
+	 * @param array $critical_page
602
+	 * @return void
603
+	 */
604
+	private static function _track_critical_page_post_shortcodes($critical_page = array())
605
+	{
606
+		// check the goods
607
+		if ( ! $critical_page['post'] instanceof WP_Post) {
608
+			$msg = sprintf(
609
+				__(
610
+					'The Event Espresso critical page shortcode for the page %s can not be tracked because it is not a WP_Post object.',
611
+					'event_espresso'
612
+				),
613
+				$critical_page['name']
614
+			);
615
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
616
+			return;
617
+		}
618
+		$EE_Core_Config = EE_Registry::instance()->CFG->core;
619
+		// map shortcode to post
620
+		$EE_Core_Config->post_shortcodes[$critical_page['post']->post_name][$critical_page['code']] = $critical_page['post']->ID;
621
+		// and make sure it's NOT added to the WP "Posts Page"
622
+		// name of the WP Posts Page
623
+		$posts_page = EE_Config::get_page_for_posts();
624
+		if (isset($EE_Core_Config->post_shortcodes[$posts_page])) {
625
+			unset($EE_Core_Config->post_shortcodes[$posts_page][$critical_page['code']]);
626
+		}
627
+		if ($posts_page !== 'posts' && isset($EE_Core_Config->post_shortcodes['posts'])) {
628
+			unset($EE_Core_Config->post_shortcodes['posts'][$critical_page['code']]);
629
+		}
630
+		// update post_shortcode CFG
631
+		EE_Config::instance()->update_espresso_config(false, false);
632
+		// verify that saved ID in the config matches the ID for the post the shortcode is on
633
+		if (
634
+			EE_Registry::instance()->CFG->core->post_shortcodes[$critical_page['post']->post_name][$critical_page['code']]
635
+			!== $critical_page['post']->ID
636
+		) {
637
+			$msg = sprintf(
638
+				__(
639
+					'The Event Espresso critical page shortcode for the %s page could not be configured properly.',
640
+					'event_espresso'
641
+				),
642
+				$critical_page['name']
643
+			);
644
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
645
+		}
646
+	}
647
+
648
+
649
+
650
+	/**
651
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
652
+	 * The role being used to check is filterable.
653
+	 *
654
+	 * @since  4.6.0
655
+	 * @global WPDB $wpdb
656
+	 * @return mixed null|int WP_user ID or NULL
657
+	 */
658
+	public static function get_default_creator_id()
659
+	{
660
+		global $wpdb;
661
+		if ( ! empty(self::$_default_creator_id)) {
662
+			return self::$_default_creator_id;
663
+		}/**/
664
+		$role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
665
+		//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.
666
+		$pre_filtered_id = apply_filters(
667
+			'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
668
+			false,
669
+			$role_to_check
670
+		);
671
+		if ($pre_filtered_id !== false) {
672
+			return (int)$pre_filtered_id;
673
+		}
674
+		$capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
675
+		$query = $wpdb->prepare(
676
+			"SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
677
+			'%' . $role_to_check . '%'
678
+		);
679
+		$user_id = $wpdb->get_var($query);
680
+		$user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
681
+		if ($user_id && (int)$user_id) {
682
+			self::$_default_creator_id = (int)$user_id;
683
+			return self::$_default_creator_id;
684
+		} else {
685
+			return null;
686
+		}
687
+	}
688
+
689
+
690
+
691
+	/**
692
+	 * used by EE and EE addons during plugin activation to create tables.
693
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
694
+	 * but includes extra logic regarding activations.
695
+	 *
696
+	 * @access public
697
+	 * @static
698
+	 * @param string  $table_name              without the $wpdb->prefix
699
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
700
+	 *                                         table query)
701
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
702
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
703
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
704
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
705
+	 *                                         you just want to verify the table exists and matches this definition
706
+	 *                                         (and if it HAS data in it you want to leave it be)
707
+	 * @return void
708
+	 * @throws EE_Error if there are database errors
709
+	 */
710
+	public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
711
+	{
712
+		if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
713
+			return;
714
+		}
715
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
716
+		if ( ! function_exists('dbDelta')) {
717
+			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
718
+		}
719
+		$tableAnalysis = \EEH_Activation::getTableAnalysis();
720
+		$wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
721
+		// do we need to first delete an existing version of this table ?
722
+		if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
723
+			// ok, delete the table... but ONLY if it's empty
724
+			$deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
725
+			// table is NOT empty, are you SURE you want to delete this table ???
726
+			if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
727
+				\EEH_Activation::getTableManager()->dropTable($wp_table_name);
728
+			} else if ( ! $deleted_safely) {
729
+				// so we should be more cautious rather than just dropping tables so easily
730
+				error_log(
731
+					sprintf(
732
+						__(
733
+							'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.',
734
+							'event_espresso'
735
+						),
736
+						$wp_table_name,
737
+						'<br/>',
738
+						'espresso_db_update'
739
+					)
740
+				);
741
+			}
742
+		}
743
+		$engine = str_replace('ENGINE=', '', $engine);
744
+		\EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
745
+	}
746
+
747
+
748
+
749
+	/**
750
+	 *    add_column_if_it_doesn't_exist
751
+	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
752
+	 *
753
+	 * @access     public
754
+	 * @static
755
+	 * @deprecated instead use TableManager::addColumn()
756
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
757
+	 * @param string $column_name
758
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
759
+	 *                            'VARCHAR(10)'
760
+	 * @return bool|int
761
+	 */
762
+	public static function add_column_if_it_doesnt_exist(
763
+		$table_name,
764
+		$column_name,
765
+		$column_info = 'INT UNSIGNED NOT NULL'
766
+	) {
767
+		return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
768
+	}
769
+
770
+
771
+	/**
772
+	 * get_fields_on_table
773
+	 * Gets all the fields on the database table.
774
+	 *
775
+	 * @access     public
776
+	 * @deprecated instead use TableManager::getTableColumns()
777
+	 * @static
778
+	 * @param string $table_name , without prefixed $wpdb->prefix
779
+	 * @return array of database column names
780
+	 */
781
+	public static function get_fields_on_table($table_name = null)
782
+	{
783
+		return \EEH_Activation::getTableManager()->getTableColumns($table_name);
784
+	}
785
+
786
+
787
+	/**
788
+	 * db_table_is_empty
789
+	 *
790
+	 * @access     public\
791
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
792
+	 * @static
793
+	 * @param string $table_name
794
+	 * @return bool
795
+	 */
796
+	public static function db_table_is_empty($table_name)
797
+	{
798
+		return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
799
+	}
800
+
801
+
802
+	/**
803
+	 * delete_db_table_if_empty
804
+	 *
805
+	 * @access public
806
+	 * @static
807
+	 * @param string $table_name
808
+	 * @return bool | int
809
+	 */
810
+	public static function delete_db_table_if_empty($table_name)
811
+	{
812
+		if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
813
+			return \EEH_Activation::getTableManager()->dropTable($table_name);
814
+		}
815
+		return false;
816
+	}
817
+
818
+
819
+	/**
820
+	 * delete_unused_db_table
821
+	 *
822
+	 * @access     public
823
+	 * @static
824
+	 * @deprecated instead use TableManager::dropTable()
825
+	 * @param string $table_name
826
+	 * @return bool | int
827
+	 */
828
+	public static function delete_unused_db_table($table_name)
829
+	{
830
+		return \EEH_Activation::getTableManager()->dropTable($table_name);
831
+	}
832
+
833
+
834
+	/**
835
+	 * drop_index
836
+	 *
837
+	 * @access     public
838
+	 * @static
839
+	 * @deprecated instead use TableManager::dropIndex()
840
+	 * @param string $table_name
841
+	 * @param string $index_name
842
+	 * @return bool | int
843
+	 */
844
+	public static function drop_index($table_name, $index_name)
845
+	{
846
+		return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
847
+	}
848
+
849
+
850
+
851
+	/**
852
+	 * create_database_tables
853
+	 *
854
+	 * @access public
855
+	 * @static
856
+	 * @throws EE_Error
857
+	 * @return boolean success (whether database is setup properly or not)
858
+	 */
859
+	public static function create_database_tables()
860
+	{
861
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
862
+		//find the migration script that sets the database to be compatible with the code
863
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
864
+		if ($dms_name) {
865
+			$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
866
+			$current_data_migration_script->set_migrating(false);
867
+			$current_data_migration_script->schema_changes_before_migration();
868
+			$current_data_migration_script->schema_changes_after_migration();
869
+			if ($current_data_migration_script->get_errors()) {
870
+				if (WP_DEBUG) {
871
+					foreach ($current_data_migration_script->get_errors() as $error) {
872
+						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
873
+					}
874
+				} else {
875
+					EE_Error::add_error(
876
+						__(
877
+							'There were errors creating the Event Espresso database tables and Event Espresso has been 
878 878
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
879
-                            'event_espresso'
880
-                        )
881
-                    );
882
-                }
883
-                return false;
884
-            }
885
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
886
-        } else {
887
-            EE_Error::add_error(
888
-                __(
889
-                    'Could not determine most up-to-date data migration script from which to pull database schema
879
+							'event_espresso'
880
+						)
881
+					);
882
+				}
883
+				return false;
884
+			}
885
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
886
+		} else {
887
+			EE_Error::add_error(
888
+				__(
889
+					'Could not determine most up-to-date data migration script from which to pull database schema
890 890
                      structure. So database is probably not setup properly',
891
-                    'event_espresso'
892
-                ),
893
-                __FILE__,
894
-                __FUNCTION__,
895
-                __LINE__
896
-            );
897
-            return false;
898
-        }
899
-        return true;
900
-    }
901
-
902
-
903
-
904
-    /**
905
-     * initialize_system_questions
906
-     *
907
-     * @access public
908
-     * @static
909
-     * @return void
910
-     */
911
-    public static function initialize_system_questions()
912
-    {
913
-        // QUESTION GROUPS
914
-        global $wpdb;
915
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
916
-        $SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
917
-        // what we have
918
-        $question_groups = $wpdb->get_col($SQL);
919
-        // check the response
920
-        $question_groups = is_array($question_groups) ? $question_groups : array();
921
-        // what we should have
922
-        $QSG_systems = array(1, 2);
923
-        // loop thru what we should have and compare to what we have
924
-        foreach ($QSG_systems as $QSG_system) {
925
-            // reset values array
926
-            $QSG_values = array();
927
-            // 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)
928
-            if (! in_array("$QSG_system", $question_groups)) {
929
-                // add it
930
-                switch ($QSG_system) {
931
-                    case 1:
932
-                        $QSG_values = array(
933
-                            'QSG_name'            => __('Personal Information', 'event_espresso'),
934
-                            'QSG_identifier'      => 'personal-information-' . time(),
935
-                            'QSG_desc'            => '',
936
-                            'QSG_order'           => 1,
937
-                            'QSG_show_group_name' => 1,
938
-                            'QSG_show_group_desc' => 1,
939
-                            'QSG_system'          => EEM_Question_Group::system_personal,
940
-                            'QSG_deleted'         => 0,
941
-                        );
942
-                        break;
943
-                    case 2:
944
-                        $QSG_values = array(
945
-                            'QSG_name'            => __('Address Information', 'event_espresso'),
946
-                            'QSG_identifier'      => 'address-information-' . time(),
947
-                            'QSG_desc'            => '',
948
-                            'QSG_order'           => 2,
949
-                            'QSG_show_group_name' => 1,
950
-                            'QSG_show_group_desc' => 1,
951
-                            'QSG_system'          => EEM_Question_Group::system_address,
952
-                            'QSG_deleted'         => 0,
953
-                        );
954
-                        break;
955
-                }
956
-                // make sure we have some values before inserting them
957
-                if (! empty($QSG_values)) {
958
-                    // insert system question
959
-                    $wpdb->insert(
960
-                        $table_name,
961
-                        $QSG_values,
962
-                        array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
963
-                    );
964
-                    $QSG_IDs[$QSG_system] = $wpdb->insert_id;
965
-                }
966
-            }
967
-        }
968
-        // QUESTIONS
969
-        global $wpdb;
970
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
971
-        $SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
972
-        // what we have
973
-        $questions = $wpdb->get_col($SQL);
974
-        // what we should have
975
-        $QST_systems = array(
976
-            'fname',
977
-            'lname',
978
-            'email',
979
-            'address',
980
-            'address2',
981
-            'city',
982
-            'country',
983
-            'state',
984
-            'zip',
985
-            'phone',
986
-        );
987
-        $order_for_group_1 = 1;
988
-        $order_for_group_2 = 1;
989
-        // loop thru what we should have and compare to what we have
990
-        foreach ($QST_systems as $QST_system) {
991
-            // reset values array
992
-            $QST_values = array();
993
-            // if we don't have what we should have
994
-            if (! in_array($QST_system, $questions)) {
995
-                // add it
996
-                switch ($QST_system) {
997
-                    case 'fname':
998
-                        $QST_values = array(
999
-                            'QST_display_text'  => __('First Name', 'event_espresso'),
1000
-                            'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
1001
-                            'QST_system'        => 'fname',
1002
-                            'QST_type'          => 'TEXT',
1003
-                            'QST_required'      => 1,
1004
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1005
-                            'QST_order'         => 1,
1006
-                            'QST_admin_only'    => 0,
1007
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1008
-                            'QST_wp_user'       => self::get_default_creator_id(),
1009
-                            'QST_deleted'       => 0,
1010
-                        );
1011
-                        break;
1012
-                    case 'lname':
1013
-                        $QST_values = array(
1014
-                            'QST_display_text'  => __('Last Name', 'event_espresso'),
1015
-                            'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
1016
-                            'QST_system'        => 'lname',
1017
-                            'QST_type'          => 'TEXT',
1018
-                            'QST_required'      => 1,
1019
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1020
-                            'QST_order'         => 2,
1021
-                            'QST_admin_only'    => 0,
1022
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1023
-                            'QST_wp_user'       => self::get_default_creator_id(),
1024
-                            'QST_deleted'       => 0,
1025
-                        );
1026
-                        break;
1027
-                    case 'email':
1028
-                        $QST_values = array(
1029
-                            'QST_display_text'  => __('Email Address', 'event_espresso'),
1030
-                            'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
1031
-                            'QST_system'        => 'email',
1032
-                            'QST_type'          => 'EMAIL',
1033
-                            'QST_required'      => 1,
1034
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1035
-                            'QST_order'         => 3,
1036
-                            'QST_admin_only'    => 0,
1037
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1038
-                            'QST_wp_user'       => self::get_default_creator_id(),
1039
-                            'QST_deleted'       => 0,
1040
-                        );
1041
-                        break;
1042
-                    case 'address':
1043
-                        $QST_values = array(
1044
-                            'QST_display_text'  => __('Address', 'event_espresso'),
1045
-                            'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
1046
-                            'QST_system'        => 'address',
1047
-                            'QST_type'          => 'TEXT',
1048
-                            'QST_required'      => 0,
1049
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1050
-                            'QST_order'         => 4,
1051
-                            'QST_admin_only'    => 0,
1052
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1053
-                            'QST_wp_user'       => self::get_default_creator_id(),
1054
-                            'QST_deleted'       => 0,
1055
-                        );
1056
-                        break;
1057
-                    case 'address2':
1058
-                        $QST_values = array(
1059
-                            'QST_display_text'  => __('Address2', 'event_espresso'),
1060
-                            'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1061
-                            'QST_system'        => 'address2',
1062
-                            'QST_type'          => 'TEXT',
1063
-                            'QST_required'      => 0,
1064
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1065
-                            'QST_order'         => 5,
1066
-                            'QST_admin_only'    => 0,
1067
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1068
-                            'QST_wp_user'       => self::get_default_creator_id(),
1069
-                            'QST_deleted'       => 0,
1070
-                        );
1071
-                        break;
1072
-                    case 'city':
1073
-                        $QST_values = array(
1074
-                            'QST_display_text'  => __('City', 'event_espresso'),
1075
-                            'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1076
-                            'QST_system'        => 'city',
1077
-                            'QST_type'          => 'TEXT',
1078
-                            'QST_required'      => 0,
1079
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1080
-                            'QST_order'         => 6,
1081
-                            'QST_admin_only'    => 0,
1082
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1083
-                            'QST_wp_user'       => self::get_default_creator_id(),
1084
-                            'QST_deleted'       => 0,
1085
-                        );
1086
-                        break;
1087
-                    case 'country':
1088
-                        $QST_values = array(
1089
-                            'QST_display_text'  => __('Country', 'event_espresso'),
1090
-                            'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1091
-                            'QST_system'        => 'country',
1092
-                            'QST_type'          => 'COUNTRY',
1093
-                            'QST_required'      => 0,
1094
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1095
-                            'QST_order'         => 7,
1096
-                            'QST_admin_only'    => 0,
1097
-                            'QST_wp_user'       => self::get_default_creator_id(),
1098
-                            'QST_deleted'       => 0,
1099
-                        );
1100
-                        break;
1101
-                    case 'state':
1102
-                        $QST_values = array(
1103
-                            'QST_display_text'  => __('State/Province', 'event_espresso'),
1104
-                            'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1105
-                            'QST_system'        => 'state',
1106
-                            'QST_type'          => 'STATE',
1107
-                            'QST_required'      => 0,
1108
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1109
-                            'QST_order'         => 8,
1110
-                            'QST_admin_only'    => 0,
1111
-                            'QST_wp_user'       => self::get_default_creator_id(),
1112
-                            'QST_deleted'       => 0,
1113
-                        );
1114
-                        break;
1115
-                    case 'zip':
1116
-                        $QST_values = array(
1117
-                            'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1118
-                            'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1119
-                            'QST_system'        => 'zip',
1120
-                            'QST_type'          => 'TEXT',
1121
-                            'QST_required'      => 0,
1122
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1123
-                            'QST_order'         => 9,
1124
-                            'QST_admin_only'    => 0,
1125
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1126
-                            'QST_wp_user'       => self::get_default_creator_id(),
1127
-                            'QST_deleted'       => 0,
1128
-                        );
1129
-                        break;
1130
-                    case 'phone':
1131
-                        $QST_values = array(
1132
-                            'QST_display_text'  => __('Phone Number', 'event_espresso'),
1133
-                            'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1134
-                            'QST_system'        => 'phone',
1135
-                            'QST_type'          => 'TEXT',
1136
-                            'QST_required'      => 0,
1137
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1138
-                            'QST_order'         => 10,
1139
-                            'QST_admin_only'    => 0,
1140
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1141
-                            'QST_wp_user'       => self::get_default_creator_id(),
1142
-                            'QST_deleted'       => 0,
1143
-                        );
1144
-                        break;
1145
-                }
1146
-                if (! empty($QST_values)) {
1147
-                    // insert system question
1148
-                    $wpdb->insert(
1149
-                        $table_name,
1150
-                        $QST_values,
1151
-                        array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1152
-                    );
1153
-                    $QST_ID = $wpdb->insert_id;
1154
-                    // QUESTION GROUP QUESTIONS
1155
-                    if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1156
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1157
-                    } else {
1158
-                        $system_question_we_want = EEM_Question_Group::system_address;
1159
-                    }
1160
-                    if (isset($QSG_IDs[$system_question_we_want])) {
1161
-                        $QSG_ID = $QSG_IDs[$system_question_we_want];
1162
-                    } else {
1163
-                        $id_col = EEM_Question_Group::instance()
1164
-                                                    ->get_col(array(array('QSG_system' => $system_question_we_want)));
1165
-                        if (is_array($id_col)) {
1166
-                            $QSG_ID = reset($id_col);
1167
-                        } else {
1168
-                            //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
1169
-                            EE_Log::instance()->log(
1170
-                                __FILE__,
1171
-                                __FUNCTION__,
1172
-                                sprintf(
1173
-                                    __(
1174
-                                        'Could not associate question %1$s to a question group because no system question
891
+					'event_espresso'
892
+				),
893
+				__FILE__,
894
+				__FUNCTION__,
895
+				__LINE__
896
+			);
897
+			return false;
898
+		}
899
+		return true;
900
+	}
901
+
902
+
903
+
904
+	/**
905
+	 * initialize_system_questions
906
+	 *
907
+	 * @access public
908
+	 * @static
909
+	 * @return void
910
+	 */
911
+	public static function initialize_system_questions()
912
+	{
913
+		// QUESTION GROUPS
914
+		global $wpdb;
915
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
916
+		$SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
917
+		// what we have
918
+		$question_groups = $wpdb->get_col($SQL);
919
+		// check the response
920
+		$question_groups = is_array($question_groups) ? $question_groups : array();
921
+		// what we should have
922
+		$QSG_systems = array(1, 2);
923
+		// loop thru what we should have and compare to what we have
924
+		foreach ($QSG_systems as $QSG_system) {
925
+			// reset values array
926
+			$QSG_values = array();
927
+			// 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)
928
+			if (! in_array("$QSG_system", $question_groups)) {
929
+				// add it
930
+				switch ($QSG_system) {
931
+					case 1:
932
+						$QSG_values = array(
933
+							'QSG_name'            => __('Personal Information', 'event_espresso'),
934
+							'QSG_identifier'      => 'personal-information-' . time(),
935
+							'QSG_desc'            => '',
936
+							'QSG_order'           => 1,
937
+							'QSG_show_group_name' => 1,
938
+							'QSG_show_group_desc' => 1,
939
+							'QSG_system'          => EEM_Question_Group::system_personal,
940
+							'QSG_deleted'         => 0,
941
+						);
942
+						break;
943
+					case 2:
944
+						$QSG_values = array(
945
+							'QSG_name'            => __('Address Information', 'event_espresso'),
946
+							'QSG_identifier'      => 'address-information-' . time(),
947
+							'QSG_desc'            => '',
948
+							'QSG_order'           => 2,
949
+							'QSG_show_group_name' => 1,
950
+							'QSG_show_group_desc' => 1,
951
+							'QSG_system'          => EEM_Question_Group::system_address,
952
+							'QSG_deleted'         => 0,
953
+						);
954
+						break;
955
+				}
956
+				// make sure we have some values before inserting them
957
+				if (! empty($QSG_values)) {
958
+					// insert system question
959
+					$wpdb->insert(
960
+						$table_name,
961
+						$QSG_values,
962
+						array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
963
+					);
964
+					$QSG_IDs[$QSG_system] = $wpdb->insert_id;
965
+				}
966
+			}
967
+		}
968
+		// QUESTIONS
969
+		global $wpdb;
970
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
971
+		$SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
972
+		// what we have
973
+		$questions = $wpdb->get_col($SQL);
974
+		// what we should have
975
+		$QST_systems = array(
976
+			'fname',
977
+			'lname',
978
+			'email',
979
+			'address',
980
+			'address2',
981
+			'city',
982
+			'country',
983
+			'state',
984
+			'zip',
985
+			'phone',
986
+		);
987
+		$order_for_group_1 = 1;
988
+		$order_for_group_2 = 1;
989
+		// loop thru what we should have and compare to what we have
990
+		foreach ($QST_systems as $QST_system) {
991
+			// reset values array
992
+			$QST_values = array();
993
+			// if we don't have what we should have
994
+			if (! in_array($QST_system, $questions)) {
995
+				// add it
996
+				switch ($QST_system) {
997
+					case 'fname':
998
+						$QST_values = array(
999
+							'QST_display_text'  => __('First Name', 'event_espresso'),
1000
+							'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
1001
+							'QST_system'        => 'fname',
1002
+							'QST_type'          => 'TEXT',
1003
+							'QST_required'      => 1,
1004
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1005
+							'QST_order'         => 1,
1006
+							'QST_admin_only'    => 0,
1007
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1008
+							'QST_wp_user'       => self::get_default_creator_id(),
1009
+							'QST_deleted'       => 0,
1010
+						);
1011
+						break;
1012
+					case 'lname':
1013
+						$QST_values = array(
1014
+							'QST_display_text'  => __('Last Name', 'event_espresso'),
1015
+							'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
1016
+							'QST_system'        => 'lname',
1017
+							'QST_type'          => 'TEXT',
1018
+							'QST_required'      => 1,
1019
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1020
+							'QST_order'         => 2,
1021
+							'QST_admin_only'    => 0,
1022
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1023
+							'QST_wp_user'       => self::get_default_creator_id(),
1024
+							'QST_deleted'       => 0,
1025
+						);
1026
+						break;
1027
+					case 'email':
1028
+						$QST_values = array(
1029
+							'QST_display_text'  => __('Email Address', 'event_espresso'),
1030
+							'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
1031
+							'QST_system'        => 'email',
1032
+							'QST_type'          => 'EMAIL',
1033
+							'QST_required'      => 1,
1034
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1035
+							'QST_order'         => 3,
1036
+							'QST_admin_only'    => 0,
1037
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1038
+							'QST_wp_user'       => self::get_default_creator_id(),
1039
+							'QST_deleted'       => 0,
1040
+						);
1041
+						break;
1042
+					case 'address':
1043
+						$QST_values = array(
1044
+							'QST_display_text'  => __('Address', 'event_espresso'),
1045
+							'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
1046
+							'QST_system'        => 'address',
1047
+							'QST_type'          => 'TEXT',
1048
+							'QST_required'      => 0,
1049
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1050
+							'QST_order'         => 4,
1051
+							'QST_admin_only'    => 0,
1052
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1053
+							'QST_wp_user'       => self::get_default_creator_id(),
1054
+							'QST_deleted'       => 0,
1055
+						);
1056
+						break;
1057
+					case 'address2':
1058
+						$QST_values = array(
1059
+							'QST_display_text'  => __('Address2', 'event_espresso'),
1060
+							'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1061
+							'QST_system'        => 'address2',
1062
+							'QST_type'          => 'TEXT',
1063
+							'QST_required'      => 0,
1064
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1065
+							'QST_order'         => 5,
1066
+							'QST_admin_only'    => 0,
1067
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1068
+							'QST_wp_user'       => self::get_default_creator_id(),
1069
+							'QST_deleted'       => 0,
1070
+						);
1071
+						break;
1072
+					case 'city':
1073
+						$QST_values = array(
1074
+							'QST_display_text'  => __('City', 'event_espresso'),
1075
+							'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1076
+							'QST_system'        => 'city',
1077
+							'QST_type'          => 'TEXT',
1078
+							'QST_required'      => 0,
1079
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1080
+							'QST_order'         => 6,
1081
+							'QST_admin_only'    => 0,
1082
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1083
+							'QST_wp_user'       => self::get_default_creator_id(),
1084
+							'QST_deleted'       => 0,
1085
+						);
1086
+						break;
1087
+					case 'country':
1088
+						$QST_values = array(
1089
+							'QST_display_text'  => __('Country', 'event_espresso'),
1090
+							'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1091
+							'QST_system'        => 'country',
1092
+							'QST_type'          => 'COUNTRY',
1093
+							'QST_required'      => 0,
1094
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1095
+							'QST_order'         => 7,
1096
+							'QST_admin_only'    => 0,
1097
+							'QST_wp_user'       => self::get_default_creator_id(),
1098
+							'QST_deleted'       => 0,
1099
+						);
1100
+						break;
1101
+					case 'state':
1102
+						$QST_values = array(
1103
+							'QST_display_text'  => __('State/Province', 'event_espresso'),
1104
+							'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1105
+							'QST_system'        => 'state',
1106
+							'QST_type'          => 'STATE',
1107
+							'QST_required'      => 0,
1108
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1109
+							'QST_order'         => 8,
1110
+							'QST_admin_only'    => 0,
1111
+							'QST_wp_user'       => self::get_default_creator_id(),
1112
+							'QST_deleted'       => 0,
1113
+						);
1114
+						break;
1115
+					case 'zip':
1116
+						$QST_values = array(
1117
+							'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1118
+							'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1119
+							'QST_system'        => 'zip',
1120
+							'QST_type'          => 'TEXT',
1121
+							'QST_required'      => 0,
1122
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1123
+							'QST_order'         => 9,
1124
+							'QST_admin_only'    => 0,
1125
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1126
+							'QST_wp_user'       => self::get_default_creator_id(),
1127
+							'QST_deleted'       => 0,
1128
+						);
1129
+						break;
1130
+					case 'phone':
1131
+						$QST_values = array(
1132
+							'QST_display_text'  => __('Phone Number', 'event_espresso'),
1133
+							'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1134
+							'QST_system'        => 'phone',
1135
+							'QST_type'          => 'TEXT',
1136
+							'QST_required'      => 0,
1137
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1138
+							'QST_order'         => 10,
1139
+							'QST_admin_only'    => 0,
1140
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1141
+							'QST_wp_user'       => self::get_default_creator_id(),
1142
+							'QST_deleted'       => 0,
1143
+						);
1144
+						break;
1145
+				}
1146
+				if (! empty($QST_values)) {
1147
+					// insert system question
1148
+					$wpdb->insert(
1149
+						$table_name,
1150
+						$QST_values,
1151
+						array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1152
+					);
1153
+					$QST_ID = $wpdb->insert_id;
1154
+					// QUESTION GROUP QUESTIONS
1155
+					if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1156
+						$system_question_we_want = EEM_Question_Group::system_personal;
1157
+					} else {
1158
+						$system_question_we_want = EEM_Question_Group::system_address;
1159
+					}
1160
+					if (isset($QSG_IDs[$system_question_we_want])) {
1161
+						$QSG_ID = $QSG_IDs[$system_question_we_want];
1162
+					} else {
1163
+						$id_col = EEM_Question_Group::instance()
1164
+													->get_col(array(array('QSG_system' => $system_question_we_want)));
1165
+						if (is_array($id_col)) {
1166
+							$QSG_ID = reset($id_col);
1167
+						} else {
1168
+							//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
1169
+							EE_Log::instance()->log(
1170
+								__FILE__,
1171
+								__FUNCTION__,
1172
+								sprintf(
1173
+									__(
1174
+										'Could not associate question %1$s to a question group because no system question
1175 1175
                                          group existed',
1176
-                                        'event_espresso'
1177
-                                    ),
1178
-                                    $QST_ID),
1179
-                                'error');
1180
-                            continue;
1181
-                        }
1182
-                    }
1183
-                    // add system questions to groups
1184
-                    $wpdb->insert(
1185
-                        \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1186
-                        array(
1187
-                            'QSG_ID'    => $QSG_ID,
1188
-                            'QST_ID'    => $QST_ID,
1189
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1190
-                        ),
1191
-                        array('%d', '%d', '%d')
1192
-                    );
1193
-                }
1194
-            }
1195
-        }
1196
-    }
1197
-
1198
-
1199
-    /**
1200
-     * Makes sure the default payment method (Invoice) is active.
1201
-     * This used to be done automatically as part of constructing the old gateways config
1202
-     *
1203
-     * @throws \EE_Error
1204
-     */
1205
-    public static function insert_default_payment_methods()
1206
-    {
1207
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1208
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1209
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1210
-        } else {
1211
-            EEM_Payment_Method::instance()->verify_button_urls();
1212
-        }
1213
-    }
1214
-
1215
-    /**
1216
-     * insert_default_status_codes
1217
-     *
1218
-     * @access public
1219
-     * @static
1220
-     * @return void
1221
-     */
1222
-    public static function insert_default_status_codes()
1223
-    {
1224
-
1225
-        global $wpdb;
1226
-
1227
-        if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1228
-
1229
-            $table_name = EEM_Status::instance()->table();
1230
-
1231
-            $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', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1232
-            $wpdb->query($SQL);
1233
-
1234
-            $SQL = "INSERT INTO $table_name
1176
+										'event_espresso'
1177
+									),
1178
+									$QST_ID),
1179
+								'error');
1180
+							continue;
1181
+						}
1182
+					}
1183
+					// add system questions to groups
1184
+					$wpdb->insert(
1185
+						\EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1186
+						array(
1187
+							'QSG_ID'    => $QSG_ID,
1188
+							'QST_ID'    => $QST_ID,
1189
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1190
+						),
1191
+						array('%d', '%d', '%d')
1192
+					);
1193
+				}
1194
+			}
1195
+		}
1196
+	}
1197
+
1198
+
1199
+	/**
1200
+	 * Makes sure the default payment method (Invoice) is active.
1201
+	 * This used to be done automatically as part of constructing the old gateways config
1202
+	 *
1203
+	 * @throws \EE_Error
1204
+	 */
1205
+	public static function insert_default_payment_methods()
1206
+	{
1207
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1208
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1209
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1210
+		} else {
1211
+			EEM_Payment_Method::instance()->verify_button_urls();
1212
+		}
1213
+	}
1214
+
1215
+	/**
1216
+	 * insert_default_status_codes
1217
+	 *
1218
+	 * @access public
1219
+	 * @static
1220
+	 * @return void
1221
+	 */
1222
+	public static function insert_default_status_codes()
1223
+	{
1224
+
1225
+		global $wpdb;
1226
+
1227
+		if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1228
+
1229
+			$table_name = EEM_Status::instance()->table();
1230
+
1231
+			$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', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1232
+			$wpdb->query($SQL);
1233
+
1234
+			$SQL = "INSERT INTO $table_name
1235 1235
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1236 1236
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1237 1237
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1271,521 +1271,521 @@  discard block
 block discarded – undo
1271 1271
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1272 1272
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1273 1273
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1274
-            $wpdb->query($SQL);
1275
-
1276
-        }
1277
-
1278
-    }
1279
-
1280
-
1281
-    /**
1282
-     * create_upload_directories
1283
-     * Creates folders in the uploads directory to facilitate addons and templates
1284
-     *
1285
-     * @access public
1286
-     * @static
1287
-     * @return boolean success of verifying upload directories exist
1288
-     */
1289
-    public static function create_upload_directories()
1290
-    {
1291
-        // Create the required folders
1292
-        $folders = array(
1293
-            EVENT_ESPRESSO_TEMPLATE_DIR,
1294
-            EVENT_ESPRESSO_GATEWAY_DIR,
1295
-            EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1296
-            EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1297
-            EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1298
-        );
1299
-        foreach ($folders as $folder) {
1300
-            try {
1301
-                EEH_File::ensure_folder_exists_and_is_writable($folder);
1302
-                @ chmod($folder, 0755);
1303
-            } catch (EE_Error $e) {
1304
-                EE_Error::add_error(
1305
-                    sprintf(
1306
-                        __('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1307
-                        $folder,
1308
-                        '<br />' . $e->getMessage()
1309
-                    ),
1310
-                    __FILE__, __FUNCTION__, __LINE__
1311
-                );
1312
-                //indicate we'll need to fix this later
1313
-                update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1314
-                return false;
1315
-            }
1316
-        }
1317
-        //just add the .htaccess file to the logs directory to begin with. Even if logging
1318
-        //is disabled, there might be activation errors recorded in there
1319
-        EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1320
-        //remember EE's folders are all good
1321
-        delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1322
-        return true;
1323
-    }
1324
-
1325
-    /**
1326
-     * Whether the upload directories need to be fixed or not.
1327
-     * If EE is installed but filesystem access isn't initially available,
1328
-     * we need to get the user's filesystem credentials and THEN create them,
1329
-     * so there might be period of time when EE is installed but its
1330
-     * upload directories aren't available. This indicates such a state
1331
-     *
1332
-     * @return boolean
1333
-     */
1334
-    public static function upload_directories_incomplete()
1335
-    {
1336
-        return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1337
-    }
1338
-
1339
-
1340
-    /**
1341
-     * generate_default_message_templates
1342
-     *
1343
-     * @static
1344
-     * @throws EE_Error
1345
-     * @return bool     true means new templates were created.
1346
-     *                  false means no templates were created.
1347
-     *                  This is NOT an error flag. To check for errors you will want
1348
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1349
-     */
1350
-    public static function generate_default_message_templates()
1351
-    {
1352
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1353
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1354
-        /*
1274
+			$wpdb->query($SQL);
1275
+
1276
+		}
1277
+
1278
+	}
1279
+
1280
+
1281
+	/**
1282
+	 * create_upload_directories
1283
+	 * Creates folders in the uploads directory to facilitate addons and templates
1284
+	 *
1285
+	 * @access public
1286
+	 * @static
1287
+	 * @return boolean success of verifying upload directories exist
1288
+	 */
1289
+	public static function create_upload_directories()
1290
+	{
1291
+		// Create the required folders
1292
+		$folders = array(
1293
+			EVENT_ESPRESSO_TEMPLATE_DIR,
1294
+			EVENT_ESPRESSO_GATEWAY_DIR,
1295
+			EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1296
+			EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1297
+			EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1298
+		);
1299
+		foreach ($folders as $folder) {
1300
+			try {
1301
+				EEH_File::ensure_folder_exists_and_is_writable($folder);
1302
+				@ chmod($folder, 0755);
1303
+			} catch (EE_Error $e) {
1304
+				EE_Error::add_error(
1305
+					sprintf(
1306
+						__('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1307
+						$folder,
1308
+						'<br />' . $e->getMessage()
1309
+					),
1310
+					__FILE__, __FUNCTION__, __LINE__
1311
+				);
1312
+				//indicate we'll need to fix this later
1313
+				update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1314
+				return false;
1315
+			}
1316
+		}
1317
+		//just add the .htaccess file to the logs directory to begin with. Even if logging
1318
+		//is disabled, there might be activation errors recorded in there
1319
+		EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1320
+		//remember EE's folders are all good
1321
+		delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1322
+		return true;
1323
+	}
1324
+
1325
+	/**
1326
+	 * Whether the upload directories need to be fixed or not.
1327
+	 * If EE is installed but filesystem access isn't initially available,
1328
+	 * we need to get the user's filesystem credentials and THEN create them,
1329
+	 * so there might be period of time when EE is installed but its
1330
+	 * upload directories aren't available. This indicates such a state
1331
+	 *
1332
+	 * @return boolean
1333
+	 */
1334
+	public static function upload_directories_incomplete()
1335
+	{
1336
+		return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1337
+	}
1338
+
1339
+
1340
+	/**
1341
+	 * generate_default_message_templates
1342
+	 *
1343
+	 * @static
1344
+	 * @throws EE_Error
1345
+	 * @return bool     true means new templates were created.
1346
+	 *                  false means no templates were created.
1347
+	 *                  This is NOT an error flag. To check for errors you will want
1348
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1349
+	 */
1350
+	public static function generate_default_message_templates()
1351
+	{
1352
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1353
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1354
+		/*
1355 1355
          * This first method is taking care of ensuring any default messengers
1356 1356
          * that should be made active and have templates generated are done.
1357 1357
          */
1358
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1359
-            $message_resource_manager
1360
-        );
1361
-        /**
1362
-         * This method is verifying there are no NEW default message types
1363
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1364
-         */
1365
-        $new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1366
-            $message_resource_manager
1367
-        );
1368
-        //after all is done, let's persist these changes to the db.
1369
-        $message_resource_manager->update_has_activated_messengers_option();
1370
-        $message_resource_manager->update_active_messengers_option();
1371
-        // will return true if either of these are true.  Otherwise will return false.
1372
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1373
-    }
1374
-
1375
-
1376
-
1377
-    /**
1378
-     * @param \EE_Message_Resource_Manager $message_resource_manager
1379
-     * @return array|bool
1380
-     * @throws \EE_Error
1381
-     */
1382
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1383
-        EE_Message_Resource_Manager $message_resource_manager
1384
-    ) {
1385
-        /** @type EE_messenger[] $active_messengers */
1386
-        $active_messengers = $message_resource_manager->active_messengers();
1387
-        $installed_message_types = $message_resource_manager->installed_message_types();
1388
-        $templates_created = false;
1389
-        foreach ($active_messengers as $active_messenger) {
1390
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1391
-            $default_message_type_names_to_activate = array();
1392
-            // looping through each default message type reported by the messenger
1393
-            // and setup the actual message types to activate.
1394
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1395
-                // if already active or has already been activated before we skip
1396
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1397
-                // we also skip if the message type is not installed.
1398
-                if (
1399
-                    $message_resource_manager->has_message_type_been_activated_for_messenger(
1400
-                        $default_message_type_name_for_messenger,
1401
-                        $active_messenger->name
1402
-                    )
1403
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1404
-                        $active_messenger->name,
1405
-                        $default_message_type_name_for_messenger
1406
-                    )
1407
-                    || ! isset($installed_message_types[$default_message_type_name_for_messenger])
1408
-                ) {
1409
-                    continue;
1410
-                }
1411
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1412
-            }
1413
-            //let's activate!
1414
-            $message_resource_manager->ensure_message_types_are_active(
1415
-                $default_message_type_names_to_activate,
1416
-                $active_messenger->name,
1417
-                false
1418
-            );
1419
-            //activate the templates for these message types
1420
-            if ( ! empty($default_message_type_names_to_activate)) {
1421
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1422
-                    $active_messenger->name,
1423
-                    $default_message_type_names_for_messenger,
1424
-                    '',
1425
-                    true
1426
-                );
1427
-            }
1428
-        }
1429
-        return $templates_created;
1430
-    }
1431
-
1432
-
1433
-
1434
-    /**
1435
-     * This will activate and generate default messengers and default message types for those messengers.
1436
-     *
1437
-     * @param EE_message_Resource_Manager $message_resource_manager
1438
-     * @return array|bool  True means there were default messengers and message type templates generated.
1439
-     *                     False means that there were no templates generated
1440
-     *                     (which could simply mean there are no default message types for a messenger).
1441
-     * @throws EE_Error
1442
-     */
1443
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1444
-        EE_Message_Resource_Manager $message_resource_manager
1445
-    ) {
1446
-        /** @type EE_messenger[] $messengers_to_generate */
1447
-        $messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1448
-        $installed_message_types = $message_resource_manager->installed_message_types();
1449
-        $templates_generated = false;
1450
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1451
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1452
-            //verify the default message types match an installed message type.
1453
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1454
-                if (
1455
-                    ! isset($installed_message_types[$name])
1456
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1457
-                        $name,
1458
-                        $messenger_to_generate->name
1459
-                    )
1460
-                ) {
1461
-                    unset($default_message_type_names_for_messenger[$key]);
1462
-                }
1463
-            }
1464
-            // in previous iterations, the active_messengers option in the db
1465
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1466
-            // This comment is left here just in case we discover that we _do_ need to update before
1467
-            // passing off to create templates (after the refactor is done).
1468
-            // @todo remove this comment when determined not necessary.
1469
-            $message_resource_manager->activate_messenger(
1470
-                $messenger_to_generate->name,
1471
-                $default_message_type_names_for_messenger,
1472
-                false
1473
-            );
1474
-            //create any templates needing created (or will reactivate templates already generated as necessary).
1475
-            if ( ! empty($default_message_type_names_for_messenger)) {
1476
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1477
-                    $messenger_to_generate->name,
1478
-                    $default_message_type_names_for_messenger,
1479
-                    '',
1480
-                    true
1481
-                );
1482
-            }
1483
-        }
1484
-        return $templates_generated;
1485
-    }
1486
-
1487
-
1488
-    /**
1489
-     * This returns the default messengers to generate templates for on activation of EE.
1490
-     * It considers:
1491
-     * - whether a messenger is already active in the db.
1492
-     * - whether a messenger has been made active at any time in the past.
1493
-     *
1494
-     * @static
1495
-     * @param  EE_Message_Resource_Manager $message_resource_manager
1496
-     * @return EE_messenger[]
1497
-     */
1498
-    protected static function _get_default_messengers_to_generate_on_activation(
1499
-        EE_Message_Resource_Manager $message_resource_manager
1500
-    ) {
1501
-        $active_messengers    = $message_resource_manager->active_messengers();
1502
-        $installed_messengers = $message_resource_manager->installed_messengers();
1503
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1504
-
1505
-        $messengers_to_generate = array();
1506
-        foreach ($installed_messengers as $installed_messenger) {
1507
-            //if installed messenger is a messenger that should be activated on install
1508
-            //and is not already active
1509
-            //and has never been activated
1510
-            if (
1511
-                ! $installed_messenger->activate_on_install
1512
-                || isset($active_messengers[$installed_messenger->name])
1513
-                || isset($has_activated[$installed_messenger->name])
1514
-            ) {
1515
-                continue;
1516
-            }
1517
-            $messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1518
-        }
1519
-        return $messengers_to_generate;
1520
-    }
1521
-
1522
-
1523
-    /**
1524
-     * This simply validates active message types to ensure they actually match installed
1525
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1526
-     * rows are set inactive.
1527
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1528
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1529
-     * are still handled in here.
1530
-     *
1531
-     * @since 4.3.1
1532
-     * @return void
1533
-     */
1534
-    public static function validate_messages_system()
1535
-    {
1536
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1537
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1538
-        $message_resource_manager->validate_active_message_types_are_installed();
1539
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1540
-    }
1541
-
1542
-
1543
-    /**
1544
-     * create_no_ticket_prices_array
1545
-     *
1546
-     * @access public
1547
-     * @static
1548
-     * @return void
1549
-     */
1550
-    public static function create_no_ticket_prices_array()
1551
-    {
1552
-        // this creates an array for tracking events that have no active ticket prices created
1553
-        // this allows us to warn admins of the situation so that it can be corrected
1554
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1555
-        if (! $espresso_no_ticket_prices) {
1556
-            add_option('ee_no_ticket_prices', array(), '', false);
1557
-        }
1558
-    }
1559
-
1560
-
1561
-    /**
1562
-     * plugin_deactivation
1563
-     *
1564
-     * @access public
1565
-     * @static
1566
-     * @return void
1567
-     */
1568
-    public static function plugin_deactivation()
1569
-    {
1570
-    }
1571
-
1572
-
1573
-    /**
1574
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1575
-     * (like post meta or term relations)
1576
-     *
1577
-     * @global wpdb $wpdb
1578
-     * @throws \EE_Error
1579
-     */
1580
-    public static function delete_all_espresso_cpt_data()
1581
-    {
1582
-        global $wpdb;
1583
-        //get all the CPT post_types
1584
-        $ee_post_types = array();
1585
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1586
-            if (method_exists($model_name, 'instance')) {
1587
-                $model_obj = call_user_func(array($model_name, 'instance'));
1588
-                if ($model_obj instanceof EEM_CPT_Base) {
1589
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1590
-                }
1591
-            }
1592
-        }
1593
-        //get all our CPTs
1594
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1595
-        $cpt_ids = $wpdb->get_col($query);
1596
-        //delete each post meta and term relations too
1597
-        foreach ($cpt_ids as $post_id) {
1598
-            wp_delete_post($post_id, true);
1599
-        }
1600
-    }
1601
-
1602
-    /**
1603
-     * Deletes all EE custom tables
1604
-     *
1605
-     * @return array
1606
-     */
1607
-    public static function drop_espresso_tables()
1608
-    {
1609
-        $tables = array();
1610
-        // load registry
1611
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1612
-            if (method_exists($model_name, 'instance')) {
1613
-                $model_obj = call_user_func(array($model_name, 'instance'));
1614
-                if ($model_obj instanceof EEM_Base) {
1615
-                    foreach ($model_obj->get_tables() as $table) {
1616
-                        if (strpos($table->get_table_name(), 'esp_')
1617
-                            &&
1618
-                            (
1619
-                                is_main_site()//main site? nuke them all
1620
-                                || ! $table->is_global()//not main site,but not global either. nuke it
1621
-                            )
1622
-                        ) {
1623
-                            $tables[] = $table->get_table_name();
1624
-                        }
1625
-                    }
1626
-                }
1627
-            }
1628
-        }
1629
-
1630
-        //there are some tables whose models were removed.
1631
-        //they should be removed when removing all EE core's data
1632
-        $tables_without_models = array(
1633
-            'esp_promotion',
1634
-            'esp_promotion_applied',
1635
-            'esp_promotion_object',
1636
-            'esp_promotion_rule',
1637
-            'esp_rule',
1638
-        );
1639
-        foreach ($tables_without_models as $table) {
1640
-            $tables[] = $table;
1641
-        }
1642
-        return \EEH_Activation::getTableManager()->dropTables($tables);
1643
-    }
1644
-
1645
-
1646
-
1647
-    /**
1648
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1649
-     * each table name provided has a wpdb prefix attached, and that it exists.
1650
-     * Returns the list actually deleted
1651
-     *
1652
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1653
-     * @global WPDB $wpdb
1654
-     * @param array $table_names
1655
-     * @return array of table names which we deleted
1656
-     */
1657
-    public static function drop_tables($table_names)
1658
-    {
1659
-        return \EEH_Activation::getTableManager()->dropTables($table_names);
1660
-    }
1661
-
1662
-
1663
-
1664
-    /**
1665
-     * plugin_uninstall
1666
-     *
1667
-     * @access public
1668
-     * @static
1669
-     * @param bool $remove_all
1670
-     * @return void
1671
-     */
1672
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1673
-    {
1674
-        global $wpdb;
1675
-        self::drop_espresso_tables();
1676
-        $wp_options_to_delete = array(
1677
-            'ee_no_ticket_prices'                => true,
1678
-            'ee_active_messengers'               => true,
1679
-            'ee_has_activated_messenger'         => true,
1680
-            'ee_flush_rewrite_rules'             => true,
1681
-            'ee_config'                          => false,
1682
-            'ee_data_migration_current_db_state' => true,
1683
-            'ee_data_migration_mapping_'         => false,
1684
-            'ee_data_migration_script_'          => false,
1685
-            'ee_data_migrations'                 => true,
1686
-            'ee_dms_map'                         => false,
1687
-            'ee_notices'                         => true,
1688
-            'lang_file_check_'                   => false,
1689
-            'ee_maintenance_mode'                => true,
1690
-            'ee_ueip_optin'                      => true,
1691
-            'ee_ueip_has_notified'               => true,
1692
-            'ee_plugin_activation_errors'        => true,
1693
-            'ee_id_mapping_from'                 => false,
1694
-            'espresso_persistent_admin_notices'  => true,
1695
-            'ee_encryption_key'                  => true,
1696
-            'pue_force_upgrade_'                 => false,
1697
-            'pue_json_error_'                    => false,
1698
-            'pue_install_key_'                   => false,
1699
-            'pue_verification_error_'            => false,
1700
-            'pu_dismissed_upgrade_'              => false,
1701
-            'external_updates-'                  => false,
1702
-            'ee_extra_data'                      => true,
1703
-            'ee_ssn_'                            => false,
1704
-            'ee_rss_'                            => false,
1705
-            'ee_rte_n_tx_'                       => false,
1706
-            'ee_pers_admin_notices'              => true,
1707
-            'ee_job_parameters_'                 => false,
1708
-            'ee_upload_directories_incomplete'   => true,
1709
-            'ee_verified_db_collations'          => true,
1710
-        );
1711
-        if (is_main_site()) {
1712
-            $wp_options_to_delete['ee_network_config'] = true;
1713
-        }
1714
-        $undeleted_options = array();
1715
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1716
-            if ($no_wildcard) {
1717
-                if ( ! delete_option($option_name)) {
1718
-                    $undeleted_options[] = $option_name;
1719
-                }
1720
-            } else {
1721
-                $option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1722
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1723
-                    if ( ! delete_option($option_name_from_wildcard)) {
1724
-                        $undeleted_options[] = $option_name_from_wildcard;
1725
-                    }
1726
-                }
1727
-            }
1728
-        }
1729
-        //also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1730
-        remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1731
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1732
-            $db_update_sans_ee4 = array();
1733
-            foreach ($espresso_db_update as $version => $times_activated) {
1734
-                if ((string)$version[0] === '3') {//if its NON EE4
1735
-                    $db_update_sans_ee4[$version] = $times_activated;
1736
-                }
1737
-            }
1738
-            update_option('espresso_db_update', $db_update_sans_ee4);
1739
-        }
1740
-        $errors = '';
1741
-        if ( ! empty($undeleted_options)) {
1742
-            $errors .= sprintf(
1743
-                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1744
-                '<br/>',
1745
-                implode(',<br/>', $undeleted_options)
1746
-            );
1747
-        }
1748
-        if ( ! empty($errors)) {
1749
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1750
-        }
1751
-    }
1752
-
1753
-    /**
1754
-     * Gets the mysql error code from the last used query by wpdb
1755
-     *
1756
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1757
-     */
1758
-    public static function last_wpdb_error_code()
1759
-    {
1760
-        global $wpdb;
1761
-        if ($wpdb->use_mysqli) {
1762
-            return mysqli_errno($wpdb->dbh);
1763
-        } else {
1764
-            return mysql_errno($wpdb->dbh);
1765
-        }
1766
-    }
1767
-
1768
-    /**
1769
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1770
-     *
1771
-     * @global wpdb  $wpdb
1772
-     * @deprecated instead use TableAnalysis::tableExists()
1773
-     * @param string $table_name with or without $wpdb->prefix
1774
-     * @return boolean
1775
-     */
1776
-    public static function table_exists($table_name)
1777
-    {
1778
-        return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1779
-    }
1780
-
1781
-    /**
1782
-     * Resets the cache on EEH_Activation
1783
-     */
1784
-    public static function reset()
1785
-    {
1786
-        self::$_default_creator_id                             = null;
1787
-        self::$_initialized_db_content_already_in_this_request = false;
1788
-    }
1358
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1359
+			$message_resource_manager
1360
+		);
1361
+		/**
1362
+		 * This method is verifying there are no NEW default message types
1363
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1364
+		 */
1365
+		$new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1366
+			$message_resource_manager
1367
+		);
1368
+		//after all is done, let's persist these changes to the db.
1369
+		$message_resource_manager->update_has_activated_messengers_option();
1370
+		$message_resource_manager->update_active_messengers_option();
1371
+		// will return true if either of these are true.  Otherwise will return false.
1372
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1373
+	}
1374
+
1375
+
1376
+
1377
+	/**
1378
+	 * @param \EE_Message_Resource_Manager $message_resource_manager
1379
+	 * @return array|bool
1380
+	 * @throws \EE_Error
1381
+	 */
1382
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1383
+		EE_Message_Resource_Manager $message_resource_manager
1384
+	) {
1385
+		/** @type EE_messenger[] $active_messengers */
1386
+		$active_messengers = $message_resource_manager->active_messengers();
1387
+		$installed_message_types = $message_resource_manager->installed_message_types();
1388
+		$templates_created = false;
1389
+		foreach ($active_messengers as $active_messenger) {
1390
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1391
+			$default_message_type_names_to_activate = array();
1392
+			// looping through each default message type reported by the messenger
1393
+			// and setup the actual message types to activate.
1394
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1395
+				// if already active or has already been activated before we skip
1396
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1397
+				// we also skip if the message type is not installed.
1398
+				if (
1399
+					$message_resource_manager->has_message_type_been_activated_for_messenger(
1400
+						$default_message_type_name_for_messenger,
1401
+						$active_messenger->name
1402
+					)
1403
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1404
+						$active_messenger->name,
1405
+						$default_message_type_name_for_messenger
1406
+					)
1407
+					|| ! isset($installed_message_types[$default_message_type_name_for_messenger])
1408
+				) {
1409
+					continue;
1410
+				}
1411
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1412
+			}
1413
+			//let's activate!
1414
+			$message_resource_manager->ensure_message_types_are_active(
1415
+				$default_message_type_names_to_activate,
1416
+				$active_messenger->name,
1417
+				false
1418
+			);
1419
+			//activate the templates for these message types
1420
+			if ( ! empty($default_message_type_names_to_activate)) {
1421
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1422
+					$active_messenger->name,
1423
+					$default_message_type_names_for_messenger,
1424
+					'',
1425
+					true
1426
+				);
1427
+			}
1428
+		}
1429
+		return $templates_created;
1430
+	}
1431
+
1432
+
1433
+
1434
+	/**
1435
+	 * This will activate and generate default messengers and default message types for those messengers.
1436
+	 *
1437
+	 * @param EE_message_Resource_Manager $message_resource_manager
1438
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1439
+	 *                     False means that there were no templates generated
1440
+	 *                     (which could simply mean there are no default message types for a messenger).
1441
+	 * @throws EE_Error
1442
+	 */
1443
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1444
+		EE_Message_Resource_Manager $message_resource_manager
1445
+	) {
1446
+		/** @type EE_messenger[] $messengers_to_generate */
1447
+		$messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1448
+		$installed_message_types = $message_resource_manager->installed_message_types();
1449
+		$templates_generated = false;
1450
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1451
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1452
+			//verify the default message types match an installed message type.
1453
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1454
+				if (
1455
+					! isset($installed_message_types[$name])
1456
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1457
+						$name,
1458
+						$messenger_to_generate->name
1459
+					)
1460
+				) {
1461
+					unset($default_message_type_names_for_messenger[$key]);
1462
+				}
1463
+			}
1464
+			// in previous iterations, the active_messengers option in the db
1465
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1466
+			// This comment is left here just in case we discover that we _do_ need to update before
1467
+			// passing off to create templates (after the refactor is done).
1468
+			// @todo remove this comment when determined not necessary.
1469
+			$message_resource_manager->activate_messenger(
1470
+				$messenger_to_generate->name,
1471
+				$default_message_type_names_for_messenger,
1472
+				false
1473
+			);
1474
+			//create any templates needing created (or will reactivate templates already generated as necessary).
1475
+			if ( ! empty($default_message_type_names_for_messenger)) {
1476
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1477
+					$messenger_to_generate->name,
1478
+					$default_message_type_names_for_messenger,
1479
+					'',
1480
+					true
1481
+				);
1482
+			}
1483
+		}
1484
+		return $templates_generated;
1485
+	}
1486
+
1487
+
1488
+	/**
1489
+	 * This returns the default messengers to generate templates for on activation of EE.
1490
+	 * It considers:
1491
+	 * - whether a messenger is already active in the db.
1492
+	 * - whether a messenger has been made active at any time in the past.
1493
+	 *
1494
+	 * @static
1495
+	 * @param  EE_Message_Resource_Manager $message_resource_manager
1496
+	 * @return EE_messenger[]
1497
+	 */
1498
+	protected static function _get_default_messengers_to_generate_on_activation(
1499
+		EE_Message_Resource_Manager $message_resource_manager
1500
+	) {
1501
+		$active_messengers    = $message_resource_manager->active_messengers();
1502
+		$installed_messengers = $message_resource_manager->installed_messengers();
1503
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1504
+
1505
+		$messengers_to_generate = array();
1506
+		foreach ($installed_messengers as $installed_messenger) {
1507
+			//if installed messenger is a messenger that should be activated on install
1508
+			//and is not already active
1509
+			//and has never been activated
1510
+			if (
1511
+				! $installed_messenger->activate_on_install
1512
+				|| isset($active_messengers[$installed_messenger->name])
1513
+				|| isset($has_activated[$installed_messenger->name])
1514
+			) {
1515
+				continue;
1516
+			}
1517
+			$messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1518
+		}
1519
+		return $messengers_to_generate;
1520
+	}
1521
+
1522
+
1523
+	/**
1524
+	 * This simply validates active message types to ensure they actually match installed
1525
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1526
+	 * rows are set inactive.
1527
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1528
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1529
+	 * are still handled in here.
1530
+	 *
1531
+	 * @since 4.3.1
1532
+	 * @return void
1533
+	 */
1534
+	public static function validate_messages_system()
1535
+	{
1536
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1537
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1538
+		$message_resource_manager->validate_active_message_types_are_installed();
1539
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1540
+	}
1541
+
1542
+
1543
+	/**
1544
+	 * create_no_ticket_prices_array
1545
+	 *
1546
+	 * @access public
1547
+	 * @static
1548
+	 * @return void
1549
+	 */
1550
+	public static function create_no_ticket_prices_array()
1551
+	{
1552
+		// this creates an array for tracking events that have no active ticket prices created
1553
+		// this allows us to warn admins of the situation so that it can be corrected
1554
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1555
+		if (! $espresso_no_ticket_prices) {
1556
+			add_option('ee_no_ticket_prices', array(), '', false);
1557
+		}
1558
+	}
1559
+
1560
+
1561
+	/**
1562
+	 * plugin_deactivation
1563
+	 *
1564
+	 * @access public
1565
+	 * @static
1566
+	 * @return void
1567
+	 */
1568
+	public static function plugin_deactivation()
1569
+	{
1570
+	}
1571
+
1572
+
1573
+	/**
1574
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1575
+	 * (like post meta or term relations)
1576
+	 *
1577
+	 * @global wpdb $wpdb
1578
+	 * @throws \EE_Error
1579
+	 */
1580
+	public static function delete_all_espresso_cpt_data()
1581
+	{
1582
+		global $wpdb;
1583
+		//get all the CPT post_types
1584
+		$ee_post_types = array();
1585
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1586
+			if (method_exists($model_name, 'instance')) {
1587
+				$model_obj = call_user_func(array($model_name, 'instance'));
1588
+				if ($model_obj instanceof EEM_CPT_Base) {
1589
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1590
+				}
1591
+			}
1592
+		}
1593
+		//get all our CPTs
1594
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1595
+		$cpt_ids = $wpdb->get_col($query);
1596
+		//delete each post meta and term relations too
1597
+		foreach ($cpt_ids as $post_id) {
1598
+			wp_delete_post($post_id, true);
1599
+		}
1600
+	}
1601
+
1602
+	/**
1603
+	 * Deletes all EE custom tables
1604
+	 *
1605
+	 * @return array
1606
+	 */
1607
+	public static function drop_espresso_tables()
1608
+	{
1609
+		$tables = array();
1610
+		// load registry
1611
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1612
+			if (method_exists($model_name, 'instance')) {
1613
+				$model_obj = call_user_func(array($model_name, 'instance'));
1614
+				if ($model_obj instanceof EEM_Base) {
1615
+					foreach ($model_obj->get_tables() as $table) {
1616
+						if (strpos($table->get_table_name(), 'esp_')
1617
+							&&
1618
+							(
1619
+								is_main_site()//main site? nuke them all
1620
+								|| ! $table->is_global()//not main site,but not global either. nuke it
1621
+							)
1622
+						) {
1623
+							$tables[] = $table->get_table_name();
1624
+						}
1625
+					}
1626
+				}
1627
+			}
1628
+		}
1629
+
1630
+		//there are some tables whose models were removed.
1631
+		//they should be removed when removing all EE core's data
1632
+		$tables_without_models = array(
1633
+			'esp_promotion',
1634
+			'esp_promotion_applied',
1635
+			'esp_promotion_object',
1636
+			'esp_promotion_rule',
1637
+			'esp_rule',
1638
+		);
1639
+		foreach ($tables_without_models as $table) {
1640
+			$tables[] = $table;
1641
+		}
1642
+		return \EEH_Activation::getTableManager()->dropTables($tables);
1643
+	}
1644
+
1645
+
1646
+
1647
+	/**
1648
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1649
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1650
+	 * Returns the list actually deleted
1651
+	 *
1652
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1653
+	 * @global WPDB $wpdb
1654
+	 * @param array $table_names
1655
+	 * @return array of table names which we deleted
1656
+	 */
1657
+	public static function drop_tables($table_names)
1658
+	{
1659
+		return \EEH_Activation::getTableManager()->dropTables($table_names);
1660
+	}
1661
+
1662
+
1663
+
1664
+	/**
1665
+	 * plugin_uninstall
1666
+	 *
1667
+	 * @access public
1668
+	 * @static
1669
+	 * @param bool $remove_all
1670
+	 * @return void
1671
+	 */
1672
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1673
+	{
1674
+		global $wpdb;
1675
+		self::drop_espresso_tables();
1676
+		$wp_options_to_delete = array(
1677
+			'ee_no_ticket_prices'                => true,
1678
+			'ee_active_messengers'               => true,
1679
+			'ee_has_activated_messenger'         => true,
1680
+			'ee_flush_rewrite_rules'             => true,
1681
+			'ee_config'                          => false,
1682
+			'ee_data_migration_current_db_state' => true,
1683
+			'ee_data_migration_mapping_'         => false,
1684
+			'ee_data_migration_script_'          => false,
1685
+			'ee_data_migrations'                 => true,
1686
+			'ee_dms_map'                         => false,
1687
+			'ee_notices'                         => true,
1688
+			'lang_file_check_'                   => false,
1689
+			'ee_maintenance_mode'                => true,
1690
+			'ee_ueip_optin'                      => true,
1691
+			'ee_ueip_has_notified'               => true,
1692
+			'ee_plugin_activation_errors'        => true,
1693
+			'ee_id_mapping_from'                 => false,
1694
+			'espresso_persistent_admin_notices'  => true,
1695
+			'ee_encryption_key'                  => true,
1696
+			'pue_force_upgrade_'                 => false,
1697
+			'pue_json_error_'                    => false,
1698
+			'pue_install_key_'                   => false,
1699
+			'pue_verification_error_'            => false,
1700
+			'pu_dismissed_upgrade_'              => false,
1701
+			'external_updates-'                  => false,
1702
+			'ee_extra_data'                      => true,
1703
+			'ee_ssn_'                            => false,
1704
+			'ee_rss_'                            => false,
1705
+			'ee_rte_n_tx_'                       => false,
1706
+			'ee_pers_admin_notices'              => true,
1707
+			'ee_job_parameters_'                 => false,
1708
+			'ee_upload_directories_incomplete'   => true,
1709
+			'ee_verified_db_collations'          => true,
1710
+		);
1711
+		if (is_main_site()) {
1712
+			$wp_options_to_delete['ee_network_config'] = true;
1713
+		}
1714
+		$undeleted_options = array();
1715
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1716
+			if ($no_wildcard) {
1717
+				if ( ! delete_option($option_name)) {
1718
+					$undeleted_options[] = $option_name;
1719
+				}
1720
+			} else {
1721
+				$option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1722
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1723
+					if ( ! delete_option($option_name_from_wildcard)) {
1724
+						$undeleted_options[] = $option_name_from_wildcard;
1725
+					}
1726
+				}
1727
+			}
1728
+		}
1729
+		//also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1730
+		remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1731
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1732
+			$db_update_sans_ee4 = array();
1733
+			foreach ($espresso_db_update as $version => $times_activated) {
1734
+				if ((string)$version[0] === '3') {//if its NON EE4
1735
+					$db_update_sans_ee4[$version] = $times_activated;
1736
+				}
1737
+			}
1738
+			update_option('espresso_db_update', $db_update_sans_ee4);
1739
+		}
1740
+		$errors = '';
1741
+		if ( ! empty($undeleted_options)) {
1742
+			$errors .= sprintf(
1743
+				__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1744
+				'<br/>',
1745
+				implode(',<br/>', $undeleted_options)
1746
+			);
1747
+		}
1748
+		if ( ! empty($errors)) {
1749
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1750
+		}
1751
+	}
1752
+
1753
+	/**
1754
+	 * Gets the mysql error code from the last used query by wpdb
1755
+	 *
1756
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1757
+	 */
1758
+	public static function last_wpdb_error_code()
1759
+	{
1760
+		global $wpdb;
1761
+		if ($wpdb->use_mysqli) {
1762
+			return mysqli_errno($wpdb->dbh);
1763
+		} else {
1764
+			return mysql_errno($wpdb->dbh);
1765
+		}
1766
+	}
1767
+
1768
+	/**
1769
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1770
+	 *
1771
+	 * @global wpdb  $wpdb
1772
+	 * @deprecated instead use TableAnalysis::tableExists()
1773
+	 * @param string $table_name with or without $wpdb->prefix
1774
+	 * @return boolean
1775
+	 */
1776
+	public static function table_exists($table_name)
1777
+	{
1778
+		return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1779
+	}
1780
+
1781
+	/**
1782
+	 * Resets the cache on EEH_Activation
1783
+	 */
1784
+	public static function reset()
1785
+	{
1786
+		self::$_default_creator_id                             = null;
1787
+		self::$_initialized_db_content_already_in_this_request = false;
1788
+	}
1789 1789
 }
1790 1790
 // End of file EEH_Activation.helper.php
1791 1791
 // Location: /helpers/EEH_Activation.core.php
Please login to merge, or discard this patch.