Completed
Branch BUG/11288/fix-datepicker (d15367)
by
unknown
108:07 queued 94:31
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 EE_Country $country
2231
     * @throws EE_Error
2232
     * @throws InvalidArgumentException
2233
     * @throws InvalidDataTypeException
2234
     * @throws InvalidInterfaceException
2235
     * @throws ReflectionException
2236
     */
2237
    public function setFromCountry(EE_Country $country)
2238
    {
2239
        $this->code    = $country->currency_code();    // currency code: USD, CAD, EUR
2240
        $this->name    = $country->currency_name_single();    // Dollar
2241
        $this->plural  = $country->currency_name_plural();    // Dollars
2242
        $this->sign    = $country->currency_sign();            // currency sign: $
2243
        $this->sign_b4 = $country->currency_sign_before();        // currency sign before or after: $TRUE  or  FALSE$
2244
        $this->dec_plc = $country->currency_decimal_places();    // decimal places: 2 = 0.00  3 = 0.000
2245
        $this->dec_mrk = $country->currency_decimal_mark();    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2246
        $this->thsnds  = $country->currency_thousands_separator();    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2247
    }
2248
}
2249
2250
2251
2252
/**
2253
 * Class for defining what's in the EE_Config relating to registration settings
2254
 */
2255
class EE_Registration_Config extends EE_Config_Base
2256
{
2257
2258
    /**
2259
     * Default registration status
2260
     *
2261
     * @var string $default_STS_ID
2262
     * eg 'RPP'
2263
     */
2264
    public $default_STS_ID;
2265
2266
2267
    /**
2268
     * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2269
     * registrations)
2270
     * @var int
2271
     */
2272
    public $default_maximum_number_of_tickets;
2273
2274
2275
    /**
2276
     * level of validation to apply to email addresses
2277
     *
2278
     * @var string $email_validation_level
2279
     * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2280
     */
2281
    public $email_validation_level;
2282
2283
    /**
2284
     *    whether or not to show alternate payment options during the reg process if payment status is pending
2285
     *
2286
     * @var boolean $show_pending_payment_options
2287
     */
2288
    public $show_pending_payment_options;
2289
2290
    /**
2291
     * Whether to skip the registration confirmation page
2292
     *
2293
     * @var boolean $skip_reg_confirmation
2294
     */
2295
    public $skip_reg_confirmation;
2296
2297
    /**
2298
     * an array of SPCO reg steps where:
2299
     *        the keys denotes the reg step order
2300
     *        each element consists of an array with the following elements:
2301
     *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2302
     *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2303
     *            "slug" => the URL param used to trigger the reg step
2304
     *
2305
     * @var array $reg_steps
2306
     */
2307
    public $reg_steps;
2308
2309
    /**
2310
     * Whether registration confirmation should be the last page of SPCO
2311
     *
2312
     * @var boolean $reg_confirmation_last
2313
     */
2314
    public $reg_confirmation_last;
2315
2316
    /**
2317
     * Whether or not to enable the EE Bot Trap
2318
     *
2319
     * @var boolean $use_bot_trap
2320
     */
2321
    public $use_bot_trap;
2322
2323
    /**
2324
     * Whether or not to encrypt some data sent by the EE Bot Trap
2325
     *
2326
     * @var boolean $use_encryption
2327
     */
2328
    public $use_encryption;
2329
2330
    /**
2331
     * Whether or not to use ReCaptcha
2332
     *
2333
     * @var boolean $use_captcha
2334
     */
2335
    public $use_captcha;
2336
2337
    /**
2338
     * ReCaptcha Theme
2339
     *
2340
     * @var string $recaptcha_theme
2341
     *    options: 'dark    ', 'light'
2342
     */
2343
    public $recaptcha_theme;
2344
2345
    /**
2346
     * ReCaptcha Type
2347
     *
2348
     * @var string $recaptcha_type
2349
     *    options: 'audio', 'image'
2350
     */
2351
    public $recaptcha_type;
2352
2353
    /**
2354
     * ReCaptcha language
2355
     *
2356
     * @var string $recaptcha_language
2357
     * eg 'en'
2358
     */
2359
    public $recaptcha_language;
2360
2361
    /**
2362
     * ReCaptcha public key
2363
     *
2364
     * @var string $recaptcha_publickey
2365
     */
2366
    public $recaptcha_publickey;
2367
2368
    /**
2369
     * ReCaptcha private key
2370
     *
2371
     * @var string $recaptcha_privatekey
2372
     */
2373
    public $recaptcha_privatekey;
2374
2375
    /**
2376
     * ReCaptcha width
2377
     *
2378
     * @var int $recaptcha_width
2379
     * @deprecated
2380
     */
2381
    public $recaptcha_width;
2382
2383
    /**
2384
     * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2385
     *
2386
     * @var boolean $track_invalid_checkout_access
2387
     */
2388
    protected $track_invalid_checkout_access = true;
2389
2390
2391
2392
    /**
2393
     *    class constructor
2394
     *
2395
     * @access    public
2396
     */
2397
    public function __construct()
2398
    {
2399
        // set default registration settings
2400
        $this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2401
        $this->email_validation_level = 'wp_default';
2402
        $this->show_pending_payment_options = true;
2403
        $this->skip_reg_confirmation = false;
2404
        $this->reg_steps = array();
2405
        $this->reg_confirmation_last = false;
2406
        $this->use_bot_trap = true;
2407
        $this->use_encryption = true;
2408
        $this->use_captcha = false;
2409
        $this->recaptcha_theme = 'light';
2410
        $this->recaptcha_type = 'image';
2411
        $this->recaptcha_language = 'en';
2412
        $this->recaptcha_publickey = null;
2413
        $this->recaptcha_privatekey = null;
2414
        $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...
2415
        $this->default_maximum_number_of_tickets = 10;
2416
    }
2417
2418
2419
2420
    /**
2421
     * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2422
     *
2423
     * @since 4.8.8.rc.019
2424
     */
2425
    public function do_hooks()
2426
    {
2427
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2428
        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2429
    }
2430
2431
2432
2433
    /**
2434
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_default_registration_status
2435
     * field matches the config setting for default_STS_ID.
2436
     */
2437
    public function set_default_reg_status_on_EEM_Event()
2438
    {
2439
        EEM_Event::set_default_reg_status($this->default_STS_ID);
2440
    }
2441
2442
2443
    /**
2444
     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2445
     * for Events matches the config setting for default_maximum_number_of_tickets
2446
     */
2447
    public function set_default_max_ticket_on_EEM_Event()
2448
    {
2449
        EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2450
    }
2451
2452
2453
2454
    /**
2455
     * @return boolean
2456
     */
2457
    public function track_invalid_checkout_access()
2458
    {
2459
        return $this->track_invalid_checkout_access;
2460
    }
2461
2462
2463
2464
    /**
2465
     * @param boolean $track_invalid_checkout_access
2466
     */
2467
    public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2468
    {
2469
        $this->track_invalid_checkout_access = filter_var(
2470
            $track_invalid_checkout_access,
2471
            FILTER_VALIDATE_BOOLEAN
2472
        );
2473
    }
2474
2475
2476
2477
}
2478
2479
2480
2481
/**
2482
 * Class for defining what's in the EE_Config relating to admin settings
2483
 */
