Completed
Branch BUG-10420-iframe-fixes (40ceb4)
by
unknown
48:33 queued 36:05
created

EEH_Activation::create_cron_tasks()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 4
nop 0
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
    exit('No direct script access allowed');
3
}
4
5
6
7
/**
8
 * EEH_Activation Helper
9
 *
10
 * @package        Event Espresso
11
 * @subpackage     /helpers/
12
 * @author         Brent Christensen
13
 */
14
class EEH_Activation
15
{
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',
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:
254
         * Top-level keys are timestamps, and their values are arrays.
255
         * The 2nd level arrays have keys with each of the cron task hook names to run at that time
256
         * and their values are arrays.
257
         * The 3rd level level arrays are keys which are hashes of the cron task's arguments,
258
         *  and their values are the UN-hashed arguments
259
         * eg
260
         * array (size=13)
261
         *		1429903276 =>
262
         *		  array (size=1)
263
         *			'AHEE__EE_Cron_Tasks__update_transaction_with_payment' =>
264
         *			  array (size=1)
265
         *				'561299d6e42c8e079285870ade0e47e6' =>
266
         *				  array (size=2)
267
         *					...
268
         *      ...
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;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $settings; of type stdClass|array is incompatible with the return type documented by EEH_Activation::migrate_old_config_data of type stdClass as it can also be of type array which is not included in this return type.
Loading history...
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 View Code Duplication
        if ( ! $critical_page['post'] instanceof WP_Post) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

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

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

2. Missing use statement

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

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

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

Loading history...
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
        if ( ! EE_Config::instance()->update_espresso_config(false, false)) {
632
            $msg = sprintf(
633
                __(
634
                    'The Event Espresso critical page shortcode for the %s page could not be configured properly.',
635
                    'event_espresso'
636
                ),
637
                $critical_page['name']
638
            );
639
            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
640
        }
641
    }
642
643
644
645
    /**
646
     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
647
     * The role being used to check is filterable.
648
     *
649
     * @since  4.6.0
650
     * @global WPDB $wpdb
651
     * @return mixed null|int WP_user ID or NULL
652
     */
653
    public static function get_default_creator_id()
654
    {
655
        global $wpdb;
656
        if ( ! empty(self::$_default_creator_id)) {
657
            return self::$_default_creator_id;
658
        }/**/
659
        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
660
        //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.
661
        $pre_filtered_id = apply_filters(
662
            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
663
            false,
664
            $role_to_check
665
        );
666
        if ($pre_filtered_id !== false) {
667
            return (int)$pre_filtered_id;
668
        }
669
        $capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
670
        $query = $wpdb->prepare(
671
            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
672
            '%' . $role_to_check . '%'
673
        );
674
        $user_id = $wpdb->get_var($query);
675
        $user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
676
        if ($user_id && (int)$user_id) {
677
            self::$_default_creator_id = (int)$user_id;
678
            return self::$_default_creator_id;
679
        } else {
680
            return null;
681
        }
682
    }
683
684
685
686
    /**
687
     * used by EE and EE addons during plugin activation to create tables.
688
     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
689
     * but includes extra logic regarding activations.
690
     *
691
     * @access public
692
     * @static
693
     * @param string  $table_name              without the $wpdb->prefix
694
     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
695
     *                                         table query)
696
     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
697
     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
698
     *                                         and new once this function is done (ie, you really do want to CREATE a
699
     *                                         table, and expect it to be empty once you're done) leave as FALSE when
700
     *                                         you just want to verify the table exists and matches this definition
701
     *                                         (and if it HAS data in it you want to leave it be)
702
     * @return void
703
     * @throws EE_Error if there are database errors
704
     */
705
    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
706
    {
707
        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
708
            return;
709
        }
710
        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
711
        if ( ! function_exists('dbDelta')) {
712
            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
713
        }
714
        $tableAnalysis = \EEH_Activation::getTableAnalysis();
715
        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
716
        // do we need to first delete an existing version of this table ?
717
        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
718
            // ok, delete the table... but ONLY if it's empty
719
            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
