Completed
Branch FET/paypal-smart-button2 (052e8d)
by
unknown
102:07 queued 88:11
created

EE_Registration_Config::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 22
nc 1
nop 0
dl 0
loc 25
rs 8.8571
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
    const OPTION_NAME_UXIP = 'ee_ueip_optin';
1611
1612
1613
    public $current_blog_id;
1614
1615
    public $ee_ueip_optin;
1616
1617
    public $ee_ueip_has_notified;
1618
1619
    /**
1620
     * Not to be confused with the 4 critical page variables (See
1621
     * get_critical_pages_array()), this is just an array of wp posts that have EE
1622
     * shortcodes in them. Keys are slugs, values are arrays with only 1 element: where the key is the shortcode
1623
     * in the page, and the value is the page's ID. The key 'posts' is basically a duplicate of this same array.
1624
     *
1625
     * @var array
1626
     */
1627
    public $post_shortcodes;
1628
1629
    public $module_route_map;
1630
1631
    public $module_forward_map;
1632
1633
    public $module_view_map;
1634
1635
    /**
1636
     * The next 4 vars are the IDs of critical EE pages.
1637
     *
1638
     * @var int
1639
     */
1640
    public $reg_page_id;
1641
1642
    public $txn_page_id;
1643
1644
    public $thank_you_page_id;
1645
1646
    public $cancel_page_id;
1647
1648
    /**
1649
     * The next 4 vars are the URLs of critical EE pages.
1650
     *
1651
     * @var int
1652
     */
1653
    public $reg_page_url;
1654
1655
    public $txn_page_url;
1656
1657
    public $thank_you_page_url;
1658
1659
    public $cancel_page_url;
1660
1661
    /**
1662
     * The next vars relate to the custom slugs for EE CPT routes
1663
     */
1664
    public $event_cpt_slug;
1665
1666
    /**
1667
     * This caches the _ee_ueip_option in case this config is reset in the same
1668
     * request across blog switches in a multisite context.
1669
     * Avoids extra queries to the db for this option.
1670
     *
1671
     * @var bool
1672
     */
1673
    public static $ee_ueip_option;
1674
1675
1676
    /**
1677
     *    class constructor
1678
     *
1679
     * @access    public
1680
     */
1681
    public function __construct()
1682
    {
1683
        // set default organization settings
1684
        $this->current_blog_id = get_current_blog_id();
1685
        $this->current_blog_id = $this->current_blog_id === null ? 1 : $this->current_blog_id;
1686
        $this->ee_ueip_optin = $this->_get_main_ee_ueip_optin();
1687
        $this->ee_ueip_has_notified = is_main_site() ? get_option('ee_ueip_has_notified', false) : true;
1688
        $this->post_shortcodes = array();
1689
        $this->module_route_map = array();
1690
        $this->module_forward_map = array();
1691
        $this->module_view_map = array();
1692
        // critical EE page IDs
1693
        $this->reg_page_id = 0;
1694
        $this->txn_page_id = 0;
1695
        $this->thank_you_page_id = 0;
1696
        $this->cancel_page_id = 0;
1697
        // critical EE page URLs
1698
        $this->reg_page_url = '';
1699
        $this->txn_page_url = '';
1700
        $this->thank_you_page_url = '';
1701
        $this->cancel_page_url = '';
1702
        // cpt slugs
1703
        $this->event_cpt_slug = __('events', 'event_espresso');
1704
        // ueip constant check
1705
        if (defined('EE_DISABLE_UXIP') && EE_DISABLE_UXIP) {
1706
            $this->ee_ueip_optin = false;
1707
            $this->ee_ueip_has_notified = true;
1708
        }
1709
    }
1710
1711
1712
    /**
1713
     * @return array
1714
     */
1715
    public function get_critical_pages_array()
1716
    {
1717
        return array(
1718
            $this->reg_page_id,
1719
            $this->txn_page_id,
1720
            $this->thank_you_page_id,
1721
            $this->cancel_page_id,
1722
        );
1723
    }
1724
1725
1726
    /**
1727
     * @return array
1728
     */
1729
    public function get_critical_pages_shortcodes_array()
1730
    {
1731
        return array(
1732
            $this->reg_page_id       => 'ESPRESSO_CHECKOUT',
1733
            $this->txn_page_id       => 'ESPRESSO_TXN_PAGE',
1734
            $this->thank_you_page_id => 'ESPRESSO_THANK_YOU',
1735
            $this->cancel_page_id    => 'ESPRESSO_CANCELLED',
1736
        );
1737
    }
1738
1739
1740
    /**
1741
     *  gets/returns URL for EE reg_page
1742
     *
1743
     * @access    public
1744
     * @return    string
1745
     */
1746
    public function reg_page_url()
1747
    {
1748
        if (! $this->reg_page_url) {
1749
            $this->reg_page_url = add_query_arg(
1750
                array('uts' => time()),
1751
                get_permalink($this->reg_page_id)
1752
            ) . '#checkout';
1753
        }
1754
        return $this->reg_page_url;
1755
    }
1756
1757
1758
    /**
1759
     *  gets/returns URL for EE txn_page
1760
     *
1761
     * @param array $query_args like what gets passed to
1762
     *                          add_query_arg() as the first argument
1763
     * @access    public
1764
     * @return    string
1765
     */
1766 View Code Duplication
    public function txn_page_url($query_args = array())
1767
    {
1768
        if (! $this->txn_page_url) {
1769
            $this->txn_page_url = get_permalink($this->txn_page_id);
1770
        }
1771
        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...
1772
            return add_query_arg($query_args, $this->txn_page_url);
1773
        } else {
1774
            return $this->txn_page_url;
1775
        }
1776
    }
1777
1778
1779
    /**
1780
     *  gets/returns URL for EE thank_you_page
1781
     *
1782
     * @param array $query_args like what gets passed to
1783
     *                          add_query_arg() as the first argument
1784
     * @access    public
1785
     * @return    string
1786
     */
1787 View Code Duplication
    public function thank_you_page_url($query_args = array())
1788
    {
1789
        if (! $this->thank_you_page_url) {
1790
            $this->thank_you_page_url = get_permalink($this->thank_you_page_id);
1791
        }
1792
        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...
1793
            return add_query_arg($query_args, $this->thank_you_page_url);
1794
        } else {
1795
            return $this->thank_you_page_url;
1796
        }
