Completed
Branch Gutenberg/event-attendees-bloc... (e27df5)
by
unknown
56:20 queued 41:53
created

setConsentCheckboxLabelText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
use EventEspresso\core\interfaces\ResettableInterface;
4
use EventEspresso\core\services\loaders\LoaderFactory;
5
use EventEspresso\core\services\shortcodes\LegacyShortcodesManager;
6
7
/**
8
 * EE_Config
9
 *
10
 * @package     Event Espresso
11
 * @subpackage  core/
12
 * @author      Brent Christensen
13
 */
14
final class EE_Config implements ResettableInterface
15
{
16
17
    const OPTION_NAME = 'ee_config';
18
19
    const LOG_NAME = 'ee_config_log';
20
21
    const LOG_LENGTH = 100;
22
23
    const ADDON_OPTION_NAMES = 'ee_config_option_names';
24
25
    /**
26
     *    instance of the EE_Config object
27
     *
28
     * @var    EE_Config $_instance
29
     * @access    private
30
     */
31
    private static $_instance;
32
33
    /**
34
     * @var boolean $_logging_enabled
35
     */
36
    private static $_logging_enabled = false;
37
38
    /**
39
     * @var LegacyShortcodesManager $legacy_shortcodes_manager
40
     */
41
    private $legacy_shortcodes_manager;
42
43
    /**
44
     * An StdClass whose property names are addon slugs,
45
     * and values are their config classes
46
     *
47
     * @var StdClass
48
     */
49
    public $addons;
50
51
    /**
52
     * @var EE_Admin_Config
53
     */
54
    public $admin;
55
56
    /**
57
     * @var EE_Core_Config
58
     */
59
    public $core;
60
61
    /**
62
     * @var EE_Currency_Config
63
     */
64
    public $currency;
65
66
    /**
67
     * @var EE_Organization_Config
68
     */
69
    public $organization;
70
71
    /**
72
     * @var EE_Registration_Config
73
     */
74
    public $registration;
75
76
    /**
77
     * @var EE_Template_Config
78
     */
79
    public $template_settings;
80
81
    /**
82
     * Holds EE environment values.
83
     *
84
     * @var EE_Environment_Config
85
     */
86
    public $environment;
87
88
    /**
89
     * settings pertaining to Google maps
90
     *
91
     * @var EE_Map_Config
92
     */
93
    public $map_settings;
94
95
    /**
96
     * settings pertaining to Taxes
97
     *
98
     * @var EE_Tax_Config
99
     */
100
    public $tax_settings;
101
102
    /**
103
     * Settings pertaining to global messages settings.
104
     *
105
     * @var EE_Messages_Config
106
     */
107
    public $messages;
108
109
    /**
110
     * @deprecated
111
     * @var EE_Gateway_Config
112
     */
113
    public $gateway;
114
115
    /**
116
     * @var    array $_addon_option_names
117
     * @access    private
118
     */
119
    private $_addon_option_names = array();
120
121
    /**
122
     * @var    array $_module_route_map
123
     * @access    private
124
     */
125
    private static $_module_route_map = array();
126
127
    /**
128
     * @var    array $_module_forward_map
129
     * @access    private
130
     */
131
    private static $_module_forward_map = array();
132
133
    /**
134
     * @var    array $_module_view_map
135
     * @access    private
136
     */
137
    private static $_module_view_map = array();
138
139
140
    /**
141
     * @singleton method used to instantiate class object
142
     * @access    public
143
     * @return EE_Config instance
144
     */
145
    public static function instance()
146
    {
147
        // check if class object is instantiated, and instantiated properly
148
        if (! self::$_instance instanceof EE_Config) {
149
            self::$_instance = new self();
150
        }
151
        return self::$_instance;
152
    }
153
154
155
    /**
156
     * Resets the config
157
     *
158
     * @param bool    $hard_reset    if TRUE, sets EE_CONFig back to its original settings in the database. If FALSE
159
     *                               (default) leaves the database alone, and merely resets the EE_Config object to
160
     *                               reflect its state in the database
161
     * @param boolean $reinstantiate if TRUE (default) call instance() and return it. Otherwise, just leave
162
     *                               $_instance as NULL. Useful in case you want to forget about the old instance on
163
     *                               EE_Config, but might not be ready to instantiate EE_Config currently (eg if the
164
     *                               site was put into maintenance mode)
165
     * @return EE_Config
166
     */
167
    public static function reset($hard_reset = false, $reinstantiate = true)
168
    {
169
        if (self::$_instance instanceof EE_Config) {
170
            if ($hard_reset) {
171
                self::$_instance->legacy_shortcodes_manager = null;
172
                self::$_instance->_addon_option_names = array();
173
                self::$_instance->_initialize_config();
174
                self::$_instance->update_espresso_config();
175
            }
176
            self::$_instance->update_addon_option_names();
177
        }
178
        self::$_instance = null;
179
        // we don't need to reset the static properties imo because those should
180
        // only change when a module is added or removed. Currently we don't
181
        // support removing a module during a request when it previously existed
182
        if ($reinstantiate) {
183
            return self::instance();
184
        } else {
185
            return null;
186
        }
187
    }
188
189
190
    /**
191
     *    class constructor
192
     *
193
     * @access    private
194
     */
195
    private function __construct()
196
    {
197
        do_action('AHEE__EE_Config__construct__begin', $this);
198
        EE_Config::$_logging_enabled = apply_filters('FHEE__EE_Config___construct__logging_enabled', false);
199
        // setup empty config classes
200
        $this->_initialize_config();
201
        // load existing EE site settings
202
        $this->_load_core_config();
203
        // confirm everything loaded correctly and set filtered defaults if not
204
        $this->_verify_config();
205
        //  register shortcodes and modules
206
        add_action(
207
            'AHEE__EE_System__register_shortcodes_modules_and_widgets',
208
            array($this, 'register_shortcodes_and_modules'),
209
            999
210
        );
211
        //  initialize shortcodes and modules
212
        add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'initialize_shortcodes_and_modules'));
213
        // register widgets
214
        add_action('widgets_init', array($this, 'widgets_init'), 10);
215
        // shutdown
216
        add_action('shutdown', array($this, 'shutdown'), 10);
217
        // construct__end hook
218
        do_action('AHEE__EE_Config__construct__end', $this);
219
        // hardcoded hack
220
        $this->template_settings->current_espresso_theme = 'Espresso_Arabica_2014';
221
    }
222
223
224
    /**
225
     * @return boolean
226
     */
227
    public static function logging_enabled()
228
    {
229
        return self::$_logging_enabled;
230
    }
231
232
233
    /**
234
     * use to get the current theme if needed from static context
235
     *
236
     * @return string current theme set.
237
     */
238
    public static function get_current_theme()
239
    {
240
        return isset(self::$_instance->template_settings->current_espresso_theme)
241
            ? self::$_instance->template_settings->current_espresso_theme : 'Espresso_Arabica_2014';
242
    }
243
244
245
    /**
246
     *        _initialize_config
247
     *
248
     * @access private
249
     * @return void
250
     */
251
    private function _initialize_config()
252
    {
253
        EE_Config::trim_log();
254
        // set defaults
255
        $this->_addon_option_names = get_option(EE_Config::ADDON_OPTION_NAMES, array());
256
        $this->addons = new stdClass();
257
        // set _module_route_map
258
        EE_Config::$_module_route_map = array();
259
        // set _module_forward_map
260
        EE_Config::$_module_forward_map = array();
261
        // set _module_view_map
262
        EE_Config::$_module_view_map = array();
263
    }
264
265
266
    /**
267
     *        load core plugin configuration
268
     *
269
     * @access private
270
     * @return void
271
     */
272
    private function _load_core_config()
273
    {
274
        // load_core_config__start hook
275
        do_action('AHEE__EE_Config___load_core_config__start', $this);
276
        $espresso_config = $this->get_espresso_config();
277
        foreach ($espresso_config as $config => $settings) {
278
            // load_core_config__start hook
279
            $settings = apply_filters(
280
                'FHEE__EE_Config___load_core_config__config_settings',
281
                $settings,
282
                $config,
283
                $this
284
            );
285 View Code Duplication
            if (is_object($settings) && property_exists($this, $config)) {
286
                $this->{$config} = apply_filters('FHEE__EE_Config___load_core_config__' . $config, $settings);
287
                // call configs populate method to ensure any defaults are set for empty values.
288
                if (method_exists($settings, 'populate')) {
289
                    $this->{$config}->populate();
290
                }
291
                if (method_exists($settings, 'do_hooks')) {
292
                    $this->{$config}->do_hooks();
293
                }
294
            }
295
        }
296
        if (apply_filters('FHEE__EE_Config___load_core_config__update_espresso_config', false)) {
297
            $this->update_espresso_config();
298
        }
299
        // load_core_config__end hook
300
        do_action('AHEE__EE_Config___load_core_config__end', $this);
301
    }
302
303
304
    /**
305
     *    _verify_config
306
     *
307
     * @access    protected
308
     * @return    void
309
     */
310
    protected function _verify_config()
311
    {
312
        $this->core = $this->core instanceof EE_Core_Config
313
            ? $this->core
314
            : new EE_Core_Config();
315
        $this->core = apply_filters('FHEE__EE_Config___initialize_config__core', $this->core);
316
        $this->organization = $this->organization instanceof EE_Organization_Config
317
            ? $this->organization
318
            : new EE_Organization_Config();
319
        $this->organization = apply_filters(
320
            'FHEE__EE_Config___initialize_config__organization',
321
            $this->organization
322
        );
323
        $this->currency = $this->currency instanceof EE_Currency_Config
324
            ? $this->currency
325
            : new EE_Currency_Config();
326
        $this->currency = apply_filters('FHEE__EE_Config___initialize_config__currency', $this->currency);
327
        $this->registration = $this->registration instanceof EE_Registration_Config
328
            ? $this->registration
329
            : new EE_Registration_Config();
330
        $this->registration = apply_filters(
331
            'FHEE__EE_Config___initialize_config__registration',
332
            $this->registration
333
        );
334
        $this->admin = $this->admin instanceof EE_Admin_Config
335
            ? $this->admin
336
            : new EE_Admin_Config();
337
        $this->admin = apply_filters('FHEE__EE_Config___initialize_config__admin', $this->admin);
338
        $this->template_settings = $this->template_settings instanceof EE_Template_Config
339
            ? $this->template_settings
340
            : new EE_Template_Config();
341
        $this->template_settings = apply_filters(
342
            'FHEE__EE_Config___initialize_config__template_settings',
343
            $this->template_settings
344
        );
345
        $this->map_settings = $this->map_settings instanceof EE_Map_Config
346
            ? $this->map_settings
347
            : new EE_Map_Config();
348
        $this->map_settings = apply_filters(
349
            'FHEE__EE_Config___initialize_config__map_settings',
350
            $this->map_settings
351
        );
352
        $this->environment = $this->environment instanceof EE_Environment_Config
353
            ? $this->environment
354
            : new EE_Environment_Config();
355
        $this->environment = apply_filters(
356
            'FHEE__EE_Config___initialize_config__environment',
357
            $this->environment
358
        );
359
        $this->tax_settings = $this->tax_settings instanceof EE_Tax_Config
360
            ? $this->tax_settings
361
            : new EE_Tax_Config();
362
        $this->tax_settings = apply_filters(
363
            'FHEE__EE_Config___initialize_config__tax_settings',
364
            $this->tax_settings
365
        );
366
        $this->messages = apply_filters('FHEE__EE_Config__initialize_config__messages', $this->messages);
367
        $this->messages = $this->messages instanceof EE_Messages_Config
368
            ? $this->messages
369
            : new EE_Messages_Config();
370
        $this->gateway = $this->gateway instanceof EE_Gateway_Config
0 ignored issues
show
Deprecated Code introduced by
The property EE_Config::$gateway has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
371
            ? $this->gateway
0 ignored issues
show
Deprecated Code introduced by
The property EE_Config::$gateway has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
372
            : new EE_Gateway_Config();
0 ignored issues
show
Deprecated Code introduced by
The class EE_Gateway_Config has been deprecated.

This class, trait or interface has been deprecated.

Loading history...
373
        $this->gateway = apply_filters('FHEE__EE_Config___initialize_config__gateway', $this->gateway);
0 ignored issues
show
Deprecated Code introduced by
The property EE_Config::$gateway has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
374
        $this->legacy_shortcodes_manager = null;
375
    }
376
377
378
    /**
379
     *    get_espresso_config
380
     *
381
     * @access    public
382
     * @return    array of espresso config stuff
383
     */
384
    public function get_espresso_config()
385
    {
386
        // grab espresso configuration
387
        return apply_filters(
388
            'FHEE__EE_Config__get_espresso_config__CFG',
389
            get_option(EE_Config::OPTION_NAME, array())
390
        );
391
    }
392
393
394
    /**
395
     *    double_check_config_comparison
396
     *
397
     * @access    public
398
     * @param string $option
399
     * @param        $old_value
400
     * @param        $value
401
     */
402
    public function double_check_config_comparison($option = '', $old_value, $value)
