Completed
Branch FET/11129/facilitate-stripe-an... (fc6ced)
by
unknown
90:22 queued 79:00
created

EE_Currency_Config::__construct()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 31
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 22
nc 8
nop 2
dl 0
loc 31
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
use EventEspresso\core\exceptions\InvalidDataTypeException;
4
use EventEspresso\core\exceptions\InvalidInterfaceException;
5
use EventEspresso\core\interfaces\ResettableInterface;
6
use EventEspresso\core\services\currency\CountryCurrencyDao;
7
use EventEspresso\core\services\shortcodes\LegacyShortcodesManager;
8
9
defined('EVENT_ESPRESSO_VERSION') || exit('No direct script access allowed');
10
11
12
13
/**
14
 * EE_Config
15
 *
16
 * @package     Event Espresso
17
 * @subpackage  core/
18
 * @author      Brent Christensen
19
 */
20
final class EE_Config implements ResettableInterface
21
{
22
23
    const OPTION_NAME        = 'ee_config';
24
25
    const LOG_NAME           = 'ee_config_log';
26
27
    const LOG_LENGTH         = 100;
28
29
    const ADDON_OPTION_NAMES = 'ee_config_option_names';
30
31
32
    /**
33
     *    instance of the EE_Config object
34
     *
35
     * @var    EE_Config $_instance
36
     * @access    private
37
     */
38
    private static $_instance;
39
40
    /**
41
     * @var boolean $_logging_enabled
42
     */
43
    private static $_logging_enabled = false;
44
45
    /**
46
     * @var LegacyShortcodesManager $legacy_shortcodes_manager
47
     */
48
    private $legacy_shortcodes_manager;
49
50
    /**
51
     * An StdClass whose property names are addon slugs,
52
     * and values are their config classes
53
     *
54
     * @var StdClass
55
     */
56
    public $addons;
57
58
    /**
59
     * @var EE_Admin_Config
60
     */
61
    public $admin;
62
63
    /**
64
     * @var EE_Core_Config
65
     */
66
    public $core;
67
68
    /**
69
     * @var EE_Currency_Config
70
     */
71
    public $currency;
72
73
    /**
74
     * @var EE_Organization_Config
75
     */
76
    public $organization;
77
78
    /**
79
     * @var EE_Registration_Config
80
     */
81
    public $registration;
82
83
    /**
84
     * @var EE_Template_Config
85
     */
86
    public $template_settings;
87
88
    /**
89
     * Holds EE environment values.
90
     *
91
     * @var EE_Environment_Config
92
     */
93
    public $environment;
94
95
    /**
96
     * settings pertaining to Google maps
97
     *
98
     * @var EE_Map_Config
99
     */
100
    public $map_settings;
101
102
    /**
103
     * settings pertaining to Taxes
104
     *
105
     * @var EE_Tax_Config
106
     */
107
    public $tax_settings;
108
109
110
    /**
111
     * Settings pertaining to global messages settings.
112
     *
113
     * @var EE_Messages_Config
114
     */
115
    public $messages;
116
117
    /**
118
     * @deprecated
119
     * @var EE_Gateway_Config
120
     */
121
    public $gateway;
122
123
    /**
124
     * @var    array $_addon_option_names
125
     * @access    private
126
     */
127
    private $_addon_option_names = array();
128
129
    /**
130
     * @var    array $_module_route_map
131
     * @access    private
132
     */
133
    private static $_module_route_map = array();
134
135
    /**
136
     * @var    array $_module_forward_map
137
     * @access    private
138
     */
139
    private static $_module_forward_map = array();
140
141
    /**
142
     * @var    array $_module_view_map
143
     * @access    private
144
     */
145
    private static $_module_view_map = array();
146
147
148
149
    /**
150
     * @singleton method used to instantiate class object
151
     * @access    public
152
     * @return EE_Config instance
153
     */
154
    public static function instance()
155
    {
156
        // check if class object is instantiated, and instantiated properly
157
        if (! self::$_instance instanceof EE_Config) {
158
            self::$_instance = new self();
159
        }
160
        return self::$_instance;
161
    }
162
163
164
165
    /**
166
     * Resets the config
167
     *
168
     * @param bool    $hard_reset    if TRUE, sets EE_CONFig back to its original settings in the database. If FALSE
169
     *                               (default) leaves the database alone, and merely resets the EE_Config object to
170
     *                               reflect its state in the database
171
     * @param boolean $reinstantiate if TRUE (default) call instance() and return it. Otherwise, just leave
172
     *                               $_instance as NULL. Useful in case you want to forget about the old instance on
173
     *                               EE_Config, but might not be ready to instantiate EE_Config currently (eg if the
174
     *                               site was put into maintenance mode)
175
     * @return EE_Config
176
     */
177
    public static function reset($hard_reset = false, $reinstantiate = true)
178
    {
179
        if (self::$_instance instanceof EE_Config) {
180
            if ($hard_reset) {
181
                self::$_instance->legacy_shortcodes_manager = null;
182
                self::$_instance->_addon_option_names = array();
183
                self::$_instance->_initialize_config();
184
                self::$_instance->update_espresso_config();
185
            }
186
            self::$_instance->update_addon_option_names();
187
        }
188
        self::$_instance = null;
189
        //we don't need to reset the static properties imo because those should
190
        //only change when a module is added or removed. Currently we don't
191
        //support removing a module during a request when it previously existed
192
        if ($reinstantiate) {
193
            return self::instance();
194
        } else {
195
            return null;
196
        }
197
    }
198
199
200
201
    /**
202
     *    class constructor
203
     *
204
     * @access    private
205
     */
206
    private function __construct()
207
    {
208
        do_action('AHEE__EE_Config__construct__begin', $this);
209
        EE_Config::$_logging_enabled = apply_filters('FHEE__EE_Config___construct__logging_enabled', false);
210
        // setup empty config classes
211
        $this->_initialize_config();
212
        // load existing EE site settings
213
        $this->_load_core_config();
214
        // confirm everything loaded correctly and set filtered defaults if not
215
        $this->_verify_config();
216
        //  register shortcodes and modules
217
        add_action(
218
            'AHEE__EE_System__register_shortcodes_modules_and_widgets',
219
            array($this, 'register_shortcodes_and_modules'),
220
            999
221
        );
222
        //  initialize shortcodes and modules
223
        add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'initialize_shortcodes_and_modules'));
224
        // register widgets
225
        add_action('widgets_init', array($this, 'widgets_init'), 10);
226
        // shutdown
227
        add_action('shutdown', array($this, 'shutdown'), 10);
228
        // construct__end hook
229
        do_action('AHEE__EE_Config__construct__end', $this);
230
        // hardcoded hack
231
        $this->template_settings->current_espresso_theme = 'Espresso_Arabica_2014';
232
    }
233
234
235
236
    /**
237
     * @return boolean
238
     */
239
    public static function logging_enabled()
240
    {
241
        return self::$_logging_enabled;
242
    }
243
244
245
246
    /**
247
     * use to get the current theme if needed from static context
248
     *
249
     * @return string current theme set.
250
     */
251
    public static function get_current_theme()
252
    {
253
        return isset(self::$_instance->template_settings->current_espresso_theme)
254
            ? self::$_instance->template_settings->current_espresso_theme : 'Espresso_Arabica_2014';
255
    }
256
257
258
259
    /**
260
     *        _initialize_config
261
     *
262
     * @access private
263
     * @return void
264
     */
265
    private function _initialize_config()
266
    {
267
        EE_Config::trim_log();
268
        //set defaults
269
        $this->_addon_option_names = get_option(EE_Config::ADDON_OPTION_NAMES, array());
270
        $this->addons = new stdClass();
271
        // set _module_route_map
272
        EE_Config::$_module_route_map = array();
273
        // set _module_forward_map
274
        EE_Config::$_module_forward_map = array();
275
        // set _module_view_map
276
        EE_Config::$_module_view_map = array();
277
    }
278
279
280
281
    /**
282
     *        load core plugin configuration
283
     *
284
     * @access private
285
     * @return void
286
     */
287
    private function _load_core_config()
288
    {
289
        // load_core_config__start hook
290
        do_action('AHEE__EE_Config___load_core_config__start', $this);
291
        $espresso_config = $this->get_espresso_config();
292
        foreach ($espresso_config as $config => $settings) {
293
            // load_core_config__start hook
294
            $settings = apply_filters(
295
                'FHEE__EE_Config___load_core_config__config_settings',
296
                $settings,
297
                $config,
298
                $this
299
            );
300 View Code Duplication
            if (is_object($settings) && property_exists($this, $config)) {
301
                $this->{$config} = apply_filters('FHEE__EE_Config___load_core_config__' . $config, $settings);
302
                //call configs populate method to ensure any defaults are set for empty values.
303
                if (method_exists($settings, 'populate')) {
304
                    $this->{$config}->populate();
305
                }
306
                if (method_exists($settings, 'do_hooks')) {
307
                    $this->{$config}->do_hooks();
308
                }
309
            }
310
        }
311
        if (apply_filters('FHEE__EE_Config___load_core_config__update_espresso_config', false)) {
312
            $this->update_espresso_config();
313
        }
314
        // load_core_config__end hook
315
        do_action('AHEE__EE_Config___load_core_config__end', $this);
316
    }
317
318
319
    /**
320
     * @return void
321
     * @throws ReflectionException
322
     * @throws InvalidArgumentException
323
     * @throws InvalidInterfaceException
324
     * @throws InvalidDataTypeException
325
     * @throws EE_Error
326
     */
327
    protected function _verify_config()
328
    {
329
        $this->core = $this->core instanceof EE_Core_Config
330
            ? $this->core
331
            : new EE_Core_Config();
332
        $this->core = apply_filters('FHEE__EE_Config___initialize_config__core', $this->core);
333
        $this->organization = $this->organization instanceof EE_Organization_Config
334
            ? $this->organization
335
            : new EE_Organization_Config();
336
        $this->organization = apply_filters(
337
            'FHEE__EE_Config___initialize_config__organization',
338
            $this->organization
339
        );
340
        $this->currency = $this->currency instanceof EE_Currency_Config
341
            ? $this->currency
342
            : new EE_Currency_Config($this->organization->CNT_ISO);
343
        $this->currency = apply_filters('FHEE__EE_Config___initialize_config__currency', $this->currency);
344
        $this->registration = $this->registration instanceof EE_Registration_Config
345
            ? $this->registration
346
            : new EE_Registration_Config();
347
        $this->registration = apply_filters(
348
            'FHEE__EE_Config___initialize_config__registration',
349
            $this->registration
350
        );
351
        $this->admin = $this->admin instanceof EE_Admin_Config
352
            ? $this->admin
353
            : new EE_Admin_Config();
354
        $this->admin = apply_filters('FHEE__EE_Config___initialize_config__admin', $this->admin);
355
        $this->template_settings = $this->template_settings instanceof EE_Template_Config
356
            ? $this->template_settings
357
            : new EE_Template_Config();
358
        $this->template_settings = apply_filters(
359
            'FHEE__EE_Config___initialize_config__template_settings',
360
            $this->template_settings
361
        );
362
        $this->map_settings = $this->map_settings instanceof EE_Map_Config
363
            ? $this->map_settings
364
            : new EE_Map_Config();
365
        $this->map_settings = apply_filters('FHEE__EE_Config___initialize_config__map_settings',
366
            $this->map_settings);
367
        $this->environment = $this->environment instanceof EE_Environment_Config
368
            ? $this->environment
369
            : new EE_Environment_Config();
370
        $this->environment = apply_filters('FHEE__EE_Config___initialize_config__environment',
371
            $this->environment);
372
        $this->tax_settings = $this->tax_settings instanceof EE_Tax_Config
373
            ? $this->tax_settings
374
            : new EE_Tax_Config();
375
        $this->tax_settings = apply_filters('FHEE__EE_Config___initialize_config__tax_settings',
376
            $this->tax_settings);
377
        $this->messages = apply_filters('FHEE__EE_Config__initialize_config__messages', $this->messages);
378
        $this->messages = $this->messages instanceof EE_Messages_Config
379
            ? $this->messages
380
            : new EE_Messages_Config();
381
        $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...
382
            ? $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...
383
            : 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...
384
        $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...
385
        $this->legacy_shortcodes_manager = null;
386
    }
387
388
389
    /**
390
     *    get_espresso_config
391
     *
392
     * @access    public
393
     * @return    array of espresso config stuff
394
     */
395
    public function get_espresso_config()
