Passed
Push — master ( a722cd...843c92 )
by Chris
03:45
created

MonsterInsights_Rest_Routes::handle_sanitization()   B

Complexity

Conditions 9
Paths 11

Size

Total Lines 42
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 22
nc 11
nop 2
dl 0
loc 42
rs 8.0555
c 0
b 0
f 0
1
<?php
2
/**
3
 * Routes for VUE are registered here.
4
 *
5
 * @package monsterinsights
6
 */
7
8
/**
9
 * Class MonsterInsights_Rest_Routes
10
 */
11
class MonsterInsights_Rest_Routes {
12
13
	/**
14
	 * MonsterInsights_Rest_Routes constructor.
15
	 */
16
	public function __construct() {
17
18
		add_action( 'wp_ajax_monsterinsights_vue_get_license', array( $this, 'get_license' ) );
19
		add_action( 'wp_ajax_monsterinsights_vue_get_profile', array( $this, 'get_profile' ) );
20
		add_action( 'wp_ajax_monsterinsights_vue_get_settings', array( $this, 'get_settings' ) );
21
		add_action( 'wp_ajax_monsterinsights_vue_update_settings', array( $this, 'update_settings' ) );
22
		add_action( 'wp_ajax_monsterinsights_vue_get_addons', array( $this, 'get_addons' ) );
23
		add_action( 'wp_ajax_monsterinsights_update_manual_ua', array( $this, 'update_manual_ua' ) );
24
		add_action( 'wp_ajax_monsterinsights_vue_get_report_data', array( $this, 'get_report_data' ) );
25
		add_action( 'wp_ajax_monsterinsights_vue_install_plugin', array( $this, 'install_plugin' ) );
26
27
		add_action( 'wp_ajax_monsterinsights_handle_settings_import', array( $this, 'handle_settings_import' ) );
28
29
		add_action( 'admin_notices', array( $this, 'hide_old_notices' ), 0 );
30
	}
31
32
	/**
33
	 * Ajax handler for grabbing the license
34
	 */
35
	public function get_license() {
36
37
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
38
39
		if ( ! current_user_can( 'monsterinsights_view_dashboard' ) ) {
40
			return;
41
		}
42
43
		$site_license    = array(
44
			'key'         => MonsterInsights()->license->get_site_license_key(),
45
			'type'        => MonsterInsights()->license->get_site_license_type(),
46
			'is_disabled' => MonsterInsights()->license->site_license_disabled(),
47
			'is_expired'  => MonsterInsights()->license->site_license_expired(),
48
			'is_invalid'  => MonsterInsights()->license->site_license_invalid(),
49
		);
50
		$network_license = array(
51
			'key'         => MonsterInsights()->license->get_network_license_key(),
52
			'type'        => MonsterInsights()->license->get_network_license_type(),
53
			'is_disabled' => MonsterInsights()->license->network_license_disabled(),
54
			'is_expired'  => MonsterInsights()->license->network_license_expired(),
55
			'is_invalid'  => MonsterInsights()->license->network_license_disabled(),
56
		);
57
58
		wp_send_json( array(
59
			'site'    => $site_license,
60
			'network' => $network_license,
61
		) );
62
63
	}
64
65
	/**
66
	 * Ajax handler for grabbing the license
67
	 */
68
	public function get_profile() {
69
70
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
71
72
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
73
			return;
74
		}
75
76
		wp_send_json( array(
77
			'ua'                => MonsterInsights()->auth->get_ua(),
78
			'viewname'          => MonsterInsights()->auth->get_viewname(),
79
			'manual_ua'         => MonsterInsights()->auth->get_manual_ua(),
80
			'network_ua'        => MonsterInsights()->auth->get_network_ua(),
81
			'network_viewname'  => MonsterInsights()->auth->get_network_viewname(),
82
			'network_manual_ua' => MonsterInsights()->auth->get_network_manual_ua(),
83
		) );
84
85
	}