2484
class EE_Admin_Config extends EE_Config_Base
2485
{
2486
2487
    /**
2488
     * @var boolean $use_personnel_manager
2489
     */
2490
    public $use_personnel_manager;
2491
2492
    /**
2493
     * @var boolean $use_dashboard_widget
2494
     */
2495
    public $use_dashboard_widget;
2496
2497
    /**
2498
     * @var int $events_in_dashboard
2499
     */
2500
    public $events_in_dashboard;
2501
2502
    /**
2503
     * @var boolean $use_event_timezones
2504
     */
2505
    public $use_event_timezones;
2506
2507
    /**
2508
     * @var boolean $use_full_logging
2509
     */
2510
    public $use_full_logging;
2511
2512
    /**
2513
     * @var string $log_file_name
2514
     */
2515
    public $log_file_name;
2516
2517
    /**
2518
     * @var string $debug_file_name
2519
     */
2520
    public $debug_file_name;
2521
2522
    /**
2523
     * @var boolean $use_remote_logging
2524
     */
2525
    public $use_remote_logging;
2526
2527
    /**
2528
     * @var string $remote_logging_url
2529
     */
2530
    public $remote_logging_url;
2531
2532
    /**
2533
     * @var boolean $show_reg_footer
2534
     */
2535
    public $show_reg_footer;
2536
2537
    /**
2538
     * @var string $affiliate_id
2539
     */
2540
    public $affiliate_id;
2541
2542
    /**
2543
     * help tours on or off (global setting)
2544
     *
2545
     * @var boolean
2546
     */
2547
    public $help_tour_activation;
2548
2549
    /**
2550
     * adds extra layer of encoding to session data to prevent serialization errors
2551
     * but is incompatible with some server configuration errors
2552
     * if you get "500 internal server errors" during registration, try turning this on
2553
     * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2554
     *
2555
     * @var boolean $encode_session_data
2556
     */
2557
    private $encode_session_data = false;
2558
2559
2560
2561
    /**
2562
     *    class constructor
2563
     *
2564
     * @access    public
2565
     */
2566
    public function __construct()
2567
    {
2568
        // set default general admin settings
2569
        $this->use_personnel_manager = true;
2570
        $this->use_dashboard_widget = true;
2571
        $this->events_in_dashboard = 30;
2572
        $this->use_event_timezones = false;
2573
        $this->use_full_logging = false;
2574
        $this->use_remote_logging = false;
2575
        $this->remote_logging_url = null;
2576
        $this->show_reg_footer = true;
2577
        $this->affiliate_id = 'default';
2578
        $this->help_tour_activation = true;
2579
        $this->encode_session_data = false;
2580
    }
2581
2582
2583
2584
    /**
2585
     * @param bool $reset
2586
     * @return string
2587
     */
2588 View Code Duplication
    public function log_file_name($reset = false)
2589
    {
2590
        if (empty($this->log_file_name) || $reset) {
2591
            $this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2592
            EE_Config::instance()->update_espresso_config(false, false);
2593
        }
2594
        return $this->log_file_name;
2595
    }
2596
2597
2598
2599
    /**
2600
     * @param bool $reset
2601
     * @return string
2602
     */
2603 View Code Duplication
    public function debug_file_name($reset = false)
2604
    {
2605
        if (empty($this->debug_file_name) || $reset) {
2606
            $this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2607
            EE_Config::instance()->update_espresso_config(false, false);
2608
        }
2609
        return $this->debug_file_name;
2610
    }
2611
2612
2613
2614
    /**
2615
     * @return string
2616
     */
2617
    public function affiliate_id()
2618
    {
2619
        return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2620
    }
2621
2622
2623
2624
    /**
2625
     * @return boolean
2626
     */
2627
    public function encode_session_data()
2628
    {
2629
        return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2630
    }
2631
2632
2633
2634
    /**
2635
     * @param boolean $encode_session_data
2636
     */
2637
    public function set_encode_session_data($encode_session_data)
2638
    {
2639
        $this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2640
    }
2641
2642
2643
2644
}
2645
2646
2647
2648
/**
2649
 * Class for defining what's in the EE_Config relating to template settings
2650
 */
