monsterinsights_string_starts_with()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
c 3
b 0
f 0
nc 2
nop 2
dl 0
loc 6
rs 10
1
<?php
2
3
/**
4
 * Helper functions.
5
 *
6
 * @since 6.0.0
7
 *
8
 * @package MonsterInsights
9
 * @subpackage Helper
10
 * @author  Chris Christoff
11
 * TODO Go through this file and remove UA and dual tracking references/usages
12
 */
13
14
// Exit if accessed directly
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
function monsterinsights_get_url($medium = '', $campaign = '', $url = '', $escape = true)
20
{
21
    // Setup Campaign variables
22
    $source      = monsterinsights_is_pro_version() ? 'proplugin' : 'liteplugin';
23
    $medium      = !empty($medium) ? $medium : 'defaultmedium';
24
    $campaign    = !empty($campaign) ? $campaign : 'defaultcampaign';
25
    $content     = MONSTERINSIGHTS_VERSION;
26
    $default_url = monsterinsights_is_pro_version() ? '' : 'lite/';
27
    $url         = !empty($url) ? $url : 'https://www.monsterinsights.com/' . $default_url;
28
29
    // Put together redirect URL
30
    $url = add_query_arg(
31
        array(
32
            'utm_source'   => $source,   // Pro/Lite Plugin
33
            'utm_medium'   => sanitize_key($medium),   // Area of MonsterInsights (example Reports)
34
            'utm_campaign' => sanitize_key($campaign), // Which link (example eCommerce Report)
35
            'utm_content'  => $content,  // Version number of MI
36
        ),
37
        trailingslashit($url)
38
    );
39
40
    if ($escape) {
41
        return esc_url($url);
42
    } else {
43
        return $url;
44
    }
45
}
46
47
function monsterinsights_is_page_reload() {
48
	// Can't be a refresh without having a referrer
49
	if ( ! isset( $_SERVER['HTTP_REFERER'] ) ) {
50
		return false;
51
	}
52
53
	// IF the referrer is identical to the current page request, then it's a refresh
54
	return ( $_SERVER['HTTP_REFERER'] === home_url( $_SERVER['REQUEST_URI'] ) ); // phpcs:ignore
55
}
56
57
58
function monsterinsights_track_user( $user_id = - 1 ) {
59
	if ( $user_id === - 1 ) {
60
		$user = wp_get_current_user();
61
	} else {
62
		$user = new WP_User( $user_id );
63
	}
64
65
	$track_user = true;
66
	$roles      = monsterinsights_get_option( 'ignore_users', array() );
67
68
	if ( ! empty( $roles ) && is_array( $roles ) ) {
0 ignored issues
show
introduced by
The condition is_array($roles) is always false.
Loading history...
69
		foreach ( $roles as $role ) {
70
			if ( is_string( $role ) ) {
71
				if ( user_can( $user, $role ) ) {
72
					$track_user = false;
73
					break;
74
				}
75
			}
76
		}
77
	}
78
79
	$track_super_admin = apply_filters( 'monsterinsights_track_super_admins', false );
80
	if ( $user_id === - 1 && $track_super_admin === false && is_multisite() && is_super_admin() ) {
81
		$track_user = false;
82
	}
83
84
	// or if tracking code is not entered
85
	$tracking_id = monsterinsights_get_v4_id();
86
	if ( empty( $tracking_id ) ) {
87
		$track_user = false;
88
	}
89
90
	return apply_filters( 'monsterinsights_track_user', $track_user, $user );
91
}
92
93
/**
94
 * Skip tracking status.
95
 *
96
 * @return bool
97
 */
98
function monsterinsights_skip_tracking() {
99
	return (bool) apply_filters( 'monsterinsights_skip_tracking', false );
100
}
101
102
function monsterinsights_get_client_id( $payment_id = false ) {
103
	if ( is_object( $payment_id ) ) {
104
		$payment_id = $payment_id->ID;
105
	}
106
	$user_cid  = monsterinsights_get_uuid();
107
	$saved_cid = ! empty( $payment_id ) ? get_post_meta( $payment_id, '_yoast_gau_uuid', true ) : false;
108
109
	if ( ! empty( $payment_id ) && ! empty( $saved_cid ) ) {
110
		return $saved_cid;
111
	} elseif ( ! empty( $user_cid ) ) {
112
		return $user_cid;
113
	} else {
114
		return monsterinsights_generate_uuid();
115
	}
116
}
117
118
/**
119
 * Returns the Google Analytics clientId to store for later use
120
 *
121
 * @return bool|string False if cookie isn't set, GA UUID otherwise
122
 * @link  https://developers.google.com/analytics/devguides/collection/analyticsjs/domains#getClientId
123
 *
124
 * @since 6.0.0
125
 */
126
function monsterinsights_get_uuid() {
127
	if ( empty( $_COOKIE['_ga'] ) ) {
128
		return false;
129
	}
130
131
	/**
132
	 * Example cookie formats:
133
	 *
134
	 * GA1.2.XXXXXXX.YYYYY
135
	 * _ga=1.2.XXXXXXX.YYYYYY -- We want the XXXXXXX.YYYYYY part
136
	 *
137
	 * for AMP pages the format is sometimes GA1.3.amp-XXXXXXXXXXXXX-XXXXXXXX
138
	 * if the first page visited is AMP, the cookie may be in the format amp-XXXXXXXXXXXXX-XXXXXXXX
139
	 */
140
141
	$ga_cookie    = sanitize_text_field($_COOKIE['_ga']);
142
	$cookie_parts = explode( '.', $ga_cookie );
143
	if ( is_array( $cookie_parts ) && ! empty( $cookie_parts[2] ) ) {
144
		$cookie_parts = array_slice( $cookie_parts, 2 );
145
		$uuid         = implode( '.', $cookie_parts );
146
		if ( is_string( $uuid ) ) {
0 ignored issues
show
introduced by
The condition is_string($uuid) is always true.
Loading history...
147
			return $uuid;
148
		} else {
149
			return false;
150
		}
151
	} elseif ( 0 === strpos( $ga_cookie, 'amp-' ) ) {
152
		return $ga_cookie;
153
	} else {
154
		return false;
155
	}
156
}
157
158
/**
159
 * Gets GA Session Id (GA4 only) from cookies.
160
 *
161
 * @var string $measurement_id
162
 *   GA4 Measurement Id (Property Id). E.g., 'G-1YS1VWHG3V'.
163
 *
164
 * @return string|null
165
 *   Returns GA4 Session Id or NULL if cookie wasn't found.
166
 */
167
function monsterinsights_get_browser_session_id( $measurement_id ) {
168
169
	if ( ! is_string( $measurement_id ) ) {
0 ignored issues
show
introduced by
The condition is_string($measurement_id) is always true.
Loading history...
170
		return null;
171
	}
172
173
	// Cookie name example: '_ga_1YS1VWHG3V'.
174
	$cookie_name = '_ga_' . str_replace( 'G-', '', $measurement_id );
175
176
	if ( ! isset( $_COOKIE[ $cookie_name ] ) ) {
177
		return null;
178
	}
179
180
	// Cookie value example: 'GS1.1.1659710029.4.1.1659710504.0'.
181
	// Session Id:                  ^^^^^^^^^^.
182
	$cookie = sanitize_text_field( $_COOKIE[ $cookie_name ] );
183
	$parts = explode( '.', $cookie );
184
185
	if ( ! isset( $parts[2] ) ){
186
		return null;
187
	}
188
189
	return $parts[2];
190
}
191
192
/**
193
 * Generate UUID v4 function - needed to generate a CID when one isn't available
194
 *
195
 * @link http://www.stumiller.me/implementing-google-analytics-measurement-protocol-in-php-and-wordpress/
196
 *
197
 * @since 6.1.8
198
 * @return string
199
 */
200
function monsterinsights_generate_uuid() {
201
202
	return sprintf(
203
		'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
204
		// 32 bits for "time_low"
205
		mt_rand( 0, 0xffff ),
206
		mt_rand( 0, 0xffff ),
207
		// 16 bits for "time_mid"
208
		mt_rand( 0, 0xffff ),
209
		// 16 bits for "time_hi_and_version",
210
		// four most significant bits holds version number 4
211
		mt_rand( 0, 0x0fff ) | 0x4000,
212
		// 16 bits, 8 bits for "clk_seq_hi_res",
213
		// 8 bits for "clk_seq_low",
214
		// two most significant bits holds zero and one for variant DCE1.1
215
		mt_rand( 0, 0x3fff ) | 0x8000,
216
		// 48 bits for "node"
217
		mt_rand( 0, 0xffff ),
218
		mt_rand( 0, 0xffff ),
219
		mt_rand( 0, 0xffff )
220
	);
221
}
222
223
/**
224
 * Returns the Google Analytics clientId to store for later use
225
 *
226
 * @return GA UUID or error code.
0 ignored issues
show
Bug introduced by
The type GA was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
227
 * @since 6.0.0
228
 */
229
function monsterinsights_get_cookie( $debug = false ) {
230
	if ( empty( $_COOKIE['_ga'] ) ) {
231
		return ( $debug ) ? 'FCE' : false;
232
	}
233
234
	$ga_cookie    = sanitize_text_field( $_COOKIE['_ga'] );
235
	$cookie_parts = explode( '.', $ga_cookie );
236
	if ( is_array( $cookie_parts ) && ! empty( $cookie_parts[2] ) ) {
237
		$cookie_parts = array_slice( $cookie_parts, 2 );
238
		$uuid         = implode( '.', $cookie_parts );
239
		if ( is_string( $uuid ) ) {
0 ignored issues
show
introduced by
The condition is_string($uuid) is always true.
Loading history...
240
			return $ga_cookie;
241
		} else {
242
			return ( $debug ) ? 'FA' : false;
243
		}
244
	} elseif ( 0 === strpos( $ga_cookie, 'amp-' ) ) {
245
		return $ga_cookie;
246
	} else {
247
		return ( $debug ) ? 'FAE' : false;
248
	}
249
}
250
251
252
function monsterinsights_generate_ga_client_id() {
253
	return wp_rand( 100000000, 999999999 ) . '.' . time();
254
}
255
256
257
/**
258
 * Hours between two timestamps.
259
 *
260
 * @access public
261
 *
262
 * @param string $start Timestamp of start time (in seconds since Unix).
263
 * @param string $stop Timestamp of stop time (in seconds since Unix). Optional. If not used, current_time (in UTC 0 / GMT ) is used.
264
 *
265
 * @return int Hours between the two timestamps, rounded.
266
 * @since 6.0.0
267
 */
268
function monsterinsights_hours_between( $start, $stop = false ) {
269
	if ( $stop === false ) {
270
		$stop = time();
271
	}
272
273
	$diff  = (int) abs( $stop - $start );
274
	$hours = round( $diff / HOUR_IN_SECONDS );
275
276
	return $hours;
277
}
278
279
/**
280
 * Is This MonsterInsights Pro?
281
 *
282
 * We use this function monsterinsights_to determine if the install is a pro version or a lite version install of MonsterInsights.
283
 * If the install is a lite version we disable the install from admin functionality[1] for addons as WordPress.org requires us to,
284
 * we change the links for where to get support (wp.org forum for free; our site for pro), we use this determine what class to load as
285
 * the base class in addons (to avoid fatal errors) and we use this on the system info page to know what constants to display values for
286
 * as the lite and pro versions of our plugin have different constants (and names for those constants) you can declare and use.
287
 *
288
 * [1] Note: This is not "feature-locking" under GPL guidelines but rather something WordPress.org requires us to do to stay
289
 * in compliance with their rules. We wish we didn't have to do this, as in our oppinion this diminishes the user experience
290
 * of users installing our free and premium addons, and we'd love to turn this on for non-Pro installs, but we're not allowed to.
291
 * If WordPress.org ever changes their mind on this subject, we'd totally turn on that feature for Lite installs in a heartbeat.
292
 *
293
 * @return bool True if pro version.
294
 * @since 6.0.0
295
 * @access public
296
 *
297
 * @todo  Are we allowed to turn on admin installing if the user has to manually declare a PHP constant (and thus would not be on
298
 * either by default or via any sort of user interface)? If so, we could add a constant for forcing Pro version so that users can see
299
 * for themselves that we're not feature locking anything inside the plugin + it would make it easier for our team to test stuff (both via
300
 * Travis-CI but also when installing addons to test with the Lite version). Also this would allow for a better user experience for users
301
 * who want that feature.
302
 */
303
function monsterinsights_is_pro_version() {
304
	if ( class_exists( 'MonsterInsights' ) ) {
305
		return true;
306
	} else {
307
		return false;
308
	}
309
}
310
311
312
/**
313
 * Get the user roles of this WordPress blog
314
 *
315
 * @return array
316
 */
317
function monsterinsights_get_roles() {
318
	global $wp_roles;
319
320
	$all_roles = $wp_roles->roles;
321
	$roles     = array();
322
323
	/**
324
	 * Filter: 'editable_roles' - Allows filtering of the roles shown within the plugin (and elsewhere in WP as it's a WP filter)
325
	 *
326
	 * @api array $all_roles
327
	 */
328
	$editable_roles = apply_filters( 'editable_roles', $all_roles );
329
330
	foreach ( $editable_roles as $id => $name ) {
331
		$roles[ $id ] = translate_user_role( $name['name'] );
332
	}
333
334
	return $roles;
335
}
336
337
/**
338
 * Get the user roles which can manage options. Used to prevent these roles from getting unselected in the settings.
339
 *
340
 * @return array
341
 */
342
function monsterinsights_get_manage_options_roles() {
343
	global $wp_roles;
344
345
	$all_roles = $wp_roles->roles;
346
	$roles     = array();
347
348
	/**
349
	 * Filter: 'editable_roles' - Allows filtering of the roles shown within the plugin (and elsewhere in WP as it's a WP filter)
350
	 *
351
	 * @api array $all_roles
352
	 */
353
	$editable_roles = apply_filters( 'editable_roles', $all_roles );
354
355
	foreach ( $editable_roles as $id => $role ) {
356
		if ( isset( $role['capabilities']['manage_options'] ) && $role['capabilities']['manage_options'] ) {
357
			$roles[ $id ] = translate_user_role( $role['name'] );
358
		}
359
	}
360
361
	return $roles;
362
}
363
364
/** Need to escape in advance of passing in $text. */
365
function monsterinsights_get_message( $type = 'error', $text = '' ) {
366
	$div = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $div is dead and can be removed.
Loading history...
367
	if ( $type === 'error' || $type === 'alert' || $type === 'success' || $type === 'info' ) {
368
		$base = MonsterInsights();
369
370
		return $base->notices->display_inline_notice( 'monsterinsights_standard_notice', '', $text, $type, false, array( 'skip_message_escape' => true ) );
371
	} else {
372
		return '';
373
	}
374
}
375
376
function monsterinsights_is_dev_url( $url = '' ) {
377
378
	if ( empty( $url ) ) {
379
		return false;
380
	}
381
382
	// Trim it up
383
	$url = strtolower( trim( $url ) );
384
	// Need to get the host...so let's add the scheme so we can use parse_url
385
	if ( false === strpos( $url, 'http://' ) && false === strpos( $url, 'https://' ) ) {
386
		$url = 'http://' . $url;
387
	}
388
	$url_parts = parse_url( $url );
389
	$host      = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false;
390
	if ( ! empty( $url ) && ! empty( $host ) ) {
391
		if ( false !== ip2long( $host ) ) {
392
			if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
393
				return true;
394
			}
395
		} elseif ( 'localhost' === $host ) {
396
			return true;
397
		}
398
399
		$tlds_to_check = array( '.local', ':8888', ':8080', ':8081', '.invalid', '.example', '.test', '.dev' );
400
		foreach ( $tlds_to_check as $tld ) {
401
			if ( false !== strpos( $host, $tld ) ) {
402
				return true;
403
			}
404
		}
405
		if ( substr_count( $host, '.' ) > 1 ) {
406
			$subdomains_to_check = array( 'dev.', '*.staging.', 'beta.', 'test.' );
407
			foreach ( $subdomains_to_check as $subdomain ) {
408
				$subdomain = str_replace( '.', '(.)', $subdomain );
409
				$subdomain = str_replace( array( '*', '(.)' ), '(.*)', $subdomain );
410
				if ( preg_match( '/^(' . $subdomain . ')/', $host ) ) {
411
					return true;
412
					break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
413
				}
414
			}
415
		}
416
417
		if ( function_exists( 'wp_get_environment_type' ) ) {
418
			$env_type = wp_get_environment_type();
419
420
			if ( 'development' === $env_type || 'local' === $env_type ) {
421
				return true;
422
			}
423
		}
424
425
		if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL ) {
0 ignored issues
show
Bug introduced by
The constant WP_HTTP_BLOCK_EXTERNAL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
426
			if ( defined( 'WP_ACCESSIBLE_HOSTS' ) && WP_ACCESSIBLE_HOSTS ) {
0 ignored issues
show
Bug introduced by
The constant WP_ACCESSIBLE_HOSTS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
427
				$allowed_hosts = preg_split( '|,\s*|', WP_ACCESSIBLE_HOSTS );
428
429
				if ( is_array( $allowed_hosts ) && ! empty( $allowed_hosts ) ) {
430
					if ( ! in_array( '*.monsterinsights.com', $allowed_hosts, true ) || ! in_array( 'api.monsterinsights.com', $allowed_hosts, true ) ) {
431
						return true;
432
					}
433
				}
434
			}
435
436
			return true;
437
		}
438
	}
439
440
	return false;