396
    {
397
        // grab espresso configuration
398
        return apply_filters(
399
            'FHEE__EE_Config__get_espresso_config__CFG',
400
            get_option(EE_Config::OPTION_NAME, array())
401
        );
402
    }
403
404
405
406
    /**
407
     *    double_check_config_comparison
408
     *
409
     * @access    public
410
     * @param string $option
411
     * @param        $old_value
412
     * @param        $value
413
     */
414
    public function double_check_config_comparison($option = '', $old_value, $value)
415
    {
416
        // make sure we're checking the ee config
417
        if ($option === EE_Config::OPTION_NAME) {
418
            // run a loose comparison of the old value against the new value for type and properties,
419
            // but NOT exact instance like WP update_option does (ie: NOT type safe comparison)
420
            if ($value != $old_value) {
421
                // if they are NOT the same, then remove the hook,
422
                // which means the subsequent update results will be based solely on the update query results
423
                // the reason we do this is because, as stated above,
424
                // WP update_option performs an exact instance comparison (===) on any update values passed to it
425
                // this happens PRIOR to serialization and any subsequent update.
426
                // If values are found to match their previous old value,
427
                // then WP bails before performing any update.
428
                // Since we are passing the EE_Config object, it is comparing the EXACT instance of the saved version
429
                // it just pulled from the db, with the one being passed to it (which will not match).
430
                // HOWEVER, once the object is serialized and passed off to MySQL to update,
431
                // MySQL MAY ALSO NOT perform the update because
432
                // the string it sees in the db looks the same as the new one it has been passed!!!
433
                // This results in the query returning an "affected rows" value of ZERO,
434
                // which gets returned immediately by WP update_option and looks like an error.
435
                remove_action('update_option', array($this, 'check_config_updated'));
436
            }
437
        }
438
    }
439
440
441
442
    /**
443
     *    update_espresso_config
444
     *
445
     * @access   public
446
     */
447
    protected function _reset_espresso_addon_config()
448
    {
449
        $this->_addon_option_names = array();
450
        foreach ($this->addons as $addon_name => $addon_config_obj) {
451
            $addon_config_obj = maybe_unserialize($addon_config_obj);
452
            $config_class = get_class($addon_config_obj);
453
            if ($addon_config_obj instanceof $config_class && ! $addon_config_obj instanceof __PHP_Incomplete_Class) {
454
                $this->update_config('addons', $addon_name, $addon_config_obj, false);
455
            }
456
            $this->addons->{$addon_name} = null;
457
        }
458
    }
459
460
461
462
    /**
463
     *    update_espresso_config
464
     *
465
     * @access   public
466
     * @param   bool $add_success
467
     * @param   bool $add_error
468
     * @return   bool
469
     */
470
    public function update_espresso_config($add_success = false, $add_error = true)
471
    {
472
        // don't allow config updates during WP heartbeats
473
        if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
474
            return false;
475
        }
476
        // commented out the following re: https://events.codebasehq.com/projects/event-espresso/tickets/8197
477
        //$clone = clone( self::$_instance );
478
        //self::$_instance = NULL;
479
        do_action('AHEE__EE_Config__update_espresso_config__begin', $this);
480
        $this->_reset_espresso_addon_config();
481
        // hook into update_option because that happens AFTER the ( $value === $old_value ) conditional
482
        // but BEFORE the actual update occurs
483
        add_action('update_option', array($this, 'double_check_config_comparison'), 1, 3);
484
        // don't want to persist legacy_shortcodes_manager, but don't want to lose it either
485
        $legacy_shortcodes_manager = $this->legacy_shortcodes_manager;
486
        $this->legacy_shortcodes_manager = null;
487
        // now update "ee_config"
488
        $saved = update_option(EE_Config::OPTION_NAME, $this);
489
        $this->legacy_shortcodes_manager = $legacy_shortcodes_manager;
490
        EE_Config::log(EE_Config::OPTION_NAME);
491
        // if not saved... check if the hook we just added still exists;
492
        // if it does, it means one of two things:
493
        // 		that update_option bailed at the ( $value === $old_value ) conditional,
494
        //		 or...
495
        // 		the db update query returned 0 rows affected
496
        // 		(probably because the data  value was the same from it's perspective)
497
        // so the existence of the hook means that a negative result from update_option is NOT an error,
498
        // but just means no update occurred, so don't display an error to the user.
499
        // BUT... if update_option returns FALSE, AND the hook is missing,
500
        // then it means that something truly went wrong
501
        $saved = ! $saved ? has_action('update_option', array($this, 'double_check_config_comparison')) : $saved;
502
        // remove our action since we don't want it in the system anymore
503
        remove_action('update_option', array($this, 'double_check_config_comparison'), 1);
504
        do_action('AHEE__EE_Config__update_espresso_config__end', $this, $saved);
505
        //self::$_instance = $clone;
506
        //unset( $clone );
507
        // if config remains the same or was updated successfully
508
        if ($saved) {
509
            if ($add_success) {
510
                EE_Error::add_success(
511
                    __('The Event Espresso Configuration Settings have been successfully updated.', 'event_espresso'),
512
                    __FILE__,
513
                    __FUNCTION__,
514
                    __LINE__
515
                );
516
            }
517
            return true;
518
        } else {
519
            if ($add_error) {
520
                EE_Error::add_error(
521
                    __('The Event Espresso Configuration Settings were not updated.', 'event_espresso'),
522
                    __FILE__,
523
                    __FUNCTION__,
524
                    __LINE__
525
                );
526
            }
527
            return false;
528
        }
529
    }
530
531
532
533
    /**
534
     *    _verify_config_params
535
     *
536
     * @access    private
537
     * @param    string         $section
538
     * @param    string         $name
539
     * @param    string         $config_class
540
     * @param    EE_Config_Base $config_obj
541
     * @param    array          $tests_to_run
542
     * @param    bool           $display_errors
543
     * @return    bool    TRUE on success, FALSE on fail
544
     */
545
    private function _verify_config_params(
546
        $section = '',
547
        $name = '',
548
        $config_class = '',
549
        $config_obj = null,
550
        $tests_to_run = array(1, 2, 3, 4, 5, 6, 7, 8),
551
        $display_errors = true
552
    ) {
553
        try {
554
            foreach ($tests_to_run as $test) {
555
                switch ($test) {
556
                    // TEST #1 : check that section was set
557 View Code Duplication
                    case 1 :
558
                        if (empty($section)) {
559
                            if ($display_errors) {
560
                                throw new EE_Error(
561
                                    sprintf(
562
                                        __(
563
                                            'No configuration section has been provided while attempting to save "%s".',
564
                                            'event_espresso'
565
                                        ),
566
                                        $config_class
567
                                    )
568
                                );
569
                            }
570
                            return false;
571
                        }
572
                        break;
573
                    // TEST #2 : check that settings section exists
574 View Code Duplication
                    case 2 :
575
                        if (! isset($this->{$section})) {
576
                            if ($display_errors) {
577
                                throw new EE_Error(
578
                                    sprintf(
579
                                        __('The "%s" configuration section does not exist.', 'event_espresso'),
580
                                        $section
581
                                    )
582
                                );
583
                            }
584
                            return false;
585
                        }
586
                        break;
587
                    // TEST #3 : check that section is the proper format
588
                    case 3 :
589
                        if (
590
                        ! ($this->{$section} instanceof EE_Config_Base || $this->{$section} instanceof stdClass)
591
                        ) {
592
                            if ($display_errors) {
593
                                throw new EE_Error(
594
                                    sprintf(
595
                                        __(
596
                                            'The "%s" configuration settings have not been formatted correctly.',
597
                                            'event_espresso'
598
                                        ),
599
                                        $section
600
                                    )
601
                                );
602
                            }
603
                            return false;
604
                        }
605
                        break;
606
                    // TEST #4 : check that config section name has been set
607 View Code Duplication
                    case 4 :
608
                        if (empty($name)) {
609
                            if ($display_errors) {
610
                                throw new EE_Error(
611
                                    __(
612
                                        'No name has been provided for the specific configuration section.',
613
                                        'event_espresso'
614
                                    )
615
                                );
616
                            }
617
                            return false;
618
                        }
619
                        break;
620
                    // TEST #5 : check that a config class name has been set
621 View Code Duplication
                    case 5 :
622
                        if (empty($config_class)) {
623
                            if ($display_errors) {
624
                                throw new EE_Error(
625
                                    __(
626
                                        'No class name has been provided for the specific configuration section.',
627
                                        'event_espresso'
628
                                    )
629
                                );
630
                            }
631
                            return false;
632
                        }
633
                        break;
634
                    // TEST #6 : verify config class is accessible
635 View Code Duplication
                    case 6 :
636
                        if (! class_exists($config_class)) {
637
                            if ($display_errors) {
638
                                throw new EE_Error(
639
                                    sprintf(
640
                                        __(
641
                                            'The "%s" class does not exist. Please ensure that an autoloader has been set for it.',
642
                                            'event_espresso'
643
                                        ),
644
                                        $config_class
645
                                    )
646
                                );
647
                            }
648
                            return false;
649
                        }
650
                        break;
651
                    // TEST #7 : check that config has even been set
652
                    case 7 :
653
                        if (! isset($this->{$section}->{$name})) {
654
                            if ($display_errors) {
655
                                throw new EE_Error(
656
                                    sprintf(
657
                                        __('No configuration has been set for "%1$s->%2$s".', 'event_espresso'),
658
                                        $section,
659
                                        $name
660
                                    )
661
                                );
662
                            }
663
                            return false;
664
                        } else {
665
                            // and make sure it's not serialized
666
                            $this->{$section}->{$name} = maybe_unserialize($this->{$section}->{$name});
667
                        }
668
                        break;
669
                    // TEST #8 : check that config is the requested type
670
                    case 8 :
671
                        if (! $this->{$section}->{$name} instanceof $config_class) {
672
                            if ($display_errors) {
673
                                throw new EE_Error(
674
                                    sprintf(
675
                                        __(
676
                                            'The configuration for "%1$s->%2$s" is not of the "%3$s" class.',
677
                                            'event_espresso'
678
                                        ),
679
                                        $section,
680
                                        $name,
681
                                        $config_class
682
                                    )
683
                                );
684
                            }
685
                            return false;
686
                        }
687
                        break;
688
                    // TEST #9 : verify config object
689 View Code Duplication
                    case 9 :
690
                        if (! $config_obj instanceof EE_Config_Base) {
691
                            if ($display_errors) {
692
                                throw new EE_Error(
693
                                    sprintf(
694
                                        __('The "%s" class is not an instance of EE_Config_Base.', 'event_espresso'),
695
                                        print_r($config_obj, true)
696
                                    )
697
                                );
698
                            }
699
                            return false;
700
                        }
701
                        break;
702
                }
703
            }
704
        } catch (EE_Error $e) {
705
            $e->get_error();
706
        }
707
        // you have successfully run the gauntlet
708
        return true;
709
    }
710
711
712
713
    /**
714
     *    _generate_config_option_name
715
     *
716
     * @access        protected
717
     * @param        string $section
718
     * @param        string $name
719
     * @return        string
720
     */
721
    private function _generate_config_option_name($section = '', $name = '')
722
    {
723
        return 'ee_config-' . strtolower($section . '-' . str_replace(array('EE_', 'EED_'), '', $name));
724
    }
725
726
727
728
    /**
729
     *    _set_config_class
730
     * ensures that a config class is set, either from a passed config class or one generated from the config name
731
     *
732
     * @access    private
733
     * @param    string $config_class
734
     * @param    string $name
735
     * @return    string
736
     */
737
    private function _set_config_class($config_class = '', $name = '')
738
    {
739
        return ! empty($config_class)
740
            ? $config_class
741
            : str_replace(' ', '_', ucwords(str_replace('_', ' ', $name))) . '_Config';
742
    }
743
744
745
746
    /**
747
     *    set_config
748
     *
749
     * @access    protected
750
     * @param    string         $section
751
     * @param    string         $name
752
     * @param    string         $config_class
753
     * @param    EE_Config_Base $config_obj
754
     * @return    EE_Config_Base
755
     */
756
    public function set_config($section = '', $name = '', $config_class = '', EE_Config_Base $config_obj = null)
757
    {
758
        // ensure config class is set to something
759
        $config_class = $this->_set_config_class($config_class, $name);
760
        // run tests 1-4, 6, and 7 to verify all config params are set and valid
761 View Code Duplication
        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
762
            return null;
763
        }
764
        $config_option_name = $this->_generate_config_option_name($section, $name);
765
        // if the config option name hasn't been added yet to the list of option names we're tracking, then do so now