2651
class EE_Template_Config extends EE_Config_Base
2652
{
2653
2654
    /**
2655
     * @var boolean $enable_default_style
2656
     */
2657
    public $enable_default_style;
2658
2659
    /**
2660
     * @var string $custom_style_sheet
2661
     */
2662
    public $custom_style_sheet;
2663
2664
    /**
2665
     * @var boolean $display_address_in_regform
2666
     */
2667
    public $display_address_in_regform;
2668
2669
    /**
2670
     * @var int $display_description_on_multi_reg_page
2671
     */
2672
    public $display_description_on_multi_reg_page;
2673
2674
    /**
2675
     * @var boolean $use_custom_templates
2676
     */
2677
    public $use_custom_templates;
2678
2679
    /**
2680
     * @var string $current_espresso_theme
2681
     */
2682
    public $current_espresso_theme;
2683
2684
    /**
2685
     * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2686
     */
2687
    public $EED_Ticket_Selector;
2688
2689
    /**
2690
     * @var EE_Event_Single_Config $EED_Event_Single
2691
     */
2692
    public $EED_Event_Single;
2693
2694
    /**
2695
     * @var EE_Events_Archive_Config $EED_Events_Archive
2696
     */
2697
    public $EED_Events_Archive;
2698
2699
2700
2701
    /**
2702
     *    class constructor
2703
     *
2704
     * @access    public
2705
     */
2706
    public function __construct()
2707
    {
2708
        // set default template settings
2709
        $this->enable_default_style = true;
2710
        $this->custom_style_sheet = null;
2711
        $this->display_address_in_regform = true;
2712
        $this->display_description_on_multi_reg_page = false;
2713
        $this->use_custom_templates = false;
2714
        $this->current_espresso_theme = 'Espresso_Arabica_2014';
2715
        $this->EED_Event_Single = null;
2716
        $this->EED_Events_Archive = null;
2717
        $this->EED_Ticket_Selector = null;
2718
    }
2719
2720
}
2721
2722
2723
2724
/**
2725
 * Class for defining what's in the EE_Config relating to map settings
2726
 */
