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

Version Description

  • Fixed a bug that occasionally prevented changes in campaigns via the OptinMonster App to not properly sync to the plugin, due to cached responses.
Download this release

Release Info

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

Code changes from version 1.9.11 to 1.9.14

CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
  # Changelog
2
  All notable changes to the OptinMonster plugin will be documented in this file.
3
 
 
 
 
 
 
 
 
 
 
4
  ### 1.9.11
5
  * Fixed a bug that caused too many redirects in the admin when clicking on certain plugin settings links.
6
  * Removed a plugin action link that was not used.
1
  # Changelog
2
  All notable changes to the OptinMonster plugin will be documented in this file.
3
 
4
+ ### 1.9.14
5
+ * Fixed a bug that occasionally prevented changes in campaigns via the OptinMonster App to not properly sync to the plugin, due to cached responses.
6
+
7
+ ### 1.9.13
8
+ * Fixed a bug that caused campaigns to be incorrectly referenced in the admin dashboard.
9
+
10
+ ### 1.9.12
11
+ * Fixed a bug where the `Access-Control-Allow-Headers` was being improperly reset for REST requests.
12
+
13
  ### 1.9.11
14
  * Fixed a bug that caused too many redirects in the admin when clicking on certain plugin settings links.
15
  * Removed a plugin action link that was not used.