766
        if (! isset($this->_addon_option_names[$config_option_name])) {
767
            $this->_addon_option_names[$config_option_name] = $config_class;
768
            $this->update_addon_option_names();
769
        }
770
        // verify the incoming config object but suppress errors
771
        if (! $this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
772
            $config_obj = new $config_class();
773
        }
774
        if (get_option($config_option_name)) {
775
            EE_Config::log($config_option_name);
776
            update_option($config_option_name, $config_obj);
777
            $this->{$section}->{$name} = $config_obj;
778
            return $this->{$section}->{$name};
779
        } else {
780
            // create a wp-option for this config
781
            if (add_option($config_option_name, $config_obj, '', 'no')) {
782
                $this->{$section}->{$name} = maybe_unserialize($config_obj);
783
                return $this->{$section}->{$name};
784
            } else {
785
                EE_Error::add_error(
786
                    sprintf(__('The "%s" could not be saved to the database.', 'event_espresso'), $config_class),
787
                    __FILE__,
788
                    __FUNCTION__,
789
                    __LINE__
790
                );
791
                return null;
792
            }
793
        }
794
    }
795
796
797
798
    /**
799
     *    update_config
800
     * Important: the config object must ALREADY be set, otherwise this will produce an error.
801
     *
802
     * @access    public
803
     * @param    string                $section
804
     * @param    string                $name
805
     * @param    EE_Config_Base|string $config_obj
806
     * @param    bool                  $throw_errors
807
     * @return    bool
808
     */
809
    public function update_config($section = '', $name = '', $config_obj = '', $throw_errors = true)
810
    {
811
        // don't allow config updates during WP heartbeats
812
        if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
813
            return false;
814
        }
815
        $config_obj = maybe_unserialize($config_obj);
816
        // get class name of the incoming object
817
        $config_class = get_class($config_obj);
818
        // run tests 1-5 and 9 to verify config
819 View Code Duplication
        if (! $this->_verify_config_params(
820
            $section,
821
            $name,
822
            $config_class,
823
            $config_obj,
824
            array(1, 2, 3, 4, 7, 9)
825
        )
826
        ) {
827
            return false;
828
        }
829
        $config_option_name = $this->_generate_config_option_name($section, $name);
830
        // check if config object has been added to db by seeing if config option name is in $this->_addon_option_names array
831
        if (! isset($this->_addon_option_names[$config_option_name])) {
832
            // save new config to db
833
            if ($this->set_config($section, $name, $config_class, $config_obj)) {
834
                return true;
835
            }
836
        } else {
837
            // first check if the record already exists
838
            $existing_config = get_option($config_option_name);
839
            $config_obj = serialize($config_obj);
840
            // just return if db record is already up to date (NOT type safe comparison)
841
            if ($existing_config == $config_obj) {
842
                $this->{$section}->{$name} = $config_obj;
843
                return true;
844
            } else if (update_option($config_option_name, $config_obj)) {
845
                EE_Config::log($config_option_name);
846
                // update wp-option for this config class
847
                $this->{$section}->{$name} = $config_obj;
848
                return true;
849
            } elseif ($throw_errors) {
850
                EE_Error::add_error(
851
                    sprintf(
852
                        __(
853
                            'The "%1$s" object stored at"%2$s" was not successfully updated in the database.',
854
                            'event_espresso'
855
                        ),
856
                        $config_class,
857
                        'EE_Config->' . $section . '->' . $name
858
                    ),
859
                    __FILE__,
860
                    __FUNCTION__,
861
                    __LINE__
862
                );
863
            }
864
        }
865
        return false;
866
    }
867
868
869
870
    /**
871
     *    get_config
872
     *
873
     * @access    public
874
     * @param    string $section
875
     * @param    string $name
876
     * @param    string $config_class
877
     * @return    mixed EE_Config_Base | NULL
878
     */
879
    public function get_config($section = '', $name = '', $config_class = '')
880
    {
881
        // ensure config class is set to something
882
        $config_class = $this->_set_config_class($config_class, $name);
883
        // run tests 1-4, 6 and 7 to verify that all params have been set
884 View Code Duplication
        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
885
            return null;
886
        }
887
        // now test if the requested config object exists, but suppress errors
888
        if ($this->_verify_config_params($section, $name, $config_class, null, array(7, 8), false)) {
889
            // config already exists, so pass it back
890
            return $this->{$section}->{$name};
891
        }
892
        // load config option from db if it exists
893
        $config_obj = $this->get_config_option($this->_generate_config_option_name($section, $name));
894
        // verify the newly retrieved config object, but suppress errors
895
        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
896
            // config is good, so set it and pass it back
897
            $this->{$section}->{$name} = $config_obj;
898
            return $this->{$section}->{$name};
899
        }
900
        // oops! $config_obj is not already set and does not exist in the db, so create a new one
901
        $config_obj = $this->set_config($section, $name, $config_class);
902
        // verify the newly created config object
903
        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9))) {
904
            return $this->{$section}->{$name};
905
        } else {
906
            EE_Error::add_error(
907
                sprintf(__('The "%s" could not be retrieved from the database.', 'event_espresso'), $config_class),
908
                __FILE__,
909
                __FUNCTION__,
910
                __LINE__
911
            );
912
        }
913
        return null;
914
    }
915
916
917
918
    /**
919
     *    get_config_option
920
     *
921
     * @access    public
922
     * @param    string $config_option_name
923
     * @return    mixed EE_Config_Base | FALSE
924
     */
925
    public function get_config_option($config_option_name = '')
926
    {
927
        // retrieve the wp-option for this config class.
928
        $config_option = maybe_unserialize(get_option($config_option_name, array()));
929
        if (empty($config_option)) {
930
            EE_Config::log($config_option_name . '-NOT-FOUND');
931
        }
932
        return $config_option;
933
    }
934
935
936
937
    /**
938
     * log
939
     *
940
     * @param string $config_option_name
941
     */
942
    public static function log($config_option_name = '')
943
    {
944
        if (EE_Config::logging_enabled() && ! empty($config_option_name)) {
945
            $config_log = get_option(EE_Config::LOG_NAME, array());
946
            //copy incoming $_REQUEST and sanitize it so we can save it
947
            $_request = $_REQUEST;
948
            array_walk_recursive($_request, 'sanitize_text_field');
949
            $config_log[(string)microtime(true)] = array(
950
                'config_name' => $config_option_name,
951
                'request'     => $_request,
952
            );
953
            update_option(EE_Config::LOG_NAME, $config_log);
954
        }
955
    }
956
957
958
959
    /**
960
     * trim_log
961
     * reduces the size of the config log to the length specified by EE_Config::LOG_LENGTH
962
     */
963
    public static function trim_log()
964
    {
965
        if (! EE_Config::logging_enabled()) {
966
            return;
967
        }
968
        $config_log = maybe_unserialize(get_option(EE_Config::LOG_NAME, array()));
969
        $log_length = count($config_log);
970
        if ($log_length > EE_Config::LOG_LENGTH) {
971
            ksort($config_log);
972
            $config_log = array_slice($config_log, $log_length - EE_Config::LOG_LENGTH, null, true);
973
            update_option(EE_Config::LOG_NAME, $config_log);
974
        }
975
    }
976
977
978
979
    /**
980
     *    get_page_for_posts
981
     *    if the wp-option "show_on_front" is set to "page", then this is the post_name for the post set in the
982
     *    wp-option "page_for_posts", or "posts" if no page is selected
983
     *
984
     * @access    public
985
     * @return    string
986
     */
987
    public static function get_page_for_posts()
988
    {
989
        $page_for_posts = get_option('page_for_posts');
990
        if (! $page_for_posts) {
991
            return 'posts';
992
        }
993
        /** @type WPDB $wpdb */
994
        global $wpdb;
995
        $SQL = "SELECT post_name from $wpdb->posts WHERE post_type='posts' OR post_type='page' AND post_status='publish' AND ID=%d";
996
        return $wpdb->get_var($wpdb->prepare($SQL, $page_for_posts));
997
    }
998
999
1000
1001
    /**
1002
     *    register_shortcodes_and_modules.
1003
     *    At this point, it's too early to tell if we're maintenance mode or not.
1004
     *    In fact, this is where we give modules a chance to let core know they exist
1005
     *    so they can help trigger maintenance mode if it's needed
1006
     *
1007
     * @access    public
1008
     * @return    void
1009
     */
1010
    public function register_shortcodes_and_modules()
1011
    {
1012
        // allow modules to set hooks for the rest of the system
1013
        EE_Registry::instance()->modules = $this->_register_modules();
1014
    }
1015
1016
1017
1018
    /**
1019
     *    initialize_shortcodes_and_modules
1020
     *    meaning they can start adding their hooks to get stuff done
1021
     *
1022
     * @access    public
1023
     * @return    void
1024
     */
1025
    public function initialize_shortcodes_and_modules()
1026
    {
1027
        // allow modules to set hooks for the rest of the system
1028
        $this->_initialize_modules();
1029
    }
1030
1031
1032
1033
    /**
1034
     *    widgets_init
1035
     *
1036
     * @access private
1037
     * @return void
1038
     */
1039
    public function widgets_init()
1040
    {
1041
        //only init widgets on admin pages when not in complete maintenance, and
1042
        //on frontend when not in any maintenance mode
1043
        if (
1044
            ! EE_Maintenance_Mode::instance()->level()
1045
            || (
1046
                is_admin()
1047
                && EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance
1048
            )
1049
        ) {
1050
            // grab list of installed widgets
1051
            $widgets_to_register = glob(EE_WIDGETS . '*', GLOB_ONLYDIR);
1052
            // filter list of modules to register
1053
            $widgets_to_register = apply_filters(
1054
                'FHEE__EE_Config__register_widgets__widgets_to_register',
1055
                $widgets_to_register
1056
            );
1057
            if (! empty($widgets_to_register)) {
1058
                // cycle thru widget folders
1059
                foreach ($widgets_to_register as $widget_path) {
1060
                    // add to list of installed widget modules
1061
                    EE_Config::register_ee_widget($widget_path);
1062
                }
1063
            }
1064
            // filter list of installed modules
1065
            EE_Registry::instance()->widgets = apply_filters(
1066
                'FHEE__EE_Config__register_widgets__installed_widgets',
1067
                EE_Registry::instance()->widgets
1068
            );
1069
        }
1070
    }
1071
1072
1073
1074
    /**
1075
     *    register_ee_widget - makes core aware of this widget
1076
     *
1077
     * @access    public
1078
     * @param    string $widget_path - full path up to and including widget folder
1079
     * @return    void
1080
     */
1081
    public static function register_ee_widget($widget_path = null)
1082
    {
1083
        do_action('AHEE__EE_Config__register_widget__begin', $widget_path);
1084
        $widget_ext = '.widget.php';
1085
        // make all separators match
1086
        $widget_path = rtrim(str_replace('/\\', DS, $widget_path), DS);
1087
        // does the file path INCLUDE the actual file name as part of the path ?
1088
        if (strpos($widget_path, $widget_ext) !== false) {
1089
            // grab and shortcode file name from directory name and break apart at dots
1090
            $file_name = explode('.', basename($widget_path));
1091
            // take first segment from file name pieces and remove class prefix if it exists
1092
            $widget = strpos($file_name[0], 'EEW_') === 0 ? substr($file_name[0], 4) : $file_name[0];
1093
            // sanitize shortcode directory name
1094
            $widget = sanitize_key($widget);
1095
            // now we need to rebuild the shortcode path
1096
            $widget_path = explode(DS, $widget_path);
1097
            // remove last segment
1098
            array_pop($widget_path);
1099
            // glue it back together
1100
            $widget_path = implode(DS, $widget_path);
1101
        } else {
1102
            // grab and sanitize widget directory name
1103
            $widget = sanitize_key(basename($widget_path));
1104
        }
1105
        // create classname from widget directory name
1106
        $widget = str_replace(' ', '_', ucwords(str_replace('_', ' ', $widget)));
1107
        // add class prefix
1108
        $widget_class = 'EEW_' . $widget;
1109
        // does the widget exist ?
1110 View Code Duplication
        if (! is_readable($widget_path . DS . $widget_class . $widget_ext)) {
1111
            $msg = sprintf(
1112
                __(
1113
                    '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',
1114
                    'event_espresso'
1115
                ),
1116
                $widget_class,
1117
                $widget_path . DS . $widget_class . $widget_ext
1118
            );
1119
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1120
            return;
1121
        }
1122
        // load the widget class file
1123
        require_once($widget_path . DS . $widget_class . $widget_ext);
1124
        // verify that class exists
1125
        if (! class_exists($widget_class)) {
1126
            $msg = sprintf(__('The requested %s widget class does not exist.', 'event_espresso'), $widget_class);
1127
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1128
            return;
1129
        }
1130
        register_widget($widget_class);
1131
        // add to array of registered widgets
1132
        EE_Registry::instance()->widgets->{$widget_class} = $widget_path . DS . $widget_class . $widget_ext;
1133
    }