441
}
442
443
// Set cookie to expire in 2 years
444
function monsterinsights_get_cookie_expiration_date( $time ) {
445
	return date( 'D, j F Y H:i:s', time() + $time );
446
}
447
448
function monsterinsights_string_ends_with( $string, $ending ) {
449
	$strlen    = strlen( $string );
450
	$endinglen = strlen( $ending );
451
	if ( $endinglen > $strlen ) {
452
		return false;
453
	}
454
455
	return substr_compare( $string, $ending, $strlen - $endinglen, $endinglen ) === 0;
456
}
457
458
function monsterinsights_string_starts_with( $string, $start ) {
459
	if ( ! is_string( $string ) || ! is_string( $start ) ) {
460
		return false;
461
	}
462
463
	return substr( $string, 0, strlen( $start ) ) === $start;
464
}
465
466
function monsterinsights_get_country_list( $translated = false ) {
467
	if ( $translated ) {
468
		$countries = array(
469
			''   => '',
470
			'US' => __( 'United States', 'google-analytics-for-wordpress' ),
471
			'CA' => __( 'Canada', 'google-analytics-for-wordpress' ),
472
			'GB' => __( 'United Kingdom', 'google-analytics-for-wordpress' ),
473
			'AF' => __( 'Afghanistan', 'google-analytics-for-wordpress' ),
474
			'AX' => __( '&#197;land Islands', 'google-analytics-for-wordpress' ),
475
			'AL' => __( 'Albania', 'google-analytics-for-wordpress' ),
476
			'DZ' => __( 'Algeria', 'google-analytics-for-wordpress' ),
477
			'AS' => __( 'American Samoa', 'google-analytics-for-wordpress' ),
478
			'AD' => __( 'Andorra', 'google-analytics-for-wordpress' ),
479
			'AO' => __( 'Angola', 'google-analytics-for-wordpress' ),
480
			'AI' => __( 'Anguilla', 'google-analytics-for-wordpress' ),
481
			'AQ' => __( 'Antarctica', 'google-analytics-for-wordpress' ),
482
			'AG' => __( 'Antigua and Barbuda', 'google-analytics-for-wordpress' ),
483
			'AR' => __( 'Argentina', 'google-analytics-for-wordpress' ),
484
			'AM' => __( 'Armenia', 'google-analytics-for-wordpress' ),
485
			'AW' => __( 'Aruba', 'google-analytics-for-wordpress' ),
486
			'AU' => __( 'Australia', 'google-analytics-for-wordpress' ),
487
			'AT' => __( 'Austria', 'google-analytics-for-wordpress' ),
488
			'AZ' => __( 'Azerbaijan', 'google-analytics-for-wordpress' ),
489
			'BS' => __( 'Bahamas', 'google-analytics-for-wordpress' ),
490
			'BH' => __( 'Bahrain', 'google-analytics-for-wordpress' ),
491
			'BD' => __( 'Bangladesh', 'google-analytics-for-wordpress' ),
492
			'BB' => __( 'Barbados', 'google-analytics-for-wordpress' ),
493
			'BY' => __( 'Belarus', 'google-analytics-for-wordpress' ),
494
			'BE' => __( 'Belgium', 'google-analytics-for-wordpress' ),
495
			'BZ' => __( 'Belize', 'google-analytics-for-wordpress' ),
496
			'BJ' => __( 'Benin', 'google-analytics-for-wordpress' ),
497
			'BM' => __( 'Bermuda', 'google-analytics-for-wordpress' ),
498
			'BT' => __( 'Bhutan', 'google-analytics-for-wordpress' ),
499
			'BO' => __( 'Bolivia', 'google-analytics-for-wordpress' ),
500
			'BQ' => __( 'Bonaire, Saint Eustatius and Saba', 'google-analytics-for-wordpress' ),
501
			'BA' => __( 'Bosnia and Herzegovina', 'google-analytics-for-wordpress' ),
502
			'BW' => __( 'Botswana', 'google-analytics-for-wordpress' ),
503
			'BV' => __( 'Bouvet Island', 'google-analytics-for-wordpress' ),
504
			'BR' => __( 'Brazil', 'google-analytics-for-wordpress' ),
505
			'IO' => __( 'British Indian Ocean Territory', 'google-analytics-for-wordpress' ),
506
			'BN' => __( 'Brunei Darrussalam', 'google-analytics-for-wordpress' ),
507
			'BG' => __( 'Bulgaria', 'google-analytics-for-wordpress' ),
508
			'BF' => __( 'Burkina Faso', 'google-analytics-for-wordpress' ),
509
			'BI' => __( 'Burundi', 'google-analytics-for-wordpress' ),
510
			'KH' => __( 'Cambodia', 'google-analytics-for-wordpress' ),
511
			'CM' => __( 'Cameroon', 'google-analytics-for-wordpress' ),
512
			'CV' => __( 'Cape Verde', 'google-analytics-for-wordpress' ),
513
			'KY' => __( 'Cayman Islands', 'google-analytics-for-wordpress' ),
514
			'CF' => __( 'Central African Republic', 'google-analytics-for-wordpress' ),
515
			'TD' => __( 'Chad', 'google-analytics-for-wordpress' ),
516
			'CL' => __( 'Chile', 'google-analytics-for-wordpress' ),
517
			'CN' => __( 'China', 'google-analytics-for-wordpress' ),
518
			'CX' => __( 'Christmas Island', 'google-analytics-for-wordpress' ),
519
			'CC' => __( 'Cocos Islands', 'google-analytics-for-wordpress' ),
520
			'CO' => __( 'Colombia', 'google-analytics-for-wordpress' ),
521
			'KM' => __( 'Comoros', 'google-analytics-for-wordpress' ),
522
			'CD' => __( 'Congo, Democratic People\'s Republic', 'google-analytics-for-wordpress' ),
523
			'CG' => __( 'Congo, Republic of', 'google-analytics-for-wordpress' ),
524
			'CK' => __( 'Cook Islands', 'google-analytics-for-wordpress' ),
525
			'CR' => __( 'Costa Rica', 'google-analytics-for-wordpress' ),
526
			'CI' => __( 'Cote d\'Ivoire', 'google-analytics-for-wordpress' ),
527
			'HR' => __( 'Croatia/Hrvatska', 'google-analytics-for-wordpress' ),
528
			'CU' => __( 'Cuba', 'google-analytics-for-wordpress' ),
529
			'CW' => __( 'Cura&Ccedil;ao', 'google-analytics-for-wordpress' ),
530
			'CY' => __( 'Cyprus', 'google-analytics-for-wordpress' ),
531
			'CZ' => __( 'Czechia', 'google-analytics-for-wordpress' ),
532
			'DK' => __( 'Denmark', 'google-analytics-for-wordpress' ),
533
			'DJ' => __( 'Djibouti', 'google-analytics-for-wordpress' ),
534
			'DM' => __( 'Dominica', 'google-analytics-for-wordpress' ),
535
			'DO' => __( 'Dominican Republic', 'google-analytics-for-wordpress' ),
536
			'TP' => __( 'East Timor', 'google-analytics-for-wordpress' ),
537
			'EC' => __( 'Ecuador', 'google-analytics-for-wordpress' ),
538
			'EG' => __( 'Egypt', 'google-analytics-for-wordpress' ),
539
			'GQ' => __( 'Equatorial Guinea', 'google-analytics-for-wordpress' ),
540
			'SV' => __( 'El Salvador', 'google-analytics-for-wordpress' ),
541
			'ER' => __( 'Eritrea', 'google-analytics-for-wordpress' ),
542
			'EE' => __( 'Estonia', 'google-analytics-for-wordpress' ),
543
			'ET' => __( 'Ethiopia', 'google-analytics-for-wordpress' ),
544
			'FK' => __( 'Falkland Islands', 'google-analytics-for-wordpress' ),
545
			'FO' => __( 'Faroe Islands', 'google-analytics-for-wordpress' ),
546
			'FJ' => __( 'Fiji', 'google-analytics-for-wordpress' ),
547
			'FI' => __( 'Finland', 'google-analytics-for-wordpress' ),
548
			'FR' => __( 'France', 'google-analytics-for-wordpress' ),
549
			'GF' => __( 'French Guiana', 'google-analytics-for-wordpress' ),
550
			'PF' => __( 'French Polynesia', 'google-analytics-for-wordpress' ),
551
			'TF' => __( 'French Southern Territories', 'google-analytics-for-wordpress' ),
552
			'GA' => __( 'Gabon', 'google-analytics-for-wordpress' ),
553
			'GM' => __( 'Gambia', 'google-analytics-for-wordpress' ),
554
			'GE' => __( 'Georgia', 'google-analytics-for-wordpress' ),
555
			'DE' => __( 'Germany', 'google-analytics-for-wordpress' ),
556
			'GR' => __( 'Greece', 'google-analytics-for-wordpress' ),
557
			'GH' => __( 'Ghana', 'google-analytics-for-wordpress' ),
558
			'GI' => __( 'Gibraltar', 'google-analytics-for-wordpress' ),
559
			'GL' => __( 'Greenland', 'google-analytics-for-wordpress' ),
560
			'GD' => __( 'Grenada', 'google-analytics-for-wordpress' ),
561
			'GP' => __( 'Guadeloupe', 'google-analytics-for-wordpress' ),
562
			'GU' => __( 'Guam', 'google-analytics-for-wordpress' ),
563
			'GT' => __( 'Guatemala', 'google-analytics-for-wordpress' ),
564
			'GG' => __( 'Guernsey', 'google-analytics-for-wordpress' ),
565
			'GN' => __( 'Guinea', 'google-analytics-for-wordpress' ),
566
			'GW' => __( 'Guinea-Bissau', 'google-analytics-for-wordpress' ),
567
			'GY' => __( 'Guyana', 'google-analytics-for-wordpress' ),
568
			'HT' => __( 'Haiti', 'google-analytics-for-wordpress' ),
569
			'HM' => __( 'Heard and McDonald Islands', 'google-analytics-for-wordpress' ),
570
			'VA' => __( 'Holy See (City Vatican State)', 'google-analytics-for-wordpress' ),
571
			'HN' => __( 'Honduras', 'google-analytics-for-wordpress' ),
572
			'HK' => __( 'Hong Kong', 'google-analytics-for-wordpress' ),
573
			'HU' => __( 'Hungary', 'google-analytics-for-wordpress' ),
574
			'IS' => __( 'Iceland', 'google-analytics-for-wordpress' ),
575
			'IN' => __( 'India', 'google-analytics-for-wordpress' ),
576
			'ID' => __( 'Indonesia', 'google-analytics-for-wordpress' ),
577
			'IR' => __( 'Iran', 'google-analytics-for-wordpress' ),
578
			'IQ' => __( 'Iraq', 'google-analytics-for-wordpress' ),
579
			'IE' => __( 'Ireland', 'google-analytics-for-wordpress' ),
580
			'IM' => __( 'Isle of Man', 'google-analytics-for-wordpress' ),
581
			'IL' => __( 'Israel', 'google-analytics-for-wordpress' ),
582
			'IT' => __( 'Italy', 'google-analytics-for-wordpress' ),
583
			'JM' => __( 'Jamaica', 'google-analytics-for-wordpress' ),
584
			'JP' => __( 'Japan', 'google-analytics-for-wordpress' ),
585
			'JE' => __( 'Jersey', 'google-analytics-for-wordpress' ),
586
			'JO' => __( 'Jordan', 'google-analytics-for-wordpress' ),
587
			'KZ' => __( 'Kazakhstan', 'google-analytics-for-wordpress' ),
588
			'KE' => __( 'Kenya', 'google-analytics-for-wordpress' ),
589
			'KI' => __( 'Kiribati', 'google-analytics-for-wordpress' ),
590
			'KW' => __( 'Kuwait', 'google-analytics-for-wordpress' ),
591
			'KG' => __( 'Kyrgyzstan', 'google-analytics-for-wordpress' ),
592
			'LA' => __( 'Lao People\'s Democratic Republic', 'google-analytics-for-wordpress' ),
593
			'LV' => __( 'Latvia', 'google-analytics-for-wordpress' ),
594
			'LB' => __( 'Lebanon', 'google-analytics-for-wordpress' ),
595
			'LS' => __( 'Lesotho', 'google-analytics-for-wordpress' ),
596
			'LR' => __( 'Liberia', 'google-analytics-for-wordpress' ),
597
			'LY' => __( 'Libyan Arab Jamahiriya', 'google-analytics-for-wordpress' ),
598
			'LI' => __( 'Liechtenstein', 'google-analytics-for-wordpress' ),
599
			'LT' => __( 'Lithuania', 'google-analytics-for-wordpress' ),
600
			'LU' => __( 'Luxembourg', 'google-analytics-for-wordpress' ),
601
			'MO' => __( 'Macau', 'google-analytics-for-wordpress' ),
602
			'MK' => __( 'Macedonia (FYROM)', 'google-analytics-for-wordpress' ),
603
			'MG' => __( 'Madagascar', 'google-analytics-for-wordpress' ),
604
			'MW' => __( 'Malawi', 'google-analytics-for-wordpress' ),
605
			'MY' => __( 'Malaysia', 'google-analytics-for-wordpress' ),
606
			'MV' => __( 'Maldives', 'google-analytics-for-wordpress' ),
607
			'ML' => __( 'Mali', 'google-analytics-for-wordpress' ),
608
			'MT' => __( 'Malta', 'google-analytics-for-wordpress' ),
609
			'MH' => __( 'Marshall Islands', 'google-analytics-for-wordpress' ),
610
			'MQ' => __( 'Martinique', 'google-analytics-for-wordpress' ),
611
			'MR' => __( 'Mauritania', 'google-analytics-for-wordpress' ),
612
			'MU' => __( 'Mauritius', 'google-analytics-for-wordpress' ),
613
			'YT' => __( 'Mayotte', 'google-analytics-for-wordpress' ),
614
			'MX' => __( 'Mexico', 'google-analytics-for-wordpress' ),
615
			'FM' => __( 'Micronesia', 'google-analytics-for-wordpress' ),
616
			'MD' => __( 'Moldova, Republic of', 'google-analytics-for-wordpress' ),
617
			'MC' => __( 'Monaco', 'google-analytics-for-wordpress' ),
618
			'MN' => __( 'Mongolia', 'google-analytics-for-wordpress' ),
619
			'ME' => __( 'Montenegro', 'google-analytics-for-wordpress' ),
620
			'MS' => __( 'Montserrat', 'google-analytics-for-wordpress' ),
621
			'MA' => __( 'Morocco', 'google-analytics-for-wordpress' ),
622
			'MZ' => __( 'Mozambique', 'google-analytics-for-wordpress' ),
623
			'MM' => __( 'Myanmar', 'google-analytics-for-wordpress' ),
624
			'NA' => __( 'Namibia', 'google-analytics-for-wordpress' ),
625
			'NR' => __( 'Nauru', 'google-analytics-for-wordpress' ),
626
			'NP' => __( 'Nepal', 'google-analytics-for-wordpress' ),
627
			'NL' => __( 'Netherlands', 'google-analytics-for-wordpress' ),
628
			'AN' => __( 'Netherlands Antilles', 'google-analytics-for-wordpress' ),
629
			'NC' => __( 'New Caledonia', 'google-analytics-for-wordpress' ),
630
			'NZ' => __( 'New Zealand', 'google-analytics-for-wordpress' ),
631
			'NI' => __( 'Nicaragua', 'google-analytics-for-wordpress' ),
632
			'NE' => __( 'Niger', 'google-analytics-for-wordpress' ),
633
			'NG' => __( 'Nigeria', 'google-analytics-for-wordpress' ),
634
			'NU' => __( 'Niue', 'google-analytics-for-wordpress' ),
635
			'NF' => __( 'Norfolk Island', 'google-analytics-for-wordpress' ),
636
			'KP' => __( 'North Korea', 'google-analytics-for-wordpress' ),
637
			'MP' => __( 'Northern Mariana Islands', 'google-analytics-for-wordpress' ),
638
			'NO' => __( 'Norway', 'google-analytics-for-wordpress' ),
639
			'OM' => __( 'Oman', 'google-analytics-for-wordpress' ),
640
			'PK' => __( 'Pakistan', 'google-analytics-for-wordpress' ),
641
			'PW' => __( 'Palau', 'google-analytics-for-wordpress' ),
642
			'PS' => __( 'Palestinian Territories', 'google-analytics-for-wordpress' ),
643
			'PA' => __( 'Panama', 'google-analytics-for-wordpress' ),
644
			'PG' => __( 'Papua New Guinea', 'google-analytics-for-wordpress' ),
645
			'PY' => __( 'Paraguay', 'google-analytics-for-wordpress' ),
646
			'PE' => __( 'Peru', 'google-analytics-for-wordpress' ),
647
			'PH' => __( 'Philippines', 'google-analytics-for-wordpress' ),
648
			'PN' => __( 'Pitcairn Island', 'google-analytics-for-wordpress' ),
649
			'PL' => __( 'Poland', 'google-analytics-for-wordpress' ),
650
			'PT' => __( 'Portugal', 'google-analytics-for-wordpress' ),
651
			'PR' => __( 'Puerto Rico', 'google-analytics-for-wordpress' ),
652
			'QA' => __( 'Qatar', 'google-analytics-for-wordpress' ),
653
			'XK' => __( 'Republic of Kosovo', 'google-analytics-for-wordpress' ),
654
			'RE' => __( 'Reunion Island', 'google-analytics-for-wordpress' ),
655
			'RO' => __( 'Romania', 'google-analytics-for-wordpress' ),
656
			'RU' => __( 'Russian Federation', 'google-analytics-for-wordpress' ),
657
			'RW' => __( 'Rwanda', 'google-analytics-for-wordpress' ),
658
			'BL' => __( 'Saint Barth&eacute;lemy', 'google-analytics-for-wordpress' ),
659
			'SH' => __( 'Saint Helena', 'google-analytics-for-wordpress' ),
660
			'KN' => __( 'Saint Kitts and Nevis', 'google-analytics-for-wordpress' ),
661
			'LC' => __( 'Saint Lucia', 'google-analytics-for-wordpress' ),
662
			'MF' => __( 'Saint Martin (French)', 'google-analytics-for-wordpress' ),
663
			'SX' => __( 'Saint Martin (Dutch)', 'google-analytics-for-wordpress' ),
664
			'PM' => __( 'Saint Pierre and Miquelon', 'google-analytics-for-wordpress' ),
665
			'VC' => __( 'Saint Vincent and the Grenadines', 'google-analytics-for-wordpress' ),
666
			'SM' => __( 'San Marino', 'google-analytics-for-wordpress' ),
667
			'ST' => __( 'S&atilde;o Tom&eacute; and Pr&iacute;ncipe', 'google-analytics-for-wordpress' ),
668
			'SA' => __( 'Saudi Arabia', 'google-analytics-for-wordpress' ),
669
			'SN' => __( 'Senegal', 'google-analytics-for-wordpress' ),
670
			'RS' => __( 'Serbia', 'google-analytics-for-wordpress' ),
671
			'SC' => __( 'Seychelles', 'google-analytics-for-wordpress' ),
672
			'SL' => __( 'Sierra Leone', 'google-analytics-for-wordpress' ),
673
			'SG' => __( 'Singapore', 'google-analytics-for-wordpress' ),
674
			'SK' => __( 'Slovak Republic', 'google-analytics-for-wordpress' ),
675
			'SI' => __( 'Slovenia', 'google-analytics-for-wordpress' ),
676
			'SB' => __( 'Solomon Islands', 'google-analytics-for-wordpress' ),
677
			'SO' => __( 'Somalia', 'google-analytics-for-wordpress' ),
678
			'ZA' => __( 'South Africa', 'google-analytics-for-wordpress' ),
679
			'GS' => __( 'South Georgia', 'google-analytics-for-wordpress' ),
680
			'KR' => __( 'South Korea', 'google-analytics-for-wordpress' ),
681
			'SS' => __( 'South Sudan', 'google-analytics-for-wordpress' ),
682
			'ES' => __( 'Spain', 'google-analytics-for-wordpress' ),
683
			'LK' => __( 'Sri Lanka', 'google-analytics-for-wordpress' ),
684
			'SD' => __( 'Sudan', 'google-analytics-for-wordpress' ),
685
			'SR' => __( 'Suriname', 'google-analytics-for-wordpress' ),
686
			'SJ' => __( 'Svalbard and Jan Mayen Islands', 'google-analytics-for-wordpress' ),
687
			'SZ' => __( 'Swaziland', 'google-analytics-for-wordpress' ),
688
			'SE' => __( 'Sweden', 'google-analytics-for-wordpress' ),
689
			'CH' => __( 'Switzerland', 'google-analytics-for-wordpress' ),
690
			'SY' => __( 'Syrian Arab Republic', 'google-analytics-for-wordpress' ),
691
			'TW' => __( 'Taiwan', 'google-analytics-for-wordpress' ),
692
			'TJ' => __( 'Tajikistan', 'google-analytics-for-wordpress' ),
693
			'TZ' => __( 'Tanzania', 'google-analytics-for-wordpress' ),
694
			'TH' => __( 'Thailand', 'google-analytics-for-wordpress' ),
695
			'TL' => __( 'Timor-Leste', 'google-analytics-for-wordpress' ),
696
			'TG' => __( 'Togo', 'google-analytics-for-wordpress' ),
697
			'TK' => __( 'Tokelau', 'google-analytics-for-wordpress' ),
698
			'TO' => __( 'Tonga', 'google-analytics-for-wordpress' ),
699
			'TT' => __( 'Trinidad and Tobago', 'google-analytics-for-wordpress' ),
700
			'TN' => __( 'Tunisia', 'google-analytics-for-wordpress' ),
701
			'TR' => __( 'Turkey', 'google-analytics-for-wordpress' ),
702
			'TM' => __( 'Turkmenistan', 'google-analytics-for-wordpress' ),
703
			'TC' => __( 'Turks and Caicos Islands', 'google-analytics-for-wordpress' ),
704
			'TV' => __( 'Tuvalu', 'google-analytics-for-wordpress' ),
705
			'UG' => __( 'Uganda', 'google-analytics-for-wordpress' ),
706
			'UA' => __( 'Ukraine', 'google-analytics-for-wordpress' ),
707
			'AE' => __( 'United Arab Emirates', 'google-analytics-for-wordpress' ),
708
			'UY' => __( 'Uruguay', 'google-analytics-for-wordpress' ),
709
			'UM' => __( 'US Minor Outlying Islands', 'google-analytics-for-wordpress' ),
710
			'UZ' => __( 'Uzbekistan', 'google-analytics-for-wordpress' ),
711
			'VU' => __( 'Vanuatu', 'google-analytics-for-wordpress' ),
712
			'VE' => __( 'Venezuela', 'google-analytics-for-wordpress' ),
713
			'VN' => __( 'Vietnam', 'google-analytics-for-wordpress' ),
714
			'VG' => __( 'Virgin Islands (British)', 'google-analytics-for-wordpress' ),
715
			'VI' => __( 'Virgin Islands (USA)', 'google-analytics-for-wordpress' ),
716
			'WF' => __( 'Wallis and Futuna Islands', 'google-analytics-for-wordpress' ),
717
			'EH' => __( 'Western Sahara', 'google-analytics-for-wordpress' ),
718
			'WS' => __( 'Western Samoa', 'google-analytics-for-wordpress' ),
719
			'YE' => __( 'Yemen', 'google-analytics-for-wordpress' ),
720
			'ZM' => __( 'Zambia', 'google-analytics-for-wordpress' ),
721
			'ZW' => __( 'Zimbabwe', 'google-analytics-for-wordpress' ),
722
			'ZZ' => __( 'Unknown Country', 'google-analytics-for-wordpress' ),
723
		);
724
	} else {
725
		$countries = array(
726
			''   => '',
727
			'US' => 'United States',
728
			'CA' => 'Canada',
729
			'GB' => 'United Kingdom',
730
			'AF' => 'Afghanistan',
731
			'AX' => '&#197;land Islands',
732
			'AL' => 'Albania',
733
			'DZ' => 'Algeria',
734
			'AS' => 'American Samoa',
735
			'AD' => 'Andorra',
736
			'AO' => 'Angola',
737
			'AI' => 'Anguilla',
738
			'AQ' => 'Antarctica',
739
			'AG' => 'Antigua and Barbuda',
740
			'AR' => 'Argentina',
741
			'AM' => 'Armenia',
742
			'AW' => 'Aruba',
743
			'AU' => 'Australia',
744
			'AT' => 'Austria',
745
			'AZ' => 'Azerbaijan',
746
			'BS' => 'Bahamas',
747
			'BH' => 'Bahrain',
748
			'BD' => 'Bangladesh',
749
			'BB' => 'Barbados',
750
			'BY' => 'Belarus',
751
			'BE' => 'Belgium',
752
			'BZ' => 'Belize',
753
			'BJ' => 'Benin',
754
			'BM' => 'Bermuda',
755
			'BT' => 'Bhutan',
756
			'BO' => 'Bolivia',
757
			'BQ' => 'Bonaire, Saint Eustatius and Saba',
758
			'BA' => 'Bosnia and Herzegovina',
759
			'BW' => 'Botswana',
760
			'BV' => 'Bouvet Island',
761
			'BR' => 'Brazil',
762
			'IO' => 'British Indian Ocean Territory',
763
			'BN' => 'Brunei Darrussalam',
764
			'BG' => 'Bulgaria',
765
			'BF' => 'Burkina Faso',
766
			'BI' => 'Burundi',
767
			'KH' => 'Cambodia',
768
			'CM' => 'Cameroon',
769
			'CV' => 'Cape Verde',
770
			'KY' => 'Cayman Islands',
771
			'CF' => 'Central African Republic',
772
			'TD' => 'Chad',
773
			'CL' => 'Chile',
774
			'CN' => 'China',
775
			'CX' => 'Christmas Island',
776
			'CC' => 'Cocos Islands',
777
			'CO' => 'Colombia',
778
			'KM' => 'Comoros',
779
			'CD' => 'Congo, Democratic People\'s Republic',
780
			'CG' => 'Congo, Republic of',
781
			'CK' => 'Cook Islands',
782
			'CR' => 'Costa Rica',
783
			'CI' => 'Cote d\'Ivoire',
784
			'HR' => 'Croatia/Hrvatska',
785
			'CU' => 'Cuba',
786
			'CW' => 'Cura&Ccedil;ao',
787
			'CY' => 'Cyprus',
788
			'CZ' => 'Czechia',
789
			'DK' => 'Denmark',
790
			'DJ' => 'Djibouti',
791
			'DM' => 'Dominica',
792
			'DO' => 'Dominican Republic',
793
			'TP' => 'East Timor',
794
			'EC' => 'Ecuador',
795
			'EG' => 'Egypt',
796
			'GQ' => 'Equatorial Guinea',
797
			'SV' => 'El Salvador',
798
			'ER' => 'Eritrea',
799
			'EE' => 'Estonia',
800
			'ET' => 'Ethiopia',
801
			'FK' => 'Falkland Islands',
802
			'FO' => 'Faroe Islands',
803
			'FJ' => 'Fiji',
804
			'FI' => 'Finland',
805
			'FR' => 'France',
806
			'GF' => 'French Guiana',
807
			'PF' => 'French Polynesia',
808
			'TF' => 'French Southern Territories',
809
			'GA' => 'Gabon',
810
			'GM' => 'Gambia',
811
			'GE' => 'Georgia',
812
			'DE' => 'Germany',
813
			'GR' => 'Greece',
814
			'GH' => 'Ghana',
815
			'GI' => 'Gibraltar',
816
			'GL' => 'Greenland',
817
			'GD' => 'Grenada',
818
			'GP' => 'Guadeloupe',
819
			'GU' => 'Guam',
820
			'GT' => 'Guatemala',
821
			'GG' => 'Guernsey',
822
			'GN' => 'Guinea',
823
			'GW' => 'Guinea-Bissau',
824
			'GY' => 'Guyana',
825
			'HT' => 'Haiti',
826
			'HM' => 'Heard and McDonald Islands',
827
			'VA' => 'Holy See (City Vatican State)',
828
			'HN' => 'Honduras',
829
			'HK' => 'Hong Kong',
830
			'HU' => 'Hungary',
831
			'IS' => 'Iceland',
832
			'IN' => 'India',
833
			'ID' => 'Indonesia',
834
			'IR' => 'Iran',
835
			'IQ' => 'Iraq',
836
			'IE' => 'Ireland',
837
			'IM' => 'Isle of Man',
838
			'IL' => 'Israel',
839
			'IT' => 'Italy',
840
			'JM' => 'Jamaica',
841
			'JP' => 'Japan',
842
			'JE' => 'Jersey',
843
			'JO' => 'Jordan',
844
			'KZ' => 'Kazakhstan',
845
			'KE' => 'Kenya',
846
			'KI' => 'Kiribati',
847
			'KW' => 'Kuwait',
848
			'KG' => 'Kyrgyzstan',
849
			'LA' => 'Lao People\'s Democratic Republic',
850
			'LV' => 'Latvia',
851
			'LB' => 'Lebanon',
852
			'LS' => 'Lesotho',
853
			'LR' => 'Liberia',
854
			'LY' => 'Libyan Arab Jamahiriya',
855
			'LI' => 'Liechtenstein',
856
			'LT' => 'Lithuania',
857
			'LU' => 'Luxembourg',
858
			'MO' => 'Macau',
859
			'MK' => 'Macedonia',
860
			'MG' => 'Madagascar',
861
			'MW' => 'Malawi',
862
			'MY' => 'Malaysia',
863
			'MV' => 'Maldives',
864
			'ML' => 'Mali',
865
			'MT' => 'Malta',
866
			'MH' => 'Marshall Islands',
867
			'MQ' => 'Martinique',
868
			'MR' => 'Mauritania',
869
			'MU' => 'Mauritius',
870
			'YT' => 'Mayotte',
871
			'MX' => 'Mexico',
872
			'FM' => 'Micronesia',
873
			'MD' => 'Moldova, Republic of',
874
			'MC' => 'Monaco',
875
			'MN' => 'Mongolia',
876
			'ME' => 'Montenegro',
877
			'MS' => 'Montserrat',
878
			'MA' => 'Morocco',
879
			'MZ' => 'Mozambique',
880
			'MM' => 'Myanmar (Burma)',
881
			'NA' => 'Namibia',
882
			'NR' => 'Nauru',
883
			'NP' => 'Nepal',
884
			'NL' => 'Netherlands',
885
			'AN' => 'Netherlands Antilles',
886
			'NC' => 'New Caledonia',
887
			'NZ' => 'New Zealand',
888
			'NI' => 'Nicaragua',
889
			'NE' => 'Niger',
890
			'NG' => 'Nigeria',
891
			'NU' => 'Niue',
892
			'NF' => 'Norfolk Island',
893
			'KP' => 'North Korea',
894
			'MP' => 'Northern Mariana Islands',
895
			'NO' => 'Norway',
896
			'OM' => 'Oman',
897
			'PK' => 'Pakistan',
898
			'PW' => 'Palau',
899
			'PS' => 'Palestinian Territories',
900
			'PA' => 'Panama',
901
			'PG' => 'Papua New Guinea',
902
			'PY' => 'Paraguay',
903
			'PE' => 'Peru',
904
			'PH' => 'Philippines',
905
			'PN' => 'Pitcairn Island',
906
			'PL' => 'Poland',
907
			'PT' => 'Portugal',
908
			'PR' => 'Puerto Rico',
909
			'QA' => 'Qatar',
910
			'XK' => 'Republic of Kosovo',
911
			'RE' => 'Reunion Island',
912
			'RO' => 'Romania',
913
			'RU' => 'Russia',
914
			'RW' => 'Rwanda',
915
			'BL' => 'Saint Barth&eacute;lemy',
916
			'SH' => 'Saint Helena',
917
			'KN' => 'Saint Kitts and Nevis',
918
			'LC' => 'Saint Lucia',
919
			'MF' => 'Saint Martin (French)',
920
			'SX' => 'Saint Martin (Dutch)',
921
			'PM' => 'Saint Pierre and Miquelon',
922
			'VC' => 'Saint Vincent and the Grenadines',
923
			'SM' => 'San Marino',
924
			'ST' => 'S&atilde;o Tom&eacute; and Pr&iacute;ncipe',
925
			'SA' => 'Saudi Arabia',
926
			'SN' => 'Senegal',
927
			'RS' => 'Serbia',
928
			'SC' => 'Seychelles',
929
			'SL' => 'Sierra Leone',
930
			'SG' => 'Singapore',
931
			'SK' => 'Slovak Republic',
932
			'SI' => 'Slovenia',
933
			'SB' => 'Solomon Islands',
934
			'SO' => 'Somalia',
935
			'ZA' => 'South Africa',
936
			'GS' => 'South Georgia',
937
			'KR' => 'South Korea',
938
			'SS' => 'South Sudan',
939
			'ES' => 'Spain',
940
			'LK' => 'Sri Lanka',
941
			'SD' => 'Sudan',
942
			'SR' => 'Suriname',
943
			'SJ' => 'Svalbard and Jan Mayen Islands',
944
			'SZ' => 'Swaziland',
945
			'SE' => 'Sweden',
946
			'CH' => 'Switzerland',
947
			'SY' => 'Syrian Arab Republic',
948
			'TW' => 'Taiwan',
949
			'TJ' => 'Tajikistan',
950
			'TZ' => 'Tanzania',
951
			'TH' => 'Thailand',
952
			'TL' => 'Timor-Leste',
953
			'TG' => 'Togo',
954
			'TK' => 'Tokelau',
955
			'TO' => 'Tonga',
956
			'TT' => 'Trinidad and Tobago',
957
			'TN' => 'Tunisia',
958
			'TR' => 'Turkey',
959
			'TM' => 'Turkmenistan',
960
			'TC' => 'Turks and Caicos Islands',
961
			'TV' => 'Tuvalu',
962
			'UG' => 'Uganda',
963
			'UA' => 'Ukraine',
964
			'AE' => 'United Arab Emirates',
965
			'UY' => 'Uruguay',
966
			'UM' => 'US Minor Outlying Islands',
967
			'UZ' => 'Uzbekistan',
968
			'VU' => 'Vanuatu',
969
			'VE' => 'Venezuela',
970
			'VN' => 'Vietnam',
971
			'VG' => 'Virgin Islands (British)',
972
			'VI' => 'Virgin Islands (USA)',
973
			'WF' => 'Wallis and Futuna Islands',
974
			'EH' => 'Western Sahara',
975
			'WS' => 'Western Samoa',
976
			'YE' => 'Yemen',
977
			'ZM' => 'Zambia',
978
			'ZW' => 'Zimbabwe',
979
			'ZZ' => 'Unknown Country',
980
		);
981
	}
982
983
	return $countries;
984
}
985
986
function monsterinsights_get_api_url() {
987
	return apply_filters( 'monsterinsights_get_api_url', 'api.monsterinsights.com/v2/' );
988
}
989
990
function monsterinsights_get_licensing_url() {
991
	$licensing_website = apply_filters( 'monsterinsights_get_licensing_url', 'https://www.monsterinsights.com' );
992
    return $licensing_website . '/license-api';
993
}
994
995
/**
996
 * Queries the remote URL via wp_remote_post and returns a json decoded response.
997
 *
998
 * @param string $action The name of the $_POST action var.
999
 * @param array  $body The content to retrieve from the remote URL.
1000
 * @param array  $headers The headers to send to the remote URL.
1001
 * @param string $return_format The format for returning content from the remote URL.
1002
 *
1003
 * @return string|bool          Json decoded response on success, false on failure.
1004
 * @since 6.0.0
1005
 */
