Custom Facebook Feed - Version 2.17.1

Version Description

  • Tweak: Added shortcode options for the "Before Date" and "After Date" settings, so that a custom text string can be displayed before and after the post date.
  • Tweak: Minor frontend CSS improvements.
  • Tweak: Added support for improved notices on the plugin settings page.
  • Fix: Fixed an issue with the Facebook Like Box widget displaying an error if the width was set to a fractional pixel.
Download this release

Release Info

Developer smashballoon
Plugin Icon 128x128 Custom Facebook Feed
Version 2.17.1
Comparing to
See all releases

Code changes from version 2.17 to 2.17.1

README.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: smashballoon
3
  Tags: Facebook, Facebook feed, Facebook posts, Facebook group, Facebook page
4
  Requires at least: 3.0
5
  Requires PHP: 5.2
6
- Tested up to: 5.5
7
- Stable tag: 2.17
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -259,6 +259,12 @@ The most common reason for this is that an add-on or extension you have installe
259
  9. It's super easy to display your Facebook feed in any page or post
260
 
261
  == Changelog ==
 
 
 
 
 
 
262
  = 2.17 =
263
  * New: Added support for Facebook oEmbeds. When you share a link to a Facebook post or video, WordPress automatically converts it into an embedded Facebook post for you (an "oEmbed"). However, on October 24, 2020, WordPress is discontinuing support for Facebook oEmbeds and so any existing or new embeds will no longer work. Don't worry though, we have your back! This update adds support for Facebook oEmbeds and so, after updating, the Custom Facebook Feed plugin will automatically keep your oEmbeds working. It will also power any new oEmbeds you post going forward.
264
  * New: Install our other free social media plugins right from the Custom Facebook Feed settings menu. Use our Instagram, YouTube, and Twitter plugins to add even more social content to your website and help further engage your viewers and increase your followers.
3
  Tags: Facebook, Facebook feed, Facebook posts, Facebook group, Facebook page
4
  Requires at least: 3.0
5
  Requires PHP: 5.2
6
+ Tested up to: 5.6
7
+ Stable tag: 2.17.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
259
  9. It's super easy to display your Facebook feed in any page or post
260
 
261
  == Changelog ==
262
+ = 2.17.1 =
263
+ * Tweak: Added shortcode options for the "Before Date" and "After Date" settings, so that a custom text string can be displayed before and after the post date.
264
+ * Tweak: Minor frontend CSS improvements.
265
+ * Tweak: Added support for improved notices on the plugin settings page.
266
+ * Fix: Fixed an issue with the Facebook Like Box widget displaying an error if the width was set to a fractional pixel.
267
+
268
  = 2.17 =
269
  * New: Added support for Facebook oEmbeds. When you share a link to a Facebook post or video, WordPress automatically converts it into an embedded Facebook post for you (an "oEmbed"). However, on October 24, 2020, WordPress is discontinuing support for Facebook oEmbeds and so any existing or new embeds will no longer work. Don't worry though, we have your back! This update adds support for Facebook oEmbeds and so, after updating, the Custom Facebook Feed plugin will automatically keep your oEmbeds working. It will also power any new oEmbeds you post going forward.
270
  * New: Install our other free social media plugins right from the Custom Facebook Feed settings menu. Use our Instagram, YouTube, and Twitter plugins to add even more social content to your website and help further engage your viewers and increase your followers.