1134
1135
1136
1137
    /**
1138
     *        _register_modules
1139
     *
1140
     * @access private
1141
     * @return array
1142
     */
1143
    private function _register_modules()
1144
    {
1145
        // grab list of installed modules
1146
        $modules_to_register = glob(EE_MODULES . '*', GLOB_ONLYDIR);
1147
        // filter list of modules to register
1148
        $modules_to_register = apply_filters(
1149
            'FHEE__EE_Config__register_modules__modules_to_register',
1150
            $modules_to_register
1151
        );
1152
        if (! empty($modules_to_register)) {
1153
            // loop through folders
1154
            foreach ($modules_to_register as $module_path) {
1155
                /**TEMPORARILY EXCLUDE gateways from modules for time being**/
1156
                if (
1157
                    $module_path !== EE_MODULES . 'zzz-copy-this-module-template'
1158
                    && $module_path !== EE_MODULES . 'gateways'
1159
                ) {
1160
                    // add to list of installed modules
1161
                    EE_Config::register_module($module_path);
1162
                }
1163
            }
1164
        }
1165
        // filter list of installed modules
1166
        return apply_filters(
1167
            'FHEE__EE_Config___register_modules__installed_modules',
1168
            EE_Registry::instance()->modules
1169
        );
1170
    }
1171
1172
1173
1174
    /**
1175
     *    register_module - makes core aware of this module
1176
     *
1177
     * @access    public
1178
     * @param    string $module_path - full path up to and including module folder
1179
     * @return    bool
1180
     */
1181
    public static function register_module($module_path = null)
1182
    {
1183
        do_action('AHEE__EE_Config__register_module__begin', $module_path);
1184
        $module_ext = '.module.php';
1185
        // make all separators match
1186
        $module_path = str_replace(array('\\', '/'), DS, $module_path);
1187
        // does the file path INCLUDE the actual file name as part of the path ?
1188
        if (strpos($module_path, $module_ext) !== false) {
1189
            // grab and shortcode file name from directory name and break apart at dots
1190
            $module_file = explode('.', basename($module_path));
1191
            // now we need to rebuild the shortcode path
1192
            $module_path = explode(DS, $module_path);
1193
            // remove last segment
1194
            array_pop($module_path);
1195
            // glue it back together
1196
            $module_path = implode(DS, $module_path) . DS;
1197
            // take first segment from file name pieces and sanitize it
1198
            $module = preg_replace('/[^a-zA-Z0-9_\-]/', '', $module_file[0]);
1199
            // ensure class prefix is added
1200
            $module_class = strpos($module, 'EED_') !== 0 ? 'EED_' . $module : $module;
1201
        } else {
1202
            // we need to generate the filename based off of the folder name
1203
            // grab and sanitize module name
1204
            $module = strtolower(basename($module_path));
1205
            $module = preg_replace('/[^a-z0-9_\-]/', '', $module);
1206
            // like trailingslashit()
1207
            $module_path = rtrim($module_path, DS) . DS;
1208
            // create classname from module directory name
1209
            $module = str_replace(' ', '_', ucwords(str_replace('_', ' ', $module)));
1210
            // add class prefix
1211
            $module_class = 'EED_' . $module;
1212
        }
1213
        // does the module exist ?
1214
        if (! is_readable($module_path . DS . $module_class . $module_ext)) {
1215
            $msg = sprintf(
1216
                __(
1217
                    'The requested %s module file could not be found or is not readable due to file permissions.',
1218
                    'event_espresso'
1219
                ),
1220
                $module
1221
            );
1222
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1223
            return false;
1224
        }
1225
        // load the module class file
1226
        require_once($module_path . $module_class . $module_ext);
1227
        // verify that class exists
1228
        if (! class_exists($module_class)) {
1229
            $msg = sprintf(__('The requested %s module class does not exist.', 'event_espresso'), $module_class);
1230
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1231
            return false;
1232
        }
1233
        // add to array of registered modules
1234
        EE_Registry::instance()->modules->{$module_class} = $module_path . $module_class . $module_ext;
1235
        do_action(
1236
            'AHEE__EE_Config__register_module__complete',
1237
            $module_class,
1238
            EE_Registry::instance()->modules->{$module_class}
1239
        );
1240
        return true;
1241
    }
1242
1243
1244
1245
    /**
1246
     *    _initialize_modules
1247
     *    allow modules to set hooks for the rest of the system
1248
     *
1249
     * @access private
1250
     * @return void
1251
     */
1252
    private function _initialize_modules()
1253
    {
1254
        // cycle thru shortcode folders
1255
        foreach (EE_Registry::instance()->modules as $module_class => $module_path) {
1256
            // fire the shortcode class's set_hooks methods in case it needs to hook into other parts of the system
1257
            // which set hooks ?
1258
            if (is_admin()) {
1259
                // fire immediately
1260
                call_user_func(array($module_class, 'set_hooks_admin'));
1261
            } else {
1262
                // delay until other systems are online
1263
                add_action(
1264
                    'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons',
1265
                    array($module_class, 'set_hooks')
1266
                );
1267
            }
1268
        }
1269
    }
1270
1271
1272
1273
    /**
1274
     *    register_route - adds module method routes to route_map
1275
     *
1276
     * @access    public
1277
     * @param    string $route       - "pretty" public alias for module method
1278
     * @param    string $module      - module name (classname without EED_ prefix)
1279
     * @param    string $method_name - the actual module method to be routed to
1280
     * @param    string $key         - url param key indicating a route is being called
1281
     * @return    bool
1282
     */
1283
    public static function register_route($route = null, $module = null, $method_name = null, $key = 'ee')
1284
    {
1285
        do_action('AHEE__EE_Config__register_route__begin', $route, $module, $method_name);
1286
        $module = str_replace('EED_', '', $module);
1287
        $module_class = 'EED_' . $module;
1288
        if (! isset(EE_Registry::instance()->modules->{$module_class})) {
1289
            $msg = sprintf(__('The module %s has not been registered.', 'event_espresso'), $module);
1290
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1291
            return false;
1292
        }
1293 View Code Duplication
        if (empty($route)) {
1294
            $msg = sprintf(__('No route has been supplied.', 'event_espresso'), $route);
1295
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1296
            return false;
1297
        }
1298 View Code Duplication
        if (! method_exists('EED_' . $module, $method_name)) {
1299
            $msg = sprintf(
1300
                __('A valid class method for the %s route has not been supplied.', 'event_espresso'),
1301
                $route
1302
            );
1303
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1304
            return false;
1305
        }
1306
        EE_Config::$_module_route_map[$key][$route] = array('EED_' . $module, $method_name);
1307
        return true;
1308
    }
1309
1310
1311
1312
    /**
1313
     *    get_route - get module method route
1314
     *
1315
     * @access    public
1316
     * @param    string $route - "pretty" public alias for module method
1317
     * @param    string $key   - url param key indicating a route is being called
1318
     * @return    string
1319
     */
1320
    public static function get_route($route = null, $key = 'ee')
1321
    {
1322
        do_action('AHEE__EE_Config__get_route__begin', $route);
1323
        $route = (string)apply_filters('FHEE__EE_Config__get_route', $route);
1324
        if (isset(EE_Config::$_module_route_map[$key][$route])) {
1325
            return EE_Config::$_module_route_map[$key][$route];
1326
        }
1327
        return null;
1328
    }
1329
1330
1331
1332
    /**
1333
     *    get_routes - get ALL module method routes
1334
     *
1335
     * @access    public
1336
     * @return    array
1337
     */
1338
    public static function get_routes()
1339
    {
1340
        return EE_Config::$_module_route_map;
1341
    }
1342
1343
1344
1345
    /**
1346
     *    register_forward - allows modules to forward request to another module for further processing
1347
     *
1348
     * @access    public
1349
     * @param    string       $route   - "pretty" public alias for module method
1350
     * @param    integer      $status  - integer value corresponding  to status constant strings set in module parent
1351
     *                                 class, allows different forwards to be served based on status
1352
     * @param    array|string $forward - function name or array( class, method )
1353
     * @param    string       $key     - url param key indicating a route is being called
1354
     * @return    bool
1355
     */
1356
    public static function register_forward($route = null, $status = 0, $forward = null, $key = 'ee')
1357
    {
1358
        do_action('AHEE__EE_Config__register_forward', $route, $status, $forward);
1359 View Code Duplication
        if (! isset(EE_Config::$_module_route_map[$key][$route]) || empty($route)) {
1360
            $msg = sprintf(
1361
                __('The module route %s for this forward has not been registered.', 'event_espresso'),
1362
                $route
1363
            );
1364
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1365
            return false;
1366
        }
1367 View Code Duplication
        if (empty($forward)) {
1368
            $msg = sprintf(__('No forwarding route has been supplied.', 'event_espresso'), $route);
1369
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1370
            return false;
1371
        }
1372
        if (is_array($forward)) {
1373 View Code Duplication
            if (! isset($forward[1])) {
1374
                $msg = sprintf(
1375
                    __('A class method for the %s forwarding route has not been supplied.', 'event_espresso'),
1376
                    $route
1377
                );
1378
                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1379
                return false;
1380
            }
1381
            if (! method_exists($forward[0], $forward[1])) {
1382
                $msg = sprintf(
1383
                    __('The class method %s for the %s forwarding route is in invalid.', 'event_espresso'),
1384
                    $forward[1],
1385
                    $route
1386
                );
1387
                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1388
                return false;
1389
            }
1390
        } else if (! function_exists($forward)) {
1391
            $msg = sprintf(
1392
                __('The function %s for the %s forwarding route is in invalid.', 'event_espresso'),
1393
                $forward,
1394
                $route
1395
            );
1396
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1397
            return false;
1398
        }
1399
        EE_Config::$_module_forward_map[$key][$route][absint($status)] = $forward;
1400
        return true;
1401
    }
1402
1403
1404
1405
    /**
1406
     *    get_forward - get forwarding route
1407
     *
1408
     * @access    public
1409
     * @param    string  $route  - "pretty" public alias for module method
1410
     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1411
     *                           allows different forwards to be served based on status
1412
     * @param    string  $key    - url param key indicating a route is being called
1413
     * @return    string
1414
     */
1415 View Code Duplication
    public static function get_forward($route = null, $status = 0, $key = 'ee')
1416
    {
1417
        do_action('AHEE__EE_Config__get_forward__begin', $route, $status);
1418
        if (isset(EE_Config::$_module_forward_map[$key][$route][$status])) {
1419
            return apply_filters(
1420
                'FHEE__EE_Config__get_forward',
1421
                EE_Config::$_module_forward_map[$key][$route][$status],
1422
                $route,
1423
                $status
1424
            );
1425
        }
1426
        return null;
1427
    }
1428
1429
1430
1431
    /**
1432
     *    register_forward - allows modules to specify different view templates for different method routes and status
1433
     *    results
1434
     *
1435
     * @access    public
1436
     * @param    string  $route  - "pretty" public alias for module method
1437
     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1438
     *                           allows different views to be served based on status
1439
     * @param    string  $view
1440
     * @param    string  $key    - url param key indicating a route is being called
1441
     * @return    bool
1442
     */
1443
    public static function register_view($route = null, $status = 0, $view = null, $key = 'ee')
1444
    {
1445
        do_action('AHEE__EE_Config__register_view__begin', $route, $status, $view);
1446 View Code Duplication
        if (! isset(EE_Config::$_module_route_map[$key][$route]) || empty($route)) {
1447
            $msg = sprintf(
1448
                __('The module route %s for this view has not been registered.', 'event_espresso'),
1449
                $route
1450
            );
1451
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1452
            return false;
1453
        }
1454
        if (! is_readable($view)) {
1455
            $msg = sprintf(
1456
                __(
1457
                    'The %s view file could not be found or is not readable due to file permissions.',
1458
                    'event_espresso'
1459
                ),
1460
                $view
1461
            );
1462
            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1463
            return false;
1464
        }
1465
        EE_Config::$_module_view_map[$key][$route][absint($status)] = $view;
1466
        return true;
1467
    }