1797
    }
1798
1799
1800
    /**
1801
     *  gets/returns URL for EE cancel_page
1802
     *
1803
     * @access    public
1804
     * @return    string
1805
     */
1806
    public function cancel_page_url()
1807
    {
1808
        if (! $this->cancel_page_url) {
1809
            $this->cancel_page_url = get_permalink($this->cancel_page_id);
1810
        }
1811
        return $this->cancel_page_url;
1812
    }
1813
1814
1815
    /**
1816
     * Resets all critical page urls to their original state.  Used primarily by the __sleep() magic method currently.
1817
     *
1818
     * @since 4.7.5
1819
     */
1820
    protected function _reset_urls()
1821
    {
1822
        $this->reg_page_url = '';
1823
        $this->txn_page_url = '';
1824
        $this->cancel_page_url = '';
1825
        $this->thank_you_page_url = '';
1826
    }
1827
1828
1829
    /**
1830
     * Used to return what the optin value is set for the EE User Experience Program.
1831
     * This accounts for multisite and this value being requested for a subsite.  In multisite, the value is set
1832
     * on the main site only.
1833
     *
1834
     * @return bool
1835
     */
1836
    protected function _get_main_ee_ueip_optin()
1837
    {
1838
        // if this is the main site then we can just bypass our direct query.
1839
        if (is_main_site()) {
1840
            return get_option(self::OPTION_NAME_UXIP, false);
1841
        }
1842
        // is this already cached for this request?  If so use it.
1843
        if (EE_Core_Config::$ee_ueip_option !== null) {
1844
            return EE_Core_Config::$ee_ueip_option;
1845
        }
1846
        global $wpdb;
1847
        $current_network_main_site = is_multisite() ? get_current_site() : null;
1848
        $current_main_site_id = ! empty($current_network_main_site) ? $current_network_main_site->blog_id : 1;
1849
        $option = self::OPTION_NAME_UXIP;
1850
        // set correct table for query
1851
        $table_name = $wpdb->get_blog_prefix($current_main_site_id) . 'options';
1852
        // rather than getting blog option for the $current_main_site_id, we do a direct $wpdb query because
1853
        // get_blog_option() does a switch_to_blog an that could cause infinite recursion because EE_Core_Config might be
1854
        // re-constructed on the blog switch.  Note, we are still executing any core wp filters on this option retrieval.
1855
        // this bit of code is basically a direct copy of get_option without any caching because we are NOT switched to the blog
1856
        // for the purpose of caching.
1857
        $pre = apply_filters('pre_option_' . $option, false, $option);
1858
        if (false !== $pre) {
1859
            EE_Core_Config::$ee_ueip_option = $pre;
1860
            return EE_Core_Config::$ee_ueip_option;
1861
        }
1862
        $row = $wpdb->get_row(
1863
            $wpdb->prepare(
1864
                "SELECT option_value FROM $table_name WHERE option_name = %s LIMIT 1",
1865
                $option
1866
            )
1867
        );
1868
        if (is_object($row)) {
1869
            $value = $row->option_value;
1870
        } else { // option does not exist so use default.
1871
            EE_Core_Config::$ee_ueip_option =  apply_filters('default_option_' . $option, false, $option);
1872
            return EE_Core_Config::$ee_ueip_option;
1873
        }
1874
        EE_Core_Config::$ee_ueip_option = apply_filters('option_' . $option, maybe_unserialize($value), $option);
1875
        return EE_Core_Config::$ee_ueip_option;
1876
    }
1877
1878
1879
    /**
1880
     * Utility function for escaping the value of a property and returning.
1881
     *
1882
     * @param string $property property name (checks to see if exists).
1883
     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1884
     * @throws \EE_Error
1885
     */
1886
    public function get_pretty($property)
1887
    {
1888
        if ($property === self::OPTION_NAME_UXIP) {
1889
            return $this->ee_ueip_optin ? 'yes' : 'no';
1890
        }
1891
        return parent::get_pretty($property);
1892
    }
1893
1894
1895
    /**
1896
     * Currently used to ensure critical page urls have initial values saved to the db instead of any current set values
1897
     * on the object.
1898
     *
1899
     * @return array
1900
     */
1901
    public function __sleep()
1902
    {
1903
        // reset all url properties
1904
        $this->_reset_urls();
1905
        // return what to save to db
1906
        return array_keys(get_object_vars($this));
1907
    }
1908
}
1909
1910
/**
1911
 * Config class for storing info on the Organization
1912
 */
