PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.0.10
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.0.10
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/models/FrmInbox.php +75 -357 6.29 → 5.0.10 View file →
@@ -9,35 +9,24 @@
9 9 class FrmInbox extends FrmFormApi {
10 10
11 11 protected $cache_key;
12 12
13 - /**
14 - * @var string
15 - */
16 13 private $option = 'frm_inbox';
17 14
18 - /**
19 - * @var array|false
20 - */
21 - private static $messages = false;
15 + private $messages = false;
22 16
23 17 /**
24 - * @var array
18 + * @param array
25 19 */
26 20 private static $banner_messages;
27 21
28 - public function __construct() {
22 + public function __construct( $for_parent = null ) {
29 23 $this->set_cache_key();
30 -
31 - if ( false === self::$messages ) {
32 - $this->set_messages();
33 - }
24 + $this->set_messages();
34 25 }
35 26
36 27 /**
37 28 * @since 4.05
38 - *
39 - * @return void
40 29 */
41 30 protected function set_cache_key() {
42 31 $this->cache_key = 'frm_inbox_cache';
43 32 }
@@ -43,10 +32,8 @@
43 32 }
44 33
45 34 /**
46 35 * @since 4.05
47 - *
48 - * @return string
49 36 */
50 37 protected function api_url() {
51 38 return 'https://formidableforms.com/wp-json/inbox/v1/message/';
52 39 }
@@ -52,33 +39,24 @@
52 39 }
53 40
54 41 /**
55 42 * @since 4.05
56 - *
57 - * @param false|string $filter
58 - *
59 - * @return array
60 43 */
61 44 public function get_messages( $filter = false ) {
62 - $messages = self::$messages;
63 -
45 + $messages = $this->messages;
64 46 if ( $filter === 'filter' ) {
65 47 $this->filter_messages( $messages );
66 48 }
67 -
68 49 return $messages;
69 50 }
70 51
71 52 /**
72 53 * @since 4.05
73 - *
74 - * @return void
75 54 */
76 55 public function set_messages() {
77 - self::$messages = get_option( $this->option );
78 -
79 - if ( ! is_array( self::$messages ) ) {
80 - self::$messages = array();
56 + $this->messages = get_option( $this->option );
57 + if ( empty( $this->messages ) ) {
58 + $this->messages = array();
81 59 }
82 60
83 61 $this->add_api_messages();
84 62
@@ -84,20 +62,17 @@
84 62
85 63 /**
86 64 * Messages are in an array.
87 65 */
88 - self::$messages = apply_filters( 'frm_inbox', self::$messages );
66 + $this->messages = apply_filters( 'frm_inbox', $this->messages );
89 67 }
90 68
91 69 /**
92 70 * @since 4.05
93 - *
94 - * @return void
95 71 */
96 72 private function add_api_messages() {
97 73 $api = $this->get_api_info();
98 -
99 - if ( ! $api ) {
74 + if ( empty( $api ) ) {
100 75 return;
101 76 }
102 77
103 78 foreach ( $api as $message ) {
@@ -106,34 +81,32 @@
106 81 }
107 82
108 83 /**
109 84 * @param array|string $message
110 - *
111 - * @return void
112 85 */
113 86 public function add_message( $message ) {
114 87 if ( ! is_array( $message ) || ! isset( $message['key'] ) ) {
115 - // If the API response is invalid, $message may not be an array.
116 - // If there are no messages from the API, it is returning a "No Entries Found" item with no key, so check for a key as well.
88 + // if the API response is invalid, $message may not be an array.
89 + // if there are no messages from the API, it is returning a "No Entries Found" item with no key, so check for a key as well.
117 90 return;
118 91 }
119 92
120 - if ( isset( self::$messages[ $message['key'] ] ) && ! isset( $message['force'] ) ) {
93 + if ( isset( $this->messages[ $message['key'] ] ) && ! isset( $message['force'] ) ) {
121 94 // Don't replace messages unless required.
122 95 return;
123 96 }
124 97
125 - if ( ! $this->within_valid_timeframe( $message ) ) {
98 + if ( $this->is_expired( $message ) ) {
126 99 return;
127 100 }
128 101
129 - if ( isset( self::$messages[ $message['key'] ] ) ) {
102 + if ( isset( $this->messages[ $message['key'] ] ) ) {
130 103 // Move up and mark as new.
131 - unset( self::$messages[ $message['key'] ] );
104 + unset( $this->messages[ $message['key'] ] );
132 105 }
133 106
134 107 $this->fill_message( $message );
135 - self::$messages[ $message['key'] ] = $message;
108 + $this->messages[ $message['key'] ] = $message;
136 109
137 110 $this->update_list();
138 111
139 112 $this->clean_messages();
@@ -138,13 +111,8 @@
138 111
139 112 $this->clean_messages();
140 113 }
141 114
142 - /**
143 - * @param array $message
144 - *
145 - * @return void
146 - */
147 115 private function fill_message( &$message ) {
148 116 $defaults = array(
149 117 'time' => time(),
150 118 'message' => '',
@@ -151,10 +119,9 @@
151 119 'subject' => '',
152 120 'icon' => 'frm_tooltip_icon',
153 121 'cta' => '',
154 122 'expires' => false,
155 - // Use 'free', 'personal', 'business', 'elite', 'grandfathered'.
156 - 'who' => 'all',
123 + 'who' => 'all', // use 'free', 'personal', 'business', 'elite', 'grandfathered'
157 124 'type' => '',
158 125 );
159 126
160 127 $message = array_merge( $defaults, $message );
@@ -162,24 +129,18 @@
162 129 $message['created'] = $message['time'];
163 130 unset( $message['time'] );
164 131 }
165 132
166 - /**
167 - * @return void
168 - */
169 133 private function clean_messages() {
170 - $removed = false;
171 -
172 - foreach ( self::$messages as $t => $message ) {
173 - $read = ! empty( $message['read'] ) && isset( $message['read'][ get_current_user_id() ] ) && $message['read'][ get_current_user_id() ] < strtotime( '-1 month' );
174 - $dismissed = ! empty( $message['dismissed'] ) && isset( $message['dismissed'][ get_current_user_id() ] ) && $message['dismissed'][ get_current_user_id() ] < strtotime( '-1 week' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
175 -
176 - if ( ! $read && ! $dismissed && $this->within_valid_timeframe( $message ) ) {
177 - continue;
134 + $removed = false;
135 + foreach ( $this->messages as $t => $message ) {
136 + $read = isset( $message['read'] ) && ! empty( $message['read'] ) && isset( $message['read'][ get_current_user_id() ] ) && $message['read'][ get_current_user_id() ] < strtotime( '-1 month' );
137 + $dismissed = isset( $message['dismissed'] ) && ! empty( $message['dismissed'] ) && isset( $message['dismissed'][ get_current_user_id() ] ) && $message['dismissed'][ get_current_user_id() ] < strtotime( '-1 week' );
138 + $expired = $this->is_expired( $message );
139 + if ( $read || $expired || $dismissed ) {
140 + unset( $this->messages[ $t ] );
141 + $removed = true;
178 142 }
179 -
180 - unset( self::$messages[ $t ] );
181 - $removed = true;
182 143 }
183 144
184 145 if ( $removed ) {
185 146 $this->update_list();
@@ -185,63 +146,23 @@
185 146 $this->update_list();
186 147 }
187 148 }
188 149
189 - /**
190 - * @param array $messages
191 - * @param string $type
192 - *
193 - * @return void
194 - */
195 - public function filter_messages( &$messages, $type = 'unread' ) {
150 + private function filter_messages( &$messages ) {
196 151 $user_id = get_current_user_id();
197 -
198 152 foreach ( $messages as $k => $message ) {
199 153 $dismissed = isset( $message['dismissed'] ) && isset( $message['dismissed'][ $user_id ] );
200 -
201 - if ( ! $k || ! $this->within_valid_timeframe( $message ) || ( $type === 'dismissed' ) !== $dismissed ) {
154 + if ( empty( $k ) || $this->is_expired( $message ) || $dismissed ) {
202 155 unset( $messages[ $k ] );
203 156 } elseif ( ! $this->is_for_user( $message ) ) {
204 157 unset( $messages[ $k ] );
205 158 }
206 159 }
207 -
208 160 $messages = apply_filters( 'frm_filter_inbox', $messages );
209 161 }
210 162
211 - /**
212 - * Check if a message has started and is not expired.
213 - *
214 - * @since 6.25
215 - *
216 - * @param array $message
217 - *
218 - * @return bool
219 - */
220 - private function within_valid_timeframe( $message ) {
221 - return $this->has_started( $message ) && ! $this->is_expired( $message );
222 - }
223 -
224 - /**
225 - * Check if a message has actually started, so we can prevent showing something that is queued up early.
226 - *
227 - * @since 6.25
228 - *
229 - * @param array $message
230 - *
231 - * @return bool
232 - */
233 - private function has_started( $message ) {
234 - return ! empty( $message['starts'] ) ? $message['starts'] <= time() : true;
235 - }
236 -
237 - /**
238 - * @param array $message
239 - *
240 - * @return bool
241 - */
242 163 private function is_expired( $message ) {
243 - return ! empty( $message['expires'] ) && $message['expires'] < time();
164 + return isset( $message['expires'] ) && ! empty( $message['expires'] ) && $message['expires'] < time();
244 165 }
245 166
246 167 /**
247 168 * Show different messages for different accounts.
@@ -246,70 +167,60 @@
246 167 /**
247 168 * Show different messages for different accounts.
248 169 *
249 170 * @param array $message
250 - *
251 171 * @return bool
252 172 */
253 173 private function is_for_user( $message ) {
254 - if ( FrmApiHelper::is_for_user( $message ) ) {
174 + if ( ! isset( $message['who'] ) || $message['who'] === 'all' ) {
255 175 return true;
256 176 }
177 + $who = (array) $message['who'];
178 + if ( in_array( 'all', $who, true ) || in_array( 'everyone', $who, true ) ) {
179 + return true;
180 + }
181 + return in_array( $this->get_user_type(), $who, true );
182 + }
257 183
258 - $who = (array) $message['who'];
184 + private function get_user_type() {
185 + if ( ! FrmAppHelper::pro_is_installed() ) {
186 + return 'free';
187 + }
259 188
260 - /**
261 - * Allow for other special inbox cases in other add-ons.
262 - *
263 - * @since 6.8.1
264 - *
265 - * @param bool $is_for_user
266 - * @param array $who
267 - * @param array $message
268 - */
269 - return (bool) apply_filters( 'frm_inbox_message_is_for_user', false, $who, $message );
189 + return FrmAddonsController::license_type();
270 190 }
271 191
272 192 /**
273 193 * @param string $key
274 - *
275 - * @return void
276 194 */
277 195 public function mark_read( $key ) {
278 - if ( ! $key || ! isset( self::$messages[ $key ] ) ) {
196 + if ( ! $key || ! isset( $this->messages[ $key ] ) ) {
279 197 return;
280 198 }
281 199
282 - if ( ! isset( self::$messages[ $key ]['read'] ) ) {
283 - self::$messages[ $key ]['read'] = array();
200 + if ( ! isset( $this->messages[ $key ]['read'] ) ) {
201 + $this->messages[ $key ]['read'] = array();
284 202 }
285 - self::$messages[ $key ]['read'][ get_current_user_id() ] = time();
203 + $this->messages[ $key ]['read'][ get_current_user_id() ] = time();
286 204
287 205 $this->update_list();
288 206 }
289 207
290 208 /**
291 - * @since 4.05.02
292 - *
293 209 * @param string $key
294 210 *
295 - * @return void
211 + * @since 4.05.02
296 212 */
297 213 public function mark_unread( $key ) {
298 - $is_read = isset( self::$messages[ $key ] ) && isset( self::$messages[ $key ]['read'] ) && isset( self::$messages[ $key ]['read'][ get_current_user_id() ] );
299 -
300 - if ( ! $is_read ) {
301 - return;
214 + $is_read = isset( $this->messages[ $key ] ) && isset( $this->messages[ $key ]['read'] ) && isset( $this->messages[ $key ]['read'][ get_current_user_id() ] );
215 + if ( $is_read ) {
216 + unset( $this->messages[ $key ]['read'][ get_current_user_id() ] );
217 + $this->update_list();
302 218 }
303 -
304 - unset( self::$messages[ $key ]['read'][ get_current_user_id() ] );
305 - $this->update_list();
306 219 }
307 220
308 221 /**
309 222 * @param string $key
310 - *
311 - * @return void
312 223 */
313 224 public function dismiss( $key ) {
314 225 if ( $key === 'all' ) {
315 226 $this->dismiss_all();
@@ -315,16 +226,16 @@
315 226 $this->dismiss_all();
316 227 return;
317 228 }
318 229
319 - if ( ! isset( self::$messages[ $key ] ) ) {
230 + if ( ! isset( $this->messages[ $key ] ) ) {
320 231 return;
321 232 }
322 233
323 - if ( ! isset( self::$messages[ $key ]['dismissed'] ) ) {
324 - self::$messages[ $key ]['dismissed'] = array();
234 + if ( ! isset( $this->messages[ $key ]['dismissed'] ) ) {
235 + $this->messages[ $key ]['dismissed'] = array();
325 236 }
326 - self::$messages[ $key ]['dismissed'][ get_current_user_id() ] = time();
237 + $this->messages[ $key ]['dismissed'][ get_current_user_id() ] = time();
327 238
328 239 $this->update_list();
329 240 }
330 241
@@ -329,280 +240,87 @@
329 240 }
330 241
331 242 /**
332 243 * @since 4.06
333 - *
334 - * @return void
335 244 */
336 245 private function dismiss_all() {
337 246 $user_id = get_current_user_id();
338 -
339 - foreach ( self::$messages as $key => $message ) {
247 + foreach ( $this->messages as $key => $message ) {
340 248 if ( ! isset( $message['dismissed'] ) ) {
341 - self::$messages[ $key ]['dismissed'] = array();
249 + $this->messages[ $key ]['dismissed'] = array();
342 250 }
343 251
344 252 if ( ! isset( $message['dismissed'][ $user_id ] ) ) {
345 - self::$messages[ $key ]['dismissed'][ $user_id ] = time();
253 + $this->messages[ $key ]['dismissed'][ $user_id ] = time();
346 254 }
347 255 }
348 256 $this->update_list();
349 257 }
350 258
351 - /**
352 - * @return array
353 - */
354 259 public function unread() {
355 260 $messages = $this->get_messages( 'filter' );
356 261 $user_id = get_current_user_id();
357 -
358 262 foreach ( $messages as $t => $message ) {
359 263 if ( isset( $message['read'] ) && isset( $message['read'][ $user_id ] ) ) {
360 264 unset( $messages[ $t ] );
361 265 }
362 266 }
363 -
364 267 return $messages;
365 268 }
366 269
367 - /**
368 - * @since 6.8.4 The $filtered parameter was added.
369 - *
370 - * @param bool $filtered
371 - *
372 - * @return string
373 - */
374 - public function unread_html( $filtered = true ) {
270 + public function unread_html() {
271 + $html = '';
375 272 $count = count( $this->unread() );
273 + if ( $count ) {
274 + $html = ' <span class="update-plugins frm_inbox_count"><span class="plugin-count">' . absint( $count ) . '</span></span>';
376 275
377 - if ( ! $count ) {
378 - return '';
276 + /**
277 + * @since 4.06.01
278 + */
279 + $html = apply_filters( 'frm_inbox_badge', $html );
379 280 }
380 -
381 - $html = ' <span class="update-plugins frm_inbox_count"><span class="plugin-count">' . absint( $count ) . '</span></span>';
382 -
383 - if ( ! $filtered ) {
384 - return $html;
385 - }
386 -
387 - /**
388 - * @since 4.06.01
389 - *
390 - * @param string $html
391 - */
392 - return (string) apply_filters( 'frm_inbox_badge', $html );
281 + return $html;
393 282 }
394 283
395 284 /**
396 285 * @since 4.05.02
397 - *
398 - * @param string $key
399 - *
400 - * @return void
401 286 */
402 287 public function remove( $key ) {
403 - if ( ! isset( self::$messages[ $key ] ) ) {
404 - return;
288 + if ( isset( $this->messages[ $key ] ) ) {
289 + unset( $this->messages[ $key ] );
290 + $this->update_list();
405 291 }
406 -
407 - unset( self::$messages[ $key ] );
408 - $this->update_list();
409 292 }
410 293
411 - /**
412 - * @return void
413 - */
414 294 private function update_list() {
415 - update_option( $this->option, self::$messages, false );
295 + update_option( $this->option, $this->messages, 'no' );
416 296 }
417 297
418 - /**
419 - * Show a banner message if one is available.
420 - *
421 - * @return bool True if a banner is available and shown.
422 - */
423 298 public static function maybe_show_banner() {
424 - if ( ! self::$banner_messages ) {
425 - return false;
299 + if ( empty( self::$banner_messages ) ) {
300 + return;
426 301 }
427 -
428 302 $message = end( self::$banner_messages );
429 - $cta = self::get_prepared_banner_cta( $message['cta'] );
430 -
431 303 require FrmAppHelper::plugin_path() . '/classes/views/inbox/banner.php';
432 - return true;
433 304 }
434 305
435 - /**
436 - * Make sure that the CTA uses utm_medium=banner.
437 - *
438 - * @since 6.8.4
439 - *
440 - * @param string $cta
441 - *
442 - * @return string
443 - */
444 - private static function get_prepared_banner_cta( $cta ) {
445 - $cta = str_replace( 'button-secondary', 'button-primary', $cta );
446 - return preg_replace_callback(
447 - '/href=("|\')(.*?)("|\')/',
448 - /**
449 - * Replace a single href attribute in the CTA.
450 - *
451 - * @param array $matches The regex results for a single match.
452 - *
453 - * @return string
454 - */
455 - function ( $matches ) {
456 - $url = $matches[2];
457 -
458 - if ( '#' === $url ) {
459 - return 'href="#"';
460 - }
461 -
462 - $parts = parse_url( $url );
463 - $query = array();
464 -
465 - if ( isset( $parts['query'] ) ) {
466 - parse_str( $parts['query'], $query );
467 - }
468 -
469 - $query['utm_medium'] = 'banner';
470 - $parts['query'] = http_build_query( $query );
471 - return 'href="' . esc_url( $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '?' . $parts['query'] ) . '"';
472 - },
473 - $cta
474 - );
475 - }
476 -
477 - /**
478 - * @return void
479 - */
480 306 public static function maybe_disable_screen_options() {
481 307 self::$banner_messages = self::get_banner_messages();
482 -
483 308 if ( self::$banner_messages ) {
484 - // Disable screen options tab when displaying banner messages because it gets in the way of the banner.
309 + // disable screen options tab when displaying banner messages because it gets in the way of the banner.
485 310 add_filter( 'screen_options_show_screen', '__return_false' );
486 311 }
487 312 }
488 313
489 314 /**
490 - * Get all message with a "banner" message key defined.
491 - *
492 315 * @return array
493 316 */
494 317 private static function get_banner_messages() {
495 - return self::get_messages_with_key( 'banner' );
496 - }
497 -
498 - /**
499 - * Get all messages with a "slidein" message key defined.
500 - *
501 - * @since 6.8.4
502 - *
503 - * @return array
504 - */
505 - private static function get_slidein_messages() {
506 - return self::get_messages_with_key( 'slidein' );
507 - }
508 -
509 - /**
510 - * Get all messages with a $key message key defined.
511 - *
512 - * @since 6.8.4
513 - *
514 - * @param string $key The key we are checking for (ie. banner or slidein).
515 - *
516 - * @return array
517 - */
518 - private static function get_messages_with_key( $key ) {
519 318 $inbox = new self();
520 319 return array_filter(
521 320 $inbox->get_messages( 'filter' ),
522 - function ( $message ) use ( $key ) {
523 - return ! empty( $message[ $key ] );
321 + function( $message ) {
322 + return ! empty( $message['banner'] );
524 323 }
525 324 );
526 - }
527 -
528 - /**
529 - * Check if there is at least one slidein message.
530 - *
531 - * @since 6.8.4
532 - *
533 - * @return bool
534 - */
535 - public static function has_a_slidein_message() {
536 - return (bool) self::get_slidein_messages();
537 - }
538 -
539 - /**
540 - * Get the array used for frmGlobal.inboxSlideIn
541 - *
542 - * @since 6.8.4
543 - *
544 - * @return array|false
545 - */
546 - public static function get_inbox_slide_in_value_for_js() {
547 - $messages = self::get_slidein_messages();
548 -
549 - if ( ! $messages ) {
550 - return false;
551 - }
552 -
553 - $message = reset( $messages );
554 -
555 - /**
556 - * Extend the keys in the global JS object.
557 - * This is used in Pro to include images.
558 - *
559 - * @since 6.8.4
560 - *
561 - * @param array $keys
562 - */
563 - $keys_to_return = apply_filters(
564 - 'frm_inbox_slidein_js_vars',
565 - array( 'key', 'slidein', 'subject', 'cta' )
566 - );
567 -
568 - return array_reduce(
569 - $keys_to_return,
570 - function ( $total, $key ) use ( $message ) {
571 - $total[ $key ] = $message[ $key ] ?? '';
572 - return $total;
573 - },
574 - array()
575 - );
576 - }
577 -
578 - /**
579 - * Clear the inbox cache by deleting the associated option from the database.
580 - *
581 - * @since 6.17
582 - *
583 - * @return void
584 - */
585 - public static function clear_cache() {
586 - delete_option( 'frm_inbox' );
587 - }
588 -
589 - /**
590 - * Check inbox for an "error" type. This is displayed on the form list page if one exists.
591 - *
592 - * @since 6.19
593 - *
594 - * @return array|false
595 - */
596 - public static function check_for_error() {
597 - $inbox = new self();
598 - $messages = $inbox->get_messages( 'filter' );
599 -
600 - foreach ( $messages as $message ) {
601 - if ( is_array( $message ) && isset( $message['type'] ) && 'error' === $message['type'] ) {
602 - return $message;
603 - }
604 - }
605 -
606 - return false;
607 325 }
608 326 }