admin/class-cff-new-user.php ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CFF_New_User.
4
+ *
5
+ * @since 2.18
6
+ */
7
+
8
+ // Exit if accessed directly
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ class CFF_New_User extends CFF_Notifications {
14
+
15
+ /**
16
+ * Source of notifications content.
17
+ *
18
+ * @since 2.18
19
+ *
20
+ * @var string
21
+ */
22
+ const SOURCE_URL = 'http://plugin.smashballoon.com/newuser.json';
23
+
24
+ /**
25
+ * @var string
26
+ */
27
+ const OPTION_NAME = 'cff_newuser_notifications';
28
+
29
+ /**
30
+ * Register hooks.
31
+ *
32
+ * @since 2.18
33
+ */
34
+ public function hooks() {
35
+ add_action( 'admin_notices', array( $this, 'output' ), 8 );
36
+
37
+ add_action( 'admin_init', array( $this, 'dismiss' ) );
38
+ }
39
+
40
+ public function option_name() {
41
+ return self::OPTION_NAME;
42
+ }
43
+
44
+ public function source_url() {
45
+ return self::SOURCE_URL;
46
+ }
47
+
48
+ /**
49
+ * Verify notification data before it is saved.
50
+ *
51
+ * @param array $notifications Array of notifications items to verify.
52
+ *
53
+ * @return array
54
+ *
55
+ * @since 2.18
56
+ */
57
+ public function verify( $notifications ) {
58
+ $data = array();
59
+
60
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
61
+ return $data;
62
+ }
63
+
64
+ $option = $this->get_option();
65
+
66
+ foreach ( $notifications as $key => $notification ) {
67
+
68
+ // The message should never be empty, if they are, ignore.
69
+ if ( empty( $notification['content'] ) ) {
70
+ continue;
71
+ }
72
+
73
+ // Ignore if notification has already been dismissed.
74
+ if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
75
+ continue;
76
+ }
77
+
78
+ $data[ $key ] = $notification;
79
+ }
80
+
81
+ return $data;
82
+ }
83
+
84
+ /**
85
+ * Verify saved notification data for active notifications.
86
+ *
87
+ * @since 2.18
88
+ *
89
+ * @param array $notifications Array of notifications items to verify.
90
+ *
91
+ * @return array
92
+ */
93
+ public function verify_active( $notifications ) {
94
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
95
+ return array();
96
+ }
97
+
98
+ $cff_statuses_option = get_option( 'cff_statuses', array() );
99
+ $current_time = cff_get_current_time();
100
+
101
+ // rating notice logic
102
+ $cff_rating_notice_option = get_option( 'cff_rating_notice', false );
103
+ $cff_rating_notice_waiting = get_transient( 'custom_facebook_rating_notice_waiting' );
104
+ $should_show_rating_notice = ($cff_rating_notice_waiting !== 'waiting' && $cff_rating_notice_option !== 'dismissed');
105
+
106
+ // new user discount logic
107
+ $in_new_user_month_range = true;
108
+ $should_show_new_user_discount = false;
109
+ $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;
110
+
111
+ if ( isset( $cff_statuses_option['first_install'] ) && $cff_statuses_option['first_install'] === 'from_update' ) {
112
+ global $current_user;
113
+ $user_id = $current_user->ID;
114
+ $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
115
+ $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
116
+ if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
117
+ $should_show_new_user_discount = true;
118
+ }
119
+ } elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal && $cff_rating_notice_waiting !== 'waiting' ) {
120
+ global $current_user;
121
+ $user_id = $current_user->ID;
122
+ $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
123
+ $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
124
+
125
+ if ( $ignore_new_user_sale_notice_meta !== 'always'
126
+ && isset( $cff_statuses_option['first_install'] )
127
+ && $current_time > (int)$cff_statuses_option['first_install'] + ((int)$notifications['discount']['wait'] * DAY_IN_SECONDS) ) {
128
+ $should_show_new_user_discount = true;
129
+ }
130
+ }
131
+
132
+ if ( isset( $notifications['review'] ) && $should_show_rating_notice ) {
133
+ return array( $notifications['review'] );
134
+ } elseif ( isset( $notifications['discount'] ) && $should_show_new_user_discount ) {
135
+ return array( $notifications['discount'] );
136
+ }
137
+
138
+ return array();
139
+ }
140
+
141
+ /**
142
+ * Get notification data.
143
+ *
144
+ * @since 2.18
145
+ *
146
+ * @return array
147
+ */
148
+ public function get() {
149
+ if ( ! $this->has_access() ) {
150
+ return array();
151
+ }
152
+
153
+ $option = $this->get_option();
154
+
155
+ // Only update if does not exist.
156
+ if ( empty( $option['update'] ) ) {
157
+ $this->update();
158
+ }
159
+
160
+ $events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
161
+ $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
162
+
163
+ return array_merge( $events, $feed );
164
+ }
165
+
166
+ /**
167
+ * Add a manual notification event.
168
+ *
169
+ * @since 2.18
170
+ *
171
+ * @param array $notification Notification data.
172
+ */
173
+ public function add( $notification ) {
174
+ if ( empty( $notification['id'] ) ) {
175
+ return;
176
+ }
177
+
178
+ $option = $this->get_option();
179
+
180
+ if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
181
+ return;
182
+ }
183
+
184
+ foreach ( $option['events'] as $item ) {
185
+ if ( $item['id'] === $notification['id'] ) {
186
+ return;
187
+ }
188
+ }
189
+
190
+ $notification = $this->verify( array( $notification ) );
191
+
192
+ update_option(
193
+ $this->option_name(),
194
+ array(
195
+ 'update' => $option['update'],
196
+ 'feed' => $option['feed'],
197
+ 'events' => array_merge( $notification, $option['events'] ),
198
+ 'dismissed' => $option['dismissed'],
199
+ )
200
+ );
201
+ }
202
+
203
+ /**
204
+ * Update notification data from feed.
205
+ *
206
+ * @since 2.18
207
+ */
208
+ public function update() {
209
+ $feed = $this->fetch_feed();
210
+ $option = $this->get_option();
211
+
212
+ update_option(
213
+ $this->option_name(),
214
+ array(
215
+ 'update' => time(),
216
+ 'feed' => $feed,
217
+ 'events' => $option['events'],
218
+ 'dismissed' => $option['dismissed'],
219
+ )
220
+ );
221
+ }
222
+
223
+ /**
224
+ * Do not enqueue anything extra.
225
+ *
226
+ * @since 2.18
227
+ */
228
+ public function enqueues() {
229
+
230
+ }
231
+
232
+ /**
233
+ * Output notifications on Form Overview admin area.
234
+ *
235
+ * @since 2.18
236
+ */
237
+ public function output() {
238
+ // If the Instagram Feed plugin is active, notices only shown on CFF Settings pages
239
+ if ( function_exists( 'sb_instagram_activate' )
240
+ && ! function_exists( 'sb_instagram_feed_pro_init' ) ) {
241
+ return;
242
+ }
243
+
244
+ $notifications = $this->get();
245
+
246
+ if ( empty( $notifications ) ) {
247
+ return;
248
+ }
249
+
250
+ // new user notices included in regular settings page notifications so this
251
+ // checks to see if user is one of those pages
252
+ if ( ! empty( $_GET['page'] )
253
+ && strpos( $_GET['page'], 'cff-' ) !== false ) {
254
+ return;
255
+ }
256
+
257
+ $content_allowed_tags = array(
258
+ 'em' => array(),
259
+ 'strong' => array(),
260
+ 'span' => array(
261
+ 'style' => array(),
262
+ ),
263
+ 'a' => array(
264
+ 'href' => array(),
265
+ 'target' => array(),
266
+ 'rel' => array(),
267
+ ),
268
+ );
269
+ $image_overlay = '';
270
+
271
+ foreach ( $notifications as $notification ) {
272
+ $type = sanitize_text_field( $notification['id'] );
273
+ $img_src = CFF_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
274
+ $content = '';
275
+ if ( ! empty( $notification['content'] ) ) {
276
+ $content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
277
+ }
278
+ $buttons = array();
279
+ if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
280
+ foreach ( $notification['btns'] as $btn_type => $btn ) {
281
+ if ( ! is_array( $btn['url'] ) ) {
282
+ $buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification );
283
+ } elseif ( is_array( $btn['url'] ) ) {
284
+ $buttons[ $btn_type ]['url'] = add_query_arg( $btn['url'] );
285
+ }
286
+
287
+ $buttons[ $btn_type ]['attr'] = '';
288
+ if ( ! empty( $btn['attr'] ) ) {
289
+ $buttons[ $btn_type ]['attr'] = ' target="_blank" rel="noopener noreferrer"';
290
+ }
291
+
292
+ $buttons[ $btn_type ]['class'] = '';
293
+ if ( ! empty( $btn['class'] ) ) {
294
+ $buttons[ $btn_type ]['class'] = ' ' . $btn['class'];
295
+ }
296
+
297
+ $buttons[ $btn_type ]['text'] = '';
298
+ if ( ! empty( $btn['text'] ) ) {
299
+ $buttons[ $btn_type ]['text'] = wp_kses( $btn['text'], $content_allowed_tags );
300
+ }
301
+ }
302
+ }
303
+ if ( isset( $notification['image_overlay'] ) ) {
304
+ $image_overlay = '<div class="img-overlay">'. esc_html( $notification['image_overlay'] ).'</div>';
305
+ }
306
+ }
307
+ ?>
308
+
309
+ <div class="cff_notice cff_<?php echo esc_attr( $type ); ?>_notice">
310
+ <div class="cff_thumb">
311
+ <img src="<?php echo esc_url( $img_src ); ?>" alt="notice">
312
+ <?php echo $image_overlay; ?>
313
+ </div>
314
+ <div class="cff-notice-text">
315
+ <p style="padding-top: 4px;"><?php echo $content; ?></p>
316
+ <p class="links">
317
+ <?php foreach ( $buttons as $button ) : ?>
318
+ <a class="<?php echo esc_attr( $button['class'] ); ?>" href="<?php echo esc_attr( $button['url'] ); ?>"<?php echo $button['attr']; ?>><?php echo $button['text']; ?></a>
319
+ <?php endforeach; ?>
320
+ </p>
321
+ </div>
322
+ <a class="cff_notice_close" href="<?php echo add_query_arg( array( 'cff_dismiss' => $type ) ); ?>"><i class="fa fa-close"></i></a>
323
+ </div>
324
+ <?php
325
+ }
326
+
327
+ /**
328
+ * Hide messages permanently or some can be dismissed temporarily
329
+ *
330
+ * @since 2.18
331
+ */
332
+ public function dismiss() {
333
+ global $current_user;
334
+ $user_id = $current_user->ID;
335
+ $cff_statuses_option = get_option( 'cff_statuses', array() );
336
+
337
+ if ( isset( $_GET['cff_ignore_rating_notice_nag'] ) ) {
338
+ if ( (int)$_GET['cff_ignore_rating_notice_nag'] === 1 ) {
339
+ update_option( 'cff_rating_notice', 'dismissed', false );
340
+ $cff_statuses_option['rating_notice_dismissed'] = cff_get_current_time();
341
+ update_option( 'cff_statuses', $cff_statuses_option, false );
342
+
343
+ } elseif ( $_GET['cff_ignore_rating_notice_nag'] === 'later' ) {
344
+ set_transient( 'custom_facebook_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
345
+ update_option( 'cff_rating_notice', 'pending', false );
346
+ }
347
+ }
348
+
349
+ if ( isset( $_GET['cff_ignore_new_user_sale_notice'] ) ) {
350
+ $response = sanitize_text_field( $_GET['cff_ignore_new_user_sale_notice'] );
351
+ if ( $response === 'always' ) {
352
+ update_user_meta( $user_id, 'cff_ignore_new_user_sale_notice', 'always' );
353
+
354
+ $current_month_number = (int)date('n', cff_get_current_time() );
355
+ $not_early_in_the_year = ($current_month_number > 5);
356
+
357
+ if ( $not_early_in_the_year ) {
358
+ update_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice', date( 'Y', cff_get_current_time() ) );
359
+ }
360
+
361
+ }
362
+ }
363
+
364
+ if ( isset( $_GET['cff_ignore_bfcm_sale_notice'] ) ) {
365
+ $response = sanitize_text_field( $_GET['cff_ignore_bfcm_sale_notice'] );
366
+ if ( $response === 'always' ) {
367
+ update_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice', 'always' );
368
+ } elseif ( $response === date( 'Y', cff_get_current_time() ) ) {
369
+ update_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice', date( 'Y', cff_get_current_time() ) );
370
+ }
371
+ update_user_meta( $user_id, 'cff_ignore_new_user_sale_notice', 'always' );
372
+ }
373
+
374
+ if ( isset( $_GET['cff_dismiss'] ) ) {
375
+ if ( $_GET['cff_dismiss'] === 'review' ) {
376
+ update_option( 'cff_rating_notice', 'dismissed', false );
377
+ $cff_statuses_option['rating_notice_dismissed'] = cff_get_current_time();
378
+ update_option( 'cff_statuses', $cff_statuses_option, false );
379
+ } elseif ( $_GET['cff_dismiss'] === 'discount' ) {
380
+ update_user_meta( $user_id, 'cff_ignore_new_user_sale_notice', 'always' );
381
+
382
+ $current_month_number = (int)date('n', cff_get_current_time() );
383
+ $not_early_in_the_year = ($current_month_number > 5);
384
+
385
+ if ( $not_early_in_the_year ) {
386
+ update_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice', date( 'Y', cff_get_current_time() ) );
387
+ }
388
+ }
389
+ update_user_meta( $user_id, 'cff_ignore_new_user_sale_notice', 'always' );
390
+ }
391
+ }
392
+ }
admin/class-cff-notifications.php ADDED
@@ -0,0 +1,575 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CFF_Notifications.
4
+ *
5
+ * @since 2.18/3.17
6
+ */
7
+
8
+ // Exit if accessed directly
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ class CFF_Notifications {
14
+
15
+ /**
16
+ * Source of notifications content.
17
+ *
18
+ * @var string
19
+ */
20
+ const SOURCE_URL = 'http://plugin.smashballoon.com/notifications.json';
21
+
22
+ /**
23
+ * @var string
24
+ */
25
+ const OPTION_NAME = 'cff_notifications';
26
+
27
+ /**
28
+ * JSON data contains notices for all plugins. This is used
29
+ * to select messages only meant for this plugin
30
+ *
31
+ * @var string
32
+ */
33
+ const PLUGIN = 'facebook';
34
+
35
+ /**
36
+ * Option value.
37
+ *
38
+ * @since 2.18/3.17
39
+ *
40
+ * @var bool|array
41
+ */
42
+ public $option = false;
43
+
44
+ /**
45
+ * Initialize class.
46
+ *
47
+ * @since 2.18/3.17
48
+ */
49
+ public function init() {
50
+ $this->hooks();
51
+ }
52
+
53
+ /**
54
+ * Use this function to get the option name to allow
55
+ * inheritance for the New_User class
56
+ *
57
+ * @return string
58
+ */
59
+ public function option_name() {
60
+ return self::OPTION_NAME;
61
+ }
62
+
63
+ /**
64
+ * Use this function to get the source URL to allow
65
+ * inheritance for the New_User class
66
+ *
67
+ * @return string
68
+ */
69
+ public function source_url() {
70
+ return self::SOURCE_URL;
71
+ }
72
+
73
+ /**
74
+ * Register hooks.
75
+ *
76
+ * @since 2.18/3.17
77
+ */
78
+ public function hooks() {
79
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ) );
80
+
81
+ add_action( 'cff_admin_overview_before_table', array( $this, 'output' ) );
82
+
83
+ // on cron. Once a week?
84
+ add_action( 'cff_notification_update', array( $this, 'update' ) );
85
+
86
+ add_action( 'wp_ajax_cff_dashboard_notification_dismiss', array( $this, 'dismiss' ) );
87
+ }
88
+
89
+
90
+ /**
91
+ * Check if user has access and is enabled.
92
+ *
93
+ * @since 2.18/3.17
94
+ *
95
+ * @return bool
96
+ */
97
+ public function has_access() {
98
+ $access = false;
99
+
100
+ if ( current_user_can( 'manage_custom_facebook_feed_options' ) ) {
101
+ $access = true;
102
+ }
103
+
104
+ return apply_filters( 'cff_admin_notifications_has_access', $access );
105
+ }
106
+
107
+ /**
108
+ * Get option value.
109
+ *
110
+ * @since 2.18/3.17
111
+ *
112
+ * @param bool $cache Reference property cache if available.
113
+ *
114
+ * @return array
115
+ */
116
+ public function get_option( $cache = true ) {
117
+ if ( $this->option && $cache ) {
118
+ return $this->option;
119
+ }
120
+
121
+ $option = get_option( $this->option_name(), array() );
122
+
123
+ $this->option = array(
124
+ 'update' => ! empty( $option['update'] ) ? $option['update'] : 0,
125
+ 'events' => ! empty( $option['events'] ) ? $option['events'] : array(),
126
+ 'feed' => ! empty( $option['feed'] ) ? $option['feed'] : array(),
127
+ 'dismissed' => ! empty( $option['dismissed'] ) ? $option['dismissed'] : array(),
128
+ );
129
+
130
+ return $this->option;
131
+ }
132
+
133
+ /**
134
+ * Fetch notifications from feed.
135
+ *
136
+ * @since 2.18/3.17
137
+ *
138
+ * @return array
139
+ */
140
+ public function fetch_feed() {
141
+ $res = wp_remote_get( $this->source_url() );
142
+
143
+ if ( is_wp_error( $res ) ) {
144
+ return array();
145
+ }
146
+
147
+ $body = wp_remote_retrieve_body( $res );
148
+
149
+ if ( empty( $body ) ) {
150
+ return array();
151
+ }
152
+
153
+ $body = str_replace( array( 'sbi_', 'sbi-' ), array( 'cff_', 'cff-' ), $body );
154
+
155
+ return $this->verify( json_decode( $body, true ) );
156
+ }
157
+
158
+ /**
159
+ * Verify notification data before it is saved.
160
+ *
161
+ * @since 2.18/3.17
162
+ *
163
+ * @param array $notifications Array of notifications items to verify.
164
+ *
165
+ * @return array
166
+ */
167
+ public function verify( $notifications ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
168
+ $data = array();
169
+
170
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
171
+ return $data;
172
+ }
173
+
174
+ $option = $this->get_option();
175
+
176
+ foreach ( $notifications as $notification ) {
177
+
178
+ // The message and license should never be empty, if they are, ignore.
179
+ if ( empty( $notification['content'] ) || empty( $notification['type'] ) ) {
180
+ continue;
181
+ }
182
+
183
+ // Ignore if license type does not match.
184
+ $license = cff_is_pro_version() ? 'pro' : 'free';
185
+
186
+ if ( ! in_array( $license, $notification['type'], true ) ) {
187
+ continue;
188
+ }
189
+
190
+ // Ignore if expired.
191
+ if ( ! empty( $notification['end'] ) && cff_get_current_time() > strtotime( $notification['end'] ) ) {
192
+ continue;
193
+ }
194
+
195
+ // Ignore if notification has already been dismissed.
196
+ if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
197
+ continue;
198
+ }
199
+
200
+ // TODO: Ignore if notification existed before installing CFF.
201
+ // Prevents bombarding the user with notifications after activation.
202
+ $activated = false;
203
+ if ( ! empty( $activated )
204
+ && ! empty( $notification['start'] )
205
+ && $activated > strtotime( $notification['start'] ) ) {
206
+ continue;
207
+ }
208
+
209
+ $data[] = $notification;
210
+ }
211
+
212
+ return $data;
213
+ }
214
+
215
+ /**
216
+ * Verify saved notification data for active notifications.
217
+ *
218
+ * @since 2.18/3.17
219
+ *
220
+ * @param array $notifications Array of notifications items to verify.
221
+ *
222
+ * @return array
223
+ */
224
+ public function verify_active( $notifications ) {
225
+ if ( ! is_array( $notifications ) || empty( $notifications ) ) {
226
+ return array();
227
+ }
228
+
229
+ // Remove notfications that are not active.
230
+ foreach ( $notifications as $key => $notification ) {
231
+ if ( ( ! empty( $notification['start'] ) && cff_get_current_time() < strtotime( $notification['start'] ) )
232
+ || ( ! empty( $notification['end'] ) && cff_get_current_time() > strtotime( $notification['end'] ) ) ) {
233
+ unset( $notifications[ $key ] );
234
+ }
235
+ }
236
+
237
+ return $notifications;
238
+ }
239
+
240
+ /**
241
+ * Get notification data.
242
+ *
243
+ * @since 2.18/3.17
244
+ *
245
+ * @return array
246
+ */
247
+ public function get() {
248
+ if ( ! $this->has_access() ) {
249
+ return array();
250
+ }
251
+
252
+ $option = $this->get_option();
253
+
254
+ // Update notifications using async task.
255
+ if ( empty( $option['update'] ) || cff_get_current_time() > $option['update'] + DAY_IN_SECONDS ) {
256
+ $this->update();
257
+ }
258
+
259
+ $events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
260
+ $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
261
+
262
+ // If there is a new user notification, add it to the beginning of the notification list
263
+ $cff_newuser = new CFF_New_User();
264
+ $newuser_notifications = $cff_newuser->get();
265
+
266
+ if ( ! empty( $newuser_notifications ) ) {
267
+ $events = array_merge( $newuser_notifications, $events );
268
+ }
269
+
270
+ return array_merge( $events, $feed );
271
+ }
272
+
273
+ /**
274
+ * Get notification count.
275
+ *
276
+ * @since 2.18/3.17
277
+ *
278
+ * @return int
279
+ */
280
+ public function get_count() {
281
+ return count( $this->get() );
282
+ }
283
+
284
+ /**
285
+ * Add a manual notification event.
286
+ *
287
+ * @since 2.18/3.17
288
+ *
289
+ * @param array $notification Notification data.
290
+ */
291
+ public function add( $notification ) {
292
+ if ( empty( $notification['id'] ) ) {
293
+ return;
294
+ }
295
+
296
+ $option = $this->get_option();
297
+
298
+ if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
299
+ return;
300
+ }
301
+
302
+ foreach ( $option['events'] as $item ) {
303
+ if ( $item['id'] === $notification['id'] ) {
304
+ return;
305
+ }
306
+ }
307
+
308
+ $notification = $this->verify( array( $notification ) );
309
+
310
+ update_option(
311
+ 'cff_notifications',
312
+ array(
313
+ 'update' => $option['update'],
314
+ 'feed' => $option['feed'],
315
+ 'events' => array_merge( $notification, $option['events'] ),
316
+ 'dismissed' => $option['dismissed'],
317
+ )
318
+ );
319
+ }
320
+
321
+ /**
322
+ * Update notification data from feed.
323
+ *
324
+ * @since 2.18/3.17
325
+ */
326
+ public function update() {
327
+ $feed = $this->fetch_feed();
328
+ $option = $this->get_option();
329
+
330
+ update_option(
331
+ 'cff_notifications',
332
+ array(
333
+ 'update' => cff_get_current_time(),
334
+ 'feed' => $feed,
335
+ 'events' => $option['events'],
336
+ 'dismissed' => $option['dismissed'],
337
+ )
338
+ );
339
+ }
340
+
341
+ /**
342
+ * Admin area Form Overview enqueues.
343
+ *
344
+ * @since 2.18/3.17
345
+ */
346
+ public function enqueues() {
347
+ if ( ! $this->has_access() ) {
348
+ return;
349
+ }
350
+
351
+ $notifications = $this->get();
352
+
353
+ if ( empty( $notifications ) ) {
354
+ return;
355
+ }
356
+
357
+ $min = '';
358
+
359
+ wp_enqueue_style(
360
+ 'cff-admin-notifications',
361
+ CFF_PLUGIN_URL . "css/admin-notifications{$min}.css",
362
+ array(),
363
+ CFFVER
364
+ );
365
+
366
+ wp_enqueue_script(
367
+ 'cff-admin-notifications',
368
+ CFF_PLUGIN_URL . "js/admin-notifications{$min}.js",
369
+ array( 'jquery' ),
370
+ CFFVER,
371
+ true
372
+ );
373
+ }
374
+
375
+ /**
376
+ * Fields from the remote source contain placeholders to allow
377
+ * some messages to be used for multiple plugins.
378
+ *
379
+ * @param $content string
380
+ * @param $notification array
381
+ *
382
+ * @return string
383
+ *
384
+ * @since 2.18/3.17
385
+ */
386
+ public function replace_merge_fields( $content, $notification ) {
387
+ $merge_fields = array(
388
+ '{plugin}' => 'Custom Facebook Feed',
389
+ '{amount}' => isset( $notification['amount'] ) ? $notification['amount'] : '',
390
+ '{platform}' => 'Facebook',
391
+ '{lowerplatform}' => 'facebook',
392
+ '{review-url}' => 'https://wordpress.org/support/plugin/custom-facebook-feed/reviews/',
393
+ '{slug}' => 'custom-facebook-feed',
394
+ '{campaign}' => 'facebook-free'
395
+ );
396
+
397
+ if ( cff_is_pro_version() ) {
398
+ $merge_fields['{campaign}'] = 'facebook-pro';
399
+ $merge_fields['{plugin}'] = 'Custom Facebook Feed Pro';
400
+ }
401
+
402
+ foreach ( $merge_fields as $find => $replace ) {
403
+ $content = str_replace( $find, $replace, $content );
404
+ }
405
+
406
+ return $content;
407
+ }
408
+
409
+ /**
410
+ * Output notifications on Custom Facebook Feed admin area.
411
+ *
412
+ * @since 2.18/3.17
413
+ */
414
+ public function output() {
415
+ $notifications = $this->get();
416
+
417
+ if ( empty( $notifications ) ) {
418
+ return;
419
+ }
420
+
421
+ $notifications_html = '';
422
+ $current_class = ' current';
423
+ $content_allowed_tags = array(
424
+ 'em' => array(),
425
+ 'strong' => array(),
426
+ 'span' => array(
427
+ 'style' => array(),
428
+ ),
429
+ 'a' => array(
430
+ 'href' => array(),
431
+ 'target' => array(),
432
+ 'rel' => array(),
433
+ ),
434
+ );
435
+
436
+ foreach ( $notifications as $notification ) {
437
+
438
+ // Buttons HTML.
439
+ $buttons_html = '';
440
+ if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
441
+ foreach ( $notification['btns'] as $btn_type => $btn ) {
442
+ if ( is_array( $btn['url'] ) ) {
443
+ $btn['url'] = add_query_arg( $btn['url'] );
444
+ }
445
+ if ( ! empty( $btn['attr'] ) ) {
446
+ $btn['target'] = '_blank';
447
+ }
448
+ $buttons_html .= sprintf(
449
+ '<a href="%1$s" class="button button-%2$s"%3$s>%4$s</a>',
450
+ ! empty( $btn['url'] ) ? esc_url( $this->replace_merge_fields( $btn['url'], $notification ) ) : '',
451
+ $btn_type === 'primary' ? 'primary' : 'secondary',
452
+ ! empty( $btn['target'] ) && $btn['target'] === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '',
453
+ ! empty( $btn['text'] ) ? sanitize_text_field( $btn['text'] ) : ''
454
+ );
455
+ }
456
+ $buttons_html = ! empty( $buttons_html ) ? '<div class="buttons">' . $buttons_html . '</div>' : '';
457
+ }
458
+
459
+ if ( empty( $notification['image'] ) ) {
460
+ $image_html = '<div class="bell">';
461
+
462
+ $image_html .= '<svg xmlns="http://www.w3.org/2000/svg" width="42" height="48" viewBox="0 0 42 48"><defs><style>.a{fill:#777;}.b{fill:#ca4a1f;}</style></defs><path class="a" d="M23-79a6.005,6.005,0,0,1-6-6h10.06a12.066,12.066,0,0,0,1.791,1.308,6.021,6.021,0,0,1-2.077,3.352A6.008,6.008,0,0,1,23-79Zm1.605-9H5.009a2.955,2.955,0,0,1-2.173-.923A3.088,3.088,0,0,1,2-91a2.919,2.919,0,0,1,.807-2.036c.111-.12.229-.243.351-.371a14.936,14.936,0,0,0,3.126-4.409A23.283,23.283,0,0,0,8.007-107.5a14.846,14.846,0,0,1,.906-5.145,14.5,14.5,0,0,1,2.509-4.324A15.279,15.279,0,0,1,20-122.046V-124a3,3,0,0,1,3-3,3,3,0,0,1,3,3v1.954a15.28,15.28,0,0,1,8.58,5.078,14.5,14.5,0,0,1,2.509,4.324,14.846,14.846,0,0,1,.906,5.145c0,.645.016,1.281.047,1.888A12.036,12.036,0,0,0,35-106a11.921,11.921,0,0,0-8.485,3.515A11.923,11.923,0,0,0,23-94a12,12,0,0,0,1.6,6Z" transform="translate(-2 127)"/><circle class="b" cx="9" cy="9" r="9" transform="translate(24 24)"/></svg>';
463
+ $image_html .= '</div>';
464
+ } else {
465
+ if ( $notification['image'] === 'balloon'
466
+ || $notification['id'] === 'review'
467
+ || $notification['id'] === 'discount') {
468
+ $image_html = '<div class="bell">';
469
+
470
+ $image_html .= '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1438 1878" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2">';
471
+ $image_html .= ' <path d="M671.51004 492.9884C539.9423 433.8663 402.90125 345.5722 274.97656 304.47286c45.45163 108.39592 83.81332 223.88017 123.51 338.03105C319.308 702.00293 226.8217 748.19258 138.46278 798.51607c75.1914 74.32371 181.67968 117.34651 266.52444 182.01607-67.96124 83.86195-201.48527 171.01801-234.02107 247.01998 140.6922-17.6268 304.63688-46.21031 435.53794-52.00418 28.76427 144.58328 43.5987 303.09763 84.50756 435.53713 60.92033-175.26574 116.0014-356.37317 188.51594-520.0451 111.90644 46.2857 248.29012 102.72607 357.52902 130.01188-76.64636-107.5347-146.59346-221.76948-214.5166-338.02903 100.51162-72.83876 202.1718-144.52451 299.02538-221.02092-136.89514-12.61229-278.73428-20.28827-422.53618-25.99865-22.85288-148.33212-16.84826-325.51604-52.005-461.53983-53.19327 111.4882-115.96694 213.39155-175.51418 318.52497m65.00513 1228.60735c-18.0795 77.37586 41.4876 109.11326 32.50298 156.01215-58.8141-20.268-103.0576-30.67962-182.01567-19.50203 2.47018-60.37036 56.76662-68.90959 45.50432-143.0108C-208.90184 1619.4318-210.59186 99.02478 626.00572 5.44992c1046.0409-117.00405 1078.86445 1689.2596 110.50945 1716.14582" fill="#e34f0e"/>';
472
+ $image_html .= ' <path d="M847.02422 174.46342c35.15674 136.02379 29.15212 313.20771 52.0046 461.53578 143.8023 5.71443 285.63982 13.38636 422.53658 26.0027-96.85317 76.4964-198.51497 148.18216-299.02579 221.0189 67.92355 116.26239 137.87024 230.49432 214.51864 338.03024-109.24093-27.28662-245.62461-83.72577-357.53106-130.01269-72.51454 163.67274-127.5956 344.78017-188.51553 520.0459-40.90926-132.4395-55.74329-290.95384-84.50796-435.53712-130.90066 5.79549-294.84493 34.37738-435.53754 52.00418 32.5358-76.00075 166.05902-163.156 234.02026-247.02038-84.84516-64.67037-191.33222-107.69074-266.52363-182.01486 88.35892-50.32349 180.8436-96.51314 260.02295-156.0162-39.69708-114.14683-78.05674-229.63108-123.50878-338.027C402.89923 345.5722 539.9423 433.86629 671.51004 492.98839c59.54684-105.13342 122.3209-207.03677 175.51418-318.52497" fill="#fff"/>';
473
+ $image_html .= '</svg>';
474
+ } else {
475
+ $image_html = '<div class="thumb">';
476
+ $img_src = SBY_PLUGIN_URL . 'img/' . sanitize_text_field( $notification['image'] );
477
+ $image_html .= '<img src="'.esc_url( $img_src ).'" alt="notice">';
478
+
479
+ if ( isset( $notification['image_overlay'] ) ) {
480
+ $image_html .= '<div class="img-overlay">'. esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ).'</div>';
481
+ }
482
+ }
483
+ $image_html .= '</div>';
484
+
485
+ }
486
+
487
+ // Notification HTML.
488
+ $notifications_html .= sprintf(
489
+ '<div class="message%5$s" data-message-id="%4$s">' . $image_html . '
490
+ <h3 class="title">%1$s</h3>
491
+ <p class="content">%2$s</p>
492
+ %3$s
493
+ </div>',
494
+ ! empty( $notification['title'] ) ? $this->replace_merge_fields( sanitize_text_field( $notification['title'] ), $notification ) : '',
495
+ ! empty( $notification['content'] ) ? wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags ) : '',
496
+ $buttons_html,
497
+ ! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
498
+ $current_class
499
+ );
500
+
501
+ // Only first notification is current.
502
+ $current_class = '';
503
+ }
504
+ ?>
505
+
506
+ <div id="cff-notifications">
507
+ <a class="dismiss" title="<?php echo esc_attr__( 'Dismiss this message', 'custom-facebook-feed' ); ?>"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
508
+
509
+ <div class="navigation">
510
+ <a class="prev disabled" title="<?php echo esc_attr__( 'Previous message', 'custom-facebook-feed' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-left" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-left fa-w-10"><path fill="currentColor" d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z" class=""></path></svg></a>
511
+ <a class="next disabled" title="<?php echo esc_attr__( 'Next message', 'custom-facebook-feed' ); ?>"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-chevron-right fa-w-10"><path fill="currentColor" d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" class=""></path></svg></a>
512
+ </div>
513
+
514
+ <div class="messages">
515
+ <?php echo $notifications_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
516
+ </div>
517
+ </div>
518
+ <?php
519
+ }
520
+
521
+ /**
522
+ * Dismiss notification via AJAX. If it's a new user message, also dismiss it
523
+ * on all admin pages.
524
+ *
525
+ * @since 2.18/3.17
526
+ */
527
+ public function dismiss() {
528
+ // Run a security check.
529
+ check_ajax_referer( 'cff-admin', 'nonce' );
530
+
531
+ // Check for access and required param.
532
+ if ( ! $this->has_access() || empty( $_POST['id'] ) ) {
533
+ wp_send_json_error();
534
+ }
535
+
536
+ $id = sanitize_text_field( wp_unslash( $_POST['id'] ) );
537
+
538
+ if ( $id === 'review' ) {
539
+ $cff_statuses_option = get_option( 'cff_statuses', array() );
540
+
541
+ update_option( 'cff_rating_notice', 'dismissed', false );
542
+ $cff_statuses_option['rating_notice_dismissed'] = cff_get_current_time();
543
+ update_option( 'cff_statuses', $cff_statuses_option, false );
544
+ } elseif ( $id === 'discount' ) {
545
+ update_user_meta( get_current_user_id(), 'cff_ignore_new_user_sale_notice', 'always' );
546
+
547
+ $current_month_number = (int)date('n', cff_get_current_time() );
548
+ $not_early_in_the_year = ($current_month_number > 5);
549
+
550
+ if ( $not_early_in_the_year ) {
551
+ update_user_meta( get_current_user_id(), 'cff_ignore_bfcm_sale_notice', date( 'Y', cff_get_current_time() ) );
552
+ }
553
+ }
554
+
555
+ $option = $this->get_option();
556
+ $type = is_numeric( $id ) ? 'feed' : 'events';
557
+
558
+ $option['dismissed'][] = $id;
559
+ $option['dismissed'] = array_unique( $option['dismissed'] );
560
+
561
+ // Remove notification.
562
+ if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) {
563
+ foreach ( $option[ $type ] as $key => $notification ) {
564
+ if ( $notification['id'] == $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons
565
+ unset( $option[ $type ][ $key ] );
566
+ break;
567
+ }
568
+ }
569
+ }
570
+
571
+ update_option( 'cff_notifications', $option );
572
+
573
+ wp_send_json_success();
574
+ }
575
+ }
css/admin-notifications.css ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #cff-notifications {
2
+ position: relative;
3
+ background: #FFFFFF 0 0 no-repeat padding-box;
4
+ box-shadow: 0px 5px 15px #0000000D;
5
+ border-radius: 6px;
6
+ opacity: 1;
7
+ min-height: 48px;
8
+ padding: 15px 102px 15px 72px;
9
+ margin: 0 0 14px 0;
10
+ }
11
+
12
+ #cff-notifications * {
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ #cff-notifications .bell,
17
+ #cff-notifications .thumb{
18
+ position: absolute;
19
+ top: 15px;
20
+ left: 15px;
21
+ width: 42px;
22
+ height: 48px;
23
+ }
24
+ #cff-notifications .thumb img {
25
+ max-width: 100%;
26
+ }
27
+ #cff-notifications .thumb .img-overlay {
28
+ top: 42px;
29
+ left: -6px;
30
+ width: 54px;
31
+ position: absolute;
32
+ background: #ca4a1f;
33
+ color: #fff;
34
+ padding: 2px 4px;
35
+ border-radius: 3px;
36
+ line-height: 1;
37
+ font-size: 11px;
38
+ font-weight: bold;
39
+ text-align: center;
40
+ }
41
+
42
+ #cff-notifications .messages .message {
43
+ display: none;
44
+ }
45
+
46
+ #cff-notifications .messages .message.current {
47
+ display: block;
48
+ }
49
+
50
+ #cff-notifications .messages .message .title {
51
+ font-weight: bold;
52
+ font-size: 17px;
53
+ line-height: 20px;
54
+ margin: 0;
55
+ color: #444;
56
+ }
57
+
58
+ #cff-notifications .messages .message .content {
59
+ font-weight: normal;
60
+ font-size: 13px;
61
+ line-height: 20px;
62
+ margin: 6px 0 40px 0;
63
+ }
64
+
65
+ #cff-notifications .messages .message .buttons {
66
+ margin: -30px 80px 0 0;
67
+ }
68
+
69
+ #cff-notifications .messages .message .buttons a {
70
+ margin: 0 6px 0 0;
71
+ padding: 8px 10px;
72
+ line-height: 13px;
73
+ font-size: 13px;
74
+ min-height: unset;
75
+ }
76
+
77
+ #cff-notifications .messages .message .buttons .button-secondary {
78
+ border: 1px solid #0071A1;
79
+ }
80
+
81
+ #cff-notifications .dismiss {
82
+ position: absolute;
83
+ top: 15px;
84
+ right: 15px;
85
+ width: 16px;
86
+ height: 16px;
87
+ color: #72777C;
88
+ font-size: 16px;
89
+ cursor: pointer;
90
+ text-align: center;
91
+ vertical-align: middle;
92
+ line-height: 16px;
93
+ }
94
+
95
+ #cff-notifications .dismiss:hover {
96
+ color: #dc3232;
97
+ }
98
+
99
+ #cff-notifications .navigation {
100
+ position: absolute;
101
+ bottom: 15px;
102
+ right: 15px;
103
+ width: 63px;
104
+ height: 30px;
105
+ }
106
+
107
+ #cff-notifications .navigation a {
108
+ display: block;
109
+ width: 30px;
110
+ height: 30px;
111
+ border: 1px solid #7E8993;
112
+ border-radius: 3px;
113
+ font-size: 8px;
114
+ text-align: center;
115
+ vertical-align: middle;
116
+ line-height: 30px;
117
+ cursor: pointer;
118
+ background-color: #ffffff;
119
+ color: #41454A;
120
+ }
121
+ #cff-notifications .navigation svg {
122
+ width: 8px;
123
+ height: 8px;
124
+ }
125
+
126
+ #cff-notifications .navigation a:hover {
127
+ background-color: #f1f1f1;
128
+ }
129
+
130
+ #cff-notifications .navigation .prev {
131
+ float: left;
132
+ }
133
+
134
+ #cff-notifications .navigation .next {
135
+ float: right;
136
+ }
137
+
138
+ #cff-notifications .navigation .disabled {
139
+ border-color: #dddddd;
140
+ color: #A0A5AA;
141
+ cursor: default;
142
+ }
143
+
144
+ #cff-notifications .navigation .disabled:hover {
145
+ background-color: #ffffff;
146
+ }
147
+
148
+ @media screen and (max-width: 768px) {
149
+ #cff-notifications {
150
+ padding: 15px 15px 15px 72px;
151
+ }
152
+ #cff-notifications .messages .message .title {
153
+ margin: 0 30px 0 0;
154
+ }
155
+ #cff-notifications .messages .message .content {
156
+ font-size: 16px;
157
+ line-height: 24px;
158
+ }
159
+ #cff-notifications .messages .message .buttons {
160
+ margin: -30px 80px 0 0;
161
+ }
162
+ #cff-notifications .messages .message .buttons a {
163
+ margin: 0;
164
+ display: table;
165
+ }
166
+ #cff-notifications .messages .message .buttons .button-secondary {
167
+ margin-top: 6px;
168
+ }
169
+ }
170
+
171
+ /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2Nzcy9hZG1pbi1ub3RpZmljYXRpb25zLmNzcyIsInNvdXJjZXMiOlsiYXNzZXRzL3Njc3MvYWRtaW4tbm90aWZpY2F0aW9ucy5zY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEFkbWluIG5vdGlmaWNhdGlvbiBzdHlsZXMuXG5cbiN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXG5cdHBvc2l0aW9uOiByZWxhdGl2ZTtcblx0YmFja2dyb3VuZDogI0ZGRkZGRiAwIDAgbm8tcmVwZWF0IHBhZGRpbmctYm94O1xuXHRib3gtc2hhZG93OiAwcHggNXB4IDE1cHggIzAwMDAwMDBEO1xuXHRib3JkZXItcmFkaXVzOiA2cHg7XG5cdG9wYWNpdHk6IDE7XG5cdG1pbi1oZWlnaHQ6IDQ4cHg7XG5cdHBhZGRpbmc6IDE1cHggMTAycHggMTVweCA3MnB4O1xuXHRtYXJnaW46IDAgMCAxNHB4IDA7XG5cblx0KiB7XG5cdFx0Ym94LXNpemluZzogYm9yZGVyLWJveDtcblx0fVxuXG5cdC5iZWxsIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdGxlZnQ6IDE1cHg7XG5cdFx0d2lkdGg6IDQycHg7XG5cdFx0aGVpZ2h0OiA0OHB4O1xuXHR9XG5cblx0Lm1lc3NhZ2VzIHtcblx0XHQubWVzc2FnZSB7XG5cdFx0XHRkaXNwbGF5OiBub25lO1xuXG5cdFx0XHQmLmN1cnJlbnQge1xuXHRcdFx0XHRkaXNwbGF5OiBibG9jaztcblx0XHRcdH1cblxuXHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IGJvbGQ7XG5cdFx0XHRcdGZvbnQtc2l6ZTogMTdweDtcblx0XHRcdFx0bGluZS1oZWlnaHQ6IDIwcHg7XG5cdFx0XHRcdG1hcmdpbjogMDtcblx0XHRcdFx0Y29sb3I6ICM0NDQ7XG5cdFx0XHR9XG5cblx0XHRcdC5jb250ZW50IHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IG5vcm1hbDtcblx0XHRcdFx0Zm9udC1zaXplOiAxM3B4O1xuXHRcdFx0XHRsaW5lLWhlaWdodDogMjBweDtcblx0XHRcdFx0bWFyZ2luOiA2cHggMCA0MHB4IDA7XG5cdFx0XHR9XG5cblx0XHRcdC5idXR0b25zIHtcblx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRhIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgNnB4IDAgMDtcblx0XHRcdFx0XHRwYWRkaW5nOiA4cHggMTBweDtcblx0XHRcdFx0XHRsaW5lLWhlaWdodDogMTNweDtcblx0XHRcdFx0XHRmb250LXNpemU6IDEzcHg7XG5cdFx0XHRcdFx0bWluLWhlaWdodDogdW5zZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9uLXNlY29uZGFyeSB7XG5cdFx0XHRcdFx0Ym9yZGVyOiAxcHggc29saWQgIzAwNzFBMTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC5kaXNtaXNzIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdHJpZ2h0OiAxNXB4O1xuXHRcdHdpZHRoOiAxNnB4O1xuXHRcdGhlaWdodDogMTZweDtcblx0XHRjb2xvcjogIzcyNzc3Qztcblx0XHRmb250LXNpemU6IDE2cHg7XG5cdFx0Y3Vyc29yOiBwb2ludGVyO1xuXHRcdHRleHQtYWxpZ246IGNlbnRlcjtcblx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdGxpbmUtaGVpZ2h0OiAxNnB4O1xuXG5cdFx0Jjpob3ZlciB7XG5cdFx0XHRjb2xvcjogI2RjMzIzMjtcblx0XHR9XG5cdH1cblxuXHQubmF2aWdhdGlvbiB7XG5cdFx0cG9zaXRpb246IGFic29sdXRlO1xuXHRcdGJvdHRvbTogMTVweDtcblx0XHRyaWdodDogMTVweDtcblx0XHR3aWR0aDogNjNweDtcblx0XHRoZWlnaHQ6IDMwcHg7XG5cblx0XHRhIHtcblx0XHRcdGRpc3BsYXk6IGJsb2NrO1xuXHRcdFx0d2lkdGg6IDMwcHg7XG5cdFx0XHRoZWlnaHQ6IDMwcHg7XG5cdFx0XHRib3JkZXI6IDFweCBzb2xpZCAjN0U4OTkzO1xuXHRcdFx0Ym9yZGVyLXJhZGl1czogM3B4O1xuXHRcdFx0Zm9udC1zaXplOiA4cHg7XG5cdFx0XHR0ZXh0LWFsaWduOiBjZW50ZXI7XG5cdFx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdFx0bGluZS1oZWlnaHQ6IDMwcHg7XG5cdFx0XHRjdXJzb3I6IHBvaW50ZXI7XG5cdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0Y29sb3I6ICM0MTQ1NEE7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZjFmMWYxO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC5wcmV2IHtcblx0XHRcdGZsb2F0OiBsZWZ0O1xuXHRcdH1cblxuXHRcdC5uZXh0IHtcblx0XHRcdGZsb2F0OiByaWdodDtcblx0XHR9XG5cblx0XHQuZGlzYWJsZWQge1xuXHRcdFx0Ym9yZGVyLWNvbG9yOiAjZGRkZGRkO1xuXHRcdFx0Y29sb3I6ICNBMEE1QUE7XG5cdFx0XHRjdXJzb3I6IGRlZmF1bHQ7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA3NjhweCkge1xuXG5cdCN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXHRcdHBhZGRpbmc6IDE1cHggMTVweCAxNXB4IDcycHg7XG5cblx0XHQubWVzc2FnZXMge1xuXG5cdFx0XHQubWVzc2FnZSB7XG5cblx0XHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgMzBweCAwIDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuY29udGVudCB7XG5cdFx0XHRcdFx0Zm9udC1zaXplOiAxNnB4O1xuXHRcdFx0XHRcdGxpbmUtaGVpZ2h0OiAyNHB4XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9ucyB7XG5cdFx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRcdGEge1xuXHRcdFx0XHRcdFx0bWFyZ2luOiAwO1xuXHRcdFx0XHRcdFx0ZGlzcGxheTogdGFibGU7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0LmJ1dHRvbi1zZWNvbmRhcnkge1xuXHRcdFx0XHRcdFx0bWFyZ2luLXRvcDogNnB4O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxBQUFBLHNCQUFzQixDQUFDO0VBRXRCLFFBQVEsRUFBRSxRQUFRO0VBQ2xCLFVBQVUsRUFBRSxpQ0FBaUM7RUFDN0MsVUFBVSxFQUFFLHNCQUFzQjtFQUNsQyxhQUFhLEVBQUUsR0FBRztFQUNsQixPQUFPLEVBQUUsQ0FBQztFQUNWLFVBQVUsRUFBRSxJQUFJO0VBQ2hCLE9BQU8sRUFBRSxvQkFBb0I7RUFDN0IsTUFBTSxFQUFFLFVBQVU7Q0FxSGxCOztBQTlIRCxBQVdDLHNCQVhxQixDQVdyQixDQUFDLENBQUM7RUFDRCxVQUFVLEVBQUUsVUFBVTtDQUN0Qjs7QUFiRixBQWVDLHNCQWZxQixDQWVyQixLQUFLLENBQUM7RUFDTCxRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULElBQUksRUFBRSxJQUFJO0VBQ1YsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtDQUNaOztBQXJCRixBQXdCRSxzQkF4Qm9CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQUFDO0VBQ1IsT0FBTyxFQUFFLElBQUk7Q0FvQ2I7O0FBN0RILEFBMkJHLHNCQTNCbUIsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLEFBR04sUUFBUSxDQUFDO0VBQ1QsT0FBTyxFQUFFLEtBQUs7Q0FDZDs7QUE3QkosQUErQkcsc0JBL0JtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FPUCxNQUFNLENBQUM7RUFDTixXQUFXLEVBQUUsSUFBSTtFQUNqQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxDQUFDO0VBQ1QsS0FBSyxFQUFFLElBQUk7Q0FDWDs7QUFyQ0osQUF1Q0csc0JBdkNtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FlUCxRQUFRLENBQUM7RUFDUixXQUFXLEVBQUUsTUFBTTtFQUNuQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxZQUFZO0NBQ3BCOztBQTVDSixBQThDRyxzQkE5Q21CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQXNCUCxRQUFRLENBQUM7RUFDUixNQUFNLEVBQUUsY0FBYztDQWF0Qjs7QUE1REosQUFpREksc0JBakRrQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FzQlAsUUFBUSxDQUdQLENBQUMsQ0FBQztFQUNELE1BQU0sRUFBRSxTQUFTO0VBQ2pCLE9BQU8sRUFBRSxRQUFRO0VBQ2pCLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLFNBQVMsRUFBRSxJQUFJO0VBQ2YsVUFBVSxFQUFFLEtBQUs7Q0FDakI7O0FBdkRMLEFBeURJLHNCQXpEa0IsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLENBc0JQLFFBQVEsQ0FXUCxpQkFBaUIsQ0FBQztFQUNqQixNQUFNLEVBQUUsaUJBQWlCO0NBQ3pCOztBQTNETCxBQWdFQyxzQkFoRXFCLENBZ0VyQixRQUFRLENBQUM7RUFDUixRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULEtBQUssRUFBRSxJQUFJO0VBQ1gsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtFQUNaLEtBQUssRUFBRSxPQUFPO0VBQ2QsU0FBUyxFQUFFLElBQUk7RUFDZixNQUFNLEVBQUUsT0FBTztFQUNmLFVBQVUsRUFBRSxNQUFNO0VBQ2xCLGNBQWMsRUFBRSxNQUFNO0VBQ3RCLFdBQVcsRUFBRSxJQUFJO0NBS2pCOztBQWhGRixBQTZFRSxzQkE3RW9CLENBZ0VyQixRQUFRLEFBYU4sTUFBTSxDQUFDO0VBQ1AsS0FBSyxFQUFFLE9BQU87Q0FDZDs7QUEvRUgsQUFrRkMsc0JBbEZxQixDQWtGckIsV0FBVyxDQUFDO0VBQ1gsUUFBUSxFQUFFLFFBQVE7RUFDbEIsTUFBTSxFQUFFLElBQUk7RUFDWixLQUFLLEVBQUUsSUFBSTtFQUNYLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7Q0FzQ1o7O0FBN0hGLEFBeUZFLHNCQXpGb0IsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLENBQUM7RUFDRCxPQUFPLEVBQUUsS0FBSztFQUNkLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7RUFDWixNQUFNLEVBQUUsaUJBQWlCO0VBQ3pCLGFBQWEsRUFBRSxHQUFHO0VBQ2xCLFNBQVMsRUFBRSxHQUFHO0VBQ2QsVUFBVSxFQUFFLE1BQU07RUFDbEIsY0FBYyxFQUFFLE1BQU07RUFDdEIsV0FBVyxFQUFFLElBQUk7RUFDakIsTUFBTSxFQUFFLE9BQU87RUFDZixnQkFBZ0IsRUFBRSxPQUFPO0VBQ3pCLEtBQUssRUFBRSxPQUFPO0NBS2Q7O0FBMUdILEFBdUdHLHNCQXZHbUIsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLEFBY0MsTUFBTSxDQUFDO0VBQ1AsZ0JBQWdCLEVBQUUsT0FBTztDQUN6Qjs7QUF6R0osQUE0R0Usc0JBNUdvQixDQWtGckIsV0FBVyxDQTBCVixLQUFLLENBQUM7RUFDTCxLQUFLLEVBQUUsSUFBSTtDQUNYOztBQTlHSCxBQWdIRSxzQkFoSG9CLENBa0ZyQixXQUFXLENBOEJWLEtBQUssQ0FBQztFQUNMLEtBQUssRUFBRSxLQUFLO0NBQ1o7O0FBbEhILEFBb0hFLHNCQXBIb0IsQ0FrRnJCLFdBQVcsQ0FrQ1YsU0FBUyxDQUFDO0VBQ1QsWUFBWSxFQUFFLE9BQU87RUFDckIsS0FBSyxFQUFFLE9BQU87RUFDZCxNQUFNLEVBQUUsT0FBTztDQUtmOztBQTVISCxBQXlIRyxzQkF6SG1CLENBa0ZyQixXQUFXLENBa0NWLFNBQVMsQUFLUCxNQUFNLENBQUM7RUFDUCxnQkFBZ0IsRUFBRSxPQUFPO0NBQ3pCOztBQUtKLE1BQU0sQ0FBQyxNQUFNLE1BQU0sU0FBUyxFQUFFLEtBQUs7RUFFbEMsQUFBQSxzQkFBc0IsQ0FBQztJQUN0QixPQUFPLEVBQUUsbUJBQW1CO0dBNkI1QjtFQTlCRCxBQU9HLHNCQVBtQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQUVQLE1BQU0sQ0FBQztJQUNOLE1BQU0sRUFBRSxVQUFVO0dBQ2xCO0VBVEosQUFXRyxzQkFYbUIsQ0FHckIsU0FBUyxDQUVSLFFBQVEsQ0FNUCxRQUFRLENBQUM7SUFDUixTQUFTLEVBQUUsSUFBSTtJQUNmLFdBQVcsRUFBRSxJQUNkO0dBQUM7RUFkSixBQWdCRyxzQkFoQm1CLENBR3JCLFNBQVMsQ0FFUixRQUFRLENBV1AsUUFBUSxDQUFDO0lBQ1IsTUFBTSxFQUFFLGNBQWM7R0FVdEI7RUEzQkosQUFtQkksc0JBbkJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FHUCxDQUFDLENBQUM7SUFDRCxNQUFNLEVBQUUsQ0FBQztJQUNULE9BQU8sRUFBRSxLQUFLO0dBQ2Q7RUF0QkwsQUF3Qkksc0JBeEJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FRUCxpQkFBaUIsQ0FBQztJQUNqQixVQUFVLEVBQUUsR0FBRztHQUNmIn0= */
css/cff-admin-style.css CHANGED
@@ -827,98 +827,123 @@
827
  }
