Completed
Pull Request — develop (#11)
by
unknown
01:24
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 ( ! 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'];
77
			$this->type       = $args['type'];
78
			$this->slug       = $args['slug'];
79
			$this->rating     = $args['rating'];
80
			$this->message    = $args['message'];
81
			$this->link_label = $args['link_label'];
82
			$this->cap        = $args['cap'];
83
			$this->scope      = $args['scope'];
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, false );
237
238
			if ( false === $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() {
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...
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