86
87
	/**
88
	 * Ajax handler for grabbing the license
89
	 */
90
	public function get_settings() {
91
92
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
93
94
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
95
			return;
96
		}
97
98
		$options = monsterinsights_get_options();
99
100
		// Array fields are needed even if empty.
101
		$array_fields = array( 'view_reports', 'save_settings', 'ignore_users' );
102
		foreach ( $array_fields as $array_field ) {
103
			if ( ! isset( $options[ $array_field ] ) ) {
104
				$options[ $array_field ] = array();
105
			}
106
		}
107
		if ( isset( $options['custom_code'] ) ) {
108
			$options['custom_code'] = stripslashes( $options['custom_code'] );
109
		}
110
111
		wp_send_json( $options );
112
113
	}
114
115
	/**
116
	 * Ajax handler for grabbing the license
117
	 */
118
	public function update_settings() {
119
120
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
121
122
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
123
			return;
124
		}
125
126
		if ( isset( $_POST['setting'] ) ) {
127
			$setting = sanitize_text_field( wp_unslash( $_POST['setting'] ) );
128
			if ( isset( $_POST['value'] ) ) {
129
				$value = $this->handle_sanitization( $setting, $_POST['value'] );
130
				monsterinsights_update_option( $setting, $value );
131
			} else {
132
				monsterinsights_update_option( $setting, false );
133
			}
134
		}
135
136
		wp_send_json_success();
137
138
	}
139
140
	/**
141
	 * Sanitization specific to each field.
142
	 *
143
	 * @param string $field The key of the field to sanitize.
144
	 * @param string $value The value of the field to sanitize.
145
	 *
146
	 * @return mixed The sanitized input.
147
	 */
148
	private function handle_sanitization( $field, $value ) {
149
150
		$value = wp_unslash( $value );
151
152
		// Textarea fields.
153
		$textarea_fields = array(
154
			'custom_code',
155
		);
156
157
		if ( in_array( $field, $textarea_fields, true ) ) {
158
			if ( function_exists( 'sanitize_textarea_field' ) ) {
159
				return sanitize_textarea_field( $value );
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, parameter $str of sanitize_textarea_field() does only seem to accept 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

159
				return sanitize_textarea_field( /** @scrutinizer ignore-type */ $value );
Loading history...
160
			} else {
161
				return wp_kses( $value, array() );
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, parameter $string of wp_kses() does only seem to accept 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

161
				return wp_kses( /** @scrutinizer ignore-type */ $value, array() );
Loading history...
162
			}
163
		}
164
165
		$array_value = json_decode( $value, true );
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, parameter $json of json_decode() does only seem to accept 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

165
		$array_value = json_decode( /** @scrutinizer ignore-type */ $value, true );
Loading history...
166
		if ( is_array( $array_value ) ) {
167
			$value = $array_value;
168
			// Don't save empty values.
169
			foreach ( $value as $key => $item ) {
170
				if ( is_array( $item ) ) {
171
					$empty = true;
172
					foreach ( $item as $item_value ) {
173
						if ( ! empty( $item_value ) ) {
174
							$empty = false;
175
						}
176
					}
177
					if ( $empty ) {
178
						unset( $value[ $key ] );
179
					}
180
				}
181
			}
182
183
			// Reset array keys because JavaScript can't handle arrays with non-sequential keys.
184
			$value = array_values( $value );
185
186
			return $value;
187
		}
188
189
		return sanitize_text_field( $value );
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, parameter $str of sanitize_text_field() does only seem to accept 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

189
		return sanitize_text_field( /** @scrutinizer ignore-type */ $value );
Loading history...
190
191
	}
192
193
	/**
194
	 * Return the state of the addons ( installed, activated )
195
	 */
196
	public function get_addons() {
197
198
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
199
200
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
201
			return;
202
		}
203
204
		if ( isset( $_POST['network'] ) && intval( $_POST['network'] ) > 0 ) {
205
			define( 'WP_NETWORK_ADMIN', true );
206
		}