1006
function monsterinsights_perform_remote_request( $action, $body = array(), $headers = array(), $return_format = 'json' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $return_format is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1006
function monsterinsights_perform_remote_request( $action, $body = array(), $headers = array(), /** @scrutinizer ignore-unused */ $return_format = 'json' ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1007
1008
    $key = is_network_admin() ? MonsterInsights()->license->get_network_license_key() : MonsterInsights()->license->get_site_license_key();
0 ignored issues
show
Bug Best Practice introduced by
The property $license is declared protected in MonsterInsights_Lite. Since you implement __get, consider adding a @property or @property-read.
Loading history...
1009
1010
    // Build the body of the request.
1011
    $query_params = wp_parse_args(
1012
        $body,
1013
        array(
1014
            'tgm-updater-action'     => $action,
1015
            'tgm-updater-key'        => $key,
1016
            'tgm-updater-wp-version' => get_bloginfo( 'version' ),
1017
            'tgm-updater-referer'    => site_url(),
1018
            'tgm-updater-mi-version' => MONSTERINSIGHTS_VERSION,
1019
            'tgm-updater-is-pro'     => monsterinsights_is_pro_version(),
1020
        )
1021
    );
1022
1023
    $args = [
1024
        'headers' => $headers,
1025
    ];
1026
1027
    // Perform the query and retrieve the response.
1028
    $response      = wp_remote_get( add_query_arg( $query_params, monsterinsights_get_licensing_url() ), $args );
1029
    $response_code = wp_remote_retrieve_response_code( $response );
1030
    $response_body = wp_remote_retrieve_body( $response );
1031
1032
    // Bail out early if there are any errors.
1033
    if ( 200 != $response_code || is_wp_error( $response_body ) ) {
1034
        return false;
1035
    }
1036
1037
    // Return the json decoded content.
1038
    return json_decode( $response_body );
1039
}
1040
1041
function monsterinsights_is_wp_seo_active() {
1042
	$wp_seo_active = false; // @todo: improve this check. This is from old Yoast code.
1043
1044
	// Makes sure is_plugin_active is available when called from front end
1045
	include_once ABSPATH . 'wp-admin/includes/plugin.php';
1046
	if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) || is_plugin_active( 'wordpress-seo-premium/wp-seo-premium.php' ) ) {
1047
		$wp_seo_active = true;
1048
	}
1049
1050
	return $wp_seo_active;
1051
}
1052
1053
function monsterinsights_get_asset_version() {
1054
	if ( monsterinsights_is_debug_mode() || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) {
1055
		return time();
1056
	} else {
1057
		return MONSTERINSIGHTS_VERSION;
1058
	}
1059
}
1060
1061
function monsterinsights_is_debug_mode() {
1062
	$debug_mode = false;
1063
	if ( defined( 'MONSTERINSIGHTS_DEBUG_MODE' ) && MONSTERINSIGHTS_DEBUG_MODE ) {
0 ignored issues
show
Bug introduced by
The constant MONSTERINSIGHTS_DEBUG_MODE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1064
		$debug_mode = true;
1065
	}
1066
1067
	return apply_filters( 'monsterinsights_is_debug_mode', $debug_mode );
1068
}
1069
1070
function monsterinsights_is_network_active() {
1071
	if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
1072
		require_once ABSPATH . '/wp-admin/includes/plugin.php';
1073
	}
1074
1075
	if ( is_multisite() && is_plugin_active_for_network( plugin_basename( MONSTERINSIGHTS_PLUGIN_FILE ) ) ) {
1076
		return true;
1077
	} else {
1078
		return false;
1079
	}
1080
}
1081
1082
if ( ! function_exists( 'remove_class_filter' ) ) {
1083
	/**
1084
	 * Remove Class Filter Without Access to Class Object
1085
	 *
1086
	 * In order to use the core WordPress remove_filter() on a filter added with the callback
1087
	 * to a class, you either have to have access to that class object, or it has to be a call
1088
	 * to a static method.  This method allows you to remove filters with a callback to a class
1089
	 * you don't have access to.
1090
	 *
1091
	 * Works with WordPress 1.2 - 4.7+
1092
	 *
1093
	 * @param string $tag Filter to remove
1094
	 * @param string $class_name Class name for the filter's callback
1095
	 * @param string $method_name Method name for the filter's callback
1096
	 * @param int    $priority Priority of the filter (default 10)
1097
	 *
1098
	 * @return bool Whether the function is removed.
1099
	 */
1100
	function remove_class_filter( $tag, $class_name = '', $method_name = '', $priority = 10 ) {
1101
		global $wp_filter;
1102
		// Check that filter actually exists first
1103
		if ( ! isset( $wp_filter[ $tag ] ) ) {
1104
			return false;
1105
		}
1106
		/**
1107
		 * If filter config is an object, means we're using WordPress 4.7+ and the config is no longer
1108
		 * a simple array, rather it is an object that implements the ArrayAccess interface.
1109
		 *
1110
		 * To be backwards compatible, we set $callbacks equal to the correct array as a reference (so $wp_filter is updated)
1111
		 *
1112
		 * @see https://make.wordpress.org/core/2016/09/08/wp_hook-next-generation-actions-and-filters/
1113
		 */
1114
		if ( is_object( $wp_filter[ $tag ] ) && isset( $wp_filter[ $tag ]->callbacks ) ) {
1115
			$callbacks = &$wp_filter[ $tag ]->callbacks;
1116
		} else {
1117
			$callbacks = &$wp_filter[ $tag ];
1118
		}
1119
		// Exit if there aren't any callbacks for specified priority
1120
		if ( ! isset( $callbacks[ $priority ] ) || empty( $callbacks[ $priority ] ) ) {
1121
			return false;
1122
		}
1123
		// Loop through each filter for the specified priority, looking for our class & method
1124
		foreach ( (array) $callbacks[ $priority ] as $filter_id => $filter ) {
1125
			// Filter should always be an array - array( $this, 'method' ), if not goto next
1126
			if ( ! isset( $filter['function'] ) || ! is_array( $filter['function'] ) ) {
1127
				continue;
1128
			}
1129
			// If first value in array is not an object, it can't be a class
1130
			if ( ! is_object( $filter['function'][0] ) ) {
1131
				continue;
1132
			}
1133
			// Method doesn't match the one we're looking for, goto next
1134
			if ( $filter['function'][1] !== $method_name ) {
1135
				continue;
1136
			}
1137
			// Method matched, now let's check the Class
1138
			if ( get_class( $filter['function'][0] ) === $class_name ) {
1139
				// Now let's remove it from the array
1140
				unset( $callbacks[ $priority ][ $filter_id ] );
1141
				// and if it was the only filter in that priority, unset that priority
1142
				if ( empty( $callbacks[ $priority ] ) ) {
1143
					unset( $callbacks[ $priority ] );
1144
				}
1145
				// and if the only filter for that tag, set the tag to an empty array
1146
				if ( empty( $callbacks ) ) {
1147
					$callbacks = array();
1148
				}
1149
				// If using WordPress older than 4.7
1150
				if ( ! is_object( $wp_filter[ $tag ] ) ) {
1151
					// Remove this filter from merged_filters, which specifies if filters have been sorted
1152
					unset( $GLOBALS['merged_filters'][ $tag ] );
1153
				}
1154
1155
				return true;
1156
			}
1157
		}
1158
1159
		return false;
1160
	}
1161
} // End function exists
1162
1163
if ( ! function_exists( 'remove_class_action' ) ) {
1164
	/**
1165
	 * Remove Class Action Without Access to Class Object
1166
	 *
1167
	 * In order to use the core WordPress remove_action() on an action added with the callback
1168
	 * to a class, you either have to have access to that class object, or it has to be a call
1169
	 * to a static method.  This method allows you to remove actions with a callback to a class
1170
	 * you don't have access to.
1171
	 *
1172
	 * Works with WordPress 1.2 - 4.7+
1173
	 *
1174
	 * @param string $tag Action to remove
1175
	 * @param string $class_name Class name for the action's callback
1176
	 * @param string $method_name Method name for the action's callback
1177
	 * @param int    $priority Priority of the action (default 10)
1178
	 *
1179
	 * @return bool               Whether the function is removed.
1180
	 */
1181
	function remove_class_action( $tag, $class_name = '', $method_name = '', $priority = 10 ) {
1182
		remove_class_filter( $tag, $class_name, $method_name, $priority );
1183
	}
1184
} // End function exists
1185
1186
/**
1187
 * Format a big number, instead of 1000000 you get 1.0M, works with billions also.
1188
 *
1189
 * @param int $number
1190
 * @param int $precision
1191
 *
1192
 * @return string
1193
 */