403
    {
404
        // make sure we're checking the ee config
405
        if ($option === EE_Config::OPTION_NAME) {
406
            // run a loose comparison of the old value against the new value for type and properties,
407
            // but NOT exact instance like WP update_option does (ie: NOT type safe comparison)
408
            if ($value != $old_value) {
409
                // if they are NOT the same, then remove the hook,
410
                // which means the subsequent update results will be based solely on the update query results
411
                // the reason we do this is because, as stated above,
412
                // WP update_option performs an exact instance comparison (===) on any update values passed to it
413
                // this happens PRIOR to serialization and any subsequent update.
414
                // If values are found to match their previous old value,
415
                // then WP bails before performing any update.
416
                // Since we are passing the EE_Config object, it is comparing the EXACT instance of the saved version
417
                // it just pulled from the db, with the one being passed to it (which will not match).
418
                // HOWEVER, once the object is serialized and passed off to MySQL to update,
419
                // MySQL MAY ALSO NOT perform the update because
420
                // the string it sees in the db looks the same as the new one it has been passed!!!
421
                // This results in the query returning an "affected rows" value of ZERO,
422
                // which gets returned immediately by WP update_option and looks like an error.
423
                remove_action('update_option', array($this, 'check_config_updated'));
424
            }
425
        }
426
    }
427
428
429
    /**
430
     *    update_espresso_config
431
     *
432
     * @access   public
433
     */
434
    protected function _reset_espresso_addon_config()
435
    {
436
        $this->_addon_option_names = array();
437
        foreach ($this->addons as $addon_name => $addon_config_obj) {
438
            $addon_config_obj = maybe_unserialize($addon_config_obj);
439
            if ($addon_config_obj instanceof EE_Config_Base) {
440
                $this->update_config('addons', $addon_name, $addon_config_obj, false);
441
            }
442
            $this->addons->{$addon_name} = null;
443
        }
444
    }
445
446
447
    /**
448
     *    update_espresso_config
449
     *
450
     * @access   public
451
     * @param   bool $add_success
452
     * @param   bool $add_error
453
     * @return   bool
454
     */
455
    public function update_espresso_config($add_success = false, $add_error = true)
456
    {
457
        // don't allow config updates during WP heartbeats
458
        if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
459
            return false;
460
        }
461
        // commented out the following re: https://events.codebasehq.com/projects/event-espresso/tickets/8197
462
        // $clone = clone( self::$_instance );
463
        // self::$_instance = NULL;
464
        do_action('AHEE__EE_Config__update_espresso_config__begin', $this);
465
        $this->_reset_espresso_addon_config();
466
        // hook into update_option because that happens AFTER the ( $value === $old_value ) conditional
467
        // but BEFORE the actual update occurs
468
        add_action('update_option', array($this, 'double_check_config_comparison'), 1, 3);
469
        // don't want to persist legacy_shortcodes_manager, but don't want to lose it either
470
        $legacy_shortcodes_manager = $this->legacy_shortcodes_manager;
471
        $this->legacy_shortcodes_manager = null;
472
        // now update "ee_config"
473
        $saved = update_option(EE_Config::OPTION_NAME, $this);
474
        $this->legacy_shortcodes_manager = $legacy_shortcodes_manager;
475
        EE_Config::log(EE_Config::OPTION_NAME);
476
        // if not saved... check if the hook we just added still exists;
477
        // if it does, it means one of two things:
478
        // that update_option bailed at the($value === $old_value) conditional,
479
        // or...
480
        // the db update query returned 0 rows affected
481
        // (probably because the data  value was the same from it's perspective)
482
        // so the existence of the hook means that a negative result from update_option is NOT an error,
483
        // but just means no update occurred, so don't display an error to the user.
484
        // BUT... if update_option returns FALSE, AND the hook is missing,
485
        // then it means that something truly went wrong
486
        $saved = ! $saved ? has_action('update_option', array($this, 'double_check_config_comparison')) : $saved;
487
        // remove our action since we don't want it in the system anymore
488
        remove_action('update_option', array($this, 'double_check_config_comparison'), 1);
489
        do_action('AHEE__EE_Config__update_espresso_config__end', $this, $saved);
490
        // self::$_instance = $clone;
491
        // unset( $clone );
492
        // if config remains the same or was updated successfully
493
        if ($saved) {
494
            if ($add_success) {
495
                EE_Error::add_success(
496
                    __('The Event Espresso Configuration Settings have been successfully updated.', 'event_espresso'),
497
                    __FILE__,
498
                    __FUNCTION__,
499
                    __LINE__
500
                );
501
            }
502
            return true;
503
        } else {
504
            if ($add_error) {
505
                EE_Error::add_error(
506
                    __('The Event Espresso Configuration Settings were not updated.', 'event_espresso'),
507
                    __FILE__,
508
                    __FUNCTION__,
509
                    __LINE__
510
                );
511
            }
512
            return false;
513
        }
514
    }
515
516
517
    /**
518
     *    _verify_config_params
519
     *
520
     * @access    private
521
     * @param    string         $section
522
     * @param    string         $name
523
     * @param    string         $config_class
524
     * @param    EE_Config_Base $config_obj
525
     * @param    array          $tests_to_run
526
     * @param    bool           $display_errors
527
     * @return    bool    TRUE on success, FALSE on fail
528
     */
529
    private function _verify_config_params(
530
        $section = '',
531
        $name = '',
532
        $config_class = '',
533
        $config_obj = null,
534
        $tests_to_run = array(1, 2, 3, 4, 5, 6, 7, 8),
535
        $display_errors = true
536
    ) {
537
        try {
538
            foreach ($tests_to_run as $test) {
539
                switch ($test) {
540
                    // TEST #1 : check that section was set
541 View Code Duplication
                    case 1:
542
                        if (empty($section)) {
543
                            if ($display_errors) {
544
                                throw new EE_Error(
545
                                    sprintf(
546
                                        __(
547
                                            'No configuration section has been provided while attempting to save "%s".',
548
                                            'event_espresso'
549
                                        ),
550
                                        $config_class
551
                                    )
552
                                );
553
                            }
554
                            return false;
555
                        }
556
                        break;
557
                    // TEST #2 : check that settings section exists
558 View Code Duplication
                    case 2:
559
                        if (! isset($this->{$section})) {
560
                            if ($display_errors) {
561
                                throw new EE_Error(
562
                                    sprintf(
563
                                        __('The "%s" configuration section does not exist.', 'event_espresso'),
564
                                        $section
565
                                    )
566
                                );
567
                            }
568
                            return false;
569
                        }
570
                        break;
571
                    // TEST #3 : check that section is the proper format
572
                    case 3:
573
                        if (! ($this->{$section} instanceof EE_Config_Base || $this->{$section} instanceof stdClass)
574
                        ) {
575
                            if ($display_errors) {
576
                                throw new EE_Error(
577
                                    sprintf(
578
                                        __(
579
                                            'The "%s" configuration settings have not been formatted correctly.',
580
                                            'event_espresso'
581
                                        ),
582
                                        $section
583
                                    )
584
                                );
585
                            }
586
                            return false;
587
                        }
588
                        break;
589
                    // TEST #4 : check that config section name has been set
590 View Code Duplication
                    case 4:
591
                        if (empty($name)) {
592
                            if ($display_errors) {
593
                                throw new EE_Error(
594
                                    __(
595
                                        'No name has been provided for the specific configuration section.',
596
                                        'event_espresso'
597
                                    )
598
                                );
599
                            }
600
                            return false;
601
                        }
602
                        break;
603
                    // TEST #5 : check that a config class name has been set
604 View Code Duplication
                    case 5:
605
                        if (empty($config_class)) {
606
                            if ($display_errors) {
607
                                throw new EE_Error(
608
                                    __(
609
                                        'No class name has been provided for the specific configuration section.',
610
                                        'event_espresso'
611
                                    )
612
                                );
613
                            }
614
                            return false;
615
                        }
616
                        break;
617
                    // TEST #6 : verify config class is accessible
618 View Code Duplication
                    case 6:
619
                        if (! class_exists($config_class)) {
620
                            if ($display_errors) {
621
                                throw new EE_Error(
622
                                    sprintf(
623
                                        __(
624
                                            'The "%s" class does not exist. Please ensure that an autoloader has been set for it.',
625
                                            'event_espresso'
626
                                        ),
627
                                        $config_class
628
                                    )
629
                                );
630
                            }
631
                            return false;
632
                        }
633
                        break;
634
                    // TEST #7 : check that config has even been set
635
                    case 7:
636
                        if (! isset($this->{$section}->{$name})) {
637
                            if ($display_errors) {
638
                                throw new EE_Error(
639
                                    sprintf(
640
                                        __('No configuration has been set for "%1$s->%2$s".', 'event_espresso'),
641
                                        $section,
642
                                        $name
643
                                    )
644
                                );
645
                            }
646
                            return false;
647
                        } else {
648
                            // and make sure it's not serialized
649
                            $this->{$section}->{$name} = maybe_unserialize($this->{$section}->{$name});
650
                        }
651
                        break;
652
                    // TEST #8 : check that config is the requested type
653
                    case 8:
654
                        if (! $this->{$section}->{$name} instanceof $config_class) {
655
                            if ($display_errors) {
656
                                throw new EE_Error(
657
                                    sprintf(
658
                                        __(
659
                                            'The configuration for "%1$s->%2$s" is not of the "%3$s" class.',
660
                                            'event_espresso'
661
                                        ),
662
                                        $section,
663
                                        $name,
664
                                        $config_class
665
                                    )
666
                                );
667
                            }
668
                            return false;
669
                        }
670
                        break;
671
                    // TEST #9 : verify config object
672 View Code Duplication
                    case 9:
673
                        if (! $config_obj instanceof EE_Config_Base) {
674
                            if ($display_errors) {
675
                                throw new EE_Error(
676
                                    sprintf(
677
                                        __('The "%s" class is not an instance of EE_Config_Base.', 'event_espresso'),
678
                                        print_r($config_obj, true)
679
                                    )
680
                                );
681
                            }
682
                            return false;
683
                        }
684
                        break;
685
                }
686
            }
687
        } catch (EE_Error $e) {
688
            $e->get_error();
689
        }
690
        // you have successfully run the gauntlet
691
        return true;
692
    }
693
694
695
    /**
696
     *    _generate_config_option_name
697
     *
698
     * @access        protected
699
     * @param        string $section
700
     * @param        string $name
701
     * @return        string
702
     */
703
    private function _generate_config_option_name($section = '', $name = '')
704
    {
705
        return 'ee_config-' . strtolower($section . '-' . str_replace(array('EE_', 'EED_'), '', $name));
706
    }
707
708
709
    /**
710
     *    _set_config_class
711
     * ensures that a config class is set, either from a passed config class or one generated from the config name
712
     *
713
     * @access    private
714
     * @param    string $config_class
715
     * @param    string $name
716
     * @return    string
717
     */
718
    private function _set_config_class($config_class = '', $name = '')
719
    {
720
        return ! empty($config_class)
721
            ? $config_class
722
            : str_replace(' ', '_', ucwords(str_replace('_', ' ', $name))) . '_Config';
723
    }
724
725
726
    /**
727
     *    set_config
728
     *
729
     * @access    protected
730
     * @param    string         $section
731
     * @param    string         $name
732
     * @param    string         $config_class
733
     * @param    EE_Config_Base $config_obj
734
     * @return    EE_Config_Base
735
     */
736
    public function set_config($section = '', $name = '', $config_class = '', EE_Config_Base $config_obj = null)
737
    {
738
        // ensure config class is set to something
739
        $config_class = $this->_set_config_class($config_class, $name);
740
        // run tests 1-4, 6, and 7 to verify all config params are set and valid
741 View Code Duplication
        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
742
            return null;
743
        }
744
        $config_option_name = $this->_generate_config_option_name($section, $name);
745
        // if the config option name hasn't been added yet to the list of option names we're tracking, then do so now
746
        if (! isset($this->_addon_option_names[ $config_option_name ])) {
747
            $this->_addon_option_names[ $config_option_name ] = $config_class;
748
            $this->update_addon_option_names();
749
        }
750
        // verify the incoming config object but suppress errors
751
        if (! $this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
752
            $config_obj = new $config_class();
753
        }
754
        if (get_option($config_option_name)) {
755
            EE_Config::log($config_option_name);
756
            update_option($config_option_name, $config_obj);
757
            $this->{$section}->{$name} = $config_obj;
758
            return $this->{$section}->{$name};
759
        } else {
760
            // create a wp-option for this config
761
            if (add_option($config_option_name, $config_obj, '', 'no')) {
762
                $this->{$section}->{$name} = maybe_unserialize($config_obj);
763
                return $this->{$section}->{$name};
764
            } else {
765
                EE_Error::add_error(
766
                    sprintf(__('The "%s" could not be saved to the database.', 'event_espresso'), $config_class),
767
                    __FILE__,
768
                    __FUNCTION__,
769
                    __LINE__
770
                );
771
                return null;
772
            }
773
        }
774
    }