207
208
		$addons_data       = monsterinsights_get_addons();
209
		$parsed_addons     = array();
210
		$installed_plugins = get_plugins();
211
212
		if ( ! is_array( $addons_data ) ) {
213
			$addons_data = array();
214
		}
215
216
		foreach ( $addons_data as $addons_type => $addons ) {
217
			foreach ( $addons as $addon ) {
218
				$slug = 'monsterinsights-' . $addon->slug;
219
				if ( 'monsterinsights-ecommerce' === $slug ) {
220
					$addon = $this->get_addon( $installed_plugins, $addons_type, $addon, $slug );
221
					if ( empty( $addon->installed ) ) {
222
						$slug  = 'ga-ecommerce';
223
						$addon = $this->get_addon( $installed_plugins, $addons_type, $addon, $slug );
224
					}
225
				} else {
226
					$addon = $this->get_addon( $installed_plugins, $addons_type, $addon, $slug );
227
				}
228
				$parsed_addons[ $addon->slug ] = $addon;
229
			}
230
		}
231
232
		// Include data about the plugins needed by some addons ( WooCommerce, EDD, Google AMP, CookieBot, etc ).
233
		// WooCommerce.
234
		$parsed_addons['woocommerce'] = array(
235
			'active' => class_exists( 'WooCommerce' ),
236
		);
237
		// Edd.
238
		$parsed_addons['easy_digital_downloads'] = array(
239
			'active' => class_exists( 'Easy_Digital_Downloads' ),
240
		);
241
		// MemberPress.
242
		$parsed_addons['memberpress'] = array(
243
			'active' => defined( 'MEPR_VERSION' ) && version_compare( MEPR_VERSION, '1.3.43', '>' ),
0 ignored issues
show
Bug introduced by
The constant MEPR_VERSION was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
244
		);
245
		// Cookiebot.
246
		$parsed_addons['cookiebot'] = array(
247
			'active' => function_exists( 'cookiebot_active' ) && cookiebot_active(),
248
		);
249
		// Cookie Notice.
250
		$parsed_addons['cookie_notice'] = array(
251
			'active' => class_exists( 'Cookie_Notice' ),
252
		);
253
		// Fb Instant Articles.
254
		$parsed_addons['instant_articles'] = array(
255
			'active' => defined( 'IA_PLUGIN_VERSION' ) && version_compare( IA_PLUGIN_VERSION, '3.3.4', '>' ),
0 ignored issues
show
Bug introduced by
The constant IA_PLUGIN_VERSION was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
256
		);
257
		// Google AMP.
258
		$parsed_addons['google_amp'] = array(
259
			'active' => defined( 'AMP__FILE__' ),
260
		);
261
		// WPForms.
262
		$parsed_addons['wpforms'] = array(
263
			'active'    => function_exists( 'wpforms' ),
264
			'icon'      => plugin_dir_url( MONSTERINSIGHTS_PLUGIN_FILE ) . 'assets/images/plugin-wpforms.png',
265
			'title'     => 'WPForms',
266
			'excerpt'   => __( 'The most beginner friendly drag & drop WordPress forms plugin allowing you to create beautiful contact forms, subscription forms, payment forms, and more in minutes, not hours!', 'google-analytics-for-wordpress' ),
267
			'installed' => array_key_exists( 'wpforms-lite/wpforms.php', $installed_plugins ),
268
			'slug'      => 'wpforms-lite',
269
		);
270
		// OptinMonster.
271
		$parsed_addons['optinmonster'] = array(
272
			'active'    => class_exists( 'OMAPI' ),
273
			'icon'      => plugin_dir_url( MONSTERINSIGHTS_PLUGIN_FILE ) . 'assets/images/plugin-om.png',
274
			'title'     => 'OptinMonster',
275
			'excerpt'   => __( 'Our high-converting optin forms like Exit-Intent® popups, Fullscreen Welcome Mats, and Scroll boxes help you dramatically boost conversions and get more email subscribers.', 'google-analytics-for-wordpress' ),
276
			'installed' => array_key_exists( 'optinmonster/optin-monster-wp-api.php', $installed_plugins ),
277
			'basename'  => 'optinmonster/optin-monster-wp-api.php',
278
			'slug'      => 'optinmonster',
279
		);