720
            // table is NOT empty, are you SURE you want to delete this table ???
721
            if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $deleted_safely of type integer|false is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
722
                \EEH_Activation::getTableManager()->dropTable($wp_table_name);
723
            } else if ( ! $deleted_safely) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $deleted_safely of type integer|false is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
724
                // so we should be more cautious rather than just dropping tables so easily
725
                error_log(
726
                    sprintf(
727
                        __(
728
                            '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.',
729
                            'event_espresso'
730
                        ),
731
                        $wp_table_name,
732
                        '<br/>',
733
                        'espresso_db_update'
734
                    )
735
                );
736
            }
737
        }
738
        $engine = str_replace('ENGINE=', '', $engine);
739
        \EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
740
    }
741
742
743
744
    /**
745
     *    add_column_if_it_doesn't_exist
746
     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
747
     *
748
     * @access     public
749
     * @static
750
     * @deprecated instead use TableManager::addColumn()
751
     * @param string $table_name  (without "wp_", eg "esp_attendee"
752
     * @param string $column_name
753
     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
754
     *                            'VARCHAR(10)'
755
     * @return bool|int
756
     */
757
    public static function add_column_if_it_doesnt_exist(
758
        $table_name,
759
        $column_name,
760
        $column_info = 'INT UNSIGNED NOT NULL'
761
    ) {
762
        return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
763
    }
764
765
766
    /**
767
     * get_fields_on_table
768
     * Gets all the fields on the database table.
769
     *
770
     * @access     public
771
     * @deprecated instead use TableManager::getTableColumns()
772
     * @static
773
     * @param string $table_name , without prefixed $wpdb->prefix
774
     * @return array of database column names
775
     */
776
    public static function get_fields_on_table($table_name = null)
777
    {
778
        return \EEH_Activation::getTableManager()->getTableColumns($table_name);
779
    }
780
781
782
    /**
783
     * db_table_is_empty
784
     *
785
     * @access     public\
786
     * @deprecated instead use TableAnalysis::tableIsEmpty()
787
     * @static
788
     * @param string $table_name
789
     * @return bool
790
     */
791
    public static function db_table_is_empty($table_name)
792
    {
793
        return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
794
    }
795
796
797
    /**
798
     * delete_db_table_if_empty
799
     *
800
     * @access public
801
     * @static
802
     * @param string $table_name
803
     * @return bool | int
804
     */
805
    public static function delete_db_table_if_empty($table_name)
806
    {
807
        if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
808
            return \EEH_Activation::getTableManager()->dropTable($table_name);
809
        }
810
        return false;
811
    }
812
813
814
    /**
815
     * delete_unused_db_table
816
     *
817
     * @access     public
818
     * @static
819
     * @deprecated instead use TableManager::dropTable()
820
     * @param string $table_name
821
     * @return bool | int
822
     */
823
    public static function delete_unused_db_table($table_name)
824
    {
825
        return \EEH_Activation::getTableManager()->dropTable($table_name);
826
    }
827
828
829
    /**
830
     * drop_index
831
     *
832
     * @access     public
833
     * @static
834
     * @deprecated instead use TableManager::dropIndex()
835
     * @param string $table_name
836
     * @param string $index_name
837
     * @return bool | int
838
     */
839
    public static function drop_index($table_name, $index_name)
840
    {
841
        return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
842
    }
843
844
845
846
    /**
847
     * create_database_tables
848
     *
849
     * @access public
850
     * @static
851
     * @throws EE_Error
852
     * @return boolean success (whether database is setup properly or not)
853
     */
854
    public static function create_database_tables()