1468
1469
1470
1471
    /**
1472
     *    get_view - get view for route and status
1473
     *
1474
     * @access    public
1475
     * @param    string  $route  - "pretty" public alias for module method
1476
     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1477
     *                           allows different views to be served based on status
1478
     * @param    string  $key    - url param key indicating a route is being called
1479
     * @return    string
1480
     */
1481 View Code Duplication
    public static function get_view($route = null, $status = 0, $key = 'ee')
1482
    {
1483
        do_action('AHEE__EE_Config__get_view__begin', $route, $status);
1484
        if (isset(EE_Config::$_module_view_map[$key][$route][$status])) {
1485
            return apply_filters(
1486
                'FHEE__EE_Config__get_view',
1487
                EE_Config::$_module_view_map[$key][$route][$status],
1488
                $route,
1489
                $status
1490
            );
1491
        }
1492
        return null;
1493
    }
1494
1495
1496
1497
    public function update_addon_option_names()
1498
    {
1499
        update_option(EE_Config::ADDON_OPTION_NAMES, $this->_addon_option_names);
1500
    }
1501
1502
1503
1504
    public function shutdown()
1505
    {
1506
        $this->update_addon_option_names();
1507
    }
1508
1509
1510
1511
    /**
1512
     * @return LegacyShortcodesManager
1513
     */
1514
    public static function getLegacyShortcodesManager()
1515
    {
1516
1517
        if ( ! EE_Config::instance()->legacy_shortcodes_manager instanceof LegacyShortcodesManager) {
1518
            EE_Config::instance()->legacy_shortcodes_manager = new LegacyShortcodesManager(
1519
                EE_Registry::instance()
1520
            );
1521
        }
1522
        return EE_Config::instance()->legacy_shortcodes_manager;
1523
    }
1524
1525
1526
1527
    /**
1528
     * register_shortcode - makes core aware of this shortcode
1529
     *
1530
     * @deprecated 4.9.26
1531
     * @param    string $shortcode_path - full path up to and including shortcode folder
1532
     * @return    bool
1533
     */
1534
    public static function register_shortcode($shortcode_path = null)
1535
    {
1536
        EE_Error::doing_it_wrong(
1537
            __METHOD__,
1538
            __(
1539
                '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.',
1540
                'event_espresso'
1541
            ),
1542
            '4.9.26'
1543
        );
1544
        return EE_Config::instance()->getLegacyShortcodesManager()->registerShortcode($shortcode_path);
1545
    }
1546
1547
1548
1549
}
1550
1551
1552
1553
/**
1554
 * Base class used for config classes. These classes should generally not have
1555
 * magic functions in use, except we'll allow them to magically set and get stuff...
1556
 * basically, they should just be well-defined stdClasses
1557
 */
1558
class EE_Config_Base
1559
{
1560
1561
    /**
1562
     * Utility function for escaping the value of a property and returning.
1563
     *
1564
     * @param string $property property name (checks to see if exists).
1565
     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1566
     * @throws EE_Error
1567
     */
1568
    public function get_pretty($property)
1569
    {
1570
        if (! property_exists($this, $property)) {
1571
            throw new EE_Error(
1572
                sprintf(
1573
                    __(
1574
                        '%1$s::get_pretty() has been called with the property %2$s which does not exist on the %1$s config class.',
1575
                        'event_espresso'
1576
                    ),
1577
                    get_class($this),
1578
                    $property
1579
                )
1580
            );
1581
        }
1582
        //just handling escaping of strings for now.
1583
        if (is_string($this->{$property})) {
1584
            return stripslashes($this->{$property});
1585
        }
1586
        return $this->{$property};
1587
    }
1588
1589
1590
1591
    public function populate()
1592
    {
1593
        //grab defaults via a new instance of this class.
1594
        $class_name = get_class($this);
1595
        $defaults = new $class_name;
1596
        //loop through the properties for this class and see if they are set.  If they are NOT, then grab the
1597
        //default from our $defaults object.
1598
        foreach (get_object_vars($defaults) as $property => $value) {
1599
            if ($this->{$property} === null) {
1600
                $this->{$property} = $value;
1601
            }
1602
        }
1603
        //cleanup
1604
        unset($defaults);
1605
    }
1606
1607
1608
1609
    /**
1610
     *        __isset
1611
     *
1612
     * @param $a
1613
     * @return bool
1614
     */
1615
    public function __isset($a)
1616
    {
1617
        return false;
1618
    }
1619
1620
1621
1622
    /**
1623
     *        __unset
1624
     *
1625
     * @param $a
1626
     * @return bool
1627
     */
1628
    public function __unset($a)
1629
    {
1630
        return false;
1631
    }
1632
1633
1634
1635
    /**
1636
     *        __clone
1637
     */
1638
    public function __clone()
1639
    {
1640
    }
1641
1642
1643
1644
    /**
1645
     *        __wakeup
1646
     */
1647
    public function __wakeup()
1648
    {
1649
    }
1650
1651
1652
1653
    /**
1654
     *        __destruct
1655
     */
1656
    public function __destruct()
1657
    {
1658
    }
1659
}
1660
1661
1662
1663
/**
1664
 * Class for defining what's in the EE_Config relating to registration settings
1665
 */
1666
class EE_Core_Config extends EE_Config_Base
1667
{
1668
1669
    public $current_blog_id;
1670
1671
    public $ee_ueip_optin;
1672
1673
    public $ee_ueip_has_notified;
1674
1675
    /**
1676
     * Not to be confused with the 4 critical page variables (See
1677
     * get_critical_pages_array()), this is just an array of wp posts that have EE
1678
     * shortcodes in them. Keys are slugs, values are arrays with only 1 element: where the key is the shortcode
1679
     * in the page, and the value is the page's ID. The key 'posts' is basically a duplicate of this same array.
1680
     *
1681
     * @var array
1682
     */
1683
    public $post_shortcodes;
1684
1685
    public $module_route_map;
1686
1687
    public $module_forward_map;
1688
1689
    public $module_view_map;
1690
1691
    /**
1692
     * The next 4 vars are the IDs of critical EE pages.
1693
     *
1694
     * @var int
1695
     */
1696
    public $reg_page_id;
1697
1698
    public $txn_page_id;
1699
1700
    public $thank_you_page_id;
1701
1702
    public $cancel_page_id;
1703
1704
    /**
1705
     * The next 4 vars are the URLs of critical EE pages.
1706
     *
1707
     * @var int
1708
     */
1709
    public $reg_page_url;
1710
1711
    public $txn_page_url;
1712
1713
    public $thank_you_page_url;
1714
1715
    public $cancel_page_url;
1716
1717
    /**
1718
     * The next vars relate to the custom slugs for EE CPT routes
1719
     */
1720
    public $event_cpt_slug;
1721
1722
1723
    /**
1724
     * This caches the _ee_ueip_option in case this config is reset in the same
1725
     * request across blog switches in a multisite context.
1726
     * Avoids extra queries to the db for this option.
1727
     *
1728
     * @var bool
1729
     */
1730
    public static $ee_ueip_option;
1731
1732
1733
1734
    /**
1735
     *    class constructor
1736
     *
1737
     * @access    public
1738
     */
1739
    public function __construct()
1740
    {
1741
        // set default organization settings
1742
        $this->current_blog_id = get_current_blog_id();
1743
        $this->current_blog_id = $this->current_blog_id === null ? 1 : $this->current_blog_id;
1744
        $this->ee_ueip_optin = $this->_get_main_ee_ueip_optin();
1745
        $this->ee_ueip_has_notified = is_main_site() ? get_option('ee_ueip_has_notified', false) : true;
1746
        $this->post_shortcodes = array();
1747
        $this->module_route_map = array();
1748
        $this->module_forward_map = array();
1749
        $this->module_view_map = array();
1750
        // critical EE page IDs
1751
        $this->reg_page_id = 0;
1752
        $this->txn_page_id = 0;
1753
        $this->thank_you_page_id = 0;
1754
        $this->cancel_page_id = 0;
1755
        // critical EE page URLs
1756
        $this->reg_page_url = '';
1757
        $this->txn_page_url = '';
1758
        $this->thank_you_page_url = '';
1759
        $this->cancel_page_url = '';
1760
        //cpt slugs
1761
        $this->event_cpt_slug = __('events', 'event_espresso');
1762
        //ueip constant check
1763
        if (defined('EE_DISABLE_UXIP') && EE_DISABLE_UXIP) {
1764
            $this->ee_ueip_optin = false;
1765
            $this->ee_ueip_has_notified = true;
1766
        }
1767
    }
1768
1769
1770
1771
    /**
1772
     * @return array
1773
     */
1774
    public function get_critical_pages_array()
1775
    {
1776
        return array(
1777
            $this->reg_page_id,
1778
            $this->txn_page_id,
1779
            $this->thank_you_page_id,
1780
            $this->cancel_page_id,
1781
        );
1782
    }
1783
1784
1785
1786
    /**
1787
     * @return array
1788
     */
1789
    public function get_critical_pages_shortcodes_array()
1790
    {
1791
        return array(
1792
            $this->reg_page_id       => 'ESPRESSO_CHECKOUT',
1793
            $this->txn_page_id       => 'ESPRESSO_TXN_PAGE',
1794
            $this->thank_you_page_id => 'ESPRESSO_THANK_YOU',
1795
            $this->cancel_page_id    => 'ESPRESSO_CANCELLED',
1796
        );
1797
    }
1798
1799
1800
1801
    /**
1802
     *  gets/returns URL for EE reg_page
1803
     *
1804
     * @access    public
1805
     * @return    string
1806
     */
1807
    public function reg_page_url()
1808
    {
1809
        if (! $this->reg_page_url) {
1810
            $this->reg_page_url = add_query_arg(
1811
                                      array('uts' => time()),
1812
                                      get_permalink($this->reg_page_id)
1813
                                  ) . '#checkout';
1814
        }
1815
        return $this->reg_page_url;
1816
    }
1817
1818
1819
1820
    /**
1821
     *  gets/returns URL for EE txn_page
1822
     *
1823
     * @param array $query_args like what gets passed to
1824
     *                          add_query_arg() as the first argument
1825
     * @access    public
1826
     * @return    string
1827
     */
1828 View Code Duplication
    public function txn_page_url($query_args = array())
1829
    {
1830
        if (! $this->txn_page_url) {
1831
            $this->txn_page_url = get_permalink($this->txn_page_id);
1832
        }
1833
        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...
1834
            return add_query_arg($query_args, $this->txn_page_url);
1835
        } else {
1836
            return $this->txn_page_url;
1837
        }
1838
    }
1839
1840
1841
1842
    /**
1843
     *  gets/returns URL for EE thank_you_page
1844
     *
1845
     * @param array $query_args like what gets passed to
1846
     *                          add_query_arg() as the first argument
1847
     * @access    public
1848
     * @return    string
1849
     */
1850 View Code Duplication
    public function thank_you_page_url($query_args = array())
1851
    {
1852
        if (! $this->thank_you_page_url) {
1853
            $this->thank_you_page_url = get_permalink($this->thank_you_page_id);
1854
        }
1855
        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...
1856
            return add_query_arg($query_args, $this->thank_you_page_url);
1857
        } else {
1858
            return $this->thank_you_page_url;
1859
        }
1860
    }
1861
1862
1863
1864
    /**
1865
     *  gets/returns URL for EE cancel_page
1866
     *
1867
     * @access    public
1868
     * @return    string
1869
     */
1870
    public function cancel_page_url()
1871
    {
1872
        if (! $this->cancel_page_url) {
1873
            $this->cancel_page_url = get_permalink($this->cancel_page_id);
1874
        }
1875
        return $this->cancel_page_url;
1876
    }
1877
1878
1879
1880
    /**
1881
     * Resets all critical page urls to their original state.  Used primarily by the __sleep() magic method currently.
1882
     *
1883
     * @since 4.7.5
1884
     */
1885
    protected function _reset_urls()
1886
    {
1887
        $this->reg_page_url = '';
1888
        $this->txn_page_url = '';
1889
        $this->cancel_page_url = '';
1890
        $this->thank_you_page_url = '';
1891
    }
1892
1893
1894
1895
    /**
1896
     * Used to return what the opt-in value is set for the EE User Experience Program.
1897
     * This accounts for multisite and this value being requested for a subsite.  In multisite, the value is set
1898
     * on the main site only.
1899
     *
1900
     * @return mixed
1901
     */
1902
    protected function _get_main_ee_ueip_optin()