775
776
777
    /**
778
     *    update_config
779
     * Important: the config object must ALREADY be set, otherwise this will produce an error.
780
     *
781
     * @access    public
782
     * @param    string                $section
783
     * @param    string                $name
784
     * @param    EE_Config_Base|string $config_obj
785
     * @param    bool                  $throw_errors
786
     * @return    bool
787
     */
788
    public function update_config($section = '', $name = '', $config_obj = '', $throw_errors = true)
789
    {
790
        // don't allow config updates during WP heartbeats
791
        if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
792
            return false;
793
        }
794
        $config_obj = maybe_unserialize($config_obj);
795
        // get class name of the incoming object
796
        $config_class = get_class($config_obj);
797
        // run tests 1-5 and 9 to verify config
798 View Code Duplication
        if (! $this->_verify_config_params(
799
            $section,
800
            $name,
801
            $config_class,
802
            $config_obj,
803
            array(1, 2, 3, 4, 7, 9)
804
        )
805
        ) {
806
            return false;
807
        }
808
        $config_option_name = $this->_generate_config_option_name($section, $name);
809
        // check if config object has been added to db by seeing if config option name is in $this->_addon_option_names array
810
        if (! isset($this->_addon_option_names[ $config_option_name ])) {
811
            // save new config to db
812
            if ($this->set_config($section, $name, $config_class, $config_obj)) {
813
                return true;
814
            }
815
        } else {
816
            // first check if the record already exists
817
            $existing_config = get_option($config_option_name);
818
            $config_obj = serialize($config_obj);
819
            // just return if db record is already up to date (NOT type safe comparison)
820
            if ($existing_config == $config_obj) {
821
                $this->{$section}->{$name} = $config_obj;
822
                return true;
823
            } elseif (update_option($config_option_name, $config_obj)) {
824
                EE_Config::log($config_option_name);
825
                // update wp-option for this config class
826
                $this->{$section}->{$name} = $config_obj;
827
                return true;
828
            } elseif ($throw_errors) {
829
                EE_Error::add_error(
830
                    sprintf(
831
                        __(
832
                            'The "%1$s" object stored at"%2$s" was not successfully updated in the database.',
833
                            'event_espresso'
834
                        ),
835
                        $config_class,
836
                        'EE_Config->' . $section . '->' . $name
837
                    ),
838
                    __FILE__,
839
                    __FUNCTION__,
840
                    __LINE__
841
                );
842
            }
843
        }
844
        return false;
845
    }
846
847
848
    /**
849
     *    get_config
850
     *
851
     * @access    public
852
     * @param    string $section
853
     * @param    string $name
854
     * @param    string $config_class
855
     * @return    mixed EE_Config_Base | NULL
856
     */
857
    public function get_config($section = '', $name = '', $config_class = '')
858
    {
859
        // ensure config class is set to something
860
        $config_class = $this->_set_config_class($config_class, $name);
861
        // run tests 1-4, 6 and 7 to verify that all params have been set
862 View Code Duplication
        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
863
            return null;
864
        }
865
        // now test if the requested config object exists, but suppress errors
866
        if ($this->_verify_config_params($section, $name, $config_class, null, array(7, 8), false)) {
867
            // config already exists, so pass it back
868
            return $this->{$section}->{$name};
869
        }
870
        // load config option from db if it exists
871
        $config_obj = $this->get_config_option($this->_generate_config_option_name($section, $name));
872
        // verify the newly retrieved config object, but suppress errors
873
        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
874
            // config is good, so set it and pass it back
875
            $this->{$section}->{$name} = $config_obj;
876
            return $this->{$section}->{$name};
877
        }
878
        // oops! $config_obj is not already set and does not exist in the db, so create a new one
879
        $config_obj = $this->set_config($section, $name, $config_class);
880
        // verify the newly created config object
881
        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9))) {
882
            return $this->{$section}->{$name};
883
        } else {
884
            EE_Error::add_error(
885
                sprintf(__('The "%s" could not be retrieved from the database.', 'event_espresso'), $config_class),
886
                __FILE__,
887
                __FUNCTION__,
888
                __LINE__
889
            );
890
        }
891
        return null;
892
    }
893
894
895
    /**
896
     *    get_config_option
897
     *
898
     * @access    public
899
     * @param    string $config_option_name
900
     * @return    mixed EE_Config_Base | FALSE
901
     */
902
    public function get_config_option($config_option_name = '')
903
    {
904
        // retrieve the wp-option for this config class.
905
        $config_option = maybe_unserialize(get_option($config_option_name, array()));
906
        if (empty($config_option)) {
907
            EE_Config::log($config_option_name . '-NOT-FOUND');
908
        }
909
        return $config_option;
910
    }
911
912
913
    /**
914
     * log
915
     *
916
     * @param string $config_option_name
917
     */
918
    public static function log($config_option_name = '')
919
    {
920
        if (EE_Config::logging_enabled() && ! empty($config_option_name)) {
921
            $config_log = get_option(EE_Config::LOG_NAME, array());
922
            // copy incoming $_REQUEST and sanitize it so we can save it
923
            $_request = $_REQUEST;
924
            array_walk_recursive($_request, 'sanitize_text_field');
925
            $config_log[ (string) microtime(true) ] = array(
926
                'config_name' => $config_option_name,
927
                'request'     => $_request,
928
            );
929
            update_option(EE_Config::LOG_NAME, $config_log);
930
        }
931
    }
932
933
934
    /**
935
     * trim_log
936
     * reduces the size of the config log to the length specified by EE_Config::LOG_LENGTH
937
     */
938
    public static function trim_log()
939
    {
940
        if (! EE_Config::logging_enabled()) {
941
            return;
942
        }
943
        $config_log = maybe_unserialize(get_option(EE_Config::LOG_NAME, array()));
944
        $log_length = count($config_log);
945
        if ($log_length > EE_Config::LOG_LENGTH) {
946
            ksort($config_log);
947
            $config_log = array_slice($config_log, $log_length - EE_Config::LOG_LENGTH, null, true);
948
            update_option(EE_Config::LOG_NAME, $config_log);
949
        }
950
    }
951
952
953
    /**
954
     *    get_page_for_posts
955
     *    if the wp-option "show_on_front" is set to "page", then this is the post_name for the post set in the
956
     *    wp-option "page_for_posts", or "posts" if no page is selected
957
     *
958
     * @access    public
959
     * @return    string
960
     */
961
    public static function get_page_for_posts()
962
    {
963
        $page_for_posts = get_option('page_for_posts');
964
        if (! $page_for_posts) {
965
            return 'posts';
966
        }
967
        /** @type WPDB $wpdb */
968
        global $wpdb;
969
        $SQL = "SELECT post_name from $wpdb->posts WHERE post_type='posts' OR post_type='page' AND post_status='publish' AND ID=%d";
970
        return $wpdb->get_var($wpdb->prepare($SQL, $page_for_posts));
971
    }
972
973
974
    /**
975
     *    register_shortcodes_and_modules.
976
     *    At this point, it's too early to tell if we're maintenance mode or not.
977
     *    In fact, this is where we give modules a chance to let core know they exist
978
     *    so they can help trigger maintenance mode if it's needed
979
     *
980
     * @access    public
981
     * @return    void
982
     */
983
    public function register_shortcodes_and_modules()
984
    {
985
        // allow modules to set hooks for the rest of the system
986
        EE_Registry::instance()->modules = $this->_register_modules();
987
    }
988
989
990
    /**
991
     *    initialize_shortcodes_and_modules
992
     *    meaning they can start adding their hooks to get stuff done
993
     *
994
     * @access    public
995
     * @return    void
996
     */
997
    public function initialize_shortcodes_and_modules()
998
    {
999
        // allow modules to set hooks for the rest of the system
1000
        $this->_initialize_modules();
1001
    }
1002
1003
1004
    /**
1005
     *    widgets_init
1006
     *
1007
     * @access private
1008
     * @return void
1009
     */
1010
    public function widgets_init()
1011
    {
1012
        // only init widgets on admin pages when not in complete maintenance, and
1013
        // on frontend when not in any maintenance mode
1014
        if (! EE_Maintenance_Mode::instance()->level()
1015
            || (
1016
                is_admin()
1017
                && EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance
1018
            )
1019
        ) {
1020
            // grab list of installed widgets
1021
            $widgets_to_register = glob(EE_WIDGETS . '*', GLOB_ONLYDIR);
1022
            // filter list of modules to register
1023
            $widgets_to_register = apply_filters(
1024
                'FHEE__EE_Config__register_widgets__widgets_to_register',
1025
                $widgets_to_register
1026
            );
1027
            if (! empty($widgets_to_register)) {
1028
                // cycle thru widget folders
1029
                foreach ($widgets_to_register as $widget_path) {
1030
                    // add to list of installed widget modules
1031
                    EE_Config::register_ee_widget($widget_path);
1032
                }
1033
            }
1034
            // filter list of installed modules
1035
            EE_Registry::instance()->widgets = apply_filters(
1036
                'FHEE__EE_Config__register_widgets__installed_widgets',
1037
                EE_Registry::instance()->widgets
1038
            );
1039
        }
1040
    }
1041
1042
1043
    /**
1044
     *    register_ee_widget - makes core aware of this widget
1045
     *
1046
     * @access    public
1047
     * @param    string $widget_path - full path up to and including widget folder
1048
     * @return    void
1049
     */
1050
    public static function register_ee_widget($widget_path = null)
1051
    {
1052
        do_action('AHEE__EE_Config__register_widget__begin', $widget_path);
1053
        $widget_ext = '.widget.php';
1054
        // make all separators match
1055
        $widget_path = rtrim(str_replace('/\\', DS, $widget_path), DS);
1056
        // does the file path INCLUDE the actual file name as part of the path ?
1057
        if (strpos($widget_path, $widget_ext) !== false) {
1058
            // grab and shortcode file name from directory name and break apart at dots
1059
            $file_name = explode('.', basename($widget_path));
1060
            // take first segment from file name pieces and remove class prefix if it exists
1061
            $widget = strpos($file_name[0], 'EEW_') === 0 ? substr($file_name[0], 4) : $file_name[0];
1062
            // sanitize shortcode directory name
1063
            $widget = sanitize_key($widget);
1064
            // now we need to rebuild the shortcode path
1065
            $widget_path = explode(DS, $widget_path);
1066
            // remove last segment
1067
            array_pop($widget_path);
1068
            // glue it back together
1069
            $widget_path = implode(DS, $widget_path);
1070
        } else {
1071
            // grab and sanitize widget directory name
1072
            $widget = sanitize_key(basename($widget_path));
1073
        }
1074
        // create classname from widget directory name
1075
        $widget = str_replace(' ', '_', ucwords(str_replace('_', ' ', $widget)));
1076
        // add class prefix
1077
        $widget_class = 'EEW_' . $widget;
1078
        // does the widget exist ?
1079 View Code Duplication
        if (! is_readable($widget_path . DS . $widget_class . $widget_ext)) {
1080
            $msg = sprintf(
1081
                __(
1082
                    'The requested %s widget file could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s',
1083
                    'event_espresso'
1084
                ),
1085
                $widget_class,
1086
                $widget_path . DS . $widget_class . $widget_ext
1087
            );
1088
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1089
            return;
1090
        }
1091
        // load the widget class file
1092
        require_once($widget_path . DS . $widget_class . $widget_ext);
1093
        // verify that class exists
1094 View Code Duplication
        if (! class_exists($widget_class)) {
1095
            $msg = sprintf(__('The requested %s widget class does not exist.', 'event_espresso'), $widget_class);
1096
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1097
            return;
1098
        }
1099
        register_widget($widget_class);
1100
        // add to array of registered widgets
1101
        EE_Registry::instance()->widgets->{$widget_class} = $widget_path . DS . $widget_class . $widget_ext;
1102
    }
1103
1104
1105
    /**
1106
     *        _register_modules
1107
     *
1108
     * @access private
1109
     * @return array
1110
     */
1111
    private function _register_modules()
1112
    {
1113
        // grab list of installed modules
1114
        $modules_to_register = glob(EE_MODULES . '*', GLOB_ONLYDIR);
1115
        // filter list of modules to register
1116
        $modules_to_register = apply_filters(
1117
            'FHEE__EE_Config__register_modules__modules_to_register',
1118
            $modules_to_register
1119
        );
1120
        if (! empty($modules_to_register)) {
1121
            // loop through folders
1122
            foreach ($modules_to_register as $module_path) {
1123
                /**TEMPORARILY EXCLUDE gateways from modules for time being**/
1124
                if ($module_path !== EE_MODULES . 'zzz-copy-this-module-template'
1125
                    && $module_path !== EE_MODULES . 'gateways'
1126
                ) {
1127
                    // add to list of installed modules
1128
                    EE_Config::register_module($module_path);
1129
                }
1130
            }
1131
        }
1132
        // filter list of installed modules
1133
        return apply_filters(
1134
            'FHEE__EE_Config___register_modules__installed_modules',
1135
            EE_Registry::instance()->modules
1136
        );
1137
    }