2727
class EE_Map_Config extends EE_Config_Base
2728
{
2729
2730
    /**
2731
     * @var boolean $use_google_maps
2732
     */
2733
    public $use_google_maps;
2734
2735
    /**
2736
     * @var string $api_key
2737
     */
2738
    public $google_map_api_key;
2739
2740
    /**
2741
     * @var int $event_details_map_width
2742
     */
2743
    public $event_details_map_width;
2744
2745
    /**
2746
     * @var int $event_details_map_height
2747
     */
2748
    public $event_details_map_height;
2749
2750
    /**
2751
     * @var int $event_details_map_zoom
2752
     */
2753
    public $event_details_map_zoom;
2754
2755
    /**
2756
     * @var boolean $event_details_display_nav
2757
     */
2758
    public $event_details_display_nav;
2759
2760
    /**
2761
     * @var boolean $event_details_nav_size
2762
     */
2763
    public $event_details_nav_size;
2764
2765
    /**
2766
     * @var string $event_details_control_type
2767
     */
2768
    public $event_details_control_type;
2769
2770
    /**
2771
     * @var string $event_details_map_align
2772
     */
2773
    public $event_details_map_align;
2774
2775
    /**
2776
     * @var int $event_list_map_width
2777
     */
2778
    public $event_list_map_width;
2779
2780
    /**
2781
     * @var int $event_list_map_height
2782
     */
2783
    public $event_list_map_height;
2784
2785
    /**
2786
     * @var int $event_list_map_zoom
2787
     */
2788
    public $event_list_map_zoom;
2789
2790
    /**
2791
     * @var boolean $event_list_display_nav
2792
     */
2793
    public $event_list_display_nav;
2794
2795
    /**
2796
     * @var boolean $event_list_nav_size
2797
     */
2798
    public $event_list_nav_size;
2799
2800
    /**
2801
     * @var string $event_list_control_type
2802
     */
2803
    public $event_list_control_type;
2804
2805
    /**
2806
     * @var string $event_list_map_align
2807
     */
2808
    public $event_list_map_align;
2809
2810
2811
2812
    /**
2813
     *    class constructor
2814
     *
2815
     * @access    public
2816
     */
2817
    public function __construct()
2818
    {
2819
        // set default map settings
2820
        $this->use_google_maps = true;
2821
        $this->google_map_api_key = '';
2822
        // for event details pages (reg page)
2823
        $this->event_details_map_width = 585;            // ee_map_width_single
2824
        $this->event_details_map_height = 362;            // ee_map_height_single
2825
        $this->event_details_map_zoom = 14;            // ee_map_zoom_single
2826
        $this->event_details_display_nav = true;            // ee_map_nav_display_single
2827
        $this->event_details_nav_size = false;            // ee_map_nav_size_single
2828
        $this->event_details_control_type = 'default';        // ee_map_type_control_single
2829
        $this->event_details_map_align = 'center';            // ee_map_align_single
2830
        // for event list pages
2831
        $this->event_list_map_width = 300;            // ee_map_width
2832
        $this->event_list_map_height = 185;        // ee_map_height
2833
        $this->event_list_map_zoom = 12;            // ee_map_zoom
2834
        $this->event_list_display_nav = false;        // ee_map_nav_display
2835
        $this->event_list_nav_size = true;            // ee_map_nav_size
2836
        $this->event_list_control_type = 'dropdown';        // ee_map_type_control
2837
        $this->event_list_map_align = 'center';            // ee_map_align
2838
    }
2839
2840
}
2841
2842
2843
2844
/**
2845
 * stores Events_Archive settings
2846
 */
