PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 1.1.6
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v1.1.6
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 47 releases
content-control / classes / Admin / Reviews.php

Reviews.php in Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More 1.1.6, at classes/Admin/Reviews.php

497 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace JP\CC\Admin;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 /**
10 * Class JP\CC\Admin\Reviews
11 *
12 * This class adds a review request system for your plugin or theme to the WP dashboard.
13 *
14 * @since 1.1.0
15 */
16 class Reviews {
17
18 /**
19 * Tracking API Endpoint.
20 *
21 * @var string
22 */
23 public static $api_url;
24
25 /**
26 *
27 */
28 public static function init() {
29 add_action( 'init', array( __CLASS__, 'hooks' ) );
30 add_action( 'wp_ajax_jp_cc_review_action', array( __CLASS__, 'ajax_handler' ) );
31 }
32
33 /**
34 * Hook into relevant WP actions.
35 */
36 public static function hooks() {
37 if ( is_admin() && current_user_can( 'edit_posts' ) ) {
38 self::installed_on();
39 add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
40 add_action( 'network_admin_notices', array( __CLASS__, 'admin_notices' ) );
41 add_action( 'user_admin_notices', array( __CLASS__, 'admin_notices' ) );
42 }
43 }
44
45 /**
46 * Get the install date for comparisons. Sets the date to now if none is found.
47 *
48 * @return false|string
49 */
50 public static function installed_on() {
51 $installed_on = get_option( 'jp_cc_reviews_installed_on', false );
52
53 if ( ! $installed_on ) {
54 $installed_on = current_time( 'mysql' );
55 update_option( 'jp_cc_reviews_installed_on', $installed_on );
56 }
57
58 return $installed_on;
59 }
60
61 /**
62 * AJAX Handler
63 */
64 public static function ajax_handler() {
65 $args = wp_parse_args( $_REQUEST, array(
66 'group' => self::get_trigger_group(),
67 'code' => self::get_trigger_code(),
68 'pri' => self::get_current_trigger( 'pri' ),
69 'reason' => 'maybe_later',
70 ) );
71
72 if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'jp_cc_review_action' ) ) {
73 wp_send_json_error();
74 }
75
76 try {
77 $user_id = get_current_user_id();
78
79 $dismissed_triggers = self::dismissed_triggers();
80 $dismissed_triggers[ $args['group'] ] = $args['pri'];
81 update_user_meta( $user_id, '_jp_cc_reviews_dismissed_triggers', $dismissed_triggers );
82 update_user_meta( $user_id, '_jp_cc_reviews_last_dismissed', current_time( 'mysql' ) );
83
84 switch ( $args['reason'] ) {
85 case 'maybe_later':
86 update_user_meta( $user_id, '_jp_cc_reviews_last_dismissed', current_time( 'mysql' ) );
87 break;
88 case 'am_now':
89 case 'already_did':
90 self::already_did( true );
91 break;
92 default:
93 // Do nothing if the reason value does not match one of ours.
94 }
95
96 wp_send_json_success();
97
98 } catch ( \Exception $e ) {
99 wp_send_json_error( $e );
100 }
101 }
102
103 /**
104 * @return int|string
105 */
106 public static function get_trigger_group() {
107 static $selected;
108
109 if ( ! isset( $selected ) ) {
110
111 $dismissed_triggers = self::dismissed_triggers();
112
113 $triggers = self::triggers();
114
115 foreach ( $triggers as $g => $group ) {
116 foreach ( $group['triggers'] as $t => $trigger ) {
117 if ( ! in_array( false, $trigger['conditions'] ) && ( empty( $dismissed_triggers[ $g ] ) || $dismissed_triggers[ $g ] < $trigger['pri'] ) ) {
118 $selected = $g;
119 break;
120 }
121 }
122
123 if ( isset( $selected ) ) {
124 break;
125 }
126 }
127 }
128
129 return $selected;
130 }
131
132 /**
133 * @return int|string
134 */
135 public static function get_trigger_code() {
136 static $selected;
137
138 if ( ! isset( $selected ) ) {
139
140 $dismissed_triggers = self::dismissed_triggers();
141
142 foreach ( self::triggers() as $g => $group ) {
143 foreach ( $group['triggers'] as $t => $trigger ) {
144 if ( ! in_array( false, $trigger['conditions'] ) && ( empty( $dismissed_triggers[ $g ] ) || $dismissed_triggers[ $g ] < $trigger['pri'] ) ) {
145 $selected = $t;
146 break;
147 }
148 }
149
150 if ( isset( $selected ) ) {
151 break;
152 }
153 }
154 }
155
156 return $selected;
157 }
158
159 /**
160 * @param null $key
161 *
162 * @return bool|mixed
163 */
164 public static function get_current_trigger( $key = null ) {
165 $group = self::get_trigger_group();
166 $code = self::get_trigger_code();
167
168 if ( ! $group || ! $code ) {
169 return false;
170 }
171
172 $trigger = self::triggers( $group, $code );
173
174 if ( empty( $key ) ) {
175 return $trigger;
176 } else {
177 return isset($trigger[$key]) ? $trigger[$key] : false;
178 }
179 }
180
181 /**
182 * Returns an array of dismissed trigger groups.
183 *
184 * Array contains the group key and highest priority trigger that has been shown previously for each group.
185 *
186 * $return = array(
187 * 'group1' => 20
188 * );
189 *
190 * @return array|mixed
191 */
192 public static function dismissed_triggers() {
193 $user_id = get_current_user_id();
194
195 $dismissed_triggers = get_user_meta( $user_id, '_jp_cc_reviews_dismissed_triggers', true );
196
197 if ( ! $dismissed_triggers ) {
198 $dismissed_triggers = array();
199 }
200
201 return $dismissed_triggers;
202 }
203
204 /**
205 * Returns true if the user has opted to never see this again. Or sets the option.
206 *
207 * @param bool $set If set this will mark the user as having opted to never see this again.
208 *
209 * @return bool
210 */
211 public static function already_did( $set = false ) {
212 $user_id = get_current_user_id();
213
214 if ( $set ) {
215 update_user_meta( $user_id, '_jp_cc_reviews_already_did', true );
216
217 return true;
218 }
219
220 return (bool) get_user_meta( $user_id, '_jp_cc_reviews_already_did', true );
221 }
222
223 /**
224 * Gets a list of triggers.
225 *
226 * @param null $group
227 * @param null $code
228 *
229 * @return bool|mixed
230 */
231 public static function triggers( $group = null, $code = null ) {
232 static $triggers;
233
234 if ( ! isset( $triggers ) ) {
235
236 $link = 'https://wordpress.org/support/plugin/content-control/reviews/?rate=5#rate-response';
237
238 $time_message = __( 'Hi there! You\'ve been using the Content Control plugin on your site for %s now - We hope it\'s been helpful. If you\'re enjoying the plugin, would you mind rating it 5-stars to help spread the word?', 'content-control' );
239 $triggers = array(
240 'time_installed' => array(
241 'triggers' => array(
242 'one_week' => array(
243 'message' => sprintf( $time_message, __( '1 week', 'content-control' ) ),
244 'conditions' => array(
245 strtotime( self::installed_on() . ' +1 week' ) < time(),
246 ),
247 'link' => $link,
248 'pri' => 10,
249 ),
250 'one_month' => array(
251 'message' => sprintf( $time_message, __( '1 month', 'content-control' ) ),
252 'conditions' => array(
253 strtotime( self::installed_on() . ' +1 month' ) < time(),
254 ),
255 'link' => $link,
256 'pri' => 20,
257 ),
258 'three_months' => array(
259 'message' => sprintf( $time_message, __( '3 months', 'content-control' ) ),
260 'conditions' => array(
261 strtotime( self::installed_on() . ' +3 months' ) < time(),
262 ),
263 'link' => $link,
264 'pri' => 30,
265 ),
266
267 ),
268 'pri' => 10,
269 ),
270 );
271
272 $triggers = apply_filters( 'jp_cc_reviews_triggers', $triggers );
273
274 // Sort Groups
275 uasort( $triggers, array( __CLASS__, 'rsort_by_priority' ) );
276
277 // Sort each groups triggers.
278 foreach ( $triggers as $k => $v ) {
279 uasort( $triggers[ $k ]['triggers'], array( __CLASS__, 'rsort_by_priority' ) );
280 }
281 }
282
283 if ( isset( $group ) ) {
284 if ( ! isset( $triggers[ $group ] ) ) {
285 return false;
286 }
287
288 if ( ! isset( $code ) ) {
289 return $triggers[ $group ];
290 } else {
291 return isset( $triggers[ $group ]['triggers'][ $code ] ) ? $triggers[ $group ]['triggers'][ $code ] : false;
292 }
293 }
294
295 return $triggers;
296 }
297
298 /**
299 * Render admin notices if available.
300 */
301 public static function admin_notices() {
302 if ( self::hide_notices() ) {
303 return;
304 }
305
306 $group = self::get_trigger_group();
307 $code = self::get_trigger_code();
308 $pri = self::get_current_trigger( 'pri' );
309 $trigger = self::get_current_trigger();
310
311 // Used to anonymously distinguish unique site+user combinations in terms of effectiveness of each trigger.
312 $uuid = wp_hash( home_url() . '-' . get_current_user_id() );
313
314 ?>
315
316 <script type="text/javascript">
317 (function ($) {
318 var trigger = {
319 group: '<?php echo $group; ?>',
320 code: '<?php echo $code; ?>',
321 pri: '<?php echo $pri; ?>'
322 };
323
324 function dismiss(reason) {
325 $.ajax({
326 method: "POST",
327 dataType: "json",
328 url: ajaxurl,
329 data: {
330 action: 'jp_cc_review_action',
331 nonce: '<?php echo wp_create_nonce( 'jp_cc_review_action' ); ?>',
332 group: trigger.group,
333 code: trigger.code,
334 pri: trigger.pri,
335 reason: reason
336 }
337 });
338
339 <?php if ( ! empty( self::$api_url ) ) : ?>
340 $.ajax({
341 method: "POST",
342 dataType: "json",
343 url: '<?php echo self::$api_url; ?>',
344 data: {
345 trigger_group: trigger.group,
346 trigger_code: trigger.code,
347 reason: reason,
348 uuid: '<?php echo $uuid; ?>'
349 }
350 });
351 <?php endif; ?>
352 }
353
354 $(document)
355 .on('click', '.jp-cc-notice .jp-cc-dismiss', function (event) {
356 var $this = $(this),
357 reason = $this.data('reason'),
358 notice = $this.parents('.jp-cc-notice');
359
360 notice.fadeTo(100, 0, function () {
361 notice.slideUp(100, function () {
362 notice.remove();
363 });
364 });
365
366 dismiss(reason);
367 })
368 .ready(function () {
369 setTimeout(function () {
370 $('.jp-cc-notice button.notice-dismiss').click(function (event) {
371 dismiss('maybe_later');
372 });
373 }, 1000);
374 });
375 }(jQuery));
376 </script>
377
378 <style>
379 .jp-cc-notice p {
380 margin-bottom: 0;
381 }
382
383 .jp-cc-notice img.logo {
384 float: right;
385 margin-left: 10px;
386 width: 75px;
387 padding: 0.25em;
388 border: 1px solid #ccc;
389 }
390 </style>
391
392 <div class="notice notice-success is-dismissible jp-cc-notice">
393
394 <p>
395 <img class="logo" src="<?php echo \JP_Content_Control::$URL; ?>assets/images/icon-128x128.png" />
396 <strong>
397 <?php echo $trigger['message']; ?>
398 <br />
399 <?php
400
401 $names = array(
402 '<a target="_blank" href="https://twitter.com/danieliser" title="Follow Daniel on Twitter">@danieliser</a>',
403 '<a target="_blank" href="https://twitter.com/calumallison" title="Follow Calum on Twitter">@calumallison</a>',
404 );
405
406 shuffle( $names );
407
408 echo '~ ' . implode( ' & ', $names );
409
410 ?>
411 </strong>
412 </p>
413 <ul>
414 <li>
415 <a class="jp-cc-dismiss" target="_blank" href="<?php echo $trigger['link']; ?>>" data-reason="am_now">
416 <strong><?php _e( 'Ok, you deserve it', 'content-control' ); ?></strong>
417 </a>
418 </li>
419 <li>
420 <a href="#" class="jp-cc-dismiss" data-reason="maybe_later">
421 <?php _e( 'Nope, maybe later', 'content-control' ); ?>
422 </a>
423 </li>
424 <li>
425 <a href="#" class="jp-cc-dismiss" data-reason="already_did">
426 <?php _e( 'I already did', 'content-control' ); ?>
427 </a>
428 </li>
429 </ul>
430
431 </div>
432
433 <?php
434 }
435
436 /**
437 * Checks if notices should be shown.
438 *
439 * @return bool
440 */
441 public static function hide_notices() {
442 $code = self::get_trigger_code();
443
444 $conditions = array(
445 self::already_did(),
446 self::last_dismissed() && strtotime( self::last_dismissed() . ' +2 weeks' ) > time(),
447 empty( $code ),
448 );
449
450 return in_array( true, $conditions );
451 }
452
453 /**
454 * Gets the last dismissed date.
455 *
456 * @return false|string
457 */
458 public static function last_dismissed() {
459 $user_id = get_current_user_id();
460
461 return get_user_meta( $user_id, '_jp_cc_reviews_last_dismissed', true );
462 }
463
464 /**
465 * Sort array by priority value
466 *
467 * @param $a
468 * @param $b
469 *
470 * @return int
471 */
472 public static function sort_by_priority( $a, $b ) {
473 if ( ! isset( $a['pri'] ) || ! isset( $b['pri'] ) || $a['pri'] === $b['pri'] ) {
474 return 0;
475 }
476
477 return ( $a['pri'] < $b['pri'] ) ? - 1 : 1;
478 }
479
480 /**
481 * Sort array in reverse by priority value
482 *
483 * @param $a
484 * @param $b
485 *
486 * @return int
487 */
488 public static function rsort_by_priority( $a, $b ) {
489 if ( ! isset( $a['pri'] ) || ! isset( $b['pri'] ) || $a['pri'] === $b['pri'] ) {
490 return 0;
491 }
492
493 return ( $a['pri'] < $b['pri'] ) ? 1 : - 1;
494 }
495
496 }
497