1194
function monsterinsights_round_number( $number, $precision = 2 ) {
1195
1196
	if ( $number < 1000000 ) {
1197
		// Anything less than a million
1198
		$number = number_format_i18n( $number );
1199
	} elseif ( $number < 1000000000 ) {
1200
		// Anything less than a billion
1201
		$number = number_format_i18n( $number / 1000000, $precision ) . 'M';
1202
	} else {
1203
		// At least a billion
1204
		$number = number_format_i18n( $number / 1000000000, $precision ) . 'B';
1205
	}
1206
1207
	return $number;
1208
}
1209
1210
if ( ! function_exists( 'wp_get_jed_locale_data' ) ) {
1211
	/**
1212
	 * Returns Jed-formatted localization data. Added for backwards-compatibility.
1213
	 *
1214
	 * @param string $domain Translation domain.
1215
	 *
1216
	 * @return array
1217
	 */
1218
	function wp_get_jed_locale_data( $domain ) {
1219
		$translations = get_translations_for_domain( $domain );
1220
1221
		$locale = array(
1222
			'' => array(
1223
				'domain' => $domain,
1224
				'lang'   => is_admin() && function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale(),
1225
			),
1226
		);
1227
1228
		if ( ! empty( $translations->headers['Plural-Forms'] ) ) {
1229
			$locale['']['plural_forms'] = $translations->headers['Plural-Forms'];
1230
		}
1231
1232
		foreach ( $translations->entries as $msgid => $entry ) {
1233
			$locale[ $msgid ] = $entry->translations;
1234
		}
1235
1236
		return $locale;
1237
	}
1238
}
1239
1240
/**
1241
 * Get JED array of translatable text.
1242
 *
1243
 * @param $domain string Text domain.
1244
 *
1245
 * @return array
1246
 */
1247
function monsterinsights_get_jed_locale_data( $domain ) {
1248
	$translations = get_translations_for_domain( $domain );
1249
1250
    $translations_entries = $translations->entries;
1251
1252
	if ( empty( $translations_entries ) ) {
1253
        return;
1254
    }
1255
1256
	$messages = array(
1257
		'' => array(
1258
			'domain'       => 'messages',
1259
			'lang'         => is_admin() && function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale(),
1260
			'plural-forms' => 'nplurals=2; plural=(n != 1);',
1261
		)
1262
	);
1263
1264
	foreach ( $translations_entries as $entry ) {
1265
		$messages[ $entry->singular ] = $entry->translations;
1266
	}
1267
1268
	return array(
1269
		'domain'      => 'messages',
1270
		'locale_data' => array(
1271
			'messages' => $messages,
1272
		),
1273
	);
1274
}
1275
1276
/**
1277
 * Get JED array of translatable text.
1278
 *
1279
 * @param $domain string Text domain.
1280
 *
1281
 * @return string
1282
 */