1913
class EE_Organization_Config extends EE_Config_Base
1914
{
1915
1916
    /**
1917
     * @var string $name
1918
     * eg EE4.1
1919
     */
1920
    public $name;
1921
1922
    /**
1923
     * @var string $address_1
1924
     * eg 123 Onna Road
1925
     */
1926
    public $address_1;
1927
1928
    /**
1929
     * @var string $address_2
1930
     * eg PO Box 123
1931
     */
1932
    public $address_2;
1933
1934
    /**
1935
     * @var string $city
1936
     * eg Inna City
1937
     */
1938
    public $city;
1939
1940
    /**
1941
     * @var int $STA_ID
1942
     * eg 4
1943
     */
1944
    public $STA_ID;
1945
1946
    /**
1947
     * @var string $CNT_ISO
1948
     * eg US
1949
     */
1950
    public $CNT_ISO;
1951
1952
    /**
1953
     * @var string $zip
1954
     * eg 12345  or V1A 2B3
1955
     */
1956
    public $zip;
1957
1958
    /**
1959
     * @var string $email
1960
     * eg [email protected]
1961
     */
1962
    public $email;
1963
1964
    /**
1965
     * @var string $phone
1966
     * eg. 111-111-1111
1967
     */
1968
    public $phone;
1969
1970
    /**
1971
     * @var string $vat
1972
     * VAT/Tax Number
1973
     */
1974
    public $vat;
1975
1976
    /**
1977
     * @var string $logo_url
1978
     * eg http://www.somedomain.com/wp-content/uploads/kittehs.jpg
1979
     */
1980
    public $logo_url;
1981
1982
    /**
1983
     * The below are all various properties for holding links to organization social network profiles
1984
     *
1985
     * @var string
1986
     */
1987
    /**
1988
     * facebook (facebook.com/profile.name)
1989
     *
1990
     * @var string
1991
     */
1992
    public $facebook;
1993
1994
    /**
1995
     * twitter (twitter.com/twitter_handle)
1996
     *
1997
     * @var string
1998
     */
1999
    public $twitter;
2000
2001
    /**
2002
     * linkedin (linkedin.com/in/profile_name)
2003
     *
2004
     * @var string
2005
     */
2006
    public $linkedin;
2007
2008
    /**
2009
     * pinterest (www.pinterest.com/profile_name)
2010
     *
2011
     * @var string
2012
     */
2013
    public $pinterest;
2014
2015
    /**
2016
     * google+ (google.com/+profileName)
2017
     *
2018
     * @var string
2019
     */
2020
    public $google;
2021
2022
    /**
2023
     * instagram (instagram.com/handle)
2024
     *
2025
     * @var string
2026
     */
2027
    public $instagram;
2028
2029
2030
    /**
2031
     *    class constructor
2032
     *
2033
     * @access    public
2034
     */
2035
    public function __construct()
2036
    {
2037
        // set default organization settings
2038
        // decode HTML entities from the WP blogname, because it's stored in the DB with HTML entities encoded
2039
        $this->name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
2040
        $this->address_1 = '123 Onna Road';
2041
        $this->address_2 = 'PO Box 123';
2042
        $this->city = 'Inna City';
2043
        $this->STA_ID = 4;
2044
        $this->CNT_ISO = 'US';
2045
        $this->zip = '12345';
2046
        $this->email = get_bloginfo('admin_email');
2047
        $this->phone = '';
2048
        $this->vat = '123456789';
2049
        $this->logo_url = '';
2050
        $this->facebook = '';
2051
        $this->twitter = '';
2052
        $this->linkedin = '';
2053
        $this->pinterest = '';
2054
        $this->google = '';
2055
        $this->instagram = '';
2056
    }
2057
}
2058
2059
/**
2060
 * Class for defining what's in the EE_Config relating to currency
2061
 */
2062
class EE_Currency_Config extends EE_Config_Base
2063
{
2064
2065
    /**
2066
     * @var string $code
2067
     * eg 'US'
2068
     */
2069
    public $code;
2070
2071
    /**
2072
     * @var string $name
2073
     * eg 'Dollar'
2074
     */
2075
    public $name;
2076
2077
    /**
2078
     * plural name
2079
     *
2080
     * @var string $plural
2081
     * eg 'Dollars'
2082
     */
2083
    public $plural;
2084
2085
    /**
2086
     * currency sign
2087
     *
2088
     * @var string $sign
2089
     * eg '$'
2090
     */
2091
    public $sign;
2092
2093
    /**
2094
     * Whether the currency sign should come before the number or not
2095
     *
2096
     * @var boolean $sign_b4
2097
     */
2098
    public $sign_b4;
2099
2100
    /**
2101
     * How many digits should come after the decimal place
2102
     *
2103
     * @var int $dec_plc
2104
     */
2105
    public $dec_plc;
2106
2107
    /**
2108
     * Symbol to use for decimal mark
2109
     *
2110
     * @var string $dec_mrk
2111
     * eg '.'
2112
     */
2113
    public $dec_mrk;
2114
2115
    /**
2116
     * Symbol to use for thousands
2117
     *
2118
     * @var string $thsnds
2119
     * eg ','
2120
     */
2121
    public $thsnds;
2122
2123
2124
    /**
2125
     *    class constructor
2126
     *
2127
     * @access    public
2128
     * @param string $CNT_ISO
2129
     * @throws \EE_Error
2130
     */
2131
    public function __construct($CNT_ISO = '')
2132
    {
2133
        /** @var \EventEspresso\core\services\database\TableAnalysis $table_analysis */
2134
        $table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
2135
        // get country code from organization settings or use default
2136
        $ORG_CNT = isset(EE_Registry::instance()->CFG->organization)
2137
                   && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
2138
            ? EE_Registry::instance()->CFG->organization->CNT_ISO
2139
            : '';
2140
        // but override if requested
2141
        $CNT_ISO = ! empty($CNT_ISO) ? $CNT_ISO : $ORG_CNT;
2142
        // 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
2143
        if (! empty($CNT_ISO)
2144
            && EE_Maintenance_Mode::instance()->models_can_query()
2145
            && $table_analysis->tableExists(EE_Registry::instance()->load_model('Country')->table())
2146
        ) {
2147
            // retrieve the country settings from the db, just in case they have been customized
2148
            $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
2149
            if ($country instanceof EE_Country) {
2150
                $this->code = $country->currency_code();    // currency code: USD, CAD, EUR
2151
                $this->name = $country->currency_name_single();    // Dollar
2152
                $this->plural = $country->currency_name_plural();    // Dollars
2153
                $this->sign = $country->currency_sign();            // currency sign: $
2154
                $this->sign_b4 = $country->currency_sign_before(
2155
                );        // currency sign before or after: $TRUE  or  FALSE$
2156
                $this->dec_plc = $country->currency_decimal_places();    // decimal places: 2 = 0.00  3 = 0.000
2157
                $this->dec_mrk = $country->currency_decimal_mark(
2158
                );    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2159
                $this->thsnds = $country->currency_thousands_separator(
2160
                );    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2161
            }
2162
        }
2163
        // fallback to hardcoded defaults, in case the above failed
2164
        if (empty($this->code)) {
2165
            // set default currency settings
2166
            $this->code = 'USD';    // currency code: USD, CAD, EUR
2167
            $this->name = __('Dollar', 'event_espresso');    // Dollar
2168
            $this->plural = __('Dollars', 'event_espresso');    // Dollars
2169
            $this->sign = '$';    // currency sign: $
2170
            $this->sign_b4 = true;    // currency sign before or after: $TRUE  or  FALSE$
2171
            $this->dec_plc = 2;    // decimal places: 2 = 0.00  3 = 0.000
2172
            $this->dec_mrk = '.';    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2173
            $this->thsnds = ',';    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2174
        }
2175
    }
2176
}
2177
2178
/**
2179
 * Class for defining what's in the EE_Config relating to registration settings
2180
 */