2847
class EE_Events_Archive_Config extends EE_Config_Base
2848
{
2849
2850
    public $display_status_banner;
2851
2852
    public $display_description;
2853
2854
    public $display_ticket_selector;
2855
2856
    public $display_datetimes;
2857
2858
    public $display_venue;
2859
2860
    public $display_expired_events;
2861
2862
    public $use_sortable_display_order;
2863
2864
    public $display_order_tickets;
2865
2866
    public $display_order_datetimes;
2867
2868
    public $display_order_event;
2869
2870
    public $display_order_venue;
2871
2872
2873
2874
    /**
2875
     *    class constructor
2876
     */
2877
    public function __construct()
2878
    {
2879
        $this->display_status_banner = 0;
2880
        $this->display_description = 1;
2881
        $this->display_ticket_selector = 0;
2882
        $this->display_datetimes = 1;
2883
        $this->display_venue = 0;
2884
        $this->display_expired_events = 0;
2885
        $this->use_sortable_display_order = false;
2886
        $this->display_order_tickets = 100;
2887
        $this->display_order_datetimes = 110;
2888
        $this->display_order_event = 120;
2889
        $this->display_order_venue = 130;
2890
    }
2891
}
2892
2893
2894
2895
/**
2896
 * Stores Event_Single_Config settings
2897
 */
2898
class EE_Event_Single_Config extends EE_Config_Base
2899
{
2900
2901
    public $display_status_banner_single;
2902
2903
    public $display_venue;
2904
2905
    public $use_sortable_display_order;
2906
2907
    public $display_order_tickets;
2908
2909
    public $display_order_datetimes;
2910
2911
    public $display_order_event;
2912
2913
    public $display_order_venue;
2914
2915
2916
2917
    /**
2918
     *    class constructor
2919
     */
2920
    public function __construct()
2921
    {
2922
        $this->display_status_banner_single = 0;
2923
        $this->display_venue = 1;
2924
        $this->use_sortable_display_order = false;
2925
        $this->display_order_tickets = 100;
2926
        $this->display_order_datetimes = 110;
2927
        $this->display_order_event = 120;
2928
        $this->display_order_venue = 130;
2929
    }
2930
}
2931
2932
2933
2934
/**
2935
 * Stores Ticket_Selector_Config settings
2936
 */