828
 
829
  /* Review notice */
830
- .cff_review_notice{
831
- position: relative;
832
- overflow: hidden;
833
- max-width: 870px;
834
- margin-top: 10px;
835
- padding: 10px 10px 7px 10px;
836
 
837
- background: #E6F0E8;
838
- border: 1px solid #6AB074;
839
- color: #214F28;
840
- }
841
- .cff_bfcm_sale_notice,
842
- .cff_new_user_sale_notice {
843
- max-width: 700px;
844
  }
845
- .cff_review_notice img{
846
- width: 74px;
847
- margin: 0 0 0 -100% !important;
 
 
848
 
849
- -moz-border-radius: 4px;
850
- -webkit-border-radius: 4px;
851
- border-radius: 4px;
852
  }
853
- .cff_review_notice .cff-notice-text{
854
- float: left;
855
- clear: none;
856
- width: 100%;
857
- padding: 0;
 
 
 
 
 
 
858
  }
859
- .cff_review_notice p{
860
- float: left;
861
- clear: both;
862
- width: auto;
863
- margin: 0 0 0 90px !important;
864
- padding: 2px 40px 2px 0;
865
- line-height: 1.4;
866
  }
867
- .cff_review_notice a{
868
- display: inline-block;
869
- padding: 0 8px;
870
- color: #178529;
 
871
  }