2181
class EE_Registration_Config extends EE_Config_Base
2182
{
2183
2184
    /**
2185
     * Default registration status
2186
     *
2187
     * @var string $default_STS_ID
2188
     * eg 'RPP'
2189
     */
2190
    public $default_STS_ID;
2191
2192
    /**
2193
     * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2194
     * registrations)
2195
     *
2196
     * @var int
2197
     */
2198
    public $default_maximum_number_of_tickets;
2199
2200
    /**
2201
     * level of validation to apply to email addresses
2202
     *
2203
     * @var string $email_validation_level
2204
     * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2205
     */
2206
    public $email_validation_level;
2207
2208
    /**
2209
     *    whether or not to show alternate payment options during the reg process if payment status is pending
2210
     *
2211
     * @var boolean $show_pending_payment_options
2212
     */
2213
    public $show_pending_payment_options;
2214
2215
    /**
2216
     * Whether to skip the registration confirmation page
2217
     *
2218
     * @var boolean $skip_reg_confirmation
2219
     */
2220
    public $skip_reg_confirmation;
2221
2222
    /**
2223
     * an array of SPCO reg steps where:
2224
     *        the keys denotes the reg step order
2225
     *        each element consists of an array with the following elements:
2226
     *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2227
     *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2228
     *            "slug" => the URL param used to trigger the reg step
2229
     *
2230
     * @var array $reg_steps
2231
     */
2232
    public $reg_steps;
2233
2234
    /**
2235
     * Whether registration confirmation should be the last page of SPCO
2236
     *
2237
     * @var boolean $reg_confirmation_last
2238
     */
2239
    public $reg_confirmation_last;
2240
2241
    /**
2242
     * Whether or not to enable the EE Bot Trap
2243
     *
2244
     * @var boolean $use_bot_trap
2245
     */
2246
    public $use_bot_trap;
2247
2248
    /**
2249
     * Whether or not to encrypt some data sent by the EE Bot Trap
2250
     *
2251
     * @var boolean $use_encryption
2252
     */
2253
    public $use_encryption;
2254
2255
    /**
2256
     * Whether or not to use ReCaptcha
2257
     *
2258
     * @var boolean $use_captcha
2259
     */
2260
    public $use_captcha;
2261
2262
    /**
2263
     * ReCaptcha Theme
2264
     *
2265
     * @var string $recaptcha_theme
2266
     *    options: 'dark', 'light', 'invisible'
2267
     */
2268
    public $recaptcha_theme;
2269
2270
    /**
2271
     * ReCaptcha Badge - determines the position of the reCAPTCHA badge if using Invisible ReCaptcha.
2272
     *
2273
     * @var string $recaptcha_badge
2274
     *    options: 'bottomright', 'bottomleft', 'inline'
2275
     */
2276
    public $recaptcha_badge;
2277
2278
    /**
2279
     * ReCaptcha Type
2280
     *
2281
     * @var string $recaptcha_type
2282
     *    options: 'audio', 'image'
2283
     */
2284
    public $recaptcha_type;
2285
2286
    /**
2287
     * ReCaptcha language
2288
     *
2289
     * @var string $recaptcha_language
2290
     * eg 'en'
2291
     */
2292
    public $recaptcha_language;
2293
2294
    /**
2295
     * ReCaptcha public key
2296
     *
2297
     * @var string $recaptcha_publickey
2298
     */
2299
    public $recaptcha_publickey;
2300
2301
    /**
2302
     * ReCaptcha private key
2303
     *
2304
     * @var string $recaptcha_privatekey
2305
     */
2306
    public $recaptcha_privatekey;
2307
2308
    /**
2309
     * array of form names protected by ReCaptcha
2310
     *
2311
     * @var array $recaptcha_protected_forms
2312
     */
2313
    public $recaptcha_protected_forms;
2314
2315
    /**
2316
     * ReCaptcha width
2317
     *
2318
     * @var int $recaptcha_width
2319
     * @deprecated
2320
     */
2321
    public $recaptcha_width;
2322
2323
    /**
2324
     * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2325
     *
2326
     * @var boolean $track_invalid_checkout_access
2327
     */
2328
    protected $track_invalid_checkout_access = true;
2329
2330
    /**
2331
     * Whether or not to show the privacy policy consent checkbox
2332
     *
2333
     * @var bool
2334
     */
2335
    public $consent_checkbox_enabled;
2336
2337
    /**
2338
     * Label text to show on the checkbox
2339
     *
2340
     * @var string
2341
     */
2342
    public $consent_checkbox_label_text;
2343
2344
    /*
2345
     * String describing how long to keep payment logs. Passed into DateTime constructor
2346
     * @var string
2347
     */
2348
    public $gateway_log_lifespan = '1 week';
2349
2350
2351
    /**
2352
     *    class constructor
2353
     *
2354
     * @access    public
2355
     */
2356
    public function __construct()
2357
    {
2358
        // set default registration settings
2359
        $this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2360
        $this->email_validation_level = 'wp_default';
2361
        $this->show_pending_payment_options = true;
2362
        $this->skip_reg_confirmation = true;
2363
        $this->reg_steps = array();
2364
        $this->reg_confirmation_last = false;
2365
        $this->use_bot_trap = true;
2366
        $this->use_encryption = true;
2367
        $this->use_captcha = false;
2368
        $this->recaptcha_theme = 'light';
2369
        $this->recaptcha_badge = 'bottomleft';
2370
        $this->recaptcha_type = 'image';
2371
        $this->recaptcha_language = 'en';
2372
        $this->recaptcha_publickey = null;
2373
        $this->recaptcha_privatekey = null;
2374
        $this->recaptcha_protected_forms = array();
2375
        $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...
2376
        $this->default_maximum_number_of_tickets = 10;
2377
        $this->consent_checkbox_enabled = false;
2378
        $this->consent_checkbox_label_text = '';
2379
        $this->gateway_log_lifespan = '7 days';
2380
    }
2381
2382
2383
    /**
2384
     * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2385
     *
2386
     * @since 4.8.8.rc.019
2387
     */
2388
    public function do_hooks()
2389
    {
2390
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2391
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2392
        add_action('setup_theme', array($this, 'setDefaultCheckboxLabelText'));
2393
    }
2394
2395
2396
    /**
2397
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the
2398
     * EVT_default_registration_status field matches the config setting for default_STS_ID.
2399
     */
2400
    public function set_default_reg_status_on_EEM_Event()
2401
    {
2402
        EEM_Event::set_default_reg_status($this->default_STS_ID);
2403
    }
2404
2405
2406
    /**
2407
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2408
     * for Events matches the config setting for default_maximum_number_of_tickets
2409
     */
2410
    public function set_default_max_ticket_on_EEM_Event()
2411
    {
2412
        EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2413
    }
2414
2415
2416
    /**
2417
     * Sets the default consent checkbox text. This needs to be done a bit later than when EE_Registration_Config is
2418
     * constructed because that happens before we can get the privacy policy page's permalink.
2419
     *
2420
     * @throws InvalidArgumentException
2421
     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2422
     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2423
     */
2424
    public function setDefaultCheckboxLabelText()
2425
    {
2426
        if ($this->getConsentCheckboxLabelText() === null
2427
            || $this->getConsentCheckboxLabelText() === '') {
2428
            $opening_a_tag = '';
2429
            $closing_a_tag = '';
2430
            if (function_exists('get_privacy_policy_url')) {
2431
                $privacy_page_url = get_privacy_policy_url();
2432
                if (! empty($privacy_page_url)) {
2433
                    $opening_a_tag = '<a href="' . $privacy_page_url . '" target="_blank">';
2434
                    $closing_a_tag = '</a>';
2435
                }
2436
            }
2437
            $loader = LoaderFactory::getLoader();
2438
            $org_config = $loader->getShared('EE_Organization_Config');
2439
            /**
2440
             * @var $org_config EE_Organization_Config
2441
             */
2442
2443
            $this->setConsentCheckboxLabelText(
2444
                sprintf(
2445
                    esc_html__(
2446
                        'I consent to %1$s storing and using my personal information, according to their %2$sprivacy policy%3$s.',
2447
                        'event_espresso'
2448
                    ),
2449
                    $org_config->name,
2450
                    $opening_a_tag,
2451
                    $closing_a_tag
2452
                )
2453
            );
2454
        }
2455
    }
2456
2457
2458
    /**
2459
     * @return boolean
2460
     */
2461
    public function track_invalid_checkout_access()
2462
    {
2463
        return $this->track_invalid_checkout_access;
2464
    }
2465
2466
2467
    /**
2468
     * @param boolean $track_invalid_checkout_access
2469
     */
2470
    public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2471
    {
2472
        $this->track_invalid_checkout_access = filter_var(
2473
            $track_invalid_checkout_access,
2474
            FILTER_VALIDATE_BOOLEAN
2475
        );
2476
    }
2477
2478
2479
    /**
2480
     * Gets the options to make availalbe for the gateway log lifespan
2481
     * @return array
2482
     */
2483
    public function gatewayLogLifespanOptions()
2484
    {
2485
        return (array) apply_filters(
2486
            'FHEE_EE_Admin_Config__gatewayLogLifespanOptions',
2487
            array(
2488
                '1 second' => esc_html__('Don\'t Log At All', 'event_espresso'),
2489
                '1 day' => esc_html__('1 Day', 'event_espresso'),
2490
                '7 days' => esc_html__('7 Days', 'event_espresso'),
2491
                '14 days' => esc_html__('14 Days', 'event_espresso'),
2492
                '30 days' => esc_html__('30 Days', 'event_espresso')
2493
            )
2494
        );
2495
    }
2496
2497
2498
    /**
2499
     * @return bool
2500
     */
2501
    public function isConsentCheckboxEnabled()
2502
    {
2503
        return $this->consent_checkbox_enabled;
2504
    }
2505
2506
2507
    /**
2508
     * @param bool $consent_checkbox_enabled
2509
     */
2510
    public function setConsentCheckboxEnabled($consent_checkbox_enabled)
2511
    {
2512
        $this->consent_checkbox_enabled = filter_var(
2513
            $consent_checkbox_enabled,
2514
            FILTER_VALIDATE_BOOLEAN
2515
        );
2516
    }
2517
2518
2519
    /**
2520
     * @return string
2521
     */
2522
    public function getConsentCheckboxLabelText()
2523
    {
2524
        return $this->consent_checkbox_label_text;
2525
    }
2526
2527
2528
    /**
2529
     * @param string $consent_checkbox_label_text
2530
     */
2531
    public function setConsentCheckboxLabelText($consent_checkbox_label_text)
2532
    {
2533
        $this->consent_checkbox_label_text = (string) $consent_checkbox_label_text;
2534
    }
2535
}
2536
2537
/**
2538
 * Class for defining what's in the EE_Config relating to admin settings
2539
 */