855
    {
856
        EE_Registry::instance()->load_core('Data_Migration_Manager');
857
        //find the migration script that sets the database to be compatible with the code
858
        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
859
        if ($dms_name) {
860
            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
861
            $current_data_migration_script->set_migrating(false);
862
            $current_data_migration_script->schema_changes_before_migration();
863
            $current_data_migration_script->schema_changes_after_migration();
864 View Code Duplication
            if ($current_data_migration_script->get_errors()) {
865
                if (WP_DEBUG) {
866
                    foreach ($current_data_migration_script->get_errors() as $error) {
867
                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
868
                    }
869
                } else {
870
                    EE_Error::add_error(
871
                        __(
872
                            'There were errors creating the Event Espresso database tables and Event Espresso has been 
873
                            deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
874
                            'event_espresso'
875
                        )
876
                    );
877
                }
878
                return false;
879
            }
880
            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
881
        } else {
882
            EE_Error::add_error(
883
                __(
884
                    'Could not determine most up-to-date data migration script from which to pull database schema
885
                     structure. So database is probably not setup properly',
886
                    'event_espresso'
887
                ),
888
                __FILE__,
889
                __FUNCTION__,
890
                __LINE__
891
            );
892
            return false;
893
        }
894
        return true;
895
    }
896
897
898
899
    /**
900
     * initialize_system_questions
901
     *
902
     * @access public
903
     * @static
904
     * @return void
905
     */
906
    public static function initialize_system_questions()
907
    {
908
        // QUESTION GROUPS
909
        global $wpdb;
910
        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
911
        $SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
912
        // what we have
913
        $question_groups = $wpdb->get_col($SQL);
914
        // check the response
915
        $question_groups = is_array($question_groups) ? $question_groups : array();
916
        // what we should have
917
        $QSG_systems = array(1, 2);
918
        // loop thru what we should have and compare to what we have
919
        foreach ($QSG_systems as $QSG_system) {
920
            // reset values array
921
            $QSG_values = array();
922
            // 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)
923
            if (! in_array("$QSG_system", $question_groups)) {
924
                // add it
925
                switch ($QSG_system) {
926 View Code Duplication
                    case 1:
927
                        $QSG_values = array(
928
                            'QSG_name'            => __('Personal Information', 'event_espresso'),
929
                            'QSG_identifier'      => 'personal-information-' . time(),
930
                            'QSG_desc'            => '',
931
                            'QSG_order'           => 1,
932
                            'QSG_show_group_name' => 1,
933
                            'QSG_show_group_desc' => 1,
934
                            'QSG_system'          => EEM_Question_Group::system_personal,
935
                            'QSG_deleted'         => 0,
936
                        );
937
                        break;
938 View Code Duplication
                    case 2:
939
                        $QSG_values = array(
940
                            'QSG_name'            => __('Address Information', 'event_espresso'),
941
                            'QSG_identifier'      => 'address-information-' . time(),
942
                            'QSG_desc'            => '',
943
                            'QSG_order'           => 2,
944
                            'QSG_show_group_name' => 1,
945
                            'QSG_show_group_desc' => 1,
946
                            'QSG_system'          => EEM_Question_Group::system_address,
947
                            'QSG_deleted'         => 0,
948
                        );
949
                        break;
950
                }
951
                // make sure we have some values before inserting them
952
                if (! empty($QSG_values)) {
953
                    // insert system question
954
                    $wpdb->insert(
955
                        $table_name,
956
                        $QSG_values,
957
                        array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
958
                    );
959
                    $QSG_IDs[$QSG_system] = $wpdb->insert_id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$QSG_IDs was never initialized. Although not strictly required by PHP, it is generally a good practice to add $QSG_IDs = array(); before regardless.

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

Let’s take a look at an example:

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

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

    // do something with $myArray
}

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

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

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

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

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

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1298
            } catch (EE_Error $e) {
1299
                EE_Error::add_error(
1300
                    sprintf(
1301
                        __('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1302
                        $folder,
1303
                        '<br />' . $e->getMessage()
1304
                    ),
1305
                    __FILE__, __FUNCTION__, __LINE__
1306
                );
1307
                //indicate we'll need to fix this later
1308
                update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1309
                return false;
1310
            }
1311
        }
1312
        //just add the .htaccess file to the logs directory to begin with. Even if logging
1313
        //is disabled, there might be activation errors recorded in there
1314
        EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1315
        //remember EE's folders are all good
1316
        delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1317
        return true;
1318
    }
1319
1320
    /**
1321
     * Whether the upload directories need to be fixed or not.
1322
     * If EE is installed but filesystem access isn't initially available,
1323
     * we need to get the user's filesystem credentials and THEN create them,
1324
     * so there might be period of time when EE is installed but its
1325
     * upload directories aren't available. This indicates such a state
1326
     *
1327
     * @return boolean
1328
     */
1329
    public static function upload_directories_incomplete()
1330
    {
1331
        return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1332
    }
1333
1334
1335
    /**
1336
     * generate_default_message_templates
1337
     *
1338
     * @static
1339
     * @throws EE_Error
1340
     * @return bool     true means new templates were created.
1341
     *                  false means no templates were created.
1342
     *                  This is NOT an error flag. To check for errors you will want
1343
     *                  to use either EE_Error or a try catch for an EE_Error exception.
1344
     */
1345
    public static function generate_default_message_templates()
1346
    {
1347
        /** @type EE_Message_Resource_Manager $message_resource_manager */
1348
        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1349
        /*
1350
         * This first method is taking care of ensuring any default messengers
1351
         * that should be made active and have templates generated are done.
1352
         */
1353
        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1354
            $message_resource_manager
1355
        );
1356
        /**
1357
         * This method is verifying there are no NEW default message types
1358
         * for ACTIVE messengers that need activated (and corresponding templates setup).
1359
         */
1360
        $new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1361
            $message_resource_manager
1362
        );
