Popups by OptinMonster – Best WordPress Lead Generation Plugin - Version 1.5.1

Version Description

  • Fixed a possible security issue with admin notices.
  • Updated outdated URLs in the admin.
Download this release

Release Info

Developer griffinjt
Plugin Icon 128x128 Popups by OptinMonster – Best WordPress Lead Generation Plugin
Version 1.5.1
Comparing to
See all releases

Code changes from version 1.4.2 to 1.5.1

OMAPI/Content.php CHANGED
@@ -181,13 +181,13 @@ class OMAPI_Content {
181
  public function api( $panel, $object ) {
182
 
183
  $link = $this->base->menu->get_action_link();
184
- $text = $this->base->menu->has_trial_link() ? 'Click here to start your free 30-day trial!' : 'Click here to view OptinMonster plans and pricing.';
185
 
186
  $credentials = $this->base->get_api_credentials();
187
 
188
  if ( ! $credentials ) : ?>
189
  <p class="omapi-red"><strong><?php _e( 'You must authenticate your OptinMonster account before you can use OptinMonster on this site.', 'optin-monster-api' ); ?></strong></p>
190
- <p><em><?php printf( __( 'Need an OptinMonster account? <a href="%s" title="Click here to view OptinMonster plans and pricing" target="_blank">%s</a>', 'optin-monster-api' ), $link, $text ); ?></em></p>
191
  <?php endif; ?>
192
 
193
  <?php echo $object->get_setting_ui( 'api', 'apikey' ); ?>
181
  public function api( $panel, $object ) {
182
 
183
  $link = $this->base->menu->get_action_link();
184
+ $text = $this->base->menu->has_trial_link() ? 'Click here to start your free 30-day trial!' : 'Click here to learn more about OptinMonster!';
185
 
186
  $credentials = $this->base->get_api_credentials();
187
 
188
  if ( ! $credentials ) : ?>
189
  <p class="omapi-red"><strong><?php _e( 'You must authenticate your OptinMonster account before you can use OptinMonster on this site.', 'optin-monster-api' ); ?></strong></p>
190
+ <p><em><?php printf( __( 'Need an OptinMonster account? <a href="%s" title="Click here to learn more about OptinMonster" target="_blank">%s</a>', 'optin-monster-api' ), $link, $text ); ?></em></p>
191
  <?php endif; ?>
192
 
193
  <?php echo $object->get_setting_ui( 'api', 'apikey' ); ?>
OMAPI/Menu.php CHANGED
@@ -1406,7 +1406,7 @@ class OMAPI_Menu {
1406
  * - define( 'OPTINMONSTER_SAS_ID', 1234 );
1407
  * - get_option( 'optinmonster_sas_id' ); (with the option being in the wp_options
1408
  * table) If an ID is present, returns the affiliate link with the affiliate ID. If no ID is
1409
- * present, just returns the OptinMonster pricing page URL.
1410
  */
1411
  public function get_sas_link() {
1412
 
@@ -1436,8 +1436,8 @@ class OMAPI_Menu {
1436
  . '&b=601672&m=49337&afftrack=&urllink=optinmonster.com';
1437
  }
1438
 
1439
- // Return the regular pricing page by default
1440
- return 'https://optinmonster.com/pricing/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpdashboard';
1441
 
1442
  }
1443
 
@@ -1450,7 +1450,7 @@ class OMAPI_Menu {
1450
  * - define( 'OPTINMONSTER_TRIAL_ID', 1234 );
1451
  * - get_option( 'optinmonster_trial_id' ); (with the option being in the wp_options
1452
  * table) If an ID is present, returns the trial link with the affiliate ID. If no ID is
1453
- * present, just returns the OptinMonster pricing page URL.
1454
  */
1455
  public function get_trial_link() {
1456
 
@@ -1480,8 +1480,8 @@ class OMAPI_Menu {
1480
  . '&b=601672&m=49337&afftrack=&urllink=optinmonster.com%2Ffree-trial%2F%3Fid%3D' . urlencode( trim( $omTrialId ) );
1481
  }
1482
 
1483
- // Return the regular pricing page by default
1484
- return 'https://optinmonster.com/pricing/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpdashboard';
1485
 
1486
  }
1487
 
@@ -1495,14 +1495,14 @@ class OMAPI_Menu {
1495
  } else if ( ! empty( $omSasId ) ) {
1496
  return $sas;
1497
  } else {
1498
- return 'https://optinmonster.com/pricing/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpdashboard';
1499
  }
1500
  }
1501
 
1502
  public function has_trial_link() {
1503
 
1504
  $link = $this->get_trial_link();
1505
- return strpos( $link, 'optinmonster.com/pricing' ) === false;
1506
 
1507
  }
1508
 
1406
  * - define( 'OPTINMONSTER_SAS_ID', 1234 );
1407
  * - get_option( 'optinmonster_sas_id' ); (with the option being in the wp_options
1408
  * table) If an ID is present, returns the affiliate link with the affiliate ID. If no ID is
1409
+ * present, just returns the OptinMonster WP landing page link instead.
1410
  */
1411
  public function get_sas_link() {
1412
 
1436
  . '&b=601672&m=49337&afftrack=&urllink=optinmonster.com';
1437
  }
1438
 
1439
+ // Return the regular WP landing page by default
1440
+ return 'https://optinmonster.com/wp/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpdashboard';
1441
 
1442
  }
1443
 
1450
  * - define( 'OPTINMONSTER_TRIAL_ID', 1234 );
1451
  * - get_option( 'optinmonster_trial_id' ); (with the option being in the wp_options
1452
  * table) If an ID is present, returns the trial link with the affiliate ID. If no ID is
1453
+ * present, just returns the OptinMonster WP landing page URL.
1454
  */
1455
  public function get_trial_link() {
1456
 
1480
  . '&b=601672&m=49337&afftrack=&urllink=optinmonster.com%2Ffree-trial%2F%3Fid%3D' . urlencode( trim( $omTrialId ) );
1481
  }
1482
 
1483
+ // Return the regular WP landing page by default
1484
+ return 'https://optinmonster.com/wp/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpdashboard';
1485
 
1486
  }
1487
 
1495
  } else if ( ! empty( $omSasId ) ) {
1496
  return $sas;
1497
  } else {
1498
+ return 'https://optinmonster.com/wp/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpdashboard';
1499
  }
1500
  }
1501
 
1502
  public function has_trial_link() {
1503
 
1504
  $link = $this->get_trial_link();
1505
+ return strpos( $link, 'optinmonster.com/wp' ) === false;
1506
 
1507
  }
1508
 