1138
1139
1140
    /**
1141
     *    register_module - makes core aware of this module
1142
     *
1143
     * @access    public
1144
     * @param    string $module_path - full path up to and including module folder
1145
     * @return    bool
1146
     */
1147
    public static function register_module($module_path = null)
1148
    {
1149
        do_action('AHEE__EE_Config__register_module__begin', $module_path);
1150
        $module_ext = '.module.php';
1151
        // make all separators match
1152
        $module_path = str_replace(array('\\', '/'), DS, $module_path);
1153
        // does the file path INCLUDE the actual file name as part of the path ?
1154
        if (strpos($module_path, $module_ext) !== false) {
1155
            // grab and shortcode file name from directory name and break apart at dots
1156
            $module_file = explode('.', basename($module_path));
1157
            // now we need to rebuild the shortcode path
1158
            $module_path = explode(DS, $module_path);
1159
            // remove last segment
1160
            array_pop($module_path);
1161
            // glue it back together
1162
            $module_path = implode(DS, $module_path) . DS;
1163
            // take first segment from file name pieces and sanitize it
1164
            $module = preg_replace('/[^a-zA-Z0-9_\-]/', '', $module_file[0]);
1165
            // ensure class prefix is added
1166
            $module_class = strpos($module, 'EED_') !== 0 ? 'EED_' . $module : $module;
1167
        } else {
1168
            // we need to generate the filename based off of the folder name
1169
            // grab and sanitize module name
1170
            $module = strtolower(basename($module_path));
1171
            $module = preg_replace('/[^a-z0-9_\-]/', '', $module);
1172
            // like trailingslashit()
1173
            $module_path = rtrim($module_path, DS) . DS;
1174
            // create classname from module directory name
1175
            $module = str_replace(' ', '_', ucwords(str_replace('_', ' ', $module)));
1176
            // add class prefix
1177
            $module_class = 'EED_' . $module;
1178
        }
1179
        // does the module exist ?
1180 View Code Duplication
        if (! is_readable($module_path . DS . $module_class . $module_ext)) {
1181
            $msg = sprintf(
1182
                __(
1183
                    'The requested %s module file could not be found or is not readable due to file permissions.',
1184
                    'event_espresso'
1185
                ),
1186
                $module
1187
            );
1188
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1189
            return false;
1190
        }
1191
        // load the module class file
1192
        require_once($module_path . $module_class . $module_ext);
1193
        // verify that class exists
1194 View Code Duplication
        if (! class_exists($module_class)) {
1195
            $msg = sprintf(__('The requested %s module class does not exist.', 'event_espresso'), $module_class);
1196
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1197
            return false;
1198
        }
1199
        // add to array of registered modules
1200
        EE_Registry::instance()->modules->{$module_class} = $module_path . $module_class . $module_ext;
1201
        do_action(
1202
            'AHEE__EE_Config__register_module__complete',
1203
            $module_class,
1204
            EE_Registry::instance()->modules->{$module_class}
1205
        );
1206
        return true;
1207
    }
1208
1209
1210
    /**
1211
     *    _initialize_modules
1212
     *    allow modules to set hooks for the rest of the system
1213
     *
1214
     * @access private
1215
     * @return void
1216
     */
1217
    private function _initialize_modules()
1218
    {
1219
        // cycle thru shortcode folders
1220
        foreach (EE_Registry::instance()->modules as $module_class => $module_path) {
1221
            // fire the shortcode class's set_hooks methods in case it needs to hook into other parts of the system
1222
            // which set hooks ?
1223
            if (is_admin()) {
1224
                // fire immediately
1225
                call_user_func(array($module_class, 'set_hooks_admin'));
1226
            } else {
1227
                // delay until other systems are online
1228
                add_action(
1229
                    'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons',
1230
                    array($module_class, 'set_hooks')
1231
                );
1232
            }
1233
        }
1234
    }
1235
1236
1237
    /**
1238
     *    register_route - adds module method routes to route_map
1239
     *
1240
     * @access    public
1241
     * @param    string $route       - "pretty" public alias for module method
1242
     * @param    string $module      - module name (classname without EED_ prefix)
1243
     * @param    string $method_name - the actual module method to be routed to
1244
     * @param    string $key         - url param key indicating a route is being called
1245
     * @return    bool
1246
     */
1247
    public static function register_route($route = null, $module = null, $method_name = null, $key = 'ee')
1248
    {
1249
        do_action('AHEE__EE_Config__register_route__begin', $route, $module, $method_name);
1250
        $module = str_replace('EED_', '', $module);
1251
        $module_class = 'EED_' . $module;
1252
        if (! isset(EE_Registry::instance()->modules->{$module_class})) {
1253
            $msg = sprintf(__('The module %s has not been registered.', 'event_espresso'), $module);
1254
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1255
            return false;
1256
        }
1257 View Code Duplication
        if (empty($route)) {
1258
            $msg = sprintf(__('No route has been supplied.', 'event_espresso'), $route);
1259
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1260
            return false;
1261
        }
1262 View Code Duplication
        if (! method_exists('EED_' . $module, $method_name)) {
1263
            $msg = sprintf(
1264
                __('A valid class method for the %s route has not been supplied.', 'event_espresso'),
1265
                $route
1266
            );
1267
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1268
            return false;
1269
        }
1270
        EE_Config::$_module_route_map[ $key ][ $route ] = array('EED_' . $module, $method_name);
1271
        return true;
1272
    }
1273
1274
1275
    /**
1276
     *    get_route - get module method route
1277
     *
1278
     * @access    public
1279
     * @param    string $route - "pretty" public alias for module method
1280
     * @param    string $key   - url param key indicating a route is being called
1281
     * @return    string
1282
     */
1283
    public static function get_route($route = null, $key = 'ee')
1284
    {
1285
        do_action('AHEE__EE_Config__get_route__begin', $route);
1286
        $route = (string) apply_filters('FHEE__EE_Config__get_route', $route);
1287
        if (isset(EE_Config::$_module_route_map[ $key ][ $route ])) {
1288
            return EE_Config::$_module_route_map[ $key ][ $route ];
1289
        }
1290
        return null;
1291
    }
1292
1293
1294
    /**
1295
     *    get_routes - get ALL module method routes
1296
     *
1297
     * @access    public
1298
     * @return    array
1299
     */
1300
    public static function get_routes()
1301
    {
1302
        return EE_Config::$_module_route_map;
1303
    }
1304
1305
1306
    /**
1307
     *    register_forward - allows modules to forward request to another module for further processing
1308
     *
1309
     * @access    public
1310
     * @param    string       $route   - "pretty" public alias for module method
1311
     * @param    integer      $status  - integer value corresponding  to status constant strings set in module parent
1312
     *                                 class, allows different forwards to be served based on status
1313
     * @param    array|string $forward - function name or array( class, method )
1314
     * @param    string       $key     - url param key indicating a route is being called
1315
     * @return    bool
1316
     */
1317
    public static function register_forward($route = null, $status = 0, $forward = null, $key = 'ee')
1318
    {
1319
        do_action('AHEE__EE_Config__register_forward', $route, $status, $forward);
1320 View Code Duplication
        if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1321
            $msg = sprintf(
1322
                __('The module route %s for this forward has not been registered.', 'event_espresso'),
1323
                $route
1324
            );
1325
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1326
            return false;
1327
        }
1328 View Code Duplication
        if (empty($forward)) {
1329
            $msg = sprintf(__('No forwarding route has been supplied.', 'event_espresso'), $route);
1330
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1331
            return false;
1332
        }
1333
        if (is_array($forward)) {
1334 View Code Duplication
            if (! isset($forward[1])) {
1335
                $msg = sprintf(
1336
                    __('A class method for the %s forwarding route has not been supplied.', 'event_espresso'),
1337
                    $route
1338
                );
1339
                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1340
                return false;
1341
            }
1342
            if (! method_exists($forward[0], $forward[1])) {
1343
                $msg = sprintf(
1344
                    __('The class method %s for the %s forwarding route is in invalid.', 'event_espresso'),
1345
                    $forward[1],
1346
                    $route
1347
                );
1348
                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1349
                return false;
1350
            }
1351 View Code Duplication
        } elseif (! function_exists($forward)) {
1352
            $msg = sprintf(
1353
                __('The function %s for the %s forwarding route is in invalid.', 'event_espresso'),
1354
                $forward,
1355
                $route
1356
            );
1357
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1358
            return false;
1359
        }
1360
        EE_Config::$_module_forward_map[ $key ][ $route ][ absint($status) ] = $forward;
1361
        return true;
1362
    }
1363
1364
1365
    /**
1366
     *    get_forward - get forwarding route
1367
     *
1368
     * @access    public
1369
     * @param    string  $route  - "pretty" public alias for module method
1370
     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1371
     *                           allows different forwards to be served based on status
1372
     * @param    string  $key    - url param key indicating a route is being called
1373
     * @return    string
1374
     */
1375 View Code Duplication
    public static function get_forward($route = null, $status = 0, $key = 'ee')
1376
    {
1377
        do_action('AHEE__EE_Config__get_forward__begin', $route, $status);
1378
        if (isset(EE_Config::$_module_forward_map[ $key ][ $route ][ $status ])) {
1379
            return apply_filters(
1380
                'FHEE__EE_Config__get_forward',
1381
                EE_Config::$_module_forward_map[ $key ][ $route ][ $status ],
1382
                $route,
1383
                $status
1384
            );
1385
        }
1386
        return null;
1387
    }
1388
1389
1390
    /**
1391
     *    register_forward - allows modules to specify different view templates for different method routes and status
1392
     *    results
1393
     *
1394
     * @access    public
1395
     * @param    string  $route  - "pretty" public alias for module method
1396
     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1397
     *                           allows different views to be served based on status
1398
     * @param    string  $view
1399
     * @param    string  $key    - url param key indicating a route is being called
1400
     * @return    bool
1401
     */
1402
    public static function register_view($route = null, $status = 0, $view = null, $key = 'ee')
1403
    {
1404
        do_action('AHEE__EE_Config__register_view__begin', $route, $status, $view);
1405 View Code Duplication
        if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1406
            $msg = sprintf(
1407
                __('The module route %s for this view has not been registered.', 'event_espresso'),
1408
                $route
1409
            );
1410
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1411
            return false;
1412
        }
1413
        if (! is_readable($view)) {
1414
            $msg = sprintf(
1415
                __(
1416
                    'The %s view file could not be found or is not readable due to file permissions.',
1417
                    'event_espresso'
1418
                ),
1419
                $view
1420
            );
1421
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1422
            return false;
1423
        }
1424
        EE_Config::$_module_view_map[ $key ][ $route ][ absint($status) ] = $view;
1425
        return true;
1426
    }
1427
1428
1429
    /**
1430
     *    get_view - get view for route and status
1431
     *
1432
     * @access    public
1433
     * @param    string  $route  - "pretty" public alias for module method
1434
     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1435
     *                           allows different views to be served based on status
1436
     * @param    string  $key    - url param key indicating a route is being called
1437
     * @return    string
1438
     */
1439 View Code Duplication
    public static function get_view($route = null, $status = 0, $key = 'ee')
1440
    {
1441
        do_action('AHEE__EE_Config__get_view__begin', $route, $status);
1442
        if (isset(EE_Config::$_module_view_map[ $key ][ $route ][ $status ])) {
1443
            return apply_filters(
1444
                'FHEE__EE_Config__get_view',
1445
                EE_Config::$_module_view_map[ $key ][ $route ][ $status ],
1446
                $route,
1447
                $status
1448
            );
1449
        }
1450
        return null;
1451
    }
1452
1453
1454
    public function update_addon_option_names()
1455
    {
1456
        update_option(EE_Config::ADDON_OPTION_NAMES, $this->_addon_option_names);
1457
    }
1458
1459
1460
    public function shutdown()
1461
    {
1462
        $this->update_addon_option_names();
1463
    }
1464
1465
1466
    /**
1467
     * @return LegacyShortcodesManager
1468
     */
1469
    public static function getLegacyShortcodesManager()
1470
    {
1471
1472
        if (! EE_Config::instance()->legacy_shortcodes_manager instanceof LegacyShortcodesManager) {
1473
            EE_Config::instance()->legacy_shortcodes_manager = new LegacyShortcodesManager(
1474
                EE_Registry::instance()
1475
            );
1476
        }
1477
        return EE_Config::instance()->legacy_shortcodes_manager;
1478
    }
1479
1480
1481
    /**
1482
     * register_shortcode - makes core aware of this shortcode
1483
     *
1484
     * @deprecated 4.9.26
1485
     * @param    string $shortcode_path - full path up to and including shortcode folder
1486
     * @return    bool
1487
     */
1488
    public static function register_shortcode($shortcode_path = null)
1489
    {
1490
        EE_Error::doing_it_wrong(
1491
            __METHOD__,
1492
            __(
1493
                'Usage is deprecated. Use \EventEspresso\core\services\shortcodes\LegacyShortcodesManager::registerShortcode() as direct replacement, or better yet, please see the new \EventEspresso\core\services\shortcodes\ShortcodesManager class.',
1494
                'event_espresso'
1495
            ),
1496
            '4.9.26'
1497
        );
1498
        return EE_Config::instance()->getLegacyShortcodesManager()->registerShortcode($shortcode_path);
1499
    }