1363
        //after all is done, let's persist these changes to the db.
1364
        $message_resource_manager->update_has_activated_messengers_option();
1365
        $message_resource_manager->update_active_messengers_option();
1366
        // will return true if either of these are true.  Otherwise will return false.
1367
        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1368
    }
1369
1370
1371
1372
    /**
1373
     * @param \EE_Message_Resource_Manager $message_resource_manager
1374
     * @return array|bool
1375
     * @throws \EE_Error
1376
     */
1377
    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1378
        EE_Message_Resource_Manager $message_resource_manager
1379
    ) {
1380
        /** @type EE_messenger[] $active_messengers */
1381
        $active_messengers = $message_resource_manager->active_messengers();
1382
        $installed_message_types = $message_resource_manager->installed_message_types();
1383
        $templates_created = false;
1384
        foreach ($active_messengers as $active_messenger) {
1385
            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1386
            $default_message_type_names_to_activate = array();
1387
            // looping through each default message type reported by the messenger
1388
            // and setup the actual message types to activate.
1389
            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1390
                // if already active or has already been activated before we skip
1391
                // (otherwise we might reactivate something user's intentionally deactivated.)
1392
                // we also skip if the message type is not installed.
1393
                if (
1394
                    $message_resource_manager->has_message_type_been_activated_for_messenger(
1395
                        $default_message_type_name_for_messenger,
1396
                        $active_messenger->name
1397
                    )
1398
                    || $message_resource_manager->is_message_type_active_for_messenger(
1399
                        $active_messenger->name,
1400
                        $default_message_type_name_for_messenger
1401
                    )
1402
                    || ! isset($installed_message_types[$default_message_type_name_for_messenger])
1403
                ) {
1404
                    continue;
1405
                }
1406
                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1407
            }
1408
            //let's activate!
1409
            $message_resource_manager->ensure_message_types_are_active(
1410
                $default_message_type_names_to_activate,
1411
                $active_messenger->name,
1412
                false
1413
            );
1414
            //activate the templates for these message types
1415
            if ( ! empty($default_message_type_names_to_activate)) {
1416
                $templates_created = EEH_MSG_Template::generate_new_templates(
1417
                    $active_messenger->name,
1418
                    $default_message_type_names_for_messenger,
1419
                    '',
1420
                    true
1421
                );
1422
            }
1423
        }
1424
        return $templates_created;
1425
    }
1426
1427
1428
1429
    /**
1430
     * This will activate and generate default messengers and default message types for those messengers.
1431
     *
1432
     * @param EE_message_Resource_Manager $message_resource_manager
1433
     * @return array|bool  True means there were default messengers and message type templates generated.
1434
     *                     False means that there were no templates generated
1435
     *                     (which could simply mean there are no default message types for a messenger).
1436
     * @throws EE_Error
1437
     */