2540
class EE_Admin_Config extends EE_Config_Base
2541
{
2542
2543
    /**
2544
     * @var boolean $use_personnel_manager
2545
     */
2546
    public $use_personnel_manager;
2547
2548
    /**
2549
     * @var boolean $use_dashboard_widget
2550
     */
2551
    public $use_dashboard_widget;
2552
2553
    /**
2554
     * @var int $events_in_dashboard
2555
     */
2556
    public $events_in_dashboard;
2557
2558
    /**
2559
     * @var boolean $use_event_timezones
2560
     */
2561
    public $use_event_timezones;
2562
2563
    /**
2564
     * @var boolean $use_full_logging
2565
     */
2566
    public $use_full_logging;
2567
2568
    /**
2569
     * @var string $log_file_name
2570
     */
2571
    public $log_file_name;
2572
2573
    /**
2574
     * @var string $debug_file_name
2575
     */
2576
    public $debug_file_name;
2577
2578
    /**
2579
     * @var boolean $use_remote_logging
2580
     */
2581
    public $use_remote_logging;
2582
2583
    /**
2584
     * @var string $remote_logging_url
2585
     */
2586
    public $remote_logging_url;
2587
2588
    /**
2589
     * @var boolean $show_reg_footer
2590
     */
2591
    public $show_reg_footer;
2592
2593
    /**
2594
     * @var string $affiliate_id
2595
     */
2596
    public $affiliate_id;
2597
2598
    /**
2599
     * help tours on or off (global setting)
2600
     *
2601
     * @var boolean
2602
     */
2603
    public $help_tour_activation;
2604
2605
    /**
2606
     * adds extra layer of encoding to session data to prevent serialization errors
2607
     * but is incompatible with some server configuration errors
2608
     * if you get "500 internal server errors" during registration, try turning this on
2609
     * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2610
     *
2611
     * @var boolean $encode_session_data
2612
     */
2613
    private $encode_session_data = false;
2614
2615
2616
    /**
2617
     *    class constructor
2618
     *
2619
     * @access    public
2620
     */
2621
    public function __construct()
2622
    {
2623
        // set default general admin settings
2624
        $this->use_personnel_manager = true;
2625
        $this->use_dashboard_widget = true;
2626
        $this->events_in_dashboard = 30;
2627
        $this->use_event_timezones = false;
2628
        $this->use_full_logging = false;
2629
        $this->use_remote_logging = false;
2630
        $this->remote_logging_url = null;
2631
        $this->show_reg_footer = true;
2632
        $this->affiliate_id = 'default';
2633
        $this->help_tour_activation = true;
2634
        $this->encode_session_data = false;
2635
    }
2636
2637
2638
    /**
2639
     * @param bool $reset
2640
     * @return string
2641
     */
2642 View Code Duplication
    public function log_file_name($reset = false)
2643
    {
2644
        if (empty($this->log_file_name) || $reset) {
2645
            $this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2646
            EE_Config::instance()->update_espresso_config(false, false);
2647
        }
2648
        return $this->log_file_name;
2649
    }
2650
2651
2652
    /**
2653
     * @param bool $reset
2654
     * @return string
2655
     */
2656 View Code Duplication
    public function debug_file_name($reset = false)
2657
    {
2658
        if (empty($this->debug_file_name) || $reset) {
2659
            $this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2660
            EE_Config::instance()->update_espresso_config(false, false);
2661
        }
2662
        return $this->debug_file_name;
2663
    }
2664
2665
2666
    /**
2667
     * @return string
2668
     */
2669
    public function affiliate_id()
2670
    {
2671
        return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2672
    }
2673
2674
2675
    /**
2676
     * @return boolean
2677
     */
2678
    public function encode_session_data()
2679
    {
2680
        return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2681
    }
2682
2683
2684
    /**
2685
     * @param boolean $encode_session_data
2686
     */
2687
    public function set_encode_session_data($encode_session_data)
2688
    {
2689
        $this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2690
    }
2691
}
2692
2693
/**
2694
 * Class for defining what's in the EE_Config relating to template settings
2695
 */