872
- .cff_review_notice a:hover,
873
- .cff_review_notice a:focus{
874
- color: #0c7abf;
875
  }
876
- .cff_review_notice .cff-links{
877
- margin: 0 0 0 90px !important;
878
- margin-top: 4px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
879
  }
880
  .cff_review_notice .links{
881
- padding: 4px 0 0 0;
882
- margin-top: 6px !important;
883
  }
884
- .cff_review_notice .cff_notice_close,
885
- .cff_review_notice .cff_bfcm_sale_notice_close,
886
- .cff_review_notice .cff_new_user_sale_notice_close {
887
- position: absolute;
888
- top: 0;
889
- right: 0;
890
- padding: 10px;
891
- line-height: 1;
 
 
 
 
892
  }
893
- .cff_review_notice .cff_notice_close:hover,
894
- .cff_review_notice .cff_notice_close:focus{
895
- color: #a34100;
896
  }
897
-
898
  /* Notice CTA btn */
899
- .cff_review_notice .cff_offer_btn{
 
900
  padding: 4px 12px 6px 12px;
901
- background: green;
902
- color: #fff;
903
- border-radius: 4px;
904
- display: inline-block;
905
- text-decoration: none;
906
- margin-left: 0;
 
907
  }
908
- .cff_review_notice .cff_offer_btn:hover,
909
- .cff_review_notice .cff_offer_btn:focus{
 
 
910
  background: #049404;
911
  color: #fff;
912
  }