1438
    protected static function _activate_and_generate_default_messengers_and_message_templates(
1439
        EE_Message_Resource_Manager $message_resource_manager
1440
    ) {
1441
        /** @type EE_messenger[] $messengers_to_generate */
1442
        $messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1443
        $installed_message_types = $message_resource_manager->installed_message_types();
1444
        $templates_generated = false;
1445
        foreach ($messengers_to_generate as $messenger_to_generate) {
1446
            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1447
            //verify the default message types match an installed message type.
1448
            foreach ($default_message_type_names_for_messenger as $key => $name) {
1449
                if (
1450
                    ! isset($installed_message_types[$name])
1451
                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1452
                        $name,
1453
                        $messenger_to_generate->name
1454
                    )
1455
                ) {
1456
                    unset($default_message_type_names_for_messenger[$key]);
1457
                }
1458
            }
1459
            // in previous iterations, the active_messengers option in the db
1460
            // needed updated before calling create templates. however with the changes this may not be necessary.
1461
            // This comment is left here just in case we discover that we _do_ need to update before
1462
            // passing off to create templates (after the refactor is done).
1463
            // @todo remove this comment when determined not necessary.
1464
            $message_resource_manager->activate_messenger(
1465
                $messenger_to_generate->name,
1466
                $default_message_type_names_for_messenger,
1467
                false
1468
            );
1469
            //create any templates needing created (or will reactivate templates already generated as necessary).
1470
            if ( ! empty($default_message_type_names_for_messenger)) {
1471
                $templates_generated = EEH_MSG_Template::generate_new_templates(
1472
                    $messenger_to_generate->name,
1473
                    $default_message_type_names_for_messenger,
1474
                    '',
1475
                    true
1476
                );
1477
            }
1478
        }
1479
        return $templates_generated;
1480
    }
1481
1482
1483
    /**
1484
     * This returns the default messengers to generate templates for on activation of EE.
1485
     * It considers:
1486
     * - whether a messenger is already active in the db.
1487
     * - whether a messenger has been made active at any time in the past.
1488
     *
1489
     * @static
1490
     * @param  EE_Message_Resource_Manager $message_resource_manager
1491
     * @return EE_messenger[]
1492
     */
1493
    protected static function _get_default_messengers_to_generate_on_activation(
1494
        EE_Message_Resource_Manager $message_resource_manager
1495
    ) {
1496
        $active_messengers    = $message_resource_manager->active_messengers();
1497
        $installed_messengers = $message_resource_manager->installed_messengers();
1498
        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1499
1500
        $messengers_to_generate = array();
1501
        foreach ($installed_messengers as $installed_messenger) {
1502
            //if installed messenger is a messenger that should be activated on install
1503
            //and is not already active
1504
            //and has never been activated
1505
            if (
1506
                ! $installed_messenger->activate_on_install
1507
                || isset($active_messengers[$installed_messenger->name])
1508
                || isset($has_activated[$installed_messenger->name])
1509
            ) {
1510
                continue;
1511
            }
1512
            $messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1513
        }
1514
        return $messengers_to_generate;
1515
    }
1516
1517
1518
    /**
1519
     * This simply validates active message types to ensure they actually match installed
1520
     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1521
     * rows are set inactive.
1522
     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1523
     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1524
     * are still handled in here.
1525
     *
1526
     * @since 4.3.1
1527
     * @return void
1528
     */
1529
    public static function validate_messages_system()
1530
    {
1531
        /** @type EE_Message_Resource_Manager $message_resource_manager */
1532
        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1533
        $message_resource_manager->validate_active_message_types_are_installed();
1534
        do_action('AHEE__EEH_Activation__validate_messages_system');
1535
    }
1536
1537
1538
    /**
1539
     * create_no_ticket_prices_array
1540
     *
1541
     * @access public
1542
     * @static
1543
     * @return void
1544
     */
1545
    public static function create_no_ticket_prices_array()