2937
class EE_Ticket_Selector_Config extends EE_Config_Base
2938
{
2939
2940
    /**
2941
     * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
2942
     */
2943
    const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
2944
2945
    /**
2946
     * constant to indicate that a datetime selector should only be shown for ticket selectors
2947
     * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
2948
     */
2949
    const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
2950
2951
    /**
2952
     * @var boolean $show_ticket_sale_columns
2953
     */
2954
    public $show_ticket_sale_columns;
2955
2956
    /**
2957
     * @var boolean $show_ticket_details
2958
     */
2959
    public $show_ticket_details;
2960
2961
    /**
2962
     * @var boolean $show_expired_tickets
2963
     */
2964
    public $show_expired_tickets;
2965
2966
    /**
2967
     * whether or not to display a dropdown box populated with event datetimes
2968
     * that toggles which tickets are displayed for a ticket selector.
2969
     * uses one of the *_DATETIME_SELECTOR constants defined above
2970
     *
2971
     * @var string $show_datetime_selector
2972
     */
2973
    private $show_datetime_selector = 'no_datetime_selector';
2974
2975
    /**
2976
     * the number of datetimes an event has to have before conditionally displaying a datetime selector
2977
     *
2978
     * @var int $datetime_selector_threshold
2979
     */
2980
    private $datetime_selector_threshold = 3;
2981
2982
2983
2984
    /**
2985
     *    class constructor
2986
     */
2987
    public function __construct()
2988
    {
2989
        $this->show_ticket_sale_columns = true;
2990
        $this->show_ticket_details = true;
2991
        $this->show_expired_tickets = true;
2992
        $this->show_datetime_selector = \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
2993
        $this->datetime_selector_threshold = 3;
2994
    }
2995
2996
2997
2998
    /**
2999
     * returns true if a datetime selector should be displayed
3000
     *
3001
     * @param array $datetimes
3002
     * @return bool
3003
     */
3004
    public function showDatetimeSelector(array $datetimes)
3005
    {
3006
        // if the settings are NOT: don't show OR below threshold, THEN active = true
3007
        return ! (
3008
            $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3009
            || (
3010
                $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3011
                && count($datetimes) < $this->getDatetimeSelectorThreshold()
3012
            )
3013
        );
3014
    }
3015
3016
3017
3018
    /**
3019
     * @return string
3020
     */
3021
    public function getShowDatetimeSelector()
3022
    {
3023
        return $this->show_datetime_selector;
3024
    }
3025
3026
3027
3028
    /**
3029
     * @param bool $keys_only
3030
     * @return array
3031
     */
3032
    public function getShowDatetimeSelectorOptions($keys_only = true)
3033
    {
3034
        return $keys_only
3035
            ? array(
3036
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3037
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3038
            )
3039
            : array(
3040
                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3041
                    'Do not show date & time filter', 'event_espresso'
3042
                ),
3043
                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3044
                    'Maybe show date & time filter', 'event_espresso'
3045
                ),
3046
            );
3047
    }
3048
3049
3050
3051
    /**
3052
     * @param string $show_datetime_selector
3053
     */
3054
    public function setShowDatetimeSelector($show_datetime_selector)
3055
    {
3056
        $this->show_datetime_selector = in_array(
3057
            $show_datetime_selector,
3058
            $this->getShowDatetimeSelectorOptions(),
3059
            true
3060
        )
3061
            ? $show_datetime_selector
3062
            : \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3063
    }
3064
3065
3066
3067
    /**
3068
     * @return int
3069
     */
3070
    public function getDatetimeSelectorThreshold()
3071
    {
3072
        return $this->datetime_selector_threshold;
3073
    }
3074
3075
3076
3077
3078
    /**
3079
     * @param int $datetime_selector_threshold
3080
     */
3081
    public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3082
    {
3083
        $datetime_selector_threshold = absint($datetime_selector_threshold);
3084
        $this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3085
    }
3086
3087
3088
3089
}
3090
3091
3092
3093
/**
3094
 * Stores any EE Environment values that are referenced through the code.
3095
 *
3096
 * @since       4.4.0
3097
 * @package     Event Espresso
3098
 * @subpackage  config
3099
 */