280
		// OptinMonster.
281
		$parsed_addons['wp-mail-smtp'] = array(
282
			'active'    => function_exists( 'wp_mail_smtp' ),
283
			'icon'      => plugin_dir_url( MONSTERINSIGHTS_PLUGIN_FILE ) . 'assets/images/plugin-smtp.png',
284
			'title'     => 'WP Mail SMTP',
285
			'excerpt'   => __( 'SMTP (Simple Mail Transfer Protocol) is an industry standard for sending emails. SMTP helps increase email deliverability by using proper authentication', 'google-analytics-for-wordpress' ),
286
			'installed' => array_key_exists( 'optinmonster/optin-monster-wp-api.php', $installed_plugins ),
287
			'basename'  => 'wp-mail-smtp/wp_mail_smtp.php',
288
			'slug'      => 'wp-mail-smtp',
289
		);
290
		// Gravity Forms.
291
		$parsed_addons['gravity_forms'] = array(
292
			'active' => class_exists( 'GFCommon' ),
293
		);
294
		// Formidable Forms.
295
		$parsed_addons['formidable_forms'] = array(
296
			'active' => class_exists( 'FrmHooksController' ),
297
		);
298
		// Manual UA Addon.
299
		if ( ! isset( $parsed_addons['manual_ua'] ) ) {
300
			$parsed_addons['manual_ua'] = array(
301
				'active' => class_exists( 'MonsterInsights_Manual_UA' ),
302
			);
303
		}
304
305
		wp_send_json( $parsed_addons );
306
	}
307
308
	public function get_addon( $installed_plugins, $addons_type, $addon, $slug ) {
309
		$active          = false;
310
		$installed       = false;
311
		$plugin_basename = monsterinsights_get_plugin_basename_from_slug( $slug );
312
313
		if ( isset( $installed_plugins[ $plugin_basename ] ) ) {
314
			$installed = true;
315
			$ms_active = is_plugin_active_for_network( $plugin_basename );
0 ignored issues
show
Unused Code introduced by
The assignment to $ms_active is dead and can be removed.
Loading history...
316
			$ss_active = is_plugin_active( $plugin_basename );
0 ignored issues
show
Unused Code introduced by
The assignment to $ss_active is dead and can be removed.
Loading history...
317
318
			if ( is_multisite() && is_network_admin() ) {
319
				$active = is_plugin_active_for_network( $plugin_basename );
320
			} else {
321
				$active = is_plugin_active( $plugin_basename );
322
			}
323
		}
324
		if ( empty( $addon->url ) ) {
325
			$addon->url = '';
326
		}
327
328
		$addon->type      = $addons_type;
329
		$addon->installed = $installed;
330
		$addon->active    = $active;
331
		$addon->basename  = $plugin_basename;
332
333
		return $addon;
334
	}
335
336
	/**
337
	 * Use custom notices in the Vue app on the Settings screen.
338
	 */
339
	public function hide_old_notices() {
340
341
		global $wp_version;
342
		if ( version_compare( $wp_version, '4.6', '<' ) ) {
343
			// remove_all_actions triggers an infinite loop on older versions.
344
			return;
345
		}
346
347
		$screen = get_current_screen();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $screen is correct as get_current_screen() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
348
		// Bail if we're not on a MonsterInsights screen.
349
		if ( empty( $screen->id ) || strpos( $screen->id, 'monsterinsights' ) === false ) {
350
			return;
351
		}
352
353
		// Hide admin notices on the settings screen.
354
		if ( monsterinsights_is_settings_page() ) {
355
			remove_all_actions( 'admin_notices' );
356
		}
357
358
	}
