PluginProbe ʕ •ᴥ•ʔ
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress / 4.12.0
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress v4.12.0
4.12.0 4.10.0 4.9.0 4.8.1 trunk 1.0 1.1 1.12.1 1.2.3 1.2.4 1.2.5 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.5 1.5.1 1.5.2 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.5.1 1.6.6 1.6.6.1 1.6.6.2 1.6.6.3 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.9.0 1.9.1 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.8.1 1.9.9 1.9.9.1 1.9.9.2 1.9.9.3 2.0 2.0.1 2.1 2.1.1 2.1.2 2.1.3 2.10 2.11 2.11.1 2.12 2.12.1 2.12.2 2.12.3 2.12.4 2.13 2.14 2.14.1 2.15 2.15.1 2.16 2.16.1 2.17 2.17.1 2.18 2.18.1 2.18.2 2.18.3 2.19 2.19.1 2.19.2 2.19.3 2.2 2.2.1 2.3 2.3.1 2.3.10 2.3.2 2.3.3 2.3.4 2.3.6 2.3.7 2.3.8 2.3.9 2.4 2.4.1 2.4.1.1 2.4.1.2 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5 2.5.1 2.5.2 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.7 2.7.1 2.7.2 2.8 2.9 2.9.1 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.1 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.7.5 4.7.6 4.7.7
custom-facebook-feed / inc / Admin / CFF_New_User.php
custom-facebook-feed / inc / Admin Last commit date
Blocks 2 weeks ago Traits 2 weeks ago CFF_About_Us.php 2 weeks ago CFF_Admin.php 2 weeks ago CFF_Admin_Notices.php 2 weeks ago CFF_Callout.php 2 weeks ago CFF_Global_Settings.php 2 weeks ago CFF_Install_Skin.php 2 weeks ago CFF_New_User.php 2 weeks ago CFF_Notifications.php 2 weeks ago CFF_Onboarding_Wizard.php 2 weeks ago CFF_Support.php 2 weeks ago CFF_Support_Tool.php 2 weeks ago CFF_Upgrader.php 2 weeks ago CFF_oEmbeds.php 2 weeks ago index.php 2 weeks ago
CFF_New_User.php
574 lines
1 <?php
2
3 /**
4 * CFF_New_User.
5 *
6 * @since 2.18
7 */
8
9 namespace CustomFacebookFeed\Admin;
10
11 // Exit if accessed directly
12 if (! defined('ABSPATH')) {
13 exit;
14 }
15
16 class CFF_New_User extends CFF_Notifications
17 {
18 /**
19 * Source of notifications content.
20 *
21 * @since 2.18
22 *
23 * @var string
24 */
25 const SOURCE_URL = 'https://plugin.smashballoon.com/newuser.json';
26
27 /**
28 * @var string
29 */
30 const OPTION_NAME = 'cff_newuser_notifications';
31
32 /**
33 * Register hooks.
34 *
35 * @since 2.18
36 */
37 public function hooks()
38 {
39 add_action('admin_notices', array( $this, 'output' ), 8);
40
41 add_action('admin_init', array( $this, 'dismiss' ));
42 add_action('wp_ajax_cff_review_notice_consent_update', array( $this, 'review_notice_consent' ));
43 }
44
45 public function option_name()
46 {
47 return self::OPTION_NAME;
48 }
49
50 public function source_url()
51 {
52 return self::SOURCE_URL;
53 }
54
55 /**
56 * Verify notification data before it is saved.
57 *
58 * @param array $notifications Array of notifications items to verify.
59 *
60 * @return array
61 *
62 * @since 2.18
63 */
64 public function verify($notifications)
65 {
66 $data = array();
67
68 if (! is_array($notifications) || empty($notifications)) {
69 return $data;
70 }
71
72 $option = $this->get_option();
73
74 foreach ($notifications as $key => $notification) {
75 // The message should never be empty, if they are, ignore.
76 if (empty($notification['content'])) {
77 continue;
78 }
79
80 // Ignore if notification has already been dismissed.
81 if (! empty($option['dismissed']) && in_array($notification['id'], $option['dismissed'])) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
82 continue;
83 }
84
85 $data[ $key ] = $notification;
86 }
87
88 return $data;
89 }
90
91 /**
92 * Verify saved notification data for active notifications.
93 *
94 * @since 2.18
95 *
96 * @param array $notifications Array of notifications items to verify.
97 *
98 * @return array
99 */
100 public function verify_active($notifications)
101 {
102 if (! is_array($notifications) || empty($notifications)) {
103 return array();
104 }
105
106 $cff_statuses_option = get_option('cff_statuses', array());
107 if (empty($cff_statuses_option)) {
108 return array();
109 }
110 $current_time = cff_get_current_time();
111
112 // rating notice logic
113 $cff_rating_notice_option = get_option('cff_rating_notice', false);
114 $cff_rating_notice_waiting = get_transient('custom_facebook_rating_notice_waiting');
115 $should_show_rating_notice = ($cff_rating_notice_waiting !== 'waiting' && $cff_rating_notice_option !== 'dismissed');
116
117 // new user discount logic
118 $in_new_user_month_range = true;
119 $should_show_new_user_discount = false;
120 $has_been_one_month_since_rating_dismissal = isset($cff_statuses_option['rating_notice_dismissed']) ? ((int)$cff_statuses_option['rating_notice_dismissed'] + ((int)$notifications['review']['wait'] * DAY_IN_SECONDS)) < $current_time + 1 : true;
121
122 if (isset($cff_statuses_option['first_install']) && $cff_statuses_option['first_install'] === 'from_update') {
123 global $current_user;
124 $user_id = $current_user->ID;
125 $ignore_new_user_sale_notice_meta = get_user_meta($user_id, 'cff_ignore_new_user_sale_notice');
126 $ignore_new_user_sale_notice_meta = isset($ignore_new_user_sale_notice_meta[0]) ? $ignore_new_user_sale_notice_meta[0] : '';
127 if ($ignore_new_user_sale_notice_meta !== 'always') {
128 $should_show_new_user_discount = true;
129 }
130 } elseif ($in_new_user_month_range && $has_been_one_month_since_rating_dismissal && $cff_rating_notice_waiting !== 'waiting') {
131 global $current_user;
132 $user_id = $current_user->ID;
133 $ignore_new_user_sale_notice_meta = get_user_meta($user_id, 'cff_ignore_new_user_sale_notice');
134 $ignore_new_user_sale_notice_meta = isset($ignore_new_user_sale_notice_meta[0]) ? $ignore_new_user_sale_notice_meta[0] : '';
135
136 if (
137 $ignore_new_user_sale_notice_meta !== 'always'
138 && isset($cff_statuses_option['first_install'])
139 && $current_time > (int)$cff_statuses_option['first_install'] + ((int)$notifications['discount']['wait'] * DAY_IN_SECONDS)
140 ) {
141 $should_show_new_user_discount = true;
142 }
143 }
144
145 if (isset($notifications['review']) && $should_show_rating_notice) {
146 return array( $notifications['review'] );
147 } elseif (isset($notifications['discount']) && $should_show_new_user_discount) {
148 return array( $notifications['discount'] );
149 }
150
151 return array();
152 }
153
154 /**
155 * Get notification data.
156 *
157 * @since 2.18
158 *
159 * @return array
160 */
161 public function get()
162 {
163 if (! $this->has_access()) {
164 return array();
165 }
166
167 $option = $this->get_option();
168
169 // Only update if does not exist.
170 if (empty($option['update'])) {
171 $this->update();
172 }
173
174 $events = ! empty($option['events']) ? $this->verify_active($option['events']) : array();
175 $feed = ! empty($option['feed']) ? $this->verify_active($option['feed']) : array();
176
177 return array_merge($events, $feed);
178 }
179
180 /**
181 * Add a manual notification event.
182 *
183 * @since 2.18
184 *
185 * @param array $notification Notification data.
186 */
187 public function add($notification)
188 {
189 if (empty($notification['id'])) {
190 return;
191 }
192
193 $option = $this->get_option();
194
195 if (in_array($notification['id'], $option['dismissed'])) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
196 return;
197 }
198
199 foreach ($option['events'] as $item) {
200 if ($item['id'] === $notification['id']) {
201 return;
202 }
203 }
204
205 $notification = $this->verify(array( $notification ));
206
207 update_option(
208 $this->option_name(),
209 array(
210 'update' => $option['update'],
211 'feed' => $option['feed'],
212 'events' => array_merge($notification, $option['events']),
213 'dismissed' => $option['dismissed'],
214 )
215 );
216 }
217
218 /**
219 * Update notification data from feed.
220 *
221 * @since 2.18
222 */
223 public function update()
224 {
225 $feed = $this->fetch_feed();
226 $option = $this->get_option();
227
228 update_option(
229 $this->option_name(),
230 array(
231 'update' => time(),
232 'feed' => $feed,
233 'events' => $option['events'],
234 'dismissed' => $option['dismissed'],
235 )
236 );
237 }
238
239 /**
240 * Do not enqueue anything extra.
241 *
242 * @since 2.18
243 */
244 public function enqueues()
245 {
246 }
247
248 /**
249 * Review Notice Consent from User
250 *
251 * @since 4.0
252 */
253 public function review_notice_consent()
254 {
255 // Security Checks
256 check_ajax_referer('cff_nonce', 'cff_nonce');
257 $cap = current_user_can('manage_custom_facebook_feed_options') ? 'manage_custom_facebook_feed_options' : 'manage_options';
258
259 $cap = apply_filters('cff_settings_pages_capability', $cap);
260 if (! current_user_can($cap)) {
261 wp_send_json_error(); // This auto-dies.
262 }
263
264 $consent = isset($_POST[ 'consent' ]) ? sanitize_text_field($_POST[ 'consent' ]) : '';
265
266 update_option('cff_review_consent', $consent);
267
268 if ($consent == 'no') {
269 $cff_statuses_option = get_option('cff_statuses', array());
270 update_option('cff_rating_notice', 'dismissed', false);
271 $cff_statuses_option['rating_notice_dismissed'] = cff_get_current_time();
272 update_option('cff_statuses', $cff_statuses_option, false);
273 }
274 wp_die();
275 }
276
277 /**
278 * Output notifications on Form Overview admin area.
279 *
280 * @since 2.18
281 */
282 public function output()
283 {
284 // If the Instagram Feed plugin is active, notices only shown on CFF Settings pages
285 if (
286 function_exists('sb_instagram_activate')
287 && ! function_exists('sb_instagram_feed_pro_init')
288 ) {
289 return;
290 }
291
292 $notifications = $this->get();
293
294 if (empty($notifications)) {
295 return;
296 }
297
298 // new user notices included in regular settings page notifications so this
299 // checks to see if user is one of those pages
300 if (
301 ! empty($_GET['page'])
302 && strpos($_GET['page'], 'cff-') !== false
303 ) {
304 return;
305 }
306
307 $content_allowed_tags = array(
308 'em' => array(),
309 'strong' => array(),
310 'span' => array(
311 'style' => array(),
312 ),
313 'a' => array(
314 'href' => array(),
315 'target' => array(),
316 'rel' => array(),
317 ),
318 );
319 $image_overlay = '';
320
321 foreach ($notifications as $notification) {
322 $img_src = CFF_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field($notification['image']);
323 $type = sanitize_text_field($notification['id']);
324 // check if this is a review notice
325 if ($type == 'review') {
326 $review_consent = get_option('cff_review_consent');
327 $cff_open_feedback_url = 'https://smashballoon.com/feedback/?plugin=facebook-lite&utm_campaign=facebook-free&utm_source=notifications&utm_medium=feedback';
328 // step #1 for the review notice
329 if (! $review_consent) {
330 ?>
331 <div class="cff_notice cff_review_notice_step_1">
332 <div class="cff_thumb">
333 <img src="<?php echo esc_url($img_src); ?>" alt="notice">
334 </div>
335 <div class="cff-notice-text">
336 <p class="cff-notice-text-p"><?php echo __('Are you enjoying the Custom Facebook Feed Plugin?', 'custom-facebook-feed'); ?></p>
337 </div>
338 <div class="cff-notice-consent-btns">
339 <?php
340 printf(
341 '<button class="cff-btn-link" id="cff_review_consent_yes">%s</button>',
342 __('Yes', 'custom-facebook-feed')
343 );
344
345 printf(
346 '<a href="%s" target="_blank" class="cff-btn-link" id="cff_review_consent_no">%s</a>',
347 $cff_open_feedback_url,
348 __('No', 'custom-facebook-feed')
349 );
350 ?>
351 </div>
352 </div>
353 <?php
354 }
355 }
356 $close_href = add_query_arg(array( 'cff_dismiss' => $type ));
357
358 $title = $this->get_notice_title($notification);
359 $content = $this->get_notice_content($notification, $content_allowed_tags);
360
361 $buttons = array();
362 if (! empty($notification['btns']) && is_array($notification['btns'])) {
363 foreach ($notification['btns'] as $btn_type => $btn) {
364 if (! is_array($btn['url'])) {
365 $buttons[ $btn_type ]['url'] = $this->replace_merge_fields($btn['url'], $notification);
366 } elseif (is_array($btn['url'])) {
367 $buttons[ $btn_type ]['url'] = add_query_arg($btn['url']);
368 }
369
370 $buttons[ $btn_type ]['attr'] = '';
371 if (! empty($btn['attr'])) {
372 $buttons[ $btn_type ]['attr'] = ' target="_blank" rel="noopener noreferrer"';
373 }
374
375 $buttons[ $btn_type ]['class'] = '';
376 if (! empty($btn['class'])) {
377 $buttons[ $btn_type ]['class'] = ' ' . $btn['class'];
378 }
379
380 $buttons[ $btn_type ]['text'] = '';
381 if (! empty($btn['text'])) {
382 $buttons[ $btn_type ]['text'] = wp_kses($btn['text'], $content_allowed_tags);
383 }
384 }
385 }
386 }
387
388 $review_consent = get_option('cff_review_consent');
389 $review_step2_style = '';
390 if ($type == 'review' && ! $review_consent) {
391 $review_step2_style = 'style="display: none;"';
392 }
393 ?>
394
395 <div class="cff_notice_op cff_notice cff_<?php echo esc_attr($type); ?>_notice" <?php echo !empty($review_step2_style) ? $review_step2_style : ''; ?>>
396 <div class="cff_thumb">
397 <img src="<?php echo esc_url($img_src); ?>" alt="notice">
398 <?php echo $image_overlay; ?>
399 </div>
400 <div class="cff-notice-text">
401 <div class="cff-notice-text-inner">
402 <h3 class="cff-notice-text-header"><?php echo $title; ?></h3>
403 <p class="cff-notice-text-p"><?php echo $content; ?></p>
404 </div>
405 <div class="cff-notice-btns-wrap">
406 <p class="cff-notice-links">
407 <?php
408 foreach ($buttons as $type => $button) :
409 $btn_classes = array('cff-btn');
410 $btn_classes[] = esc_attr($button['class']);
411 if ($type == 'primary') {
412 $btn_classes[] = 'cff-btn-blue';
413 } else {
414 $btn_classes[] = 'cff-btn-grey';
415 }
416 ?>
417 <a class="<?php echo implode(' ', $btn_classes); ?>" href="<?php echo esc_attr($button['url']); ?>"<?php echo $button['attr']; ?>><?php echo $button['text']; ?></a>
418 <?php endforeach; ?>
419 </p>
420 </div>
421 </div>
422 <div class="cff-notice-dismiss">
423 <a href="<?php echo esc_url($close_href); ?>" aria-label="<?php echo esc_attr__('Dismiss this notice', 'custom-facebook-feed'); ?>">
424 <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
425 <path d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z" fill="#141B38"></path>
426 </svg>
427 </a>
428 </div>
429 </div>
430 <?php
431 }
432
433 /**
434 * CFF Get Notice Title depending on the notice type
435 *
436 * @since 4.0
437 *
438 * @param array $notification
439 *
440 * @return string $title
441 */
442 public function get_notice_title($notification)
443 {
444 $type = $notification['id'];
445 $title = '';
446
447 // Notice title depending on notice type
448 if ($type == 'review') {
449 $title = __('Glad to hear you are enjoying it. Would you consider leaving a positive review?', 'custom-facebook-feed');
450 } elseif ($type == 'discount') {
451 $title = __('Exclusive Offer! 60% OFF', 'custom-facebook-feed');
452 } else {
453 $title = $this->replace_merge_fields($notification['title'], $notification);
454 }
455
456 return $title;
457 }
458
459 /**
460 * CFF Get Notice Content depending on the notice type
461 *
462 * @since 4.0
463 *
464 * @param array $notification
465 * @param array $content_allowed_tags
466 *
467 * @return string $content
468 */
469 public function get_notice_content($notification, $content_allowed_tags)
470 {
471 $type = $notification['id'];
472 $content = '';
473
474 // Notice content depending on notice type
475 if ($type == 'review') {
476 $content = __('It really helps to support the plugin and help others to discover it too!', 'custom-facebook-feed');
477 } elseif ($type == 'discount') {
478 $content = __('We don’t run promotions very often, but for a limited time we’re offering 60% Off our Pro version to all users of our free Facebook Feed.', 'custom-facebook-feed');
479 } else {
480 if (! empty($notification['content'])) {
481 $content = wp_kses($this->replace_merge_fields($notification['content'], $notification), $content_allowed_tags);
482 }
483 }
484 return $content;
485 }
486
487 /**
488 * Hide messages permanently or some can be dismissed temporarily
489 *
490 * @since 2.18
491 */
492 public function dismiss()
493 {
494 global $current_user;
495 $cap = current_user_can('manage_custom_facebook_feed_options') ? 'manage_custom_facebook_feed_options' : 'manage_options';
496 $cap = apply_filters('cff_settings_pages_capability', $cap);
497 if (!current_user_can($cap)) {
498 return;
499 }
500 $user_id = $current_user->ID;
501 $cff_statuses_option = get_option('cff_statuses', array());
502 if (isset($_GET['cff_ignore_rating_notice_nag'])) {
503 $rating_ignore = false;
504 if (isset($_GET['cff_nonce']) && wp_verify_nonce($_GET['cff_nonce'], 'cff-review')) {
505 $rating_ignore = isset($_GET['cff_ignore_rating_notice_nag']) ? sanitize_text_field($_GET['cff_ignore_rating_notice_nag']) : false;
506 }
507
508 if (1 === (int)$rating_ignore) {
509 update_option('cff_rating_notice', 'dismissed', false);
510 $cff_statuses_option['rating_notice_dismissed'] = cff_get_current_time();
511 update_option('cff_statuses', $cff_statuses_option, false);
512 } elseif ('later' === $rating_ignore) {
513 set_transient('custom_facebook_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS);
514 update_option('cff_rating_notice', 'pending', false);
515 }
516 }
517
518 if (isset($_GET['cff_ignore_new_user_sale_notice'])) {
519 $new_user_ignore = false;
520 if (isset($_GET['cff_nonce']) && wp_verify_nonce($_GET['cff_nonce'], 'cff-discount')) {
521 $new_user_ignore = isset($_GET['cff_ignore_new_user_sale_notice']) ? sanitize_text_field($_GET['cff_ignore_new_user_sale_notice']) : false;
522 }
523
524 if ('always' === $new_user_ignore) {
525 update_user_meta($user_id, 'cff_ignore_new_user_sale_notice', 'always');
526
527 $current_month_number = (int)date('n', cff_get_current_time());
528 $not_early_in_the_year = ($current_month_number > 5);
529
530 if ($not_early_in_the_year) {
531 update_user_meta($user_id, 'cff_ignore_bfcm_sale_notice', date('Y', cff_get_current_time()));
532 }
533 }
534 }
535
536 if (isset($_GET['cff_ignore_bfcm_sale_notice'])) {
537 $bfcm_ignore = false;
538 if (isset($_GET['cff_nonce']) && wp_verify_nonce($_GET['cff_nonce'], 'cff-bfcm')) {
539 $bfcm_ignore = isset($_GET['cff_ignore_bfcm_sale_notice']) ? sanitize_text_field($_GET['cff_ignore_bfcm_sale_notice']) : false;
540 }
541
542 if ('always' === $bfcm_ignore) {
543 update_user_meta($user_id, 'cff_ignore_bfcm_sale_notice', 'always');
544 } elseif (date('Y', cff_get_current_time()) === $bfcm_ignore) {
545 update_user_meta($user_id, 'cff_ignore_bfcm_sale_notice', date('Y', cff_get_current_time()));
546 }
547 update_user_meta($user_id, 'cff_ignore_new_user_sale_notice', 'always');
548 }
549
550 if (isset($_GET['cff_dismiss'])) {
551 $notice_dismiss = false;
552 if (isset($_GET['cff_nonce']) && wp_verify_nonce($_GET['cff_nonce'], 'cff-review')) {
553 $notice_dismiss = sanitize_text_field($_GET['cff_dismiss']);
554 }
555
556 if ('review' === $notice_dismiss) {
557 update_option('cff_rating_notice', 'dismissed', false);
558 $cff_statuses_option['rating_notice_dismissed'] = cff_get_current_time();
559 update_option('cff_statuses', $cff_statuses_option, false);
560 } elseif ('discount' === $notice_dismiss) {
561 update_user_meta($user_id, 'cff_ignore_new_user_sale_notice', 'always');
562
563 $current_month_number = (int)date('n', cff_get_current_time());
564 $not_early_in_the_year = ($current_month_number > 5);
565
566 if ($not_early_in_the_year) {
567 update_user_meta($user_id, 'cff_ignore_bfcm_sale_notice', date('Y', cff_get_current_time()));
568 }
569 }
570 update_user_meta($user_id, 'cff_ignore_new_user_sale_notice', 'always');
571 }
572 }
573 }
574