Completed
Pull Request — develop (#10)
by
unknown
09:17
created

review.php (1 issue)

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 this file is called directly, abort.
23
if ( ! defined( 'WPINC' ) ) {
24
	die;
25
}
26
27
if ( ! class_exists( 'WP_Review_Me' ) ) {
28
29
	class WP_Review_Me {
30
31
		/**
32
		 * Library version
33
		 *
34
		 * @since 1.0
35
		 * @var string
36
		 */
37
		public $version = '2.0.1';
38
39
		/**
40
		 * Required version of PHP.
41
		 *
42
		 * @since 1.0
43
		 * @var string
44
		 */
45
		public $php_version_required = '5.5';
46
47
		/**
48
		 * Minimum version of WordPress required to use the library
49
		 *
50
		 * @since 1.0
51
		 * @var string
52
		 */
53
		public $wordpress_version_required = '4.2';
54
55
		/**
56
		 * Holds the unique identifying key for this particular instance
57
		 *
58
		 * @since 1.0
59
		 * @var string
60
		 */
61
		protected $key;
62
63
		/**
64
		 * Link unique ID
65
		 *
66
		 * @since 1.0
67
		 * @var string
68
		 */
69
		public $link_id;
70
71
		/**
72
		 * WP_Review_Me constructor.
73
		 *
74
		 * @since 1.0
75
		 *
76
		 * @param array $args Object settings
77
		 */
78
		public function __construct( $args ) {
79
80
			$args             = wp_parse_args( $args, $this->get_defaults() );
81
			$this->days       = $args['days_after'];
82
			$this->type       = $args['type'];
83
			$this->slug       = $args['slug'];
84
			$this->rating     = $args['rating'];
85
			$this->message    = $args['message'];
86
			$this->link_label = $args['link_label'];
87
			$this->cap        = $args['cap'];
88
			$this->scope      = $args['scope'];
89
90
			// Set the unique identifying key for this instance
91
			$this->key     = 'wrm_' . substr( md5( plugin_basename( __FILE__ ) ), 0, 20 );
92
			$this->link_id = 'wrm-review-link-' . $this->key;
93
94
			// Instantiate
95
			$this->init();
96
97
		}
98
99
		/**
100
		 * Get default object settings
101
		 *
102
		 * @since 1.0
103
		 * @return array
104
		 */
105
		protected function get_defaults() {
106
107
			$defaults = array(
108
				'days_after' => 10,
109
				'type'       => '',
110
				'slug'       => '',
111
				'rating'     => 5,
112
				'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' ) ),
113
				'link_label' => esc_html__( 'Click here to leave your review', 'wp-review-me' ),
114
				// Parameters used in WP Dismissible Notices Handler
115
				'cap'        => 'administrator',
116
				'scope'      => 'global',
117
			);
118
119
			return $defaults;
120
121
		}
122
123
		/**
124
		 * Initialize the library
125
		 *
126
		 * @since 1.0
127
		 * @return void
128
		 */
129
		private function init() {
130
131
			// Make sure WordPress is compatible
132
			if ( ! $this->is_wp_compatible() ) {
133
				$this->spit_error(
134
					sprintf(
135
						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' ),
136
						$this->wordpress_version_required
137
					)
138
				);
139
140
				return;
141
			}
142
143
			// Make sure PHP is compatible
144
			if ( ! $this->is_php_compatible() ) {
145
				$this->spit_error(
146
					sprintf(
147
						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' ),
148
						$this->php_version_required
149
					)
150
				);
151
152
				return;
153
			}
154
155
			// Make sure the dependencies are loaded
156
			if ( ! function_exists( 'dnh_register_notice' ) ) {
157
158
				$dnh_file = trailingslashit( plugin_dir_path( __FILE__ ) ) . 'vendor/julien731/wp-dismissible-notices-handler/handler.php';
159
160
				if ( file_exists( $dnh_file ) ) {
161
					require( $dnh_file );
162
				}
163
164
				if ( ! function_exists( 'dnh_register_notice' ) ) {
165
					$this->spit_error(
166
						sprintf(
167
							esc_html__( 'Dependencies are missing. Please run a %s.', 'wp-review-me' ),
168
							'<code>composer install</code>'
169
						)
170
					);
171
172
					return;
173
				}
174
			}
175
176
			add_action( 'admin_footer', array( $this, 'script' ) );
177
			add_action( 'wp_ajax_wrm_clicked_review', array( $this, 'dismiss_notice' ) );
178
179
			// And let's roll... maybe.
180
			$this->maybe_prompt();
181
182
		}
183
184
		/**
185
		 * Check if the current WordPress version fits the requirements
186
		 *
187
		 * @since  1.0
188
		 * @return boolean
189
		 */
190
		private function is_wp_compatible() {
191
192
			if ( version_compare( get_bloginfo( 'version' ), $this->wordpress_version_required, '<' ) ) {
193
				return false;
194
			}
195
196
			return true;
197
198
		}
199
200
		/**
201
		 * Check if the version of PHP is compatible with this library
202
		 *
203
		 * @since  1.0
204
		 * @return boolean
205
		 */
206
		private function is_php_compatible() {
207
208
			if ( version_compare( phpversion(), $this->php_version_required, '<' ) ) {
209
				return false;
210
			}
211
212
			return true;
213
214
		}
215
216
		/**
217
		 * Spits an error message at the top of the admin screen
218
		 *
219
		 * @since 1.0
220
		 *
221
		 * @param string $error Error message to spit
222
		 *
223
		 * @return void
224
		 */
225
		protected function spit_error( $error ) {
226
			printf(
227
				'<div style="margin: 20px; text-align: center;"><strong>%1$s</strong> %2$s</pre></div>',
228
				esc_html__( 'WP Review Me Error:', 'wp-review-me' ),
229
				wp_kses_post( $error )
230
			);
231
		}
232
233
		/**
234
		 * Check if it is time to ask for a review
235
		 *
236
		 * @since 1.0
237
		 * @return bool
238
		 */
239
		public function is_time() {
240
241
			$installed = (int) get_option( $this->key, false );
242
243
			if ( false === $installed ) {
244
				$this->setup_date();
245
				$installed = time();
246
			}
247
248
			if ( $installed + ( $this->days * 86400 ) > time() ) {
249
				return false;
250
			}
251
252
			return true;
253
254
		}
255
256
		/**
257
		 * Save the current date as the installation date
258
		 *
259
		 * @since 1.0
260
		 * @return void
261
		 */
262
		protected function setup_date() {
263
			update_option( $this->key, time() );
264
		}
265
266
		/**
267
		 * Get the review link
268
		 *
269
		 * @since 1.0
270
		 * @return string
271
		 */
272
		protected function get_review_link() {
273
274
			$link = 'https://wordpress.org/support/';
275
276
			switch ( $this->type ) {
277
278
				case 'theme':
279
					$link .= 'theme/';
280
					break;
281
282
				case 'plugin':
283
					$link .= 'plugin/';
284
					break;
285
286
			}
287
288
			$link .= $this->slug . '/reviews';
289
			$link = add_query_arg( 'rate', $this->rating, $link );
290
			$link = esc_url( $link . '#new-post' );
291
292
			return $link;
293
294
		}
295
296
		/**
297
		 * Get the complete link tag
298
		 *
299
		 * @since 1.0
300
		 * @return string
301
		 */
302
		protected function get_review_link_tag() {
303
304
			$link = $this->get_review_link();
305
306
			return "<a href='$link' target='_blank' id='$this->link_id'>$this->link_label</a>";
307
308
		}
309
310
		/**
311
		 * Trigger the notice if it is time to ask for a review
312
		 *
313
		 * @since 1.0
314
		 * @return void
315
		 */
316
		protected function maybe_prompt() {
317
318
			if ( ! $this->is_time() ) {
319
				return;
320
			}
321
322
			dnh_register_notice( $this->key, 'updated', $this->get_message(), array(
323
				'scope' => $this->scope,
324
				'cap'   => $this->cap
325
			) );
326
327
		}
328
329
		/**
330
		 * Echo the JS script in the admin footer
331
		 *
332
		 * @since 1.0
333
		 * @return void
334
		 */
335
		public function script() { ?>
336
337
			<script>
338
				jQuery(document).ready(function($) {
339
					$('#<?php echo $this->link_id; ?>').on('click', wrmDismiss);
340
					function wrmDismiss() {
341
342
						var data = {
343
							action: 'wrm_clicked_review',
344
							id: '<?php echo $this->link_id; ?>'
345
						};
346
347
						jQuery.ajax({
348
							type:'POST',
349
							url: ajaxurl,
350
							data: data,
351
							success:function( data ){
352
								console.log(data);
353
							}
354
						});
355
356
					}
357
				});
358
			</script>
359
360
		<?php }
361
362
		/**
363
		 * Dismiss the notice when the review link is clicked
364
		 *
365
		 * @since 1.0
366
		 * @return void
367
		 */
368
		public function dismiss_notice() {
0 ignored issues
show
dismiss_notice uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
369
370
			if ( empty( $_POST ) ) {
371
				echo 'missing POST';
372
				die();
373
			}
374
375
			if ( ! isset( $_POST['id'] ) ) {
376
				echo 'missing ID';
377
				die();
378
			}
379
380
			$id = sanitize_text_field( $_POST['id'] );
381
382
			if ( $id !== $this->link_id ) {
383
				echo "not this instance's job";
384
				die();
385
			}
386
387
			// Get the DNH notice ID ready
388
			$notice_id = DNH()->get_id( str_replace( 'wrm-review-link-', '', $id ) );
389
			$dismissed = DNH()->dismiss_notice( $notice_id );
390
			
391
			echo $dismissed;
392
393
			/**
394
			 * Fires right after the notice has been dismissed. This allows for various integrations to perform additional tasks.
395
			 *
396
			 * @since 1.0
397
			 *
398
			 * @param string $id        The notice ID
399
			 * @param string $notice_id The notice ID as defined by the DNH class
400
			 */
401
			do_action( 'wrm_after_notice_dismissed', $id, $notice_id );
402
403
			// Stop execution here
404
			die();
405
406
		}
407
408
		/**
409
		 * Get the review prompt message
410
		 *
411
		 * @since 1.0
412
		 * @return string
413
		 */
414
		protected function get_message() {
415
416
			$message = $this->message;
417
			$link    = $this->get_review_link_tag();
418
			$message = $message . ' ' . $link;
419
420
			return wp_kses_post( $message );
421
422
		}
423
424
	}
425
426
}