359
360
	/**
361
	 * Update manual ua.
362
	 */
363
	public function update_manual_ua() {
364
365
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
366
367
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
368
			return;
369
		}
370
371
		$manual_ua_code     = isset( $_POST['manual_ua_code'] ) ? sanitize_text_field( wp_unslash( $_POST['manual_ua_code'] ) ) : '';
372
		$manual_ua_code     = monsterinsights_is_valid_ua( $manual_ua_code ); // Also sanitizes the string.
373
		$manual_ua_code_old = MonsterInsights()->auth->get_manual_ua();
374
		if ( ! empty( $_REQUEST['isnetwork'] ) && sanitize_text_field( wp_unslash( $_REQUEST['isnetwork'] ) ) ) {
375
			define( 'WP_NETWORK_ADMIN', true );
376
		}
377
378
		if ( $manual_ua_code && $manual_ua_code_old && $manual_ua_code_old === $manual_ua_code ) {
379
			// Same code we had before
380
			// Do nothing.
381
			wp_send_json_success();
382
		} else if ( $manual_ua_code && $manual_ua_code_old && $manual_ua_code_old !== $manual_ua_code ) {
383
			// Different UA code.
384
			if ( is_network_admin() ) {
385
				MonsterInsights()->auth->set_network_manual_ua( $manual_ua_code );
386
			} else {
387
				MonsterInsights()->auth->set_manual_ua( $manual_ua_code );
388
			}
389
		} else if ( $manual_ua_code && empty( $manual_ua_code_old ) ) {
390
			// Move to manual.
391
			if ( is_network_admin() ) {
392
				MonsterInsights()->auth->set_network_manual_ua( $manual_ua_code );
393
			} else {
394
				MonsterInsights()->auth->set_manual_ua( $manual_ua_code );
395
			}
396
		} else if ( empty( $manual_ua_code ) && $manual_ua_code_old ) {
397
			// Deleted manual.
398
			if ( is_network_admin() ) {
399
				MonsterInsights()->auth->delete_network_manual_ua();
400
			} else {
401
				MonsterInsights()->auth->delete_manual_ua();
402
			}
403
		} else if ( isset( $_POST['manual_ua_code'] ) && empty( $manual_ua_code ) ) {
404
			wp_send_json_error( array(
405
				'error' => __( 'Invalid UA code', 'google-analytics-for-wordpress' ),
406
			) );
407
		}
408
409
		wp_send_json_success();
410
	}
411
412
	/**
413
	 *
414
	 */
415
	public function handle_settings_import() {
416
417
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
418
419
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
420
			return;
421
		}
422
423
		if ( ! isset( $_FILES['import_file'] ) ) {
424
			return;
425
		}
426
427
		$extension = explode( '.', sanitize_text_field( wp_unslash( $_FILES['import_file']['name'] ) ) );
428
		$extension = end( $extension );
429
430
		if ( 'json' !== $extension ) {
431
			wp_send_json_error( array(
432
				'message' => esc_html__( 'Please upload a valid .json file', 'google-analytics-for-wordpress' ),
433
			) );
434
		}
435
436
		$import_file = sanitize_text_field( wp_unslash( $_FILES['import_file']['tmp_name'] ) );
437
438
		$file = file_get_contents( $import_file );
439
		if ( empty( $file ) ) {
440
			wp_send_json_error( array(
441
				'message' => esc_html__( 'Please upload a file to import', 'google-analytics-for-wordpress' ),
442
			) );
443
		}
444
445
		// Retrieve the settings from the file and convert the json object to an array.
446
		$new_settings = json_decode( wp_json_encode( json_decode( $file ) ), true );
447
		$settings     = monsterinsights_get_options();
448
		$exclude      = array(
449
			'analytics_profile',
450
			'analytics_profile_code',
451
			'analytics_profile_name',
452
			'oauth_version',
453
			'cron_last_run',
454
			'monsterinsights_oauth_status',
455
		);
