Issues (8)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

review.php (8 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * WP Review Me
4
 *
5
 * A lightweight library to help you get more reviews for your WordPress theme/plugin.
6
 *
7
 * LICENSE: This program is free software; you can redistribute it and/or modify it under the terms of the GNU
8
 * General Public License as published by the Free Software Foundation; either version 3 of the License, or (at
9
 * your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY
10
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
 * General Public License for more details. You should have received a copy of the GNU General Public License along
12
 * with this program. If not, see <http://opensource.org/licenses/gpl-license.php>
13
 *
14
 * @package   WP Review Me
15
 * @author    Julien Liabeuf <[email protected]>
16
 * @version   2.0.1
17
 * @license   GPL-2.0+
18
 * @link      https://julienliabeuf.com
19
 * @copyright 2016 Julien Liabeuf
20
 */
21
22
if ( ! class_exists( 'WP_Review_Me' ) ) {
23
24
	class WP_Review_Me {
25
26
		/**
27
		 * Library version
28
		 *
29
		 * @since 1.0
30
		 * @var string
31
		 */
32
		public $version = '2.0.1';
33
34
		/**
35
		 * Required version of PHP.
36
		 *
37
		 * @since 1.0
38
		 * @var string
39
		 */
40
		public $php_version_required = '5.5';
41
42
		/**
43
		 * Minimum version of WordPress required to use the library
44
		 *
45
		 * @since 1.0
46
		 * @var string
47
		 */
48
		public $wordpress_version_required = '4.2';
49
50
		/**
51
		 * Holds the unique identifying key for this particular instance
52
		 *
53
		 * @since 1.0
54
		 * @var string
55
		 */
56
		protected $key;
57
58
		/**
59
		 * Link unique ID
60
		 *
61
		 * @since 1.0
62
		 * @var string
63
		 */
64
		public $link_id;
65
66
		/**
67
		 * WP_Review_Me constructor.
68
		 *
69
		 * @since 1.0
70
		 *
71
		 * @param array $args Object settings
72
		 */
73
		public function __construct( $args ) {
74
75
			$args             = wp_parse_args( $args, $this->get_defaults() );
76
			$this->days       = $args['days_after'];
0 ignored issues
show
The property days does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
77
			$this->type       = $args['type'];
0 ignored issues
show
The property type does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
78
			$this->slug       = $args['slug'];
0 ignored issues
show
The property slug does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
79
			$this->rating     = $args['rating'];
0 ignored issues
show
The property rating does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
80
			$this->message    = $args['message'];
0 ignored issues
show
The property message does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
81
			$this->link_label = $args['link_label'];
0 ignored issues
show
The property link_label does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
82
			$this->cap        = $args['cap'];
0 ignored issues
show
The property cap does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
83
			$this->scope      = $args['scope'];
0 ignored issues
show
The property scope does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
84
85
			// Set the unique identifying key for this instance
86
			$this->key     = 'wrm_' . substr( md5( plugin_basename( __FILE__ ) ), 0, 20 );
87
			$this->link_id = 'wrm-review-link-' . $this->key;
88
89
			// Instantiate
90
			$this->init();
91
92
		}
93
94
		/**
95
		 * Get default object settings
96
		 *
97
		 * @since 1.0
98
		 * @return array
99
		 */
100
		protected function get_defaults() {
101
102
			$defaults = array(
103
				'days_after' => 10,
104
				'type'       => '',
105
				'slug'       => '',
106
				'rating'     => 5,
107
				'message'    => sprintf( esc_html__( 'Hey! It&#039;s been a little while that you&#039;ve been using this product. You might not realize it, but user reviews are such a great help to us. We would be so grateful if you could take a minute to leave a review on WordPress.org. Many thanks in advance :)', 'wp-review-me' ) ),
108
				'link_label' => esc_html__( 'Click here to leave your review', 'wp-review-me' ),
109
				// Parameters used in WP Dismissible Notices Handler
110
				'cap'        => 'administrator',
111
				'scope'      => 'global',
112
			);
113
114
			return $defaults;
115
116
		}
117
118
		/**
119
		 * Initialize the library
120
		 *
121
		 * @since 1.0
122
		 * @return void
123
		 */
124
		private function init() {
125
126
			// Make sure WordPress is compatible
127
			if ( ! $this->is_wp_compatible() ) {
128
				$this->spit_error(
129
					sprintf(
130
						esc_html__( 'The library can not be used because your version of WordPress is too old. You need version %s at least.', 'wp-review-me' ),
131
						$this->wordpress_version_required
132
					)
133
				);
134
135
				return;
136
			}
137
138
			// Make sure PHP is compatible
139
			if ( ! $this->is_php_compatible() ) {
140
				$this->spit_error(
141
					sprintf(
142
						esc_html__( 'The library can not be used because your version of PHP is too old. You need version %s at least.', 'wp-review-me' ),
143
						$this->php_version_required
144
					)
145
				);
146
147
				return;
148
			}
149
150
			// Make sure the dependencies are loaded
151
			if ( ! function_exists( 'dnh_register_notice' ) ) {
152
153
				$dnh_file = trailingslashit( plugin_dir_path( __FILE__ ) ) . 'vendor/julien731/wp-dismissible-notices-handler/handler.php';
154
155
				if ( file_exists( $dnh_file ) ) {
156
					require( $dnh_file );
157
				}
158
159
				if ( ! function_exists( 'dnh_register_notice' ) ) {
160
					$this->spit_error(
161
						sprintf(
162
							esc_html__( 'Dependencies are missing. Please run a %s.', 'wp-review-me' ),
163
							'<code>composer install</code>'
164
						)
165
					);
166
167
					return;
168
				}
169
			}
170
171
			add_action( 'admin_footer', array( $this, 'script' ) );
172
			add_action( 'wp_ajax_wrm_clicked_review', array( $this, 'dismiss_notice' ) );
173
174
			// And let's roll... maybe.
175
			$this->maybe_prompt();
176
177
		}
178
179
		/**
180
		 * Check if the current WordPress version fits the requirements
181
		 *
182
		 * @since  1.0
183
		 * @return boolean
184
		 */
185
		private function is_wp_compatible() {
186
187
			if ( version_compare( get_bloginfo( 'version' ), $this->wordpress_version_required, '<' ) ) {
188
				return false;
189
			}
190
191
			return true;
192
193
		}
194
195
		/**
196
		 * Check if the version of PHP is compatible with this library
197
		 *
198
		 * @since  1.0
199
		 * @return boolean
200
		 */
201
		private function is_php_compatible() {
202
203
			if ( version_compare( phpversion(), $this->php_version_required, '<' ) ) {
204
				return false;
205
			}
206
207
			return true;
208
209
		}
210
211
		/**
212
		 * Spits an error message at the top of the admin screen
213
		 *
214
		 * @since 1.0
215
		 *
216
		 * @param string $error Error message to spit
217
		 *
218
		 * @return void
219
		 */
220
		protected function spit_error( $error ) {
221
			printf(
222
				'<div style="margin: 20px; text-align: center;"><strong>%1$s</strong> %2$s</pre></div>',
223
				esc_html__( 'WP Review Me Error:', 'wp-review-me' ),
224
				wp_kses_post( $error )
225
			);
226
		}
227
228
		/**
229
		 * Check if it is time to ask for a review
230
		 *
231
		 * @since 1.0
232
		 * @return bool
233
		 */
234
		public function is_time() {
235
236
			$installed = (int) get_option( $this->key, 0 );
237
238
			if ( 0 === $installed ) {
239
				$this->setup_date();
240
				$installed = time();
241
			}
242
243
			if ( $installed + ( $this->days * 86400 ) > time() ) {
244
				return false;
245
			}
246
247
			return true;
248
249
		}
250
251
		/**
252
		 * Save the current date as the installation date
253
		 *
254
		 * @since 1.0
255
		 * @return void
256
		 */
257
		protected function setup_date() {
258
			update_option( $this->key, time() );
259
		}
260
261
		/**
262
		 * Get the review link
263
		 *
264
		 * @since 1.0
265
		 * @return string
266
		 */
267
		protected function get_review_link() {
268
269
			$link = 'https://wordpress.org/support/';
270
271
			switch ( $this->type ) {
272
273
				case 'theme':
274
					$link .= 'theme/';
275
					break;
276
277
				case 'plugin':
278
					$link .= 'plugin/';
279
					break;
280
281
			}
282
283
			$link .= $this->slug . '/reviews';
284
			$link = add_query_arg( 'rate', $this->rating, $link );
285
			$link = esc_url( $link . '#new-post' );
286
287
			return $link;
288
289
		}
290
291
		/**
292
		 * Get the complete link tag
293
		 *
294
		 * @since 1.0
295
		 * @return string
296
		 */
297
		protected function get_review_link_tag() {
298
299
			$link = $this->get_review_link();
300
301
			return "<a href='$link' target='_blank' id='$this->link_id'>$this->link_label</a>";
302
303
		}
304
305
		/**
306
		 * Trigger the notice if it is time to ask for a review
307
		 *
308
		 * @since 1.0
309
		 * @return void
310
		 */
311
		protected function maybe_prompt() {
312
313
			if ( ! $this->is_time() ) {
314
				return;
315
			}
316
317
			dnh_register_notice( $this->key, 'updated', $this->get_message(), array(
318
				'scope' => $this->scope,
319
				'cap'   => $this->cap
320
			) );
321
322
		}
323
324
		/**
325
		 * Echo the JS script in the admin footer
326
		 *
327
		 * @since 1.0
328
		 * @return void
329
		 */
330
		public function script() { ?>
331
332
			<script>
333
				jQuery(document).ready(function($) {
334
					$('#<?php echo $this->link_id; ?>').on('click', wrmDismiss);
335
					function wrmDismiss() {
336
337
						var data = {
338
							action: 'wrm_clicked_review',
339
							id: '<?php echo $this->link_id; ?>'
340
						};
341
342
						jQuery.ajax({
343
							type:'POST',
344
							url: ajaxurl,
345
							data: data,
346
							success:function( data ){
347
								console.log(data);
348
							}
349
						});
350
351
					}
352
				});
353
			</script>
354
355
		<?php }
356
357
		/**
358
		 * Dismiss the notice when the review link is clicked
359
		 *
360
		 * @since 1.0
361
		 * @return void
362
		 */
363
		public function dismiss_notice() {
364
365
			if ( empty( $_POST ) ) {
366
				echo 'missing POST';
367
				die();
368
			}
369
370
			if ( ! isset( $_POST['id'] ) ) {
371
				echo 'missing ID';
372
				die();
373
			}
374
375
			$id = sanitize_text_field( $_POST['id'] );
376
377
			if ( $id !== $this->link_id ) {
378
				echo "not this instance's job";
379
				die();
380
			}
381
382
			// Get the DNH notice ID ready
383
			$notice_id = DNH()->get_id( str_replace( 'wrm-review-link-', '', $id ) );
384
			$dismissed = DNH()->dismiss_notice( $notice_id );
385
			
386
			echo $dismissed;
387
388
			/**
389
			 * Fires right after the notice has been dismissed. This allows for various integrations to perform additional tasks.
390
			 *
391
			 * @since 1.0
392
			 *
393
			 * @param string $id        The notice ID
394
			 * @param string $notice_id The notice ID as defined by the DNH class
395
			 */
396
			do_action( 'wrm_after_notice_dismissed', $id, $notice_id );
397
398
			// Stop execution here
399
			die();
400
401
		}
402
403
		/**
404
		 * Get the review prompt message
405
		 *
406
		 * @since 1.0
407
		 * @return string
408
		 */
409
		protected function get_message() {
410
411
			$message = $this->message;
412
			$link    = $this->get_review_link_tag();
413
			$message = $message . ' ' . $link;
414
415
			return wp_kses_post( $message );
416
417
		}
418
419
	}
420
421
}
422