1500
}
1501
1502
/**
1503
 * Base class used for config classes. These classes should generally not have
1504
 * magic functions in use, except we'll allow them to magically set and get stuff...
1505
 * basically, they should just be well-defined stdClasses
1506
 */
1507
class EE_Config_Base
1508
{
1509
1510
    /**
1511
     * Utility function for escaping the value of a property and returning.
1512
     *
1513
     * @param string $property property name (checks to see if exists).
1514
     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1515
     * @throws \EE_Error
1516
     */
1517
    public function get_pretty($property)
1518
    {
1519
        if (! property_exists($this, $property)) {
1520
            throw new EE_Error(
1521
                sprintf(
1522
                    __(
1523
                        '%1$s::get_pretty() has been called with the property %2$s which does not exist on the %1$s config class.',
1524
                        'event_espresso'
1525
                    ),
1526
                    get_class($this),
1527
                    $property
1528
                )
1529
            );
1530
        }
1531
        // just handling escaping of strings for now.
1532
        if (is_string($this->{$property})) {
1533
            return stripslashes($this->{$property});
1534
        }
1535
        return $this->{$property};
1536
    }
1537
1538
1539
    public function populate()
1540
    {
1541
        // grab defaults via a new instance of this class.
1542
        $class_name = get_class($this);
1543
        $defaults = new $class_name;
1544
        // loop through the properties for this class and see if they are set.  If they are NOT, then grab the
1545
        // default from our $defaults object.
1546
        foreach (get_object_vars($defaults) as $property => $value) {
1547
            if ($this->{$property} === null) {
1548
                $this->{$property} = $value;
1549
            }
1550
        }
1551
        // cleanup
1552
        unset($defaults);
1553
    }
1554
1555
1556
    /**
1557
     *        __isset
1558
     *
1559
     * @param $a
1560
     * @return bool
1561
     */
1562
    public function __isset($a)
1563
    {
1564
        return false;
1565
    }
1566
1567
1568
    /**
1569
     *        __unset
1570
     *
1571
     * @param $a
1572
     * @return bool
1573
     */
1574
    public function __unset($a)
1575
    {
1576
        return false;
1577
    }
1578
1579
1580
    /**
1581
     *        __clone
1582
     */
1583
    public function __clone()
1584
    {
1585
    }
1586
1587
1588
    /**
1589
     *        __wakeup
1590
     */
1591
    public function __wakeup()
1592
    {
1593
    }
1594
1595
1596
    /**
1597
     *        __destruct
1598
     */
1599
    public function __destruct()
1600
    {
1601
    }
1602
}
1603
1604
/**
1605
 * Class for defining what's in the EE_Config relating to registration settings
1606
 */
1607
class EE_Core_Config extends EE_Config_Base
1608
{
1609
1610
    public $current_blog_id;
1611
1612
    public $ee_ueip_optin;
1613
1614
    public $ee_ueip_has_notified;
1615
1616
    /**
1617
     * Not to be confused with the 4 critical page variables (See
1618
     * get_critical_pages_array()), this is just an array of wp posts that have EE
1619
     * shortcodes in them. Keys are slugs, values are arrays with only 1 element: where the key is the shortcode
1620
     * in the page, and the value is the page's ID. The key 'posts' is basically a duplicate of this same array.
1621
     *
1622
     * @var array
1623
     */
1624
    public $post_shortcodes;
1625
1626
    public $module_route_map;
1627
1628
    public $module_forward_map;
1629
1630
    public $module_view_map;
1631
1632
    /**
1633
     * The next 4 vars are the IDs of critical EE pages.
1634
     *
1635
     * @var int
1636
     */
1637
    public $reg_page_id;
1638
1639
    public $txn_page_id;
1640
1641
    public $thank_you_page_id;
1642
1643
    public $cancel_page_id;
1644
1645
    /**
1646
     * The next 4 vars are the URLs of critical EE pages.
1647
     *
1648
     * @var int
1649
     */
1650
    public $reg_page_url;
1651
1652
    public $txn_page_url;
1653
1654
    public $thank_you_page_url;
1655
1656
    public $cancel_page_url;
1657
1658
    /**
1659
     * The next vars relate to the custom slugs for EE CPT routes
1660
     */
1661
    public $event_cpt_slug;
1662
1663
    /**
1664
     * This caches the _ee_ueip_option in case this config is reset in the same
1665
     * request across blog switches in a multisite context.
1666
     * Avoids extra queries to the db for this option.
1667
     *
1668
     * @var bool
1669
     */
1670
    public static $ee_ueip_option;
1671
1672
1673
    /**
1674
     *    class constructor
1675
     *
1676
     * @access    public
1677
     */
1678
    public function __construct()
1679
    {
1680
        // set default organization settings
1681
        $this->current_blog_id = get_current_blog_id();
1682
        $this->current_blog_id = $this->current_blog_id === null ? 1 : $this->current_blog_id;
1683
        $this->ee_ueip_optin = $this->_get_main_ee_ueip_optin();
1684
        $this->ee_ueip_has_notified = is_main_site() ? get_option('ee_ueip_has_notified', false) : true;
1685
        $this->post_shortcodes = array();
1686
        $this->module_route_map = array();
1687
        $this->module_forward_map = array();
1688
        $this->module_view_map = array();
1689
        // critical EE page IDs
1690
        $this->reg_page_id = 0;
1691
        $this->txn_page_id = 0;
1692
        $this->thank_you_page_id = 0;
1693
        $this->cancel_page_id = 0;
1694
        // critical EE page URLs
1695
        $this->reg_page_url = '';
1696
        $this->txn_page_url = '';
1697
        $this->thank_you_page_url = '';
1698
        $this->cancel_page_url = '';
1699
        // cpt slugs
1700
        $this->event_cpt_slug = __('events', 'event_espresso');
1701
        // ueip constant check
1702
        if (defined('EE_DISABLE_UXIP') && EE_DISABLE_UXIP) {
1703
            $this->ee_ueip_optin = false;
1704
            $this->ee_ueip_has_notified = true;
1705
        }
1706
    }
1707
1708
1709
    /**
1710
     * @return array
1711
     */
1712
    public function get_critical_pages_array()
1713
    {
1714
        return array(
1715
            $this->reg_page_id,
1716
            $this->txn_page_id,
1717
            $this->thank_you_page_id,
1718
            $this->cancel_page_id,
1719
        );
1720
    }
1721
1722
1723
    /**
1724
     * @return array
1725
     */
1726
    public function get_critical_pages_shortcodes_array()
1727
    {
1728
        return array(
1729
            $this->reg_page_id       => 'ESPRESSO_CHECKOUT',
1730
            $this->txn_page_id       => 'ESPRESSO_TXN_PAGE',
1731
            $this->thank_you_page_id => 'ESPRESSO_THANK_YOU',
1732
            $this->cancel_page_id    => 'ESPRESSO_CANCELLED',
1733
        );
1734
    }
1735
1736
1737
    /**
1738
     *  gets/returns URL for EE reg_page
1739
     *
1740
     * @access    public
1741
     * @return    string
1742
     */
1743
    public function reg_page_url()
1744
    {
1745
        if (! $this->reg_page_url) {
1746
            $this->reg_page_url = add_query_arg(
1747
                array('uts' => time()),
1748
                get_permalink($this->reg_page_id)
1749
            ) . '#checkout';
1750
        }
1751
        return $this->reg_page_url;
1752
    }
1753
1754
1755
    /**
1756
     *  gets/returns URL for EE txn_page
1757
     *
1758
     * @param array $query_args like what gets passed to
1759
     *                          add_query_arg() as the first argument
1760
     * @access    public
1761
     * @return    string
1762
     */
1763 View Code Duplication
    public function txn_page_url($query_args = array())
1764
    {
1765
        if (! $this->txn_page_url) {
1766
            $this->txn_page_url = get_permalink($this->txn_page_id);
1767
        }
1768
        if ($query_args) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $query_args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1769
            return add_query_arg($query_args, $this->txn_page_url);
1770
        } else {
1771
            return $this->txn_page_url;
1772
        }
1773
    }
1774
1775
1776
    /**
1777
     *  gets/returns URL for EE thank_you_page
1778
     *
1779
     * @param array $query_args like what gets passed to
1780
     *                          add_query_arg() as the first argument
1781
     * @access    public
1782
     * @return    string
1783
     */
1784 View Code Duplication
    public function thank_you_page_url($query_args = array())
1785
    {
1786
        if (! $this->thank_you_page_url) {
1787
            $this->thank_you_page_url = get_permalink($this->thank_you_page_id);
1788
        }
1789
        if ($query_args) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $query_args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1790
            return add_query_arg($query_args, $this->thank_you_page_url);
1791
        } else {
1792
            return $this->thank_you_page_url;
1793
        }
1794
    }
1795
1796
1797
    /**
1798
     *  gets/returns URL for EE cancel_page
1799
     *
1800
     * @access    public
1801
     * @return    string
1802
     */
1803
    public function cancel_page_url()
1804
    {
1805
        if (! $this->cancel_page_url) {
1806
            $this->cancel_page_url = get_permalink($this->cancel_page_id);
1807
        }
1808
        return $this->cancel_page_url;
1809
    }
1810
1811
1812
    /**
1813
     * Resets all critical page urls to their original state.  Used primarily by the __sleep() magic method currently.
1814
     *
1815
     * @since 4.7.5
1816
     */
1817
    protected function _reset_urls()
1818
    {
1819
        $this->reg_page_url = '';
1820
        $this->txn_page_url = '';
1821
        $this->cancel_page_url = '';
1822
        $this->thank_you_page_url = '';
1823
    }
1824
1825
1826
    /**
1827
     * Used to return what the optin value is set for the EE User Experience Program.
1828
     * This accounts for multisite and this value being requested for a subsite.  In multisite, the value is set
1829
     * on the main site only.
1830
     *
1831
     * @return mixed|void
1832
     */
1833
    protected function _get_main_ee_ueip_optin()
1834
    {
1835
        // if this is the main site then we can just bypass our direct query.
1836
        if (is_main_site()) {
1837
            return get_option('ee_ueip_optin', false);
1838
        }
1839
        // is this already cached for this request?  If so use it.
1840
        if (! empty(EE_Core_Config::$ee_ueip_option)) {
1841
            return EE_Core_Config::$ee_ueip_option;
1842
        }
1843
        global $wpdb;
1844
        $current_network_main_site = is_multisite() ? get_current_site() : null;
1845
        $current_main_site_id = ! empty($current_network_main_site) ? $current_network_main_site->blog_id : 1;
1846
        $option = 'ee_ueip_optin';
1847
        // set correct table for query
1848
        $table_name = $wpdb->get_blog_prefix($current_main_site_id) . 'options';
1849
        // rather than getting blog option for the $current_main_site_id, we do a direct $wpdb query because
1850
        // get_blog_option() does a switch_to_blog an that could cause infinite recursion because EE_Core_Config might be
1851
        // re-constructed on the blog switch.  Note, we are still executing any core wp filters on this option retrieval.
1852
        // this bit of code is basically a direct copy of get_option without any caching because we are NOT switched to the blog
1853
        // for the purpose of caching.
1854
        $pre = apply_filters('pre_option_' . $option, false, $option);
1855
        if (false !== $pre) {
1856
            EE_Core_Config::$ee_ueip_option = $pre;
1857
            return EE_Core_Config::$ee_ueip_option;
1858
        }
1859
        $row = $wpdb->get_row(
1860
            $wpdb->prepare(
1861
                "SELECT option_value FROM $table_name WHERE option_name = %s LIMIT 1",
1862
                $option
1863
            )
1864
        );
1865
        if (is_object($row)) {
1866
            $value = $row->option_value;
1867
        } else { // option does not exist so use default.
1868
            return apply_filters('default_option_' . $option, false, $option);
1869
        }
1870
        EE_Core_Config::$ee_ueip_option = apply_filters('option_' . $option, maybe_unserialize($value), $option);
1871
        return EE_Core_Config::$ee_ueip_option;
1872
    }
1873
1874
1875
    /**
1876
     * Utility function for escaping the value of a property and returning.
1877
     *
1878
     * @param string $property property name (checks to see if exists).
1879
     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1880
     * @throws \EE_Error
1881
     */
1882
    public function get_pretty($property)
1883
    {
1884
        if ($property === 'ee_ueip_optin') {
1885
            return $this->ee_ueip_optin ? 'yes' : 'no';
1886
        }
1887
        return parent::get_pretty($property);
1888
    }
1889
1890
1891
    /**
1892
     * Currently used to ensure critical page urls have initial values saved to the db instead of any current set values
1893
     * on the object.
1894
     *
1895
     * @return array
1896
     */
1897
    public function __sleep()
1898
    {
1899
        // reset all url properties
1900
        $this->_reset_urls();
1901
        // return what to save to db
1902
        return array_keys(get_object_vars($this));
1903
    }
