Completed
Branch ENHANCE/255/add-wp-version-to-... (b44276)
by
unknown
24:50 queued 16:56
created

EE_Registration_Config   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 383
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 383
rs 10
c 0
b 0
f 0
wmc 18
lcom 3
cbo 5

14 Methods

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

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

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

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

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

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

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

This class, trait or interface has been deprecated.

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

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

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

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

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

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

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

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

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

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