1283
function monsterinsights_get_printable_translations( $domain ) {
1284
	$locale = determine_locale();
1285
1286
	if ( 'en_US' == $locale ) {
1287
		return '';
1288
	}
1289
1290
    $locale_data = monsterinsights_get_jed_locale_data( $domain );
1291
1292
    if ( ! $locale_data ) {
0 ignored issues
show
introduced by
$locale_data is a non-empty array, thus ! $locale_data is always false.
Loading history...
Bug Best Practice introduced by
The expression $locale_data of type array<string,array<strin...tring,string>>>|string> 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...
1293
	    return '';
1294
    }
1295
1296
	$json_translations = wp_json_encode( $locale_data );
1297
1298
	$output = <<<JS
1299
( function( domain, translations ) {
1300
	var localeData = translations.locale_data[ domain ] || translations.locale_data.messages;
1301
	localeData[""].domain = domain;
1302
	wp.i18n.setLocaleData( localeData, domain );
1303
} )( "{$domain}", {$json_translations} );
1304
JS;
1305
1306
	return wp_get_inline_script_tag( $output );
1307
}
1308
1309
function monsterinsights_get_inline_menu_icon() {
1310
	$scheme          = get_user_option( 'admin_color', get_current_user_id() );
1311
	$use_dark_scheme = $scheme === 'light';
1312
	if ( $use_dark_scheme ) {
1313
		return 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTciIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJub256ZXJvIj48cGF0aCBkPSJNOC4zNyA3LjE5OWMuMDI4LS4wMS4wNTQtLjAyLjA4My0uMDI5YTEuNDcgMS40NyAwIDAgMSAuMTExLS4wMzJjLjAzLS4wMDYuMDU1LS4wMTMuMDg0LS4wMTYuMDg2LS4wMTYuMTcyLS4wMjUuMjU5LS4wMzIuMDI4IDAgLjA1Ny0uMDAzLjA5LS4wMDNsLjAwMi4wMDNoLjAwNGMuMDMyIDAgLjA2NCAwIC4wOTYuMDAzLjAxNiAwIC4wMzUuMDA0LjA1LjAwNGwuMDQyLjAwMy4wNjcuMDEuMDIzLjAwM2MuMDI1LjAwMy4wNTEuMDEuMDc3LjAxMmwuMDEyLjAwNGMuMDMuMDA2LjA1NS4wMTIuMDguMDE5aC4wMWMuMDI2LjAwNi4wNTQuMDE2LjA4LjAyMmguMDA2YS43NzIuNzcyIDAgMCAxIC4wOC4wMjZsLjAwNy4wMDMuMDc2LjAzMi4wMDcuMDAzLjAyOS4wMTMuMDA2LjAwM2MuMjUuMTEyLjQ3LjI3OC42NS40OS4xNjUtLjI2LjM2Ny0uNDkuNi0uNjkxYTMuMjg0IDMuMjg0IDAgMCAwLTIuMDQzLTEuODM2Yy0uMDM1LS4wMS0uMDc0LS4wMjMtLjExMi0uMDMybC0uMDMyLS4wMWEzLjk0MyAzLjk0MyAwIDAgMC0uMzg3LS4wNzcgMS43NjIgMS43NjIgMCAwIDAtLjE4Mi0uMDE5IDEuNjI4IDEuNjI4IDAgMCAwLS4xMjUtLjAwNmMtLjA0MiAwLS4wODMtLjAwMy0uMTI4LS4wMDMtLjExNSAwLS4yMy4wMDYtLjM0Mi4wMTlsLS4wODcuMDEtLjA2NC4wMWMtLjA2My4wMDktLjEyNC4wMTgtLjE4OC4wMzRoLS4wMDNjLS4wMjMuMDA0LS4wNDIuMDEtLjA2NC4wMTNhLjUyNS41MjUgMCAwIDAtLjAzNi4wMWMtLjAwNiAwLS4wMTIuMDAzLS4wMTYuMDAzbC0uMDEuMDAzLS4wNTcuMDE2aC0uMDAzbC0uMDE2LjAwMy0uMDI5LjAxLS4wNi4wMTZoLS4wMDRhMy4yODYgMy4yODYgMCAwIDAtMi4xOTcgMi4zMDljMCAuMDAzIDAgLjAwMy0uMDAzLjAwNi0uMDA2LjAyNi0uMDEzLjA1MS0uMDE2LjA3N2EzLjI4IDMuMjggMCAwIDAgMi43MTggMy45ODJjLjAzMi4wMDMuMDYxLjAxLjA5My4wMTJsLjA5My4wMWMuMDk2LjAwNi4xOTIuMDEzLjI4OC4wMTNoLjAwM2MuMDUxIDAgLjEwNiAwIC4xNTctLjAwMy4wNS0uMDA0LjEwMi0uMDA3LjE1My0uMDEzYTQuNjMgNC42MyAwIDAgMCAuMzA0LS4wNDJjLjExMi0uMDIyLjIyNC0uMDQ4LjMzMy0uMDhsLjA4Ni0uMDI4YTMuMzM1IDMuMzM1IDAgMCAwIDEuMTYtLjY3NSAyLjkyNiAyLjkyNiAwIDAgMS0uMTI3LS4zM2gtLjAwM2ExLjgyIDEuODIgMCAwIDEtLjk4NS4zMzNoLS4wNzdjLS4wNDUgMC0uMDg2IDAtLjEyOC0uMDAzLS4wMjItLjAwMy0uMDQyLS4wMDMtLjA2LS4wMDdhMS44NTMgMS44NTMgMCAwIDEtMS40MjctLjk0NmgtLjAwM2ExLjg0NCAxLjg0NCAwIDAgMS0uMjMtLjg5M2MwLS4wMzIgMC0uMDY0LjAwMy0uMDk2YS43NDQuNzQ0IDAgMCAwIC42NTYuMjE3Ljc1Mi43NTIgMCAwIDAgLjYyLS44NjkuNzUzLjc1MyAwIDAgMC0uNjU2LS42MjdoLS4wMDNjLjE3LS4xNS4zNjUtLjI2OC41NzYtLjM0OGwuMDI4LS4wMTNaTTIuODk0IDE0LjEyYy0uNDYtLjAzOS0uNTc5LS4yMTgtLjU5MS0uMzIzLS4wNDItLjQxLS4wODctLjgyMi0uMTI1LTEuMjM1bC0uMDQ4LS41MDItLjIwMi0yLjE1MmMtLjAxMi0uMTI1LS4wMjItLjI1LS4wMzUtLjM3NWE0LjMgNC4zIDAgMCAwLS41MzQuNTE5Yy0uNjMuNzI2LS45OTQgMS42MDgtMS4xODMgMi41NzQtLjEwNi41NS0uMTYzIDEuMTA3LS4xNzYgMS42NjZsLjAwMy4wMDNIMGMuMDIuNDQ4LjExOC44LjMxNyAxLjAxNy4yMDEtLjAxNi4zOC0uMTY2LjUxNS0uMzUxYTEuNyAxLjcgMCAwIDAgLjI4LjY5Yy40NC0uMDkyLjc4NC0uMzMyLjk0MS0uNzEuMDc3LjAwNC4xNTcuMDA0LjIzNC4wMDQuMTEyLjQwMy41MDUuNTk4LjcxLjU4OC4wOTktLjE2Ni4xOTUtLjM4NC4xOTgtLjY0NnYtLjc1MWwtLjEzOC0uMDFjLS4wNiAwLS4xMTItLjAwMy0uMTYzLS4wMDZaTS4zNzcgMTUuMTVhMS4zMzQgMS4zMzQgMCAwIDEtLjIyLS43M2guMDE5Yy4wOTYuMDYuMTk1LjExNS4yOTQuMTYzbC0uMDkzLjU2NlptLjguMzMyYTEuNzY0IDEuNzY0IDAgMCAxLS4yMy0uNzEzYy4xNDQuMDQxLjI5LjA3Ni40MzguMTAybC0uMjA4LjYxWm0xLjc0LS4xLS4xMjgtLjQ1M2MuMDkyLS4wMDcuMTg1LS4wMTYuMjc4LS4wMjZhMS4wNjEgMS4wNjEgMCAwIDEtLjE1LjQ4Wk00LjYyNCAxNC4xOTNsLS4zMjktLjAxNmMtLjIzLjM0NS0uMzkuNzItLjQ0OCAxLjAzMy4xNjcuMjA4LjM2NS4zODcuNTg5LjUzMWEuODcuODcgMCAwIDAtLjE0MS4yNTZoMy4zNjh2LTEuNzI0Yy0uMTEgMC0uMjE4IDAtLjMyMy0uMDAzYTYzLjUxOCA2My41MTggMCAwIDEtMi43MTYtLjA3N1pNMTEuMjY0IDE0LjE5M2E2OS4yMyA2OS4yMyAwIDAgMS0yLjcxMi4wOGMtLjExIDAtLjIxOCAwLS4zMjcuMDAzVjE2aDMuMzY4YS44MjYuODI2IDAgMCAwLS4xNDQtLjI1OWMuMjItLjE0Ny40Mi0uMzI2LjU4NS0uNTMtLjA1Ny0uMzE0LS4yMTctLjY4OS0uNDQ3LTEuMDM0bC0uMzIzLjAxNloiLz48cGF0aCBkPSJNMTUuODE4IDExLjM4OGMtLjA0Mi0uMDQ0LS4wOS0uMDgzLS4xMzUtLjEyNC0uMDU0LjA3Ni0uMTEyLjE1LS4xNy4yMjRhMy4xNTMgMy4xNTMgMCAwIDEtMi4yNTUgMS4xMzVoLS4wMjhhMy41MjcgMy41MjcgMCAwIDEtLjM2Ny0uMDAzbC0uMDc3LS4wMDdhMy4xODYgMy4xODYgMCAwIDEtMi40MTEtMS40OTQgMy42NjEgMy42NjEgMCAwIDEtNS45NTItMy42bC4wMDYtLjAyM2MuMDA0LS4wMjIuMDEtLjA0MS4wMTYtLjA2NHYtLjAwNmEzLjY2OCAzLjY2OCAwIDAgMSAyLjc5LTIuNjY3IDMuNjYyIDMuNjYyIDAgMCAxIDQuMDggMi4wNDcgMy4xNzcgMy4xNzcgMCAwIDEgMi40ODgtLjQ0OGMuMDctLjgyOS4xMzctMS42Ny4yMDUtMi41NTJsLTEuMTIzLS4zMWMuMTIyLS44MDMtLjAxMy0xLjIxOS0uMTc2LTEuOTQ4LS41MDguNDIyLS44MzUuNzI5LTEuNDUyIDEuMDRBNi4yNzQgNi4yNzQgMCAwIDAgMTAuNDYxLjRsLS4yNC0uNGMtLjkwOC42ODQtMS42NzkgMS4yMzQtMi4yOCAyLjE0QzcuMzQ2IDEuMjM0IDYuNTY5LjY4NCA1LjY2NCAwbC0uMjM3LjQwM2E2LjMxMyA2LjMxMyAwIDAgMC0uNzk2IDIuMTljLS42Mi0uMzEzLS45NDQtLjYxNy0xLjQ1Mi0xLjAzOS0uMTY2LjczLS4zIDEuMTQ1LS4xNzYgMS45NDhoLS4wMDZsLTEuMTIzLjMxYTM2OS40MTEgMzY5LjQxMSAwIDAgMCAuNDg2IDUuNjdjLjA2Ny43Mi4xMzEgMS40MzYuMjAyIDIuMTUzbC4wNDguNTAyLjEyNCAxLjIzMWMuMDEzLjEwNi4xMjguMjg1LjU5Mi4zMjMuMDUxLjAwMy4xMDYuMDA2LjE2My4wMDZsLjEzOC4wMWMuMjIzLjAxNi40NDcuMDI5LjY3NC4wMzhhNjkuMjMgNjkuMjMgMCAwIDAgMy4wNDEuMDk2aDEuMjEzYTYzLjM1IDYzLjM1IDAgMCAwIDIuNzEyLS4wOGMuMTA5LS4wMDYuMjE3LS4wMTIuMzI2LS4wMTZsLjgwNi0uMDQ4Yy4xMTUgMCAuMjMtLjAxLjM0Mi0uMDMyLjM0Ni42MTEuOTkyLjk5MiAxLjY5NS45OTJoLjA1MWwuMTQ3LjQzOGMuMDguMjM3Ljk2My0uMDU4Ljg4My0uMjk0bC0uMDctLjIxOGExLjExIDEuMTEgMCAwIDEtLjMwNC0uMDU3IDEuMjE0IDEuMjE0IDAgMCAxLS4zNTItLjE5MiAxLjcxNiAxLjcxNiAwIDAgMS0uMjY5LS4yNmMuMTEyLS4yMTQuMjctLjQwMi40NTgtLjU1YTEuMTUgMS4xNSAwIDAgMS0uNDQ4LS4xODVjLjAzNS4zMTQtLjAzMi42MDUtLjIwOC44MjJhMS4wNjYgMS4wNjYgMCAwIDEtLjEzNC4xMzRjLS40NjctLjA0MS0uNjU5LS40NDQtLjYzLS45MjdsLS4wMDMtLjAwM2MuMTUzLS4wNDIuMzEzLS4wNy40NzMtLjA4My4xNjYtLjAxMy4zMzYuMDA2LjQ5Ni4wNTRhMS42NyAxLjY3IDAgMCAxLS4zMzMtLjMwN2MuMTI4LS4yNDMuMzEtLjQ1LjUzNC0uNjEuMDk2LS4wNzEuMTk1LS4xMzUuMy0uMjAyLjI1LjIxNy40MTcuNDcuNDUyLjcyOWEuNzI1LjcyNSAwIDAgMS0uMDUxLjM3N2MuMTMuMTE5LjIzNi4yNjIuMzEzLjQyMmEuODM2LjgzNiAwIDAgMSAuMDc3LjM0MyAxLjkxMiAxLjkxMiAwIDAgMCAwLTIuN1pNNi40MTIgMy42NWExLjkzOSAxLjkzOSAwIDAgMSAxLjUzMi0uMzhjLjQ1Ny4wODYuODg2LjM2IDEuMTguODY2di4wMDNDNy42NjYgMy45MTQgNi4zOCA0LjI3IDUuNzEgNS4zNzZhMS44MTUgMS44MTUgMCAwIDEgLjcwNC0xLjcyN1oiLz48cGF0aCBkPSJNMTMuMzY4IDYuNjg3YTIuNzg0IDIuNzg0IDAgMCAwLTIuNjc0IDQuMjA5bC41MDItLjY5NGEuNTcyLjU3MiAwIDEgMSAxLjAwMS0uMjgybC44NDUuMzUyYy4wMTMtLjAxNi4wMjUtLjAzNS4wNDEtLjA1LjEtLjExLjI0LS4xNzQuMzg0LS4xODNoLjAwN2EuNDQuNDQgMCAwIDEgLjE0My4wMTNsLjYwMi0xLjI0NGEuNTcuNTcgMCAwIDEtLjA3LS44MDYuNTcuNTcgMCAwIDEgLjgwNS0uMDdjLjEyMi4xMDIuMTk1LjI0OS4yMDUuNDA1di4wMDRsLjUwMi4wOTZoLjAwM2EyLjc4NiAyLjc4NiAwIDAgMC0xLjg5Ni0xLjY3MyAyLjQ1IDIuNDUgMCAwIDAtLjQtLjA3N1oiLz48cGF0aCBkPSJtMTQuNDY4IDguOTI5LS42MDEgMS4yNGEuNTc3LjU3NyAwIDAgMSAuMTUuNjg1LjU3NC41NzQgMCAwIDEtLjY0OS4zMS41NzQuNTc0IDAgMCAxLS40MzItLjY0M2wtLjg0NC0uMzUxYS41NzQuNTc0IDAgMCAxLS42NzIuMTg1bC0uNTYuNzc4YTIuNzcgMi43NyAwIDAgMCAyIDEuMDljLjAxMiAwIC4wMjUuMDAzLjAzOC4wMDMuMTEyLjAwNy4yMjQuMDEuMzM2LjAwMy4wMSAwIC4wMTktLjAwMy4wMzItLjAwMy4wNTctLjAwMy4xMTUtLjAxLjE3Mi0uMDE2YTIuNzkgMi43OSAwIDAgMCAxLjc0Ni0uOTQzYy4wNjEtLjA3NC4xMjItLjE0Ny4xNzYtLjIyN2EyLjc4NyAyLjc4NyAwIDAgMCAuNDEtMi4zMDZoLS4wMDNsLS42NTYtLjEyOGEuNTguNTggMCAwIDEtLjY0My4zMjNaIi8+PC9nPjwvc3ZnPg==';
1314
		// return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAFQUlEQVRYha2Yb2hXZRTHP+c3nc6pm07NF0KWWUtSo0wqzBdiZRItTKMaEZXSi0zRNAsqTBKKSFOa0B8Jigqz2lSwLMtqRURgRuCCLLNmselyZups2+/04pzbnt3de3eTDlzufc5znvN8n+ec55zzXFFV8pKITANOqmpTP3JTgIKq7sutPCJVzfUABeAb4DSwMENuKdABNObV3Wv8fwB0C6DAUX8/67sQ9Q8ANsVk5v5vgIDKWHsvcAgYCWzzCbc6kFJgh/PqgVHAb8DnWTpzA3LzHARmeXuqT/Zo0L/eeZuAV/x7fbRrwJPOu9Dbc4EDgJwNoMmurAt4Bljt7cmBjACvOl+BzTEdVzj/EWAj0O3tC84G0AIf3BRMeDz0GZcbBvzqKy+L9Q30A6AxXTdmARqQcPAAyv29CBjjO1RU1SKAiIwGFgLX+MrbgBnAh5ECVe0UkUMO6nHgFLA70J1McacD5gHbfTXzg77qwBeOBysPn830PnnVwXety7wL1AAV/ZoM+MIHdQCfAdfF+s8H/koBEz0rU9xgLtAInHG5j/KYrNWf8ap6OmFD7w+2/Cugwd/NmOkqgbIUS+wEdorIEOAwFqv6UBKgihQwANNc0b2quh1ARIZi/nUqZUycOrDDcCSps5AAaJBPkkStwNVAs4i8JiLHgBPASRFpFZEGEZktIpIBqBIoIWWH4nZegtl3fIofjAKeoyemfAe8hZnu64D/NjAsRcdEl1mcx6lvc+HLU6L3O97/JXBlgszF9KSVvXhswkxUC6wLdKzIA2iWC1+fMNlK72sASlMjrQHf4LIvAw8B7fScwmNAZ7DDs7MARSmjNsYf7oqak0wBjAXuBlb5Lo9wE0Yg6rHAOdjlR2KB9Qc384o0QOe4giUx/u3OX5oA5gEsCoexqBnYAxTTfMXHlvuOF4F5SYBKHPGaGH+jTzQxxefSnnVpYAIdg9x0PwEDkwSOAHUx3hafoDzGP5AB5gQ56h/XU+NjauJxCCxRjo7xOvw9ImKISBUwIWF8RLtVtT2jP6SdWBKe1QuQiCwDLsKcNKSoqJ8e8BJTREAHc4JBVTuBn4Gx/wISkflYndyNOXdI2/29OOAd7mfSIXkBOZUDxTACt2A78SLQnmDnBszOiwLeraT70Ld5/Mf1jPMxqyLGWqxcnYoFMqVvBTgOK9y7gOVAifMfdF4SqJk5Aa3FLFMNduxagQbvvJOUfIb51/f0lKSrsROyHCtlIyDtrrMJqOoHzAysRvrA28wmSBfAtd7uk6u8vwwr/JOqxm4sl01wvZ3AfhJyo+taAPyJhYi/gekCPIXdNitV9YyIXIIFqptVdVsf13MSkVJgJlZF4rvSqKq/BzJzgNexcPEp8LFPXAHcAFzqoKcAddjR5z2Cay/m4Arcl9cp+zFJFfA0dslMOwB1wD1AewGrTw4Ei2/zVcSP/lmRqrap6irs8gAwid7xDOAuzNwlgmXxF1T14ahXRPZjtU1k3+g5Tk8pkUUFzCwVWC003N/DgGVYIXheIF/EfmQcFczDW4DnsVtBCxbUtmIOPAAzY6MPLgMG+/dlDrIADHWlYL4QpZuZWLjYgp3SOb7QMbFFFLF6LDNB7sGcri7FP7qwWmcX9t8oSWaDA6zCqomXUuZ6U1UpYDXxH5jfgKWET/y7zXfolIgkJeJMEpES/xwMXKWq3aq6CLu9PAH8Eog/Fn2UYnlkDWa2c719E3Y/f8NX0AL8GHuianAXtuXx/lZ6brR9/npgcWgHcEfEkyg6ZqyyBrt1ptE+X9SkDJl6VX0/cyKnfwBb6gwNaZ8ExgAAAABJRU5ErkJggg';
1315
	} else {
1316
		return 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTciIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI0ZGRiIgZmlsbC1ydWxlPSJub256ZXJvIj48cGF0aCBkPSJNOC4zNyA3LjE5OWMuMDI4LS4wMS4wNTQtLjAyLjA4My0uMDI5YTEuNDcgMS40NyAwIDAgMSAuMTExLS4wMzJjLjAzLS4wMDYuMDU1LS4wMTMuMDg0LS4wMTYuMDg2LS4wMTYuMTcyLS4wMjUuMjU5LS4wMzIuMDI4IDAgLjA1Ny0uMDAzLjA5LS4wMDNsLjAwMi4wMDNoLjAwNGMuMDMyIDAgLjA2NCAwIC4wOTYuMDAzLjAxNiAwIC4wMzUuMDA0LjA1LjAwNGwuMDQyLjAwMy4wNjcuMDEuMDIzLjAwM2MuMDI1LjAwMy4wNTEuMDEuMDc3LjAxMmwuMDEyLjAwNGMuMDMuMDA2LjA1NS4wMTIuMDguMDE5aC4wMWMuMDI2LjAwNi4wNTQuMDE2LjA4LjAyMmguMDA2YS43NzIuNzcyIDAgMCAxIC4wOC4wMjZsLjAwNy4wMDMuMDc2LjAzMi4wMDcuMDAzLjAyOS4wMTMuMDA2LjAwM2MuMjUuMTEyLjQ3LjI3OC42NS40OS4xNjUtLjI2LjM2Ny0uNDkuNi0uNjkxYTMuMjg0IDMuMjg0IDAgMCAwLTIuMDQzLTEuODM2Yy0uMDM1LS4wMS0uMDc0LS4wMjMtLjExMi0uMDMybC0uMDMyLS4wMWEzLjk0MyAzLjk0MyAwIDAgMC0uMzg3LS4wNzcgMS43NjIgMS43NjIgMCAwIDAtLjE4Mi0uMDE5IDEuNjI4IDEuNjI4IDAgMCAwLS4xMjUtLjAwNmMtLjA0MiAwLS4wODMtLjAwMy0uMTI4LS4wMDMtLjExNSAwLS4yMy4wMDYtLjM0Mi4wMTlsLS4wODcuMDEtLjA2NC4wMWMtLjA2My4wMDktLjEyNC4wMTgtLjE4OC4wMzRoLS4wMDNjLS4wMjMuMDA0LS4wNDIuMDEtLjA2NC4wMTNhLjUyNS41MjUgMCAwIDAtLjAzNi4wMWMtLjAwNiAwLS4wMTIuMDAzLS4wMTYuMDAzbC0uMDEuMDAzLS4wNTcuMDE2aC0uMDAzbC0uMDE2LjAwMy0uMDI5LjAxLS4wNi4wMTZoLS4wMDRhMy4yODYgMy4yODYgMCAwIDAtMi4xOTcgMi4zMDljMCAuMDAzIDAgLjAwMy0uMDAzLjAwNi0uMDA2LjAyNi0uMDEzLjA1MS0uMDE2LjA3N2EzLjI4IDMuMjggMCAwIDAgMi43MTggMy45ODJjLjAzMi4wMDMuMDYxLjAxLjA5My4wMTJsLjA5My4wMWMuMDk2LjAwNi4xOTIuMDEzLjI4OC4wMTNoLjAwM2MuMDUxIDAgLjEwNiAwIC4xNTctLjAwMy4wNS0uMDA0LjEwMi0uMDA3LjE1My0uMDEzYTQuNjMgNC42MyAwIDAgMCAuMzA0LS4wNDJjLjExMi0uMDIyLjIyNC0uMDQ4LjMzMy0uMDhsLjA4Ni0uMDI4YTMuMzM1IDMuMzM1IDAgMCAwIDEuMTYtLjY3NSAyLjkyNiAyLjkyNiAwIDAgMS0uMTI3LS4zM2gtLjAwM2ExLjgyIDEuODIgMCAwIDEtLjk4NS4zMzNoLS4wNzdjLS4wNDUgMC0uMDg2IDAtLjEyOC0uMDAzLS4wMjItLjAwMy0uMDQxLS4wMDMtLjA2LS4wMDdhMS44NTMgMS44NTMgMCAwIDEtMS40MjctLjk0NmgtLjAwM2ExLjg0NCAxLjg0NCAwIDAgMS0uMjMtLjg5M2MwLS4wMzIgMC0uMDY0LjAwMy0uMDk2YS43NDQuNzQ0IDAgMCAwIC42NTYuMjE3Ljc1Mi43NTIgMCAwIDAgLjYyLS44NjkuNzUzLjc1MyAwIDAgMC0uNjU2LS42MjdoLS4wMDNjLjE3LS4xNS4zNjUtLjI2OC41NzYtLjM0OGwuMDI4LS4wMTNaTTIuODk0IDE0LjEyYy0uNDYtLjAzOS0uNTc5LS4yMTgtLjU5MS0uMzIzLS4wNDItLjQxLS4wODctLjgyMi0uMTI1LTEuMjM1bC0uMDQ4LS41MDItLjIwMi0yLjE1MmMtLjAxMi0uMTI1LS4wMjItLjI1LS4wMzUtLjM3NWE0LjMgNC4zIDAgMCAwLS41MzQuNTE5Yy0uNjMuNzI2LS45OTQgMS42MDgtMS4xODMgMi41NzQtLjEwNi41NS0uMTYzIDEuMTA3LS4xNzYgMS42NjZsLjAwMy4wMDNIMGMuMDIuNDQ4LjExOC44LjMxNyAxLjAxNy4yMDEtLjAxNi4zOC0uMTY2LjUxNS0uMzUxYTEuNyAxLjcgMCAwIDAgLjI4LjY5Yy40NC0uMDkyLjc4NC0uMzMyLjk0MS0uNzEuMDc3LjAwNC4xNTcuMDA0LjIzNC4wMDQuMTEyLjQwMy41MDUuNTk4LjcxLjU4OC4wOTktLjE2Ni4xOTUtLjM4NC4xOTgtLjY0NnYtLjc1MWwtLjEzOC0uMDFjLS4wNiAwLS4xMTItLjAwMy0uMTYzLS4wMDZaTS4zNzcgMTUuMTVhMS4zMzQgMS4zMzQgMCAwIDEtLjIyLS43M2guMDE5Yy4wOTYuMDYuMTk1LjExNS4yOTQuMTYzbC0uMDkzLjU2NlptLjguMzMyYTEuNzY0IDEuNzY0IDAgMCAxLS4yMy0uNzEzYy4xNDQuMDQxLjI5LjA3Ni40MzguMTAybC0uMjA4LjYxWm0xLjc0LS4xLS4xMjgtLjQ1M2MuMDkyLS4wMDcuMTg1LS4wMTYuMjc4LS4wMjZhMS4wNjEgMS4wNjEgMCAwIDEtLjE1LjQ4Wk00LjYyNCAxNC4xOTNsLS4zMjktLjAxNmMtLjIzLjM0NS0uMzkuNzItLjQ0OCAxLjAzMy4xNjcuMjA4LjM2NS4zODcuNTg5LjUzMWEuODcuODcgMCAwIDAtLjE0MS4yNTZoMy4zNjh2LTEuNzI0Yy0uMTEgMC0uMjE4IDAtLjMyMy0uMDAzYTYzLjUxOCA2My41MTggMCAwIDEtMi43MTYtLjA3N1pNMTEuMjY0IDE0LjE5M2E2OS4yMyA2OS4yMyAwIDAgMS0yLjcxMi4wOGMtLjExIDAtLjIxOCAwLS4zMjcuMDAzVjE2aDMuMzY4YS44MjYuODI2IDAgMCAwLS4xNDQtLjI1OWMuMjItLjE0Ny40Mi0uMzI2LjU4NS0uNTMtLjA1Ny0uMzE0LS4yMTctLjY4OS0uNDQ3LTEuMDM0bC0uMzIzLjAxNloiLz48cGF0aCBkPSJNMTUuODE4IDExLjM4OGMtLjA0Mi0uMDQ0LS4wOS0uMDgzLS4xMzUtLjEyNC0uMDU0LjA3Ni0uMTEyLjE1LS4xNy4yMjRhMy4xNTMgMy4xNTMgMCAwIDEtMi4yNTUgMS4xMzVoLS4wMjhhMy41MjcgMy41MjcgMCAwIDEtLjM2Ny0uMDAzbC0uMDc3LS4wMDdhMy4xODYgMy4xODYgMCAwIDEtMi40MTEtMS40OTQgMy42NjEgMy42NjEgMCAwIDEtNS45NTItMy42bC4wMDYtLjAyM2MuMDA0LS4wMjIuMDEtLjA0MS4wMTYtLjA2NHYtLjAwNmEzLjY2OCAzLjY2OCAwIDAgMSAyLjc5LTIuNjY3IDMuNjYyIDMuNjYyIDAgMCAxIDQuMDggMi4wNDcgMy4xNzcgMy4xNzcgMCAwIDEgMi40ODgtLjQ0OGMuMDctLjgyOS4xMzctMS42Ny4yMDUtMi41NTJsLTEuMTIzLS4zMWMuMTIyLS44MDMtLjAxMy0xLjIxOS0uMTc2LTEuOTQ4LS41MDguNDIyLS44MzUuNzI5LTEuNDUyIDEuMDRBNi4yNzQgNi4yNzQgMCAwIDAgMTAuNDYxLjRsLS4yNC0uNGMtLjkwOC42ODQtMS42NzkgMS4yMzQtMi4yOCAyLjE0QzcuMzQ2IDEuMjM0IDYuNTY5LjY4NCA1LjY2NCAwbC0uMjM3LjQwM2E2LjMxMyA2LjMxMyAwIDAgMC0uNzk2IDIuMTljLS42Mi0uMzEzLS45NDQtLjYxNy0xLjQ1Mi0xLjAzOS0uMTY2LjczLS4zIDEuMTQ1LS4xNzYgMS45NDhoLS4wMDZsLTEuMTIzLjMxYTM2OS40MTEgMzY5LjQxMSAwIDAgMCAuNDg2IDUuNjdjLjA2Ny43Mi4xMzEgMS40MzYuMjAyIDIuMTUzbC4wNDguNTAyLjEyNCAxLjIzMWMuMDEzLjEwNi4xMjguMjg1LjU5Mi4zMjMuMDUxLjAwMy4xMDYuMDA2LjE2My4wMDZsLjEzOC4wMWMuMjIzLjAxNi40NDcuMDI5LjY3NC4wMzhhNjkuMjMgNjkuMjMgMCAwIDAgMy4wNDEuMDk2aDEuMjEzYTYzLjM1IDYzLjM1IDAgMCAwIDIuNzEyLS4wOGMuMTA5LS4wMDYuMjE3LS4wMTIuMzI2LS4wMTZsLjgwNi0uMDQ4Yy4xMTUgMCAuMjMtLjAxLjM0Mi0uMDMyLjM0Ni42MTEuOTkyLjk5MiAxLjY5NS45OTJoLjA1MWwuMTQ3LjQzOGMuMDguMjM3Ljk2My0uMDU4Ljg4My0uMjk0bC0uMDctLjIxOGExLjExIDEuMTEgMCAwIDEtLjMwNC0uMDU3IDEuMjE0IDEuMjE0IDAgMCAxLS4zNTItLjE5MiAxLjcxNiAxLjcxNiAwIDAgMS0uMjY5LS4yNmMuMTEyLS4yMTQuMjctLjQwMi40NTgtLjU1YTEuMTUgMS4xNSAwIDAgMS0uNDQ4LS4xODVjLjAzNS4zMTQtLjAzMi42MDUtLjIwOC44MjJhMS4wNjYgMS4wNjYgMCAwIDEtLjEzNC4xMzRjLS40NjctLjA0MS0uNjU5LS40NDQtLjYzLS45MjdsLS4wMDMtLjAwM2MuMTUzLS4wNDIuMzEzLS4wNy40NzMtLjA4My4xNjYtLjAxMy4zMzYuMDA2LjQ5Ni4wNTRhMS42NyAxLjY3IDAgMCAxLS4zMzMtLjMwN2MuMTI4LS4yNDMuMzEtLjQ1LjUzNC0uNjEuMDk2LS4wNzEuMTk1LS4xMzUuMy0uMjAyLjI1LjIxNy40MTcuNDcuNDUyLjcyOWEuNzI1LjcyNSAwIDAgMS0uMDUxLjM3N2MuMTMuMTE5LjIzNi4yNjIuMzEzLjQyMmEuODM2LjgzNiAwIDAgMSAuMDc3LjM0MyAxLjkxMiAxLjkxMiAwIDAgMCAwLTIuN1pNNi40MTIgMy42NWExLjkzOSAxLjkzOSAwIDAgMSAxLjUzMi0uMzhjLjQ1Ny4wODYuODg2LjM2IDEuMTguODY2di4wMDNDNy42NjYgMy45MTQgNi4zOCA0LjI3IDUuNzEgNS4zNzZhMS44MTUgMS44MTUgMCAwIDEgLjcwNC0xLjcyN1oiLz48cGF0aCBkPSJNMTMuMzY4IDYuNjg3YTIuNzg0IDIuNzg0IDAgMCAwLTIuNjc0IDQuMjA5bC41MDItLjY5NGEuNTcyLjU3MiAwIDEgMSAxLjAwMS0uMjgybC44NDUuMzUyYy4wMTMtLjAxNi4wMjUtLjAzNS4wNDEtLjA1LjEtLjExLjI0LS4xNzQuMzg0LS4xODNoLjAwN2EuNDQuNDQgMCAwIDEgLjE0My4wMTNsLjYwMi0xLjI0NGEuNTcuNTcgMCAwIDEtLjA3LS44MDYuNTcuNTcgMCAwIDEgLjgwNS0uMDdjLjEyMi4xMDIuMTk1LjI0OS4yMDUuNDA1di4wMDRsLjUwMi4wOTZoLjAwM2EyLjc4NiAyLjc4NiAwIDAgMC0xLjg5Ni0xLjY3MyAyLjQ1IDIuNDUgMCAwIDAtLjQtLjA3N1oiLz48cGF0aCBkPSJtMTQuNDY4IDguOTI5LS42MDEgMS4yNGEuNTc3LjU3NyAwIDAgMSAuMTUuNjg1LjU3NC41NzQgMCAwIDEtLjY0OS4zMS41NzQuNTc0IDAgMCAxLS40MzItLjY0M2wtLjg0NC0uMzUxYS41NzQuNTc0IDAgMCAxLS42NzIuMTg1bC0uNTYuNzc4YTIuNzcgMi43NyAwIDAgMCAyIDEuMDljLjAxMiAwIC4wMjUuMDAzLjAzOC4wMDMuMTEyLjAwNy4yMjQuMDEuMzM2LjAwMy4wMSAwIC4wMTktLjAwMy4wMzItLjAwMy4wNTctLjAwMy4xMTUtLjAxLjE3Mi0uMDE2YTIuNzkgMi43OSAwIDAgMCAyLjMzMi0zLjQ3NmgtLjAwM2wtLjY1Ni0uMTI4YS41OC41OCAwIDAgMS0uNjQzLjMyM1oiLz48L2c+PC9zdmc+';
1317
		// return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4AoEBjcfBsDvpwAABQBJREFUWMO1mGmollUQgJ9z79Vc01LLH0GLWRqlUhYV5o+LbRIVbVQSUSn9qJTKsqDCoqCINKUbtBEUFbbeDGyz1SIiaCHIINu18KZ1bbkuV+/Tj+arw8v7fvdVcuDjvGdmzsycM3Nm5nywE6BOVSfW4JukTmF3gtqifqJuVmc34ZunblFX7W6DzvYf2BDjPWpLRm9T7y/wzPw/DRhZmH+sfq/urb4YCp8JQwaqLwXuBXW0+pP6XjOZO+ueb9X2mE8OZTdl9MWBu199NL4XN05NvT1wh8R8prpGTbti0BEhbLt6t7ow5kdkPEl9zP/gkYKMowN/o7pU3RHzg3fFoHNj8epM4aY8ZoJvuPpj7HxwgTYgLoAFWac1091WgR8a4xxgH2Ah0JdS6gtlY4DZwAnADmAjMA14vSEgpdSrfg9sBm4BeoCVmex6gayepS6P3ZyT0SZksbDJcnikcPMmZN+zgud59Qx1RB2D3o9FW9R31ZMK9IPUP20O11XInqmuUrcG3xt1XNYVvwNSSptL+K/IjvxDoDPGteG6kcDgMkUppRXACnUIsA7YUNegERXGAEwNQZellJbHzodFfPXUjIwtwHDglzJiS4lBe4SSMugCjgfWqo+rvwF/AH+pXWqnOqOfXDMSaK06oaKf54Z/D6igj1bvzXLK5+rTYchHGf5ZdXiFjPHBc2Udg84P5qMqsvdzQf9APbaEZ2JWVj5u5KbIV7PURZmM+XUMag/mk0to1wWtUx3YT9lZErwPq9er3dkt/E3tzU54Rp2SMauA3zMErS1zhTpWvURdEKe8V7jQrOBOUwcF/97qbPWrcPP8KoP2DQFzC/gLAj+vZM1Vak8hF61V31L7msWKOjROvE89q4yhNSy+rYBfGorGV8RcFSyqESZ7hOu+UQeUMfyidhRwy0LB0AJ+TRNj/qjb/0QpUT2jpYS+ERhTkswA9sqEjALGNdGzMqXUXTNZrogi3F5sJ64GDgXGFhasjvGYDDe4HyXf1i3qKaVe4DtgbF6ZzwHuiZq0b2HN8hjzAF3Xj9IhO9mGDQX68gy8PpqoB9XuEj93hp/nZLjzmsTQZzvR9uwXaxY0EHdEuzo5EpklHeB+0bhvV69RWwN/beDKYHpNg+6I2z2hce261M4gXlRVz9RD1S+zlnRh3JBropVtQHfIXB3B38yYadEjvdZAzMjLhXpizI+tEDA4Gv+yrnFH1LJxIbdX/aKsNma9+++RIrapxyT1TmAeMDKltFU9HPgcODOl9GKTnQ0EpgMHBaobWJVS+jnjOQV4ItLFO8CbwDZgBHAqMAXoBSYBHcBm1JfzZ28EuOrl/9ODc5R6Vzwyq6BDvVTtbgHGA2sKiXFbydXfJUgpbUwpLQAateqwQj4DuDjSTWuKru+BlNIN2a6+ACYCv0dH2PhtCtfYjx0t4ZYR0a7uGeNw4GpgLnBgxt8HfAJsSOpWYD1wH7AqvocAz0Q2bgNGB62RoQfF95FhZAswLIQSZaBRbqYDPwHLogqcEhvdp7CJPqC9vwL5VtyUjor42B69zqvqXxU8S+IFOyq6iYcqdD3VONqngV8jbhol4e0sntqAnuIzumZAt8bnIOC4lNKOlNKceL3cCvyQsd/87/WNRuk29T51/5ifHu/zJ2MH69WvCz+zE+oroXdlL9pUkYdeUi/89xLU6VWAZn88fQoMjNtTBS+klF6pc6p/A2ye4OCYzm1lAAAAAElFTkSuQmCC';
1318
	}
1319
}
1320
1321
function monsterinsights_get_ai_menu_icon() {
1322
    return '
1323
        <span class="monsterinsights-sidebar-icon">
1324
            <svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.9301 1.27472C12.1523 0.259572 13.5986 0.253501 13.8305 1.26743L13.8402 1.31479L13.8621 1.4095C14.1292 2.54364 15.0472 3.40943 16.1959 3.60979C17.2548 3.79436 17.2548 5.31464 16.1959 5.49922C15.6311 5.59753 15.1078 5.86056 14.6919 6.25526C14.2761 6.64996 13.9861 7.15875 13.8584 7.71771L13.8293 7.84157C13.5986 8.8555 12.1536 8.84943 11.9301 7.83429L11.9071 7.72743C11.7845 7.16626 11.4975 6.65435 11.0826 6.25704C10.6678 5.85974 10.144 5.59505 9.57806 5.49679C8.52163 5.31343 8.52163 3.79557 9.57806 3.61221C10.142 3.51435 10.6641 3.25127 11.0783 2.85631C11.4925 2.46136 11.7801 1.95232 11.9046 1.39372L11.9216 1.31357L11.9301 1.27472ZM12.8129 9.918C12.2343 9.90674 11.6813 9.6773 11.2647 9.27564C11.1731 9.33603 11.0933 9.41256 11.0291 9.5015C10.4827 10.2252 9.84278 10.9647 9.11906 11.6872C8.57021 12.2361 8.01406 12.7351 7.4652 13.1808C6.91635 12.7351 6.3602 12.2361 5.81135 11.6872C5.28543 11.1624 4.78691 10.6107 4.31778 10.0346C4.76342 9.4845 5.2637 8.92957 5.81135 8.38071C6.49514 7.69453 7.22544 7.05633 7.99706 6.47064C8.07764 6.41292 8.1482 6.34236 8.20592 6.26179C7.97508 6.05132 7.79016 5.79548 7.66271 5.51028C7.53525 5.22508 7.46802 4.91666 7.4652 4.60429C6.27399 3.77007 5.09613 3.152 4.04456 2.83021C2.90556 2.48172 1.56985 2.38822 0.694348 3.2625C0.127276 3.83079 -0.026938 4.60307 0.0167763 5.33771C0.0604906 6.07357 0.306991 6.88229 0.679776 7.70314C1.06006 8.51991 1.51406 9.30029 2.03613 10.0346C1.51419 10.7681 1.06019 11.5476 0.679776 12.3636C0.306991 13.1844 0.0604906 13.9931 0.0167763 14.729C-0.026938 15.4636 0.126062 16.2359 0.694348 16.8042C1.26263 17.3713 2.03492 17.5255 2.76956 17.4818C3.5042 17.4369 4.31413 17.1916 5.13499 16.8188C5.87571 16.4824 6.66378 16.0234 7.46642 15.4624C8.26785 16.0234 9.0547 16.4824 9.79663 16.8188C10.6163 17.1916 11.4262 17.4381 12.1621 17.4818C12.8967 17.5255 13.6678 17.3713 14.2361 16.803C15.1116 15.9287 15.0181 14.593 14.6696 13.454C14.3368 12.3684 13.6896 11.1481 12.8129 9.918ZM3.51149 4.5715C4.21092 4.78521 5.04513 5.19079 5.94856 5.7785C4.9622 6.61536 4.046 7.53157 3.20913 8.51793C2.88027 8.01716 2.58886 7.49278 2.33728 6.94907C2.01792 6.24479 1.86128 5.66193 1.83456 5.22843C1.80906 4.7925 1.91592 4.61764 1.9827 4.55086C2.09199 4.44157 2.49513 4.26186 3.51149 4.5715ZM2.33728 13.1189C2.5607 12.6271 2.85335 12.0989 3.20913 11.55C4.0464 12.5364 4.96301 13.4526 5.94978 14.2894C5.44943 14.6186 4.92546 14.9105 4.38213 15.1625C3.67785 15.4819 3.09499 15.6385 2.66149 15.6652C2.22435 15.6907 2.0507 15.5839 1.98392 15.5171C1.91713 15.4503 1.81028 15.2742 1.83578 14.8395C1.86249 14.406 2.01792 13.8231 2.33849 13.1189H2.33728ZM10.5495 15.1625C10.0064 14.9108 9.48279 14.619 8.98306 14.2894C9.96858 13.4525 10.884 12.5363 11.7201 11.55C12.3066 12.4546 12.7121 13.2889 12.9258 13.9883C13.2367 15.0034 13.057 15.4078 12.9477 15.5171C12.8797 15.5839 12.7048 15.6907 12.2701 15.664C11.8354 15.6397 11.2538 15.4819 10.5495 15.1625ZM6.25092 10.0346C6.25092 9.71252 6.37885 9.40366 6.60658 9.17594C6.8343 8.94822 7.14316 8.82029 7.4652 8.82029C7.78725 8.82029 8.09611 8.94822 8.32383 9.17594C8.55156 9.40366 8.67949 9.71252 8.67949 10.0346C8.67949 10.3566 8.55156 10.6655 8.32383 10.8932C8.09611 11.1209 7.78725 11.2489 7.4652 11.2489C7.14316 11.2489 6.8343 11.1209 6.60658 10.8932C6.37885 10.6655 6.25092 10.3566 6.25092 10.0346Z" fill="currentColor"/></svg>
1325
        </span>
1326
    ';
1327
}
1328
1329
1330
function monsterinsights_get_shareasale_id() {
1331
	// Check if there's a constant.
1332
	$shareasale_id = '';
1333
	if ( defined( 'MONSTERINSIGHTS_SHAREASALE_ID' ) ) {
1334
		$shareasale_id = MONSTERINSIGHTS_SHAREASALE_ID;
0 ignored issues
show
Bug introduced by
The constant MONSTERINSIGHTS_SHAREASALE_ID was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1335
	}
1336
1337
	// If there's no constant, check if there's an option.
1338
	if ( empty( $shareasale_id ) ) {
1339
		$shareasale_id = get_option( 'monsterinsights_shareasale_id', '' );
1340
	}
1341
1342
	// Whether we have an ID or not, filter the ID.
1343
	$shareasale_id = apply_filters( 'monsterinsights_shareasale_id', $shareasale_id );
1344
1345
	// Ensure it's a number
1346
	$shareasale_id = absint( $shareasale_id );
1347
1348
	return $shareasale_id;
1349
}
1350
1351
// Passed in with mandatory default redirect and shareasaleid from monsterinsights_get_upgrade_link
1352
function monsterinsights_get_shareasale_url( $shareasale_id, $shareasale_redirect ) {
1353
	// Check if there's a constant.
1354
	$custom = false;
1355
	if ( defined( 'MONSTERINSIGHTS_SHAREASALE_REDIRECT_URL' ) ) {
1356
		$shareasale_redirect = MONSTERINSIGHTS_SHAREASALE_REDIRECT_URL;
0 ignored issues
show
Bug introduced by
The constant MONSTERINSIGHTS_SHAREASALE_REDIRECT_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1357
		$custom              = true;
1358
	}
1359
1360
	// If there's no constant, check if there's an option.
1361
	if ( empty( $custom ) ) {
1362
		$shareasale_redirect = get_option( 'monsterinsights_shareasale_redirect_url', '' );
1363
		$custom              = true;
1364
	}
1365
1366
	// Whether we have an ID or not, filter the ID.
1367
	$shareasale_redirect = apply_filters( 'monsterinsights_shareasale_redirect_url', $shareasale_redirect, $custom );
1368
	$shareasale_url      = sprintf( 'https://www.shareasale.com/r.cfm?B=971799&U=%s&M=69975&urllink=%s', $shareasale_id, $shareasale_redirect );
1369
	$shareasale_url      = apply_filters( 'monsterinsights_shareasale_redirect_entire_url', $shareasale_url, $shareasale_id, $shareasale_redirect );
1370
1371
	return $shareasale_url;
1372
}
1373
1374
/**
1375
 * Get a clean page title for archives.
1376
 */