1904
}
1905
1906
/**
1907
 * Config class for storing info on the Organization
1908
 */
1909
class EE_Organization_Config extends EE_Config_Base
1910
{
1911
1912
    /**
1913
     * @var string $name
1914
     * eg EE4.1
1915
     */
1916
    public $name;
1917
1918
    /**
1919
     * @var string $address_1
1920
     * eg 123 Onna Road
1921
     */
1922
    public $address_1;
1923
1924
    /**
1925
     * @var string $address_2
1926
     * eg PO Box 123
1927
     */
1928
    public $address_2;
1929
1930
    /**
1931
     * @var string $city
1932
     * eg Inna City
1933
     */
1934
    public $city;
1935
1936
    /**
1937
     * @var int $STA_ID
1938
     * eg 4
1939
     */
1940
    public $STA_ID;
1941
1942
    /**
1943
     * @var string $CNT_ISO
1944
     * eg US
1945
     */
1946
    public $CNT_ISO;
1947
1948
    /**
1949
     * @var string $zip
1950
     * eg 12345  or V1A 2B3
1951
     */
1952
    public $zip;
1953
1954
    /**
1955
     * @var string $email
1956
     * eg [email protected]
1957
     */
1958
    public $email;
1959
1960
    /**
1961
     * @var string $phone
1962
     * eg. 111-111-1111
1963
     */
1964
    public $phone;
1965
1966
    /**
1967
     * @var string $vat
1968
     * VAT/Tax Number
1969
     */
1970
    public $vat;
1971
1972
    /**
1973
     * @var string $logo_url
1974
     * eg http://www.somedomain.com/wp-content/uploads/kittehs.jpg
1975
     */
1976
    public $logo_url;
1977
1978
    /**
1979
     * The below are all various properties for holding links to organization social network profiles
1980
     *
1981
     * @var string
1982
     */
1983
    /**
1984
     * facebook (facebook.com/profile.name)
1985
     *
1986
     * @var string
1987
     */
1988
    public $facebook;
1989
1990
    /**
1991
     * twitter (twitter.com/twitter_handle)
1992
     *
1993
     * @var string
1994
     */
1995
    public $twitter;
1996
1997
    /**
1998
     * linkedin (linkedin.com/in/profile_name)
1999
     *
2000
     * @var string
2001
     */
2002
    public $linkedin;
2003
2004
    /**
2005
     * pinterest (www.pinterest.com/profile_name)
2006
     *
2007
     * @var string
2008
     */
2009
    public $pinterest;
2010
2011
    /**
2012
     * google+ (google.com/+profileName)
2013
     *
2014
     * @var string
2015
     */
2016
    public $google;
2017
2018
    /**
2019
     * instagram (instagram.com/handle)
2020
     *
2021
     * @var string
2022
     */
2023
    public $instagram;
2024
2025
2026
    /**
2027
     *    class constructor
2028
     *
2029
     * @access    public
2030
     */
2031
    public function __construct()
2032
    {
2033
        // set default organization settings
2034
        // decode HTML entities from the WP blogname, because it's stored in the DB with HTML entities encoded
2035
        $this->name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
2036
        $this->address_1 = '123 Onna Road';
2037
        $this->address_2 = 'PO Box 123';
2038
        $this->city = 'Inna City';
2039
        $this->STA_ID = 4;
2040
        $this->CNT_ISO = 'US';
2041
        $this->zip = '12345';
2042
        $this->email = get_bloginfo('admin_email');
2043
        $this->phone = '';
2044
        $this->vat = '123456789';
2045
        $this->logo_url = '';
2046
        $this->facebook = '';
2047
        $this->twitter = '';
2048
        $this->linkedin = '';
2049
        $this->pinterest = '';
2050
        $this->google = '';
2051
        $this->instagram = '';
2052
    }
2053
}
2054
2055
/**
2056
 * Class for defining what's in the EE_Config relating to currency
2057
 */
2058
class EE_Currency_Config extends EE_Config_Base
2059
{
2060
2061
    /**
2062
     * @var string $code
2063
     * eg 'US'
2064
     */
2065
    public $code;
2066
2067
    /**
2068
     * @var string $name
2069
     * eg 'Dollar'
2070
     */
2071
    public $name;
2072
2073
    /**
2074
     * plural name
2075
     *
2076
     * @var string $plural
2077
     * eg 'Dollars'
2078
     */
2079
    public $plural;
2080
2081
    /**
2082
     * currency sign
2083
     *
2084
     * @var string $sign
2085
     * eg '$'
2086
     */
2087
    public $sign;
2088
2089
    /**
2090
     * Whether the currency sign should come before the number or not
2091
     *
2092
     * @var boolean $sign_b4
2093
     */
2094
    public $sign_b4;
2095
2096
    /**
2097
     * How many digits should come after the decimal place
2098
     *
2099
     * @var int $dec_plc
2100
     */
2101
    public $dec_plc;
2102
2103
    /**
2104
     * Symbol to use for decimal mark
2105
     *
2106
     * @var string $dec_mrk
2107
     * eg '.'
2108
     */
2109
    public $dec_mrk;
2110
2111
    /**
2112
     * Symbol to use for thousands
2113
     *
2114
     * @var string $thsnds
2115
     * eg ','
2116
     */
2117
    public $thsnds;
2118
2119
2120
    /**
2121
     *    class constructor
2122
     *
2123
     * @access    public
2124
     * @param string $CNT_ISO
2125
     * @throws \EE_Error
2126
     */
2127
    public function __construct($CNT_ISO = '')
2128
    {
2129
        /** @var \EventEspresso\core\services\database\TableAnalysis $table_analysis */
2130
        $table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
2131
        // get country code from organization settings or use default
2132
        $ORG_CNT = isset(EE_Registry::instance()->CFG->organization)
2133
                   && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
2134
            ? EE_Registry::instance()->CFG->organization->CNT_ISO
2135
            : '';
2136
        // but override if requested
2137
        $CNT_ISO = ! empty($CNT_ISO) ? $CNT_ISO : $ORG_CNT;
2138
        // so if that all went well, and we are not in M-Mode (cuz you can't query the db in M-Mode) and double-check the countries table exists
2139
        if (! empty($CNT_ISO)
2140
            && EE_Maintenance_Mode::instance()->models_can_query()
2141
            && $table_analysis->tableExists(EE_Registry::instance()->load_model('Country')->table())
2142
        ) {
2143
            // retrieve the country settings from the db, just in case they have been customized
2144
            $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
2145
            if ($country instanceof EE_Country) {
2146
                $this->code = $country->currency_code();    // currency code: USD, CAD, EUR
2147
                $this->name = $country->currency_name_single();    // Dollar
2148
                $this->plural = $country->currency_name_plural();    // Dollars
2149
                $this->sign = $country->currency_sign();            // currency sign: $
2150
                $this->sign_b4 = $country->currency_sign_before(
2151
                );        // currency sign before or after: $TRUE  or  FALSE$
2152
                $this->dec_plc = $country->currency_decimal_places();    // decimal places: 2 = 0.00  3 = 0.000
2153
                $this->dec_mrk = $country->currency_decimal_mark(
2154
                );    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2155
                $this->thsnds = $country->currency_thousands_separator(
2156
                );    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2157
            }
2158
        }
2159
        // fallback to hardcoded defaults, in case the above failed
2160
        if (empty($this->code)) {
2161
            // set default currency settings
2162
            $this->code = 'USD';    // currency code: USD, CAD, EUR
2163
            $this->name = __('Dollar', 'event_espresso');    // Dollar
2164
            $this->plural = __('Dollars', 'event_espresso');    // Dollars
2165
            $this->sign = '$';    // currency sign: $
2166
            $this->sign_b4 = true;    // currency sign before or after: $TRUE  or  FALSE$
2167
            $this->dec_plc = 2;    // decimal places: 2 = 0.00  3 = 0.000
2168
            $this->dec_mrk = '.';    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2169
            $this->thsnds = ',';    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2170
        }
2171
    }
2172
}
2173
2174
/**
2175
 * Class for defining what's in the EE_Config relating to registration settings
2176
 */