1903
    {
1904
        //if this is the main site then we can just bypass our direct query.
1905
        if (is_main_site()) {
1906
            return get_option('ee_ueip_optin', false);
1907
        }
1908
        //is this already cached for this request?  If so use it.
1909
        if ( ! empty(EE_Core_Config::$ee_ueip_option)) {
1910
            return EE_Core_Config::$ee_ueip_option;
1911
        }
1912
        global $wpdb;
1913
        $current_network_main_site = is_multisite() ? get_current_site() : null;
1914
        $current_main_site_id = ! empty($current_network_main_site) ? $current_network_main_site->blog_id : 1;
1915
        $option = 'ee_ueip_optin';
1916
        //set correct table for query
1917
        $table_name = $wpdb->get_blog_prefix($current_main_site_id) . 'options';
1918
        //rather than getting blog option for the $current_main_site_id, we do a direct $wpdb query because
1919
        //get_blog_option() does a switch_to_blog an that could cause infinite recursion because EE_Core_Config might be
1920
        //re-constructed on the blog switch.  Note, we are still executing any core wp filters on this option retrieval.
1921
        //this bit of code is basically a direct copy of get_option without any caching because we are NOT switched to the blog
1922
        //for the purpose of caching.
1923
        $pre = apply_filters('pre_option_' . $option, false, $option);
1924
        if (false !== $pre) {
1925
            EE_Core_Config::$ee_ueip_option = $pre;
1926
            return EE_Core_Config::$ee_ueip_option;
1927
        }
1928
        $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $table_name WHERE option_name = %s LIMIT 1",
1929
            $option));
1930
        if (is_object($row)) {
1931
            $value = $row->option_value;
1932
        } else { //option does not exist so use default.
1933
            return apply_filters('default_option_' . $option, false, $option);
1934
        }
1935
        EE_Core_Config::$ee_ueip_option = apply_filters('option_' . $option, maybe_unserialize($value), $option);
1936
        return EE_Core_Config::$ee_ueip_option;
1937
    }
1938
1939
1940
1941
    /**
1942
     * Currently used to ensure critical page urls have initial values saved to the db instead of any current set values
1943
     * on the object.
1944
     *
1945
     * @return array
1946
     */
1947
    public function __sleep()
1948
    {
1949
        //reset all url properties
1950
        $this->_reset_urls();
1951
        //return what to save to db
1952
        return array_keys(get_object_vars($this));
1953
    }
1954
1955
}
1956
1957
1958
1959
/**
1960
 * Config class for storing info on the Organization
1961
 */
1962
class EE_Organization_Config extends EE_Config_Base
1963
{
1964
1965
    /**
1966
     * @var string $name
1967
     * eg EE4.1
1968
     */
1969
    public $name;
1970
1971
    /**
1972
     * @var string $address_1
1973
     * eg 123 Onna Road
1974
     */
1975
    public $address_1;
1976
1977
    /**
1978
     * @var string $address_2
1979
     * eg PO Box 123
1980
     */
1981
    public $address_2;
1982
1983
    /**
1984
     * @var string $city
1985
     * eg Inna City
1986
     */
1987
    public $city;
1988
1989
    /**
1990
     * @var int $STA_ID
1991
     * eg 4
1992
     */
1993
    public $STA_ID;
1994
1995
    /**
1996
     * @var string $CNT_ISO
1997
     * eg US
1998
     */
1999
    public $CNT_ISO;
2000
2001
    /**
2002
     * @var string $zip
2003
     * eg 12345  or V1A 2B3
2004
     */
2005
    public $zip;
2006
2007
    /**
2008
     * @var string $email
2009
     * eg [email protected]
2010
     */
2011
    public $email;
2012
2013
2014
    /**
2015
     * @var string $phone
2016
     * eg. 111-111-1111
2017
     */
2018
    public $phone;
2019
2020
2021
    /**
2022
     * @var string $vat
2023
     * VAT/Tax Number
2024
     */
2025
    public $vat;
2026
2027
    /**
2028
     * @var string $logo_url
2029
     * eg http://www.somedomain.com/wp-content/uploads/kittehs.jpg
2030
     */
2031
    public $logo_url;
2032
2033
2034
    /**
2035
     * The below are all various properties for holding links to organization social network profiles
2036
     *
2037
     * @var string
2038
     */
2039
    /**
2040
     * facebook (facebook.com/profile.name)
2041
     *
2042
     * @var string
2043
     */
2044
    public $facebook;
2045
2046
2047
    /**
2048
     * twitter (twitter.com/twitter_handle)
2049
     *
2050
     * @var string
2051
     */
2052
    public $twitter;
2053
2054
2055
    /**
2056
     * linkedin (linkedin.com/in/profile_name)
2057
     *
2058
     * @var string
2059
     */
2060
    public $linkedin;
2061
2062
2063
    /**
2064
     * pinterest (www.pinterest.com/profile_name)
2065
     *
2066
     * @var string
2067
     */
2068
    public $pinterest;
2069
2070
2071
    /**
2072
     * google+ (google.com/+profileName)
2073
     *
2074
     * @var string
2075
     */
2076
    public $google;
2077
2078
2079
    /**
2080
     * instagram (instagram.com/handle)
2081
     *
2082
     * @var string
2083
     */
2084
    public $instagram;
2085
2086
2087
2088
    /**
2089
     *    class constructor
2090
     *
2091
     * @access    public
2092
     */
2093
    public function __construct()
2094
    {
2095
        // set default organization settings
2096
        $this->name = get_bloginfo('name');
2097
        $this->address_1 = '123 Onna Road';
2098
        $this->address_2 = 'PO Box 123';
2099
        $this->city = 'Inna City';
2100
        $this->STA_ID = 4;
2101
        $this->CNT_ISO = 'US';
2102
        $this->zip = '12345';
2103
        $this->email = get_bloginfo('admin_email');
2104
        $this->phone = '';
2105
        $this->vat = '123456789';
2106
        $this->logo_url = '';
2107
        $this->facebook = '';
2108
        $this->twitter = '';
2109
        $this->linkedin = '';
2110
        $this->pinterest = '';
2111
        $this->google = '';
2112
        $this->instagram = '';
2113
    }
2114
2115
}
2116
2117
2118
2119
/**
2120
 * Class for defining what's in the EE_Config relating to currency
2121
 */
2122
class EE_Currency_Config extends EE_Config_Base
2123
{
2124
2125
    /**
2126
     * @var string $code
2127
     * eg 'US'
2128
     */
2129
    public $code;
2130
2131
    /**
2132
     * @var string $name
2133
     * eg 'Dollar'
2134
     */
2135
    public $name;
2136
2137
    /**
2138
     * plural name
2139
     *
2140
     * @var string $plural
2141
     * eg 'Dollars'
2142
     */
2143
    public $plural;
2144
2145
    /**
2146
     * currency sign
2147
     *
2148
     * @var string $sign
2149
     * eg '$'
2150
     */
2151
    public $sign;
2152
2153
    /**
2154
     * Whether the currency sign should come before the number or not
2155
     *
2156
     * @var boolean $sign_b4
2157
     */
2158
    public $sign_b4;
2159
2160
    /**
2161
     * How many digits should come after the decimal place
2162
     *
2163
     * @var int $dec_plc
2164
     */
2165
    public $dec_plc;
2166
2167
    /**
2168
     * Symbol to use for decimal mark
2169
     *
2170
     * @var string $dec_mrk
2171
     * eg '.'
2172
     */
2173
    public $dec_mrk;
2174
2175
    /**
2176
     * Symbol to use for thousands
2177
     *
2178
     * @var string $thsnds
2179
     * eg ','
2180
     */
2181
    public $thsnds;
2182
2183
2184
    /**
2185
     *    class constructor
2186
     *
2187
     * @access    public
2188
     * @param string             $CNT_ISO
2189
     * @param CountryCurrencyDao $country_currencies
2190
     * @throws EE_Error
2191
     * @throws InvalidArgumentException
2192
     * @throws ReflectionException
2193
     * @throws InvalidDataTypeException
2194
     * @throws InvalidInterfaceException
2195
     */
2196
    public function __construct($CNT_ISO = '', CountryCurrencyDao $country_currencies = null)
2197
    {
2198
        if(! $country_currencies instanceof CountryCurrencyDao){
2199
            $country_currencies = new CountryCurrencyDao();
2200
        }
2201
        // 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
2202
        if (! empty($CNT_ISO)) {
2203
            // retrieve the country settings from the db, just in case they have been customized
2204
            $country_currency = $country_currencies->getCountryCurrencyByIsoCode($CNT_ISO);
2205
            $this->code = $country_currency['CurrencyCode'];    // currency code: USD, CAD, EUR
2206
            $this->name = $country_currency['CurrencyNameSingle'];    // Dollar
2207
            $this->plural = $country_currency['CurrencyNamePlural'];    // Dollars
2208
            $this->sign = $country_currency['CurrencySign'];            // currency sign: $
2209
            $this->sign_b4 = $country_currency['CurrencySignB4'];        // currency sign before or after: $TRUE  or  FALSE$
2210
            $this->dec_plc = $country_currency['CurrencyDecimalPlaces'];    // decimal places: 2 = 0.00  3 = 0.000
2211
            $this->dec_mrk = $country_currency['CurrencyDecimalMark'];    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2212
            $this->thsnds = $country_currency['CurrencyThousands'];    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2213
        }
2214
        // fallback to hardcoded defaults, in case the above failed
2215
        if (empty($this->code)) {
2216
            // set default currency settings
2217
            $this->code = 'USD';    // currency code: USD, CAD, EUR
2218
            $this->name = esc_html__('Dollar', 'event_espresso');    // Dollar
2219
            $this->plural = esc_html__('Dollars', 'event_espresso');    // Dollars
2220
            $this->sign = '$';    // currency sign: $
2221
            $this->sign_b4 = true;    // currency sign before or after: $TRUE  or  FALSE$
2222
            $this->dec_plc = 2;    // decimal places: 2 = 0.00  3 = 0.000
2223
            $this->dec_mrk = '.';    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2224
            $this->thsnds = ',';    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2225
        }
2226
    }
2227
2228
2229
    /**
2230
     * @param string $CNT_ISO
2231
     * @throws EE_Error
2232
     * @throws InvalidArgumentException
2233
     * @throws InvalidDataTypeException
2234
     * @throws InvalidInterfaceException
2235
     * @throws ReflectionException
2236
     */
2237
    public function setFromCountryModel($CNT_ISO)
2238
    {
2239
        /** @var \EventEspresso\core\services\database\TableAnalysis $table_analysis */
2240
        $table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
2241
        if (
2242
            ! EE_Maintenance_Mode::instance()->models_can_query()
2243
            || ! $table_analysis->tableExists(EE_Registry::instance()->load_model('Country')->table())
2244
        ) {
2245
            return;
2246
        }
2247
        $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
2248
        if ($country instanceof EE_Country) {
2249
            $this->code    = $country->currency_code();    // currency code: USD, CAD, EUR
2250
            $this->name    = $country->currency_name_single();    // Dollar
2251
            $this->plural  = $country->currency_name_plural();    // Dollars
2252
            $this->sign    = $country->currency_sign();            // currency sign: $
2253
            $this->sign_b4 = $country->currency_sign_before();        // currency sign before or after: $TRUE  or  FALSE$
2254
            $this->dec_plc = $country->currency_decimal_places();    // decimal places: 2 = 0.00  3 = 0.000
2255
            $this->dec_mrk = $country->currency_decimal_mark();    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2256
            $this->thsnds  = $country->currency_thousands_separator();    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2257
        }
2258
    }
2259
}
2260
2261
2262
2263
/**
2264
 * Class for defining what's in the EE_Config relating to registration settings
2265
 */