1377
function monsterinsights_get_page_title() {
1378
1379
	$title = __( 'Archives' );
1380
1381
	if ( is_category() ) {
1382
		/* translators: Category archive title. %s: Category name */
1383
		$title = sprintf( __( 'Category: %s' ), single_cat_title( '', false ) );
1384
	} elseif ( is_tag() ) {
1385
		/* translators: Tag archive title. %s: Tag name */
1386
		$title = sprintf( __( 'Tag: %s' ), single_tag_title( '', false ) );
1387
	} elseif ( is_author() ) {
1388
		/* translators: Author archive title. %s: Author name */
1389
		$title = sprintf( __( 'Author: %s' ), '<span class="vcard">' . get_the_author() . '</span>' );
1390
	} elseif ( is_year() ) {
1391
		/* translators: Yearly archive title. %s: Year */
1392
		$title = sprintf( __( 'Year: %s' ), get_the_date( _x( 'Y', 'yearly archives date format' ) ) );
0 ignored issues
show
Bug introduced by
It seems like get_the_date(_x('Y', 'ye...archives date format')) can also be of type false; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1392
		$title = sprintf( __( 'Year: %s' ), /** @scrutinizer ignore-type */ get_the_date( _x( 'Y', 'yearly archives date format' ) ) );
Loading history...
1393
	} elseif ( is_month() ) {
1394
		/* translators: Monthly archive title. %s: Month name and year */
1395
		$title = sprintf( __( 'Month: %s' ), get_the_date( _x( 'F Y', 'monthly archives date format' ) ) );
1396
	} elseif ( is_day() ) {
1397
		/* translators: Daily archive title. %s: Date */
1398
		$title = sprintf( __( 'Day: %s' ), get_the_date( _x( 'F j, Y', 'daily archives date format' ) ) );
1399
	} elseif ( is_tax( 'post_format' ) ) {
1400
		if ( is_tax( 'post_format', 'post-format-aside' ) ) {
1401
			$title = _x( 'Asides', 'post format archive title' );
1402
		} elseif ( is_tax( 'post_format', 'post-format-gallery' ) ) {
1403
			$title = _x( 'Galleries', 'post format archive title' );
1404
		} elseif ( is_tax( 'post_format', 'post-format-image' ) ) {
1405
			$title = _x( 'Images', 'post format archive title' );
1406
		} elseif ( is_tax( 'post_format', 'post-format-video' ) ) {
1407
			$title = _x( 'Videos', 'post format archive title' );
1408
		} elseif ( is_tax( 'post_format', 'post-format-quote' ) ) {
1409
			$title = _x( 'Quotes', 'post format archive title' );
1410
		} elseif ( is_tax( 'post_format', 'post-format-link' ) ) {
1411
			$title = _x( 'Links', 'post format archive title' );
1412
		} elseif ( is_tax( 'post_format', 'post-format-status' ) ) {
1413
			$title = _x( 'Statuses', 'post format archive title' );
1414
		} elseif ( is_tax( 'post_format', 'post-format-audio' ) ) {
1415
			$title = _x( 'Audio', 'post format archive title' );
1416
		} elseif ( is_tax( 'post_format', 'post-format-chat' ) ) {
1417
			$title = _x( 'Chats', 'post format archive title' );
1418
		}
1419
	} elseif ( is_post_type_archive() ) {
1420
		/* translators: Post type archive title. %s: Post type name */
1421
		$title = sprintf( __( 'Archives: %s' ), post_type_archive_title( '', false ) );
1422
	} elseif ( is_tax() ) {
1423
		$tax = get_taxonomy( get_queried_object()->taxonomy );
0 ignored issues
show
Bug introduced by
The property taxonomy does not exist on WP_Post_Type. Did you mean taxonomies?
Loading history...
1424
		/* translators: Taxonomy term archive title. 1: Taxonomy singular name, 2: Current taxonomy term */
1425
		$title = sprintf( '%1$s: %2$s', $tax->labels->singular_name, single_term_title( '', false ) );
1426
	}
1427
1428
	return $title;
1429
}
1430
1431
/**
1432
 * Count the number of occurrences of UA tags inserted by third-party plugins.
1433
 *
1434
 * @param string $body
1435
 *
1436
 * @return int
1437
 */
1438
function monsterinsights_count_third_party_v4_codes($body) {
0 ignored issues
show
Unused Code introduced by
The parameter $body is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1438
function monsterinsights_count_third_party_v4_codes(/** @scrutinizer ignore-unused */ $body) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1439
	$count = 0;
1440
	return $count;
1441
}
1442
1443
/**
1444
 * Count the number of times the same tracking ID is used for Ads and Performance
1445
 *
1446
 * @param $current_code
1447
 *
1448
 * @return int
1449
 */
1450
function monsterinsights_count_addon_codes( $current_code ) {
1451
	$count = 0;
1452
1453
	// If the ads addon is installed and its conversion ID is the same as the current code, then increase the count
1454
	if ( class_exists( 'MonsterInsights_Ads' ) ) {
1455
		$ads_id = esc_attr( monsterinsights_get_option( 'gtag_ads_conversion_id' ) );
1456
1457
		if ( $ads_id === $current_code ) {
1458
			$count ++;
1459
		}
1460
	}
1461
1462
	return $count;
1463
}
1464
1465
/**
1466
 * Detect tracking code error depending on the type of tracking code
1467
 *
1468
 * @param string $body
1469
 *
1470
 * @return array
1471
 */