456
457
		foreach ( $exclude as $e ) {
458
			if ( ! empty( $new_settings[ $e ] ) ) {
459
				unset( $new_settings[ $e ] );
460
			}
461
		}
462
463
		if ( ! is_super_admin() ) {
464
			if ( ! empty( $new_settings['custom_code'] ) ) {
465
				unset( $new_settings['custom_code'] );
466
			}
467
		}
468
469
		foreach ( $exclude as $e ) {
470
			if ( ! empty( $settings[ $e ] ) ) {
471
				$new_settings = $settings[ $e ];
472
			}
473
		}
474
475
		global $monsterinsights_settings;
476
		$monsterinsights_settings = $new_settings;
477
478
		update_option( monsterinsights_get_option_name(), $new_settings );
479
480
		wp_send_json_success( $new_settings );
481
482
	}
483
484
	/**
485
	 * Generic Ajax handler for grabbing report data in JSON.
486
	 */
487
	public function get_report_data() {
488
489
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
490
491
		if ( ! current_user_can( 'monsterinsights_view_dashboard' ) ) {
492
			wp_send_json_error( array( 'message' => __( "You don't have permission to view MonsterInsights reports.", 'google-analytics-for-wordpress' ) ) );
493
		}
494
495
		if ( ! empty( $_REQUEST['isnetwork'] ) && $_REQUEST['isnetwork'] ) {
496
			define( 'WP_NETWORK_ADMIN', true );
497
		}
498
		$settings_page = admin_url( 'admin.php?page=monsterinsights_settings' );
499
500
		// Only for Pro users, require a license key to be entered first so we can link to things.
501
		if ( monsterinsights_is_pro_version() ) {
502
			if ( ! MonsterInsights()->license->is_site_licensed() && ! MonsterInsights()->license->is_network_licensed() ) {
503
				wp_send_json_error( array(
504
					'message' => __( "You can't view MonsterInsights reports because you are not licensed.", 'google-analytics-for-wordpress' ),
505
					'footer'  => '<a href="' . $settings_page . '">' . __( 'Add your license', 'google-analytics-for-wordpress' ) . '</a>',
506
				) );
507
			} else if ( MonsterInsights()->license->is_site_licensed() && ! MonsterInsights()->license->site_license_has_error() ) {
508
				// Good to go: site licensed.
509
			} else if ( MonsterInsights()->license->is_network_licensed() && ! MonsterInsights()->license->network_license_has_error() ) {
510
				// Good to go: network licensed.
511
			} else {
512
				wp_send_json_error( array( 'message' => __( "You can't view MonsterInsights reports due to license key errors.", 'google-analytics-for-wordpress' ) ) );
513
			}
514
		}
515
516
		// We do not have a current auth.
517
		$site_auth = MonsterInsights()->auth->get_viewname();
518
		$ms_auth   = is_multisite() && MonsterInsights()->auth->get_network_viewname();
519
		if ( ! $site_auth && ! $ms_auth ) {
520
			wp_send_json_error( array( 'message' => __( 'You must authenticate with MonsterInsights before you can view reports.', 'google-analytics-for-wordpress' ) ) );
521
		}
522
523
		$report_name = isset( $_POST['report'] ) ? sanitize_text_field( wp_unslash( $_POST['report'] ) ) : '';
524
525
		if ( empty( $report_name ) ) {
526
			wp_send_json_error( array( 'message' => __( 'Unknown report. Try refreshing and retrying. Contact support if this issue persists.', 'google-analytics-for-wordpress' ) ) );
527
		}
528
529
		$report = MonsterInsights()->reporting->get_report( $report_name );
530
531
		$isnetwork = ! empty( $_REQUEST['isnetwork'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['isnetwork'] ) ) : '';
532
		$start     = ! empty( $_POST['start'] ) ? sanitize_text_field( wp_unslash( $_POST['start'] ) ) : '';
533
		$end       = ! empty( $_POST['end'] ) ? sanitize_text_field( wp_unslash( $_POST['end'] ) ) : '';
534
		$args      = array(
535
			'start' => $start,
536
			'end'   => $end,
537
		);
538
		if ( $isnetwork ) {
539
			$args['network'] = true;
540
		}
541
542
		if ( ! MonsterInsights()->license->license_can( $report->level ) ) {
543
			$data = array(
544
				'success' => false,
545
				'error'   => 'license_level',
546
			);
547
		} else {
548
			$data = apply_filters( 'monsterinsights_vue_reports_data', $report->get_data( $args ), $report_name, $report );
549
		}
550
551
		if ( ! empty( $data['success'] ) && ! empty( $data['data'] ) ) {
552
			wp_send_json_success( $data['data'] );
553
		} else if ( isset( $data['success'] ) && false === $data['success'] && ! empty( $data['error'] ) ) {
554
			wp_send_json_error(
555
				array(
556
					'message' => $data['error'],
557
					'footer'  => isset( $data['data']['footer'] ) ? $data['data']['footer'] : '',
558
				)
559
			);
560
		}
561
562
		wp_send_json_error( array( 'message' => __( 'We encountered an error when fetching the report data.', 'google-analytics-for-wordpress' ) ) );
563
564
	}