2177
class EE_Registration_Config extends EE_Config_Base
2178
{
2179
2180
    /**
2181
     * Default registration status
2182
     *
2183
     * @var string $default_STS_ID
2184
     * eg 'RPP'
2185
     */
2186
    public $default_STS_ID;
2187
2188
    /**
2189
     * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2190
     * registrations)
2191
     *
2192
     * @var int
2193
     */
2194
    public $default_maximum_number_of_tickets;
2195
2196
    /**
2197
     * level of validation to apply to email addresses
2198
     *
2199
     * @var string $email_validation_level
2200
     * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2201
     */
2202
    public $email_validation_level;
2203
2204
    /**
2205
     *    whether or not to show alternate payment options during the reg process if payment status is pending
2206
     *
2207
     * @var boolean $show_pending_payment_options
2208
     */
2209
    public $show_pending_payment_options;
2210
2211
    /**
2212
     * Whether to skip the registration confirmation page
2213
     *
2214
     * @var boolean $skip_reg_confirmation
2215
     */
2216
    public $skip_reg_confirmation;
2217
2218
    /**
2219
     * an array of SPCO reg steps where:
2220
     *        the keys denotes the reg step order
2221
     *        each element consists of an array with the following elements:
2222
     *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2223
     *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2224
     *            "slug" => the URL param used to trigger the reg step
2225
     *
2226
     * @var array $reg_steps
2227
     */
2228
    public $reg_steps;
2229
2230
    /**
2231
     * Whether registration confirmation should be the last page of SPCO
2232
     *
2233
     * @var boolean $reg_confirmation_last
2234
     */
2235
    public $reg_confirmation_last;
2236
2237
    /**
2238
     * Whether or not to enable the EE Bot Trap
2239
     *
2240
     * @var boolean $use_bot_trap
2241
     */
2242
    public $use_bot_trap;
2243
2244
    /**
2245
     * Whether or not to encrypt some data sent by the EE Bot Trap
2246
     *
2247
     * @var boolean $use_encryption
2248
     */
2249
    public $use_encryption;
2250
2251
    /**
2252
     * Whether or not to use ReCaptcha
2253
     *
2254
     * @var boolean $use_captcha
2255
     */
2256
    public $use_captcha;
2257
2258
    /**
2259
     * ReCaptcha Theme
2260
     *
2261
     * @var string $recaptcha_theme
2262
     *    options: 'dark', 'light', 'invisible'
2263
     */
2264
    public $recaptcha_theme;
2265
2266
    /**
2267
     * ReCaptcha Badge - determines the position of the reCAPTCHA badge if using Invisible ReCaptcha.
2268
     *
2269
     * @var string $recaptcha_badge
2270
     *    options: 'bottomright', 'bottomleft', 'inline'
2271
     */
2272
    public $recaptcha_badge;
2273
2274
    /**
2275
     * ReCaptcha Type
2276
     *
2277
     * @var string $recaptcha_type
2278
     *    options: 'audio', 'image'
2279
     */
2280
    public $recaptcha_type;
2281
2282
    /**
2283
     * ReCaptcha language
2284
     *
2285
     * @var string $recaptcha_language
2286
     * eg 'en'
2287
     */
2288
    public $recaptcha_language;
2289
2290
    /**
2291
     * ReCaptcha public key
2292
     *
2293
     * @var string $recaptcha_publickey
2294
     */
2295
    public $recaptcha_publickey;
2296
2297
    /**
2298
     * ReCaptcha private key
2299
     *
2300
     * @var string $recaptcha_privatekey
2301
     */
2302
    public $recaptcha_privatekey;
2303
2304
    /**
2305
     * array of form names protected by ReCaptcha
2306
     *
2307
     * @var array $recaptcha_protected_forms
2308
     */
2309
    public $recaptcha_protected_forms;
2310
2311
    /**
2312
     * ReCaptcha width
2313
     *
2314
     * @var int $recaptcha_width
2315
     * @deprecated
2316
     */
2317
    public $recaptcha_width;
2318
2319
    /**
2320
     * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2321
     *
2322
     * @var boolean $track_invalid_checkout_access
2323
     */
2324
    protected $track_invalid_checkout_access = true;
2325
2326
    /**
2327
     * Whether or not to show the privacy policy consent checkbox
2328
     *
2329
     * @var bool
2330
     */
2331
    public $consent_checkbox_enabled;
2332
2333
    /**
2334
     * Label text to show on the checkbox
2335
     *
2336
     * @var string
2337
     */
2338
    public $consent_checkbox_label_text;
2339
2340
    /*
2341
     * String describing how long to keep payment logs. Passed into DateTime constructor
2342
     * @var string
2343
     */
2344
    public $gateway_log_lifespan = '1 week';
2345
2346
2347
    /**
2348
     *    class constructor
2349
     *
2350
     * @access    public
2351
     */
2352
    public function __construct()
2353
    {
2354
        // set default registration settings
2355
        $this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2356
        $this->email_validation_level = 'wp_default';
2357
        $this->show_pending_payment_options = true;
2358
        $this->skip_reg_confirmation = true;
2359
        $this->reg_steps = array();
2360
        $this->reg_confirmation_last = false;
2361
        $this->use_bot_trap = true;
2362
        $this->use_encryption = true;
2363
        $this->use_captcha = false;
2364
        $this->recaptcha_theme = 'light';
2365
        $this->recaptcha_badge = 'bottomleft';
2366
        $this->recaptcha_type = 'image';
2367
        $this->recaptcha_language = 'en';
2368
        $this->recaptcha_publickey = null;
2369
        $this->recaptcha_privatekey = null;
2370
        $this->recaptcha_protected_forms = array();
2371
        $this->recaptcha_width = 500;
0 ignored issues
show
Deprecated Code introduced by
The property EE_Registration_Config::$recaptcha_width has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2372
        $this->default_maximum_number_of_tickets = 10;
2373
        $this->consent_checkbox_enabled = false;
2374
        $this->consent_checkbox_label_text = '';
2375
        $this->gateway_log_lifespan = '7 days';
2376
    }
2377
2378
2379
    /**
2380
     * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2381
     *
2382
     * @since 4.8.8.rc.019
2383
     */
2384
    public function do_hooks()
2385
    {
2386
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2387
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2388
        add_action('setup_theme', array($this, 'setDefaultCheckboxLabelText'));
2389
    }
2390
2391
2392
    /**
2393
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the
2394
     * EVT_default_registration_status field matches the config setting for default_STS_ID.
2395
     */
2396
    public function set_default_reg_status_on_EEM_Event()
2397
    {
2398
        EEM_Event::set_default_reg_status($this->default_STS_ID);
2399
    }
2400
2401
2402
    /**
2403
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2404
     * for Events matches the config setting for default_maximum_number_of_tickets
2405
     */
2406
    public function set_default_max_ticket_on_EEM_Event()
2407
    {
2408
        EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2409
    }
2410
2411
2412
    /**
2413
     * Sets the default consent checkbox text. This needs to be done a bit later than when EE_Registration_Config is
2414
     * constructed because that happens before we can get the privacy policy page's permalink.
2415
     *
2416
     * @throws InvalidArgumentException
2417
     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2418
     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2419
     */
2420
    public function setDefaultCheckboxLabelText()
2421
    {
2422
        if ($this->getConsentCheckboxLabelText() === null
2423
            || $this->getConsentCheckboxLabelText() === '') {
2424
            $opening_a_tag = '';
2425
            $closing_a_tag = '';
2426
            if (function_exists('get_privacy_policy_url')) {
2427
                $privacy_page_url = get_privacy_policy_url();
2428
                if (! empty($privacy_page_url)) {
2429
                    $opening_a_tag = '<a href="' . $privacy_page_url . '" target="_blank">';
2430
                    $closing_a_tag = '</a>';
2431
                }
2432
            }
2433
            $loader = LoaderFactory::getLoader();
2434
            $org_config = $loader->getShared('EE_Organization_Config');
2435
            /**
2436
             * @var $org_config EE_Organization_Config
2437
             */
2438
2439
            $this->setConsentCheckboxLabelText(
2440
                sprintf(
2441
                    esc_html__(
2442
                        'I consent to %1$s storing and using my personal information, according to their %2$sprivacy policy%3$s.',
2443
                        'event_espresso'
2444
                    ),
2445
                    $org_config->name,
2446
                    $opening_a_tag,
2447
                    $closing_a_tag
2448
                )
2449
            );
2450
        }
2451
    }
2452
2453
2454
    /**
2455
     * @return boolean
2456
     */
2457
    public function track_invalid_checkout_access()
2458
    {
2459
        return $this->track_invalid_checkout_access;
2460
    }
2461
2462
2463
    /**
2464
     * @param boolean $track_invalid_checkout_access
2465
     */
2466
    public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2467
    {
2468
        $this->track_invalid_checkout_access = filter_var(
2469
            $track_invalid_checkout_access,
2470
            FILTER_VALIDATE_BOOLEAN
2471
        );
2472
    }
2473
2474
2475
    /**
2476
     * Gets the options to make availalbe for the gateway log lifespan
2477
     * @return array
2478
     */
2479
    public function gatewayLogLifespanOptions()
2480
    {
2481
        return (array) apply_filters(
2482
            'FHEE_EE_Admin_Config__gatewayLogLifespanOptions',
2483
            array(
2484
                '1 second' => esc_html__('Don\'t Log At All', 'event_espresso'),
2485
                '1 day' => esc_html__('1 Day', 'event_espresso'),
2486
                '7 days' => esc_html__('7 Days', 'event_espresso'),
2487
                '14 days' => esc_html__('14 Days', 'event_espresso'),
2488
                '30 days' => esc_html__('30 Days', 'event_espresso')
2489
            )
2490
        );
2491
    }
2492
2493
2494
    /**
2495
     * @return bool
2496
     */
2497
    public function isConsentCheckboxEnabled()
2498
    {
2499
        return $this->consent_checkbox_enabled;
2500
    }
2501
2502
2503
    /**
2504
     * @param bool $consent_checkbox_enabled
2505
     */
2506
    public function setConsentCheckboxEnabled($consent_checkbox_enabled)
2507
    {
2508
        $this->consent_checkbox_enabled = filter_var(
2509
            $consent_checkbox_enabled,
2510
            FILTER_VALIDATE_BOOLEAN
2511
        );
2512
    }
2513
2514
2515
    /**
2516
     * @return string
2517
     */
2518
    public function getConsentCheckboxLabelText()
2519
    {
2520
        return $this->consent_checkbox_label_text;
2521
    }
2522
2523
2524
    /**
2525
     * @param string $consent_checkbox_label_text
2526
     */
2527
    public function setConsentCheckboxLabelText($consent_checkbox_label_text)
2528
    {
2529
        $this->consent_checkbox_label_text = (string) $consent_checkbox_label_text;
2530
    }
2531
}
2532
2533
/**
2534
 * Class for defining what's in the EE_Config relating to admin settings
2535
 */
2536
class EE_Admin_Config extends EE_Config_Base
2537
{
2538
2539
    /**
2540
     * @var boolean $use_personnel_manager
2541
     */
2542
    public $use_personnel_manager;
2543
2544
    /**
2545
     * @var boolean $use_dashboard_widget
2546
     */
2547
    public $use_dashboard_widget;
2548
2549
    /**
2550
     * @var int $events_in_dashboard
2551
     */
2552
    public $events_in_dashboard;
2553
2554
    /**
2555
     * @var boolean $use_event_timezones
2556
     */
2557
    public $use_event_timezones;
2558
2559
    /**
2560
     * @var boolean $use_full_logging
2561
     */
2562
    public $use_full_logging;
2563
2564
    /**
2565
     * @var string $log_file_name
2566
     */
2567
    public $log_file_name;
2568
2569
    /**
2570
     * @var string $debug_file_name
2571
     */
2572
    public $debug_file_name;
2573
2574
    /**
2575
     * @var boolean $use_remote_logging
2576
     */
2577
    public $use_remote_logging;
2578
2579
    /**
2580
     * @var string $remote_logging_url
2581
     */
2582
    public $remote_logging_url;
2583
2584
    /**
2585
     * @var boolean $show_reg_footer
2586
     */
2587
    public $show_reg_footer;
2588
2589
    /**
2590
     * @var string $affiliate_id
2591
     */
2592
    public $affiliate_id;
2593
2594
    /**
2595
     * help tours on or off (global setting)
2596
     *
2597
     * @var boolean
2598
     */
2599
    public $help_tour_activation;
2600
2601
    /**
2602
     * adds extra layer of encoding to session data to prevent serialization errors
2603
     * but is incompatible with some server configuration errors
2604
     * if you get "500 internal server errors" during registration, try turning this on
2605
     * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2606
     *
2607
     * @var boolean $encode_session_data
2608
     */
2609
    private $encode_session_data = false;
2610
2611
2612
    /**
2613
     *    class constructor
2614
     *
2615
     * @access    public
2616
     */
2617
    public function __construct()
2618
    {
2619
        // set default general admin settings
2620
        $this->use_personnel_manager = true;
2621
        $this->use_dashboard_widget = true;
2622
        $this->events_in_dashboard = 30;
2623
        $this->use_event_timezones = false;
2624
        $this->use_full_logging = false;
2625
        $this->use_remote_logging = false;
2626
        $this->remote_logging_url = null;
2627
        $this->show_reg_footer = true;
2628
        $this->affiliate_id = 'default';
2629
        $this->help_tour_activation = true;
2630
        $this->encode_session_data = false;
2631
    }
2632
2633
2634
    /**
2635
     * @param bool $reset
2636
     * @return string
2637
     */
2638 View Code Duplication
    public function log_file_name($reset = false)
2639
    {
2640
        if (empty($this->log_file_name) || $reset) {
2641
            $this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2642
            EE_Config::instance()->update_espresso_config(false, false);
2643
        }
2644
        return $this->log_file_name;
2645
    }
2646
2647
2648
    /**
2649
     * @param bool $reset
2650
     * @return string
2651
     */
2652 View Code Duplication
    public function debug_file_name($reset = false)
2653
    {
2654
        if (empty($this->debug_file_name) || $reset) {
2655
            $this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2656
            EE_Config::instance()->update_espresso_config(false, false);
2657
        }
2658
        return $this->debug_file_name;
2659
    }
2660
2661
2662
    /**
2663
     * @return string
2664
     */
2665
    public function affiliate_id()
2666
    {
2667
        return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2668
    }
2669
2670
2671
    /**
2672
     * @return boolean
2673
     */
2674
    public function encode_session_data()
2675
    {
2676
        return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2677
    }
2678
2679
2680
    /**
2681
     * @param boolean $encode_session_data
2682
     */
2683
    public function set_encode_session_data($encode_session_data)
2684
    {
2685
        $this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2686
    }
2687
}
2688
2689
/**
2690
 * Class for defining what's in the EE_Config relating to template settings
2691
 */
2692
class EE_Template_Config extends EE_Config_Base
2693
{
2694
2695
    /**
2696
     * @var boolean $enable_default_style
2697
     */
2698
    public $enable_default_style;
2699
2700
    /**
2701
     * @var string $custom_style_sheet
2702
     */
2703
    public $custom_style_sheet;
2704
2705
    /**
2706
     * @var boolean $display_address_in_regform
2707
     */
2708
    public $display_address_in_regform;
2709
2710
    /**
2711
     * @var int $display_description_on_multi_reg_page
2712
     */
2713
    public $display_description_on_multi_reg_page;
2714
2715
    /**
2716
     * @var boolean $use_custom_templates
2717
     */
2718
    public $use_custom_templates;
2719
2720
    /**
2721
     * @var string $current_espresso_theme
2722
     */
2723
    public $current_espresso_theme;
2724
2725
    /**
2726
     * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2727
     */
2728
    public $EED_Ticket_Selector;
2729
2730
    /**
2731
     * @var EE_Event_Single_Config $EED_Event_Single
2732
     */
2733
    public $EED_Event_Single;
2734
2735
    /**
2736
     * @var EE_Events_Archive_Config $EED_Events_Archive
2737
     */
2738
    public $EED_Events_Archive;
2739
2740
2741
    /**
2742
     *    class constructor
2743
     *
2744
     * @access    public
2745
     */
2746
    public function __construct()
2747
    {
2748
        // set default template settings
2749
        $this->enable_default_style = true;
2750
        $this->custom_style_sheet = null;
2751
        $this->display_address_in_regform = true;
2752
        $this->display_description_on_multi_reg_page = false;
2753
        $this->use_custom_templates = false;
2754
        $this->current_espresso_theme = 'Espresso_Arabica_2014';
2755
        $this->EED_Event_Single = null;
2756
        $this->EED_Events_Archive = null;
2757
        $this->EED_Ticket_Selector = null;
2758
    }
2759
}
2760
2761
/**
2762
 * Class for defining what's in the EE_Config relating to map settings
2763
 */