1472
function monsterinsights_detect_tracking_code_error( $body ) {
1473
	$errors = array();
1474
1475
	$current_code = monsterinsights_get_v4_id_to_output();
1476
1477
	$url = monsterinsights_get_url( 'notice', 'using-cache', 'https://www.wpbeginner.com/beginners-guide/how-to-clear-your-cache-in-wordpress/' );
1478
	// Translators: The placeholders are for making the "We noticed you're using a caching plugin" text bold.
1479
	$cache_error = sprintf(
1480
		esc_html__( '%1$sWe noticed you\'re using a caching plugin or caching from your hosting provider.%2$s Be sure to clear the cache to ensure the tracking appears on all pages and posts. %3$s(See this guide on how to clear cache)%4$s.', 'google-analytics-for-wordpress' ),
1481
		'<b>',
1482
		'</b>',
1483
		'<a target="_blank" href="' . esc_url( $url ) . '" target="_blank">',
1484
		'</a>'
1485
	);
1486
1487
	// Check if the current UA code is actually present.
1488
	if ( $current_code && false === strpos( $body, $current_code ) ) {
1489
		// We have the tracking code but using another UA, so it's cached.
1490
		$errors[] = $cache_error;
1491
1492
		return $errors;
1493
	}
1494
1495
	if ( empty( $current_code ) ) {
1496
		return $errors;
1497
	}
1498
1499
	if ( false === strpos( $body, '__gtagTracker' ) ) {
1500
		if ( ! isset ( $errors ) ) {
1501
			$errors[] = $cache_error;
1502
		}
1503
1504
		return $errors;
1505
	}
1506
1507
	$limit = 3;
1508
1509
	$limit += monsterinsights_count_addon_codes( $current_code );
1510
1511
	// TODO: Need to re-evaluate this regularly when third party plugins start supporting v4
1512
	$limit += monsterinsights_count_third_party_v4_codes( $body );
1513
1514
	// Count all the codes from the page.
1515
	$total_count = substr_count( $body, $current_code );
1516
1517
	// Count the `send_to` instances which are valid
1518
	$pattern = '/send_to[\'"]*?:\s*[\'"]' . $current_code . '/m';
1519
	if ( preg_match_all( $pattern, $body, $matches ) ) {
1520
		$total_count -= count( $matches[0] );
1521
	}
1522
1523
	// Main property always has a ?id=(UA|G|GT)-XXXXXXXX script
1524
	if ( strpos( $body, 'googletagmanager.com/gtag/js?id=' . $current_code ) !== false ) {
1525
		// In that case, we can safely deduct one from the total count
1526
		-- $total_count;
1527
	}
1528
1529
	// Test for Advanced Ads plugin tracking code.
1530
	$pattern = '/advanced_ads_ga_UID.*?"' . $current_code . '"/m';
1531
	if ( preg_match_all( $pattern, $body, $matches ) ) {
1532
		$total_count -= count( $matches[0] );
1533
	}
1534
1535
	// Test for WP Popups tracking code.
1536
	$pattern = '/wppopups_pro_vars.*?"' . $current_code . '"/m';
1537
	if ( preg_match_all( $pattern, $body, $matches ) ) {
1538
		$total_count -= count( $matches[0] );
1539
	}
1540
1541
	if ( $total_count > $limit ) {
1542
		// Translators: The placeholders are for making the "We have detected multiple tracking codes" text bold & adding a link to support.
1543
		$message           = esc_html__( '%1$sWe have detected multiple tracking codes%2$s! You should remove non-MonsterInsights ones. If you need help finding them please %3$sread this article%4$s.', 'google-analytics-for-wordpress' );
1544
		$url               = monsterinsights_get_url( 'site-health', 'comingsoon', 'https://www.monsterinsights.com/docs/how-to-find-duplicate-google-analytics-tracking-codes-in-wordpress/' );
1545
		$multiple_ua_error = sprintf(
1546
			$message,
1547
			'<b>',
1548
			'</b>',
1549
			'<a target="_blank" href="' . $url . '" target="_blank">',
1550
			'</a>'
1551
		);
1552
1553
		$errors[] = $multiple_ua_error;
1554
	}
1555
1556
	return $errors;
1557
}
1558
1559
/**
1560
 * Make a request to the front page and check if the tracking code is present. Moved here from onboarding wizard
1561
 * to be used in the site health check.
1562
 *
1563
 * @return array
1564
 */
1565
function monsterinsights_is_code_installed_frontend() {
1566
	// Grab the front page html.
1567
	$request = wp_remote_request(
1568
		home_url(),
1569
		array(
1570
			'sslverify' => false,
1571
		)
1572
	);
1573
	$errors  = array();
1574
1575
	$accepted_http_codes = array(
1576
		200,
1577
		503,
1578
	);
1579
1580
	$response_code = wp_remote_retrieve_response_code( $request );
1581
1582
	if ( in_array( $response_code, $accepted_http_codes, true ) ) {
1583
		$body = wp_remote_retrieve_body( $request );
1584
1585
		$errors = monsterinsights_detect_tracking_code_error( $body );
1586
	}
1587
1588
	return $errors;
1589
}
1590
1591
/**
1592
 * Returns a HEX color to highlight menu items based on the admin color scheme.
1593
 */
1594
function monsterinsights_menu_highlight_color() {
1595
1596
	$color_scheme = get_user_option( 'admin_color' );
1597
	$color        = '#1da867';
1598
	if ( 'light' === $color_scheme || 'blue' === $color_scheme ) {
1599
		$color = '#5f3ea7';
1600
	}
1601
1602
	return $color;
1603
}
1604
1605
/**
1606
 * Track Pretty Links redirects with MonsterInsights.
1607
 *
1608
 * @param string $url The url to which users get redirected.
1609
 */
1610
function monsterinsights_custom_track_pretty_links_redirect( $url ) {
1611
	if ( ! function_exists( 'monsterinsights_mp_collect_v4' ) ) {
1612
		return;
1613
	}
1614
1615
	// Track if it is a file.
1616
	monsterinsights_track_pretty_links_file_download_redirect( $url );
1617
1618
	// Try to determine if click originated on the same site.
1619
	$referer = ! empty( $_SERVER['HTTP_REFERER'] ) ? esc_url( $_SERVER['HTTP_REFERER'] ) : '';
1620
	if ( ! empty( $referer ) ) {
1621
		$current_site_url    = get_bloginfo( 'url' );
1622
		$current_site_parsed = wp_parse_url( $current_site_url );
1623
		$parsed_referer      = wp_parse_url( $referer );
1624
		if ( ! empty( $parsed_referer['host'] ) && ! empty( $current_site_parsed['host'] ) && $current_site_parsed['host'] === $parsed_referer['host'] ) {
1625
			// Don't track clicks originating from same site as those are tracked with JS.
1626
			return;
1627
		}
1628
	}
1629
	// Check if this is an affiliate link and use the appropriate category.
1630
	$inbound_paths = monsterinsights_get_option( 'affiliate_links', array() );
1631
	$path          = empty( $_SERVER['REQUEST_URI'] ) ? '' : $_SERVER['REQUEST_URI']; // phpcs:ignore
1632
	if ( ! empty( $inbound_paths ) && is_array( $inbound_paths ) && ! empty( $path ) ) {
0 ignored issues
show
introduced by
The condition is_array($inbound_paths) is always false.
Loading history...
1633
		$found = false;
1634
		foreach ( $inbound_paths as $inbound_path ) {
1635
			if ( empty( $inbound_path['path'] ) ) {
1636
				continue;
1637
			}
1638
			if ( 0 === strpos( $path, trim( $inbound_path['path'] ) ) ) {
1639
				$label = ! empty( $inbound_path['label'] ) ? trim( $inbound_path['label'] ) : 'aff';
1640
				$found = true;
1641
				break;
1642
			}
1643
		}
1644
		if ( ! $found ) {
1645
			return;
1646
		}
1647
	} else {
1648
		// no paths setup in MonsterInsights settings
1649
		return;
1650
	}
1651
1652
	if ( monsterinsights_get_v4_id_to_output() ) {
1653
		// Get Pretty Links settings.
1654
		$pretty_track = monsterinsights_get_option( 'pretty_links_backend_track', '' );
1655
1656
		if ( 'pretty_link' == $pretty_track ) {
1657
			global $prli_link;
1658
			$pretty_link = $prli_link->get_one_by( 'url', $url );
1659
			$link_url    = PrliUtils::get_pretty_link_url( $pretty_link->slug );
0 ignored issues
show
Bug introduced by
The type PrliUtils was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1660
		} else {
1661
			$link_url = $url;
1662
		}
1663
1664
		$url_components = parse_url( $url );
1665
		$params_args    = array(
1666
			'link_text'   => 'external-redirect',
1667
			'link_url'    => $link_url,
1668
			'link_domain' => $url_components['host'],
1669
			'outbound'    => 'true',
1670
		);
1671
1672
		if ( ! empty( $label ) ) {
1673
			$params_args['affiliate_label']   = $label;
1674
			$params_args['is_affiliate_link'] = 'true';
1675
		}
1676
1677
		monsterinsights_mp_collect_v4( array(
1678
			'events' => array(
1679
				array(
1680
					'name'   => 'click',
1681
					'params' => $params_args,
1682
				)
1683
			),
1684
		) );
1685
	}
1686
}
1687
1688
add_action( 'prli_before_redirect', 'monsterinsights_custom_track_pretty_links_redirect' );
1689
1690
/**
1691
 * Track Pretty Links file download redirects with MonsterInsights.
1692
 *
1693
 * @param string $url The url to which users get redirected.
1694
 */
1695
function monsterinsights_track_pretty_links_file_download_redirect( $url ) {
1696
	$file_info = pathinfo( $url );
1697
1698
	// If no extension in URL.
1699
	if ( ! isset( $file_info['extension'] ) ) {
1700
		return;
1701
	}
1702
1703
	if ( ! $file_info['extension'] ) {
1704
		return;
1705
	}
1706
1707
	// Get download extensions to track.
1708
	$download_extensions = monsterinsights_get_option( 'extensions_of_files', '' );
1709
1710
	if ( ! $download_extensions ) {
1711
		return;
1712
	}
1713
1714
	$download_extensions = explode( ',', str_replace( '.', '', $download_extensions ) );
1715
1716
	if ( ! is_array( $download_extensions ) ) {
0 ignored issues
show
introduced by
The condition is_array($download_extensions) is always true.
Loading history...
1717
		$download_extensions = array( $download_extensions );
1718
	}
1719
1720
	// If current URL extension is not in settings.
1721
	if ( ! in_array( $file_info['extension'], $download_extensions ) ) {
1722
		return;
1723
	}
1724
1725
	$url_components = parse_url( $url );
1726
1727
	global $prli_link;
1728
	$pretty_link = $prli_link->get_one_by( 'url', $url );
1729
1730
	$args = array(
1731
		'events' => array(
1732
			array(
1733
				'name'   => 'file_download',
1734
				'params' => array(
1735
					'link_text'      => $pretty_link->name,
1736
					'link_url'       => $url,
1737
					'link_domain'    => $url_components['host'],
1738
					'file_extension' => $file_info['extension'],
1739
					'file_name'      => $file_info['basename'],
1740
				)
1741
			)
1742
		),
1743
	);
1744
1745
	monsterinsights_mp_collect_v4( $args );
1746
}
1747
1748
/**
1749
 * Get post type in admin side
1750
 */
1751
function monsterinsights_get_current_post_type() {
1752
	global $post, $typenow, $current_screen;
1753
1754
	if ( $post && $post->post_type ) {
1755
		return $post->post_type;
1756
	} elseif ( $typenow ) {
1757
		return $typenow;
1758
	} elseif ( $current_screen && $current_screen->post_type ) {
1759
		return $current_screen->post_type;
1760
	} elseif ( isset( $_REQUEST['post_type'] ) ) {
1761
		return sanitize_key( $_REQUEST['post_type'] );
1762
	}
1763
1764
	return null;
1765
}
1766
1767
/** Decode special characters, both alpha- (<) and numeric-based (').
1768
 *
1769
 * @param string $string Raw string to decode.
1770
 *
1771
 * @return string
1772
 * @since 7.10.5
1773
 */
1774
function monsterinsights_decode_string( $string ) {
1775
1776
	if ( ! is_string( $string ) ) {
0 ignored issues
show
introduced by
The condition is_string($string) is always true.
Loading history...
1777
		return $string;
1778
	}
1779
1780
	return wp_kses_decode_entities( html_entity_decode( $string, ENT_QUOTES ) );
1781
}
1782
1783
add_filter( 'monsterinsights_email_message', 'monsterinsights_decode_string' );
1784
1785
/**
1786
 * Sanitize a string, that can be a multiline.
1787
 * If WP core `sanitize_textarea_field()` exists (after 4.7.0) - use it.
1788
 * Otherwise - split onto separate lines, sanitize each one, merge again.
1789
 *
1790
 * @param string $string
1791
 *
1792
 * @return string If empty var is passed, or not a string - return unmodified. Otherwise - sanitize.
1793
 * @since 7.10.5
1794
 */
1795
function monsterinsights_sanitize_textarea_field( $string ) {
1796
1797
	if ( empty( $string ) || ! is_string( $string ) ) {
1798
		return $string;
1799
	}
1800
1801
	if ( function_exists( 'sanitize_textarea_field' ) ) {
1802
		$string = sanitize_textarea_field( $string );
1803
	} else {
1804
		$string = implode( "\n", array_map( 'sanitize_text_field', explode( "\n", $string ) ) );
1805
	}
1806
1807
	return $string;
1808
}
1809
1810
/**
1811
 * Trim a sentence
1812
 *
1813
 * @param string $string
1814
 * @param int    $count
1815
 *
1816
 * @return trimed sentence
0 ignored issues
show
Bug introduced by
The type trimed was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1817
 * @since 7.10.5
1818
 */
1819
function monsterinsights_trim_text( $text, $count ) {
1820
	$text   = str_replace( '  ', ' ', $text );
1821
	$string = explode( ' ', $text );
1822
	$trimed = '';
1823
1824
	for ( $wordCounter = 0; $wordCounter <= $count; $wordCounter ++ ) {
1825
		$trimed .= isset( $string[ $wordCounter ] ) ? $string[ $wordCounter ] : '';
1826
1827
		if ( $wordCounter < $count ) {
1828
			$trimed .= ' ';
1829
		} else {
1830
			$trimed .= '...';
1831
		}
1832
	}
1833
1834
	$trimed = trim( $trimed );
1835
1836
	return $trimed;
1837
}
1838
1839
/**
1840
 * Add newly generated builder URL to PrettyLinks &
1841
 * Clear localStorage key(MonsterInsightsURL) after saving PrettyLink
1842
 */
1843
function monsterinsights_tools_copy_url_to_prettylinks() {
1844
	global $pagenow;
1845
1846
	$post_type                 = isset( $_GET['post_type'] ) ? sanitize_text_field( $_GET['post_type'] ) : '';
1847
	$monsterinsights_reference = isset( $_GET['monsterinsights_reference'] ) ? sanitize_text_field( $_GET['monsterinsights_reference'] ) : '';
1848
1849
	if ( 'post-new.php' === $pagenow && 'pretty-link' === $post_type && 'url_builder' === $monsterinsights_reference ) { ?>
1850
<script>
1851
let targetTitleField = document.querySelector("input[name='post_title']");
1852
let targetUrlField = document.querySelector("textarea[name='prli_url']");
1853
let MonsterInsightsUrl = JSON.parse(localStorage.getItem('MonsterInsightsURL'));
1854
if ('undefined' !== typeof targetUrlField && 'undefined' !== typeof MonsterInsightsUrl) {
1855
    let url = MonsterInsightsUrl.value;
1856
    let postTitle = '';
1857
    let pathArray = url.split('?');
1858
    if (pathArray.length <= 1) {
1859
        pathArray = url.split('#');
1860
    }
1861
    let urlParams = new URLSearchParams(pathArray[1]);
1862
    if (urlParams.has('utm_campaign')) {
1863
        let campaign_name = urlParams.get('utm_campaign');
1864
        postTitle += campaign_name;
1865
    }
1866
    if (urlParams.has('utm_medium')) {
1867
        let campaign_medium = urlParams.get('utm_medium');
1868
        postTitle += ` ${campaign_medium}`;
1869
    }
1870
    if (urlParams.has('utm_source')) {
1871
        let campaign_source = urlParams.get('utm_source');
1872
        postTitle += ` on ${campaign_source}`;
1873
    }
1874
    if (urlParams.has('utm_term')) {
1875
        let campaign_term = urlParams.get('utm_term');
1876
        postTitle += ` for ${campaign_term}`;
1877
    }
1878
    if (urlParams.has('utm_content')) {
1879
        let campaign_content = urlParams.get('utm_content');
1880
        postTitle += ` - ${campaign_content}`;
1881
    }
1882
    if ('undefined' !== typeof targetTitleField && postTitle) {
1883
        targetTitleField.value = postTitle;
1884
    }
1885
    if (url) {
1886
        targetUrlField.value = url;
1887
    }
1888
}
1889
let form = document.getElementById('post');
1890
form.addEventListener('submit', function() {
1891
    localStorage.removeItem('MonsterInsightsURL');
1892
});
1893
</script>
1894
<?php
1895
	}
1896
}
1897
1898
add_action( 'admin_footer', 'monsterinsights_tools_copy_url_to_prettylinks' );
1899
1900
/**
1901
 * When click on 'Create New Pretty Link" button(on tools/prettylinks-flow page) after installing & activating prettylinks plugin
1902
 * it redirects to PrettyLinks welcome scree page instead of prettylinks add new page.
1903
 * This function will skip that welcome screen
1904
 */
1905
function monsterinsights_skip_prettylinks_welcome_screen() {
1906
	global $pagenow;
1907
1908
	$post_type                 = isset( $_GET['post_type'] ) ? sanitize_text_field( $_GET['post_type'] ) : '';
1909
	$monsterinsights_reference = isset( $_GET['monsterinsights_reference'] ) ? sanitize_text_field( $_GET['monsterinsights_reference'] ) : '';
1910
1911
	if ( 'post-new.php' === $pagenow && 'pretty-link' === $post_type && 'url_builder' === $monsterinsights_reference ) {
1912
		$onboard = get_option( 'prli_onboard' );
1913
1914
		if ( $onboard == 'welcome' || $onboard == 'update' ) {
1915
			update_option( 'monsterinsights_backup_prli_onboard_value', $onboard );
1916
			delete_option( 'prli_onboard' );
1917
		}
1918
	}
1919
}
1920
1921
add_action( 'wp_loaded', 'monsterinsights_skip_prettylinks_welcome_screen', 9 );
1922
1923
/**
1924
 * Restore the `prli_onboard` value after creating a prettylinks with monsterinsights prettylinks flow
1925
 * users will see the prettylinks welcome screen after fresh installation & creating prettylinks with monsterinsights prettylinks flow
1926
 */
1927
function monsterinsights_restore_prettylinks_onboard_value() {
1928
	global $pagenow;
1929
1930
	$post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( $_GET['post_type'] ) : '';
1931
1932
	if ( 'edit.php' === $pagenow && 'pretty-link' === $post_type ) {
1933
		$onboard = get_option( 'monsterinsights_backup_prli_onboard_value' );
1934
1935
		if ( class_exists( 'PrliBaseController' ) && ( $onboard == 'welcome' || $onboard == 'update' ) ) {
1936
			update_option( 'prli_onboard', $onboard );
1937
			delete_option( 'monsterinsights_backup_prli_onboard_value' );
1938
		}
1939
	}
1940
}
1941
1942
add_action( 'wp_loaded', 'monsterinsights_restore_prettylinks_onboard_value', 15 );
1943
1944
/**
1945
 * Check WP version and include the compatible upgrader skin.
1946
 *
1947
 * @param bool $custom_upgrader If true it will include our custom upgrader, otherwise it will use the default WP one.
1948
 */
1949
function monsterinsights_require_upgrader( $custom_upgrader = true ) {
1950
1951
	global $wp_version;
1952
1953
	$base = MonsterInsights();
1954
1955
	if ( ! $custom_upgrader ) {
1956
		require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1957
	}
1958
1959
	// WP 5.3 changes the upgrader skin.
1960
	if ( version_compare( $wp_version, '5.3', '<' ) ) {
1961
		if ( $custom_upgrader ) {
1962
			require_once plugin_dir_path( $base->file ) . 'includes/admin/licensing/plugin-upgrader.php';
1963
		}
1964
		require_once plugin_dir_path( $base->file ) . '/includes/admin/licensing/skin-legacy.php';
1965
	} else {
1966
		if ( $custom_upgrader ) {
1967
			require_once plugin_dir_path( $base->file ) . 'includes/admin/licensing/plugin-upgrader.php';
1968
		}
1969
		require_once plugin_dir_path( $base->file ) . '/includes/admin/licensing/skin.php';
1970
	}
1971
}
1972
1973
/**
1974
 * Load headline analyzer if wp version is higher than/equal to 5.4
1975
 *
1976
 * @return boolean
1977
 * @since 7.12.3
1978
 */