565
566
	/**
567
	 * Install plugins which are not addons.
568
	 */
569
	public function install_plugin() {
570
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
571
572
		if ( ! current_user_can( 'install_plugins' ) ) {
573
			wp_send_json( array(
574
				'message' => esc_html__( 'You are not allowed to install plugins', 'ga-premium' ),
575
			) );
576
		}
577
578
		$slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : false;
579
580
		if ( ! $slug ) {
581
			wp_send_json( array(
582
				'message' => esc_html__( 'Missing plugin name.', 'ga-premium' ),
583
			) );
584
		}
585
586
		include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
587
588
		$api = plugins_api( 'plugin_information', array(
589
			'slug'   => $slug,
590
			'fields' => array(
591
				'short_description' => false,
592
				'sections'          => false,
593
				'requires'          => false,
594
				'rating'            => false,
595
				'ratings'           => false,
596
				'downloaded'        => false,
597
				'last_updated'      => false,
598
				'added'             => false,
599
				'tags'              => false,
600
				'compatibility'     => false,
601
				'homepage'          => false,
602
				'donate_link'       => false,
603
			),
604
		) );
605
606
		if ( is_wp_error( $api ) ) {
607
			return $api->get_error_message();
608
		}
609
610
		$download_url = $api->download_link;
611
612
		$method = '';
613
		$url    = add_query_arg(
614
			array(
615
				'page' => 'monsterinsights-settings',
616
			),
617
			admin_url( 'admin.php' )
618
		);
619
		$url    = esc_url( $url );
620
621
		ob_start();
622
		if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, null ) ) ) {
623
			$form = ob_get_clean();
624
625
			wp_send_json( array( 'form' => $form ) );
626
		}
627
628
		// If we are not authenticated, make it happen now.
629
		if ( ! WP_Filesystem( $creds ) ) {
630
			ob_start();
631
			request_filesystem_credentials( $url, $method, true, false, null );
632
			$form = ob_get_clean();
633
634
			wp_send_json( array( 'form' => $form ) );
635
636
		}
637
638
		// We do not need any extra credentials if we have gotten this far, so let's install the plugin.
639
		require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
640
		$base = MonsterInsights();
641
		require_once plugin_dir_path( $base->file ) . '/includes/admin/licensing/skin.php';
642
643
		// Create the plugin upgrader with our custom skin.
644
		$installer = new Plugin_Upgrader( new MonsterInsights_Skin() );
645
		$installer->install( $download_url );
646
647
		// Flush the cache and return the newly installed plugin basename.
648
		wp_cache_flush();
649
		wp_send_json_success();
650
651
		wp_die();
652
	}
653
}
654