OMAPI/Actions.php CHANGED
@@ -188,7 +188,7 @@ class OMAPI_Actions {
188
  */
189
  public function cookies() {
190
 
191
- $optins = $this->base->get_optins();
192
  if ( ! empty( $optins ) ) {
193
  foreach ( (array) $optins as $optin ) {
194
  if ( $optin ) {
188
  */
189
  public function cookies() {
190
 
191
+ $optins = $this->base->get_optins( array( 'post_status' => 'any' ) );
192
  if ( ! empty( $optins ) ) {
193
  foreach ( (array) $optins as $optin ) {
194
  if ( $optin ) {
OMAPI/Refresh.php CHANGED
@@ -199,9 +199,10 @@ class OMAPI_Refresh {
199
  * @return WP_Error|bool True if successful.
200
  */
201
  public function sync( $campaign_id, $is_legacy ) {
202
- $path = "for-wp/{$campaign_id}";
 
203
  if ( $is_legacy ) {
204
- $path .= '?legacy=true';
205
  }
206
 
207
  $this->api = OMAPI_Api::build( 'v1', $path, 'GET' );
199
  * @return WP_Error|bool True if successful.
200
  */
201
  public function sync( $campaign_id, $is_legacy ) {
202
+ $time = time();
203
+ $path = "for-wp/{$campaign_id}?t={$time}";
204
  if ( $is_legacy ) {
205
+ $path .= '&legacy=true';
206
  }
207
 
208
  $this->api = OMAPI_Api::build( 'v1', $path, 'GET' );
OMAPI/RestApi.php CHANGED
@@ -3,6 +3,9 @@
3
  * Rest API Class, where we register/execute any REST API Routes
4
  *
5
  * @since 1.8.0
 
 
 
6
  */
7
 
8
  // Exit if accessed directly.
@@ -35,6 +38,20 @@ class OMAPI_RestApi {
35
  */
36
  protected $namespace = 'omapp/v1';
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  public function __construct() {
39
  $this->base = OMAPI::get_instance();
40
  $this->register_rest_routes();
@@ -49,9 +66,13 @@ class OMAPI_RestApi {
49
  */
50
  public function register_rest_routes() {
51
 
52
- add_filter( 'rest_pre_serve_request', array( $this, 'allow_headers' ) );
 
 
 
 
53
 
54
- // Fetch some quick info about this WP installation
55
  register_rest_route(
56
  $this->namespace,
57
  'info',
@@ -97,7 +118,7 @@ class OMAPI_RestApi {
97
  )
98
  );
99
 
100
- // Route for updating the campaign data
101
  // TODO: Keeping for future settings revamp.
102
  register_rest_route(
103
  $this->namespace,
@@ -121,7 +142,7 @@ class OMAPI_RestApi {
121
  )
122
  );
123
 
124
- // Route for fetching the campaign data
125
  // TODO: Keeping for future settings revamp.
126
  register_rest_route(
127
  $this->namespace,
@@ -134,8 +155,54 @@ class OMAPI_RestApi {
134
  );
135
  }
136
 
137
- public function allow_headers() {
138
- header( 'Access-Control-Allow-Headers: X-OptinMonster-ApiKey, content-type' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
  /**
@@ -143,7 +210,7 @@ class OMAPI_RestApi {
143
  *
144
  * @since 1.9.10
145
  *
146
- * @param WP_REST_Request The REST Request
147
  * @return WP_REST_Response The API Response
148
  */
149
  public function refresh_campaigns( $request ) {
@@ -161,7 +228,7 @@ class OMAPI_RestApi {
161
  *
162
  * @since 1.9.10
163
  *
164
- * @param WP_REST_Request The REST Request
165
  *
166
  * @return WP_REST_Response
167
  */
@@ -175,7 +242,7 @@ class OMAPI_RestApi {
175
  *
176
  * @since 1.9.10
177
  *
178
- * @param WP_REST_Request The REST Request
179
  *
180
  * @return WP_REST_Response
181
  */
@@ -195,7 +262,7 @@ class OMAPI_RestApi {
195
  *
196
  * @since 1.9.10
197
  *
198
- * @param WP_REST_Request The REST Request
199
  * @return WP_REST_Response The API Response
200
  */
201
  public function sync_campaign( $request ) {
@@ -204,7 +271,7 @@ class OMAPI_RestApi {
204
  if ( empty( $campaign_id ) ) {
205
  return new WP_REST_Response(
206
  array( 'message' => esc_html__( 'No campaign ID given.', 'optin-monster-api' ) ),
207
- 401
208
  );
209
  }
210
 
@@ -221,7 +288,7 @@ class OMAPI_RestApi {
221
  *
222
  * @since 1.9.10
223
  *
224
- * @param WP_REST_Request The REST Request
225
  * @return WP_REST_Response The API Response
226
  */
227
  public function get_campaign_data( $request ) {
@@ -230,7 +297,7 @@ class OMAPI_RestApi {
230
  if ( empty( $campaign_id ) ) {
231
  return new WP_REST_Response(
232
  array( 'message' => esc_html__( 'No campaign ID given.', 'optin-monster-api' ) ),
233
- 401
234
  );
235
  }
236
 
@@ -238,13 +305,14 @@ class OMAPI_RestApi {
238
  if ( empty( $campaign->ID ) ) {
239
  return new WP_REST_Response(
240
  array(
 
241
  'message' => sprintf( esc_html__( 'Could not find campaign by given ID: %s.', 'optin-monster-api' ), $campaign_id ),
242
  ),
243
- 401
244
  );
245
  }
246
 
247
- // Get Campaigns Data
248
  $data = $this->base->collect_campaign_data( $campaign );
249
  $data = apply_filters( 'optin_monster_api_setting_ui_data_for_campaign', $data, $campaign );
250
 
@@ -256,20 +324,20 @@ class OMAPI_RestApi {
256
  *
257
  * @since 1.9.10
258
  *
259
- * @param WP_REST_Request The REST Request
260
  *
261
  * @return WP_REST_Response The API Response
262
  */
263
  public function update_campaign_data( $request ) {
264
  $campaign_id = $request->get_param( 'id' );
265
 
266
- // If no campaign_id, return error
267
 
268
  $campaign = $this->base->get_optin_by_slug( $campaign_id );
269
 
270
- // If no campaign, return 404
271
 
272
- // Get the Request Params
273
  $fields = json_decode( $request->get_body(), true );
274
 
275
  if ( ! empty( $fields['taxonomies'] ) ) {
@@ -288,8 +356,8 @@ class OMAPI_RestApi {
288
  : array();
289
  }
290
 
291
- // Escape Parameters as needed
292
- // Update Post Meta
293
  foreach ( $fields as $key => $value ) {
294
  $value = $this->sanitize( $value );
295
 
@@ -310,7 +378,7 @@ class OMAPI_RestApi {
310
  *
311
  * @since 1.9.10
312
  *
313
- * @param WP_REST_Request The REST Request
314
  * @return WP_REST_Response The API Response
315
  */
316
  public function get_campaigns_data( $request ) {
@@ -320,7 +388,7 @@ class OMAPI_RestApi {
320
  $this->base->refresh->refresh();
321
  }
322
 
323
- // Get Campaigns Data
324
  $campaigns = $this->base->get_optins();
325
  $campaigns = ! empty( $campaigns ) ? $campaigns : array();
326
  $campaign_data = array();
@@ -332,7 +400,7 @@ class OMAPI_RestApi {
332
  $woo = $this->base->is_woocommerce_active();
333
  $mp = $this->base->is_mailpoet_active();
334
 
335
- // Get Taxonomies Data
336
  $taxonomies = get_taxonomies( array( 'public' => true ), 'objects' );
337
  $taxonomies = apply_filters( 'optin_monster_api_setting_ui_taxonomies', $taxonomies );
338
  $taxonomy_map = array();
@@ -365,7 +433,7 @@ class OMAPI_RestApi {
365
  );
366
  }
367
 
368
- // Get "Config" data
369
  $config = array(
370
  'hasMailPoet' => $mp,
371
  'hasWooCommerce' => $woo,
@@ -373,7 +441,7 @@ class OMAPI_RestApi {
373
  );
374
 
375
  // Posts query.
376
- $post_types = implode( '","', get_post_types( array( 'public' => true ) ) );
377
  $posts = $wpdb->get_results( "SELECT ID AS `value`, post_title AS `name` FROM {$wpdb->prefix}posts WHERE post_type IN (\"{$post_types}\") AND post_status IN('publish', 'future') ORDER BY post_title ASC", ARRAY_A );
378
 
379
  $response_data = apply_filters(
@@ -395,9 +463,9 @@ class OMAPI_RestApi {
395
  *
396
  * @since 1.9.10
397
  *
398
- * @param mixed $value
399
  *
400
- * @return mixed
401
  */
402
  public function sanitize( $value ) {
403
  if ( empty( $value ) ) {
@@ -418,14 +486,14 @@ class OMAPI_RestApi {
418
  *
419
  * @since 1.9.10
420
  *
421
- * @param WP_REST_Request The REST Request
422
  *
423
  * @return bool
424
  */
425
  public function has_valid_api_key( $request ) {
426
  $header = $request->get_header( 'X-OptinMonster-ApiKey' );
427
 
428
- // Use this API Key to validate
429
  if ( ! $this->validate_api_key( $header ) ) {
430
  return new WP_Error(
431
  'omapp_rest_forbidden',
@@ -444,7 +512,7 @@ class OMAPI_RestApi {
444
  *
445
  * @since 1.9.10
446
  *
447
- * @param WP_REST_Request The REST Request
448
  *
449
  * @return bool
450
  */
@@ -459,7 +527,7 @@ class OMAPI_RestApi {
459
  *
460
  * @since 1.8.0
461
  *
462
- * @param string $api_key
463
  *
464
  * @return bool True if the Key can be validated
465
  */
3
  * Rest API Class, where we register/execute any REST API Routes
4
  *
5
  * @since 1.8.0
6
+ *
7
+ * @package OMAPI
8
+ * @author Justin Sternberg
9
  */
10
 
11
  // Exit if accessed directly.
38
  */
39
  protected $namespace = 'omapp/v1';
40
 
41
+ /**
42
+ * Whether Access-Control-Allow-Headers header was set/updated by us.
43
+ *
44
+ * @since 1.9.12
45
+ *
46
+ * @var bool
47
+ */
48
+ protected $allow_header_set = false;
49
+
50
+ /**
51
+ * Build our object.
52
+ *
53
+ * @since 1.8.0
54
+ */
55
  public function __construct() {
56
  $this->base = OMAPI::get_instance();
57
  $this->register_rest_routes();
66
  */
67
  public function register_rest_routes() {
68
 
69
+ // Filter only available in WP 5.5.
70
+ add_filter( 'rest_allowed_cors_headers', array( $this, 'set_allow_headers' ), 999 );
71
+
72
+ // Fall-through to check if we still need to set header (WP < 5.5)
73
+ add_filter( 'rest_send_nocache_headers', array( $this, 'fallback_set_allow_headers' ), 999 );
74
 
75
+ // Fetch some quick info about this WP installation.
76
  register_rest_route(
77
  $this->namespace,
78
  'info',
118
  )
119
  );
120
 
121
+ // Route for updating the campaign data.
122
  // TODO: Keeping for future settings revamp.
123
  register_rest_route(
124
  $this->namespace,
142
  )
143
  );
144
 
145
+ // Route for fetching the campaign data.
146
  // TODO: Keeping for future settings revamp.
147
  register_rest_route(
148
  $this->namespace,
155
  );
156
  }
157
 
158
+ /**
159
+ * Filters the list of request headers that are allowed for CORS requests,
160
+ * and ensures our API key is allowed.
161
+ *
162
+ * @since 1.9.12
163
+ *
164
+ * @param string[] $allow_headers The list of headers to allow.
165
+ *
166
+ * @return string[]
167
+ */
168
+ public function set_allow_headers( $allow_headers ) {
169
+ $allow_headers[] = 'X-OptinMonster-ApiKey';
170
+ $this->allow_header_set = true;
171
+
172
+ // remove fall-through.
173
+ remove_filter( 'rest_send_nocache_headers', array( $this, 'fallback_set_allow_headers' ), 999 );
174
+
175
+ return $allow_headers;
176
+ }
177
+
178
+ /**
179
+ * Fallback to make sure we set the allow headers.
180
+ *
181
+ * @since 1.9.12
182
+ *
183
+ * @param bool $rest_send_nocache_headers Whether to send no-cache headers.
184
+ * We ignore this, because we're simply using this
185
+ * as an action hook.
186
+ *
187
+ * @return bool Unchanged result.
188
+ */
189
+ function fallback_set_allow_headers( $rest_send_nocache_headers ) {
190
+ if ( ! $this->allow_header_set && ! headers_sent() ) {
191
+ foreach ( headers_list() as $header ) {
192
+ if ( 0 === strpos( $header, 'Access-Control-Allow-Headers: ' ) ) {
193
+
194
+ list( $key, $value ) = explode( 'Access-Control-Allow-Headers: ', $header );
195
+ if ( false === strpos( $value, 'X-OptinMonster-ApiKey' ) ) {
196
+ header( 'Access-Control-Allow-Headers: ' . $value . ', X-OptinMonster-ApiKey' );
197
+ }
198
+
199
+ $this->allow_header_set = true;
200
+ break;
201
+ }
202
+ }
203
+ }
204
+
205
+ return $rest_send_nocache_headers;
206
  }
207
 
208
  /**
210
  *
211
  * @since 1.9.10
212
  *
213
+ * @param WP_REST_Request $request The REST Request.
214
  * @return WP_REST_Response The API Response
215
  */
216
  public function refresh_campaigns( $request ) {
228
  *
229
  * @since 1.9.10
230
  *
231
+ * @param WP_REST_Request $request The REST Request.
232
  *
233
  * @return WP_REST_Response
234
  */
242
  *
243
  * @since 1.9.10
244
  *
245
+ * @param WP_REST_Request $request The REST Request.
246
  *
247
  * @return WP_REST_Response
248
  */
262
  *
263
  * @since 1.9.10
264
  *
265
+ * @param WP_REST_Request $request The REST Request.
266
  * @return WP_REST_Response The API Response
267
  */
268
  public function sync_campaign( $request ) {
271
  if ( empty( $campaign_id ) ) {
272
  return new WP_REST_Response(
273
  array( 'message' => esc_html__( 'No campaign ID given.', 'optin-monster-api' ) ),
274
+ 400
275
  );
276
  }
277
 
288
  *
289
  * @since 1.9.10
290
  *
291
+ * @param WP_REST_Request $request The REST Request.
292
  * @return WP_REST_Response The API Response
293
  */
294
  public function get_campaign_data( $request ) {
297
  if ( empty( $campaign_id ) ) {
298
  return new WP_REST_Response(
299
  array( 'message' => esc_html__( 'No campaign ID given.', 'optin-monster-api' ) ),
300
+ 400
301
  );
302
  }
303
 
305
  if ( empty( $campaign->ID ) ) {
306
  return new WP_REST_Response(
307
  array(
308
+ /* translators: %s: the campaign post id. */
309
  'message' => sprintf( esc_html__( 'Could not find campaign by given ID: %s.', 'optin-monster-api' ), $campaign_id ),
310
  ),
311
+ 404
312
  );
313
  }
314
 
315
+ // Get Campaigns Data.
316
  $data = $this->base->collect_campaign_data( $campaign );
317
  $data = apply_filters( 'optin_monster_api_setting_ui_data_for_campaign', $data, $campaign );
318
 
324
  *
325
  * @since 1.9.10
326
  *
327
+ * @param WP_REST_Request $request The REST Request.
328
  *
329
  * @return WP_REST_Response The API Response
330
  */
331
  public function update_campaign_data( $request ) {
332
  $campaign_id = $request->get_param( 'id' );
333
 
334
+ // If no campaign_id, return error.
335
 
336
  $campaign = $this->base->get_optin_by_slug( $campaign_id );
337
 
338
+ // If no campaign, return 404.
339
 
340
+ // Get the Request Params.
341
  $fields = json_decode( $request->get_body(), true );
342
 
343
  if ( ! empty( $fields['taxonomies'] ) ) {
356
  : array();
357
  }
358
 
359
+ // Escape Parameters as needed.
360
+ // Update Post Meta.
361
  foreach ( $fields as $key => $value ) {
362
  $value = $this->sanitize( $value );
363
 
378
  *
379
  * @since 1.9.10
380
  *
381
+ * @param WP_REST_Request $request The REST Request.
382
  * @return WP_REST_Response The API Response
383
  */
384
  public function get_campaigns_data( $request ) {
388
  $this->base->refresh->refresh();
389
  }
390
 
391
+ // Get Campaigns Data.
392
  $campaigns = $this->base->get_optins();
393
  $campaigns = ! empty( $campaigns ) ? $campaigns : array();
394
  $campaign_data = array();
400
  $woo = $this->base->is_woocommerce_active();
401
  $mp = $this->base->is_mailpoet_active();
402
 
403
+ // Get Taxonomies Data.
404
  $taxonomies = get_taxonomies( array( 'public' => true ), 'objects' );
405
  $taxonomies = apply_filters( 'optin_monster_api_setting_ui_taxonomies', $taxonomies );
406
  $taxonomy_map = array();
433
  );
434
  }
435
 
436
+ // Get "Config" data.
437
  $config = array(
438
  'hasMailPoet' => $mp,
439
  'hasWooCommerce' => $woo,
441
  );
442
 
443
  // Posts query.
444
+ $post_types = sanitize_text_field( implode( '","', get_post_types( array( 'public' => true ) ) ) );
445
  $posts = $wpdb->get_results( "SELECT ID AS `value`, post_title AS `name` FROM {$wpdb->prefix}posts WHERE post_type IN (\"{$post_types}\") AND post_status IN('publish', 'future') ORDER BY post_title ASC", ARRAY_A );
446
 
447
  $response_data = apply_filters(
463
  *
464
  * @since 1.9.10
465
  *
466
+ * @param mixed $value The value to sanitize.
467
  *
468
+ * @return mixed The sanitized value.
469
  */
470
  public function sanitize( $value ) {
471
  if ( empty( $value ) ) {
486
  *
487
  * @since 1.9.10
488
  *
489
+ * @param WP_REST_Request $request The REST Request.
490
  *
491
  * @return bool
492
  */
493
  public function has_valid_api_key( $request ) {
494
  $header = $request->get_header( 'X-OptinMonster-ApiKey' );
495
 
496
+ // Use this API Key to validate.
497
  if ( ! $this->validate_api_key( $header ) ) {
498
  return new WP_Error(
499
  'omapp_rest_forbidden',
512
  *
513
  * @since 1.9.10
514
  *
515
+ * @param WP_REST_Request $request The REST Request.
516
  *
517
  * @return bool
518
  */
527
  *
528
  * @since 1.8.0
529
  *
530
+ * @param string $api_key The OM api key.
531
  *
532
  * @return bool True if the Key can be validated
533
  */
OMAPI/Save.php CHANGED
@@ -396,7 +396,7 @@ class OMAPI_Save {
396
  }
397
 
398
  // Loop through all of the local optins so we can try to match and update.
399
- $local_optins = $this->base->get_optins();
400
  if ( ! empty( $local_optins ) ) {
401
  $this->sync_optins( $local_optins, $optins, $enabled );
402
  } else {
@@ -453,7 +453,12 @@ class OMAPI_Save {
453
  // If we still have optins, they are new and we need to add them.
454
  if ( ! empty( $remote_optins ) ) {
455
  foreach ( (array) $remote_optins as $slug => $optin ) {
456
- $this->new_optin( $slug, $optin, $enabled );
 
 
 
 
 
457
  }
458
  }
459
  }
396
  }
397
 
398
  // Loop through all of the local optins so we can try to match and update.
399
+ $local_optins = $this->base->get_optins( array( 'post_status' => 'any' ) );
400
  if ( ! empty( $local_optins ) ) {
401
  $this->sync_optins( $local_optins, $optins, $enabled );
402
  } else {
453
  // If we still have optins, they are new and we need to add them.
454
  if ( ! empty( $remote_optins ) ) {
455
  foreach ( (array) $remote_optins as $slug => $optin ) {
456
+ $local = $this->base->get_optin_by_slug( $slug );
457
+ if ( $local ) {
458
+ $this->update_optin( $local, $optin );
459
+ } else {
460
+ $this->new_optin( $slug, $optin, $enabled );
461
+ }
462
  }
463
  }
464
  }
OMAPI/Support.php CHANGED
@@ -57,7 +57,7 @@ class OMAPI_Support {
57
  */
58
  public function get_campaign_data( $format = 'raw' ) {
59
 
60
- $campaigns = $this->base->get_optins();
61
  $data = array();
62
 
63
  if ( empty( $campaigns ) ) {
57
  */
58
  public function get_campaign_data( $format = 'raw' ) {
59
 
60
+ $campaigns = $this->base->get_optins( array( 'post_status' => 'any' ) );
61
  $data = array();
62
 
63
  if ( empty( $campaigns ) ) {
optin-monster-wp-api.php CHANGED
@@ -5,11 +5,11 @@
5
  * Description: OptinMonster is the best WordPress popup plugin that helps you grow your email list and sales with email popups, exit intent popups, floating bars and more!
6
  * Author: OptinMonster Team
7
  * Author URI: https://optinmonster.com
8
- * Version: 1.9.11
9
  * Text Domain: optin-monster-api
10
  * Domain Path: languages
11
  * WC requires at least: 3.2.0
12
- * WC tested up to: 4.2.2
13
  *
14
  * OptinMonster is free software: you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ class OMAPI {
62
  *
63
  * @var string
64
  */
65
- public $version = '1.9.11';
66
 
67
  /**
68
  * The name of the plugin.
@@ -243,6 +243,9 @@ class OMAPI {
243
  // Hide the unrelated admin notices.
244
  add_action( 'admin_print_scripts', array( $this, 'hide_unrelated_admin_notices' ) );
245
 
 
 
 
246
  // Filter the WooCommerce category/tag REST API responses.
247
  add_filter( 'woocommerce_rest_prepare_product_cat', 'OMAPI_WooCommerce::add_category_base_to_api_response' );
248
  add_filter( 'woocommerce_rest_prepare_product_tag', 'OMAPI_WooCommerce::add_tag_base_to_api_response' );
@@ -889,6 +892,58 @@ class OMAPI {
889
  }
890
  }
891
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
892
  /**
893
  * Get beta version.
894
  *
5
  * Description: OptinMonster is the best WordPress popup plugin that helps you grow your email list and sales with email popups, exit intent popups, floating bars and more!
6
  * Author: OptinMonster Team
7
  * Author URI: https://optinmonster.com
8
+ * Version: 1.9.14
9
  * Text Domain: optin-monster-api
10
  * Domain Path: languages
11
  * WC requires at least: 3.2.0
12
+ * WC tested up to: 4.4.1
13
  *
14
  * OptinMonster is free software: you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License as published by
62
  *
63
  * @var string
64
  */
65
+ public $version = '1.9.14';
66
 
67
  /**
68
  * The name of the plugin.
243
  // Hide the unrelated admin notices.
244
  add_action( 'admin_print_scripts', array( $this, 'hide_unrelated_admin_notices' ) );
245
 
246
+ // PHP version check.
247
+ add_action( 'admin_init', array( $this, 'check_php_version' ) );
248
+
249
  // Filter the WooCommerce category/tag REST API responses.
250
  add_filter( 'woocommerce_rest_prepare_product_cat', 'OMAPI_WooCommerce::add_category_base_to_api_response' );
251
  add_filter( 'woocommerce_rest_prepare_product_tag', 'OMAPI_WooCommerce::add_tag_base_to_api_response' );
892
  }
893
  }
894
 
895
+ public function check_php_version() {
896
+
897
+ // Display for PHP below 5.6
898
+ if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {
899
+ return;
900
+ }
901
+
902
+ // Display for admins only.
903
+ if ( ! is_super_admin() ) {
904
+ return;
905
+ }
906
+
907
+ // Display on Dashboard page only.
908
+ if ( isset( $GLOBALS['pagenow'] ) && 'index.php' !== $GLOBALS['pagenow'] ) {
909
+ return;
910
+ }
911
+
912
+ // Do not double up on WPForms notice.
913
+ if ( function_exists( 'wpforms_check_php_version' ) ) {
914
+ return;
915
+ }
916
+
917
+ // Display the notice, finally.
918
+ echo '<div id="message" class="notice notice-error">' .
919
+ '<p>' .
920
+ sprintf(
921
+ wp_kses(
922
+ /* translators: %1$s - OptinMonster API plugin name; %2$s - optinmonster.com URL to a related doc. */
923
+ __( 'Your site is running an outdated version of PHP that is no longer supported and may cause issues with the %1$s plugin. <a href="%2$s" target="_blank" rel="noopener noreferrer">Read more</a> for additional information.', 'optin-monster-api' ),
924
+ array(
925
+ 'a' => array(
926
+ 'href' => array(),
927
+ 'target' => array(),
928
+ 'rel' => array(),
929
+ ),
930
+ )
931
+ ),
932
+ '<strong>OptinMonster API</strong>',
933
+ 'https://optinmonster.com/docs/supported-php-version/'
934
+ ) .
935
+ '<br><br><em>' .
936
+ wp_kses(
937
+ __( '<strong>Please Note:</strong> Support for PHP 5.5 will be discontinued in 2020. After this, if no further action is taken, OptinMonster functionality will be disabled.', 'optin-monster-api' ),
938
+ array(
939
+ 'strong' => array(),
940
+ 'em' => array(),
941
+ )
942
+ ) .
943
+ '</em></p>' .
944
+ '</div>';
945
+ }
946
+
947
  /**
948
  * Get beta version.
949
  *
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: optinmonster, griffinjt, smub
3
  Tags: marketing, popups, popup builder, newsletter, conversion, optin forms, forms, subscribers, exit intent popup, email marketing, crm, popup maker, popup plugin, cart abandonment, spin a wheel popup, conversion optimization, a/b testing, email opt-in, retargeting, ecommerce, cro, lightbox, promotion, shipping bar, announcement bar, advertising, mailing list, popup slide-in
4
  Requires at least: 4.7.0
5
- Tested up to: 5.4.2
6
  Requires PHP: 5.3
7
- Stable tag: 1.9.11
8
  License: GNU General Public License v2.0 or later
9
 
10
  Create popups, opt-in forms, & floating bars to get more email newsletter subscribers, leads, and increase sales conversion - #1 marketing popup plugin.
@@ -471,6 +471,15 @@ Syed Balkhi
471
 
472
  **Most Recent Changes:**
473
 
 
 
 
 
 
 
 
 
 
474
  = 1.9.11 =
475
  * Fixed a bug that caused too many redirects in the admin when clicking on certain plugin settings links.
476
  * Removed a plugin action link that was not used.
@@ -514,8 +523,4 @@ Syed Balkhi
514
  * Remove old jQuery dependencies.
515
  * Update internal notices to be more friendly with other plugins.
516
 
517
- = 1.9.7 =
518
- * Update the OptinMonster API JS URL.
519
- * Update trustpulse menu title.
520
-
521
  **[View entire changelog](https://plugins.svn.wordpress.org/optinmonster/trunk/CHANGELOG.md)**
2
  Contributors: optinmonster, griffinjt, smub
3
  Tags: marketing, popups, popup builder, newsletter, conversion, optin forms, forms, subscribers, exit intent popup, email marketing, crm, popup maker, popup plugin, cart abandonment, spin a wheel popup, conversion optimization, a/b testing, email opt-in, retargeting, ecommerce, cro, lightbox, promotion, shipping bar, announcement bar, advertising, mailing list, popup slide-in
4
  Requires at least: 4.7.0
5
+ Tested up to: 5.5
6
  Requires PHP: 5.3
7
+ Stable tag: 1.9.14
8
  License: GNU General Public License v2.0 or later
9
 
10
  Create popups, opt-in forms, & floating bars to get more email newsletter subscribers, leads, and increase sales conversion - #1 marketing popup plugin.
471
 
472
  **Most Recent Changes:**
473
 
474
+ = 1.9.14 =
475
+ * Fixed a bug that occasionally prevented changes in campaigns via the OptinMonster App to not properly sync to the plugin, due to cached responses.
476
+
477
+ = 1.9.13 =
478
+ * Fixed a bug that caused campaigns to be incorrectly referenced in the admin dashboard.
479
+
480
+ = 1.9.12 =
481
+ * Fixed a bug where the `Access-Control-Allow-Headers` was being improperly reset for REST requests.
482
+
483
  = 1.9.11 =
484
  * Fixed a bug that caused too many redirects in the admin when clicking on certain plugin settings links.
485
  * Removed a plugin action link that was not used.
523
  * Remove old jQuery dependencies.
524
  * Update internal notices to be more friendly with other plugins.
525
 
 
 
 
 
526
  **[View entire changelog](https://plugins.svn.wordpress.org/optinmonster/trunk/CHANGELOG.md)**