1979
function monsterinsights_load_gutenberg_app() {
1980
	global $wp_version;
1981
1982
	if ( version_compare( $wp_version, '5.4', '<' ) ) {
1983
		return false;
1984
	}
1985
1986
	return true;
1987
}
1988
1989
/**
1990
 * Helper function for frontend script attributes
1991
 *
1992
 * @return string
1993
 * @since 7.12.3
1994
 */
1995
function monsterinsights_get_frontend_analytics_script_atts() {
1996
	$attr_string = '';
1997
1998
	$default_attributes = array(
1999
		'data-cfasync'     => 'false',
2000
		'data-wpfc-render' => 'false',
2001
	);
2002
	if ( ! current_theme_supports( 'html5', 'script' ) ) {
2003
		$default_attributes['type'] = 'text/javascript';
2004
	}
2005
2006
	$attributes = apply_filters( 'monsterinsights_tracking_analytics_script_attributes', $default_attributes );
2007
2008
	if ( ! empty( $attributes ) ) {
2009
		foreach ( $attributes as $attr_name => $attr_value ) {
2010
			if ( ! empty( $attr_name ) ) {
2011
				$attr_string .= ' ' . sanitize_key( $attr_name ) . '="' . esc_attr( $attr_value ) . '"';
2012
			} else {
2013
				$attr_string .= ' ' . esc_attr( $attr_value );
2014
			}
2015
		}
2016
	}
2017
2018
	return $attr_string;
2019
}
2020
2021
/**
2022
 * Helper function instead of wp_localize_script with our script tag attributes.
2023
 *
2024
 * @return string
2025
 * @since 8.5.0
2026
 */
2027
function monsterinsights_localize_script( $handle, $object_name, $data, $priority = 100 ) {
2028
	$theme_supports_html5 = current_theme_supports( 'html5', 'script' );
2029
	$script_js            = ! $theme_supports_html5 ? "/* <![CDATA[ */\n" : '';
2030
	$script_js           .= "var $object_name = " . wp_json_encode( $data ) . ';';
0 ignored issues
show
Bug introduced by
Are you sure wp_json_encode($data) of type false|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2030
	$script_js           .= "var $object_name = " . /** @scrutinizer ignore-type */ wp_json_encode( $data ) . ';';
Loading history...
2031
	$script_js           .= ! $theme_supports_html5 ? "/* ]]> */\n" : '';
2032
2033
	$script = sprintf(
2034
		"<script%s id='%s-js-extra'>%s</script>\n",
2035
		monsterinsights_get_frontend_analytics_script_atts(),
2036
		esc_attr( $handle ),
2037
		$script_js
2038
	);
2039
2040
	add_filter(
2041
		'script_loader_tag',
2042
		function ( $tag, $current_handle ) use ( $handle, $script ) {
2043
			if ( $current_handle !== $handle ) {
2044
				return $tag;
2045
			}
2046
2047
			return $tag . $script;
2048
		},
2049
		$priority,
2050
		2
2051
	);
2052
}
2053
2054
/**
2055
 * Get native english speaking countries
2056
 *
2057
 * @return array
2058
 *
2059
 * @since 7.12.3
2060
 */
2061
function monsterinsights_get_english_speaking_countries() {
2062
	return array(
2063
		'AG' => __( 'Antigua and Barbuda', 'google-analytics-for-wordpress' ),
2064
		'AU' => __( 'Australia', 'google-analytics-for-wordpress' ),
2065
		'BB' => __( 'Barbados', 'google-analytics-for-wordpress' ),
2066
		'BZ' => __( 'Belize', 'google-analytics-for-wordpress' ),
2067
		'BW' => __( 'Botswana', 'google-analytics-for-wordpress' ),
2068
		'BI' => __( 'Burundi', 'google-analytics-for-wordpress' ),
2069
		'CM' => __( 'Cameroon', 'google-analytics-for-wordpress' ),
2070
		'CA' => __( 'Canada', 'google-analytics-for-wordpress' ),
2071
		'DM' => __( 'Dominica', 'google-analytics-for-wordpress' ),
2072
		'FJ' => __( 'Fiji', 'google-analytics-for-wordpress' ),
2073
		'GD' => __( 'Grenada', 'google-analytics-for-wordpress' ),
2074
		'GY' => __( 'Guyana', 'google-analytics-for-wordpress' ),
2075
		'GM' => __( 'Gambia', 'google-analytics-for-wordpress' ),
2076
		'GH' => __( 'Ghana', 'google-analytics-for-wordpress' ),
2077
		'IE' => __( 'Ireland', 'google-analytics-for-wordpress' ),
2078
		'IN' => __( 'India', 'google-analytics-for-wordpress' ),
2079
		'JM' => __( 'Jamaica', 'google-analytics-for-wordpress' ),
2080
		'KE' => __( 'Kenya', 'google-analytics-for-wordpress' ),
2081
		'KI' => __( 'Kiribati', 'google-analytics-for-wordpress' ),
2082
		'LS' => __( 'Lesotho', 'google-analytics-for-wordpress' ),
2083
		'LR' => __( 'Liberia', 'google-analytics-for-wordpress' ),
2084
		'MW' => __( 'Malawi', 'google-analytics-for-wordpress' ),
2085
		'MT' => __( 'Malta', 'google-analytics-for-wordpress' ),
2086
		'MH' => __( 'Marshall Islands', 'google-analytics-for-wordpress' ),
2087
		'MU' => __( 'Mauritius', 'google-analytics-for-wordpress' ),
2088
		'FM' => __( 'Micronesia', 'google-analytics-for-wordpress' ),
2089
		'NZ' => __( 'New Zealand', 'google-analytics-for-wordpress' ),
2090
		'NA' => __( 'Namibia', 'google-analytics-for-wordpress' ),
2091
		'NR' => __( 'Nauru', 'google-analytics-for-wordpress' ),
2092
		'NG' => __( 'Nigeria', 'google-analytics-for-wordpress' ),
2093
		'PK' => __( 'Pakistan', 'google-analytics-for-wordpress' ),
2094
		'PW' => __( 'Palau', 'google-analytics-for-wordpress' ),
2095
		'PG' => __( 'Papua New Guinea', 'google-analytics-for-wordpress' ),
2096
		'PH' => __( 'Philippines', 'google-analytics-for-wordpress' ),
2097
		'RW' => __( 'Rwanda', 'google-analytics-for-wordpress' ),
2098
		'SG' => __( 'Singapore', 'google-analytics-for-wordpress' ),
2099
		'KN' => __( 'St Kitts and Nevis', 'google-analytics-for-wordpress' ),
2100
		'LC' => __( 'St Lucia', 'google-analytics-for-wordpress' ),
2101
		'VC' => __( 'St Vincent and the Grenadines', 'google-analytics-for-wordpress' ),
2102
		'SZ' => __( 'Swaziland', 'google-analytics-for-wordpress' ),
2103
		'WS' => __( 'Samoa', 'google-analytics-for-wordpress' ),
2104
		'SC' => __( 'Seychelles', 'google-analytics-for-wordpress' ),
2105
		'SL' => __( 'Sierra Leone', 'google-analytics-for-wordpress' ),
2106
		'SB' => __( 'Solomon Islands', 'google-analytics-for-wordpress' ),
2107
		'ZA' => __( 'South Africa', 'google-analytics-for-wordpress' ),
2108
		'SS' => __( 'South Sudan', 'google-analytics-for-wordpress' ),
2109
		'SD' => __( 'Sudan', 'google-analytics-for-wordpress' ),
2110
		'TT' => __( 'Trinidad and Tobago', 'google-analytics-for-wordpress' ),
2111
		'BS' => __( 'The Bahamas', 'google-analytics-for-wordpress' ),
2112
		'TZ' => __( 'Tanzania', 'google-analytics-for-wordpress' ),
2113
		'TO' => __( 'Tonga', 'google-analytics-for-wordpress' ),
2114
		'TV' => __( 'Tuvalu', 'google-analytics-for-wordpress' ),
2115
		'GB' => __( 'United Kingdom', 'google-analytics-for-wordpress' ),
2116
		'US' => __( 'United States of America', 'google-analytics-for-wordpress' ),
2117
		'UG' => __( 'Uganda', 'google-analytics-for-wordpress' ),
2118
		'VU' => __( 'Vanuatu', 'google-analytics-for-wordpress' ),
2119
		'ZM' => __( 'Zambia', 'google-analytics-for-wordpress' ),
2120
		'ZW' => __( 'Zimbabwe', 'google-analytics-for-wordpress' ),
2121
	);
2122
}
2123
2124
/**
2125
 * Helper function to check if the current user can install a plugin.
2126
 *
2127
 * @return bool
2128
 */
2129
function monsterinsights_can_install_plugins() {
2130
2131
	if ( ! current_user_can( 'install_plugins' ) ) {
2132
		return false;
2133
	}
2134
2135
	// Determine whether file modifications are allowed.
2136
	if ( function_exists( 'wp_is_file_mod_allowed' ) && ! wp_is_file_mod_allowed( 'monsterinsights_can_install' ) ) {
2137
		return false;
2138
	}
2139
2140
	return true;
2141
}
2142
2143
/**
2144
 * Check if current date is between given dates. Date format: Y-m-d.
2145
 *
2146
 * @param string $start_date Start Date. Eg: 2021-01-01.
2147
 * @param string $end_date End Date. Eg: 2021-01-14.
2148
 *
2149
 * @return bool
2150
 * @since 7.13.2
2151
 */
2152
function monsterinsights_date_is_between( $start_date, $end_date ) {
2153
2154
	$current_date = current_time( 'Y-m-d' );
2155
2156
	$start_date = date( 'Y-m-d', strtotime( $start_date ) );
2157
	$end_date   = date( 'Y-m-d', strtotime( $end_date ) );
2158
2159
	if ( ( $current_date >= $start_date ) && ( $current_date <= $end_date ) ) {
2160
		return true;
2161
	}
2162
2163
	return false;
2164
}
2165
2166
/**
2167
 * Check is All-In-One-Seo plugin is active or not.
2168
 *
2169
 * @return bool
2170
 * @since 7.17.0
2171
 */
2172
function monsterinsights_is_aioseo_active() {
2173
2174
	if ( function_exists( 'aioseo' ) ) {
2175
		return true;
2176
	}
2177
2178
	return false;
2179
}
2180
2181
// /**
2182
//  * Return FunnelKit Stripe Woo Gateway Settings URL if plugin is active.
2183
//  *
2184
//  * @return string
2185
//  * @since 8.24.0
2186
//  */
2187
// function monsterinsights_funnelkit_stripe_woo_gateway_dashboard_url() {
2188
// 	$url = '';
2189
2190
// 	if ( class_exists( 'FKWCS_Gateway_Stripe' ) ) {
2191
// 		$url = is_multisite() ? network_admin_url( 'admin.php?page=wc-settings&tab=fkwcs_api_settings' ) : admin_url( 'admin.php?page=wc-settings&tab=fkwcs_api_settings' );
2192
// 	}
2193
2194
// 	return $url;
2195
// }
2196
2197
/**
2198
 * Return AIOSEO Dashboard URL if plugin is active.
2199
 *
2200
 * @return string
2201
 * @since 7.17.0
2202
 */
2203
function monsterinsights_aioseo_dashboard_url() {
2204
	$url = '';
2205
2206
	if ( function_exists( 'aioseo' ) ) {
2207
		$url = is_multisite() ? network_admin_url( 'admin.php?page=aioseo' ) : admin_url( 'admin.php?page=aioseo' );
2208
	}
2209
2210
	return $url;
2211
}
2212
2213
/**
2214
 * Check if AIOSEO Pro version is installed or not.
2215
 *
2216
 * @return bool
2217
 * @since 7.17.10
2218
 */
2219
function monsterinsights_is_installed_aioseo_pro() {
2220
	$installed_plugins = get_plugins();
2221
2222
	if ( array_key_exists( 'all-in-one-seo-pack-pro/all_in_one_seo_pack.php', $installed_plugins ) ) {
2223
		return true;
2224
	}
2225
2226
	return false;
2227
}
2228
2229
/**
2230
 * Check if Cookiebot plugin functionality active.
2231
 *
2232
 * @since 8.9.0
2233
 *
2234
 * @return bool
2235
 */
2236
function monsterinsights_is_cookiebot_active() {
2237
2238
	if ( function_exists( '\cybot\cookiebot\lib\cookiebot_active' ) ) {
2239
		return \cybot\cookiebot\lib\cookiebot_active();
0 ignored issues
show
Bug introduced by
The function cookiebot_active was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2239
		return /** @scrutinizer ignore-call */ \cybot\cookiebot\lib\cookiebot_active();
Loading history...
2240
	}
2241
2242
	if ( function_exists( 'cookiebot_active' ) ) {
2243
		return cookiebot_active();
2244
	}
2245
2246
	return false;
2247
}
2248
2249
if ( ! function_exists( 'wp_date' ) ) {
2250
	/**
2251
	 * Retrieves the date, in localized format.
2252
	 *
2253
	 * This is a newer function, intended to replace `date_i18n()` without legacy quirks in it.
2254
	 *
2255
	 * Note that, unlike `date_i18n()`, this function accepts a true Unix timestamp, not summed
2256
	 * with timezone offset.
2257
	 *
2258
	 * @since WP 5.3.0
2259
	 *
2260
	 * @global WP_Locale $wp_locale WordPress date and time locale object.
2261
	 *
2262
	 * @param string       $format    PHP date format.
2263
	 * @param int          $timestamp Optional. Unix timestamp. Defaults to current time.
2264
	 * @param DateTimeZone $timezone  Optional. Timezone to output result in. Defaults to timezone
2265
	 *                                from site settings.
2266
	 * @return string|false The date, translated if locale specifies it. False on invalid timestamp input.
2267
	 */
2268
	function wp_date( $format, $timestamp = null, $timezone = null ) {
2269
		global $wp_locale;
2270
2271
		if ( null === $timestamp ) {
2272
			$timestamp = time();
2273
		} elseif ( ! is_numeric( $timestamp ) ) {
0 ignored issues
show
introduced by
The condition is_numeric($timestamp) is always true.
Loading history...
2274
			return false;
2275
		}
2276
2277
		if ( ! $timezone ) {
2278
			$timezone = wp_timezone();
2279
		}
2280
2281
		$datetime = date_create( '@' . $timestamp );
2282
		$datetime->setTimezone( $timezone );
2283
2284
		if ( empty( $wp_locale->month ) || empty( $wp_locale->weekday ) ) {
2285
			$date = $datetime->format( $format );
2286
		} else {
2287
			// We need to unpack shorthand `r` format because it has parts that might be localized.
2288
			$format = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $format );
2289
2290
			$new_format    = '';
2291
			$format_length = strlen( $format );
2292
			$month         = $wp_locale->get_month( $datetime->format( 'm' ) );
2293
			$weekday       = $wp_locale->get_weekday( $datetime->format( 'w' ) );
2294
2295
			for ( $i = 0; $i < $format_length; $i ++ ) {
2296
				switch ( $format[ $i ] ) {
2297
					case 'D':
2298
						$new_format .= addcslashes( $wp_locale->get_weekday_abbrev( $weekday ), '\\A..Za..z' );
2299
						break;
2300
					case 'F':
2301
						$new_format .= addcslashes( $month, '\\A..Za..z' );
2302
						break;
2303
					case 'l':
2304
						$new_format .= addcslashes( $weekday, '\\A..Za..z' );
2305
						break;
2306
					case 'M':
2307
						$new_format .= addcslashes( $wp_locale->get_month_abbrev( $month ), '\\A..Za..z' );
2308
						break;
2309
					case 'a':
2310
						$new_format .= addcslashes( $wp_locale->get_meridiem( $datetime->format( 'a' ) ), '\\A..Za..z' );
2311
						break;
2312
					case 'A':
2313
						$new_format .= addcslashes( $wp_locale->get_meridiem( $datetime->format( 'A' ) ), '\\A..Za..z' );
2314
						break;
2315
					case '\\':
2316
						$new_format .= $format[ $i ];
2317
2318
						// If character follows a slash, we add it without translating.
2319
						if ( $i < $format_length ) {
2320
							$new_format .= $format[ ++$i ];
2321
						}
2322
						break;
2323
					default:
2324
						$new_format .= $format[ $i ];
2325
						break;
2326
				}
2327
			}
2328
2329
			$date = $datetime->format( $new_format );
2330
			$date = wp_maybe_decline_date( $date, $format );
2331
		}
2332
2333
		/**
2334
		 * Filters the date formatted based on the locale.
2335
		 *
2336
		 * @since WP 5.3.0
2337
		 *
2338
		 * @param string       $date      Formatted date string.
2339
		 * @param string       $format    Format to display the date.
2340
		 * @param int          $timestamp Unix timestamp.
2341
		 * @param DateTimeZone $timezone  Timezone.
2342
		 */
2343
		$date = apply_filters( 'wp_date', $date, $format, $timestamp, $timezone );
2344
2345
		return $date;
2346
	}
2347
}
2348
2349
if ( ! function_exists( 'wp_timezone_string' ) ) {
2350
	/**
2351
	 * Retrieves the timezone of the site as a string.
2352
	 *
2353
	 * Uses the `timezone_string` option to get a proper timezone name if available,
2354
	 * otherwise falls back to a manual UTC ± offset.
2355
	 *
2356
	 * Example return values:
2357
	 *
2358
	 *  - 'Europe/Rome'
2359
	 *  - 'America/North_Dakota/New_Salem'
2360
	 *  - 'UTC'
2361
	 *  - '-06:30'
2362
	 *  - '+00:00'
2363
	 *  - '+08:45'
2364
	 *
2365
	 * @since WP 5.3.0
2366
	 *
2367
	 * @return string PHP timezone name or a ±HH:MM offset.
2368
	 */
2369
	function wp_timezone_string() {
2370
		$timezone_string = get_option( 'timezone_string' );
2371
2372
		if ( $timezone_string ) {
2373
			return $timezone_string;
2374
		}
2375
2376
		$offset  = (float) get_option( 'gmt_offset' );
2377
		$hours   = (int) $offset;
2378
		$minutes = ( $offset - $hours );
2379
2380
		$sign      = ( $offset < 0 ) ? '-' : '+';
2381
		$abs_hour  = abs( $hours );
2382
		$abs_mins  = abs( $minutes * 60 );
2383
		$tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
2384
2385
		return $tz_offset;
2386
	}
2387
}
2388
2389
if ( ! function_exists( 'wp_timezone' ) ) {
2390
	/**
2391
	 * Retrieves the timezone of the site as a `DateTimeZone` object.
2392
	 *
2393
	 * Timezone can be based on a PHP timezone string or a ±HH:MM offset.
2394
	 *
2395
	 * @since WP 5.3.0
2396
	 *
2397
	 * @return DateTimeZone Timezone object.
2398
	 */
2399
	function wp_timezone() {
2400
		return new DateTimeZone( wp_timezone_string() );
2401
	}
2402
}
2403
2404
if ( ! function_exists( 'current_datetime' ) ) {
2405
	/**
2406
	 * Retrieves the current time as an object using the site's timezone.
2407
	 *
2408
	 * @since WP 5.3.0
2409
	 *
2410
	 * @return DateTimeImmutable Date and time object.
2411
	 */
2412
	function current_datetime() {
2413
		return new DateTimeImmutable( 'now', wp_timezone() );
2414
	}
2415
}
2416
2417
2418
if ( ! function_exists( 'monsterinsights_is_authed' ) ) {
2419
	function monsterinsights_is_authed() {
2420
		$site_profile = get_option('monsterinsights_site_profile');
2421
		return isset($site_profile['key']);
2422
	}
2423
}
2424