913
- .cff_review_notice .cff_other_notice{
914
  padding-top: 10px;
915
- font-style: italic;
916
- font-size: 12px;
917
  }
918
- .cff_review_notice .cff_other_notice a{
919
  padding: 0;
920
  }
921
-
 
 
922
 
923
  /* Support page */
924
  #cff-admin .cff_support{
827
  }
828
 
829
  /* Review notice */
830
+ .cff_notice{
831
+ position: relative;
832
+ overflow: hidden;
833
+ max-width: 885px;
834
+ margin-top: 10px;
835
+ padding: 10px 10px 7px 10px;
836
 
837
+ background: #E6F0E8;
838
+ border: 1px solid #6AB074;
839
+ color: #214F28;
 
 
 
 
840
  }
841
+ .cff_notice .cff_thumb{
842
+ position: relative;
843
+ display: inline-block;
844
+ width: 74px;
845
+ margin: 0 0 0 -100% !important;
846
 
847
+ -moz-border-radius: 4px;
848
+ -webkit-border-radius: 4px;
849
+ border-radius: 4px;
850
  }
851
+ .cff_notice .cff_thumb .img-overlay {
852
+ position: absolute;
853
+ bottom: 4px;
854
+ padding: 6px 7px 6px 5px;
855
+ font-size: 13px;
856
+ font-weight: bold;
857
+ background: #fff;
858
+ background: rgba(255,255,255,0.85);
859
+ line-height: 1;
860
+ color: #333;
861
+ box-shadow: 1px -1px 3px 0 rgba(0,0,0,0.15);
862
  }
863
+ .cff_notice .cff_thumb img {
864
+ max-width: 100%;
 
 
 
 
 
865
  }
866
+ .cff_notice .cff-notice-text{
867
+ float: left;
868
+ clear: none;
869
+ width: 100%;
870
+ padding: 0;
871
  }
872
+ .cff_notice .cff-links{
873
+ margin-top: 4px !important;
 
874
  }