2266
class EE_Registration_Config extends EE_Config_Base
2267
{
2268
2269
    /**
2270
     * Default registration status
2271
     *
2272
     * @var string $default_STS_ID
2273
     * eg 'RPP'
2274
     */
2275
    public $default_STS_ID;
2276
2277
2278
    /**
2279
     * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2280
     * registrations)
2281
     * @var int
2282
     */
2283
    public $default_maximum_number_of_tickets;
2284
2285
2286
    /**
2287
     * level of validation to apply to email addresses
2288
     *
2289
     * @var string $email_validation_level
2290
     * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2291
     */
2292
    public $email_validation_level;
2293
2294
    /**
2295
     *    whether or not to show alternate payment options during the reg process if payment status is pending
2296
     *
2297
     * @var boolean $show_pending_payment_options
2298
     */
2299
    public $show_pending_payment_options;
2300
2301
    /**
2302
     * Whether to skip the registration confirmation page
2303
     *
2304
     * @var boolean $skip_reg_confirmation
2305
     */
2306
    public $skip_reg_confirmation;
2307
2308
    /**
2309
     * an array of SPCO reg steps where:
2310
     *        the keys denotes the reg step order
2311
     *        each element consists of an array with the following elements:
2312
     *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2313
     *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2314
     *            "slug" => the URL param used to trigger the reg step
2315
     *
2316
     * @var array $reg_steps
2317
     */
2318
    public $reg_steps;
2319
2320
    /**
2321
     * Whether registration confirmation should be the last page of SPCO
2322
     *
2323
     * @var boolean $reg_confirmation_last
2324
     */
2325
    public $reg_confirmation_last;
2326
2327
    /**
2328
     * Whether or not to enable the EE Bot Trap
2329
     *
2330
     * @var boolean $use_bot_trap
2331
     */
2332
    public $use_bot_trap;
2333
2334
    /**
2335
     * Whether or not to encrypt some data sent by the EE Bot Trap
2336
     *
2337
     * @var boolean $use_encryption
2338
     */
2339
    public $use_encryption;
2340
2341
    /**
2342
     * Whether or not to use ReCaptcha
2343
     *
2344
     * @var boolean $use_captcha
2345
     */
2346
    public $use_captcha;
2347
2348
    /**
2349
     * ReCaptcha Theme
2350
     *
2351
     * @var string $recaptcha_theme
2352
     *    options: 'dark    ', 'light'
2353
     */
2354
    public $recaptcha_theme;
2355
2356
    /**
2357
     * ReCaptcha Type
2358
     *
2359
     * @var string $recaptcha_type
2360
     *    options: 'audio', 'image'
2361
     */
2362
    public $recaptcha_type;
2363
2364
    /**
2365
     * ReCaptcha language
2366
     *
2367
     * @var string $recaptcha_language
2368
     * eg 'en'
2369
     */
2370
    public $recaptcha_language;
2371
2372
    /**
2373
     * ReCaptcha public key
2374
     *
2375
     * @var string $recaptcha_publickey
2376
     */
2377
    public $recaptcha_publickey;
2378
2379
    /**
2380
     * ReCaptcha private key
2381
     *
2382
     * @var string $recaptcha_privatekey
2383
     */
2384
    public $recaptcha_privatekey;
2385
2386
    /**
2387
     * ReCaptcha width
2388
     *
2389
     * @var int $recaptcha_width
2390
     * @deprecated
2391
     */
2392
    public $recaptcha_width;
2393
2394
    /**
2395
     * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2396
     *
2397
     * @var boolean $track_invalid_checkout_access
2398
     */
2399
    protected $track_invalid_checkout_access = true;
2400
2401
2402
2403
    /**
2404
     *    class constructor
2405
     *
2406
     * @access    public
2407
     */
2408
    public function __construct()
2409
    {
2410
        // set default registration settings
2411
        $this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2412
        $this->email_validation_level = 'wp_default';
2413
        $this->show_pending_payment_options = true;
2414
        $this->skip_reg_confirmation = false;
2415
        $this->reg_steps = array();
2416
        $this->reg_confirmation_last = false;
2417
        $this->use_bot_trap = true;
2418
        $this->use_encryption = true;
2419
        $this->use_captcha = false;
2420
        $this->recaptcha_theme = 'light';
2421
        $this->recaptcha_type = 'image';
2422
        $this->recaptcha_language = 'en';
2423
        $this->recaptcha_publickey = null;
2424
        $this->recaptcha_privatekey = null;
2425
        $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...
2426
        $this->default_maximum_number_of_tickets = 10;
2427
    }
2428
2429
2430
2431
    /**
2432
     * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2433
     *
2434
     * @since 4.8.8.rc.019
2435
     */
2436
    public function do_hooks()
2437
    {
2438
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2439
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2440
    }
2441
2442
2443
2444
    /**
2445
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_default_registration_status
2446
     * field matches the config setting for default_STS_ID.
2447
     */
2448
    public function set_default_reg_status_on_EEM_Event()
2449
    {
2450
        EEM_Event::set_default_reg_status($this->default_STS_ID);
2451
    }
2452
2453
2454
    /**
2455
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2456
     * for Events matches the config setting for default_maximum_number_of_tickets
2457
     */
2458
    public function set_default_max_ticket_on_EEM_Event()
2459
    {
2460
        EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2461
    }
2462
2463
2464
2465
    /**
2466
     * @return boolean
2467
     */
2468
    public function track_invalid_checkout_access()
2469
    {
2470
        return $this->track_invalid_checkout_access;
2471
    }
2472
2473
2474
2475
    /**
2476
     * @param boolean $track_invalid_checkout_access
2477
     */
2478
    public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2479
    {
2480
        $this->track_invalid_checkout_access = filter_var(
2481
            $track_invalid_checkout_access,
2482
            FILTER_VALIDATE_BOOLEAN
2483
        );
2484
    }
2485
2486
2487
2488
}
2489
2490
2491
2492
/**
2493
 * Class for defining what's in the EE_Config relating to admin settings
2494
 */
2495
class EE_Admin_Config extends EE_Config_Base
2496
{
2497
2498
    /**
2499
     * @var boolean $use_personnel_manager
2500
     */
2501
    public $use_personnel_manager;
2502
2503
    /**
2504
     * @var boolean $use_dashboard_widget
2505
     */
2506
    public $use_dashboard_widget;
2507
2508
    /**
2509
     * @var int $events_in_dashboard
2510
     */
2511
    public $events_in_dashboard;
2512
2513
    /**
2514
     * @var boolean $use_event_timezones
2515
     */
2516
    public $use_event_timezones;
2517
2518
    /**
2519
     * @var boolean $use_full_logging
2520
     */
2521
    public $use_full_logging;
2522
2523
    /**
2524
     * @var string $log_file_name
2525
     */
2526
    public $log_file_name;
2527
2528
    /**
2529
     * @var string $debug_file_name
2530
     */
2531
    public $debug_file_name;
2532
2533
    /**
2534
     * @var boolean $use_remote_logging
2535
     */
2536
    public $use_remote_logging;
2537
2538
    /**
2539
     * @var string $remote_logging_url
2540
     */
2541
    public $remote_logging_url;
2542
2543
    /**
2544
     * @var boolean $show_reg_footer
2545
     */
2546
    public $show_reg_footer;
2547
2548
    /**
2549
     * @var string $affiliate_id
2550
     */
2551
    public $affiliate_id;
2552
2553
    /**
2554
     * help tours on or off (global setting)
2555
     *
2556
     * @var boolean
2557
     */
2558
    public $help_tour_activation;
2559
2560
    /**
2561
     * adds extra layer of encoding to session data to prevent serialization errors
2562
     * but is incompatible with some server configuration errors
2563
     * if you get "500 internal server errors" during registration, try turning this on
2564
     * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2565
     *
2566
     * @var boolean $encode_session_data
2567
     */
2568
    private $encode_session_data = false;
2569
2570
2571
2572
    /**
2573
     *    class constructor
2574
     *
2575
     * @access    public
2576
     */
2577
    public function __construct()
2578
    {
2579
        // set default general admin settings
2580
        $this->use_personnel_manager = true;
2581
        $this->use_dashboard_widget = true;
2582
        $this->events_in_dashboard = 30;
2583
        $this->use_event_timezones = false;
2584
        $this->use_full_logging = false;
2585
        $this->use_remote_logging = false;
2586
        $this->remote_logging_url = null;
2587
        $this->show_reg_footer = true;
2588
        $this->affiliate_id = 'default';
2589
        $this->help_tour_activation = true;
2590
        $this->encode_session_data = false;
2591
    }
2592
2593
2594
2595
    /**
2596
     * @param bool $reset
2597
     * @return string
2598
     */
2599 View Code Duplication
    public function log_file_name($reset = false)
2600
    {
2601
        if (empty($this->log_file_name) || $reset) {
2602
            $this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2603
            EE_Config::instance()->update_espresso_config(false, false);
2604
        }
2605
        return $this->log_file_name;
2606
    }
2607
2608
2609
2610
    /**
2611
     * @param bool $reset
2612
     * @return string
2613
     */
2614 View Code Duplication
    public function debug_file_name($reset = false)
2615
    {
2616
        if (empty($this->debug_file_name) || $reset) {
2617
            $this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2618
            EE_Config::instance()->update_espresso_config(false, false);
2619
        }
2620
        return $this->debug_file_name;
2621
    }
2622
2623
2624
2625
    /**
2626
     * @return string
2627
     */
2628
    public function affiliate_id()
2629
    {
2630
        return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2631
    }
2632
2633
2634
2635
    /**
2636
     * @return boolean
2637
     */
2638
    public function encode_session_data()
2639
    {
2640
        return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2641
    }
2642
2643
2644
2645
    /**
2646
     * @param boolean $encode_session_data
2647
     */
2648
    public function set_encode_session_data($encode_session_data)
2649
    {
2650
        $this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2651
    }
2652
2653
2654
2655
}
2656
2657
2658
2659
/**
2660
 * Class for defining what's in the EE_Config relating to template settings
2661
 */
2662
class EE_Template_Config extends EE_Config_Base
2663
{
2664
2665
    /**
2666
     * @var boolean $enable_default_style
2667
     */
2668
    public $enable_default_style;
2669
2670
    /**
2671
     * @var string $custom_style_sheet
2672
     */
2673
    public $custom_style_sheet;
2674
2675
    /**
2676
     * @var boolean $display_address_in_regform
2677
     */
2678
    public $display_address_in_regform;
2679
2680
    /**
2681
     * @var int $display_description_on_multi_reg_page
2682
     */
2683
    public $display_description_on_multi_reg_page;
2684
2685
    /**
2686
     * @var boolean $use_custom_templates
2687
     */
2688
    public $use_custom_templates;
2689
2690
    /**
2691
     * @var string $current_espresso_theme
2692
     */
2693
    public $current_espresso_theme;
2694
2695
    /**
2696
     * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2697
     */
2698
    public $EED_Ticket_Selector;
2699
2700
    /**
2701
     * @var EE_Event_Single_Config $EED_Event_Single
2702
     */
2703
    public $EED_Event_Single;
2704
2705
    /**
2706
     * @var EE_Events_Archive_Config $EED_Events_Archive
2707
     */
2708
    public $EED_Events_Archive;
2709
2710
2711
2712
    /**
2713
     *    class constructor
2714
     *
2715
     * @access    public
2716
     */
2717
    public function __construct()
2718
    {
2719
        // set default template settings
2720
        $this->enable_default_style = true;
2721
        $this->custom_style_sheet = null;
2722
        $this->display_address_in_regform = true;
2723
        $this->display_description_on_multi_reg_page = false;
2724
        $this->use_custom_templates = false;
2725
        $this->current_espresso_theme = 'Espresso_Arabica_2014';
2726
        $this->EED_Event_Single = null;
2727
        $this->EED_Events_Archive = null;
2728
        $this->EED_Ticket_Selector = null;
2729
    }
2730
2731
}
2732
2733
2734
2735
/**
2736
 * Class for defining what's in the EE_Config relating to map settings
2737
 */