2764
class EE_Map_Config extends EE_Config_Base
2765
{
2766
2767
    /**
2768
     * @var boolean $use_google_maps
2769
     */
2770
    public $use_google_maps;
2771
2772
    /**
2773
     * @var string $api_key
2774
     */
2775
    public $google_map_api_key;
2776
2777
    /**
2778
     * @var int $event_details_map_width
2779
     */
2780
    public $event_details_map_width;
2781
2782
    /**
2783
     * @var int $event_details_map_height
2784
     */
2785
    public $event_details_map_height;
2786
2787
    /**
2788
     * @var int $event_details_map_zoom
2789
     */
2790
    public $event_details_map_zoom;
2791
2792
    /**
2793
     * @var boolean $event_details_display_nav
2794
     */
2795
    public $event_details_display_nav;
2796
2797
    /**
2798
     * @var boolean $event_details_nav_size
2799
     */
2800
    public $event_details_nav_size;
2801
2802
    /**
2803
     * @var string $event_details_control_type
2804
     */
2805
    public $event_details_control_type;
2806
2807
    /**
2808
     * @var string $event_details_map_align
2809
     */
2810
    public $event_details_map_align;
2811
2812
    /**
2813
     * @var int $event_list_map_width
2814
     */
2815
    public $event_list_map_width;
2816
2817
    /**
2818
     * @var int $event_list_map_height
2819
     */
2820
    public $event_list_map_height;
2821
2822
    /**
2823
     * @var int $event_list_map_zoom
2824
     */
2825
    public $event_list_map_zoom;
2826
2827
    /**
2828
     * @var boolean $event_list_display_nav
2829
     */
2830
    public $event_list_display_nav;
2831
2832
    /**
2833
     * @var boolean $event_list_nav_size
2834
     */
2835
    public $event_list_nav_size;
2836
2837
    /**
2838
     * @var string $event_list_control_type
2839
     */
2840
    public $event_list_control_type;
2841
2842
    /**
2843
     * @var string $event_list_map_align
2844
     */
2845
    public $event_list_map_align;
2846
2847
2848
    /**
2849
     *    class constructor
2850
     *
2851
     * @access    public
2852
     */
2853
    public function __construct()
2854
    {
2855
        // set default map settings
2856
        $this->use_google_maps = true;
2857
        $this->google_map_api_key = '';
2858
        // for event details pages (reg page)
2859
        $this->event_details_map_width = 585;            // ee_map_width_single
2860
        $this->event_details_map_height = 362;            // ee_map_height_single
2861
        $this->event_details_map_zoom = 14;            // ee_map_zoom_single
2862
        $this->event_details_display_nav = true;            // ee_map_nav_display_single
2863
        $this->event_details_nav_size = false;            // ee_map_nav_size_single
2864
        $this->event_details_control_type = 'default';        // ee_map_type_control_single
2865
        $this->event_details_map_align = 'center';            // ee_map_align_single
2866
        // for event list pages
2867
        $this->event_list_map_width = 300;            // ee_map_width
2868
        $this->event_list_map_height = 185;        // ee_map_height
2869
        $this->event_list_map_zoom = 12;            // ee_map_zoom
2870
        $this->event_list_display_nav = false;        // ee_map_nav_display
2871
        $this->event_list_nav_size = true;            // ee_map_nav_size
2872
        $this->event_list_control_type = 'dropdown';        // ee_map_type_control
2873
        $this->event_list_map_align = 'center';            // ee_map_align
2874
    }
2875
}
2876
2877
/**
2878
 * stores Events_Archive settings
2879
 */
2880
class EE_Events_Archive_Config extends EE_Config_Base
2881
{
2882
2883
    public $display_status_banner;
2884
2885
    public $display_description;
2886
2887
    public $display_ticket_selector;
2888
2889
    public $display_datetimes;
2890
2891
    public $display_venue;
2892
2893
    public $display_expired_events;
2894
2895
    public $use_sortable_display_order;
2896
2897
    public $display_order_tickets;
2898
2899
    public $display_order_datetimes;
2900
2901
    public $display_order_event;
2902
2903
    public $display_order_venue;
2904
2905
2906
    /**
2907
     *    class constructor
2908
     */
2909
    public function __construct()
2910
    {
2911
        $this->display_status_banner = 0;
2912
        $this->display_description = 1;
2913
        $this->display_ticket_selector = 0;
2914
        $this->display_datetimes = 1;
2915
        $this->display_venue = 0;
2916
        $this->display_expired_events = 0;
2917
        $this->use_sortable_display_order = false;
2918
        $this->display_order_tickets = 100;
2919
        $this->display_order_datetimes = 110;
2920
        $this->display_order_event = 120;
2921
        $this->display_order_venue = 130;
2922
    }
2923
}
2924
2925
/**
2926
 * Stores Event_Single_Config settings
2927
 */
2928
class EE_Event_Single_Config extends EE_Config_Base
2929
{
2930
2931
    public $display_status_banner_single;
2932
2933
    public $display_venue;
2934
2935
    public $use_sortable_display_order;
2936
2937
    public $display_order_tickets;
2938
2939
    public $display_order_datetimes;
2940
2941
    public $display_order_event;
2942
2943
    public $display_order_venue;
2944
2945
2946
    /**
2947
     *    class constructor
2948
     */
2949
    public function __construct()
2950
    {
2951
        $this->display_status_banner_single = 0;
2952
        $this->display_venue = 1;
2953
        $this->use_sortable_display_order = false;
2954
        $this->display_order_tickets = 100;
2955
        $this->display_order_datetimes = 110;
2956
        $this->display_order_event = 120;
2957
        $this->display_order_venue = 130;
2958
    }
2959
}
2960
2961
/**
2962
 * Stores Ticket_Selector_Config settings
2963
 */
2964
class EE_Ticket_Selector_Config extends EE_Config_Base
2965
{
2966
2967
    /**
2968
     * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
2969
     */
2970
    const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
2971
2972
    /**
2973
     * constant to indicate that a datetime selector should only be shown for ticket selectors
2974
     * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
2975
     */
2976
    const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
2977
2978
    /**
2979
     * @var boolean $show_ticket_sale_columns
2980
     */
2981
    public $show_ticket_sale_columns;
2982
2983
    /**
2984
     * @var boolean $show_ticket_details
2985
     */
2986
    public $show_ticket_details;
2987
2988
    /**
2989
     * @var boolean $show_expired_tickets
2990
     */
2991
    public $show_expired_tickets;
2992
2993
    /**
2994
     * whether or not to display a dropdown box populated with event datetimes
2995
     * that toggles which tickets are displayed for a ticket selector.
2996
     * uses one of the *_DATETIME_SELECTOR constants defined above
2997
     *
2998
     * @var string $show_datetime_selector
2999
     */
3000
    private $show_datetime_selector = 'no_datetime_selector';
3001
3002
    /**
3003
     * the number of datetimes an event has to have before conditionally displaying a datetime selector
3004
     *
3005
     * @var int $datetime_selector_threshold
3006
     */
3007
    private $datetime_selector_threshold = 3;
3008
3009
3010
    /**
3011
     *    class constructor
3012
     */
3013
    public function __construct()
3014
    {
3015
        $this->show_ticket_sale_columns = true;
3016
        $this->show_ticket_details = true;
3017
        $this->show_expired_tickets = true;
3018
        $this->show_datetime_selector = \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3019
        $this->datetime_selector_threshold = 3;
3020
    }
3021
3022
3023
    /**
3024
     * returns true if a datetime selector should be displayed
3025
     *
3026
     * @param array $datetimes
3027
     * @return bool
3028
     */
3029
    public function showDatetimeSelector(array $datetimes)
3030
    {
3031
        // if the settings are NOT: don't show OR below threshold, THEN active = true
3032
        return ! (
3033
            $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3034
            || (
3035
                $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3036
                && count($datetimes) < $this->getDatetimeSelectorThreshold()
3037
            )
3038
        );
3039
    }
3040
3041
3042
    /**
3043
     * @return string
3044
     */
3045
    public function getShowDatetimeSelector()
3046
    {
3047
        return $this->show_datetime_selector;
3048
    }
3049
3050
3051
    /**
3052
     * @param bool $keys_only
3053
     * @return array
3054
     */
3055
    public function getShowDatetimeSelectorOptions($keys_only = true)
3056
    {
3057
        return $keys_only
3058
            ? array(
3059
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3060
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3061
            )
3062
            : array(
3063
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3064
                    'Do not show date & time filter',
3065
                    'event_espresso'
3066
                ),
3067
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3068
                    'Maybe show date & time filter',
3069
                    'event_espresso'
3070
                ),
3071
            );
3072
    }
3073
3074
3075
    /**
3076
     * @param string $show_datetime_selector
3077
     */
3078
    public function setShowDatetimeSelector($show_datetime_selector)
3079
    {
3080
        $this->show_datetime_selector = in_array(
3081
            $show_datetime_selector,
3082
            $this->getShowDatetimeSelectorOptions(),
3083
            true
3084
        )
3085
            ? $show_datetime_selector
3086
            : \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3087
    }
3088
3089
3090
    /**
3091
     * @return int
3092
     */
3093
    public function getDatetimeSelectorThreshold()
3094
    {
3095
        return $this->datetime_selector_threshold;
3096
    }
3097
3098
3099
    /**
3100
     * @param int $datetime_selector_threshold
3101
     */
3102
    public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3103
    {
3104
        $datetime_selector_threshold = absint($datetime_selector_threshold);
3105
        $this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3106
    }
3107
}
3108
3109
/**
3110
 * Stores any EE Environment values that are referenced through the code.
3111
 *
3112
 * @since       4.4.0
3113
 * @package     Event Espresso
3114
 * @subpackage  config
3115
 */
3116
class EE_Environment_Config extends EE_Config_Base
3117
{
3118
3119
    /**
3120
     * Hold any php environment variables that we want to track.
3121
     *
3122
     * @var stdClass;
3123
     */
3124
    public $php;
3125
3126
3127
    /**
3128
     *    constructor
3129
     */
3130
    public function __construct()
3131
    {
3132
        $this->php = new stdClass();
3133
        $this->_set_php_values();
3134
    }
3135
3136
3137
    /**
3138
     * This sets the php environment variables.
3139
     *
3140
     * @since 4.4.0
3141
     * @return void
3142
     */
3143
    protected function _set_php_values()
3144
    {
3145
        $this->php->max_input_vars = ini_get('max_input_vars');
3146
        $this->php->version = phpversion();
3147
    }
3148
3149
3150
    /**
3151
     * helper method for determining whether input_count is
3152
     * reaching the potential maximum the server can handle
3153
     * according to max_input_vars
3154
     *
3155
     * @param int   $input_count the count of input vars.
3156
     * @return array {
3157
     *                           An array that represents whether available space and if no available space the error
3158
     *                           message.
3159
     * @type bool   $has_space   whether more inputs can be added.
3160
     * @type string $msg         Any message to be displayed.
3161
     *                           }
3162
     */
3163
    public function max_input_vars_limit_check($input_count = 0)
3164
    {
3165
        if (! empty($this->php->max_input_vars)
3166
            && ($input_count >= $this->php->max_input_vars)
3167
            && (PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3 && PHP_RELEASE_VERSION >= 9)
3168
        ) {
3169
            return sprintf(
3170
                __(
3171
                    'The maximum number of inputs on this page has been exceeded.  You cannot add anymore items (i.e. tickets, datetimes, custom fields) on this page because of your servers PHP "max_input_vars" setting.%1$sThere are %2$d inputs and the maximum amount currently allowed by your server is %3$d.',
3172
                    'event_espresso'
3173
                ),
3174
                '<br>',
3175
                $input_count,
3176
                $this->php->max_input_vars
3177
            );
3178
        } else {
3179
            return '';
3180
        }
3181
    }
3182
3183
3184
    /**
3185
     * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3186
     *
3187
     * @since 4.4.1
3188
     * @return void
3189
     */
3190
    public function recheck_values()
3191
    {
3192
        $this->_set_php_values();
3193
    }
3194
}
3195
3196
/**
3197
 * Stores any options pertaining to taxes
3198
 *
3199
 * @since       4.9.13
3200
 * @package     Event Espresso
3201
 * @subpackage  config
3202
 */
3203
class EE_Tax_Config extends EE_Config_Base
3204
{
3205
3206
    /*
3207
     * flag to indicate whether or not to display ticket prices with the taxes included
3208
     *
3209
     * @var boolean $prices_displayed_including_taxes
3210
     */
3211
    public $prices_displayed_including_taxes;
3212
3213
3214
    /**
3215
     *    class constructor
3216
     */
3217
    public function __construct()
3218
    {
3219
        $this->prices_displayed_including_taxes = true;
3220
    }
3221
}
3222
3223
/**
3224
 * Holds all global messages configuration options.
3225
 *
3226
 * @package    EventEspresso/core/
3227
 * @subpackage config
3228
 * @author     Darren Ethier
3229
 * @since      4.27.rc
3230
 */
3231
class EE_Messages_Config extends EE_Config_Base
3232
{
3233
3234
    /**
3235
     * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3236
     * A value of 0 represents never deleting.  Default is 0.
3237
     *
3238
     * @var integer
3239
     */
3240
    public $delete_threshold;
3241
3242
3243
    public function __construct()
3244
    {
3245
        $this->delete_threshold = 0;
3246
    }
3247
}
3248
3249
/**
3250
 * stores payment gateway info
3251
 *
3252
 * @deprecated
3253
 */
3254
class EE_Gateway_Config extends EE_Config_Base
3255
{
3256
3257
    /**
3258
     * Array with keys that are payment gateways slugs, and values are arrays
3259
     * with any config info the gateway wants to store
3260
     *
3261
     * @var array
3262
     */
3263
    public $payment_settings;
3264
3265
    /**
3266
     * Where keys are gateway slugs, and values are booleans indicating whether or not
3267
     * the gateway is stored in the uploads directory
3268
     *
3269
     * @var array
3270
     */
3271
    public $active_gateways;
3272
3273
3274
    /**
3275
     *    class constructor
3276
     *
3277
     * @deprecated
3278
     */
3279
    public function __construct()
3280
    {
3281
        $this->payment_settings = array();
3282
        $this->active_gateways = array('Invoice' => false);
3283
    }
3284
}
3285