875
+ .cff_notice p{
876
+ float: left;
877
+ clear: both;
878
+ width: auto;
879
+ margin: 0 0 0 90px !important;
880
+ padding: 2px 40px 2px 0;
881
+ line-height: 1.4;
882
+ }
883
+ .cff_notice a{
884
+ display: inline-block;
885
+ padding: 0 8px;
886
+ color: #178529;
887
+ }
888
+ .cff_notice a:hover,
889
+ .cff_notice a:focus{
890
+ color: #0c7abf;
891
+ }
892
+ .cff_notice .links{
893
+ margin: 0 0 0 90px !important;
894
+ padding: 4px 0 0 0;
895
+ margin-top: 1px !important;
896
  }
897
  .cff_review_notice .links{
898
+ margin-left: 82px !important;
899
+ margin-top: 0 !important;
900
  }
901
+ .cff_notice .cff_notice_close,
902
+ .cff_notice .cff_bfcm_sale_notice_close,
903
+ .cff_notice .cff_new_user_sale_notice_close {
904
+ position: absolute;
905
+ top: 0;
906
+ right: 0;
907
+ padding: 10px;
908
+ line-height: 1;
909
+ }
910
+ .cff_notice .cff_notice_close:hover,
911
+ .cff_notice .cff_notice_close:focus{
912
+ color: #a34100;
913
  }
914
+ .cff_notice strong span {
915
+ font-weight: 900;
 
916
  }
 
917
  /* Notice CTA btn */
918
+ .cff_notice .cff_offer_btn,
919
+ .cff_notice .cff_main_cta{
920
  padding: 4px 12px 6px 12px;
921
+ background: green;
922
+ color: #fff;
923
+ border-radius: 4px;
924
+ display: inline-block;
925
+ text-decoration: none;
926
+ margin-left: 0;
927
+ margin-right: 4px;
928
  }
929
+ .cff_notice .cff_offer_btn:hover,
930
+ .cff_notice .cff_offer_btn:focus,
931
+ .cff_notice .cff_main_cta:hover,
932
+ .cff_notice .cff_main_cta:focus{
933
  background: #049404;
934
  color: #fff;
935
  }
936
+ .cff_notice .cff_other_notice{
937
  padding-top: 10px;
938
+ font-style: italic;
939
+ font-size: 12px;
940
  }
941
+ .cff_notice .cff_other_notice a{
942
  padding: 0;
943
  }
944
+ .cff_notice .links > .cff_main_cta:first-child {
945
+ margin-left: 8px;
946
+ }
947
 
948
  /* Support page */
949
  #cff-admin .cff_support{
css/cff-style.css CHANGED
@@ -336,7 +336,7 @@
336
  #cff .cff-author .cff-date{
337
  color: #9197a3;
338
  font-size: 11px;
339
- margin-top: 0px !important;
340
  margin-bottom: 0px !important;
341
  }
342
  #cff.cff-default-styles .cff-author .cff-date{
@@ -344,7 +344,7 @@
344
  }
345
  #cff .cff-author .cff-page-name.cff-author-date{
346
  float: left;
347
- padding: 2px 0 0 0;
348
  font-size: 14px;
349
  }
350
 
@@ -537,7 +537,7 @@
537
  bottom: 22px;
538
  right: -40px;
539
  width: 110px;
540
- padding: 5px 5px 4px 5px;
541
  margin: 0;
542
  background: #333;
543
  color: #eee;
336
  #cff .cff-author .cff-date{
337
  color: #9197a3;
338
  font-size: 11px;
339
+ margin-top: 2px !important;
340
  margin-bottom: 0px !important;
341
  }
342
  #cff.cff-default-styles .cff-author .cff-date{
344
  }
345
  #cff .cff-author .cff-page-name.cff-author-date{
346
  float: left;
347
+ padding: 3px 0 0 0;
348
  font-size: 14px;
349
  }
350
 
537
  bottom: 22px;
538
  right: -40px;
539
  width: 110px;
540
+ padding: 3px 5px 4px 5px;
541
  margin: 0;
542
  background: #333;
543
  color: #eee;