2696
class EE_Template_Config extends EE_Config_Base
2697
{
2698
2699
    /**
2700
     * @var boolean $enable_default_style
2701
     */
2702
    public $enable_default_style;
2703
2704
    /**
2705
     * @var string $custom_style_sheet
2706
     */
2707
    public $custom_style_sheet;
2708
2709
    /**
2710
     * @var boolean $display_address_in_regform
2711
     */
2712
    public $display_address_in_regform;
2713
2714
    /**
2715
     * @var int $display_description_on_multi_reg_page
2716
     */
2717
    public $display_description_on_multi_reg_page;
2718
2719
    /**
2720
     * @var boolean $use_custom_templates
2721
     */
2722
    public $use_custom_templates;
2723
2724
    /**
2725
     * @var string $current_espresso_theme
2726
     */
2727
    public $current_espresso_theme;
2728
2729
    /**
2730
     * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2731
     */
2732
    public $EED_Ticket_Selector;
2733
2734
    /**
2735
     * @var EE_Event_Single_Config $EED_Event_Single
2736
     */
2737
    public $EED_Event_Single;
2738
2739
    /**
2740
     * @var EE_Events_Archive_Config $EED_Events_Archive
2741
     */
2742
    public $EED_Events_Archive;
2743
2744
2745
    /**
2746
     *    class constructor
2747
     *
2748
     * @access    public
2749
     */
2750
    public function __construct()
2751
    {
2752
        // set default template settings
2753
        $this->enable_default_style = true;
2754
        $this->custom_style_sheet = null;
2755
        $this->display_address_in_regform = true;
2756
        $this->display_description_on_multi_reg_page = false;
2757
        $this->use_custom_templates = false;
2758
        $this->current_espresso_theme = 'Espresso_Arabica_2014';
2759
        $this->EED_Event_Single = null;
2760
        $this->EED_Events_Archive = null;
2761
        $this->EED_Ticket_Selector = null;
2762
    }
2763
}
2764
2765
/**
2766
 * Class for defining what's in the EE_Config relating to map settings
2767
 */
