PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.16.3
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.16.3
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 +236 -23 6.56.16.3 View file →
@@ -14,9 +14,9 @@
14 14
15 15 private static $messages = false;
16 16
17 17 /**
18 - * @param array
18 + * @var array
19 19 */
20 20 private static $banner_messages;
21 21
22 22 public function __construct( $for_parent = null ) {
@@ -47,9 +47,9 @@
47 47
48 48 /**
49 49 * @since 4.05
50 50 *
51 - * @param false|string $filter
51 + * @param array|false $filter
52 52 */
53 53 public function get_messages( $filter = false ) {
54 54 $messages = self::$messages;
55 55 if ( $filter === 'filter' ) {
@@ -139,9 +139,10 @@
139 139 'subject' => '',
140 140 'icon' => 'frm_tooltip_icon',
141 141 'cta' => '',
142 142 'expires' => false,
143 - 'who' => 'all', // use 'free', 'personal', 'business', 'elite', 'grandfathered'
143 + // Use 'free', 'personal', 'business', 'elite', 'grandfathered'.
144 + 'who' => 'all',
144 145 'type' => '',
145 146 );
146 147
147 148 $message = array_merge( $defaults, $message );
@@ -155,10 +156,10 @@
155 156 */
156 157 private function clean_messages() {
157 158 $removed = false;
158 159 foreach ( self::$messages as $t => $message ) {
159 - $read = isset( $message['read'] ) && ! empty( $message['read'] ) && isset( $message['read'][ get_current_user_id() ] ) && $message['read'][ get_current_user_id() ] < strtotime( '-1 month' );
160 - $dismissed = isset( $message['dismissed'] ) && ! empty( $message['dismissed'] ) && isset( $message['dismissed'][ get_current_user_id() ] ) && $message['dismissed'][ get_current_user_id() ] < strtotime( '-1 week' );
160 + $read = ! empty( $message['read'] ) && isset( $message['read'][ get_current_user_id() ] ) && $message['read'][ get_current_user_id() ] < strtotime( '-1 month' );
161 + $dismissed = ! empty( $message['dismissed'] ) && isset( $message['dismissed'][ get_current_user_id() ] ) && $message['dismissed'][ get_current_user_id() ] < strtotime( '-1 week' );
161 162 $expired = $this->is_expired( $message );
162 163 if ( $read || $expired || $dismissed ) {
163 164 unset( self::$messages[ $t ] );
164 165 $removed = true;
@@ -170,15 +171,17 @@
170 171 }
171 172 }
172 173
173 174 /**
175 + * @param array $messages
176 + * @param string $type
174 177 * @return void
175 178 */
176 - private function filter_messages( &$messages ) {
179 + public function filter_messages( &$messages, $type = 'unread' ) {
177 180 $user_id = get_current_user_id();
178 181 foreach ( $messages as $k => $message ) {
179 182 $dismissed = isset( $message['dismissed'] ) && isset( $message['dismissed'][ $user_id ] );
180 - if ( empty( $k ) || $this->is_expired( $message ) || $dismissed ) {
183 + if ( empty( $k ) || $this->is_expired( $message ) || ( $type === 'dismissed' ) !== $dismissed ) {
181 184 unset( $messages[ $k ] );
182 185 } elseif ( ! $this->is_for_user( $message ) ) {
183 186 unset( $messages[ $k ] );
184 187 }
@@ -191,9 +194,9 @@
191 194 *
192 195 * @return bool
193 196 */
194 197 private function is_expired( $message ) {
195 - return isset( $message['expires'] ) && ! empty( $message['expires'] ) && $message['expires'] < time();
198 + return ! empty( $message['expires'] ) && $message['expires'] < time();
196 199 }
197 200
198 201 /**
199 202 * Show different messages for different accounts.
@@ -205,11 +208,49 @@
205 208 if ( ! isset( $message['who'] ) || $message['who'] === 'all' ) {
206 209 return true;
207 210 }
208 211 $who = (array) $message['who'];
209 - if ( in_array( 'all', $who, true ) || in_array( 'everyone', $who, true ) ) {
212 + if ( $this->is_for_everyone( $who ) ) {
210 213 return true;
211 214 }
215 + if ( $this->is_user_type( $who ) ) {
216 + return true;
217 + }
218 + if ( in_array( 'free_first_30', $who, true ) && $this->is_free_first_30() ) {
219 + return true;
220 + }
221 + if ( in_array( 'free_not_first_30', $who, true ) && $this->is_free_not_first_30() ) {
222 + return true;
223 + }
224 + /**
225 + * Allow for other special inbox cases in other add-ons.
226 + *
227 + * @since 6.8.1
228 + *
229 + * @param bool $is_for_user
230 + * @param array $who
231 + * @param array $message
232 + */
233 + return (bool) apply_filters( 'frm_inbox_message_is_for_user', false, $who, $message );
234 + }
235 +
236 + /**
237 + * @since 6.16.3
238 + *
239 + * @param array $who
240 + * @return bool
241 + */
242 + private function is_for_everyone( $who ) {
243 + return in_array( 'all', $who, true ) || in_array( 'everyone', $who, true );
244 + }
245 +
246 + /**
247 + * @since 6.16.3
248 + *
249 + * @param array $who
250 + * @return bool
251 + */
252 + private function is_user_type( $who ) {
212 253 return in_array( $this->get_user_type(), $who, true );
213 254 }
214 255
215 256 private function get_user_type() {
@@ -238,12 +279,11 @@
238 279 $this->update_list();
239 280 }
240 281
241 282 /**
242 - * @param string $key
243 - *
244 283 * @since 4.05.02
245 284 *
285 + * @param string $key
246 286 * @return void
247 287 */
248 288 public function mark_unread( $key ) {
249 289 $is_read = isset( self::$messages[ $key ] ) && isset( self::$messages[ $key ]['read'] ) && isset( self::$messages[ $key ]['read'][ get_current_user_id() ] );
@@ -305,20 +345,32 @@
305 345 }
306 346 return $messages;
307 347 }
308 348
309 - public function unread_html() {
310 - $html = '';
349 + /**
350 + * @since 6.8.4 The $filtered parameter was added.
351 + *
352 + * @param bool $filtered
353 + * @return string
354 + */
355 + public function unread_html( $filtered = true ) {
311 356 $count = count( $this->unread() );
312 - if ( $count ) {
313 - $html = ' <span class="update-plugins frm_inbox_count"><span class="plugin-count">' . absint( $count ) . '</span></span>';
357 + if ( ! $count ) {
358 + return '';
359 + }
314 360
315 - /**
316 - * @since 4.06.01
317 - */
318 - $html = apply_filters( 'frm_inbox_badge', $html );
361 + $html = ' <span class="update-plugins frm_inbox_count"><span class="plugin-count">' . absint( $count ) . '</span></span>';
362 +
363 + if ( ! $filtered ) {
364 + return $html;
319 365 }
320 - return $html;
366 +
367 + /**
368 + * @since 4.06.01
369 + *
370 + * @param string $html
371 + */
372 + return (string) apply_filters( 'frm_inbox_badge', $html );
321 373 }
322 374
323 375 /**
324 376 * @since 4.05.02
@@ -323,9 +375,8 @@
323 375 /**
324 376 * @since 4.05.02
325 377 *
326 378 * @param string $key
327 - *
328 379 * @return void
329 380 */
330 381 public function remove( $key ) {
331 382 if ( isset( self::$messages[ $key ] ) ) {
@@ -341,8 +392,56 @@
341 392 update_option( $this->option, self::$messages, 'no' );
342 393 }
343 394
344 395 /**
396 + * Check if user is still using the Lite version only, and within
397 + * the first 30 days of activation.
398 + *
399 + * @since 6.16
400 + *
401 + * @return bool
402 + */
403 + private function is_free_first_30() {
404 + return $this->is_free() && $this->is_first_30();
405 + }
406 +
407 + /**
408 + * @since 6.16.3
409 + *
410 + * @return bool
411 + */
412 + private function is_first_30() {
413 + $activation_timestamp = get_option( 'frm_first_activation' );
414 + if ( false === $activation_timestamp ) {
415 + // If the option does not exist, assume that it is
416 + // because the user was active before this option was introduced.
417 + return false;
418 + }
419 + $cutoff = strtotime( '-30 days' );
420 + return $activation_timestamp > $cutoff;
421 + }
422 +
423 + /**
424 + * @since 6.16.3
425 + *
426 + * @return bool
427 + */
428 + private function is_free_not_first_30() {
429 + return $this->is_free() && ! $this->is_first_30();
430 + }
431 +
432 + /**
433 + * Check if the Pro plugin is active. If not, consider the user to be on the free version.
434 + *
435 + * @since 6.16.3
436 + *
437 + * @return bool
438 + */
439 + private function is_free() {
440 + return ! FrmAppHelper::pro_is_included();
441 + }
442 +
443 + /**
345 444 * Show a banner message if one is available.
346 445 *
347 446 * @return bool True if a banner is available and shown.
348 447 */
@@ -350,13 +449,53 @@
350 449 if ( empty( self::$banner_messages ) ) {
351 450 return false;
352 451 }
353 452 $message = end( self::$banner_messages );
453 + $cta = self::get_prepared_banner_cta( $message['cta'] );
454 +
354 455 require FrmAppHelper::plugin_path() . '/classes/views/inbox/banner.php';
355 456 return true;
356 457 }
357 458
358 459 /**
460 + * Make sure that the CTA uses utm_medium=banner.
461 + *
462 + * @since 6.8.4
463 + *
464 + * @param string $cta
465 + * @return string
466 + */
467 + private static function get_prepared_banner_cta( $cta ) {
468 + $cta = str_replace( 'button-secondary', 'button-primary', $cta );
469 + return preg_replace_callback(
470 + '/href=("|\')(.*?)("|\')/',
471 + /**
472 + * Replace a single href attribute in the CTA.
473 + *
474 + * @param array $matches The regex results for a single match.
475 + * @return string
476 + */
477 + function ( $matches ) {
478 + $url = $matches[2];
479 + $parts = parse_url( $url );
480 +
481 + if ( '#' === $url ) {
482 + return 'href="#"';
483 + }
484 +
485 + $query = array();
486 + if ( isset( $parts['query'] ) ) {
487 + parse_str( $parts['query'], $query );
488 + }
489 + $query['utm_medium'] = 'banner';
490 + $parts['query'] = http_build_query( $query );
491 + return 'href="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '?' . $parts['query'] . '"';
492 + },
493 + $cta
494 + );
495 + }
496 +
497 + /**
359 498 * @return void
360 499 */
361 500 public static function maybe_disable_screen_options() {
362 501 self::$banner_messages = self::get_banner_messages();
@@ -366,16 +505,90 @@
366 505 }
367 506 }
368 507
369 508 /**
509 + * Get all message with a "banner" message key defined.
510 + *
370 511 * @return array
371 512 */
372 513 private static function get_banner_messages() {
514 + return self::get_messages_with_key( 'banner' );
515 + }
516 +
517 + /**
518 + * Get all messages with a "slidein" message key defined.
519 + *
520 + * @since 6.8.4
521 + *
522 + * @return array
523 + */
524 + private static function get_slidein_messages() {
525 + return self::get_messages_with_key( 'slidein' );
526 + }
527 +
528 + /**
529 + * Get all messages with a $key message key defined.
530 + *
531 + * @since 6.8.4
532 + *
533 + * @param string $key The key we are checking for (ie. banner or slidein).
534 + * @return array
535 + */
536 + private static function get_messages_with_key( $key ) {
373 537 $inbox = new self();
374 538 return array_filter(
375 539 $inbox->get_messages( 'filter' ),
376 - function( $message ) {
377 - return ! empty( $message['banner'] );
540 + function ( $message ) use ( $key ) {
541 + return ! empty( $message[ $key ] );
378 542 }
543 + );
544 + }
545 +
546 + /**
547 + * Check if there is at least one slidein message.
548 + *
549 + * @since 6.8.4
550 + *
551 + * @return bool
552 + */
553 + public static function has_a_slidein_message() {
554 + return (bool) self::get_slidein_messages();
555 + }
556 +
557 + /**
558 + * Get the array used for frmGlobal.inboxSlideIn
559 + *
560 + * @since 6.8.4
561 + *
562 + * @return array|false
563 + */
564 + public static function get_inbox_slide_in_value_for_js() {
565 + $messages = self::get_slidein_messages();
566 + if ( ! $messages ) {
567 + return false;
568 + }
569 +
570 + $message = reset( $messages );
571 +
572 + /**
573 + * Extend the keys in the global JS object.
574 + * This is used in Pro to include images.
575 + *
576 + * @since 6.8.4
577 + *
578 + * @param array $keys
579 + */
580 + $keys_to_return = apply_filters(
581 + 'frm_inbox_slidein_js_vars',
582 + array( 'key', 'slidein', 'subject', 'cta' )
583 + );
584 +
585 + return array_reduce(
586 + $keys_to_return,
587 + function ( $total, $key ) use ( $message ) {
588 + $total[ $key ] = isset( $message[ $key ] ) ? $message[ $key ] : '';
589 + return $total;
590 + },
591 + array()
379 592 );
380 593 }
381 594 }