custom-facebook-feed-admin.php CHANGED
@@ -457,6 +457,7 @@ function cff_settings_page() {
457
  </button>
458
  </div>
459
  <?php endif; ?>
 
460
 
461
  <div id="header">
462
  <h1><?php _e('Custom Facebook Feed', 'custom-facebook-feed'); ?></h1>
@@ -3974,7 +3975,8 @@ function cff_style_page() {
3974
  </td>
3975
  </tr>
3976
  <tr>
3977
- <th class="bump-left"><label for="cff_date_before" class="bump-left"><?php _e('Text Before Date'); ?></label></th>
 
3978
  <td>
3979
  <input name="cff_date_before" type="text" value="<?php esc_attr_e( $cff_date_before ); ?>" size="20" placeholder="Eg. Posted" />
3980
  <a class="cff-tooltip-link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
@@ -3982,7 +3984,8 @@ function cff_style_page() {
3982
  </td>
3983
  </tr>
3984
  <tr>
3985
- <th class="bump-left"><label for="cff_date_after" class="bump-left"><?php _e('Text After Date'); ?></label></th>
 
3986
  <td>
3987
  <input name="cff_date_after" type="text" value="<?php esc_attr_e( $cff_date_after ); ?>" size="20" placeholder="Eg. by ___" />
3988
  <a class="cff-tooltip-link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
@@ -5222,8 +5225,6 @@ function cff_cron_clear_cache() {
5222
  cff_delete_cache();
5223
  }
5224
 
5225
-
5226
-
5227
  //NOTICES
5228
  function cff_get_current_time() {
5229
  $current_time = time();
@@ -5236,247 +5237,24 @@ function cff_get_current_time() {
5236
 
5237
  // generates the html for the admin notices
5238
  function cff_notices_html() {
5239
-
5240
- //Don't show notices if Instagram notices are being shown
5241
- if ( function_exists( 'sbi_notices_html' ) ) {
5242
- return;
5243
- }
5244
-
5245
- //Only show to admins
5246
- if ( ! current_user_can( 'manage_options' ) ) {
5247
- return;
5248
- }
5249
-
5250
- $cff_statuses_option = get_option( 'cff_statuses', array() );
5251
- $current_time = cff_get_current_time();
5252
- $cff_bfcm_discount_code = 'happysmashgiving' . date('Y', $current_time );
5253
-
5254
  // reset everything for testing
5255
- if ( false ) {
5256
- global $current_user;
5257
- $user_id = $current_user->ID;
5258
- // delete_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice' );
5259
- //delete_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
5260
- // $cff_statuses_option = array( 'first_install' => strtotime( 'December 8, 2017' ) );
5261
- //$cff_statuses_option = array( 'first_install' => time() );
5262
-
5263
- //update_option( 'cff_statuses', $cff_statuses_option, false );
5264
- //delete_option( 'cff_rating_notice');
5265
- //delete_transient( 'custom_facebook_rating_notice_waiting' );
5266
-
5267
- // set_transient( 'custom_facebook_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
5268
- delete_transient('custom_facebook_rating_notice_waiting');
5269
- update_option( 'cff_rating_notice', 'pending', false );
5270
- }
5271
-
5272
- //$cff_statuses_option['rating_notice_dismissed'] = time();
5273
- //update_option( 'cff_statuses', $cff_statuses_option, false );
5274
- // rating notice logic
5275
- $cff_rating_notice_option = get_option( 'cff_rating_notice', false );
5276
- $cff_rating_notice_waiting = get_transient( 'custom_facebook_rating_notice_waiting' );
5277
- $should_show_rating_notice = ($cff_rating_notice_waiting !== 'waiting' && $cff_rating_notice_option !== 'dismissed');
5278
-
5279
- // black friday cyber monday logic
5280
- $thanksgiving_this_year = cff_get_future_date( 11, date('Y', $current_time ), 4, 4, 1 );
5281
- $one_week_before_black_friday_this_year = $thanksgiving_this_year - 7*24*60*60;
5282
- $one_day_after_cyber_monday_this_year = $thanksgiving_this_year + 5*24*60*60;
5283
- $has_been_two_days_since_rating_dismissal = isset( $cff_statuses_option['rating_notice_dismissed'] ) ? ((int)$cff_statuses_option['rating_notice_dismissed'] + 2*24*60*60) < $current_time : true;
5284
-
5285
- $could_show_bfcm_discount = ($current_time > $one_week_before_black_friday_this_year && $current_time < $one_day_after_cyber_monday_this_year);
5286
- $should_show_bfcm_discount = false;
5287
- if ( $could_show_bfcm_discount && $has_been_two_days_since_rating_dismissal ) {
5288
- global $current_user;
5289
- $user_id = $current_user->ID;
5290
-
5291
- $ignore_bfcm_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice' );
5292
- $ignore_bfcm_sale_notice_meta = isset( $ignore_bfcm_sale_notice_meta[0] ) ? $ignore_bfcm_sale_notice_meta[0] : '';
5293
-
5294
- /* Check that the user hasn't already clicked to ignore the message */
5295
- $should_show_bfcm_discount = ($ignore_bfcm_sale_notice_meta !== 'always' && $ignore_bfcm_sale_notice_meta !== date( 'Y', $current_time ));
5296
- }
5297
-
5298
- // new user discount logic
5299
- $in_new_user_month_range = true;
5300
- $should_show_new_user_discount = false;
5301
- $has_been_one_month_since_rating_dismissal = isset( $cff_statuses_option['rating_notice_dismissed'] ) ? ((int)$cff_statuses_option['rating_notice_dismissed'] + 30*24*60*60) < $current_time + 1: true;
5302
-
5303
- if ( isset( $cff_statuses_option['first_install'] ) && $cff_statuses_option['first_install'] === 'from_update' ) {
5304
- global $current_user;
5305
- $user_id = $current_user->ID;
5306
- $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
5307
- $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
5308
-
5309
- if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
5310
- $should_show_new_user_discount = true;
5311
- }
5312
- } elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal ) {
5313
- global $current_user;
5314
- $user_id = $current_user->ID;
5315
- $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
5316
- $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
5317
-
5318
- if ( $ignore_new_user_sale_notice_meta !== 'always'
5319
- && isset( $cff_statuses_option['first_install'] )
5320
- && $current_time > (int)$cff_statuses_option['first_install'] + 60*60*24*30 ) {
5321
- $should_show_new_user_discount = true;
5322
- }
5323
- }
5324
-
5325
- // for debugging
5326
- if ( false ) {
5327
- global $current_user;
5328
- $user_id = $current_user->ID;
5329
- $ignore_bfcm_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice' );
5330
- $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
5331
-
5332
- var_dump( 'new user rating option', $cff_rating_notice_option );
5333
- var_dump( 'new user rating transient', $cff_rating_notice_waiting );
5334
-
5335
- var_dump( 'should show new user rating notice?', $should_show_rating_notice );
5336
-
5337
- var_dump( 'new user discount month range?', $in_new_user_month_range );
5338
- var_dump( 'should show new user discount?', $should_show_new_user_discount );
5339
-
5340
- var_dump( 'Thanksgiving this year?', date('m/d/Y', $thanksgiving_this_year ) );
5341
-
5342
- var_dump( 'could show bfcm discount?', $could_show_bfcm_discount );
5343
- var_dump( 'should show bfcm discount?', $should_show_bfcm_discount );
5344
-
5345
- var_dump( 'ignore_bfcm_sale_notice_meta', $ignore_bfcm_sale_notice_meta );
5346
- var_dump( 'ignore_new_user_sale_notice_meta', $ignore_new_user_sale_notice_meta );
5347
-
5348
- var_dump( $cff_statuses_option );
5349
- }
5350
-
5351
-
5352
- if ( $should_show_rating_notice ) {
5353
- $other_notice_html = '';
5354
- $dismiss_url = add_query_arg( 'cff_ignore_rating_notice_nag', '1' );
5355
- $later_url = add_query_arg( 'cff_ignore_rating_notice_nag', 'later' );
5356
- if ( $should_show_bfcm_discount ) {
5357
- $other_notice_html = '<p class="cff_other_notice">' . __( 'PS. We currently have a <a href="https://smashballoon.com/custom-facebook-feed/?utm_campaign=facebook-free&utm_source=notices&utm_medium=rating&discount='.$cff_bfcm_discount_code.'" target="_blank"><b style="font-weight: 700;">Black Friday deal</b></a> for 60% off the Pro version!', 'custom-facebook-feed' ) . '</p>';
5358
-
5359
- $dismiss_url = add_query_arg( array(
5360
- 'cff_ignore_rating_notice_nag' => '1',
5361
- 'cff_ignore_bfcm_sale_notice' => date( 'Y', $current_time )
5362
- )
5363
- );
5364
- $later_url = add_query_arg( array(
5365
- 'cff_ignore_rating_notice_nag' => 'later',
5366
- 'cff_ignore_bfcm_sale_notice' => date( 'Y', $current_time )
5367
- )
5368
- );
5369
- }
5370
-
5371
- echo"
5372
- <div class='cff_notice cff_review_notice'>
5373
- <img src='" . plugins_url( 'img/cff-icon.png?74px' , __FILE__ ) . "' alt='" . __( 'Custom Facebook Feed', 'custom-facebook-feed' ) . "'>
5374
- <div class='cff-notice-text'>
5375
- <p style='padding-top: 4px;'>" . __( "It's great to see that you've been using the <strong style='font-weight: 700;'>Smash Balloon Custom Facebook Feed</strong> plugin for a while now. Hopefully you like it! If so, would you consider leaving a positive review? It really helps support the plugin and helps others to discover it too!", 'custom-facebook-feed' ) . "</p>
5376
- <p class='links'";
5377
- if( $should_show_bfcm_discount ) echo " style='margin-top: 0 !important;'";
5378
- echo ">
5379
- <a class='cff_notice_dismiss' style='margin-left:-8px;' href='https://wordpress.org/support/plugin/custom-facebook-feed/reviews/' target='_blank'>" . __( 'Sure, I\'d love to!', 'custom-facebook-feed' ) . "</a>
5380
- &middot;
5381
- <a class='cff_notice_dismiss' href='" .esc_url( $dismiss_url ). "'>" . __( 'No thanks', 'custom-facebook-feed' ) . "</a>
5382
- &middot;
5383
- <a class='cff_notice_dismiss' href='" .esc_url( $dismiss_url ). "'>" . __( 'I\'ve already given a review', 'custom-facebook-feed' ) . "</a>
5384
- &middot;
5385
- <a class='cff_notice_dismiss' href='" .esc_url( $later_url ). "'>" . __( 'Ask Me Later', 'custom-facebook-feed' ) . "</a>
5386
- </p>"
5387
- . $other_notice_html .
5388
- "</div>
5389
- <a class='cff_notice_close' href='" .esc_url( $dismiss_url ). "'><i class='fa fa-close'></i></a>
5390
- </div>";
5391
-
5392
- } elseif ( $should_show_new_user_discount ) {
5393
- global $current_user;
5394
- $user_id = $current_user->ID;
5395
- $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
5396
- if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
5397
-
5398
- echo "
5399
- <div class='cff_notice cff_review_notice cff_new_user_sale_notice'>
5400
- <img src='" . plugins_url( 'img/cff-icon-offer.png?74px' , __FILE__ ) . "' alt='Facebook Feed'>
5401
- <div class='cff-notice-text'>
5402
- <p>" . __( '<b style="font-weight: 700;">Exclusive offer!</b> We don\'t run promotions very often, but for a limited time we\'re offering <b style="font-weight: 700;">60% off</b> our Pro version to all users of our free Smash Balloon Custom Facebook Feed plugin.', 'custom-facebook-feed' ) . "</p>
5403
- <p class='cff-links'>
5404
- <a class='cff_notice_dismiss cff_offer_btn' href='https://smashballoon.com/custom-facebook-feed/?utm_campaign=facebook-free&utm_source=notices&utm_medium=newuser&discount=facebookthankyou' target='_blank'><b>" . __( 'Get this offer', 'custom-facebook-feed' ) . "</b></a>
5405
- <a class='cff_notice_dismiss' style='margin-left: 5px;' href='" . esc_url( add_query_arg( 'cff_ignore_new_user_sale_notice', 'always' ) ) . "'>" . __( 'I\'m not interested', 'custom-facebook-feed' ) . "</a>
5406
-
5407
- </p>
5408
- </div>
5409
- <a class='cff_new_user_sale_notice_close' href='" . esc_url( add_query_arg( 'cff_ignore_new_user_sale_notice', 'always' ) ) . "'><i class='fa fa-close'></i></a>
5410
- </div>
5411
- ";
5412
- }
5413
-
5414
- } elseif ( $should_show_bfcm_discount ) {
5415
-
5416
- echo "
5417
- <div class='cff_notice cff_review_notice cff_bfcm_sale_notice'>
5418
- <img src='". plugins_url( 'img/cff-icon-offer.png?74px' , __FILE__ ) ."' alt='Facebook Feed'>
5419
- <div class='cff-notice-text'>
5420
- <p>" . __( '<b style="font-weight: 700;">Black Friday/Cyber Monday Deal!</b> Thank you for using the free Smash Balloon Custom Facebook Feed plugin. For a limited time, we\'re offering <b style="font-weight: 700;">60% off</b> the Pro version for all of our users.', 'custom-facebook-feed' ) . "</p>
5421
- <p class='cff-links'>
5422
- <a class='cff_notice_dismiss cff_offer_btn' href='https://smashballoon.com/custom-facebook-feed/?utm_campaign=facebook-free&utm_source=notices&utm_medium=bfcm&discount=".$cff_bfcm_discount_code."' target='_blank'><b>" . __( 'Get this offer', 'custom-facebook-feed' ) . "</b></a>
5423
- <a class='cff_notice_dismiss' style='margin-left: 5px;' href='" .esc_url( add_query_arg( 'cff_ignore_bfcm_sale_notice', date( 'Y', $current_time ) ) ). "'>" . __( 'I\'m not interested', 'custom-facebook-feed' ) . "</a>
5424
- </p>
5425
- </div>
5426
- <a class='cff_bfcm_sale_notice_close' href='" .esc_url( add_query_arg( 'cff_ignore_bfcm_sale_notice', date( 'Y', $current_time ) ) ). "'><i class='fa fa-close'></i></a>
5427
- </div>
5428
- ";
5429
-
5430
- }
5431
-
5432
- }
5433
- add_action( 'admin_notices', 'cff_notices_html', 10 );
5434
-
5435
- function cff_process_nags() {
5436
-
5437
  global $current_user;
5438
  $user_id = $current_user->ID;
5439
- $cff_statuses_option = get_option( 'cff_statuses', array() );
5440
-
5441
- if ( isset( $_GET['cff_ignore_rating_notice_nag'] ) ) {
5442
- if ( (int)$_GET['cff_ignore_rating_notice_nag'] === 1 ) {
5443
- update_option( 'cff_rating_notice', 'dismissed', false );
5444
- $cff_statuses_option['rating_notice_dismissed'] = cff_get_current_time();
5445
- update_option( 'cff_statuses', $cff_statuses_option, false );
5446
-
5447
- } elseif ( $_GET['cff_ignore_rating_notice_nag'] === 'later' ) {
5448
- set_transient( 'custom_facebook_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
5449
- update_option( 'cff_rating_notice', 'pending', false );
5450
- }
5451
- }
5452
-
5453
- if ( isset( $_GET['cff_ignore_new_user_sale_notice'] ) ) {
5454
- $response = sanitize_text_field( $_GET['cff_ignore_new_user_sale_notice'] );
5455
- if ( $response === 'always' ) {
5456
- update_user_meta( $user_id, 'cff_ignore_new_user_sale_notice', 'always' );
5457
-
5458
- $current_month_number = (int)date('n', cff_get_current_time() );
5459
- $not_early_in_the_year = ($current_month_number > 5);
5460
-
5461
- if ( $not_early_in_the_year ) {
5462
- update_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice', date( 'Y', cff_get_current_time() ) );
5463
- }
5464
-
5465
- }
5466
- }
5467
-
5468
- if ( isset( $_GET['cff_ignore_bfcm_sale_notice'] ) ) {
5469
- $response = sanitize_text_field( $_GET['cff_ignore_bfcm_sale_notice'] );
5470
- if ( $response === 'always' ) {
5471
- update_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice', 'always' );
5472
- } elseif ( $response === date( 'Y', cff_get_current_time() ) ) {
5473
- update_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice', date( 'Y', cff_get_current_time() ) );
5474
- }
5475
- update_user_meta( $user_id, 'cff_ignore_new_user_sale_notice', 'always' );
5476
- }
5477
-
5478
  }
5479
- add_action( 'admin_init', 'cff_process_nags' );
5480
 
5481
  function cff_get_future_date( $month, $year, $week, $day, $direction ) {
5482
  if ( $direction > 0 ) {
457
  </button>
458
  </div>
459
  <?php endif; ?>
460
+ <?php do_action( 'cff_admin_overview_before_table' ); ?>
461
 
462
  <div id="header">
463
  <h1><?php _e('Custom Facebook Feed', 'custom-facebook-feed'); ?></h1>
3975
  </td>
3976
  </tr>
3977
  <tr>
3978
+ <th class="bump-left"><label for="cff_date_before" class="bump-left"><?php _e('Text Before Date'); ?></label><code class="cff_shortcode"> beforedate
3979
+ Eg: beforedate='Posted'</code></th>
3980
  <td>
3981
  <input name="cff_date_before" type="text" value="<?php esc_attr_e( $cff_date_before ); ?>" size="20" placeholder="Eg. Posted" />
3982
  <a class="cff-tooltip-link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
3984
  </td>
3985
  </tr>
3986
  <tr>
3987
+ <th class="bump-left"><label for="cff_date_after" class="bump-left"><?php _e('Text After Date'); ?></label><code class="cff_shortcode"> afterdate
3988
+ Eg: afterdate='Ago'</code></th>
3989
  <td>
3990
  <input name="cff_date_after" type="text" value="<?php esc_attr_e( $cff_date_after ); ?>" size="20" placeholder="Eg. by ___" />
3991
  <a class="cff-tooltip-link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
5225
  cff_delete_cache();
5226
  }
5227
 
 
 
5228
  //NOTICES
5229
  function cff_get_current_time() {
5230
  $current_time = time();
5237
 
5238
  // generates the html for the admin notices
5239
  function cff_notices_html() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5240
  // reset everything for testing
5241
+ /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5242
  global $current_user;
5243
  $user_id = $current_user->ID;
5244
+ // delete_user_meta( $user_id, 'cff_ignore_bfcm_sale_notice' );
5245
+ // delete_user_meta( $user_id, 'cff_ignore_new_user_sale_notice' );
5246
+ // $cff_statuses_option = array( 'first_install' => strtotime( 'December 8, 2017' ) );
5247
+ // $cff_statuses_option = array( 'first_install' => time() );
5248
+
5249
+ // update_option( 'cff_statuses', $cff_statuses_option, false );
5250
+ // delete_option( 'cff_rating_notice');
5251
+ // delete_transient( 'custom_facebook_rating_notice_waiting' );
5252
+
5253
+ // set_transient( 'custom_facebook_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
5254
+ delete_transient('custom_facebook_rating_notice_waiting');
5255
+ update_option( 'cff_rating_notice', 'pending', false );
5256
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5257
  }
 
5258
 
5259
  function cff_get_future_date( $month, $year, $week, $day, $direction ) {
5260
  if ( $direction > 0 ) {
custom-facebook-feed.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Smash Balloon Custom Facebook Feed
4
  Plugin URI: https://smashballoon.com/custom-facebook-feed
5
  Description: Add completely customizable Facebook feeds to your WordPress site
6
- Version: 2.17
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  License: GPLv2 or later
@@ -24,11 +24,11 @@ along with this program; if not, write to the Free Software
24
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
  */
26
 
27
- define('CFFVER', '2.17');
28
 
29
  // Db version.
30
  if ( ! defined( 'CFF_DBVERSION' ) ) {
31
- define( 'CFF_DBVERSION', '1.1' );
32
  }
33
 
34
  // Plugin Folder Path.
@@ -83,6 +83,19 @@ function cff_check_for_db_updates() {
83
  }
84
 
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  update_option( 'cff_db_version', CFF_DBVERSION );
87
  }
88
  }
@@ -108,6 +121,14 @@ function cff_plugin_init() {
108
 
109
  if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0
110
  && version_compare( get_bloginfo('version'), '4.6' , '>' ) ) {
 
 
 
 
 
 
 
 
111
  require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/addon-functions.php';
112
  require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/PluginSilentUpgrader.php';
113
  require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/PluginSilentUpgraderSkin.php';
@@ -267,6 +288,8 @@ function display_cff($atts) {
267
  'datecolor' => isset($options[ 'cff_date_color' ]) ? $options[ 'cff_date_color' ] : '',
268
  'dateformat' => isset($options[ 'cff_date_formatting' ]) ? $options[ 'cff_date_formatting' ] : '',
269
  'datecustom' => isset($options[ 'cff_date_custom' ]) ? $options[ 'cff_date_custom' ] : '',
 
 
270
  'timezone' => isset($options[ 'cff_timezone' ]) ? $options[ 'cff_timezone' ] : 'America/Chicago',
271
 
272
  //Link to Facebook
@@ -2855,6 +2878,15 @@ function cff_activate() {
2855
 
2856
  update_option( 'cff_usage_tracking', $usage_tracking, false );
2857
  }
 
 
 
 
 
 
 
 
 
2858
  }
2859
  register_activation_hook( __FILE__, 'cff_activate' );
2860
 
@@ -2870,6 +2902,7 @@ add_filter( 'cron_schedules', 'cff_cron_custom_interval' );
2870
 
2871
  function cff_deactivate() {
2872
  wp_clear_scheduled_hook('cff_cron_job');
 
2873
  }
2874
  register_deactivation_hook(__FILE__, 'cff_deactivate');
2875
 
@@ -2908,6 +2941,8 @@ function cff_uninstall()
2908
  delete_option( 'cff_statuses' );
2909
  delete_option( 'cff_rating_notice' );
2910
  delete_option( 'cff_db_version' );
 
 
2911
 
2912
  global $wp_roles;
2913
  $wp_roles->remove_cap( 'administrator', 'manage_custom_facebook_feed_options' );
3
  Plugin Name: Smash Balloon Custom Facebook Feed
4
  Plugin URI: https://smashballoon.com/custom-facebook-feed
5
  Description: Add completely customizable Facebook feeds to your WordPress site
6
+ Version: 2.17.1
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  License: GPLv2 or later
24
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
  */
26
 
27
+ define('CFFVER', '2.17.1');
28
 
29
  // Db version.
30
  if ( ! defined( 'CFF_DBVERSION' ) ) {
31
+ define( 'CFF_DBVERSION', '1.2' );
32
  }
33
 
34
  // Plugin Folder Path.
83
  }
84
 
85
 
86
+ update_option( 'cff_db_version', CFF_DBVERSION );
87
+ }
88
+
89
+ if ( (float) $db_ver < 1.2 ) {
90
+ if ( ! wp_next_scheduled( 'cff_notification_update' ) ) {
91
+ $timestamp = strtotime( 'next monday' );
92
+ $timestamp = $timestamp + (3600 * 24 * 7);
93
+ $six_am_local = $timestamp + cff_get_utc_offset() + (6*60*60);
94
+
95
+ wp_schedule_event( $six_am_local, 'cffweekly', 'cff_notification_update' );
96
+ }
97
+
98
+
99
  update_option( 'cff_db_version', CFF_DBVERSION );
100
  }
101
  }
121
 
122
  if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0
123
  && version_compare( get_bloginfo('version'), '4.6' , '>' ) ) {
124
+ require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/class-cff-notifications.php';
125
+ $cff_notifications = new CFF_Notifications();
126
+ $cff_notifications->init();
127
+
128
+ require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/class-cff-new-user.php';
129
+ $cff_newuser = new CFF_New_User();
130
+ $cff_newuser->init();
131
+
132
  require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/addon-functions.php';
133
  require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/PluginSilentUpgrader.php';
134
  require_once trailingslashit( CFF_PLUGIN_DIR ) . 'admin/PluginSilentUpgraderSkin.php';
288
  'datecolor' => isset($options[ 'cff_date_color' ]) ? $options[ 'cff_date_color' ] : '',
289
  'dateformat' => isset($options[ 'cff_date_formatting' ]) ? $options[ 'cff_date_formatting' ] : '',
290
  'datecustom' => isset($options[ 'cff_date_custom' ]) ? $options[ 'cff_date_custom' ] : '',
291
+ 'beforedate' => isset($options[ 'cff_date_before' ]) ? $options[ 'cff_date_before' ] : '',
292
+ 'afterdate' => isset($options[ 'cff_date_after' ]) ? $options[ 'cff_date_after' ] : '',
293
  'timezone' => isset($options[ 'cff_timezone' ]) ? $options[ 'cff_timezone' ] : 'America/Chicago',
294
 
295
  //Link to Facebook
2878
 
2879
  update_option( 'cff_usage_tracking', $usage_tracking, false );
2880
  }
2881
+
2882
+ if ( ! wp_next_scheduled( 'cff_notification_update' ) ) {
2883
+ $timestamp = strtotime( 'next monday' );
2884
+ $timestamp = $timestamp + (3600 * 24 * 7);
2885
+ $six_am_local = $timestamp + cff_get_utc_offset() + (6*60*60);
2886
+
2887
+ wp_schedule_event( $six_am_local, 'cffweekly', 'cff_notification_update' );
2888
+ }
2889
+
2890
  }