3100
class EE_Environment_Config extends EE_Config_Base
3101
{
3102
3103
    /**
3104
     * Hold any php environment variables that we want to track.
3105
     *
3106
     * @var stdClass;
3107
     */
3108
    public $php;
3109
3110
3111
3112
    /**
3113
     *    constructor
3114
     */
3115
    public function __construct()
3116
    {
3117
        $this->php = new stdClass();
3118
        $this->_set_php_values();
3119
    }
3120
3121
3122
3123
    /**
3124
     * This sets the php environment variables.
3125
     *
3126
     * @since 4.4.0
3127
     * @return void
3128
     */
3129
    protected function _set_php_values()
3130
    {
3131
        $this->php->max_input_vars = ini_get('max_input_vars');
3132
        $this->php->version = phpversion();
3133
    }
3134
3135
3136
3137
    /**
3138
     * helper method for determining whether input_count is
3139
     * reaching the potential maximum the server can handle
3140
     * according to max_input_vars
3141
     *
3142
     * @param int   $input_count the count of input vars.
3143
     * @return array {
3144
     *                           An array that represents whether available space and if no available space the error
3145
     *                           message.
3146
     * @type bool   $has_space   whether more inputs can be added.
3147
     * @type string $msg         Any message to be displayed.
3148
     *                           }
3149
     */
3150
    public function max_input_vars_limit_check($input_count = 0)
3151
    {
3152
        if (! empty($this->php->max_input_vars)
3153
            && ($input_count >= $this->php->max_input_vars)
3154
            && (PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3 && PHP_RELEASE_VERSION >= 9)
3155
        ) {
3156
            return sprintf(
3157
                __(
3158
                    '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.',
3159
                    'event_espresso'
3160
                ),
3161
                '<br>',
3162
                $input_count,
3163
                $this->php->max_input_vars
3164
            );
3165
        } else {
3166
            return '';
3167
        }
3168
    }
3169
3170
3171
3172
    /**
3173
     * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3174
     *
3175
     * @since 4.4.1
3176
     * @return void
3177
     */
3178
    public function recheck_values()
3179
    {
3180
        $this->_set_php_values();
3181
    }
3182
3183
3184
3185
}
3186
3187
3188
3189
/**
3190
 * Stores any options pertaining to taxes
3191
 *
3192
 * @since       4.9.13
3193
 * @package     Event Espresso
3194
 * @subpackage  config
3195
 */
3196
class EE_Tax_Config extends EE_Config_Base
3197
{
3198
3199
    /*
3200
     * flag to indicate whether or not to display ticket prices with the taxes included
3201
     *
3202
     * @var boolean $prices_displayed_including_taxes
3203
     */
3204
    public $prices_displayed_including_taxes;
3205
3206
3207
3208
    /**
3209
     *    class constructor
3210
     */
3211
    public function __construct()
3212
    {
3213
        $this->prices_displayed_including_taxes = true;
3214
    }
3215
}
3216
3217
3218
/**
3219
 * Holds all global messages configuration options.
3220
 *
3221
 * @package    EventEspresso/core/
3222
 * @subpackage config
3223
 * @author     Darren Ethier
3224
 * @since      4.27.rc
3225
 */
3226
class EE_Messages_Config extends EE_Config_Base
3227
{
3228
3229
    /**
3230
     * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3231
     * A value of 0 represents never deleting.  Default is 0.
3232
     *
3233
     * @var integer
3234
     */
3235
    public $delete_threshold;
3236
3237
    public function __construct() {
3238
        $this->delete_threshold = 0;
3239
    }
3240
}
3241
3242
3243
/**
3244
 * stores payment gateway info
3245
 *
3246
 * @deprecated
3247
 */
3248
class EE_Gateway_Config extends EE_Config_Base
3249
{
3250
3251
    /**
3252
     * Array with keys that are payment gateways slugs, and values are arrays
3253
     * with any config info the gateway wants to store
3254
     *
3255
     * @var array
3256
     */
3257
    public $payment_settings;
3258
3259
    /**
3260
     * Where keys are gateway slugs, and values are booleans indicating whether or not
3261
     * the gateway is stored in the uploads directory
3262
     *
3263
     * @var array
3264
     */
3265
    public $active_gateways;
3266
3267
3268
3269
    /**
3270
     *    class constructor
3271
     *
3272
     * @deprecated
3273
     */
3274
    public function __construct()
3275
    {
3276
        $this->payment_settings = array();
3277
        $this->active_gateways = array('Invoice' => false);
3278
    }
3279
}
3280
3281
// End of file EE_Config.core.php
3282
// Location: /core/EE_Config.core.php
3283