Admin
2 weeks ago
Ajax
2 weeks ago
Asset
2 weeks ago
Context
2 weeks ago
Customizer
2 weeks ago
Debug_Bar
2 weeks ago
Dialog
2 weeks ago
Documentation
2 weeks ago
Duplicate
2 weeks ago
Editor
2 weeks ago
Image
2 weeks ago
JSON_LD
2 weeks ago
Languages
2 weeks ago
Log
2 weeks ago
Meta
2 weeks ago
Models
2 weeks ago
PUE
2 weeks ago
Process
2 weeks ago
Promoter
2 weeks ago
REST
2 weeks ago
Repository
2 weeks ago
Service_Providers
2 weeks ago
Shortcode
2 weeks ago
Support
2 weeks ago
Tabbed_View
2 weeks ago
Tooltip
2 weeks ago
Traits
2 weeks ago
Utils
2 weeks ago
Validator
2 weeks ago
Widget
2 weeks ago
Abstract_Deactivation.php
2 weeks ago
Abstract_Plugin_Register.php
2 weeks ago
App_Shop.php
2 weeks ago
Assets.php
2 weeks ago
Assets_Pipeline.php
2 weeks ago
Autoloader.php
2 weeks ago
Cache.php
2 weeks ago
Cache_Listener.php
2 weeks ago
Changelog_Reader.php
2 weeks ago
Container.php
2 weeks ago
Context.php
2 weeks ago
Cost_Utils.php
2 weeks ago
Credits.php
2 weeks ago
Customizer.php
2 weeks ago
DB_Lock.php
2 weeks ago
Data.php
2 weeks ago
Date_Utils.php
2 weeks ago
Db.php
2 weeks ago
Debug.php
2 weeks ago
Dependency.php
2 weeks ago
Deprecation.php
2 weeks ago
Editor.php
2 weeks ago
Error.php
2 weeks ago
Exception.php
2 weeks ago
Extension.php
2 weeks ago
Extension_Loader.php
2 weeks ago
Feature_Detection.php
2 weeks ago
Field.php
2 weeks ago
Field_Conditional.php
2 weeks ago
Freemius.php
2 weeks ago
Log.php
2 weeks ago
Main.php
2 weeks ago
Notices.php
2 weeks ago
Plugin_Meta_Links.php
2 weeks ago
Plugins.php
2 weeks ago
Plugins_API.php
2 weeks ago
Post_History.php
2 weeks ago
Post_Transient.php
2 weeks ago
Promise.php
2 weeks ago
Repository.php
2 weeks ago
Rewrite.php
2 weeks ago
Settings.php
2 weeks ago
Settings_Manager.php
2 weeks ago
Settings_Tab.php
2 weeks ago
Simple_Table.php
2 weeks ago
Support.php
2 weeks ago
Tabbed_View.php
2 weeks ago
Template.php
2 weeks ago
Template_Factory.php
2 weeks ago
Template_Part_Cache.php
2 weeks ago
Templates.php
2 weeks ago
Terms.php
2 weeks ago
Timezones.php
2 weeks ago
Tracker.php
2 weeks ago
Updater.php
2 weeks ago
Validate.php
2 weeks ago
View_Helpers.php
2 weeks ago
Support.php
468 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Class for managing technical support components |
| 4 | */ |
| 5 | |
| 6 | // Don't load directly |
| 7 | if ( ! defined( 'ABSPATH' ) ) { |
| 8 | die( '-1' ); |
| 9 | } |
| 10 | |
| 11 | if ( ! class_exists( 'Tribe__Support' ) ) { |
| 12 | |
| 13 | class Tribe__Support { |
| 14 | |
| 15 | public static $support; |
| 16 | public $rewrite_rules_purged = false; |
| 17 | |
| 18 | /** |
| 19 | * @var Tribe__Support__Obfuscator |
| 20 | */ |
| 21 | protected $obfuscator; |
| 22 | |
| 23 | /** |
| 24 | * Fields listed here contain HTML and should be escaped before being |
| 25 | * printed. |
| 26 | * |
| 27 | * @var array |
| 28 | */ |
| 29 | protected $must_escape = [ |
| 30 | 'tribeEventsAfterHTML', |
| 31 | 'tribeEventsBeforeHTML', |
| 32 | ]; |
| 33 | |
| 34 | /** |
| 35 | * Field prefixes here should be partially obfuscated before being printed. |
| 36 | * |
| 37 | * @var array |
| 38 | */ |
| 39 | protected $must_obfuscate_prefixes = [ |
| 40 | 'pue_install_key_', |
| 41 | 'google_maps_js_api_key', |
| 42 | ]; |
| 43 | |
| 44 | private function __construct() { |
| 45 | /** |
| 46 | * Allows for customizing the list of fields by array key whose values must be HTML-escaped. |
| 47 | * |
| 48 | * @param array $must_escape An array of array keys corresponding to fields whose values must be HTML-escaped. |
| 49 | */ |
| 50 | $this->must_escape = (array) apply_filters( 'tribe_help_must_escape_fields', $this->must_escape ); |
| 51 | |
| 52 | add_action( 'tribe_help_pre_get_sections', [ $this, 'append_system_info' ], 10 ); |
| 53 | add_action( 'delete_option_rewrite_rules', [ $this, 'log_rewrite_rule_purge' ] ); |
| 54 | |
| 55 | add_action( 'rest_api_init', [ __CLASS__, 'create_sysinfo_endpoint' ] ); |
| 56 | add_action( 'wp_ajax_tribe_toggle_sysinfo_optin', [ __CLASS__, 'ajax_sysinfo_optin' ] ); |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * Display help tab info in events settings |
| 61 | * |
| 62 | * @param Tribe__Admin__Help_Page $help The Help Page Instance |
| 63 | */ |
| 64 | public function append_system_info( Tribe__Admin__Help_Page $help ) { |
| 65 | $help->add_section_content( 'system-info', $this->formattedSupportStats(), 10 ); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * Collect system information for support |
| 70 | * |
| 71 | * @return array of system data for support |
| 72 | */ |
| 73 | public function getSupportStats() { |
| 74 | global $wpdb; |
| 75 | $user = wp_get_current_user(); |
| 76 | |
| 77 | $plugins = []; |
| 78 | if ( function_exists( 'get_plugin_data' ) ) { |
| 79 | $plugins_raw = wp_get_active_and_valid_plugins(); |
| 80 | foreach ( $plugins_raw as $k => $v ) { |
| 81 | $plugin_details = get_plugin_data( $v ); |
| 82 | $plugin = $plugin_details['Name']; |
| 83 | if ( ! empty( $plugin_details['Version'] ) ) { |
| 84 | $plugin .= sprintf( ' version %s', $plugin_details['Version'] ); |
| 85 | } |
| 86 | if ( ! empty( $plugin_details['Author'] ) ) { |
| 87 | $plugin .= sprintf( ' by %s', $plugin_details['Author'] ); |
| 88 | } |
| 89 | if ( ! empty( $plugin_details['AuthorURI'] ) ) { |
| 90 | $plugin .= sprintf( ' (%s)', $plugin_details['AuthorURI'] ); |
| 91 | } |
| 92 | $plugins[] = $plugin; |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | $network_plugins = []; |
| 97 | if ( is_multisite() && function_exists( 'get_plugin_data' ) ) { |
| 98 | $plugins_raw = wp_get_active_network_plugins(); |
| 99 | foreach ( $plugins_raw as $k => $v ) { |
| 100 | $plugin_details = get_plugin_data( $v ); |
| 101 | $plugin = $plugin_details['Name']; |
| 102 | if ( ! empty( $plugin_details['Version'] ) ) { |
| 103 | $plugin .= sprintf( ' version %s', $plugin_details['Version'] ); |
| 104 | } |
| 105 | if ( ! empty( $plugin_details['Author'] ) ) { |
| 106 | $plugin .= sprintf( ' by %s', $plugin_details['Author'] ); |
| 107 | } |
| 108 | if ( ! empty( $plugin_details['AuthorURI'] ) ) { |
| 109 | $plugin .= sprintf( ' (%s)', $plugin_details['AuthorURI'] ); |
| 110 | } |
| 111 | $network_plugins[] = $plugin; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | $mu_plugins = []; |
| 116 | if ( function_exists( 'get_mu_plugins' ) ) { |
| 117 | $mu_plugins_raw = get_mu_plugins(); |
| 118 | foreach ( $mu_plugins_raw as $k => $v ) { |
| 119 | $plugin = $v['Name']; |
| 120 | if ( ! empty( $v['Version'] ) ) { |
| 121 | $plugin .= sprintf( ' version %s', $v['Version'] ); |
| 122 | } |
| 123 | if ( ! empty( $v['Author'] ) ) { |
| 124 | $plugin .= sprintf( ' by %s', $v['Author'] ); |
| 125 | } |
| 126 | if ( ! empty( $v['AuthorURI'] ) ) { |
| 127 | $plugin .= sprintf( ' (%s)', $v['AuthorURI'] ); |
| 128 | } |
| 129 | $mu_plugins[] = $plugin; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | $keys = apply_filters( 'tribe-pue-install-keys', [] ); |
| 134 | //Obfuscate the License Keys for Security |
| 135 | if ( is_array( $keys ) && ! empty( $keys ) ) { |
| 136 | $secure_keys = []; |
| 137 | foreach ( $keys as $plugin => $license ) { |
| 138 | $secure_keys[ $plugin ] = preg_replace( '/^(.{4}).*(.{4})$/', '$1' . str_repeat( '#', 32 ) . '$2', $license ); |
| 139 | } |
| 140 | $keys = $secure_keys; |
| 141 | } |
| 142 | |
| 143 | //Server |
| 144 | $server = explode( ' ', $_SERVER['SERVER_SOFTWARE'] ); |
| 145 | $server = explode( '/', reset( $server ) ); |
| 146 | |
| 147 | //PHP Information |
| 148 | $php_info = []; |
| 149 | $php_vars = [ |
| 150 | 'max_execution_time', |
| 151 | 'memory_limit', |
| 152 | 'upload_max_filesize', |
| 153 | 'post_max_size', |
| 154 | 'display_errors', |
| 155 | 'log_errors', |
| 156 | ]; |
| 157 | |
| 158 | foreach ( $php_vars as $php_var ) { |
| 159 | if ( isset( $wpdb->qm_php_vars ) && isset( $wpdb->qm_php_vars[ $php_var ] ) ) { |
| 160 | $val = $wpdb->qm_php_vars[ $php_var ]; |
| 161 | } else { |
| 162 | $val = ini_get( $php_var ); |
| 163 | } |
| 164 | $php_info[ $php_var ] = $val; |
| 165 | } |
| 166 | |
| 167 | $homepage = get_option( 'show_on_front' ); |
| 168 | $homepage_page_id = get_option( 'page_on_front' ); |
| 169 | |
| 170 | if ( 'page' === $homepage ) { |
| 171 | if ( -10 === (int) $homepage_page_id ) { |
| 172 | $homepage_page_id .= ' (Main Events Page)'; |
| 173 | } else { |
| 174 | $homepage_page_id .= ' (' . esc_html( get_the_title( $homepage_page_id ) ) . ')'; |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | $site_url = get_site_url(); |
| 179 | $systeminfo = [ |
| 180 | 'Home URL' => get_home_url(), |
| 181 | 'Site URL' => $site_url, |
| 182 | 'Site Language' => get_option( 'WPLANG' ) ? get_option( 'WPLANG' ) : esc_html__( 'English', 'tribe-common' ), |
| 183 | 'Character Set' => get_option( 'blog_charset' ), |
| 184 | 'Name' => $user->display_name, |
| 185 | 'Email' => $user->user_email, |
| 186 | 'Install keys' => $keys, |
| 187 | 'WordPress version' => get_bloginfo( 'version' ), |
| 188 | 'Permalink Structure' => $site_url . get_option( 'permalink_structure' ), |
| 189 | 'Your homepage displays' => $homepage, |
| 190 | 'Homepage page ID' => $homepage_page_id, |
| 191 | 'PHP version' => phpversion(), |
| 192 | 'PHP' => $php_info, |
| 193 | 'Server' => $server[0], |
| 194 | 'SAPI' => php_sapi_name(), |
| 195 | 'Plugins' => $plugins, |
| 196 | 'Network Plugins' => $network_plugins, |
| 197 | 'MU Plugins' => $mu_plugins, |
| 198 | 'Theme' => wp_get_theme()->get( 'Name' ), |
| 199 | 'Multisite' => is_multisite(), |
| 200 | 'Settings' => Tribe__Settings_Manager::get_options(), |
| 201 | 'WP Timezone' => get_option( 'timezone_string' ) ? get_option( 'timezone_string' ) : esc_html__( 'Unknown or not set', 'tribe-common' ), |
| 202 | 'WP GMT Offset' => get_option( 'gmt_offset' ) ? ' ' . get_option( 'gmt_offset' ) : esc_html__( 'Unknown or not set', 'tribe-common' ), |
| 203 | 'Default PHP Timezone' => date_default_timezone_get(), |
| 204 | 'WP Date Format' => get_option( 'date_format' ), |
| 205 | 'WP Time Format' => get_option( 'time_format' ), |
| 206 | 'Week Starts On' => get_option( 'start_of_week' ), |
| 207 | 'Common Library Dir' => $GLOBALS['tribe-common-info']['dir'], |
| 208 | 'Common Library Version' => $GLOBALS['tribe-common-info']['version'], |
| 209 | ]; |
| 210 | |
| 211 | if ( $this->rewrite_rules_purged ) { |
| 212 | $systeminfo['rewrite rules purged'] = esc_html__( 'Rewrite rules were purged on load of this help page. Chances are there is a rewrite rule flush occurring in a plugin or theme!', 'tribe-common' ); |
| 213 | } |
| 214 | |
| 215 | /** |
| 216 | * Allow for customization of the array of information that's turned into the "System Information" screen in the "Help" admin page. |
| 217 | * |
| 218 | * @param array $systeminfo The array of information turned into the "System Information" screen. |
| 219 | */ |
| 220 | $systeminfo = apply_filters( 'tribe-events-pro-support', $systeminfo ); |
| 221 | |
| 222 | return $systeminfo; |
| 223 | } |
| 224 | |
| 225 | /** |
| 226 | * Render system information into a pretty output |
| 227 | * |
| 228 | * @return string pretty HTML |
| 229 | */ |
| 230 | public function formattedSupportStats() { |
| 231 | $systeminfo = $this->getSupportStats(); |
| 232 | $output = ''; |
| 233 | $output .= '<dl class="support-stats">'; |
| 234 | |
| 235 | foreach ( $systeminfo as $k => $v ) { |
| 236 | |
| 237 | switch ( $k ) { |
| 238 | case 'name' : |
| 239 | case 'email' : |
| 240 | continue 2; |
| 241 | break; |
| 242 | case 'url' : |
| 243 | $v = sprintf( '<a href="%s">%s</a>', $v, $v ); |
| 244 | break; |
| 245 | } |
| 246 | |
| 247 | if ( is_array( $v ) ) { |
| 248 | $keys = array_keys( $v ); |
| 249 | $key = array_shift( $keys ); |
| 250 | $is_numeric_array = is_numeric( $key ); |
| 251 | unset( $keys ); |
| 252 | unset( $key ); |
| 253 | } |
| 254 | |
| 255 | $output .= sprintf( '<dt>%s</dt>', $k ); |
| 256 | if ( empty( $v ) ) { |
| 257 | $output .= '<dd class="support-stats-null">-</dd>'; |
| 258 | } elseif ( is_bool( $v ) ) { |
| 259 | $output .= sprintf( '<dd class="support-stats-bool">%s</dd>', $v ); |
| 260 | } elseif ( is_string( $v ) ) { |
| 261 | $output .= sprintf( '<dd class="support-stats-string">%s</dd>', $v ); |
| 262 | } elseif ( is_array( $v ) && $is_numeric_array ) { |
| 263 | $output .= sprintf( '<dd class="support-stats-array"><ul><li>%s</li></ul></dd>', join( '</li><li>', $v ) ); |
| 264 | } else { |
| 265 | $formatted_v = []; |
| 266 | foreach ( $v as $obj_key => $obj_val ) { |
| 267 | if ( in_array( $obj_key, $this->must_escape ) ) { |
| 268 | $obj_val = esc_html( $obj_val ); |
| 269 | } |
| 270 | |
| 271 | $obj_val = $this->obfuscator->obfuscate( $obj_key, $obj_val ); |
| 272 | |
| 273 | if ( is_array( $obj_val ) ) { |
| 274 | $formatted_v[] = sprintf( '<li>%s = <pre>%s</pre></li>', $obj_key, print_r( $obj_val, true ) ); |
| 275 | } else { |
| 276 | $formatted_v[] = sprintf( '<li>%s = %s</li>', $obj_key, $obj_val ); |
| 277 | } |
| 278 | } |
| 279 | $v = join( "\n", $formatted_v ); |
| 280 | $output .= sprintf( '<dd class="support-stats-object"><ul>%s</ul></dd>', print_r( $v, true ) ); |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | $output .= '</dl>'; |
| 285 | |
| 286 | return $output; |
| 287 | } |
| 288 | |
| 289 | /** |
| 290 | * Logs the occurrence of rewrite rule purging |
| 291 | */ |
| 292 | public function log_rewrite_rule_purge() { |
| 293 | $this->rewrite_rules_purged = true; |
| 294 | }//end log_rewrite_rule_purge |
| 295 | |
| 296 | /** |
| 297 | * Sets the obfuscator to be used. |
| 298 | * |
| 299 | * @param Tribe__Support__Obfuscator $obfuscator |
| 300 | */ |
| 301 | public function set_obfuscator( Tribe__Support__Obfuscator $obfuscator ) { |
| 302 | $this->obfuscator = $obfuscator; |
| 303 | } |
| 304 | |
| 305 | /** |
| 306 | * Creates Fields in Help Tab to Opt In to System Info |
| 307 | * |
| 308 | * @return string |
| 309 | */ |
| 310 | public static function opt_in() { |
| 311 | |
| 312 | $checked = ''; |
| 313 | $optin_key = get_option( 'tribe_systeminfo_optin' ); |
| 314 | if ( $optin_key ) { |
| 315 | $checked = 'checked'; |
| 316 | } |
| 317 | |
| 318 | $opt_in = '<p class="system-info"><input name="tribe_auto_sysinfo_opt_in" id="tribe_auto_sysinfo_opt_in" type="checkbox" value="optin" ' . esc_attr( $checked ) . '/><label for="tribe_auto_sysinfo_opt_in">' . esc_html__( 'Yes, automatically share my system information with The Events Calendar\'s support team', 'tribe-common' ) . '</label></p>'; |
| 319 | $opt_in .= '<p class="tooltip description">' . esc_html__( 'Your system information will only be used by The Events Calendar\'s support team. All information is stored securely. We do not share this information with any third parties.', 'tribe-common' ) . '</p>'; |
| 320 | $opt_in .= '<p class="tribe-sysinfo-optin-msg"></p>'; |
| 321 | |
| 322 | return $opt_in; |
| 323 | } |
| 324 | |
| 325 | /** |
| 326 | * Method to send back sysinfo |
| 327 | * |
| 328 | * @param $query |
| 329 | * |
| 330 | * @return string|void |
| 331 | * |
| 332 | */ |
| 333 | public static function sysinfo_query( $query ) { |
| 334 | |
| 335 | $optin_key = get_option( 'tribe_systeminfo_optin' ); |
| 336 | |
| 337 | if ( ! $optin_key ) { |
| 338 | wp_send_json_error( __( 'Invalid Key', 'tribe-common' ) ); |
| 339 | } |
| 340 | |
| 341 | $key = $query['key']; |
| 342 | if ( $key != $optin_key ) { |
| 343 | wp_send_json_error( __( 'Invalid Key', 'tribe-common' ) ); |
| 344 | } |
| 345 | |
| 346 | $support = Tribe__Support::getInstance(); |
| 347 | $systeminfo = $support->formattedSupportStats(); |
| 348 | |
| 349 | return $systeminfo; |
| 350 | } |
| 351 | |
| 352 | /* |
| 353 | * Create Unique Enpoint Per Site |
| 354 | */ |
| 355 | public static function create_sysinfo_endpoint() { |
| 356 | $optin_key = get_option( 'tribe_systeminfo_optin' ); |
| 357 | if ( $optin_key ) { |
| 358 | register_rest_route( |
| 359 | 'tribe_events/v2', |
| 360 | '/(?P<key>[a-z0-9\-]+)/sysinfo/', |
| 361 | [ |
| 362 | 'methods' => 'GET', |
| 363 | 'callback' => [ 'Tribe__Support', 'sysinfo_query' ], |
| 364 | 'permission_callback' => '__return_true', |
| 365 | ] |
| 366 | ); |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | /** |
| 371 | * Ajax Method to Create Unique Key and send to tec.com |
| 372 | */ |
| 373 | public static function ajax_sysinfo_optin() { |
| 374 | |
| 375 | if ( ! isset( $_POST['confirm'] ) || ! wp_verify_nonce( $_POST['confirm'], 'sysinfo_optin_nonce' ) ) { |
| 376 | wp_send_json_error( __( 'Permission Error', 'tribe-common' ) ); |
| 377 | } |
| 378 | |
| 379 | if ( 'generate' == $_POST['generate_key'] ) { |
| 380 | |
| 381 | $random = base_convert( rand( 0, getrandmax() ), 10, 36 ); |
| 382 | $optin_key = hash( 'sha1', $random ); |
| 383 | update_option( 'tribe_systeminfo_optin', $optin_key ); |
| 384 | |
| 385 | //Only Connect If a License Exists |
| 386 | $keys = apply_filters( 'tribe-pue-install-keys', [] ); |
| 387 | if ( is_array( $keys ) && ! empty( $keys ) ) { |
| 388 | Tribe__Support::send_sysinfo_key( $optin_key ); |
| 389 | } else { |
| 390 | wp_send_json_success( __( 'Unique System Info Key Generated', 'tribe-common' ) ); |
| 391 | } |
| 392 | |
| 393 | } elseif ( 'remove' == $_POST['generate_key'] ) { |
| 394 | $optin_key = get_option( 'tribe_systeminfo_optin' ); |
| 395 | |
| 396 | delete_option( 'tribe_systeminfo_optin' ); |
| 397 | |
| 398 | Tribe__Support::send_sysinfo_key( $optin_key, null, 'remove' ); |
| 399 | |
| 400 | } |
| 401 | |
| 402 | wp_send_json_error( __( 'Permission Error', 'tribe-common' ) ); |
| 403 | } |
| 404 | |
| 405 | /** |
| 406 | * Contact Tribe Website to Add SysInfo Key |
| 407 | * |
| 408 | * @param null $optin_key provide key for system info |
| 409 | * @param null $url domain of current site |
| 410 | * @param null $remove string used if removing $optin_key from tec.com |
| 411 | * @param null $pueadd boolean to disable messaging when coming from pue script |
| 412 | */ |
| 413 | public static function send_sysinfo_key( $optin_key = null, $url = null, $remove = null, $pueadd = false ) { |
| 414 | |
| 415 | $url = $url ? $url : urlencode( str_replace( [ 'http://', 'https://' ], '', get_site_url() ) ); |
| 416 | |
| 417 | $teccom_url = 'https://theeventscalendar.com/'; |
| 418 | |
| 419 | if ( defined( 'TEC_URL' ) ) { |
| 420 | $teccom_url = trailingslashit( TEC_URL ); |
| 421 | } |
| 422 | |
| 423 | $query = $teccom_url . 'wp-json/tribe_system/v2/customer-info/' . $optin_key . '/' . $url; |
| 424 | |
| 425 | if ( $remove ) { |
| 426 | $query .= '?status=remove'; |
| 427 | } |
| 428 | |
| 429 | $response = wp_remote_get( esc_url( $query ) ); |
| 430 | |
| 431 | $response = json_decode( wp_remote_retrieve_body( $response ) ); |
| 432 | |
| 433 | if ( ! $pueadd ) { |
| 434 | // make sure the response came back okay |
| 435 | if ( ! isset( $response->success ) ) { |
| 436 | //on error delete the key |
| 437 | delete_option( 'tribe_systeminfo_optin' ); |
| 438 | |
| 439 | //send error response |
| 440 | wp_send_json_error( $response ); |
| 441 | } |
| 442 | |
| 443 | wp_send_json_success( $response->data ); |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | |
| 448 | /****************** SINGLETON GUTS ******************/ |
| 449 | |
| 450 | /** |
| 451 | * Enforce Singleton Pattern |
| 452 | */ |
| 453 | private static $instance; |
| 454 | |
| 455 | |
| 456 | public static function getInstance() { |
| 457 | if ( null == self::$instance ) { |
| 458 | $instance = new self; |
| 459 | $instance->set_obfuscator( new Tribe__Support__Obfuscator( $instance->must_obfuscate_prefixes ) ); |
| 460 | self::$instance = $instance; |
| 461 | } |
| 462 | |
| 463 | return self::$instance; |
| 464 | } |
| 465 | } |
| 466 | |
| 467 | } |
| 468 |