2891
  register_activation_hook( __FILE__, 'cff_activate' );
2892
 
2902
 
2903
  function cff_deactivate() {
2904
  wp_clear_scheduled_hook('cff_cron_job');
2905
+ wp_clear_scheduled_hook('cff_notification_update');
2906
  }
2907
  register_deactivation_hook(__FILE__, 'cff_deactivate');
2908
 
2941
  delete_option( 'cff_statuses' );
2942
  delete_option( 'cff_rating_notice' );
2943
  delete_option( 'cff_db_version' );
2944
+ delete_option( 'cff_newuser_notifications' );
2945
+ delete_option( 'cff_notifications' );
2946
 
2947
  global $wp_roles;
2948
  $wp_roles->remove_cap( 'administrator', 'manage_custom_facebook_feed_options' );
img/cff-icon-offer.png DELETED
Binary file
js/admin-notifications.js ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * CFF Admin Notifications.
3
+ *
4
+ * @since 2.18
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ var CFFAdminNotifications = window.CFFAdminNotifications || ( function( document, window, $ ) {
10
+
11
+ /**
12
+ * Elements holder.
13
+ *
14
+ * @since 2.18
15
+ *
16
+ * @type {object}
17
+ */
18
+ var el = {
19
+
20
+ $notifications: $( '#cff-notifications' ),
21
+ $nextButton: $( '#cff-notifications .navigation .next' ),
22
+ $prevButton: $( '#cff-notifications .navigation .prev' ),
23
+ $adminBarCounter: $( '#wp-admin-bar-wpforms-menu .cff-menu-notification-counter' ),
24
+ $adminBarMenuItem: $( '#wp-admin-bar-cff-notifications' ),
25
+
26
+ };
27
+
28
+ /**
29
+ * Public functions and properties.
30
+ *
31
+ * @since 2.18
32
+ *
33
+ * @type {object}
34
+ */
35
+ var app = {
36
+
37
+ /**
38
+ * Start the engine.
39
+ *
40
+ * @since 2.18
41
+ */
42
+ init: function() {
43
+ el.$notifications.find( '.messages a').each(function() {
44
+ if ($(this).attr('href').indexOf('dismiss=') > -1 ) {
45
+ $(this).addClass('button-dismiss');
46
+ }
47
+ })
48
+
49
+ $( app.ready );
50
+ },
51
+
52
+ /**
53
+ * Document ready.
54
+ *
55
+ * @since 2.18
56
+ */
57
+ ready: function() {
58
+
59
+ app.updateNavigation();
60
+ app.events();
61
+ },
62
+
63
+ /**
64
+ * Register JS events.
65
+ *
66
+ * @since 2.18
67
+ */
68
+ events: function() {
69
+
70
+ el.$notifications
71
+ .on( 'click', '.dismiss', app.dismiss )
72
+ .on( 'click', '.button-dismiss', app.buttonDismiss )
73
+ .on( 'click', '.next', app.navNext )
74
+ .on( 'click', '.prev', app.navPrev );
75
+ },
76
+
77
+ /**
78
+ * Click on a dismiss button.
79
+ *
80
+ * @since 2.18
81
+ */
82
+ buttonDismiss: function( event ) {
83
+ event.preventDefault();
84
+ app.dismiss();
85
+ },
86
+
87
+ /**
88
+ * Click on the Dismiss notification button.
89
+ *
90
+ * @since 2.18
91
+ *
92
+ * @param {object} event Event object.
93
+ */
94
+ dismiss: function( event ) {
95
+
96
+ if ( el.$currentMessage.length === 0 ) {
97
+ return;
98
+ }
99
+
100
+ // Update counter.
101
+ var count = parseInt( el.$adminBarCounter.text(), 10 );
102
+ if ( count > 1 ) {
103
+ --count;
104
+ el.$adminBarCounter.html( '<span>' + count + '</span>' );
105
+ } else {
106
+ el.$adminBarCounter.remove();
107
+ el.$adminBarMenuItem.remove();
108
+ }
109
+
110
+ // Remove notification.
111
+ var $nextMessage = el.$nextMessage.length < 1 ? el.$prevMessage : el.$nextMessage,
112
+ messageId = el.$currentMessage.data( 'message-id' );
113
+
114
+ if ( $nextMessage.length === 0 ) {
115
+ el.$notifications.remove();
116
+ } else {
117
+ el.$currentMessage.remove();
118
+ $nextMessage.addClass( 'current' );
119
+ app.updateNavigation();
120
+ }
121
+
122
+ // AJAX call - update option.
123
+ var data = {
124
+ action: 'cff_dashboard_notification_dismiss',
125
+ nonce: cff_admin.nonce,
126
+ id: messageId,
127
+ };
128
+
129
+ $.post( cff_admin.ajax_url, data, function( res ) {
130
+
131
+ if ( ! res.success ) {
132
+ //CFFAdmin.debug( res );
133
+ }
134
+ } ).fail( function( xhr, textStatus, e ) {
135
+
136
+ //CFFAdmin.debug( xhr.responseText );
137
+ } );
138
+ },
139
+
140
+ /**
141
+ * Click on the Next notification button.
142
+ *
143
+ * @since 2.18
144
+ *
145
+ * @param {object} event Event object.
146
+ */
147
+ navNext: function( event ) {
148
+
149
+ if ( el.$nextButton.hasClass( 'disabled' ) ) {
150
+ return;
151
+ }
152
+
153
+ el.$currentMessage.removeClass( 'current' );
154
+ el.$nextMessage.addClass( 'current' );
155
+
156
+ app.updateNavigation();
157
+ },
158
+
159
+ /**
160
+ * Click on the Previous notification button.
161
+ *
162
+ * @since 2.18
163
+ *
164
+ * @param {object} event Event object.
165
+ */
166
+ navPrev: function( event ) {
167
+
168
+ if ( el.$prevButton.hasClass( 'disabled' ) ) {
169
+ return;
170
+ }
171
+
172
+ el.$currentMessage.removeClass( 'current' );
173
+ el.$prevMessage.addClass( 'current' );
174
+
175
+ app.updateNavigation();
176
+ },
177
+
178
+ /**
179
+ * Update navigation buttons.
180
+ *
181
+ * @since 2.18
182
+ */
183
+ updateNavigation: function() {
184
+
185
+ el.$currentMessage = el.$notifications.find( '.message.current' );
186
+ el.$nextMessage = el.$currentMessage.next( '.message' );
187
+ el.$prevMessage = el.$currentMessage.prev( '.message' );
188
+
189
+ if ( el.$nextMessage.length === 0 ) {
190
+ el.$nextButton.addClass( 'disabled' );
191
+ } else {
192
+ el.$nextButton.removeClass( 'disabled' );
193
+ }
194
+
195
+ if ( el.$prevMessage.length === 0 ) {
196
+ el.$prevButton.addClass( 'disabled' );
197
+ } else {
198
+ el.$prevButton.removeClass( 'disabled' );
199
+ }
200
+ },
201
+ };
202
+
203
+ return app;
204
+
205
+ }( document, window, jQuery ) );
206
+
207
+ // Initialize.
208
+ CFFAdminNotifications.init();
js/cff-scripts.js CHANGED
@@ -90,7 +90,7 @@ if(!cff_js_exists){
90
  //Change the width dynamically so it's responsive
91
  if( cffFeedWidth < likeboxWidth ) likeboxWidth = cffFeedWidth;
92
 
93
- $likebox.attr('src', 'https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2F'+$likebox.attr('data-likebox-id')+'%2F&tabs&width='+likeboxWidth+'&small_header='+$likebox.attr('data-likebox-header')+'&adapt_container_width=true&hide_cover='+$likebox.attr('data-hide-cover')+'&hide_cta='+$likebox.attr('data-hide-cta')+'&show_facepile='+$likebox.attr('data-likebox-faces')+'&locale='+$likebox.attr('data-locale'));
94
  });
95
 
96
  jQuery('#cff .cff-item').each(function(){
90
  //Change the width dynamically so it's responsive
91
  if( cffFeedWidth < likeboxWidth ) likeboxWidth = cffFeedWidth;
92
 
93
+ $likebox.attr('src', 'https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2F'+$likebox.attr('data-likebox-id')+'%2F&tabs&width='+Math.floor(likeboxWidth)+'&small_header='+$likebox.attr('data-likebox-header')+'&adapt_container_width=true&hide_cover='+$likebox.attr('data-hide-cover')+'&hide_cta='+$likebox.attr('data-hide-cta')+'&show_facepile='+$likebox.attr('data-likebox-faces')+'&locale='+$likebox.attr('data-locale'));
94
  });
95
 
96
  jQuery('#cff .cff-item').each(function(){