Completed
Pull Request — develop (#11)
by
unknown
01:24
created

review.php (2 issues)

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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 29 and the first side effect is on line 24.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
}