OMAPI/Output.php CHANGED
@@ -43,38 +43,7 @@ class OMAPI_Output {
43
  *
44
  * @var array
45
  */
46
- public $fields = array(
47
- 'enabled',
48
- 'automatic',
49
- 'users',
50
- 'never',
51
- 'only',
52
- 'categories',
53
- 'taxonomies',
54
- 'show',
55
- 'type',
56
- 'shortcode',
57
- 'shortcode_output',
58
- 'mailpoet',
59
- 'test',
60
- 'show_on_woocommerce',
61
- 'is_wc_shop',
62
- 'is_wc_product',
63
- 'is_wc_cart',
64
- 'is_wc_checkout',
65
- 'is_wc_account',
66
- 'is_wc_endpoint',
67
- 'is_wc_endpoint_order_pay',
68
- 'is_wc_endpoint_order_received',
69
- 'is_wc_endpoint_view_order',
70
- 'is_wc_endpoint_edit_account',
71
- 'is_wc_endpoint_edit_address',
72
- 'is_wc_endpoint_lost_password',
73
- 'is_wc_endpoint_customer_logout',
74
- 'is_wc_endpoint_add_payment_method',
75
- 'is_wc_product_category',
76
- 'is_wc_product_tag',
77
- );
78
 
79
  /**
80
  * Flag for determining if localized JS variable is output.
@@ -113,6 +82,8 @@ class OMAPI_Output {
113
  // Set our object.
114
  $this->set();
115
 
 
 
116
  // If no credentials have been provided, do nothing.
117
  if ( ! $this->base->get_api_credentials() ) {
118
  return;
@@ -137,7 +108,11 @@ class OMAPI_Output {
137
 
138
  self::$instance = $this;
139
  $this->base = OMAPI::get_instance();
140
- $this->fields = apply_filters( 'optin_monster_api_output_fields', $this->fields );
 
 
 
 
141
 
142
  }
143
 
@@ -148,7 +123,7 @@ class OMAPI_Output {
148
  */
149
  public function api_script() {
150
 
151
- wp_enqueue_script( $this->base->plugin_slug . '-api-script', OPTINMONSTER_APIJS_URL, array( 'jquery' ), $this->base->version );
152
 
153
  if ( version_compare( get_bloginfo( 'version' ), '4.1.0', '>=' ) ) {
154
  add_filter( 'script_loader_tag', array( $this, 'filter_api_script' ), 10, 2 );
@@ -226,9 +201,7 @@ class OMAPI_Output {
226
  public function maybe_load_optinmonster() {
227
 
228
  // If a URL suffix is set to not load optinmonster, don't do anything.
229
- $bool = apply_filters( 'optin_monster_query_filter', false ); // Deprecated.
230
- $bool = apply_filters( 'optin_monster_api_query_filter', false );
231
- if ( $bool ) {
232
  // Default the global cookie to 30 days.
233
  $global_cookie = 30;
234
  $global_cookie = apply_filters( 'optin_monster_query_cookie', $global_cookie ); // Deprecated.
@@ -304,7 +277,6 @@ class OMAPI_Output {
304
  }
305
  }
306
  $optins = $this->base->get_optins();
307
- $fields = array();
308
 
309
  // If no optins are found, return early.
310
  if ( ! $optins ) {
@@ -313,296 +285,12 @@ class OMAPI_Output {
313
 
314
  // Loop through each optin and optionally output it on the site.
315
  foreach ( $optins as $optin ) {
316
- // Grab all the fields to check against.
317
- foreach ( (array) $this->fields as $field ) {
318
- $fields[ $field ] = get_post_meta( $optin->ID, '_omapi_' . $field, true );
319
- }
320
-
321
- // Ensure the optin is enabled. If not, pass over it.
322
- if ( empty( $fields['enabled'] ) || ! $fields['enabled'] ) {
323
- continue;
324
- }
325
-
326
- // If in legacy test mode but not logged in, skip over the optin.
327
- if ( isset( $fields['test'] ) && $fields['test'] && ! is_user_logged_in() ) {
328
- continue;
329
- }
330
-
331
- // If the type is a sidebar or after post optin, pass over it.
332
- if ( isset( $fields['type'] ) && ! OMAPI_Utils::is_inline_type( $fields['type'] ) ) {
333
- continue;
334
- }
335
-
336
- // If the optin is to be shown only to logged in users but is not logged in, pass over it.
337
- if ( isset( $fields['users'] ) && 'in' == $fields['users'] && ! is_user_logged_in() ) {
338
- continue;
339
- }
340
-
341
- // If the optin is to be shown only to visitors but is logged in, pass over it.
342
- if ( isset( $fields['users'] ) && 'out' == $fields['users'] && is_user_logged_in() ) {
343
- continue;
344
- }
345
-
346
- // Check to see if we need to load the WP API helper script.
347
- if ( isset( $fields['mailpoet'] ) && $fields['mailpoet'] ) {
348
- $this->wp_helper();
349
- }
350
-
351
- // Prepare the optin campaign.
352
- $html = trim( html_entity_decode( stripslashes( $optin->post_content ), ENT_QUOTES ), '\'' );
353
-
354
- // If the optin is only to be shown on specific post IDs, get the code and break.
355
- if ( ! empty( $fields['only'] ) ) {
356
- if ( $post_id && in_array( $post_id, (array) $fields['only'] ) ) {
357
- $content .= $html;
358
- $this->set_slug( $optin );
359
- continue;
360
- }
361
- }
362
-
363
- // Exclude posts/pages from optin display.
364
- if ( ! empty( $fields['never'] ) ) {
365
- if ( $post_id && in_array( $post_id, (array) $fields['never'] ) ) {
366
- continue;
367
- }
368
- }
369
-
370
- // If the optin is only to be shown on particular categories, get the code and break.
371
- if ( ! empty( $fields['categories'] ) && ( 'post' == get_post_type() ) ) {
372
- // If this is the home page, check to see if they have decided to load on certain archive pages.
373
- if ( is_home() ) {
374
- // Run a check for archive-type pages.
375
- if ( ! empty( $fields['show'] ) ) {
376
- // If showing on index pages and we are on an index page, show the optin.
377
- if ( in_array( 'index', (array) $fields['show'] ) ) {
378
- if ( is_front_page() || is_home() || is_archive() || is_search() ) {
379
- $content .= $html;
380
- $this->set_slug( $optin );
381
- continue;
382
- }
383
- }
384
-
385
- // Check if we should show on a selected post type.
386
- if ( in_array( 'post', (array) $fields['show'] ) && ! ( is_front_page() || is_home() || is_archive() || is_search() ) ) {
387
- $content .= $html;
388
- $this->set_slug( $optin );
389
- continue;
390
- }
391
- }
392
- }
393
-
394
- $categories = wp_get_object_terms( $post_id, 'category', array( 'fields' => 'ids' ) );
395
- foreach ( (array) $categories as $category_id ) {
396
- if ( $category_id && in_array( $category_id, $fields['categories'] ) && ! is_archive() ) {
397
- $content .= $html;
398
- $this->set_slug( $optin );
399
- continue 2;
400
- }
401
- }
402
- }
403
-
404
- // If the optin is only to be shown on particular taxonomies, get the code and break.
405
- if ( ! empty( $fields['taxonomies'] ) && ( is_singular() ) ) {
406
- // If this is the home page, check to see if they have decided to load on certain archive pages.
407
- if ( is_home() ) {
408
- // Run a check for archive-type pages.
409
- if ( ! empty( $fields['show'] ) ) {
410
- // If showing on index pages and we are on an index page, show the optin.
411
- if ( in_array( 'index', (array) $fields['show'] ) ) {
412
- if ( is_front_page() || is_home() || is_archive() || is_search() ) {
413
- $content .= $html;
414
- $this->set_slug( $optin );
415
- continue;
416
- }
417
- }
418
-
419
- // Check if we should show on a selected post type.
420
- if ( in_array( 'post', (array) $fields['show'] ) && ! ( is_front_page() || is_home() || is_archive() || is_search() ) ) {
421
- $content .= $html;
422
- $this->set_slug( $optin );
423
- continue;
424
- }
425
- }
426
- }
427
-
428
- foreach ( $fields['taxonomies'] as $taxonomy => $taxonomy_id ) {
429
- if ( 'post_tag' === $taxonomy ) {
430
- $tax_ids = wp_parse_id_list( $taxonomy_id[0] );
431
- } else {
432
- $tax_ids = wp_parse_id_list( $taxonomy_id );
433
- }
434
-
435
- foreach ( $tax_ids as $tax_id ) {
436
- if ( $post_id && $tax_id && has_term( $tax_id, $taxonomy, $post_id ) ) {
437
- $content .= $html;
438
- $this->set_slug( $optin );
439
- continue 2;
440
- }
441
- }
442
- }
443
- }
444
-
445
- // Run a check for specific post types.
446
- if ( ! empty( $fields['show'] ) ) {
447
- // Check if we should show on a selected post type.
448
- if ( in_array( get_post_type(), (array) $fields['show'] ) && ! ( is_front_page() || is_home() || is_search() ) ) {
449
- $content .= $html;
450
- $this->set_slug( $optin );
451
- continue;
452
- }
453
- }
454
-
455
- // If WooCommerce is enabled we can look for WooCommerce specific settings.
456
- if ( $this->base->is_woocommerce_active() ) {
457
-
458
- // is_woocommerce anything
459
- if ( isset( $fields['show_on_woocommerce'] ) && $fields['show_on_woocommerce'] ) {
460
- if( is_woocommerce() ) {
461
- $content .= $html;
462
- $this->set_slug( $optin );
463
- continue;
464
- }
465
- }
466
- // is_product
467
- if ( isset( $fields['is_wc_product'] ) && $fields['is_wc_product'] ) {
468
- $global = false;
469
- if( is_product() ) {
470
- $content .= $html;
471
- $this->set_slug( $optin );
472
- continue;
473
- }
474
- }
475
-
476
- // is_cart
477
- if ( isset( $fields['is_wc_cart'] ) && $fields['is_wc_cart'] ) {
478
- $global = false;
479
- if( is_cart() ) {
480
- $content .= $html;
481
- $this->set_slug( $optin );
482
- continue;
483
- }
484
- }
485
-
486
- // is_checkout
487
- if ( isset( $fields['is_wc_checkout'] ) && $fields['is_wc_checkout'] ) {
488
- $global = false;
489
- if( is_checkout() ) {
490
- $content .= $html;
491
- $this->set_slug( $optin );
492
- continue;
493
- }
494
- }
495
-
496
- // is_account_page
497
- if ( isset( $fields['is_wc_account'] ) && $fields['is_wc_account'] ) {
498
- $global = false;
499
- if( is_account_page() ) {
500
- $content .= $html;
501
- $this->set_slug( $optin );
502
- continue;
503
- }
504
- }
505
-
506
- // is_wc_endpoint_url
507
- if ( isset( $fields['is_wc_endpoint'] ) && $fields['is_wc_endpoint'] ) {
508
- $global = false;
509
- if( is_wc_endpoint_url() ) {
510
- $content .= $html;
511
- $this->set_slug( $optin );
512
- continue;
513
- }
514
- }
515
-
516
- // is_wc_endpoint_url( 'order-pay' )
517
- if ( isset( $fields['is_wc_endpoint_order_pay'] ) && $fields['is_wc_endpoint_order_pay'] ) {
518
- $global = false;
519
- if( is_wc_endpoint_url( 'order-pay' ) ) {
520
- $content .= $html;
521
- $this->set_slug( $optin );
522
- continue;
523
- }
524
- }
525
-
526
- // is_wc_endpoint_url( 'order-received' )
527
- if ( isset( $fields['is_wc_endpoint_order_received'] ) && $fields['is_wc_endpoint_order_received'] ) {
528
- $global = false;
529
- if( is_wc_endpoint_url( 'order-received' ) ) {
530
- $content .= $html;
531
- $this->set_slug( $optin );
532
- continue;
533
- }
534
- }
535
-
536
- // is_wc_endpoint_url( 'view-order' )
537
- if ( isset( $fields['is_wc_endpoint_view_order'] ) && $fields['is_wc_endpoint_view_order'] ) {
538
- $global = false;
539
- if( is_wc_endpoint_url( 'view-order' ) ) {
540
- $content .= $html;
541
- $this->set_slug( $optin );
542
- continue;
543
- }
544
- }
545
-
546
- // is_wc_endpoint_url( 'edit-account' )
547
- if ( isset( $fields['is_wc_endpoint_edit_account'] ) && $fields['is_wc_endpoint_edit_account'] ) {
548
- $global = false;
549
- if( is_wc_endpoint_url( 'edit-account' ) ) {
550
- $content .= $html;
551
- $this->set_slug( $optin );
552
- continue;
553
- }
554
- }
555
-
556
- // is_wc_endpoint_url( 'edit-address' )
557
- if ( isset( $fields['is_wc_endpoint_edit_address'] ) && $fields['is_wc_endpoint_edit_address'] ) {
558
- $global = false;
559
- if( is_wc_endpoint_url( 'edit-address' ) ) {
560
- $content .= $html;
561
- $this->set_slug( $optin );
562
- continue;
563
- }
564
- }
565
-
566
- // is_wc_endpoint_url( 'lost-password' )
567
- if ( isset( $fields['is_wc_endpoint_lost_password'] ) && $fields['is_wc_endpoint_lost_password'] ) {
568
- $global = false;
569
- if( is_wc_endpoint_url( 'lost-password' ) ) {
570
- $content .= $html;
571
- $this->set_slug( $optin );
572
- continue;
573
- }
574
- }
575
-
576
- // is_wc_endpoint_url( 'customer-logout' )
577
- if ( isset( $fields['is_wc_endpoint_customer_logout'] ) && $fields['is_wc_endpoint_customer_logout'] ) {
578
- $global = false;
579
- if( is_wc_endpoint_url( 'customer-logout' ) ) {
580
- $content .= $html;
581
- $this->set_slug( $optin );
582
- continue;
583
- }
584
- }
585
- // is_wc_endpoint_url( 'add-payment-method' )
586
- if ( isset( $fields['is_wc_endpoint_add_payment_method'] ) && $fields['is_wc_endpoint_add_payment_method'] ) {
587
- $global = false;
588
- if( is_wc_endpoint_url( 'add-payment-method' ) ) {
589
- $content .= $html;
590
- $this->set_slug( $optin );
591
- continue;
592
- }
593
- }
594
-
595
-
596
-
597
- }
598
-
599
- // If the optin is set to be automatically displayed, show it.
600
- if ( isset( $fields['automatic'] ) && $fields['automatic'] && is_singular( 'post' ) ) {
601
- $content .= $html;
602
  $this->set_slug( $optin );
603
- continue;
604
- }
605
 
 
 
 
606
  }
607
 
608
  // Return the content.
@@ -627,7 +315,6 @@ class OMAPI_Output {
627
  }
628
  $optins = $this->base->get_optins();
629
  $init = array();
630
- $fields = array();
631
 
632
  // If no optins are found, return early.
633
  if ( ! $optins ) {
@@ -636,368 +323,17 @@ class OMAPI_Output {
636
 
637
  // Loop through each optin and optionally output it on the site.
638
  foreach ( $optins as $optin ) {
 
639
 
640
- // Grab all the fields to check against.
641
- foreach ( (array) $this->fields as $field ) {
642
- $fields[ $field ] = get_post_meta( $optin->ID, '_omapi_' . $field, true );
643
- }
644
-
645
- // Ensure the optin is enabled. If not, pass over it.
646
- if ( empty( $fields['enabled'] ) || ! $fields['enabled'] ) {
647
- continue;
648
- }
649
-
650
- // If in legacy test mode but not logged in, skip over the optin.
651
- if ( isset( $fields['test'] ) && $fields['test'] && ! is_user_logged_in() ) {
652
- continue;
653
- }
654
-
655
- // If the type is a sidebar or after post optin, pass over it.
656
- if ( isset( $fields['type'] ) && ( 'sidebar' == $fields['type'] || OMAPI_Utils::is_inline_type( $fields['type'] ) ) ) {
657
- continue;
658
- }
659
-
660
- // If the optin is to be shown only to logged in users but is not logged in, pass over it.
661
- if ( isset( $fields['users'] ) && 'in' == $fields['users'] && ! is_user_logged_in() ) {
662
- continue;
663
- }
664
 
665
- // If the optin is to be shown only to visitors but is logged in, pass over it.
666
- if ( isset( $fields['users'] ) && 'out' == $fields['users'] && is_user_logged_in() ) {
667
  continue;
668
  }
669
 
670
- // Check to see if we need to load the WP API helper script.
671
- if ( isset( $fields['mailpoet'] ) && $fields['mailpoet'] ) {
672
- $this->wp_helper();
673
- }
674
-
675
- // Prepare the optin campaign.
676
- $html = trim( html_entity_decode( stripslashes( $optin->post_content ), ENT_QUOTES ), '\'' );
677
- $global = true;
678
-
679
- // If the optin is only to be shown on specific post IDs, get the code and break.
680
- if ( ! empty( $fields['only'] ) ) {
681
- // Set flag for possibly not loading globally.
682
- $values = array_filter( array_values( $fields['only'] ) );
683
- if ( ! empty( $values ) ) {
684
- $global = false;
685
- }
686
-
687
- if ( $post_id && in_array( $post_id, (array) $fields['only'] ) ) {
688
- $init[ $optin->post_name ] = $html;
689
- $this->set_slug( $optin );
690
- continue;
691
- }
692
- }
693
-
694
- // Exclude posts/pages from optin display.
695
- if ( ! empty( $fields['never'] ) ) {
696
- // No global check on purpose. Global is still true if only this setting is populated.
697
- if ( $post_id && in_array( $post_id, (array) $fields['never'] ) ) {
698
- continue;
699
- }
700
- }
701
-
702
- // If the optin is only to be shown on particular categories, get the code and break.
703
- if ( ! empty( $fields['categories'] ) ) {
704
- // Set flag for possibly not loading globally.
705
- $values = array_filter( array_values( $fields['categories'] ) );
706
- if ( ! empty( $values ) ) {
707
- $global = false;
708
- }
709
-
710
- // Only load for the main "post" post type.
711
- if ( 'post' == get_post_type() ) {
712
- // Don't try to load on the blog home page even if a category that is selected appears in the loop.
713
- if ( is_home() ) {
714
- // Run a check for archive-type pages.
715
- if ( ! empty( $fields['show'] ) ) {
716
- // If showing on index pages and we are on an index page, show the optin.
717
- if ( in_array( 'index', (array) $fields['show'] ) ) {
718
- if ( is_front_page() || is_home() || is_search() ) {
719
- $init[ $optin->post_name ] = $html;
720
- $this->set_slug( $optin );
721
- continue;
722
- }
723
- }
724
-
725
- // Check if we should show on the 'post' post type.
726
- if ( in_array( 'post', (array) $fields['show'] ) && ! ( is_front_page() || is_home() || is_search() ) ) {
727
- $init[ $optin->post_name ] = $html;
728
- $this->set_slug( $optin );
729
- continue;
730
- }
731
- }
732
- }
733
-
734
- $categories = wp_get_object_terms( $post_id, 'category', array( 'fields' => 'ids' ) );
735
-
736
- // Check againts singular.
737
- foreach ( (array) $categories as $category_id ) {
738
- if ( $category_id && in_array( $category_id, $fields['categories'] ) ) {
739
- $init[ $optin->post_name ] = $html;
740
- $this->set_slug( $optin );
741
- continue 2;
742
- }
743
- }
744
-
745
- // Check archives.
746
- if ( is_category( $fields['categories'] ) ) {
747
- $init[ $optin->post_name ] = $html;
748
- $this->set_slug( $optin );
749
- continue;
750
- }
751
- }
752
- }
753
-
754
- // If the optin is only to be shown on particular taxonomies, get the code and break.
755
- if ( ! empty( $fields['taxonomies'] ) ) {
756
- // Set flag for possibly not loading globally.
757
- $values = array_filter( array_values( $fields['taxonomies'] ) );
758
- if ( ! empty( $values ) ) {
759
- foreach ( $values as $i => $value ) {
760
- $value = array_filter( array_values( $value ) );
761
- if ( $value ) {
762
- $global = false;
763
- break;
764
- }
765
- }
766
- }
767
-
768
- // If this is the home page, check to see if they have decided to load on certain archive pages.
769
- if ( is_home() ) {
770
- // Run a check for archive-type pages.
771
- if ( ! empty( $fields['show'] ) ) {
772
- // If showing on index pages and we are on an index page, show the optin.
773
- if ( in_array( 'index', (array) $fields['show'] ) ) {
774
- if ( is_front_page() || is_home() || is_search() ) {
775
- $init[ $optin->post_name ] = $html;
776
- $this->set_slug( $optin );
777
- continue;
778
- }
779
- }
780
-
781
- // Check if we should show on the 'post' post type.
782
- if ( in_array( 'post', (array) $fields['show'] ) && ! ( is_front_page() || is_home() || is_search() ) ) {
783
- $init[ $optin->post_name ] = $html;
784
- $this->set_slug( $optin );
785
- continue;
786
- }
787
- }
788
- }
789
-
790
- foreach ( $fields['taxonomies'] as $taxonomy => $taxonomy_id ) {
791
- if ( 'post_tag' === $taxonomy ) {
792
- $tax_ids = wp_parse_id_list( $taxonomy_id[0] );
793
- } else {
794
- $tax_ids = wp_parse_id_list( $taxonomy_id );
795
- }
796
-
797
- foreach ( $tax_ids as $tax_id ) {
798
- if ( $post_id && $tax_id && ( has_term( $tax_id, $taxonomy, $post_id ) || is_tag( $tax_id ) ) ) {
799
- $init[ $optin->post_name ] = $html;
800
- $this->set_slug( $optin );
801
- continue 2;
802
- }
803
- }
804
- }
805
- }
806
-
807
- // Run a check for archive-type pages.
808
- if ( ! empty( $fields['show'] ) ) {
809
- // Set flag for possibly not loading globally.
810
- $values = array_filter( array_values( $fields['show'] ) );
811
- if ( ! empty( $values ) ) {
812
- $global = false;
813
- }
814
-
815
- // If showing on index pages and we are on an index page, show the optin.
816
- if ( in_array( 'index', (array) $fields['show'] ) ) {
817
- if ( is_front_page() || is_home() || is_search() ) {
818
- $init[ $optin->post_name ] = $html;
819
- $this->set_slug( $optin );
820
- continue;
821
- }
822
- }
823
-
824
- // Check if we should show on a selected post type.
825
- if ( in_array( get_post_type(), (array) $fields['show'] ) && ! ( is_front_page() || is_home() || is_search() ) ) {
826
- $init[ $optin->post_name ] = $html;
827
- $this->set_slug( $optin );
828
- continue;
829
- }
830
- }
831
-
832
- // If WooCommerce is enabled we can look for WooCommerce specific settings.
833
- if ( $this->base->is_woocommerce_active() ) {
834
-
835
- // Separate never checks for WooCommerce pages that don't ID match
836
- if ( ! empty( $fields['never'] ) ) {
837
- // No global check on purpose. Global is still true if only this setting is populated.
838
- if ( in_array( wc_get_page_id( 'shop' ), (array) $fields['never'] ) && is_shop() ) {
839
- continue;
840
- }
841
- }
842
-
843
- // is_woocommerce
844
- if ( isset( $fields['show_on_woocommerce'] ) && $fields['show_on_woocommerce'] ) {
845
- $global = false;
846
- if( is_woocommerce() ) {
847
- $init[ $optin->post_name ] = $html;
848
- $this->set_slug( $optin );
849
- continue;
850
- }
851
- }
852
-
853
- // is_shop
854
- if ( isset( $fields['is_wc_shop'] ) && $fields['is_wc_shop'] ) {
855
- $global = false;
856
- if( is_shop() ) {
857
- $init[ $optin->post_name ] = $html;
858
- $this->set_slug( $optin );
859
- continue;
860
- }
861
- }
862
-
863
- // is_product
864
- if ( isset( $fields['is_wc_product'] ) && $fields['is_wc_product'] ) {
865
- $global = false;
866
- if( is_product() ) {
867
- $init[ $optin->post_name ] = $html;
868
- $this->set_slug( $optin );
869
- continue;
870
- }
871
- }
872
-
873
- // is_cart
874
- if ( isset( $fields['is_wc_cart'] ) && $fields['is_wc_cart'] ) {
875
- $global = false;
876
- if( is_cart() ) {
877
- $init[ $optin->post_name ] = $html;
878
- $this->set_slug( $optin );
879
- continue;
880
- }
881
- }
882
-
883
- // is_checkout
884
- if ( isset( $fields['is_wc_checkout'] ) && $fields['is_wc_checkout'] ) {
885
- $global = false;
886
- if( is_checkout() ) {
887
- $init[ $optin->post_name ] = $html;
888
- $this->set_slug( $optin );
889
- continue;
890
- }
891
- }
892
-
893
- // is_account_page
894
- if ( isset( $fields['is_wc_account'] ) && $fields['is_wc_account'] ) {
895
- $global = false;
896
- if( is_account_page() ) {
897
- $init[ $optin->post_name ] = $html;
898
- $this->set_slug( $optin );
899
- continue;
900
- }
901
- }
902
-
903
- // is_wc_endpoint_url
904
- if ( isset( $fields['is_wc_endpoint'] ) && $fields['is_wc_endpoint'] ) {
905
- $global = false;
906
- if( is_wc_endpoint_url() ) {
907
- $init[ $optin->post_name ] = $html;
908
- $this->set_slug( $optin );
909
- continue;
910
- }
911
- }
912
-
913
- // is_wc_endpoint_url( 'order-pay' )
914
- if ( isset( $fields['is_wc_endpoint_order_pay'] ) && $fields['is_wc_endpoint_order_pay'] ) {
915
- $global = false;
916
- if( is_wc_endpoint_url( 'order-pay' ) ) {
917
- $init[ $optin->post_name ] = $html;
918
- $this->set_slug( $optin );
919
- continue;
920
- }
921
- }
922
-
923
- // is_wc_endpoint_url( 'order-received' )
924
- if ( isset( $fields['is_wc_endpoint_order_received'] ) && $fields['is_wc_endpoint_order_received'] ) {
925
- $global = false;
926
- if( is_wc_endpoint_url( 'order-received' ) ) {
927
- $init[ $optin->post_name ] = $html;
928
- $this->set_slug( $optin );
929
- continue;
930
- }
931
- }
932
-
933
- // is_wc_endpoint_url( 'view-order' )
934
- if ( isset( $fields['is_wc_endpoint_view_order'] ) && $fields['is_wc_endpoint_view_order'] ) {
935
- $global = false;
936
- if( is_wc_endpoint_url( 'view-order' ) ) {
937
- $init[ $optin->post_name ] = $html;
938
- $this->set_slug( $optin );
939
- continue;
940
- }
941
- }
942
-
943
- // is_wc_endpoint_url( 'edit-account' )
944
- if ( isset( $fields['is_wc_endpoint_edit_account'] ) && $fields['is_wc_endpoint_edit_account'] ) {
945
- $global = false;
946
- if( is_wc_endpoint_url( 'edit-account' ) ) {
947
- $init[ $optin->post_name ] = $html;
948
- $this->set_slug( $optin );
949
- continue;
950
- }
951
- }
952
-
953
- // is_wc_endpoint_url( 'edit-address' )
954
- if ( isset( $fields['is_wc_endpoint_edit_address'] ) && $fields['is_wc_endpoint_edit_address'] ) {
955
- $global = false;
956
- if( is_wc_endpoint_url( 'edit-address' ) ) {
957
- $init[ $optin->post_name ] = $html;
958
- $this->set_slug( $optin );
959
- continue;
960
- }
961
- }
962
-
963
- // is_wc_endpoint_url( 'lost-password' )
964
- if ( isset( $fields['is_wc_endpoint_lost_password'] ) && $fields['is_wc_endpoint_lost_password'] ) {
965
- $global = false;
966
- if( is_wc_endpoint_url( 'lost-password' ) ) {
967
- $init[ $optin->post_name ] = $html;
968
- $this->set_slug( $optin );
969
- continue;
970
- }
971
- }
972
-
973
- // is_wc_endpoint_url( 'customer-logout' )
974
- if ( isset( $fields['is_wc_endpoint_customer_logout'] ) && $fields['is_wc_endpoint_customer_logout'] ) {
975
- $global = false;
976
- if( is_wc_endpoint_url( 'customer-logout' ) ) {
977
- $init[ $optin->post_name ] = $html;
978
- $this->set_slug( $optin );
979
- continue;
980
- }
981
- }
982
- // is_wc_endpoint_url( 'add-payment-method' )
983
- if ( isset( $fields['is_wc_endpoint_add_payment_method'] ) && $fields['is_wc_endpoint_add_payment_method'] ) {
984
- $global = false;
985
- if( is_wc_endpoint_url( 'add-payment-method' ) ) {
986
- $init[ $optin->post_name ] = $html;
987
- $this->set_slug( $optin );
988
- continue;
989
- }
990
- }
991
-
992
-
993
- }
994
-
995
- // If we should be loading globally, do it now.
996
- if ( $global ) {
997
- $init[ $optin->post_name ] = $html;
998
- $this->set_slug( $optin );
999
- continue;
1000
- }
1001
 
1002
  // Allow devs to filter the final output for more granular control over optin targeting.
1003
  // Devs should return the value for the slug key as false if the conditions are not met.
@@ -1031,19 +367,20 @@ class OMAPI_Output {
1031
  * @param object $optin The optin object.
1032
  */
1033
  public function set_slug( $optin ) {
 
1034
 
1035
  // Set the slug.
1036
- $this->slugs[ str_replace( '-', '_', $optin->post_name ) ] = array(
1037
- 'slug' => str_replace( '-', '_', $optin->post_name ),
1038
- 'mailpoet' => (bool) get_post_meta( $optin->ID, '_omapi_mailpoet', true )
1039
  );
1040
 
1041
  // Maybe set shortcode.
1042
- $shortcode = get_post_meta( $optin->ID, '_omapi_shortcode', true );
1043
- if ( $shortcode ) {
1044
  $this->shortcodes[] = get_post_meta( $optin->ID, '_omapi_shortcode_output', true );
1045
  }
1046
 
 
1047
  }
1048
 
1049
  /**
@@ -1117,7 +454,7 @@ class OMAPI_Output {
1117
  }
1118
 
1119
  /**
1120
- * Outputs the WP helper script for storing local optins.
1121
  *
1122
  * @since 1.0.0
1123
  */
@@ -1134,4 +471,39 @@ class OMAPI_Output {
1134
  }
1135
  }
1136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1137
  }
43
  *
44
  * @var array
45
  */
46
+ public $fields = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  /**
49
  * Flag for determining if localized JS variable is output.
82
  // Set our object.
83
  $this->set();
84
 
85
+ add_filter( 'optinmonster_pre_campaign_should_output', array( $this, 'enqueue_helper_js_if_applicable' ), 999, 2 );
86
+
87
  // If no credentials have been provided, do nothing.
88
  if ( ! $this->base->get_api_credentials() ) {
89
  return;
108
 
109
  self::$instance = $this;
110
  $this->base = OMAPI::get_instance();
111
+
112
+ $rules = new OMAPI_Rules();
113
+
114
+ // Keep these around for back-compat.
115
+ $this->fields = $rules->fields;
116
 
117
  }
118
 
123
  */
124
  public function api_script() {
125
 
126
+ wp_enqueue_script( $this->base->plugin_slug . '-api-script', OPTINMONSTER_APIJS_URL, array( 'jquery' ), null );
127
 
128
  if ( version_compare( get_bloginfo( 'version' ), '4.1.0', '>=' ) ) {
129
  add_filter( 'script_loader_tag', array( $this, 'filter_api_script' ), 10, 2 );
201
  public function maybe_load_optinmonster() {
202
 
203
  // If a URL suffix is set to not load optinmonster, don't do anything.
204
+ if ( apply_filters( 'optin_monster_api_query_filter', false ) ) {
 
 
205
  // Default the global cookie to 30 days.
206
  $global_cookie = 30;
207
  $global_cookie = apply_filters( 'optin_monster_query_cookie', $global_cookie ); // Deprecated.
277
  }
278
  }
279
  $optins = $this->base->get_optins();
 
280
 
281
  // If no optins are found, return early.
282
  if ( ! $optins ) {
285
 
286
  // Loop through each optin and optionally output it on the site.
287
  foreach ( $optins as $optin ) {
288
+ if ( OMAPI_Rules::check_inline( $optin, $post_id, true ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  $this->set_slug( $optin );
 
 
290
 
291
+ // Prepare the optin campaign.
292
+ $content .= $this->prepare_campaign( $optin );
293
+ }
294
  }
295
 
296
  // Return the content.
315
  }
316
  $optins = $this->base->get_optins();
317
  $init = array();
 
318
 
319
  // If no optins are found, return early.
320
  if ( ! $optins ) {
323
 
324
  // Loop through each optin and optionally output it on the site.
325
  foreach ( $optins as $optin ) {
326
+ $rules = new OMAPI_Rules( $optin, $post_id );
327
 
328
+ if ( $rules->should_output() ) {
329
+ $this->set_slug( $optin );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
 
331
+ // Prepare the optin campaign.
332
+ $init[ $optin->post_name ] = $this->prepare_campaign( $optin );
333
  continue;
334
  }
335
 
336
+ $fields = $rules->field_values;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
 
338
  // Allow devs to filter the final output for more granular control over optin targeting.
339
  // Devs should return the value for the slug key as false if the conditions are not met.
367
  * @param object $optin The optin object.
368
  */
369
  public function set_slug( $optin ) {
370
+ $slug = str_replace( '-', '_', $optin->post_name );
371
 
372
  // Set the slug.
373
+ $this->slugs[ $slug ] = array(
374
+ 'slug' => $slug,
375
+ 'mailpoet' => (bool) get_post_meta( $optin->ID, '_omapi_mailpoet', true ),
376
  );
377
 
378
  // Maybe set shortcode.
379
+ if ( get_post_meta( $optin->ID, '_omapi_shortcode', true ) ) {
 
380
  $this->shortcodes[] = get_post_meta( $optin->ID, '_omapi_shortcode_output', true );
381
  }
382
 
383
+ return $this;
384
  }
385
 
386
  /**
454
  }
455
 
456
  /**
457
+ * Enqueues the WP helper script for storing local optins.
458
  *
459
  * @since 1.0.0
460
  */
471
  }
472
  }
473
 
474
+ /**
475
+ * Prepare the optin campaign html.
476
+ *
477
+ * @since 1.5.0
478
+ *
479
+ * @param object $optin The option post object.
480
+ *
481
+ * @return string The optin campaign html.
482
+ */
483
+ public function prepare_campaign( $optin ) {
484
+ return isset( $optin->post_content ) && ! empty( $optin->post_content )
485
+ ? trim( html_entity_decode( stripslashes( $optin->post_content ), ENT_QUOTES ), '\'' )
486
+ : '';
487
+ }
488
+
489
+ /**
490
+ * Enqueues the WP helper script if relevant optin fields are found.
491
+ *
492
+ * @since 1.5.0
493
+ *
494
+ * @param bool $should_output Whether it should output.
495
+ * @param OMAPI_Rules $rules OMAPI_Rules object
496
+ *
497
+ * @return array
498
+ */
499
+ public function enqueue_helper_js_if_applicable( $should_output, $rules ) {
500
+
501
+ // Check to see if we need to load the WP API helper script.
502
+ if ( $should_output && ! $rules->field_empty( 'mailpoet' ) ) {
503
+ $this->wp_helper();
504
+ }
505
+
506
+ return $should_output;
507
+ }
508
+
509
  }
OMAPI/Rules.php ADDED
@@ -0,0 +1,681 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Rules exception base class.
4
+ *
5
+ * @since 1.5.0
6
+ *
7
+ * @package OMAPI
8
+ * @author Justin Sternberg
9
+ */
10
+ class OMAPI_Rules_Exception extends Exception {
11
+ protected $bool = null;
12
+ public function __construct( $message = null, $code = 0, Exception $previous = null ) {
13
+ if ( is_bool( $message ) ) {
14
+ $this->bool = $message;
15
+ $message = null;
16
+ }
17
+ parent::__construct( $message, $code, $previous );
18
+ }
19
+
20
+ public function get_bool() {
21
+ return $this->bool;
22
+ }
23
+ }
24
+ class OMAPI_Rules_False extends OMAPI_Rules_Exception {
25
+ protected $bool = false;
26
+ }
27
+ class OMAPI_Rules_True extends OMAPI_Rules_Exception {
28
+ protected $bool = true;
29
+ }
30
+
31
+ /**
32
+ * Rules class.
33
+ *
34
+ * @since 1.5.0
35
+ *
36
+ * @package OMAPI
37
+ * @author Justin Sternberg
38
+ */
39
+ class OMAPI_Rules {
40
+
41
+ /**
42
+ * Holds the meta fields used for checking output statuses.
43
+ *
44
+ * @since 1.5.0
45
+ *
46
+ * @var array
47
+ */
48
+ protected $fields = array(
49
+ 'enabled',
50
+ 'automatic',
51
+ 'users',
52
+ 'never',
53
+ 'only',
54
+ 'categories',
55
+ 'taxonomies',
56
+ 'show',
57
+ 'type',
58
+ 'shortcode',
59
+ 'shortcode_output',
60
+ 'mailpoet',
61
+ 'test',
62
+ 'show_on_woocommerce',
63
+ 'is_wc_shop',
64
+ 'is_wc_product',
65
+ 'is_wc_cart',
66
+ 'is_wc_checkout',
67
+ 'is_wc_account',
68
+ 'is_wc_endpoint',
69
+ 'is_wc_endpoint_order_pay',
70
+ 'is_wc_endpoint_order_received',
71
+ 'is_wc_endpoint_view_order',
72
+ 'is_wc_endpoint_edit_account',
73
+ 'is_wc_endpoint_edit_address',
74
+ 'is_wc_endpoint_lost_password',
75
+ 'is_wc_endpoint_customer_logout',
76
+ 'is_wc_endpoint_add_payment_method',
77
+ 'is_wc_product_category',
78
+ 'is_wc_product_tag',
79
+ );
80
+
81
+ /**
82
+ * Holds the meta field values for optin.
83
+ *
84
+ * @since 1.5.0
85
+ *
86
+ * @var array
87
+ */
88
+ protected $field_values = array();
89
+
90
+ /**
91
+ * Whether we're checking for inline display.
92
+ *
93
+ * @since 1.5.0
94
+ *
95
+ * @var boolean
96
+ */
97
+ protected $is_inline_check = false;
98
+
99
+ /**
100
+ * The current post id.
101
+ *
102
+ * @since 1.5.0
103
+ *
104
+ * @var int
105
+ */
106
+ protected $post_id = 0;
107
+
108
+ /**
109
+ * The campaign post object.
110
+ *
111
+ * @since 1.5.0
112
+ *
113
+ * @var object
114
+ */
115
+ protected $optin = null;
116
+
117
+ /**
118
+ * The OMAPI_Rules_Exception if applicable.
119
+ *
120
+ * @var OMAPI_Rules_Exception
121
+ */
122
+ protected $caught = null;
123
+
124
+ /**
125
+ * Whether campaign in loop should be output globally.
126
+ *
127
+ * @since 1.5.0
128
+ *
129
+ * @var bool
130
+ */
131
+ protected $global_override = true;
132
+
133
+ /**
134
+ * The last instance called of this class.
135
+ *
136
+ * @var OMAPI_Rules
137
+ */
138
+ public static $last_instance = null;
139
+
140
+ /**
141
+ * Primary class constructor.
142
+ *
143
+ * @since 1.5.0
144
+ *
145
+ * @param null|object $optin The campaign post object.
146
+ * @param int $post_id The current post id.
147
+ * @param bool $is_inline_check Whether we're checking for inline display.
148
+ */
149
+ public function __construct( $optin = null, $post_id = 0, $is_inline_check = false ) {
150
+ $this->fields = apply_filters( 'optin_monster_api_output_fields', $this->fields );
151
+
152
+ // Default to allowing global override if not an inline check.
153
+ $this->optin = $optin;
154
+ $this->post_id = $post_id;
155
+ $this->is_inline_check = $is_inline_check;
156
+ $this->global_override = ! $is_inline_check;
157
+
158
+ self::$last_instance = $this;
159
+ }
160
+
161
+ /**
162
+ * Determines if given campaign should show inline.
163
+ *
164
+ * @since 1.5.0
165
+ *
166
+ * @param int $post_id The current post id.
167
+ * @param object $optin The campaign post object.
168
+ *
169
+ * @return boolean|array
170
+ */
171
+ public static function check_inline( $optin, $post_id = 0 ) {
172
+ return self::check( $optin, $post_id, true );
173
+ }
174
+
175
+ /**
176
+ * Determines if given campaign should show for a shortcode.
177
+ *
178
+ * @since 1.5.0
179
+ *
180
+ * @param int $post_id The current post id.
181
+ * @param object $optin The campaign post object.
182
+ *
183
+ * @return boolean|array
184
+ */
185
+ public static function check_shortcode( $optin, $post_id = 0 ) {
186
+ return self::check( $optin, $post_id, 'shortcode' );
187
+ }
188
+
189
+ /**
190
+ * Determines if given campaign should show.
191
+ *
192
+ * @since 1.5.0
193
+ *
194
+ * @param int $post_id The current post id.
195
+ * @param object $optin The campaign post object.
196
+ * @param bool $is_inline_check Whether we're checking for inline display.
197
+ *
198
+ * @return boolean|array
199
+ */
200
+ public static function check( $optin, $post_id = 0, $is_inline_check = false ) {
201
+ $rules = new self( $optin, $post_id, $is_inline_check );
202
+
203
+ return $rules->should_output();
204
+ }
205
+
206
+ public function get_field_value( $field ) {
207
+ return isset( $this->field_values[ $field ] )
208
+ ? $this->field_values[ $field ]
209
+ : null;
210
+ }
211
+
212
+ public function field_empty( $field ) {
213
+ return empty( $this->field_values[ $field ] );
214
+ }
215
+
216
+ public function field_not_empty_array( $field ) {
217
+ return OMAPI_Utils::field_not_empty_array( $this->field_values, $field );
218
+ }
219
+
220
+ public function item_in_field( $item, $field ) {
221
+ return OMAPI_Utils::item_in_field( $item, $this->field_values, $field );
222
+ }
223
+
224
+ public function field_is( $field, $value ) {
225
+ return isset( $this->field_values[ $field ] ) && $value === $this->field_values[ $field ];
226
+ }
227
+
228
+ public function is_inline_type() {
229
+ return OMAPI_Utils::is_inline_type( $this->get_field_value( 'type' ) );
230
+ }
231
+
232
+ /**
233
+ * Determines if given campaign should show.
234
+ *
235
+ * @since 1.5.0
236
+ *
237
+ * @return boolean|array
238
+ */
239
+ public function should_output() {
240
+
241
+ // Collect all the fields to check against.
242
+ $this->collect_optin_fields();
243
+
244
+ $should_output = $this->check_should_output();
245
+
246
+ return apply_filters( 'optinmonster_pre_campaign_should_output', $should_output, $this );
247
+ }
248
+
249
+ /**
250
+ * Runs all checks to determine if given campaign should show.
251
+ *
252
+ * @since 1.5.0
253
+ *
254
+ * @return boolean|array
255
+ */
256
+ protected function check_should_output() {
257
+ try {
258
+
259
+ $this->exclude_if_not_enabled();
260
+ $this->exclude_on_campaign_types();
261
+ $this->exclude_on_user_logged_in_checks();
262
+
263
+ $this->default_checks();
264
+ $this->woocommerce_checks();
265
+ $this->include_if_inline_and_automatic();
266
+ $this->output_if_global_override();
267
+
268
+ // If we get this far, include it.
269
+ throw new OMAPI_Rules_False( 'default no show' );
270
+
271
+ } catch ( OMAPI_Rules_Exception $e ) {
272
+ $this->caught = $e;
273
+ $should_output = $e instanceof OMAPI_Rules_True;
274
+ }
275
+
276
+ return $should_output;
277
+ }
278
+
279
+ /**
280
+ * Collect all the field values for an optin.
281
+ *
282
+ * @since 1.5.0
283
+ *
284
+ * @return OMAPI_Rules
285
+ */
286
+ public function collect_optin_fields() {
287
+ foreach ( $this->fields as $field ) {
288
+ $this->field_values[ $field ] = get_post_meta( $this->optin->ID, '_omapi_' . $field, true );
289
+ }
290
+
291
+ return $this;
292
+ }
293
+
294
+ /**
295
+ * Excludes campaign from showing if its 'enabled' field is falsey or missing.
296
+ *
297
+ * @since 1.5.0
298
+ *
299
+ * @throws OMAPI_Rules_False
300
+ * @return void
301
+ */
302
+ public function exclude_if_not_enabled() {
303
+ if (
304
+ // Ensure the optin is enabled and should output.
305
+ $this->field_empty( 'enabled' )
306
+ // Unless it's a shortcode, in which case, we don't want to check
307
+ // if the campaign in the shortcode is "enabled".
308
+ // This is for legacy reasons. ¯\_(ツ)_/¯
309
+ && 'shortcode' !== $this->is_inline_check
310
+ ) {
311
+ throw new OMAPI_Rules_False( 'not enabled' );
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Excludes campaign from showing if its 'type' field is not an inline type
317
+ * and it's an inline request, or if it IS an inline type but NOT an inline request.
318
+ *
319
+ * @since 1.5.0
320
+ *
321
+ * @throws OMAPI_Rules_False
322
+ * @return void
323
+ */
324
+ public function exclude_on_campaign_types() {
325
+ // If inline check
326
+ if ( $this->is_inline_check ) {
327
+ // And if the type is not an inline type...
328
+ if ( ! $this->is_inline_type() ) {
329
+ // exclude it from outputting.
330
+ throw new OMAPI_Rules_False( 'only inline for inline check' );
331
+ }
332
+ } else {
333
+ // Ok, it's not an inline check
334
+ // So check if the type is an inline or sidebar type
335
+ if ( $this->field_is( 'type', 'sidebar' ) || $this->is_inline_type() ) {
336
+ // and exclude it from outputting.
337
+ throw new OMAPI_Rules_False( 'no inline for global check' );
338
+ }
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Checks if campaign should be shown based on its field and if user is logged in.
344
+ *
345
+ * @since 1.5.0
346
+ *
347
+ * @throws OMAPI_Rules_False
348
+ * @return void
349
+ */
350
+ public function exclude_on_user_logged_in_checks() {
351
+ $is_logged_in = is_user_logged_in();
352
+
353
+ // If in legacy test mode but not logged in, skip over the optin.
354
+ if ( ! $this->field_empty( 'test' ) && ! $is_logged_in ) {
355
+ throw new OMAPI_Rules_False( 'test mode' );
356
+ }
357
+
358
+ // If the optin is to be shown only to logged in users but is not logged in, pass over it.
359
+ if ( $this->field_is( 'users', 'in' ) && ! $is_logged_in ) {
360
+ throw new OMAPI_Rules_False( 'exclude for logged out' );
361
+ }
362
+
363
+ // If the optin is to be shown only to visitors but is logged in, pass over it.
364
+ if ( $this->field_is( 'users', 'out' ) && $is_logged_in ) {
365
+ throw new OMAPI_Rules_False( 'exclude for logged in' );
366
+ }
367
+ }
368
+
369
+ /**
370
+ * The default checks to see if given campaign should show.
371
+ *
372
+ * @since 1.5.0
373
+ *
374
+ * @throws OMAPI_Rules_False
375
+ * @return void
376
+ */
377
+ public function default_checks() {
378
+
379
+ // Exclude posts/pages from optin display
380
+
381
+ // Set flag for possibly not loading globally.
382
+ if ( $this->field_not_empty_array( 'only' ) ) {
383
+ $this->global_override = false;
384
+
385
+ // If the optin is only to be shown on specific post IDs...
386
+ if ( $this->item_in_field( $this->post_id, 'only' ) ) {
387
+ throw new OMAPI_Rules_True( "include on only $this->post_id" );
388
+ }
389
+ }
390
+
391
+ // Exclude posts/pages from optin display
392
+ if ( $this->item_in_field( $this->post_id, 'never' ) ) {
393
+ // No global check on purpose. Global is still true if only this setting is populated.
394
+ throw new OMAPI_Rules_False( "exclude on never $this->post_id" );
395
+ }
396
+
397
+ try {
398
+ // If the optin is only to be shown on particular categories...
399
+ $this->check_categories_field();
400
+ } catch ( OMAPI_Rules_Exception $e ) {
401
+ if ( $e instanceof OMAPI_Rules_True ) {
402
+ throw new OMAPI_Rules_True( 'include on categories', 0, $e );
403
+ }
404
+ }
405
+
406
+ try {
407
+ // If the optin is only to be shown on particular taxonomies...
408
+ $this->check_taxonomies_field();
409
+ } catch ( OMAPI_Rules_Exception $e ) {
410
+ if ( $e instanceof OMAPI_Rules_True ) {
411
+ throw new OMAPI_Rules_True( 'include on taxonomies', 0, $e );
412
+ }
413
+ }
414
+
415
+ if ( $this->field_not_empty_array( 'show' ) ) {
416
+ // Set flag for not loading globally.
417
+ $this->global_override = false;
418
+ }
419
+
420
+ if (
421
+ ! $this->is_inline_check
422
+ && $this->item_in_field( 'index', 'show' ) && OMAPI_Utils::is_front_or_search()
423
+ ) {
424
+ throw new OMAPI_Rules_True( 'is front or search and show on index' );
425
+ }
426
+
427
+ // Check if we should show on a selected post type.
428
+ if ( $this->item_in_field( get_post_type(), 'show' ) && ! OMAPI_Utils::is_front_or_search() ) {
429
+ throw new OMAPI_Rules_True( 'include on post type but not front/search' );
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Check for woocommerce rules.
435
+ *
436
+ * @since 1.5.0
437
+ *
438
+ * @throws OMAPI_Rules_False
439
+ * @return void
440
+ */
441
+ public function woocommerce_checks() {
442
+ // If WooCommerce is enabled we can look for WooCommerce specific settings.
443
+ if ( OMAPI::is_woocommerce_active() ) {
444
+
445
+ if (
446
+ ! $this->is_inline_check
447
+ // Separate never checks for WooCommerce pages that don't ID match
448
+ // No global check on purpose. Global is still true if only this setting is populated.
449
+ && $this->item_in_field( wc_get_page_id( 'shop' ), 'never' )
450
+ && is_shop()
451
+ ) {
452
+ throw new OMAPI_Rules_False( 'never on wc is_shop' );
453
+ }
454
+
455
+ try {
456
+ $this->check_woocommerce_field();
457
+ } catch ( OMAPI_Rules_Exception $e ) {
458
+ if ( $e instanceof OMAPI_Rules_True ) {
459
+ throw new OMAPI_Rules_True( 'include woocommerce', 0, $e );
460
+ }
461
+ }
462
+ }
463
+ }
464
+
465
+ /**
466
+ * Enable campaign to show if it is being checked inline and is set to automatic.
467
+ *
468
+ * @since 1.5.0
469
+ *
470
+ * @throws OMAPI_Rules_False
471
+ * @return void
472
+ */
473
+ public function include_if_inline_and_automatic() {
474
+ if (
475
+ $this->is_inline_check
476
+ // We don't want to output the shortcode version if it is set to show automatically,
477
+ // as they will conflict.
478
+ && 'shortcode' !== $this->is_inline_check
479
+ && ! $this->field_empty( 'automatic' )
480
+ && is_singular( 'post' )
481
+ ) {
482
+ throw new OMAPI_Rules_True( 'include inline automatic on singular post' );
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Enable campaign to show if it's global override to show is still true.'
488
+ *
489
+ * @since 1.5.0
490
+ *
491
+ * @throws OMAPI_Rules_False
492
+ * @return void
493
+ */
494
+ public function output_if_global_override() {
495
+ if ( $this->global_override ) {
496
+ // TODO: Track how often this occurs to determine the importance
497
+ // of the $this->global_override logic.
498
+ throw new OMAPI_Rules_True( 'include with global override' );
499
+ }
500
+ }
501
+
502
+ protected function check_categories_field() {
503
+ $categories = $this->get_field_value( 'categories' );
504
+ if ( empty( $categories ) ) {
505
+ throw new OMAPI_Rules_False( 'no categories' );
506
+ }
507
+
508
+ if ( $this->field_not_empty_array( 'categories' ) ) {
509
+ // Set flag for possibly not loading globally.
510
+ $this->global_override = false;
511
+ }
512
+
513
+ // If the optin is only to be shown on particular categories...
514
+ if ( 'post' !== get_post_type() ) {
515
+ throw new OMAPI_Rules_False( 'not post post_type' );
516
+ }
517
+
518
+ // If this is the home page, check to see if they have decided to load on certain archive pages.
519
+ // Run a check for archive-type pages.
520
+ // If showing on home and we are on an index page, show the optin.
521
+ // TODO: this originally checked is_front_page() || is_home() || is_archive() || is_search()
522
+ // but only is_home() would work originally (https://github.com/awesomemotive/optin-monster-wp-api/blame/948b74254284a57f1a338dfc70bc6db59ed3ce8b/OMAPI/Output.php#L407).
523
+ // Maybe reintroduce other conditions?
524
+ $this->check_is_home_and_show_on_index();
525
+
526
+ // TODO: Add check for: "Check if we should show on a selected post type."
527
+ // This was in the old logic (https://github.com/awesomemotive/optin-monster-wp-api/blame/948b74254284a57f1a338dfc70bc6db59ed3ce8b/OMAPI/Output.php#L385-L392)
528
+ // But has not worked for 3+ years as the is_home() condition was precluding it.
529
+ // Also applies to logic in check_taxonomies_field
530
+ // if ( in_array( 'post', (array) $fields['show'] ) && ! ( is_front_page() || is_home() || is_archive() || is_search() ) ) {
531
+ // $omapi_output->set_slug( $optin );
532
+ // return $html;
533
+ // }
534
+
535
+ $taxonomy = 'category';
536
+ if ( $this->post_id ) {
537
+ $all_cats = get_the_category( $this->post_id );
538
+
539
+ if ( ! empty( $all_cats ) ) {
540
+ foreach ( $all_cats as $term ) {
541
+ $has_term = in_array( $term->term_id, $categories );
542
+
543
+ if ( ! $has_term ) {
544
+ continue;
545
+ }
546
+
547
+ if ( ! $this->is_inline_check ) {
548
+ throw new OMAPI_Rules_True( "post has category $term->name" );
549
+ }
550
+
551
+ if ( ! is_archive() ) {
552
+ throw new OMAPI_Rules_True( "post has category $term->name & is not archive" );
553
+ }
554
+ }
555
+ }
556
+ }
557
+
558
+ if ( ! $this->is_inline_check && is_category( $categories ) ) {
559
+ throw new OMAPI_Rules_True( 'post on category' );
560
+ }
561
+
562
+ throw new OMAPI_Rules_False( 'categories check failed' );
563
+ }
564
+
565
+ protected function check_taxonomies_field() {
566
+ $taxonomies = $this->get_field_value( 'taxonomies' );
567
+ if ( empty( $taxonomies ) ) {
568
+ throw new OMAPI_Rules_False( 'no taxonomies' );
569
+ }
570
+
571
+ $values = $this->field_not_empty_array( 'taxonomies' );
572
+ if ( $values ) {
573
+ foreach ( $values as $i => $value ) {
574
+ if ( OMAPI_Utils::field_not_empty_array( $values, $i ) ) {
575
+ $this->global_override = false;
576
+ break;
577
+ }
578
+ }
579
+ }
580
+
581
+ // If the optin is only to be shown on particular taxonomies...
582
+ if ( $this->is_inline_check && ! is_singular() ) {
583
+ throw new OMAPI_Rules_False( 'not singular template' );
584
+ }
585
+
586
+ // If this is the home page, check to see if they have decided to load on certain archive pages.
587
+ // Run a check for archive-type pages.
588
+ // If showing on index pages and we are on an index page, show the optin.
589
+ // TODO: potentially move this above check_taxonomies_field && check_categories_field
590
+ $this->check_is_home_and_show_on_index();
591
+
592
+ foreach ( $taxonomies as $taxonomy => $ids_to_check ) {
593
+
594
+ if ( $this->post_id ) {
595
+ $all_terms = get_the_terms( $this->post_id, $taxonomy );
596
+
597
+ if ( ! empty( $all_terms ) ) {
598
+ foreach ( $all_terms as $term ) {
599
+ // TODO: determine why this logic is different than in check_categories_field.
600
+ if ( in_array( $term->term_id, $ids_to_check ) ) {
601
+ throw new OMAPI_Rules_True( "post has $taxonomy $term->name" );
602
+ }
603
+ }
604
+ }
605
+ }
606
+
607
+ if ( ! $this->is_inline_check && OMAPI_Utils::is_term_archive( $ids_to_check, $taxonomy ) ) {
608
+ throw new OMAPI_Rules_True( "not inline and is on $taxonomy archive" );
609
+ }
610
+
611
+ }
612
+
613
+ throw new OMAPI_Rules_False( 'taxonomies check failed' );
614
+ }
615
+
616
+ protected function check_is_home_and_show_on_index() {
617
+ if ( is_home() && $this->item_in_field( 'index', 'show' ) ) {
618
+ throw new OMAPI_Rules_True( 'is_home and show on index' );
619
+ }
620
+ }
621
+
622
+ protected function check_woocommerce_field() {
623
+
624
+ $wc_checks = array(
625
+ 'show_on_woocommerce' => array( 'is_woocommerce' ), // is woocommerce anything
626
+ 'is_wc_shop' => array( 'is_shop' ),
627
+ 'is_wc_product' => array( 'is_product' ),
628
+ 'is_wc_cart' => array( 'is_cart' ),
629
+ 'is_wc_checkout' => array( 'is_checkout' ),
630
+ 'is_wc_account' => array( 'is_account_page' ),
631
+ 'is_wc_endpoint' => array( 'is_wc_endpoint_url' ),
632
+ 'is_wc_endpoint_order_pay' => array( 'is_wc_endpoint_url', 'order-pay' ),
633
+ 'is_wc_endpoint_order_received' => array( 'is_wc_endpoint_url', 'order-received' ),
634
+ 'is_wc_endpoint_view_order' => array( 'is_wc_endpoint_url', 'view-order' ),
635
+ 'is_wc_endpoint_edit_account' => array( 'is_wc_endpoint_url', 'edit-account' ),
636
+ 'is_wc_endpoint_edit_address' => array( 'is_wc_endpoint_url', 'edit-address' ),
637
+ 'is_wc_endpoint_lost_password' => array( 'is_wc_endpoint_url', 'lost-password' ),
638
+ 'is_wc_endpoint_customer_logout' => array( 'is_wc_endpoint_url', 'customer-logout' ),
639
+ 'is_wc_endpoint_add_payment_method' => array( 'is_wc_endpoint_url', 'add-payment-method' ),
640
+ );
641
+
642
+ foreach ( $wc_checks as $field => $callback ) {
643
+ if ( $this->field_empty( $field ) ) {
644
+ continue;
645
+ }
646
+
647
+ $this->global_override = false;
648
+
649
+ if ( call_user_func_array( array_shift( $callback ), $callback ) ) {
650
+ // If it passes, send it back.
651
+ throw new OMAPI_Rules_True( $field );
652
+ }
653
+ }
654
+ }
655
+
656
+ /**
657
+ * Magic getter for our object.
658
+ *
659
+ * @since 1.5.0
660
+ *
661
+ * @param string $property
662
+ * @throws Exception Throws an exception if the field is invalid.
663
+ *
664
+ * @return mixed
665
+ */
666
+ public function __get( $property ) {
667
+ switch ( $property ) {
668
+ case 'is_inline_check':
669
+ case 'post_id':
670
+ case 'optin':
671
+ case 'fields':
672
+ case 'field_values':
673
+ case 'caught':
674
+ case 'global_override':
675
+ return $this->$property;
676
+ }
677
+
678
+ throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'optin-monster-api' ), __CLASS__, $property ) );
679
+ }
680
+
681
+ }
OMAPI/Shortcode.php CHANGED
@@ -10,135 +10,144 @@
10
  class OMAPI_Shortcode {
11
 
12
  /**
13
- * Holds the class object.
14
- *
15
- * @since 1.0.0
16
- *
17
- * @var object
18
- */
19
- public static $instance;
20
 
21
  /**
22
- * Path to the file.
23
- *
24
- * @since 1.0.0
25
- *
26
- * @var string
27
- */
28
- public $file = __FILE__;
29
-
30
- /**
31
- * Holds the base class object.
32
- *
33
- * @since 1.0.0
34
- *
35
- * @var object
36
- */
37
- public $base;
38
-
39
- /**
40
- * Primary class constructor.
41
- *
42
- * @since 1.0.0
43
- */
44
- public function __construct() {
45
-
46
- // Set our object.
47
- $this->set();
48
-
49
- // Load actions and filters.
50
- add_shortcode( 'optin-monster', array( $this, 'shortcode' ) );
51
- add_shortcode( 'optin-monster-shortcode', array( $this, 'shortcode_v1' ) );
52
- add_filter( 'widget_text', 'shortcode_unautop' );
53
- add_filter( 'widget_text', 'do_shortcode' );
54
-
55
- }
56
-
57
- /**
58
- * Sets our object instance and base class instance.
59
- *
60
- * @since 1.0.0
61
- */
62
- public function set() {
63
-
64
- self::$instance = $this;
65
- $this->base = OMAPI::get_instance();
66
-
67
- }
68
-
69
- /**
70
- * Creates the shortcode for the plugin.
71
- *
72
- * @since 1.0.0
73
- *
74
- * @global object $post The current post object.
75
- *
76
- * @param array $atts Array of shortcode attributes.
77
- * @return string The optin output.
78
- */
79
- public function shortcode( $atts ) {
80
-
81
- global $post;
82
-
83
- $optin_id = false;
84
- if ( isset( $atts['id'] ) ) {
85
- $optin_id = (int) $atts['id'];
86
- } else if ( isset( $atts['slug'] ) ) {
87
- $optin = get_page_by_path( $atts['slug'], OBJECT, 'omapi' );
88
- if ( $optin ) {
89
- $optin_id = $optin->ID;
90
- }
91
- } else {
92
- // A custom attribute must have been passed. Allow it to be filtered to grab the optin ID from a custom source.
93
- $optin_id = apply_filters( 'optin_monster_api_custom_optin_id', false, $atts, $post );
94
- }
95
-
96
- // Allow the optin ID to be filtered before it is stored and used to create the optin output.
97
- $optin_id = apply_filters( 'optin_monster_api_pre_optin_id', $optin_id, $atts, $post );
98
-
99
- // If there is no optin, do nothing.
100
- if ( ! $optin_id ) {
101
- return false;
102
- }
103
 
104
- // Try to grab the stored HTML.
105
- $optin = $this->base->get_optin( $optin_id );
106
- $html = trim( html_entity_decode( stripslashes( $optin->post_content ), ENT_QUOTES ), '\'' );
107
- if ( ! $html ) {
108
- return false;
109
- }
110
-
111
- // Make sure to apply shortcode filtering.
112
- OMAPI::get_instance()->output->set_slug( $optin );
113
-
114
- // Possibly add support for Mailpoet.
115
- $mailpoet = get_post_meta( $optin->ID, '_omapi_mailpoet', true );
116
- if ( $mailpoet ) {
117
- OMAPI::get_instance()->output->wp_helper();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
 
120
- // Return the HTML.
121
- return $html;
 
 
 
 
 
122
 
123
- }
 
 
 
 
 
124
 
125
- /**
126
- * Backwards compat shortcode for v1.
127
- *
128
- * @since 1.0.0
129
- *
130
- * @global object $post The current post object.
131
- *
132
- * @param array $atts Array of shortcode attributes.
133
- * @return string The optin output.
134
- */
135
- public function shortcode_v1( $atts ) {
136
 
137
- // Run the v2 implementation.
138
- $atts['slug'] = $atts['id'];
139
- unset( $atts['id'] );
140
- return $this->shortcode( $atts );
141
 
142
- }
 
 
143
 
144
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  class OMAPI_Shortcode {
11
 
12
  /**
13
+ * Holds the class object.
14
+ *
15
+ * @since 1.0.0
16
+ *
17
+ * @var object
18
+ */
19
+ public static $instance;
20
 
21
  /**
22
+ * Path to the file.
23
+ *
24
+ * @since 1.0.0
25
+ *
26
+ * @var string
27
+ */
28
+ public $file = __FILE__;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ /**
31
+ * Holds the base class object.
32
+ *
33
+ * @since 1.0.0
34
+ *
35
+ * @var object
36
+ */
37
+ public $base;
38
+
39
+ /**
40
+ * Primary class constructor.
41
+ *
42
+ * @since 1.0.0
43
+ */
44
+ public function __construct() {
45
+
46
+ // Set our object.
47
+ $this->set();
48
+
49
+ // Load actions and filters.
50
+ add_shortcode( 'optin-monster', array( $this, 'shortcode' ) );
51
+ add_shortcode( 'optin-monster-shortcode', array( $this, 'shortcode_v1' ) );
52
+ add_filter( 'widget_text', 'shortcode_unautop' );
53
+ add_filter( 'widget_text', 'do_shortcode' );
54
+
55
+ }
56
+
57
+ /**
58
+ * Sets our object instance and base class instance.
59
+ *
60
+ * @since 1.0.0
61
+ */
62
+ public function set() {
63
+
64
+ self::$instance = $this;
65
+ $this->base = OMAPI::get_instance();
66
+
67
+ }
68
+
69
+ /**
70
+ * Creates the shortcode for the plugin.
71
+ *
72
+ * @since 1.0.0
73
+ *
74
+ * @global object $post The current post object.
75
+ *
76
+ * @param array $atts Array of shortcode attributes.
77
+ * @return string The optin output.
78
+ */
79
+ public function shortcode( $atts ) {
80
+
81
+ global $post;
82
+
83
+ // Merge default attributes with passed attributes.
84
+ $atts = shortcode_atts( array(
85
+ 'slug' => '',
86
+ 'followrules' => 'false',
87
+ // id attribute is deprecated.
88
+ 'id' => '',
89
+ ), $atts, 'optin-monster' );
90
+
91
+ $optin_id = false;
92
+ if ( ! empty( $atts['id'] ) ) {
93
+ $optin_id = absint( $atts['id'] );
94
+ } elseif ( isset( $atts['slug'] ) ) {
95
+ $optin = get_page_by_path( $atts['slug'], OBJECT, 'omapi' );
96
+ if ( $optin ) {
97
+ $optin_id = $optin->ID;
98
+ }
99
+ } else {
100
+ // A custom attribute must have been passed. Allow it to be filtered to grab the optin ID from a custom source.
101
+ $optin_id = apply_filters( 'optin_monster_api_custom_optin_id', false, $atts, $post );
102
  }
103
 
104
+ // Allow the optin ID to be filtered before it is stored and used to create the optin output.
105
+ $optin_id = apply_filters( 'optin_monster_api_pre_optin_id', $optin_id, $atts, $post );
106
+
107
+ // If there is no optin, do nothing.
108
+ if ( ! $optin_id ) {
109
+ return false;
110
+ }
111
 
112
+ // Try to grab the stored HTML.
113
+ $optin = $this->base->get_optin( $optin_id );
114
+ $html = $this->base->output->prepare_campaign( $optin );
115
+ if ( ! $html ) {
116
+ return false;
117
+ }
118
 
119
+ if (
120
+ wp_validate_boolean( $atts['followrules'] )
121
+ // Do OMAPI Output rules check.
122
+ && ! OMAPI_Rules::check_shortcode( $optin, $post->ID )
123
+ ) {
124
+ return false;
125
+ }
 
 
 
 
126
 
127
+ // Make sure to apply shortcode filtering.
128
+ $this->base->output->set_slug( $optin );
 
 
129
 
130
+ // Return the HTML.
131
+ return $html;
132
+ }
133
 
134
+ /**
135
+ * Backwards compat shortcode for v1.
136
+ *
137
+ * @since 1.0.0
138
+ *
139
+ * @global object $post The current post object.
140
+ *
141
+ * @param array $atts Array of shortcode attributes.
142
+ * @return string The optin output.
143
+ */
144
+ public function shortcode_v1( $atts ) {
145
+
146
+ // Run the v2 implementation.
147
+ $atts['slug'] = $atts['id'];
148
+ unset( $atts['id'] );
149
+ return $this->shortcode( $atts );
150
+
151
+ }
152
+
153
+ }
OMAPI/Utils.php CHANGED
@@ -22,4 +22,37 @@ class OMAPI_Utils {
22
  return 'post' === $type || 'inline' === $type;
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
22
  return 'post' === $type || 'inline' === $type;
23
  }
24
 
25
+ public static function item_in_field( $item, $fields, $field ) {
26
+ return $item
27
+ && is_array( $fields )
28
+ && ! empty( $fields[ $field ] )
29
+ && in_array( $item, (array) $fields[ $field ] );
30
+ }
31
+
32
+ public static function field_not_empty_array( $fields, $field ) {
33
+ if ( empty( $fields[ $field ] ) ) {
34
+ return false;
35
+ }
36
+
37
+ $values = array_values( (array) $fields[ $field ] );
38
+ $values = array_filter( $values );
39
+
40
+ return ! empty( $values ) ? $values : false;
41
+ }
42
+
43
+ /**
44
+ * WordPress utility functions.
45
+ */
46
+
47
+ public static function is_front_or_search() {
48
+ return is_front_page() || is_home() || is_search();
49
+ }
50
+
51
+ public static function is_term_archive( $term_id, $taxonomy ) {
52
+ if ( ! $term_id ) {
53
+ return false;
54
+ }
55
+ return 'post_tag' === $taxonomy && is_tag( $term_id ) || is_tax( $taxonomy, $term_id );
56
+ }
57
+
58
  }
includes/class-am-notification.php CHANGED
@@ -10,7 +10,7 @@ if ( ! class_exists( 'AM_Notification' ) ) {
10
  * @author Benjamin Rojas
11
  * @license GPL-2.0+
12
  * @copyright Copyright (c) 2017, Retyp LLC
13
- * @version 1.0.0
14
  */
15
  class AM_Notification {
16
  /**
@@ -197,15 +197,15 @@ if ( ! class_exists( 'AM_Notification' ) ) {
197
  $dismissable = get_post_meta( $notification->ID, 'dismissable', true );
198
  $type = get_post_meta( $notification->ID, 'type', true );
199
  ?>
200
- <div class="am-notification am-notification-<?php echo $notification->ID; ?> notice notice-<?php echo $type; ?><?php echo $dismissable ? ' is-dismissible' : ''; ?>">
201
- <?php echo $notification->post_content; ?>
202
  </div>
203
  <script type="text/javascript">
204
  jQuery(document).ready(function ($) {
205
- $(document).on('click', '.am-notification-<?php echo $notification->ID; ?> button.notice-dismiss', function (event) {
206
  $.post(ajaxurl, {
207
  action: 'am_notification_dismiss',
208
- notification_id: '<?php echo $notification->ID; ?>'
209
  });
210
  });
211
  });
10
  * @author Benjamin Rojas
11
  * @license GPL-2.0+
12
  * @copyright Copyright (c) 2017, Retyp LLC
13
+ * @version 1.0.6
14
  */
15
  class AM_Notification {
16
  /**
197
  $dismissable = get_post_meta( $notification->ID, 'dismissable', true );
198
  $type = get_post_meta( $notification->ID, 'type', true );
199
  ?>
200
+ <div class="am-notification am-notification-<?php echo absint( $notification->ID ); ?> notice notice-<?php echo esc_attr( $type ); ?><?php echo $dismissable ? ' is-dismissible' : ''; ?>">
201
+ <?php echo wp_kses_post( $notification->post_content ); ?>
202
  </div>
203
  <script type="text/javascript">
204
  jQuery(document).ready(function ($) {
205
+ $(document).on('click', '.am-notification-<?php echo absint( $notification->ID ); ?> button.notice-dismiss', function (event) {
206
  $.post(ajaxurl, {
207
  action: 'am_notification_dismiss',
208
+ notification_id: '<?php echo absint( $notification->ID ); ?>'
209
  });
210
  });
211
  });
optin-monster-wp-api.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: OptinMonster API plugin to connect your WordPress site to your OptinMonster account.
6
  * Author: OptinMonster Team
7
  * Author URI: https://optinmonster.com
8
- * Version: 1.4.2
9
  * Text Domain: optin-monster-api
10
  * Domain Path: languages
11
  *
@@ -60,7 +60,7 @@ class OMAPI {
60
  *
61
  * @var string
62
  */
63
- public $version = '1.4.2';
64
 
65
  /**
66
  * The name of the plugin.
@@ -89,6 +89,97 @@ class OMAPI {
89
  */
90
  public $file = __FILE__;
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  /**
93
  * Primary class constructor.
94
  *
@@ -143,7 +234,7 @@ class OMAPI {
143
 
144
  // Define necessary plugin constants.
145
  if ( ! defined( 'OPTINMONSTER_APIJS_URL' ) ) {
146
- define( 'OPTINMONSTER_APIJS_URL', 'https://a.optmstr.com/app/js/api.min.js' );
147
  }
148
 
149
  if ( ! defined( 'OPTINMONSTER_APP_URL' ) ) {
@@ -402,12 +493,8 @@ class OMAPI {
402
  *
403
  * @return bool
404
  */
405
- public function is_legacy_active() {
406
- if( class_exists( 'Optin_Monster' ) ) {
407
- return true;
408
- }
409
-
410
- return false;
411
  }
412
 
413
  /**
@@ -417,11 +504,8 @@ class OMAPI {
417
  *
418
  * @return bool
419
  */
420
- public function is_woocommerce_active() {
421
- if (class_exists( 'WooCommerce' ) ) {
422
- return true;
423
- }
424
- return false;
425
  }
426
 
427
  /**
@@ -431,8 +515,8 @@ class OMAPI {
431
  *
432
  * @return bool
433
  */
434
- public function is_mailpoet_active() {
435
- return ( class_exists( 'WYSIJA_object' ) || class_exists( '\\MailPoet\\Config\\Initializer' ) );
436
  }
437
 
438
  /**
5
  * Description: OptinMonster API plugin to connect your WordPress site to your OptinMonster account.
6
  * Author: OptinMonster Team
7
  * Author URI: https://optinmonster.com
8
+ * Version: 1.5.1
9
  * Text Domain: optin-monster-api
10
  * Domain Path: languages
11
  *
60
  *
61
  * @var string
62
  */
63
+ public $version = '1.5.1';
64
 
65
  /**
66
  * The name of the plugin.
89
  */
90
  public $file = __FILE__;
91
 
92
+ /**
93
+ * OMAPI_Ajax object
94
+ *
95
+ * @var OMAPI_Ajax
96
+ */
97
+ public $ajax;
98
+
99
+ /**
100
+ * OMAPI_Type object
101
+ *
102
+ * @var OMAPI_Type
103
+ */
104
+ public $type;
105
+
106
+ /**
107
+ * OMAPI_Output object
108
+ *
109
+ * @var OMAPI_Output
110
+ */
111
+ public $output;
112
+
113
+ /**
114
+ * OMAPI_Shortcode object
115
+ *
116
+ * @var OMAPI_Shortcode
117
+ */
118
+ public $shortcode;
119
+
120
+ /**
121
+ * OMAPI_Actions object (loaded only in the admin)
122
+ *
123
+ * @var OMAPI_Actions
124
+ */
125
+ public $actions;
126
+
127
+ /**
128
+ * OMAPI_Menu object (loaded only in the admin)
129
+ *
130
+ * @var OMAPI_Menu
131
+ */
132
+ public $menu;
133
+
134
+ /**
135
+ * OMAPI_Content object (loaded only in the admin)
136
+ *
137
+ * @var OMAPI_Content
138
+ */
139
+ public $content;
140
+
141
+ /**
142
+ * OMAPI_Save object (loaded only in the admin)
143
+ *
144
+ * @var OMAPI_Save
145
+ */
146
+ public $save;
147
+
148
+ /**
149
+ * OMAPI_Refresh object (loaded only in the admin)
150
+ *
151
+ * @var OMAPI_Refresh
152
+ */
153
+ public $refresh;
154
+
155
+ /**
156
+ * OMAPI_Validate object (loaded only in the admin)
157
+ *
158
+ * @var OMAPI_Validate
159
+ */
160
+ public $validate;
161
+
162
+ /**
163
+ * OMAPI_Welcome object (loaded only in the admin)
164
+ *
165
+ * @var OMAPI_Welcome
166
+ */
167
+ public $welcome;
168
+
169
+ /**
170
+ * OMAPI_Review object (loaded only in the admin)
171
+ *
172
+ * @var OMAPI_Review
173
+ */
174
+ public $review;
175
+
176
+ /**
177
+ * AM_Notification object (loaded only in the admin)
178
+ *
179
+ * @var AM_Notification
180
+ */
181
+ public $notifications;
182
+
183
  /**
184
  * Primary class constructor.
185
  *
234
 
235
  // Define necessary plugin constants.
236
  if ( ! defined( 'OPTINMONSTER_APIJS_URL' ) ) {
237
+ define( 'OPTINMONSTER_APIJS_URL', 'https://a.optmnstr.com/app/js/api.min.js' );
238
  }
239
 
240
  if ( ! defined( 'OPTINMONSTER_APP_URL' ) ) {
493
  *
494
  * @return bool
495
  */
496
+ public static function is_legacy_active() {
497
+ return class_exists( 'Optin_Monster' );
 
 
 
 
498
  }
499
 
500
  /**
504
  *
505
  * @return bool
506
  */
507
+ public static function is_woocommerce_active() {
508
+ return class_exists( 'WooCommerce' );
 
 
 
509
  }
510
 
511
  /**
515
  *
516
  * @return bool
517
  */
518
+ public static function is_mailpoet_active() {
519
+ return class_exists( 'WYSIJA_object' ) || class_exists( '\\MailPoet\\Config\\Initializer' );
520
  }
521
 
522
  /**
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: optinmonster, griffinjt, smub
3
  Tags: wordpress popup, popup, lightbox popup, mailchimp, aweber, campaign monitor, constant contact, exit-intent, madmimi, infusionsoft, getresponse, hubspot, marketo, activecampaign, pardot, totalsend, emma, icontact, mailerlite, mailpoet, google analytics, pop over, optin forms, email list, subscribers, wordpress popup form, lightbox, wordpress popups, popups, lightbox popups, optin form, wordpress optin form, sidebar optin form, sidebar optin, sidebar form, wordpress overlay popup, wordpress popup plugin, popup plugin, wordpress lightbox optin, wordpress lightbox optin form, after post optin form, wordpress after post optin form, after post optin form plugin, lightbox popup plugin, wordpress popup solution, exit intent, exit-intent, optinmonster, optin monster, optin-monster, mobile popup, mobile popups, mobile optin forms, mobile optins, lightbox optins, wordpress mobile popup, wordpress mobile popups, wordpress mobile optin forms, wordpress lightbox optins, lead gen, lead generation, wordpress lead generation, lead generation wordpress, wordpress lead gen, fullscreen, welcome gate, interstitial
4
  Requires at least: 3.5.1
5
- Tested up to: 4.9.6
6
  Requires PHP: 5.3
7
- Stable tag: 1.4.2
8
  License: GNU General Public License v2.0 or later
9
 
10
  OptinMonster helps you grow your email list by converting visitors into subscribers and customers. Get more email subscribers now!
@@ -15,7 +15,7 @@ OptinMonster helps you grow your email list by converting visitors into subscrib
15
  Did you know that over 70% of website visitors who leave your website will never return? Why? Because most people find your blog, read, and leave (that's just a natural pattern). Wouldn't it be nice if you can convert some of those people to subscribe to your blog? That's where <a href="https://optinmonster.com" rel="friend" title="OptinMonster">OptinMonster</a> can help. OptinMonster helps you grow your email list and get more subscribers with popup and other types of high converting optin forms.
16
 
17
  > <strong>OptinMonster App</strong><br>
18
- > OptinMonster is a standalone application that integrates with all web platforms including WordPress. You must have an OptinMonster account in order to take advantage of this plugin. <a href="https://optinmonster.com/pricing/" rel="friend" title="OptinMonster Plans">Click here to create your account.</a>
19
 
20
  OptinMonster comes with an easy to use form builder that allows you to create beautiful optin forms that are proven to convert. You can create various type of campaigns including WordPress popup forms, floating header and footer bars, slide-ins also known as scroll triggered boxes, sidebar forms, after post forms, in-line forms, mobile-specific forms, welcome gates and more.
21
 
@@ -24,7 +24,7 @@ Using OptinMonster forms combined with our exit-intent technology, page-level ta
24
  Let's take a look at how OptinMonster can help you get more email subscribers.
25
 
26
  > <strong>OptinMonster App</strong><br>
27
- > OptinMonster is a standalone application that integrates with all web platforms including WordPress. You must have an OptinMonster account in order to take advantage of this plugin. <a href="https://optinmonster.com/pricing/" rel="friend" title="OptinMonster Plans">Click here to create your account.</a>
28
 
29
  = OptinMonster Builder + Optin Forms Templates =
30
 
@@ -144,14 +144,14 @@ OptinMonster® and Exit-Intent® are registered trademarks of Retyp, LLC.
144
 
145
  = I downloaded this plugin but don't have an OptinMonster account. How can I get one? =
146
 
147
- You can sign up for an OptinMonster account by <a href="https://optinmonster.com/pricing/" rel="friend" title="OptinMonster Plans and Pricing">visiting our Pricing page</a> and choosing the account that best suits your needs.
148
 
149
  == Screenshots ==
150
 
151
 
152
  == Notes ==
153
 
154
- OptinMonster is the <a href="https://optinmonster.com" rel="friend" title="OptinMonster">best WordPress lead generation and WordPress popup plugin solution</a> on the market. No other WordPress popup plugin or WordPress optin form solution compares to OptinMonster and features it offers.
155
 
156
  = Testimonial =
157
 
@@ -160,6 +160,13 @@ OptinMonster is the <a href="https://optinmonster.com" rel="friend" title="Optin
160
 
161
  == Changelog ==
162
 
 
 
 
 
 
 
 
163
  = 1.4.2 =
164
  * Fixed a bug that caused issues with PHP versions under 5.6.
165
 
2
  Contributors: optinmonster, griffinjt, smub
3
  Tags: wordpress popup, popup, lightbox popup, mailchimp, aweber, campaign monitor, constant contact, exit-intent, madmimi, infusionsoft, getresponse, hubspot, marketo, activecampaign, pardot, totalsend, emma, icontact, mailerlite, mailpoet, google analytics, pop over, optin forms, email list, subscribers, wordpress popup form, lightbox, wordpress popups, popups, lightbox popups, optin form, wordpress optin form, sidebar optin form, sidebar optin, sidebar form, wordpress overlay popup, wordpress popup plugin, popup plugin, wordpress lightbox optin, wordpress lightbox optin form, after post optin form, wordpress after post optin form, after post optin form plugin, lightbox popup plugin, wordpress popup solution, exit intent, exit-intent, optinmonster, optin monster, optin-monster, mobile popup, mobile popups, mobile optin forms, mobile optins, lightbox optins, wordpress mobile popup, wordpress mobile popups, wordpress mobile optin forms, wordpress lightbox optins, lead gen, lead generation, wordpress lead generation, lead generation wordpress, wordpress lead gen, fullscreen, welcome gate, interstitial
4
  Requires at least: 3.5.1
5
+ Tested up to: 4.9.8
6
  Requires PHP: 5.3
7
+ Stable tag: 1.5.1
8
  License: GNU General Public License v2.0 or later
9
 
10
  OptinMonster helps you grow your email list by converting visitors into subscribers and customers. Get more email subscribers now!
15
  Did you know that over 70% of website visitors who leave your website will never return? Why? Because most people find your blog, read, and leave (that's just a natural pattern). Wouldn't it be nice if you can convert some of those people to subscribe to your blog? That's where <a href="https://optinmonster.com" rel="friend" title="OptinMonster">OptinMonster</a> can help. OptinMonster helps you grow your email list and get more subscribers with popup and other types of high converting optin forms.
16
 
17
  > <strong>OptinMonster App</strong><br>
18
+ > OptinMonster is a standalone application that integrates with all web platforms including WordPress. You must have an OptinMonster account in order to take advantage of this plugin. <a href="https://optinmonster.com/wp/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpreadme" rel="friend" title="Click here to learn more about OptinMonster">Click here to learn more about OptinMonster.</a>
19
 
20
  OptinMonster comes with an easy to use form builder that allows you to create beautiful optin forms that are proven to convert. You can create various type of campaigns including WordPress popup forms, floating header and footer bars, slide-ins also known as scroll triggered boxes, sidebar forms, after post forms, in-line forms, mobile-specific forms, welcome gates and more.
21
 
24
  Let's take a look at how OptinMonster can help you get more email subscribers.
25
 
26
  > <strong>OptinMonster App</strong><br>
27
+ > OptinMonster is a standalone application that integrates with all web platforms including WordPress. You must have an OptinMonster account in order to take advantage of this plugin. <a href="https://optinmonster.com/wp/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpreadme" rel="friend" title="Click here to learn more about OptinMonster">Click here to learn more about OptinMonster.</a>
28
 
29
  = OptinMonster Builder + Optin Forms Templates =
30
 
144
 
145
  = I downloaded this plugin but don't have an OptinMonster account. How can I get one? =
146
 
147
+ You can sign up for an OptinMonster account by <a href="https://optinmonster.com/wp/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpreadme" rel="friend" title="Click here to learn more about OptinMonster">visiting our overview page</a> and following the instructions on the screen.
148
 
149
  == Screenshots ==
150
 
151
 
152
  == Notes ==
153
 
154
+ OptinMonster is the <a href="https://optinmonster.com" rel="friend" title="OptinMonster">best WordPress lead generation and WordPress popup plugin solution</a> on the market. No other WordPress popup plugin or WordPress optin form solution compares to OptinMonster and the features it offers.
155
 
156
  = Testimonial =
157
 
160
 
161
  == Changelog ==
162
 
163
+ = 1.5.1 =
164
+ * Fixed a possible security issue with admin notices.
165
+ * Updated outdated URLs in the admin.
166
+
167
+ = 1.5.0 =
168
+ * Refactored WordPress rules system, and a new `[optin-monster]` shortcode parameter, `followrules=true`. This means if you have specific WordPress display rules (e.g. which categories/posts/pages to display the campaign), and use the shortcode to output the campaign, you can have the shortcode follow the rules you have setup. Example shortcode usage: `[optin-monster slug="XXXXXXXXXXXXXXXXXXXX" followrules=true]`
169
+
170
  = 1.4.2 =
171
  * Fixed a bug that caused issues with PHP versions under 5.6.
172