2738
class EE_Map_Config extends EE_Config_Base
2739
{
2740
2741
    /**
2742
     * @var boolean $use_google_maps
2743
     */
2744
    public $use_google_maps;
2745
2746
    /**
2747
     * @var string $api_key
2748
     */
2749
    public $google_map_api_key;
2750
2751
    /**
2752
     * @var int $event_details_map_width
2753
     */
2754
    public $event_details_map_width;
2755
2756
    /**
2757
     * @var int $event_details_map_height
2758
     */
2759
    public $event_details_map_height;
2760
2761
    /**
2762
     * @var int $event_details_map_zoom
2763
     */
2764
    public $event_details_map_zoom;
2765
2766
    /**
2767
     * @var boolean $event_details_display_nav
2768
     */
2769
    public $event_details_display_nav;
2770
2771
    /**
2772
     * @var boolean $event_details_nav_size
2773
     */
2774
    public $event_details_nav_size;
2775
2776
    /**
2777
     * @var string $event_details_control_type
2778
     */
2779
    public $event_details_control_type;
2780
2781
    /**
2782
     * @var string $event_details_map_align
2783
     */
2784
    public $event_details_map_align;
2785
2786
    /**
2787
     * @var int $event_list_map_width
2788
     */
2789
    public $event_list_map_width;
2790
2791
    /**
2792
     * @var int $event_list_map_height
2793
     */
2794
    public $event_list_map_height;
2795
2796
    /**
2797
     * @var int $event_list_map_zoom
2798
     */
2799
    public $event_list_map_zoom;
2800
2801
    /**
2802
     * @var boolean $event_list_display_nav
2803
     */
2804
    public $event_list_display_nav;
2805
2806
    /**
2807
     * @var boolean $event_list_nav_size
2808
     */
2809
    public $event_list_nav_size;
2810
2811
    /**
2812
     * @var string $event_list_control_type
2813
     */
2814
    public $event_list_control_type;
2815
2816
    /**
2817
     * @var string $event_list_map_align
2818
     */
2819
    public $event_list_map_align;
2820
2821
2822
2823
    /**
2824
     *    class constructor
2825
     *
2826
     * @access    public
2827
     */
2828
    public function __construct()
2829
    {
2830
        // set default map settings
2831
        $this->use_google_maps = true;
2832
        $this->google_map_api_key = '';
2833
        // for event details pages (reg page)
2834
        $this->event_details_map_width = 585;            // ee_map_width_single
2835
        $this->event_details_map_height = 362;            // ee_map_height_single
2836
        $this->event_details_map_zoom = 14;            // ee_map_zoom_single
2837
        $this->event_details_display_nav = true;            // ee_map_nav_display_single
2838
        $this->event_details_nav_size = false;            // ee_map_nav_size_single
2839
        $this->event_details_control_type = 'default';        // ee_map_type_control_single
2840
        $this->event_details_map_align = 'center';            // ee_map_align_single
2841
        // for event list pages
2842
        $this->event_list_map_width = 300;            // ee_map_width
2843
        $this->event_list_map_height = 185;        // ee_map_height
2844
        $this->event_list_map_zoom = 12;            // ee_map_zoom
2845
        $this->event_list_display_nav = false;        // ee_map_nav_display
2846
        $this->event_list_nav_size = true;            // ee_map_nav_size
2847
        $this->event_list_control_type = 'dropdown';        // ee_map_type_control
2848
        $this->event_list_map_align = 'center';            // ee_map_align
2849
    }
2850
2851
}
2852
2853
2854
2855
/**
2856
 * stores Events_Archive settings
2857
 */
2858
class EE_Events_Archive_Config extends EE_Config_Base
2859
{
2860
2861
    public $display_status_banner;
2862
2863
    public $display_description;
2864
2865
    public $display_ticket_selector;
2866
2867
    public $display_datetimes;
2868
2869
    public $display_venue;
2870
2871
    public $display_expired_events;
2872
2873
    public $use_sortable_display_order;
2874
2875
    public $display_order_tickets;
2876
2877
    public $display_order_datetimes;
2878
2879
    public $display_order_event;
2880
2881
    public $display_order_venue;
2882
2883
2884
2885
    /**
2886
     *    class constructor
2887
     */
2888
    public function __construct()
2889
    {
2890
        $this->display_status_banner = 0;
2891
        $this->display_description = 1;
2892
        $this->display_ticket_selector = 0;
2893
        $this->display_datetimes = 1;
2894
        $this->display_venue = 0;
2895
        $this->display_expired_events = 0;
2896
        $this->use_sortable_display_order = false;
2897
        $this->display_order_tickets = 100;
2898
        $this->display_order_datetimes = 110;
2899
        $this->display_order_event = 120;
2900
        $this->display_order_venue = 130;
2901
    }
2902
}
2903
2904
2905
2906
/**
2907
 * Stores Event_Single_Config settings
2908
 */
2909
class EE_Event_Single_Config extends EE_Config_Base
2910
{
2911
2912
    public $display_status_banner_single;
2913
2914
    public $display_venue;
2915
2916
    public $use_sortable_display_order;
2917
2918
    public $display_order_tickets;
2919
2920
    public $display_order_datetimes;
2921
2922
    public $display_order_event;
2923
2924
    public $display_order_venue;
2925
2926
2927
2928
    /**
2929
     *    class constructor
2930
     */
2931
    public function __construct()
2932
    {
2933
        $this->display_status_banner_single = 0;
2934
        $this->display_venue = 1;
2935
        $this->use_sortable_display_order = false;
2936
        $this->display_order_tickets = 100;
2937
        $this->display_order_datetimes = 110;
2938
        $this->display_order_event = 120;
2939
        $this->display_order_venue = 130;
2940
    }
2941
}
2942
2943
2944
2945
/**
2946
 * Stores Ticket_Selector_Config settings
2947
 */
2948
class EE_Ticket_Selector_Config extends EE_Config_Base
2949
{
2950
2951
    /**
2952
     * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
2953
     */
2954
    const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
2955
2956
    /**
2957
     * constant to indicate that a datetime selector should only be shown for ticket selectors
2958
     * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
2959
     */
2960
    const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
2961
2962
    /**
2963
     * @var boolean $show_ticket_sale_columns
2964
     */
2965
    public $show_ticket_sale_columns;
2966
2967
    /**
2968
     * @var boolean $show_ticket_details
2969
     */
2970
    public $show_ticket_details;
2971
2972
    /**
2973
     * @var boolean $show_expired_tickets
2974
     */
2975
    public $show_expired_tickets;
2976
2977
    /**
2978
     * whether or not to display a dropdown box populated with event datetimes
2979
     * that toggles which tickets are displayed for a ticket selector.
2980
     * uses one of the *_DATETIME_SELECTOR constants defined above
2981
     *
2982
     * @var string $show_datetime_selector
2983
     */
2984
    private $show_datetime_selector = 'no_datetime_selector';
2985
2986
    /**
2987
     * the number of datetimes an event has to have before conditionally displaying a datetime selector
2988
     *
2989
     * @var int $datetime_selector_threshold
2990
     */
2991
    private $datetime_selector_threshold = 3;
2992
2993
2994
2995
    /**
2996
     *    class constructor
2997
     */
2998
    public function __construct()
2999
    {
3000
        $this->show_ticket_sale_columns = true;
3001
        $this->show_ticket_details = true;
3002
        $this->show_expired_tickets = true;
3003
        $this->show_datetime_selector = \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3004
        $this->datetime_selector_threshold = 3;
3005
    }
3006
3007
3008
3009
    /**
3010
     * returns true if a datetime selector should be displayed
3011
     *
3012
     * @param array $datetimes
3013
     * @return bool
3014
     */
3015
    public function showDatetimeSelector(array $datetimes)
3016
    {
3017
        // if the settings are NOT: don't show OR below threshold, THEN active = true
3018
        return ! (
3019
            $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3020
            || (
3021
                $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3022
                && count($datetimes) < $this->getDatetimeSelectorThreshold()
3023
            )
3024
        );
3025
    }
3026
3027
3028
3029
    /**
3030
     * @return string
3031
     */
3032
    public function getShowDatetimeSelector()
3033
    {
3034
        return $this->show_datetime_selector;
3035
    }
3036
3037
3038
3039
    /**
3040
     * @param bool $keys_only
3041
     * @return array
3042
     */
3043
    public function getShowDatetimeSelectorOptions($keys_only = true)
3044
    {
3045
        return $keys_only
3046
            ? array(
3047
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3048
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3049
            )
3050
            : array(
3051
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3052
                    'Do not show date & time filter', 'event_espresso'
3053
                ),
3054
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3055
                    'Maybe show date & time filter', 'event_espresso'
3056
                ),
3057
            );
3058
    }
3059
3060
3061
3062
    /**
3063
     * @param string $show_datetime_selector
3064
     */
3065
    public function setShowDatetimeSelector($show_datetime_selector)
3066
    {
3067
        $this->show_datetime_selector = in_array(
3068
            $show_datetime_selector,
3069
            $this->getShowDatetimeSelectorOptions(),
3070
            true
3071
        )
3072
            ? $show_datetime_selector
3073
            : \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3074
    }
3075
3076
3077
3078
    /**
3079
     * @return int
3080
     */
3081
    public function getDatetimeSelectorThreshold()
3082
    {
3083
        return $this->datetime_selector_threshold;
3084
    }
3085
3086
3087
3088
3089
    /**
3090
     * @param int $datetime_selector_threshold
3091
     */
3092
    public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3093
    {
3094
        $datetime_selector_threshold = absint($datetime_selector_threshold);
3095
        $this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3096
    }
3097
3098
3099
3100
}
3101
3102
3103
3104
/**
3105
 * Stores any EE Environment values that are referenced through the code.
3106
 *
3107
 * @since       4.4.0
3108
 * @package     Event Espresso
3109
 * @subpackage  config
3110
 */
3111
class EE_Environment_Config extends EE_Config_Base
3112
{
3113
3114
    /**
3115
     * Hold any php environment variables that we want to track.
3116
     *
3117
     * @var stdClass;
3118
     */
3119
    public $php;
3120
3121
3122
3123
    /**
3124
     *    constructor
3125
     */
3126
    public function __construct()
3127
    {
3128
        $this->php = new stdClass();
3129
        $this->_set_php_values();
3130
    }
3131
3132
3133
3134
    /**
3135
     * This sets the php environment variables.
3136
     *
3137
     * @since 4.4.0
3138
     * @return void
3139
     */
3140
    protected function _set_php_values()
3141
    {
3142
        $this->php->max_input_vars = ini_get('max_input_vars');
3143
        $this->php->version = phpversion();
3144
    }
3145
3146
3147
3148
    /**
3149
     * helper method for determining whether input_count is
3150
     * reaching the potential maximum the server can handle
3151
     * according to max_input_vars
3152
     *
3153
     * @param int   $input_count the count of input vars.
3154
     * @return array {
3155
     *                           An array that represents whether available space and if no available space the error
3156
     *                           message.
3157
     * @type bool   $has_space   whether more inputs can be added.
3158
     * @type string $msg         Any message to be displayed.
3159
     *                           }
3160
     */
3161
    public function max_input_vars_limit_check($input_count = 0)
3162
    {
3163
        if (! empty($this->php->max_input_vars)
3164
            && ($input_count >= $this->php->max_input_vars)
3165
            && (PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3 && PHP_RELEASE_VERSION >= 9)
3166
        ) {
3167
            return sprintf(
3168
                __(
3169
                    '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.',
3170
                    'event_espresso'
3171
                ),
3172
                '<br>',
3173
                $input_count,
3174
                $this->php->max_input_vars
3175
            );
3176
        } else {
3177
            return '';
3178
        }
3179
    }
3180
3181
3182
3183
    /**
3184
     * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3185
     *
3186
     * @since 4.4.1
3187
     * @return void
3188
     */
3189
    public function recheck_values()
3190
    {
3191
        $this->_set_php_values();
3192
    }
3193
3194
3195
3196
}
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
    /**
3220
     *    class constructor
3221
     */
3222
    public function __construct()
3223
    {
3224
        $this->prices_displayed_including_taxes = true;
3225
    }
3226
}
3227
3228
3229
/**
3230
 * Holds all global messages configuration options.
3231
 *
3232
 * @package    EventEspresso/core/
3233
 * @subpackage config
3234
 * @author     Darren Ethier
3235
 * @since      4.27.rc
3236
 */
3237
class EE_Messages_Config extends EE_Config_Base
3238
{
3239
3240
    /**
3241
     * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3242
     * A value of 0 represents never deleting.  Default is 0.
3243
     *
3244
     * @var integer
3245
     */
3246
    public $delete_threshold;
3247
3248
    public function __construct() {
3249
        $this->delete_threshold = 0;
3250
    }
3251
}
3252
3253
3254
/**
3255
 * stores payment gateway info
3256
 *
3257
 * @deprecated
3258
 */
3259
class EE_Gateway_Config extends EE_Config_Base
3260
{
3261
3262
    /**
3263
     * Array with keys that are payment gateways slugs, and values are arrays
3264
     * with any config info the gateway wants to store
3265
     *
3266
     * @var array
3267
     */
3268
    public $payment_settings;
3269
3270
    /**
3271
     * Where keys are gateway slugs, and values are booleans indicating whether or not
3272
     * the gateway is stored in the uploads directory
3273
     *
3274
     * @var array
3275
     */
3276
    public $active_gateways;
3277
3278
3279
3280
    /**
3281
     *    class constructor
3282
     *
3283
     * @deprecated
3284
     */
3285
    public function __construct()
3286
    {
3287
        $this->payment_settings = array();
3288
        $this->active_gateways = array('Invoice' => false);
3289
    }
3290
}
3291
3292
// End of file EE_Config.core.php
3293
// Location: /core/EE_Config.core.php
3294