1546
    {
1547
        // this creates an array for tracking events that have no active ticket prices created
1548
        // this allows us to warn admins of the situation so that it can be corrected
1549
        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1550
        if (! $espresso_no_ticket_prices) {
1551
            add_option('ee_no_ticket_prices', array(), '', false);
1552
        }
1553
    }
1554
1555
1556
    /**
1557
     * plugin_deactivation
1558
     *
1559
     * @access public
1560
     * @static
1561
     * @return void
1562
     */
1563
    public static function plugin_deactivation()
1564
    {
1565
    }
1566
1567
1568
    /**
1569
     * Finds all our EE4 custom post types, and deletes them and their associated data
1570
     * (like post meta or term relations)
1571
     *
1572
     * @global wpdb $wpdb
1573
     * @throws \EE_Error
1574
     */
1575
    public static function delete_all_espresso_cpt_data()
1576
    {
1577
        global $wpdb;
1578
        //get all the CPT post_types
1579
        $ee_post_types = array();
1580
        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1581
            if (method_exists($model_name, 'instance')) {
1582
                $model_obj = call_user_func(array($model_name, 'instance'));
1583
                if ($model_obj instanceof EEM_CPT_Base) {
1584
                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1585
                }
1586
            }
1587
        }
1588
        //get all our CPTs
1589
        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1590
        $cpt_ids = $wpdb->get_col($query);
1591
        //delete each post meta and term relations too
1592
        foreach ($cpt_ids as $post_id) {
1593
            wp_delete_post($post_id, true);
1594
        }
1595
    }
1596
1597
    /**
1598
     * Deletes all EE custom tables
1599
     *
1600
     * @return array
1601
     */
1602
    public static function drop_espresso_tables()
1603
    {
1604
        $tables = array();
1605
        // load registry
1606 View Code Duplication
        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1607
            if (method_exists($model_name, 'instance')) {
1608
                $model_obj = call_user_func(array($model_name, 'instance'));
1609
                if ($model_obj instanceof EEM_Base) {
1610
                    foreach ($model_obj->get_tables() as $table) {
1611
                        if (strpos($table->get_table_name(), 'esp_')
1612
                            &&
1613
                            (
1614
                                is_main_site()//main site? nuke them all
1615
                                || ! $table->is_global()//not main site,but not global either. nuke it
1616
                            )
1617
                        ) {
1618
                            $tables[] = $table->get_table_name();
1619
                        }
1620
                    }
1621
                }
1622
            }
1623
        }
1624
1625
        //there are some tables whose models were removed.
1626
        //they should be removed when removing all EE core's data
1627
        $tables_without_models = array(
1628
            'esp_promotion',
1629
            'esp_promotion_applied',
1630
            'esp_promotion_object',
1631
            'esp_promotion_rule',
1632
            'esp_rule',
1633
        );
1634
        foreach ($tables_without_models as $table) {
1635
            $tables[] = $table;
1636
        }
1637
        return \EEH_Activation::getTableManager()->dropTables($tables);
1638
    }
1639
1640
1641
1642
    /**
1643
     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1644
     * each table name provided has a wpdb prefix attached, and that it exists.
1645
     * Returns the list actually deleted
1646
     *
1647
     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1648
     * @global WPDB $wpdb
1649
     * @param array $table_names
1650
     * @return array of table names which we deleted
1651
     */
1652
    public static function drop_tables($table_names)
1653
    {
1654
        return \EEH_Activation::getTableManager()->dropTables($table_names);
1655
    }
1656
1657
1658
1659
    /**
1660
     * plugin_uninstall
1661
     *
1662
     * @access public
1663
     * @static
1664
     * @param bool $remove_all
1665
     * @return void
1666
     */
1667
    public static function delete_all_espresso_tables_and_data($remove_all = true)