2768
class EE_Map_Config extends EE_Config_Base
2769
{
2770
2771
    /**
2772
     * @var boolean $use_google_maps
2773
     */
2774
    public $use_google_maps;
2775
2776
    /**
2777
     * @var string $api_key
2778
     */
2779
    public $google_map_api_key;
2780
2781
    /**
2782
     * @var int $event_details_map_width
2783
     */
2784
    public $event_details_map_width;
2785
2786
    /**
2787
     * @var int $event_details_map_height
2788
     */
2789
    public $event_details_map_height;
2790
2791
    /**
2792
     * @var int $event_details_map_zoom
2793
     */
2794
    public $event_details_map_zoom;
2795
2796
    /**
2797
     * @var boolean $event_details_display_nav
2798
     */
2799
    public $event_details_display_nav;
2800
2801
    /**
2802
     * @var boolean $event_details_nav_size
2803
     */
2804
    public $event_details_nav_size;
2805
2806
    /**
2807
     * @var string $event_details_control_type
2808
     */
2809
    public $event_details_control_type;
2810
2811
    /**
2812
     * @var string $event_details_map_align
2813
     */
2814
    public $event_details_map_align;
2815
2816
    /**
2817
     * @var int $event_list_map_width
2818
     */
2819
    public $event_list_map_width;
2820
2821
    /**
2822
     * @var int $event_list_map_height
2823
     */
2824
    public $event_list_map_height;
2825
2826
    /**
2827
     * @var int $event_list_map_zoom
2828
     */
2829
    public $event_list_map_zoom;
2830
2831
    /**
2832
     * @var boolean $event_list_display_nav
2833
     */
2834
    public $event_list_display_nav;
2835
2836
    /**
2837
     * @var boolean $event_list_nav_size
2838
     */
2839
    public $event_list_nav_size;
2840
2841
    /**
2842
     * @var string $event_list_control_type
2843
     */
2844
    public $event_list_control_type;
2845
2846
    /**
2847
     * @var string $event_list_map_align
2848
     */
2849
    public $event_list_map_align;
2850
2851
2852
    /**
2853
     *    class constructor
2854
     *
2855
     * @access    public
2856
     */
2857
    public function __construct()
2858
    {
2859
        // set default map settings
2860
        $this->use_google_maps = true;
2861
        $this->google_map_api_key = '';
2862
        // for event details pages (reg page)
2863
        $this->event_details_map_width = 585;            // ee_map_width_single
2864
        $this->event_details_map_height = 362;            // ee_map_height_single
2865
        $this->event_details_map_zoom = 14;            // ee_map_zoom_single
2866
        $this->event_details_display_nav = true;            // ee_map_nav_display_single
2867
        $this->event_details_nav_size = false;            // ee_map_nav_size_single
2868
        $this->event_details_control_type = 'default';        // ee_map_type_control_single
2869
        $this->event_details_map_align = 'center';            // ee_map_align_single
2870
        // for event list pages
2871
        $this->event_list_map_width = 300;            // ee_map_width
2872
        $this->event_list_map_height = 185;        // ee_map_height
2873
        $this->event_list_map_zoom = 12;            // ee_map_zoom
2874
        $this->event_list_display_nav = false;        // ee_map_nav_display
2875
        $this->event_list_nav_size = true;            // ee_map_nav_size
2876
        $this->event_list_control_type = 'dropdown';        // ee_map_type_control
2877
        $this->event_list_map_align = 'center';            // ee_map_align
2878
    }
2879
}
2880
2881
/**
2882
 * stores Events_Archive settings
2883
 */
2884
class EE_Events_Archive_Config extends EE_Config_Base
2885
{
2886
2887
    public $display_status_banner;
2888
2889
    public $display_description;
2890
2891
    public $display_ticket_selector;
2892
2893
    public $display_datetimes;
2894
2895
    public $display_venue;
2896
2897
    public $display_expired_events;
2898
2899
    public $use_sortable_display_order;
2900
2901
    public $display_order_tickets;
2902
2903
    public $display_order_datetimes;
2904
2905
    public $display_order_event;
2906
2907
    public $display_order_venue;
2908
2909
2910
    /**
2911
     *    class constructor
2912
     */
2913
    public function __construct()
2914
    {
2915
        $this->display_status_banner = 0;
2916
        $this->display_description = 1;
2917
        $this->display_ticket_selector = 0;
2918
        $this->display_datetimes = 1;
2919
        $this->display_venue = 0;
2920
        $this->display_expired_events = 0;
2921
        $this->use_sortable_display_order = false;
2922
        $this->display_order_tickets = 100;
2923
        $this->display_order_datetimes = 110;
2924
        $this->display_order_event = 120;
2925
        $this->display_order_venue = 130;
2926
    }
2927
}
2928
2929
/**
2930
 * Stores Event_Single_Config settings
2931
 */
2932
class EE_Event_Single_Config extends EE_Config_Base
2933
{
2934
2935
    public $display_status_banner_single;
2936
2937
    public $display_venue;
2938
2939
    public $use_sortable_display_order;
2940
2941
    public $display_order_tickets;
2942
2943
    public $display_order_datetimes;
2944
2945
    public $display_order_event;
2946
2947
    public $display_order_venue;
2948
2949
2950
    /**
2951
     *    class constructor
2952
     */
2953
    public function __construct()
2954
    {
2955
        $this->display_status_banner_single = 0;
2956
        $this->display_venue = 1;
2957
        $this->use_sortable_display_order = false;
2958
        $this->display_order_tickets = 100;
2959
        $this->display_order_datetimes = 110;
2960
        $this->display_order_event = 120;
2961
        $this->display_order_venue = 130;
2962
    }
2963
}
2964
2965
/**
2966
 * Stores Ticket_Selector_Config settings
2967
 */
2968
class EE_Ticket_Selector_Config extends EE_Config_Base
2969
{
2970
2971
    /**
2972
     * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
2973
     */
2974
    const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
2975
2976
    /**
2977
     * constant to indicate that a datetime selector should only be shown for ticket selectors
2978
     * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
2979
     */
2980
    const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
2981
2982
    /**
2983
     * @var boolean $show_ticket_sale_columns
2984
     */
2985
    public $show_ticket_sale_columns;
2986
2987
    /**
2988
     * @var boolean $show_ticket_details
2989
     */
2990
    public $show_ticket_details;
2991
2992
    /**
2993
     * @var boolean $show_expired_tickets
2994
     */
2995
    public $show_expired_tickets;
2996
2997
    /**
2998
     * whether or not to display a dropdown box populated with event datetimes
2999
     * that toggles which tickets are displayed for a ticket selector.
3000
     * uses one of the *_DATETIME_SELECTOR constants defined above
3001
     *
3002
     * @var string $show_datetime_selector
3003
     */
3004
    private $show_datetime_selector = 'no_datetime_selector';
3005
3006
    /**
3007
     * the number of datetimes an event has to have before conditionally displaying a datetime selector
3008
     *
3009
     * @var int $datetime_selector_threshold
3010
     */
3011
    private $datetime_selector_threshold = 3;
3012
3013
3014
    /**
3015
     *    class constructor
3016
     */
3017
    public function __construct()
3018
    {
3019
        $this->show_ticket_sale_columns = true;
3020
        $this->show_ticket_details = true;
3021
        $this->show_expired_tickets = true;
3022
        $this->show_datetime_selector = \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3023
        $this->datetime_selector_threshold = 3;
3024
    }
3025
3026
3027
    /**
3028
     * returns true if a datetime selector should be displayed
3029
     *
3030
     * @param array $datetimes
3031
     * @return bool
3032
     */
3033
    public function showDatetimeSelector(array $datetimes)
3034
    {
3035
        // if the settings are NOT: don't show OR below threshold, THEN active = true
3036
        return ! (
3037
            $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3038
            || (
3039
                $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3040
                && count($datetimes) < $this->getDatetimeSelectorThreshold()
3041
            )
3042
        );
3043
    }
3044
3045
3046
    /**
3047
     * @return string
3048
     */
3049
    public function getShowDatetimeSelector()
3050
    {
3051
        return $this->show_datetime_selector;
3052
    }
3053
3054
3055
    /**
3056
     * @param bool $keys_only
3057
     * @return array
3058
     */
3059
    public function getShowDatetimeSelectorOptions($keys_only = true)
3060
    {
3061
        return $keys_only
3062
            ? array(
3063
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3064
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3065
            )
3066
            : array(
3067
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3068
                    'Do not show date & time filter',
3069
                    'event_espresso'
3070
                ),
3071
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3072
                    'Maybe show date & time filter',
3073
                    'event_espresso'
3074
                ),
3075
            );
3076
    }
3077
3078
3079
    /**
3080
     * @param string $show_datetime_selector
3081
     */
3082
    public function setShowDatetimeSelector($show_datetime_selector)
3083
    {
3084
        $this->show_datetime_selector = in_array(
3085
            $show_datetime_selector,
3086
            $this->getShowDatetimeSelectorOptions(),
3087
            true
3088
        )
3089
            ? $show_datetime_selector
3090
            : \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3091
    }
3092
3093
3094
    /**
3095
     * @return int
3096
     */
3097
    public function getDatetimeSelectorThreshold()
3098
    {
3099
        return $this->datetime_selector_threshold;
3100
    }
3101
3102
3103
    /**
3104
     * @param int $datetime_selector_threshold
3105
     */
3106
    public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3107
    {
3108
        $datetime_selector_threshold = absint($datetime_selector_threshold);
3109
        $this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3110
    }
3111
}
3112
3113
/**
3114
 * Stores any EE Environment values that are referenced through the code.
3115
 *
3116
 * @since       4.4.0
3117
 * @package     Event Espresso
3118
 * @subpackage  config
3119
 */
3120
class EE_Environment_Config extends EE_Config_Base
3121
{
3122
3123
    /**
3124
     * Hold any php environment variables that we want to track.
3125
     *
3126
     * @var stdClass;
3127
     */
3128
    public $php;
3129
3130
3131
    /**
3132
     *    constructor
3133
     */
3134
    public function __construct()
3135
    {
3136
        $this->php = new stdClass();
3137
        $this->_set_php_values();
3138
    }
3139
3140
3141
    /**
3142
     * This sets the php environment variables.
3143
     *
3144
     * @since 4.4.0
3145
     * @return void
3146
     */
3147
    protected function _set_php_values()
3148
    {
3149
        $this->php->max_input_vars = ini_get('max_input_vars');
3150
        $this->php->version = phpversion();
3151
    }
3152
3153
3154
    /**
3155
     * helper method for determining whether input_count is
3156
     * reaching the potential maximum the server can handle
3157
     * according to max_input_vars
3158
     *
3159
     * @param int   $input_count the count of input vars.
3160
     * @return array {
3161
     *                           An array that represents whether available space and if no available space the error
3162
     *                           message.
3163
     * @type bool   $has_space   whether more inputs can be added.
3164
     * @type string $msg         Any message to be displayed.
3165
     *                           }
3166
     */
3167
    public function max_input_vars_limit_check($input_count = 0)
3168
    {
3169
        if (! empty($this->php->max_input_vars)
3170
            && ($input_count >= $this->php->max_input_vars)
3171
            && (PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3 && PHP_RELEASE_VERSION >= 9)
3172
        ) {
3173
            return sprintf(
3174
                __(
3175
                    '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.',
3176
                    'event_espresso'
3177
                ),
3178
                '<br>',
3179
                $input_count,
3180
                $this->php->max_input_vars
3181
            );
3182
        } else {
3183
            return '';
3184
        }
3185
    }
3186
3187
3188
    /**
3189
     * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3190
     *
3191
     * @since 4.4.1
3192
     * @return void
3193
     */
3194
    public function recheck_values()
3195
    {
3196
        $this->_set_php_values();
3197
    }
3198
}
3199
3200
/**
3201
 * Stores any options pertaining to taxes
3202
 *
3203
 * @since       4.9.13
3204
 * @package     Event Espresso
3205
 * @subpackage  config
3206
 */
3207
class EE_Tax_Config extends EE_Config_Base
3208
{
3209
3210
    /*
3211
     * flag to indicate whether or not to display ticket prices with the taxes included
3212
     *
3213
     * @var boolean $prices_displayed_including_taxes
3214
     */
3215
    public $prices_displayed_including_taxes;
3216
3217
3218
    /**
3219
     *    class constructor
3220
     */
3221
    public function __construct()
3222
    {
3223
        $this->prices_displayed_including_taxes = true;
3224
    }
3225
}
3226
3227
/**
3228
 * Holds all global messages configuration options.
3229
 *
3230
 * @package    EventEspresso/core/
3231
 * @subpackage config
3232
 * @author     Darren Ethier
3233
 * @since      4.27.rc
3234
 */
3235
class EE_Messages_Config extends EE_Config_Base
3236
{
3237
3238
    /**
3239
     * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3240
     * A value of 0 represents never deleting.  Default is 0.
3241
     *
3242
     * @var integer
3243
     */
3244
    public $delete_threshold;
3245
3246
3247
    public function __construct()
3248
    {
3249
        $this->delete_threshold = 0;
3250
    }
3251
}
3252
3253
/**
3254
 * stores payment gateway info
3255
 *
3256
 * @deprecated
3257
 */
3258
class EE_Gateway_Config extends EE_Config_Base
3259
{
3260
3261
    /**
3262
     * Array with keys that are payment gateways slugs, and values are arrays
3263
     * with any config info the gateway wants to store
3264
     *
3265
     * @var array
3266
     */
3267
    public $payment_settings;
3268
3269
    /**
3270
     * Where keys are gateway slugs, and values are booleans indicating whether or not
3271
     * the gateway is stored in the uploads directory
3272
     *
3273
     * @var array
3274
     */
3275
    public $active_gateways;
3276
3277
3278
    /**
3279
     *    class constructor
3280
     *
3281
     * @deprecated
3282
     */
3283
    public function __construct()
3284
    {
3285
        $this->payment_settings = array();
3286
        $this->active_gateways = array('Invoice' => false);
3287
    }
3288
}
3289