1668
    {
1669
        global $wpdb;
1670
        self::drop_espresso_tables();
1671
        $wp_options_to_delete = array(
1672
            'ee_no_ticket_prices'                => true,
1673
            'ee_active_messengers'               => true,
1674
            'ee_has_activated_messenger'         => true,
1675
            'ee_flush_rewrite_rules'             => true,
1676
            'ee_config'                          => false,
1677
            'ee_data_migration_current_db_state' => true,
1678
            'ee_data_migration_mapping_'         => false,
1679
            'ee_data_migration_script_'          => false,
1680
            'ee_data_migrations'                 => true,
1681
            'ee_dms_map'                         => false,
1682
            'ee_notices'                         => true,
1683
            'lang_file_check_'                   => false,
1684
            'ee_maintenance_mode'                => true,
1685
            'ee_ueip_optin'                      => true,
1686
            'ee_ueip_has_notified'               => true,
1687
            'ee_plugin_activation_errors'        => true,
1688
            'ee_id_mapping_from'                 => false,
1689
            'espresso_persistent_admin_notices'  => true,
1690
            'ee_encryption_key'                  => true,
1691
            'pue_force_upgrade_'                 => false,
1692
            'pue_json_error_'                    => false,
1693
            'pue_install_key_'                   => false,
1694
            'pue_verification_error_'            => false,
1695
            'pu_dismissed_upgrade_'              => false,
1696
            'external_updates-'                  => false,
1697
            'ee_extra_data'                      => true,
1698
            'ee_ssn_'                            => false,
1699
            'ee_rss_'                            => false,
1700
            'ee_rte_n_tx_'                       => false,
1701
            'ee_pers_admin_notices'              => true,
1702
            'ee_job_parameters_'                 => false,
1703
            'ee_upload_directories_incomplete'   => true,
1704
            'ee_verified_db_collations'          => true,
1705
        );
1706
        if (is_main_site()) {
1707
            $wp_options_to_delete['ee_network_config'] = true;
1708
        }
1709
        $undeleted_options = array();
1710
        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1711
            if ($no_wildcard) {
1712
                if ( ! delete_option($option_name)) {
1713
                    $undeleted_options[] = $option_name;
1714
                }
1715
            } else {
1716
                $option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1717
                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1718
                    if ( ! delete_option($option_name_from_wildcard)) {
1719
                        $undeleted_options[] = $option_name_from_wildcard;
1720
                    }
1721
                }
1722
            }
1723
        }
1724
        //also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1725
        remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1726
        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1727
            $db_update_sans_ee4 = array();
1728
            foreach ($espresso_db_update as $version => $times_activated) {
1729
                if ((string)$version[0] === '3') {//if its NON EE4
1730
                    $db_update_sans_ee4[$version] = $times_activated;
1731
                }
1732
            }
1733
            update_option('espresso_db_update', $db_update_sans_ee4);
1734
        }
1735
        $errors = '';
1736
        if ( ! empty($undeleted_options)) {
1737
            $errors .= sprintf(
1738
                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1739
                '<br/>',
1740
                implode(',<br/>', $undeleted_options)
1741
            );
1742
        }
1743
        if ( ! empty($errors)) {
1744
            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1745
        }
1746
    }
1747
1748
    /**
1749
     * Gets the mysql error code from the last used query by wpdb
1750
     *
1751
     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1752
     */
1753
    public static function last_wpdb_error_code()
1754
    {
1755
        global $wpdb;
1756
        if ($wpdb->use_mysqli) {
1757
            return mysqli_errno($wpdb->dbh);
1758
        } else {
1759
            return mysql_errno($wpdb->dbh);
1760
        }
1761
    }
1762
1763
    /**
1764
     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1765
     *
1766
     * @global wpdb  $wpdb
1767
     * @deprecated instead use TableAnalysis::tableExists()
1768
     * @param string $table_name with or without $wpdb->prefix
1769
     * @return boolean
1770
     */
1771
    public static function table_exists($table_name)
1772
    {
1773
        return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1774
    }
1775
1776
    /**
1777
     * Resets the cache on EEH_Activation
1778
     */
1779
    public static function reset()
1780
    {
1781
        self::$_default_creator_id                             = null;
1782
        self::$_initialized_db_content_already_in_this_request = false;
1783
    }
1784
}
1785
// End of file EEH_Activation.helper.php
1786
// Location: /helpers/EEH_Activation.core.php
1787