Popup Maker – Popup Forms, Optins & More - Version 1.8.6

Version Description

Download this release

Release Info

Developer danieliser
Plugin Icon 128x128 Popup Maker – Popup Forms, Optins & More
Version 1.8.6
Comparing to
See all releases

Code changes from version 1.8.5 to 1.8.6

Files changed (5) hide show
  1. CHANGELOG.md +110 -106
  2. classes/Privacy.php +457 -457
  3. classes/Utils/Alerts.php +485 -485
  4. popup-maker.php +2 -2
  5. readme.txt +7 -3
CHANGELOG.md CHANGED
@@ -1,25 +1,29 @@
1
- = v1.8.5 - 04/17/2019 =
 
 
 
 
2
  * Tweak: Removed unused settings.
3
  * Fix: Typo in method name that would generate errors in some extension migration routines.
4
  * Fix: Issue when using class="" in our Popup Trigger shortcode would not get converted to classes on the element.
5
  * Fix: Bug in JS due to missing default value.
6
  * Fix: Bug older extensions caused by deprecated filter not getting loaded properly.
7
 
8
- = v1.8.4 - 03/21/2019 =
9
  * Improvement: Added content caching in the head to prevent second call to do_shortcode in the footer.
10
  * Improvement: Added runtime model caching to reduce memory usage.
11
 
12
- = v1.8.3 - 02/27/2019 =
13
  * Fix: Added back deprecated function that got truncated previously.
14
 
15
- = v1.8.2 - 02/25/2019 =
16
  * Fix: Bug on older versions of PHP due to usage of [] rather than array().
17
 
18
- = v1.8.1 - 02/22/2019 =
19
  * Fix: Error on older versions of PHP when calling get_plugin_data on a plugin that wasn't installed.
20
  * Fix: "Fatal error: Can not use method return value in write context" on older versions of PHP.
21
 
22
- = v1.8.0 - 02/20/2019 =
23
  * Feature: New popup theme settings:
24
  * New close button positions top center, bottom center, middle left & middle right.
25
  * New option to position close button outside of popup.
@@ -35,7 +39,7 @@
35
  * Fix: iOS Click overlay close not working.
36
  * Fix: Analytics not working for themes with incorrect wp_footer usage.
37
 
38
- = v1.7.30 - 09/06/2018 =
39
  * Improvement: Further added methods to log unique messages only once.
40
  * Tweak: Remove usage of Freemius.
41
  * Fix: Added option to disable popups accessibility functionality to resolve some issues with focus trapping.
@@ -45,50 +49,50 @@
45
  * Fix: Typo pointing to incorrect internal method call in new has_cookie method.
46
  * Fix: Issues with fields not being readonly.
47
 
48
- = v1.7.29 - 06/13/2018 =
49
  * Improvement: Added new enabled() method for the PUM_AssetCache class that checks both is writable and not disabled.
50
  * Improvement: Added option to disable just asset caching. This should help in the case your server is blocking the use of our JS from the /uploads/ folder with a 403 error.
51
  * Fix: Bug caused by string representations of boolean values passed in our subscription forms.
52
 
53
- = v1.7.28 - 06/10/2018 =
54
  * Tweak: Improved validation of subscription form data and messaging.
55
  * Fix: Bug with front end form serialization issue with single checkboxes (privacy field).
56
 
57
- = v1.7.27 - 06/08/2018 =
58
  * Improvement: Added additional variable checks to allow graceful failing during certain JS errors when page cache is out of date.
59
 
60
- = v1.7.26 - 06/07/2018 =
61
  * Fix: Add empty popups array to prevent errors due to page caching.
62
 
63
- = v1.7.25 - 06/05/2018 =
64
  * Tweak: Localized most variables earlier to prevent errors. Added in default values in case they do not get rendered to prevent fatal JS errors.
65
  * Fix: Tweaked extension activation class to be compatible with PHP 5.2.
66
  * Fix: Bug where boolean scalar values were changed to "" for json_encode.
67
 
68
- = v1.7.24 - 06/04/2018 =
69
  * Tweak: Updated subscriber table for existing sites that failed to add it properly before.
70
 
71
- = v1.7.23 - 06/04/2018 =
72
  * Improvement: Converted cookie privacy info to tabular rendering.
73
  * Tweak: Improved update notice text.
74
  * Fix: Issues with subscriber table not being created. Thanks @jnorell
75
  * Fix: Bug not allowing more than one cookie for a trigger.
76
  * Fix: Undefined index errors in shortcake/shortcode-ui integration.
77
 
78
- = v1.7.22 - 05/25/2018 =
79
  * Tweak: Updated Freemius library for GDPR optin support.
80
  * Improvement: Made all popup loops more reliable.
81
  * Fix: Error where objects were processed incorrectly.
82
  * Fix: "Uncaught Error: Call to a member function get_setting() on boolean in /popup-maker/classes/AssetCache.php:314"
83
 
84
- = v1.7.21 - 05/24/2018 =
85
  * Tweak: Clear asset cache on settings save.
86
  * Improvement: Check that post is singular to prevent Post Selected conditions from working on site index.
87
  * Improvement: Remove jquery-cookie from assets as we no longer use or load it anywhere.
88
  * Fix: Missing function errors if you don't have WordPress v4.9.6.
89
  * Fix: Added better & safer json encoding function that properly sanitizes data for encoding to prevent empty strings for non english sites.
90
 
91
- = v1.7.20 - 05/19/2018 =
92
  * Feature: Support for GDPR Personal Data Exporter
93
  * Feature: Support for GDPR Personal Data Eraser
94
  * Feature: New privacy consent field for Subscription Forms for GDPR consent collection.
@@ -96,13 +100,13 @@
96
  * Improvement: Updated dependency libs.
97
  * Fix: Bug in subscriber tables if no popup ID was stored.
98
 
99
- = v1.7.19 - 05/01/2018 =
100
  * Version bump due to svn file add issues during last commit.
101
 
102
- = v1.7.18 - 05/01/2018 =
103
  * Fix: Typo in JS that may cause errors for some.
104
 
105
- = v1.7.17 - 05/01/2018 =
106
  * Improvement: Added popup option to disable automatic re-triggering of popup after non-ajax form submission.
107
  * Improvement: Added notice when JS errors occur in Popup Maker admin interfaces with link to documentation for proper diagnosis & reporting.
108
  * Tweak: Added asset cache reset on update of core version & db version.
@@ -110,14 +114,14 @@
110
  * Tweak: Simplified the post type batch processor setup for extensions.
111
  * Dev: Added base PUM_Extension_Activator class to standardize extension activation and various other things.
112
 
113
- = v1.7.16 - 04/24/2018 =
114
  * Tweak: Removed debug code.
115
  * Fix: Issue with valueless shortcode attributes not processing properly.
116
  * Fix: Issues where our scripts loaded before Ninja Forms scripts did and our integration didn't initialize.
117
  * Dev: Added helper function to return array of shortcodes and data in usable format from any content.
118
  * Dev: Added support for measure fields for shortcodes.
119
 
120
- = v1.7.15 - 04/14/2018 =
121
  * Improvement: Removed metadata from object models to reduce cache size as WordPress already has them cached.
122
  * Tweak: Added new filter and corrected typo in existing ones for extension integrations.
123
  * Fix: Bug for potentially missing variable.
@@ -125,13 +129,13 @@
125
  * Fix: Bug where google fonts didn't always get loaded correctly.
126
  * Fix: Missing styles from Advanced Theme Builder due to misordering.
127
 
128
- = v1.7.14 - 03/28/2018 =
129
  * Fix: Obscure PHP error caused by method from interface was marked abstract in an abstract class inheriting the interface.
130
  * Fix: Bug when jquery cookie is called from another plugin.
131
  * Fix: Bug where form submit button triggered popup close when overlay click to close was enabled.
132
  * Fix: Typo in previous patch for db_var not being updated properly.
133
 
134
- = v1.7.13 - 03/27/2018 =
135
  * Tweak: Added fallback methods for conditions using MobileDetect to prevent errors when for whatever reason it was not loaded properly.
136
  * Tweak: Added value type check to prevent errors in popup data.
137
  * Fix: Bug with accessibility forced focus when there is a link in the popup, causing the close button to focus the link before closing.
@@ -140,7 +144,7 @@
140
  * Fix: Set a deprecated option on new installs for backward compatibility issues.
141
  * Fix: Selector correction in z-index setting application.
142
 
143
- = v1.7.12 - 03/21/2018 =
144
  * Improvement: Added option to disable the shortcode ui.
145
  * Tweak: Removed private popup type links from the nav menu editor.
146
  * Fix: Bug with long term cached assets causing JS errors on nginx servers.
@@ -149,53 +153,53 @@
149
  * Fix: Bugs in close delay settings for form integrations. Was in ms but needed to be in seconds.
150
  * Fix: Bug where Yoast SEO plugin shows popups in the xml sitemaps and showing Yoast metabox on popup editor.
151
 
152
- = v1.7.11 - 03/14/2018 =
153
  * Fix: Bug where Middle Center option wouldn't stay selected after saving.
154
  * Fix: Bug with incorrect field dependency for custom height & scrollable options.
155
 
156
- = v1.7.10 - 03/14/2018 =
157
  * Improvement: Further improved compatibility with shortcodes that echo/print rather than return content.
158
  * Fix: Bug where cookies wouldn't always be set in Edge & Safari due to cookie path including the root url.
159
  * Fix: Bug that changed the default tag for popup_trigger & popup_close shortcodes.
160
  * Fix: Bug where extra close buttons didn't always work correctly.
161
  * Fix: Removal of deprecated function that triggered warnings in PHP 7.2.
162
 
163
- = v1.7.9 - 03/14/2018 =
164
  * Improvement: Replaced usage of pumSerializeForm with pumSerializeObject which is more reliable.
165
  * Fix: Bug where deprecated directory reference causes popup html not to render properly breaking popups that should have worked otherwise.
166
  * Fix: Bug where checkbox defaults continuously applied making it impossible to uncheck them.
167
 
168
- = v1.7.8 - 03/13/2018 =
169
  * Improvement: Added output buffering to early calls to do_shortcode to prevent premature output in the head.
170
  * Improvement: Added sanity checks to make sure only valid popup objects are used in some older template functions.
171
 
172
- = v1.7.7 - 03/13/2018 =
173
  * Fix: Removed jQuery.serializeJSON functionality which was unused and causing conflicts with WooCommerce.
174
  * Fix: SSL Issues due to not specifying protocol.
175
  * Fix: Error caused by invalid popup object being used in function.
176
  * Fix: PHP 5.2 compatibility issue.
177
 
178
- = v1.7.6 - 03/12/2018 =
179
  * Fix: Undid previous changes from 1.7.1 and reworked in a new way to be backward compatible with existing extensions.
180
 
181
- = v1.7.5 - 03/12/2018 =
182
  * Fix: Sticky Popup Maker settings checkboxes that wouldn't uncheck after save.
183
 
184
- = v1.7.4 - 03/12/2018 =
185
  * Fix: Invalid method declaration error introduced by v1.7.2 patch to Shortcode core class.
186
 
187
- = v1.7.3 - 03/12/2018 =
188
  * Fix: Error due to usage of __CLASS__ rather than $this.
189
  * Fix: Edge case where function returns can't be used inside empty().
190
 
191
- = v1.7.2 - 03/12/2018 =
192
  * Fix: Initialization variable wasn't set to true early enough.
193
 
194
- = v1.7.1 - 03/12/2018 =
195
  * Fix: Empty value errors.
196
  * Fix: Missing function for 3rd party plugin backward compatibility (Elementor).
197
 
198
- = v1.7.0 - 03/12/2018 =
199
  This was a monster update, our largest to date in terms of improving existing functionality, reducing maintenance and the time it takes to implement new features in the future.
200
 
201
  Noticeably there are a lot of interface changes with this version as we simplified from having many meta boxes in the popup editor to a new single panel interface.
@@ -251,15 +255,15 @@ Lastly we now have include our extendable subscription forms right in the free v
251
  * Fix: Bug when WPML isn't yet available.
252
 
253
 
254
- = v1.6.7 - Rolled into v1.7.0 =
255
  * Fix: Typo in JS event name prevented forceFocus for popups.
256
  * Fix: JS errors when Marionette JS library on page without Ninja Forms.
257
  * Fix: WPML missing variable errors.
258
 
259
- = v1.6.6 - 07/29/2017 =
260
  * Fix: Bug with closing forms using newest version of Gravity Forms.
261
 
262
- = v1.6.5 - 07/16/2017 =
263
  * Tweak: Added new popup class for theme names. Thanks @bluantinoo.
264
  * Fix: Bug in menu popups save and render functionality not working correctly.
265
  * Fix: Finally found issue where randomly assets tab checkboxes wouldn't uncheck & save properly.
@@ -267,7 +271,7 @@ Lastly we now have include our extendable subscription forms right in the free v
267
  * Fix: Errors in w3c validation scans from form meta fields.
268
  * Fix: Settings asset label mismatch.
269
 
270
- = v1.6.4 - 07/07/2017 =
271
  * Imporvement: Reworked all form integrations to be as DRY as possible making it more reliable.
272
  * Tweak: Added sanity check in case previous filter mucks up the $item object variable in menu item filters causing warnings.
273
  * Tweak: Disabled the open count & sorting when Popup Analytics is activated.
@@ -280,18 +284,18 @@ Lastly we now have include our extendable subscription forms right in the free v
280
  * Fix: Bug with GForms closing popup after submission.
281
  * Fix: Bug where CF7 Forms with required fields trigger popup to close without being filled properly.
282
 
283
- = v1.6.3 - 05/19/2017 =
284
  * Fix: Removed 3rd parameter from number_format as it only accepts 1, 2 or 4 arguments, not 3 per php.net documentation.
285
 
286
- = v1.6.2 - 05/18/2017 =
287
  * Fix: Bug caused by rounding to whole numbers in opacity values.
288
 
289
- = v1.6.1 - 05/17/2017 =
290
  * Improvement: Major improvements to the Shortcode UI (builder & in editor previews). Now supports true live rendering of PM shortcodes. This will be most apparent in upcoming extension updates.
291
  * Fix: Forced decimal formatting in CSS output functions in case of locale changes to formatting. Fix thanks to @timhavinga
292
 
293
 
294
- = v1.6.0 - 04/26/2017 =
295
  * Feature: Added Gravity Forms direct integrations.
296
  * Close popup with delay when Gravity Form is submitted.
297
  * Trigger a thank you popup when Gravity Form is submitted.
@@ -306,42 +310,42 @@ Lastly we now have include our extendable subscription forms right in the free v
306
  * Fix: Bug where you couldn't enter values higher than the rangeslider max.
307
  * Fix: JS error when creating a cookie before a trigger exists.
308
 
309
- = v1.5.8 - 04/04/2017 =
310
  * Fix: Error when extensions were active due to null values for checkboxes.
311
 
312
 
313
- = v1.5.7 - 03/27/2017 =
314
  * Improvement: Added option to disable the menu editors in case of a conflict.
315
  * Fix: Forced 100% width on page select boxes to prevent them from being too small.
316
  * Fix: Bug where checkboxes were not staying checked.
317
 
318
- = v1.5.6 - 03/16/2017 =
319
  * Feature: Admin Bar helper tool to assist in getting proper click trigger selectors easily.
320
  * Improvement: Further tweaks for maximium compatibitlity with nav menu editor.
321
  * Improvement: Added Popup option to nav menu editor Screen Options to easily hide them.
322
  * Fix: Updated the freemius-sdk to fix an obscure secured php core function error.
323
 
324
- = v1.5.5 - 03/13/2017 =
325
  * Improvment: Used generic Nav Menu Editor Walker classes for better support. This should remove the notices from other plugins as well.
326
  * Fix: Bug that causes click triggers to lag.
327
 
328
- = v1.5.4 - 03/13/2017 =
329
  * Fix: Typos in conditions.
330
  * Fix: Moved class_exists checks to better handle possible missing class errors.
331
 
332
- = v1.5.3 - 03/13/2017 =
333
  * Improvement: Added a catch for any triggers not initialized at page load.
334
  * Fix: Typo in multi check field template that led to admin JS errors.
335
 
336
- = v1.5.2 - 03/10/2017 =
337
  * Improvement: Added option to disable the admin bar Popups helper menu item.
338
  * Improvement: Simplified the nav menu editor modification class to reduce un-needed translation strings.
339
  * Fix: Added check for missing class in the nav menu editor walker classes.
340
 
341
- = v1.5.1 - 03/09/2017 =
342
  * Fix: PHP 5.2 Compatibility issue.
343
 
344
- = v1.5.0 - 03/08/2017 =
345
  * Feature: Position popups based on the click trigger. Tooltips & Popovers are now possible.
346
  * Feature: Added new conditions for targeting children & grandchildren / ancestors of selected content.
347
  * Feature: Added new settings to the Nav Menu editor to choose a popup that a menu item will trigger.
@@ -367,19 +371,19 @@ Lastly we now have include our extendable subscription forms right in the free v
367
  * Fix: Bug where links in the close button were not triggered even when do_default was enabled.
368
  * Fix: Bug with scrollbar "flashing" when popup opens.
369
 
370
- = v1.4.21 - 12/12/2016 =
371
  * Feature: Added option to disable popup on mobile to comply with [Google's new interstital policy](https://webmasters.googleblog.com/2016/08/helping-users-easily-access-content-on.html).
372
  * Tweak: Added additional paramter to the pum_popup_get_conditions filter.
373
  * Tweak: Fixed possible false init of NF integration if NF is not enabled.
374
  * Tweak: Added CSS override for Ninja Forms datepickers to properly layer them above popups.
375
 
376
- = v1.4.20 - 10/13/2016 =
377
  * Feature: Added [Ninja Forms](https://wppopupmaker.com/grab/ninja-forms?utm_source=readme-changelog&utm_medium=text-link&utm_campaign=Readme&utm_content=ninja-forms-features) success actions for opening & closing popups.
378
  * Feature: Added new cookie event for successful submission of a [Ninja Forms](https://wppopupmaker.com/recommends/ninja-forms) form.
379
  * Improvement: Added wp.hooks JS library, allowing actions & filters via our plugin JS.
380
  * Tweaks: Added various admin css tweaks.
381
 
382
- = v1.4.19 - 9/30/2016 =
383
  * Feature: Added a do_default parameter to the trigger & close shortcodes. This allows making close buttons that also download a file.
384
  * Improvement: Added support for JS (advanced) conditions & condition processing after checking for cookies.
385
  * Improvement: Upgraded from jQuery-Cookie (modified) to JS-Cookie (modified) for more flexibility.
@@ -387,14 +391,14 @@ Lastly we now have include our extendable subscription forms right in the free v
387
  * Fix: Added prefix to admin pages to prevent conflicts.
388
  * Fix: Removed usage of deprecated filter.
389
 
390
- = v1.4.18 - 8/15/2016 =
391
  * Fix: Bug with PHP 5.2 compatibility.
392
  * Fix: Added missing post_type index condition callback.
393
 
394
- = v1.4.17 - 8/14/2016 =
395
  * Fix: Bug caused by using return value in write context.
396
 
397
- = v1.4.16 - 8/14/2016 =
398
  * Feature: New Condition: Pages: With Template. Thanks @cedmund.
399
  * Feature: Option to Disable reposition on window resize/scroll.
400
  * Improvement: Enable Visual Composer for Popups by default (VC 4.8+). Thanks @NoahjChampion.
@@ -406,33 +410,33 @@ Lastly we now have include our extendable subscription forms right in the free v
406
  * Fix: Error in JS due to shortcodes: Uncaught Error: Syntax error, unrecognized expression.
407
  * Fix: Issue where some custom post types not working with conditions.
408
 
409
- = v1.4.15 - 7/20/2016 =
410
  * Improvement: Only showed the aria-label attribute if the label will be shown.
411
  * Tweak: Updated the Freemius SDK.
412
  * Tweak: Updated the #popmake-{ID} selector to work at the end of a link.
413
  * Fix: Bug where stackable popups would lose their scroll bar after one was closed.
414
 
415
- = v1.4.14 - 7/14/2016 =
416
  * Feature: Links with the url #popmake-{ID} will now trigger a popup when clicked. Links with this href will work similar to elements with the popmake-{ID} class.
417
 
418
- = v1.4.13 - 6/26/2016 =
419
  * Feature: Added 12 of the most commonly needed BuddyPress content types & targeting conditions. Target any BP content type. Now full support for BuddyPress.
420
  * Tweak: Moved a few functions from the plugins_loaded action to the init action for minor compatibility benefits.
421
  * Tweak: Removed Popup & Popup Theme Meta Revisioning as it adds unneeded clutter to the DB.
422
 
423
- = v1.4.12 - 6/24/2016 =
424
  * Improvement: Reduced translatable strings from 569 total to 439 which is about a 23% reduction which will reduce work for our translators.
425
  * Tweak: Removed the welcome page and associated CSS, images etc. This cleans up some useless strings for translation.
426
  * Fix: Bug where add_new cookie wasn't properly replaced for the first trigger.
427
 
428
- = v1.4.11 - 6/10/2016 =
429
  * Feature: New conditions for targeting posts & taxonomy by ID.
430
  * Improvement: Added link to Conditions Documentation to the Conditions editor.
431
  * Tweak: Namespaced jQuery.serializeObject to prevent conflicts with other plugins/themes in the admin editor.
432
  * Fix: Bug on add new page/post and during post update.
433
  * Fix: Bug in edit this theme link on page load.
434
 
435
- = v1.4.10 - 5/23/2016 =
436
  * Feature: Added Do Default option to the click triggers. Allows a triggers default browsers behavior to occur and still open a popup, such as a file link.
437
  * Improvement: Added additional links to the theme editor for better visibility and to guide users there.
438
  * Tweak: Older methods are only loaded when needed, this also removes usage of a deprecated filter.
@@ -443,7 +447,7 @@ Lastly we now have include our extendable subscription forms right in the free v
443
  * Fix: Cleaned up issues allowing popup post type to be added directly to menus and sitemaps.
444
  * Fix: Bug where auto height checkbox would not stay checked.
445
 
446
- = v1.4.9 - 5/01/2016 =
447
  * Improvement: Reduced front end queries by over 85%. Avgerage sites should now only have 2 to 3.
448
  * Improvement: Added caching enhancements for even better performance on servers with page, object & query caching.
449
  * Improvement: Added a fully namespaced version of Select2 for compatiblitiy while other plugins await updating. Will gracefully fall back to the non namespaced version when it no longer causes issues.
@@ -451,40 +455,40 @@ Lastly we now have include our extendable subscription forms right in the free v
451
  * Fix: The "Use Your Theme" font option was not working correctly.
452
  * Fix: Removed leftover console.logs in our JavaScript.
453
 
454
- = v1.4.8 - 4/27/2016 =
455
  * Improvement: Sandboxed Select2 v4 since it breaks other plugins when loaded properly. v4 adds accessiblity enhancements that we are not going to sacrifice for compatiblity with plugins who have not updated to include it. This provides a safe alternative in the meantime.
456
  * Tweak: Removed extra shortcode files.
457
  * Tweak: Allow popup Click Triggers to target another popups close button. Close one triggers another etc.
458
  * Fix: Bug caused by pum_shortcode_ui not loading properly everywhere.
459
  * Fix: Bug in popup position calculation when the popup used Fixed Position and Disable Overlay
460
 
461
- = v1.4.7 - 4/24/2016 =
462
  * Improvement: Removed the old styles dropdown as it is no longer needed.
463
  * Improvement: Added check for old versions of Select2 and replace them with latest which is backward compatible.
464
  * Fix: Bug that caused Close button delay to not show the close button.
465
  * Fix: Replaced usage of <% style JS template with <# & {{ for PHP asp_tags compatibility.
466
 
467
- = v1.4.6 - 4/22/2016 =
468
  * Fix: Bug in new post editor JS.
469
  * Fix: Added filter to override permissions for upgrade routines.
470
 
471
- = v1.4.5 - 4/21/2016 =
472
  * Fix: Replaced all usage of static:: for PHP 5.2 compatiblity.
473
  * Fix: Forced the latest version of Select2 to load on Popup Maker admin pages in the case that an older version was enqueued.
474
 
475
- = v1.4.4 - 4/20/2016 =
476
  * Fix: Version Bump to fix upgrade issues.
477
 
478
- = v1.4.3 - 4/20/2016 =
479
  * Fix: Removed extra whitespace before opening php tags.
480
 
481
- = v1.4.2 - 4/20/2016 =
482
  * Fix: Bug in popup maker deprecated filter caused by no defaults passed.
483
 
484
- = v1.4.1 - 4/20/2016 =
485
  * Fix: Bug in popup maker upgrade class for older versions of PHP.
486
 
487
- = v1.4 - 4/20/2016 =
488
  * Feature: Added basic analytics. Tracks how many unique opens each popup has.
489
  * Feature: Added new Popup Maker shortcodes button to the editor with visual previews.
490
  * Feature: Added option to reset popup open counts demand.
@@ -524,7 +528,7 @@ Lastly we now have include our extendable subscription forms right in the free v
524
  365 Commits / 53 Major & Minor Issues Closed.
525
  285 changed files with 20,437 additions and 3,607 deletions.
526
 
527
- = v1.3.9 - 10/14/2015 =
528
  * Feature: New shortcode - [popup_close] allows adding custom close buttons/text. Ex. [popup_close] Click Me [/popup_close].
529
  * Improvement: Added SASS/SCSS files for the site & admin styles.
530
  * Improvement: Added better support for current & legacy versions of Visual Composer.
@@ -535,11 +539,11 @@ Lastly we now have include our extendable subscription forms right in the free v
535
  * Fix: Fixed bug in CSS that caused popup to appear below site on mobile.
536
  * Fix: WP Multi Site: Fatal Error.
537
 
538
- = v1.3.8 - 9/29/2015 =
539
  * Fix: Updated links to documentation.
540
  * Fix: Removed exploitable bug allowing script execution in the admin. Discovered 9/29/15 - Patched 9/29/15
541
 
542
- = v1.3.7 - 9/21/2015 =
543
  * Feature: Added support for Visual Composer to popups. (Backend Editor Only). Works Perfectly with Responsive Popups.
544
  * Tweak: Disable position fixed on mobile screens for responsive popups.
545
  * Tweak: Improved UI with better popup formats selection.
@@ -551,36 +555,36 @@ Lastly we now have include our extendable subscription forms right in the free v
551
  * Fix: Bug with targeting conditions for categories.
552
  * Fix: Bug in positioning left & right values. Credit to @invik for the solution.
553
 
554
- = v1.3.6 - 8/25/2015 =
555
  * Confirmed WP v4.3 compatibility.
556
  * Tweak: Default theme is automatically used if a popup does not have one assigned.
557
  * Fix: UI bug where fixed position checkbox wouldn't stay checked.
558
  * Fix: Bug with Theme Default values & v1.2 values not being merged.
559
 
560
- = v1.3.5 - 8/18/2015 =
561
  * Tweak: Corrected missing keys for required script checks.
562
  * Fix: Error message caused by non array value from get_post_custom.
563
  * Fix: Removed missing variable.
564
  * Fix: Text corrections.
565
 
566
- = v1.3.4 - 8/12/2015 =
567
  * Fix: Added px to font-size & line-height.
568
 
569
- = v1.3.3 - 8/12/2015 =
570
  * Fix: Added current_action fallback function for older versions of WP.
571
  * Fix: Theme CSS rendering incorrect font settings.
572
 
573
- = v1.3.2 - 8/10/2015 =
574
  * Tweak: Pause HTML5 Videos when popup closes.
575
  * Fix: Prefixed several functions that collided with some themes.
576
  * Fix: Changed default Close Height & Width to 0/auto.
577
 
578
- = v1.3.1 - 8/8/2015 =
579
  * Fix: Error in get_called_class alternate function for PHP 5.2
580
  * Fix: Force theme css builder to check for empty themes.
581
  * Fix: Bug where z-indexes were incorrectly set.
582
 
583
- = v1.3 - 8/7/2015 =
584
  * Feature: Added unlimited themes functionality to the core.
585
  * Feature: Allow disabling of event.prevendDefault() for on click events by adding do-default class.
586
  * Feature: Added support for session based cookies.
@@ -619,7 +623,7 @@ Lastly we now have include our extendable subscription forms right in the free v
619
  * Fix: Bug where popup & popup_theme meta was stored with other post types on revision.
620
  * Fix: Bug in the popup_trigger shortcode with $content not being rendered properly.
621
 
622
- = v1.2.2 =
623
  * Added (string) typecast to prevent errors in wp_localize_script when passing integers.
624
  * Added 100% French & Hungarian translations.
625
  * Added partial German translation.
@@ -636,10 +640,10 @@ Lastly we now have include our extendable subscription forms right in the free v
636
  * Temporarily removed the grow animations due to removal of Greensock Animation Platform.
637
  * Removed Greensock Animation Platform dependancy.
638
 
639
- = v1.2.1 =
640
  * Fixed bug caused by null value passed to JS data attr.
641
 
642
- = v1.2 =
643
  * Added full screen preview for themes when editing using the Preview button.
644
  * Added full screen preview for popup when editing using the Preview button.
645
  * Added new shortcode 'popup_trigger' that allows users to easily add the correct popmake- class. Accepts id, tag & class parameters.
@@ -653,16 +657,16 @@ Lastly we now have include our extendable subscription forms right in the free v
653
  * Added function to prevent deletion of default theme.
654
  * Fixed bug which caused Popup Maker menu to show to all users.
655
 
656
- = v1.1.10 =
657
  * Fixed invalid argument bug passed to google font foreach.
658
  * Fixed CSS box-sizing cross browser support.
659
 
660
- = v1.1.9 =
661
  * Added %'s to reponsive sizes in size dropdown.
662
  * Remove usage of the_content and the_content filters.
663
  * Fixed responsive sizes.
664
 
665
- = v1.1.8 =
666
  * Fixed issue with admin menu position collisions.
667
  * Fixed issue with banner not staying dismissed.
668
  * Removed dependency jQuery.cookie
@@ -676,57 +680,57 @@ Lastly we now have include our extendable subscription forms right in the free v
676
  * Disabled Popup Maker JS & CSS when no popups detected to load.
677
  * Added new function popmake_enqueue_scripts() which allows manual enqueuing of scripts and styles.
678
 
679
- = v1.1.7 =
680
  * Fixed undefined function popmake_default_settings.
681
  * Fixed specific pages not saving properly.
682
  * Now removes ?autoplay parameter from Videos preventing them from playing again without interaction.
683
 
684
- = v1.1.6 =
685
  * Fixed bug in js not setting correct CSS value for min-width.
686
  * Changed close link element tag from a > span.
687
 
688
- = v1.1.5 =
689
  * Fixed bug when clicking add selected buttons.
690
  * Changed how popmake_popup_is_loadable works. It is now more organized and readable.
691
  * Added 2 new Targeting Conditions: Search & 404.
692
 
693
- = v1.1.4 =
694
  * Fixed bug in scrollable content styles.
695
  * Fixed bug in admin JS for duplicate input names.
696
  * Changed Powered By Setting to Off by Default.
697
  * Changed default permissions required to use theme builder.
698
  * Fixed bug in targeting conditions.
699
 
700
- = v1.1.3 =
701
  * Fixed some incorrect links to resources and kb.
702
  * Removed Auto Open Promotional Material ( as it is now included ).
703
 
704
- = v1.1.2 =
705
  * Further enhancements to ensure proper checking of Auto Open Enabled.
706
 
707
- = v1.1.1 =
708
  * Fixed bug in JS that didn't properly check if Auto Open was enabled.
709
 
710
- = v1.1 =
711
  * Added Importer for Easy Modal v2 - Availabe under Tools -> Import
712
  * Added Easy Modal v2 Compatibility Option - Available under Settings -> Misc (This will allow all of your existing eModal classes to open the proper Popup once imported)
713
  * Added custom selector functionality - Availabe on Modal editor (This will allow you to use your own css selectors that when clicked will trigger the popup to open. Ex. #main-menu li.menu-item-3 would cause the corresponding menu item to trigger that popup)
714
 
715
- = v1.0.5 =
716
  * Fixed bug caused by changes in v1.0.4.
717
 
718
- = v1.0.4 =
719
  * Admin UI Adjustments & Tweaks.
720
  * Fixed bug in removing specific post types.
721
  * Reformatted Code.
722
  * Fixed incorrect variable.
723
 
724
- = v1.0.3 =
725
  * Fixed bug with recursive filter.
726
  * Fixed bug caused by typo.
727
  * Fixed bug in JS for removing specific post type posts.
728
 
729
- = v1.0.2 =
730
  * Resized Extension page images to load quicker on extensions page.
731
  * Added last_open_popup proerty to popmake jQuery function.
732
  * Resized Extension page images to load quicker on extensions page.
@@ -737,11 +741,11 @@ Lastly we now have include our extendable subscription forms right in the free v
737
  * Added new section callback for settings API.
738
  * Fixed small glitch in Opt In for Credit Link.
739
 
740
- = v1.0.1 =
741
  * Removed links to getting started from "Dashboard" Admin Menu.
742
  * Added Line Height Setting to Both Title and Close, Allowing Perfect Circles for close button.
743
  * Updated admin styles.
744
  * Misc Admin changes, including new filters/hooks for upcoming extensions.
745
 
746
- = v1.0.0 =
747
  * Initial Release
1
+ ### v1.8.6 - 05/05/2019
2
+ * Fix: Typo in GDPR eraser that could sometimes result in errors when processing GDPR requests
3
+ * Fix: Added function exists check to prevent errors on WP 4.1
4
+
5
+ ### v1.8.5 - 04/17/2019
6
  * Tweak: Removed unused settings.
7
  * Fix: Typo in method name that would generate errors in some extension migration routines.
8
  * Fix: Issue when using class="" in our Popup Trigger shortcode would not get converted to classes on the element.
9
  * Fix: Bug in JS due to missing default value.
10
  * Fix: Bug older extensions caused by deprecated filter not getting loaded properly.
11
 
12
+ ### v1.8.4 - 03/21/2019
13
  * Improvement: Added content caching in the head to prevent second call to do_shortcode in the footer.
14
  * Improvement: Added runtime model caching to reduce memory usage.
15
 
16
+ ### v1.8.3 - 02/27/2019
17
  * Fix: Added back deprecated function that got truncated previously.
18
 
19
+ ### v1.8.2 - 02/25/2019
20
  * Fix: Bug on older versions of PHP due to usage of [] rather than array().
21
 
22
+ ### v1.8.1 - 02/22/2019
23
  * Fix: Error on older versions of PHP when calling get_plugin_data on a plugin that wasn't installed.
24
  * Fix: "Fatal error: Can not use method return value in write context" on older versions of PHP.
25
 
26
+ ### v1.8.0 - 02/20/2019
27
  * Feature: New popup theme settings:
28
  * New close button positions top center, bottom center, middle left & middle right.
29
  * New option to position close button outside of popup.
39
  * Fix: iOS Click overlay close not working.
40
  * Fix: Analytics not working for themes with incorrect wp_footer usage.
41
 
42
+ ### v1.7.30 - 09/06/2018
43
  * Improvement: Further added methods to log unique messages only once.
44
  * Tweak: Remove usage of Freemius.
45
  * Fix: Added option to disable popups accessibility functionality to resolve some issues with focus trapping.
49
  * Fix: Typo pointing to incorrect internal method call in new has_cookie method.
50
  * Fix: Issues with fields not being readonly.
51
 
52
+ ### v1.7.29 - 06/13/2018
53
  * Improvement: Added new enabled() method for the PUM_AssetCache class that checks both is writable and not disabled.
54
  * Improvement: Added option to disable just asset caching. This should help in the case your server is blocking the use of our JS from the /uploads/ folder with a 403 error.
55
  * Fix: Bug caused by string representations of boolean values passed in our subscription forms.
56
 
57
+ ### v1.7.28 - 06/10/2018
58
  * Tweak: Improved validation of subscription form data and messaging.
59
  * Fix: Bug with front end form serialization issue with single checkboxes (privacy field).
60
 
61
+ ### v1.7.27 - 06/08/2018
62
  * Improvement: Added additional variable checks to allow graceful failing during certain JS errors when page cache is out of date.
63
 
64
+ ### v1.7.26 - 06/07/2018
65
  * Fix: Add empty popups array to prevent errors due to page caching.
66
 
67
+ ### v1.7.25 - 06/05/2018
68
  * Tweak: Localized most variables earlier to prevent errors. Added in default values in case they do not get rendered to prevent fatal JS errors.
69
  * Fix: Tweaked extension activation class to be compatible with PHP 5.2.
70
  * Fix: Bug where boolean scalar values were changed to "" for json_encode.
71
 
72
+ ### v1.7.24 - 06/04/2018
73
  * Tweak: Updated subscriber table for existing sites that failed to add it properly before.
74
 
75
+ ### v1.7.23 - 06/04/2018
76
  * Improvement: Converted cookie privacy info to tabular rendering.
77
  * Tweak: Improved update notice text.
78
  * Fix: Issues with subscriber table not being created. Thanks @jnorell
79
  * Fix: Bug not allowing more than one cookie for a trigger.
80
  * Fix: Undefined index errors in shortcake/shortcode-ui integration.
81
 
82
+ ### v1.7.22 - 05/25/2018
83
  * Tweak: Updated Freemius library for GDPR optin support.
84
  * Improvement: Made all popup loops more reliable.
85
  * Fix: Error where objects were processed incorrectly.
86
  * Fix: "Uncaught Error: Call to a member function get_setting() on boolean in /popup-maker/classes/AssetCache.php:314"
87
 
88
+ ### v1.7.21 - 05/24/2018
89
  * Tweak: Clear asset cache on settings save.
90
  * Improvement: Check that post is singular to prevent Post Selected conditions from working on site index.
91
  * Improvement: Remove jquery-cookie from assets as we no longer use or load it anywhere.
92
  * Fix: Missing function errors if you don't have WordPress v4.9.6.
93
  * Fix: Added better & safer json encoding function that properly sanitizes data for encoding to prevent empty strings for non english sites.
94
 
95
+ ### v1.7.20 - 05/19/2018
96
  * Feature: Support for GDPR Personal Data Exporter
97
  * Feature: Support for GDPR Personal Data Eraser
98
  * Feature: New privacy consent field for Subscription Forms for GDPR consent collection.
100
  * Improvement: Updated dependency libs.
101
  * Fix: Bug in subscriber tables if no popup ID was stored.
102
 
103
+ ### v1.7.19 - 05/01/2018
104
  * Version bump due to svn file add issues during last commit.
105
 
106
+ ### v1.7.18 - 05/01/2018
107
  * Fix: Typo in JS that may cause errors for some.
108
 
109
+ ### v1.7.17 - 05/01/2018
110
  * Improvement: Added popup option to disable automatic re-triggering of popup after non-ajax form submission.
111
  * Improvement: Added notice when JS errors occur in Popup Maker admin interfaces with link to documentation for proper diagnosis & reporting.
112
  * Tweak: Added asset cache reset on update of core version & db version.
114
  * Tweak: Simplified the post type batch processor setup for extensions.
115
  * Dev: Added base PUM_Extension_Activator class to standardize extension activation and various other things.
116
 
117
+ ### v1.7.16 - 04/24/2018
118
  * Tweak: Removed debug code.
119
  * Fix: Issue with valueless shortcode attributes not processing properly.
120
  * Fix: Issues where our scripts loaded before Ninja Forms scripts did and our integration didn't initialize.
121
  * Dev: Added helper function to return array of shortcodes and data in usable format from any content.
122
  * Dev: Added support for measure fields for shortcodes.
123
 
124
+ ### v1.7.15 - 04/14/2018
125
  * Improvement: Removed metadata from object models to reduce cache size as WordPress already has them cached.
126
  * Tweak: Added new filter and corrected typo in existing ones for extension integrations.
127
  * Fix: Bug for potentially missing variable.
129
  * Fix: Bug where google fonts didn't always get loaded correctly.
130
  * Fix: Missing styles from Advanced Theme Builder due to misordering.
131
 
132
+ ### v1.7.14 - 03/28/2018
133
  * Fix: Obscure PHP error caused by method from interface was marked abstract in an abstract class inheriting the interface.
134
  * Fix: Bug when jquery cookie is called from another plugin.
135
  * Fix: Bug where form submit button triggered popup close when overlay click to close was enabled.
136
  * Fix: Typo in previous patch for db_var not being updated properly.
137
 
138
+ ### v1.7.13 - 03/27/2018
139
  * Tweak: Added fallback methods for conditions using MobileDetect to prevent errors when for whatever reason it was not loaded properly.
140
  * Tweak: Added value type check to prevent errors in popup data.
141
  * Fix: Bug with accessibility forced focus when there is a link in the popup, causing the close button to focus the link before closing.
144
  * Fix: Set a deprecated option on new installs for backward compatibility issues.
145
  * Fix: Selector correction in z-index setting application.
146
 
147
+ ### v1.7.12 - 03/21/2018
148
  * Improvement: Added option to disable the shortcode ui.
149
  * Tweak: Removed private popup type links from the nav menu editor.
150
  * Fix: Bug with long term cached assets causing JS errors on nginx servers.
153
  * Fix: Bugs in close delay settings for form integrations. Was in ms but needed to be in seconds.
154
  * Fix: Bug where Yoast SEO plugin shows popups in the xml sitemaps and showing Yoast metabox on popup editor.
155
 
156
+ ### v1.7.11 - 03/14/2018
157
  * Fix: Bug where Middle Center option wouldn't stay selected after saving.
158
  * Fix: Bug with incorrect field dependency for custom height & scrollable options.
159
 
160
+ ### v1.7.10 - 03/14/2018
161
  * Improvement: Further improved compatibility with shortcodes that echo/print rather than return content.
162
  * Fix: Bug where cookies wouldn't always be set in Edge & Safari due to cookie path including the root url.
163
  * Fix: Bug that changed the default tag for popup_trigger & popup_close shortcodes.
164
  * Fix: Bug where extra close buttons didn't always work correctly.
165
  * Fix: Removal of deprecated function that triggered warnings in PHP 7.2.
166
 
167
+ ### v1.7.9 - 03/14/2018
168
  * Improvement: Replaced usage of pumSerializeForm with pumSerializeObject which is more reliable.
169
  * Fix: Bug where deprecated directory reference causes popup html not to render properly breaking popups that should have worked otherwise.
170
  * Fix: Bug where checkbox defaults continuously applied making it impossible to uncheck them.
171
 
172
+ ### v1.7.8 - 03/13/2018
173
  * Improvement: Added output buffering to early calls to do_shortcode to prevent premature output in the head.
174
  * Improvement: Added sanity checks to make sure only valid popup objects are used in some older template functions.
175
 
176
+ ### v1.7.7 - 03/13/2018
177
  * Fix: Removed jQuery.serializeJSON functionality which was unused and causing conflicts with WooCommerce.
178
  * Fix: SSL Issues due to not specifying protocol.
179
  * Fix: Error caused by invalid popup object being used in function.
180
  * Fix: PHP 5.2 compatibility issue.
181
 
182
+ ### v1.7.6 - 03/12/2018
183
  * Fix: Undid previous changes from 1.7.1 and reworked in a new way to be backward compatible with existing extensions.
184
 
185
+ ### v1.7.5 - 03/12/2018
186
  * Fix: Sticky Popup Maker settings checkboxes that wouldn't uncheck after save.
187
 
188
+ ### v1.7.4 - 03/12/2018
189
  * Fix: Invalid method declaration error introduced by v1.7.2 patch to Shortcode core class.
190
 
191
+ ### v1.7.3 - 03/12/2018
192
  * Fix: Error due to usage of __CLASS__ rather than $this.
193
  * Fix: Edge case where function returns can't be used inside empty().
194
 
195
+ ### v1.7.2 - 03/12/2018
196
  * Fix: Initialization variable wasn't set to true early enough.
197
 
198
+ ### v1.7.1 - 03/12/2018
199
  * Fix: Empty value errors.
200
  * Fix: Missing function for 3rd party plugin backward compatibility (Elementor).
201
 
202
+ ### v1.7.0 - 03/12/2018
203
  This was a monster update, our largest to date in terms of improving existing functionality, reducing maintenance and the time it takes to implement new features in the future.
204
 
205
  Noticeably there are a lot of interface changes with this version as we simplified from having many meta boxes in the popup editor to a new single panel interface.
255
  * Fix: Bug when WPML isn't yet available.
256
 
257
 
258
+ ### v1.6.7 - Rolled into v1.7.0
259
  * Fix: Typo in JS event name prevented forceFocus for popups.
260
  * Fix: JS errors when Marionette JS library on page without Ninja Forms.
261
  * Fix: WPML missing variable errors.
262
 
263
+ ### v1.6.6 - 07/29/2017
264
  * Fix: Bug with closing forms using newest version of Gravity Forms.
265
 
266
+ ### v1.6.5 - 07/16/2017
267
  * Tweak: Added new popup class for theme names. Thanks @bluantinoo.
268
  * Fix: Bug in menu popups save and render functionality not working correctly.
269
  * Fix: Finally found issue where randomly assets tab checkboxes wouldn't uncheck & save properly.
271
  * Fix: Errors in w3c validation scans from form meta fields.
272
  * Fix: Settings asset label mismatch.
273
 
274
+ ### v1.6.4 - 07/07/2017
275
  * Imporvement: Reworked all form integrations to be as DRY as possible making it more reliable.
276
  * Tweak: Added sanity check in case previous filter mucks up the $item object variable in menu item filters causing warnings.
277
  * Tweak: Disabled the open count & sorting when Popup Analytics is activated.
284
  * Fix: Bug with GForms closing popup after submission.
285
  * Fix: Bug where CF7 Forms with required fields trigger popup to close without being filled properly.
286
 
287
+ ### v1.6.3 - 05/19/2017
288
  * Fix: Removed 3rd parameter from number_format as it only accepts 1, 2 or 4 arguments, not 3 per php.net documentation.
289
 
290
+ ### v1.6.2 - 05/18/2017
291
  * Fix: Bug caused by rounding to whole numbers in opacity values.
292
 
293
+ ### v1.6.1 - 05/17/2017
294
  * Improvement: Major improvements to the Shortcode UI (builder & in editor previews). Now supports true live rendering of PM shortcodes. This will be most apparent in upcoming extension updates.
295
  * Fix: Forced decimal formatting in CSS output functions in case of locale changes to formatting. Fix thanks to @timhavinga
296
 
297
 
298
+ ### v1.6.0 - 04/26/2017
299
  * Feature: Added Gravity Forms direct integrations.
300
  * Close popup with delay when Gravity Form is submitted.
301
  * Trigger a thank you popup when Gravity Form is submitted.
310
  * Fix: Bug where you couldn't enter values higher than the rangeslider max.
311
  * Fix: JS error when creating a cookie before a trigger exists.
312
 
313
+ ### v1.5.8 - 04/04/2017
314
  * Fix: Error when extensions were active due to null values for checkboxes.
315
 
316
 
317
+ ### v1.5.7 - 03/27/2017
318
  * Improvement: Added option to disable the menu editors in case of a conflict.
319
  * Fix: Forced 100% width on page select boxes to prevent them from being too small.
320
  * Fix: Bug where checkboxes were not staying checked.
321
 
322
+ ### v1.5.6 - 03/16/2017
323
  * Feature: Admin Bar helper tool to assist in getting proper click trigger selectors easily.
324
  * Improvement: Further tweaks for maximium compatibitlity with nav menu editor.
325
  * Improvement: Added Popup option to nav menu editor Screen Options to easily hide them.
326
  * Fix: Updated the freemius-sdk to fix an obscure secured php core function error.
327
 
328
+ ### v1.5.5 - 03/13/2017
329
  * Improvment: Used generic Nav Menu Editor Walker classes for better support. This should remove the notices from other plugins as well.
330
  * Fix: Bug that causes click triggers to lag.
331
 
332
+ ### v1.5.4 - 03/13/2017
333
  * Fix: Typos in conditions.
334
  * Fix: Moved class_exists checks to better handle possible missing class errors.
335
 
336
+ ### v1.5.3 - 03/13/2017
337
  * Improvement: Added a catch for any triggers not initialized at page load.
338
  * Fix: Typo in multi check field template that led to admin JS errors.
339
 
340
+ ### v1.5.2 - 03/10/2017
341
  * Improvement: Added option to disable the admin bar Popups helper menu item.
342
  * Improvement: Simplified the nav menu editor modification class to reduce un-needed translation strings.
343
  * Fix: Added check for missing class in the nav menu editor walker classes.
344
 
345
+ ### v1.5.1 - 03/09/2017
346
  * Fix: PHP 5.2 Compatibility issue.
347
 
348
+ ### v1.5.0 - 03/08/2017
349
  * Feature: Position popups based on the click trigger. Tooltips & Popovers are now possible.
350
  * Feature: Added new conditions for targeting children & grandchildren / ancestors of selected content.
351
  * Feature: Added new settings to the Nav Menu editor to choose a popup that a menu item will trigger.
371
  * Fix: Bug where links in the close button were not triggered even when do_default was enabled.
372
  * Fix: Bug with scrollbar "flashing" when popup opens.
373
 
374
+ ### v1.4.21 - 12/12/2016
375
  * Feature: Added option to disable popup on mobile to comply with [Google's new interstital policy](https://webmasters.googleblog.com/2016/08/helping-users-easily-access-content-on.html).
376
  * Tweak: Added additional paramter to the pum_popup_get_conditions filter.
377
  * Tweak: Fixed possible false init of NF integration if NF is not enabled.
378
  * Tweak: Added CSS override for Ninja Forms datepickers to properly layer them above popups.
379
 
380
+ ### v1.4.20 - 10/13/2016
381
  * Feature: Added [Ninja Forms](https://wppopupmaker.com/grab/ninja-forms?utm_source=readme-changelog&utm_medium=text-link&utm_campaign=Readme&utm_content=ninja-forms-features) success actions for opening & closing popups.
382
  * Feature: Added new cookie event for successful submission of a [Ninja Forms](https://wppopupmaker.com/recommends/ninja-forms) form.
383
  * Improvement: Added wp.hooks JS library, allowing actions & filters via our plugin JS.
384
  * Tweaks: Added various admin css tweaks.
385
 
386
+ ### v1.4.19 - 9/30/2016
387
  * Feature: Added a do_default parameter to the trigger & close shortcodes. This allows making close buttons that also download a file.
388
  * Improvement: Added support for JS (advanced) conditions & condition processing after checking for cookies.
389
  * Improvement: Upgraded from jQuery-Cookie (modified) to JS-Cookie (modified) for more flexibility.
391
  * Fix: Added prefix to admin pages to prevent conflicts.
392
  * Fix: Removed usage of deprecated filter.
393
 
394
+ ### v1.4.18 - 8/15/2016
395
  * Fix: Bug with PHP 5.2 compatibility.
396
  * Fix: Added missing post_type index condition callback.
397
 
398
+ ### v1.4.17 - 8/14/2016
399
  * Fix: Bug caused by using return value in write context.
400
 
401
+ ### v1.4.16 - 8/14/2016
402
  * Feature: New Condition: Pages: With Template. Thanks @cedmund.
403
  * Feature: Option to Disable reposition on window resize/scroll.
404
  * Improvement: Enable Visual Composer for Popups by default (VC 4.8+). Thanks @NoahjChampion.
410
  * Fix: Error in JS due to shortcodes: Uncaught Error: Syntax error, unrecognized expression.
411
  * Fix: Issue where some custom post types not working with conditions.
412
 
413
+ ### v1.4.15 - 7/20/2016
414
  * Improvement: Only showed the aria-label attribute if the label will be shown.
415
  * Tweak: Updated the Freemius SDK.
416
  * Tweak: Updated the #popmake-{ID} selector to work at the end of a link.
417
  * Fix: Bug where stackable popups would lose their scroll bar after one was closed.
418
 
419
+ ### v1.4.14 - 7/14/2016
420
  * Feature: Links with the url #popmake-{ID} will now trigger a popup when clicked. Links with this href will work similar to elements with the popmake-{ID} class.
421
 
422
+ ### v1.4.13 - 6/26/2016
423
  * Feature: Added 12 of the most commonly needed BuddyPress content types & targeting conditions. Target any BP content type. Now full support for BuddyPress.
424
  * Tweak: Moved a few functions from the plugins_loaded action to the init action for minor compatibility benefits.
425
  * Tweak: Removed Popup & Popup Theme Meta Revisioning as it adds unneeded clutter to the DB.
426
 
427
+ ### v1.4.12 - 6/24/2016
428
  * Improvement: Reduced translatable strings from 569 total to 439 which is about a 23% reduction which will reduce work for our translators.
429
  * Tweak: Removed the welcome page and associated CSS, images etc. This cleans up some useless strings for translation.
430
  * Fix: Bug where add_new cookie wasn't properly replaced for the first trigger.
431
 
432
+ ### v1.4.11 - 6/10/2016
433
  * Feature: New conditions for targeting posts & taxonomy by ID.
434
  * Improvement: Added link to Conditions Documentation to the Conditions editor.
435
  * Tweak: Namespaced jQuery.serializeObject to prevent conflicts with other plugins/themes in the admin editor.
436
  * Fix: Bug on add new page/post and during post update.
437
  * Fix: Bug in edit this theme link on page load.
438
 
439
+ ### v1.4.10 - 5/23/2016
440
  * Feature: Added Do Default option to the click triggers. Allows a triggers default browsers behavior to occur and still open a popup, such as a file link.
441
  * Improvement: Added additional links to the theme editor for better visibility and to guide users there.
442
  * Tweak: Older methods are only loaded when needed, this also removes usage of a deprecated filter.
447
  * Fix: Cleaned up issues allowing popup post type to be added directly to menus and sitemaps.
448
  * Fix: Bug where auto height checkbox would not stay checked.
449
 
450
+ ### v1.4.9 - 5/01/2016
451
  * Improvement: Reduced front end queries by over 85%. Avgerage sites should now only have 2 to 3.
452
  * Improvement: Added caching enhancements for even better performance on servers with page, object & query caching.
453
  * Improvement: Added a fully namespaced version of Select2 for compatiblitiy while other plugins await updating. Will gracefully fall back to the non namespaced version when it no longer causes issues.
455
  * Fix: The "Use Your Theme" font option was not working correctly.
456
  * Fix: Removed leftover console.logs in our JavaScript.
457
 
458
+ ### v1.4.8 - 4/27/2016
459
  * Improvement: Sandboxed Select2 v4 since it breaks other plugins when loaded properly. v4 adds accessiblity enhancements that we are not going to sacrifice for compatiblity with plugins who have not updated to include it. This provides a safe alternative in the meantime.
460
  * Tweak: Removed extra shortcode files.
461
  * Tweak: Allow popup Click Triggers to target another popups close button. Close one triggers another etc.
462
  * Fix: Bug caused by pum_shortcode_ui not loading properly everywhere.
463
  * Fix: Bug in popup position calculation when the popup used Fixed Position and Disable Overlay
464
 
465
+ ### v1.4.7 - 4/24/2016
466
  * Improvement: Removed the old styles dropdown as it is no longer needed.
467
  * Improvement: Added check for old versions of Select2 and replace them with latest which is backward compatible.
468
  * Fix: Bug that caused Close button delay to not show the close button.
469
  * Fix: Replaced usage of <% style JS template with <# & {{ for PHP asp_tags compatibility.
470
 
471
+ ### v1.4.6 - 4/22/2016
472
  * Fix: Bug in new post editor JS.
473
  * Fix: Added filter to override permissions for upgrade routines.
474
 
475
+ ### v1.4.5 - 4/21/2016
476
  * Fix: Replaced all usage of static:: for PHP 5.2 compatiblity.
477
  * Fix: Forced the latest version of Select2 to load on Popup Maker admin pages in the case that an older version was enqueued.
478
 
479
+ ### v1.4.4 - 4/20/2016
480
  * Fix: Version Bump to fix upgrade issues.
481
 
482
+ ### v1.4.3 - 4/20/2016
483
  * Fix: Removed extra whitespace before opening php tags.
484
 
485
+ ### v1.4.2 - 4/20/2016
486
  * Fix: Bug in popup maker deprecated filter caused by no defaults passed.
487
 
488
+ ### v1.4.1 - 4/20/2016
489
  * Fix: Bug in popup maker upgrade class for older versions of PHP.
490
 
491
+ ### v1.4 - 4/20/2016
492
  * Feature: Added basic analytics. Tracks how many unique opens each popup has.
493
  * Feature: Added new Popup Maker shortcodes button to the editor with visual previews.
494
  * Feature: Added option to reset popup open counts demand.
528
  365 Commits / 53 Major & Minor Issues Closed.
529
  285 changed files with 20,437 additions and 3,607 deletions.
530
 
531
+ ### v1.3.9 - 10/14/2015
532
  * Feature: New shortcode - [popup_close] allows adding custom close buttons/text. Ex. [popup_close] Click Me [/popup_close].
533
  * Improvement: Added SASS/SCSS files for the site & admin styles.
534
  * Improvement: Added better support for current & legacy versions of Visual Composer.
539
  * Fix: Fixed bug in CSS that caused popup to appear below site on mobile.
540
  * Fix: WP Multi Site: Fatal Error.
541
 
542
+ ### v1.3.8 - 9/29/2015
543
  * Fix: Updated links to documentation.
544
  * Fix: Removed exploitable bug allowing script execution in the admin. Discovered 9/29/15 - Patched 9/29/15
545
 
546
+ ### v1.3.7 - 9/21/2015
547
  * Feature: Added support for Visual Composer to popups. (Backend Editor Only). Works Perfectly with Responsive Popups.
548
  * Tweak: Disable position fixed on mobile screens for responsive popups.
549
  * Tweak: Improved UI with better popup formats selection.
555
  * Fix: Bug with targeting conditions for categories.
556
  * Fix: Bug in positioning left & right values. Credit to @invik for the solution.
557
 
558
+ ### v1.3.6 - 8/25/2015
559
  * Confirmed WP v4.3 compatibility.
560
  * Tweak: Default theme is automatically used if a popup does not have one assigned.
561
  * Fix: UI bug where fixed position checkbox wouldn't stay checked.
562
  * Fix: Bug with Theme Default values & v1.2 values not being merged.
563
 
564
+ ### v1.3.5 - 8/18/2015
565
  * Tweak: Corrected missing keys for required script checks.
566
  * Fix: Error message caused by non array value from get_post_custom.
567
  * Fix: Removed missing variable.
568
  * Fix: Text corrections.
569
 
570
+ ### v1.3.4 - 8/12/2015
571
  * Fix: Added px to font-size & line-height.
572
 
573
+ ### v1.3.3 - 8/12/2015
574
  * Fix: Added current_action fallback function for older versions of WP.
575
  * Fix: Theme CSS rendering incorrect font settings.
576
 
577
+ ### v1.3.2 - 8/10/2015
578
  * Tweak: Pause HTML5 Videos when popup closes.
579
  * Fix: Prefixed several functions that collided with some themes.
580
  * Fix: Changed default Close Height & Width to 0/auto.
581
 
582
+ ### v1.3.1 - 8/8/2015
583
  * Fix: Error in get_called_class alternate function for PHP 5.2
584
  * Fix: Force theme css builder to check for empty themes.
585
  * Fix: Bug where z-indexes were incorrectly set.
586
 
587
+ ### v1.3 - 8/7/2015
588
  * Feature: Added unlimited themes functionality to the core.
589
  * Feature: Allow disabling of event.prevendDefault() for on click events by adding do-default class.
590
  * Feature: Added support for session based cookies.
623
  * Fix: Bug where popup & popup_theme meta was stored with other post types on revision.
624
  * Fix: Bug in the popup_trigger shortcode with $content not being rendered properly.
625
 
626
+ ### v1.2.2
627
  * Added (string) typecast to prevent errors in wp_localize_script when passing integers.
628
  * Added 100% French & Hungarian translations.
629
  * Added partial German translation.
640
  * Temporarily removed the grow animations due to removal of Greensock Animation Platform.
641
  * Removed Greensock Animation Platform dependancy.
642
 
643
+ ### v1.2.1
644
  * Fixed bug caused by null value passed to JS data attr.
645
 
646
+ ### v1.2
647
  * Added full screen preview for themes when editing using the Preview button.
648
  * Added full screen preview for popup when editing using the Preview button.
649
  * Added new shortcode 'popup_trigger' that allows users to easily add the correct popmake- class. Accepts id, tag & class parameters.
657
  * Added function to prevent deletion of default theme.
658
  * Fixed bug which caused Popup Maker menu to show to all users.
659
 
660
+ ### v1.1.10
661
  * Fixed invalid argument bug passed to google font foreach.
662
  * Fixed CSS box-sizing cross browser support.
663
 
664
+ ### v1.1.9
665
  * Added %'s to reponsive sizes in size dropdown.
666
  * Remove usage of the_content and the_content filters.
667
  * Fixed responsive sizes.
668
 
669
+ ### v1.1.8
670
  * Fixed issue with admin menu position collisions.
671
  * Fixed issue with banner not staying dismissed.
672
  * Removed dependency jQuery.cookie
680
  * Disabled Popup Maker JS & CSS when no popups detected to load.
681
  * Added new function popmake_enqueue_scripts() which allows manual enqueuing of scripts and styles.
682
 
683
+ ### v1.1.7
684
  * Fixed undefined function popmake_default_settings.
685
  * Fixed specific pages not saving properly.
686
  * Now removes ?autoplay parameter from Videos preventing them from playing again without interaction.
687
 
688
+ ### v1.1.6
689
  * Fixed bug in js not setting correct CSS value for min-width.
690
  * Changed close link element tag from a > span.
691
 
692
+ ### v1.1.5
693
  * Fixed bug when clicking add selected buttons.
694
  * Changed how popmake_popup_is_loadable works. It is now more organized and readable.
695
  * Added 2 new Targeting Conditions: Search & 404.
696
 
697
+ ### v1.1.4
698
  * Fixed bug in scrollable content styles.
699
  * Fixed bug in admin JS for duplicate input names.
700
  * Changed Powered By Setting to Off by Default.
701
  * Changed default permissions required to use theme builder.
702
  * Fixed bug in targeting conditions.
703
 
704
+ ### v1.1.3
705
  * Fixed some incorrect links to resources and kb.
706
  * Removed Auto Open Promotional Material ( as it is now included ).
707
 
708
+ ### v1.1.2
709
  * Further enhancements to ensure proper checking of Auto Open Enabled.
710
 
711
+ ### v1.1.1
712
  * Fixed bug in JS that didn't properly check if Auto Open was enabled.
713
 
714
+ ### v1.1
715
  * Added Importer for Easy Modal v2 - Availabe under Tools -> Import
716
  * Added Easy Modal v2 Compatibility Option - Available under Settings -> Misc (This will allow all of your existing eModal classes to open the proper Popup once imported)
717
  * Added custom selector functionality - Availabe on Modal editor (This will allow you to use your own css selectors that when clicked will trigger the popup to open. Ex. #main-menu li.menu-item-3 would cause the corresponding menu item to trigger that popup)
718
 
719
+ ### v1.0.5
720
  * Fixed bug caused by changes in v1.0.4.
721
 
722
+ ### v1.0.4
723
  * Admin UI Adjustments & Tweaks.
724
  * Fixed bug in removing specific post types.
725
  * Reformatted Code.
726
  * Fixed incorrect variable.
727
 
728
+ ### v1.0.3
729
  * Fixed bug with recursive filter.
730
  * Fixed bug caused by typo.
731
  * Fixed bug in JS for removing specific post type posts.
732
 
733
+ ### v1.0.2
734
  * Resized Extension page images to load quicker on extensions page.
735
  * Added last_open_popup proerty to popmake jQuery function.
736
  * Resized Extension page images to load quicker on extensions page.
741
  * Added new section callback for settings API.
742
  * Fixed small glitch in Opt In for Credit Link.
743
 
744
+ ### v1.0.1
745
  * Removed links to getting started from "Dashboard" Admin Menu.
746
  * Added Line Height Setting to Both Title and Close, Allowing Perfect Circles for close button.
747
  * Updated admin styles.
748
  * Misc Admin changes, including new filters/hooks for upcoming extensions.
749
 
750
+ ### v1.0.0
751
  * Initial Release
classes/Privacy.php CHANGED
@@ -1,458 +1,458 @@
1
- <?php
2
- /*******************************************************************************
3
- * Copyright (c) 2018, WP Popup Maker
4
- ******************************************************************************/
5
-
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
-
11
- /**
12
- * Class PUM_Privacy
13
- */
14
- class PUM_Privacy {
15
-
16
- public static function init() {
17
- add_filter( 'wp_privacy_personal_data_exporters', array( __CLASS__, 'register_exporter' ), 10 );
18
- add_filter( 'wp_privacy_personal_data_erasers', array( __CLASS__, 'register_erasers' ), 10 );
19
- add_action( 'admin_init', array( __CLASS__, 'privacy_policy_content' ), 20 );
20
- add_action( 'pum_save_popup', array( __CLASS__, 'clear_cookie_list' ) );
21
- }
22
-
23
- public static function clear_cookie_list() {
24
- delete_option( 'pum_privacy_cookie_list' );
25
- }
26
-
27
- /**
28
- * Add the suggested privacy policy text to the policy postbox.
29
- */
30
- public static function privacy_policy_content() {
31
- if ( function_exists( 'wp_add_privacy_policy_content' ) ) {
32
- $content = self::default_privacy_policy_content( true );
33
- wp_add_privacy_policy_content( __( 'Popup Maker', 'popup-maker' ), $content );
34
- }
35
- }
36
-
37
- /**
38
- * Return the default suggested privacy policy content.
39
- *
40
- * @param bool $descr Whether to include the descriptions under the section headings. Default false.
41
- *
42
- * @return string The default policy content.
43
- */
44
- public static function default_privacy_policy_content( $descr = false ) {
45
- $suggested_text = $descr ? '<strong class="privacy-policy-tutorial">' . __( 'Suggested text:', 'popup-maker' ) . ' </strong>' : '';
46
- ob_start();
47
- ?>
48
- <div class="pum-suggested-text">
49
- <p class="privacy-policy-tutorial"><?php _e( 'Hello,', 'popup-maker' ); ?></p> <p class="privacy-policy-tutorial"><?php _e( 'This information serves as a guide on what sections need to be modified due to usage of Popup Maker and its extensions.', 'popup-maker' ); ?></p>
50
- <p class="privacy-policy-tutorial"><?php _e( 'You should include the information below in the correct sections of you privacy policy.', 'popup-maker' ); ?></p>
51
- <p class="privacy-policy-tutorial"><strong> <?php _e( 'Disclaimer:', 'popup-maker' ); ?></strong> <?php _e( 'This information is only for guidance and not to be considered as legal advice.', 'popup-maker' ); ?></p>
52
- <p class="privacy-policy-tutorial"><strong> <?php _e( 'Note:', 'popup-maker' ); ?></strong> <?php _e( 'Some of the information below is dynamically generated, such as cookies. If you add or change popups you will see those additions or changes below and will need to update your policy accordingly.', 'popup-maker' ); ?>
53
- </p>
54
-
55
- <h2><?php _e( 'What personal data we collect and why we collect it', 'popup-maker' ); ?></h2>
56
-
57
- <h3><?php _e( 'Subscription forms', 'popup-maker' ); ?></h3>
58
- <p class="privacy-policy-tutorial"><?php _e( 'Popup Maker subscription forms are not enabled by default.', 'popup-maker' ); ?></p>
59
- <p class="privacy-policy-tutorial"><?php _e( 'If you have used them in your popups to collect email subscribers, use this subsection to note what personal data is captured when someone submits a subscription form, and how long you keep it.', 'popup-maker' ); ?></p>
60
- <p class="privacy-policy-tutorial"><?php _e( 'For example, you may note that you keep form submissions for ongoing marketing purposes.', 'popup-maker' ); ?></p>
61
- <p><?php echo $suggested_text . __( 'If you submit a subscription form on our site you will be opting in for us to save your name, email address and other relevant information.', 'popup-maker' ); ?></p>
62
- <p><?php _e( 'These subscriptions are used to notify you about related content, discounts & other special offers.', 'popup-maker' ); ?></p> <p><?php _e( 'You can opt our or unsubscribe at any time in the future by clicking link in the bottom of any email.', 'popup-maker' ); ?></p>
63
-
64
- <h3><?php _e( 'Cookies', 'popup-maker' ); ?></h3>
65
- <p class="privacy-policy-tutorial"><?php _e( 'Popup Maker uses cookies for most popups. The primary function is to prevent your users from being annoyed by seeing the same popup repeatedly.', 'popup-maker' ); ?></p>
66
- <p class="privacy-policy-tutorial"><?php _e( 'This may result in cookies being saved for an extended period of time. These are non-tracking cookies used only by our popups.', 'popup-maker' ); ?></p>
67
-
68
- <?php
69
- $cookies = self::get_all_cookies();
70
- if ( ! empty( $cookies ) ) : ?>
71
- <p class="privacy-policy-tutorial"><?php _e( 'Below is a list of all cookies currently registered within your popup settings. These are here for you to disclose if you are so required.', 'popup-maker' ); ?></p>
72
- <table class="wp-list-table" style="width: 100%;">
73
- <thead>
74
- <tr>
75
- <th align="left"><?php _e( 'Cookie Name', 'popup-maker' ); ?></th>
76
- <th align="left"><?php _e( 'Usage', 'popup-maker' ); ?></th>
77
- <th align="left"><?php _e( 'Time', 'popup-maker' ); ?></th>
78
- </tr>
79
- </thead>
80
- <tbody style="border: 1px solid;"><?php
81
- foreach ( $cookies as $cookie ) {
82
- if ( ! is_array( $cookie ) ) {
83
- continue;
84
- }
85
-
86
- $cookie = wp_parse_args( $cookie, array(
87
- 'name' => '',
88
- 'label' => '',
89
- 'time' => '',
90
- ) );
91
-
92
- printf( '<tr><td style="border-top: 1px dashed;">%s</td><td style="border-top: 1px dashed;">%s</td><td style="border-top: 1px dashed;">%s</td></tr>', $cookie['name'], $cookie['label'], $cookie['time'] );
93
- }
94
- ?>
95
- </tbody>
96
- </table>
97
- <?php
98
- endif; ?>
99
-
100
- <p><?php echo $suggested_text . __( 'We use anonymous cookies to prevent users from seeing the same popup repetitively in an attempt to make our users experience more pleasant while still delivering time sensitive messaging.', 'popup-maker' ); ?></p>
101
-
102
- <h3><?php _e( 'Analytics', 'popup-maker' ); ?></h3>
103
- <p class="privacy-policy-tutorial"><?php _e( 'Popup Maker anonymously tracks popup views and conversions.', 'popup-maker' ); ?></p>
104
-
105
- <h2><?php _e( 'How long we retain your data', 'popup-maker' ); ?></h2>
106
- <p><?php _e( 'Subscriber information is retained in the local database indefinitely for analytic tracking purposes and for future export.', 'popup-maker' ); ?></p>
107
- <p><?php _e( 'Data will be exported or removed upon users request via the existing Exporter or Eraser.', 'popup-maker' ); ?></p> <p><?php _e( 'If syncing data to a 3rd party service (for example Mailchimp), data is retained there until unsubscribed or deleted.', 'popup-maker' ); ?></p>
108
-
109
- <h2><?php _e( 'Where we send your data', 'popup-maker' ); ?></h2>
110
- <p><?php _e( 'Popup Maker does not send any user data outside of your site by default.', 'popup-maker' ); ?></p>
111
- <p><?php _e( 'If you have extended our subscription forms to send data to a 3rd party service such as Mailchimp, user info may be passed to these external services. These services may be located abroad.', 'popup-maker' ); ?></p>
112
- </div>
113
-
114
- <?php
115
- $content = ob_get_clean();
116
-
117
- /**
118
- * Filters the default content suggested for inclusion in a privacy policy.
119
- *
120
- * @param $content string The default policy content.
121
- */
122
- return apply_filters( 'pum_get_default_privacy_policy_content', $content );
123
-
124
- }
125
-
126
- /**
127
- * Register exporter for Popup Maker Optin Form Subscriber Data.
128
- *
129
- * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
130
- *
131
- * @param $exporters
132
- *
133
- * @return array
134
- */
135
- public static function register_exporter( $exporters ) {
136
- $exporters[] = array(
137
- 'exporter_friendly_name' => __( 'Popup Maker Subscribe Form' ),
138
- 'callback' => array( __CLASS__, 'exporter' ),
139
- );
140
-
141
- return $exporters;
142
- }
143
-
144
- /**
145
- * Register erasers for Popup Maker Optin Form Subscriber Data.
146
- *
147
- * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
148
- *
149
- * @param $exporters
150
- *
151
- * @return array
152
- */
153
- public static function register_erasers( $exporters ) {
154
- $exporters[] = array(
155
- 'eraser_friendly_name' => __( 'Popup Maker Subscribe Form' ),
156
- 'callback' => array( __CLASS__, 'exporter' ),
157
- );
158
-
159
- return $exporters;
160
- }
161
-
162
- /**
163
- * Exporter for Popup Maker Optin Form Subscriber Data.
164
- *
165
- * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
166
- *
167
- * @param $email_address
168
- * @param int $page
169
- *
170
- * @return array
171
- */
172
- public static function exporter( $email_address, $page = 1 ) {
173
- $number = 500; // Limit us to avoid timing out
174
- $page = (int) $page;
175
-
176
- $export_items = array();
177
- $subscribers = PUM_DB_Subscribers::instance()->query( array(
178
- 's' => $email_address,
179
- 'page' => $page,
180
- 'limit' => $number,
181
- 'orderby' => 'ID',
182
- 'order' => 'ASC',
183
- ), 'ARRAY_A' );
184
-
185
- foreach ( (array) $subscribers as $subscriber ) {
186
- if ( $subscriber['email'] == $email_address ) {
187
- // Most item IDs should look like postType-postID
188
- // If you don't have a post, comment or other ID to work with,
189
- // use a unique value to avoid having this item's export
190
- // combined in the final report with other items of the same id
191
- $item_id = "pum-subscriber-{$subscriber['ID']}";
192
-
193
- // Core group IDs include 'comments', 'posts', etc.
194
- // But you can add your own group IDs as needed
195
- $group_id = 'pum-subscribers';
196
-
197
- // Optional group label. Core provides these for core groups.
198
- // If you define your own group, the first exporter to
199
- // include a label will be used as the group label in the
200
- // final exported report
201
- $group_label = __( 'Subscriber Data' );
202
-
203
- // Plugins can add as many items in the item data array as they want
204
-
205
- $data = array();
206
-
207
- foreach ( $subscriber as $field_key => $field_value ) {
208
- switch ( $field_key ) {
209
- case 'ID':
210
- $data[] = array(
211
- 'name' => __( 'ID', 'popup-maker' ),
212
- 'value' => $field_value,
213
- );
214
- break;
215
- case 'email':
216
- $data[] = array(
217
- 'name' => __( 'Email', 'popup-maker' ),
218
- 'value' => $field_value,
219
- );
220
- break;
221
- case 'name':
222
- $data[] = array(
223
- 'name' => __( 'Name', 'popup-maker' ),
224
- 'value' => $field_value,
225
- );
226
- break;
227
- case 'fname':
228
- $data[] = array(
229
- 'name' => __( 'First Name', 'popup-maker' ),
230
- 'value' => $field_value,
231
- );
232
- break;
233
- case 'lname':
234
- $data[] = array(
235
- 'name' => __( 'Last Name', 'popup-maker' ),
236
- 'value' => $field_value,
237
- );
238
- break;
239
- case 'consent':
240
- $data[] = array(
241
- 'name' => __( 'Provided Consent', 'popup-maker' ),
242
- 'value' => ucfirst( $field_value ),
243
- );
244
- break;
245
- case 'values':
246
- case 'consent_args':
247
- $values = maybe_unserialize( $field_value );
248
-
249
- foreach ( (array) $values as $key => $value ) {
250
-
251
- // Empty values don't need to be rendered.
252
- if ( empty( $value ) ) {
253
- continue;
254
- }
255
-
256
- $label = '';
257
-
258
- switch ( $key ) {
259
- case 'provider':
260
- $providers = PUM_Newsletter_Providers::instance()->get_providers();
261
-
262
- if ( ! empty( $providers[ $value ] ) ) {
263
- $label = $providers[ $value ]->name;
264
- }
265
- break;
266
- case 'required':
267
- $label = __( 'Consent Required', 'popup-maker' );
268
- break;
269
- case 'text':
270
- $label = __( 'Consent Text', 'popup-maker' );
271
- break;
272
- case 'name':
273
- case 'lname':
274
- case 'email':
275
- case 'fname':
276
- case 'list_id':
277
- case 'popup_id':
278
- case 'email_hash':
279
- case 'pum_form_popup_id':
280
- case 'mc_args':
281
- // Leave these values out.
282
- break;
283
- }
284
-
285
- $label = apply_filters( 'pum_privacy_subscriber_value_label', $label, $key, $value );
286
-
287
- if ( ! empty( $label ) ) {
288
- $data[] = array(
289
- 'name' => $label,
290
- 'value' => $value,
291
- );
292
- }
293
- }
294
-
295
- break;
296
- case 'created':
297
- $data[] = array(
298
- 'name' => __( 'Date Subscribed', 'popup-maker' ),
299
- 'value' => $field_value,
300
- );
301
- break;
302
- }
303
- }
304
-
305
- $export_items[] = array(
306
- 'group_id' => $group_id,
307
- 'group_label' => $group_label,
308
- 'item_id' => $item_id,
309
- 'data' => $data,
310
- );
311
- }
312
-
313
- }
314
-
315
- // Tell core if we have more comments to work on still
316
- $done = count( $subscribers ) < $number;
317
-
318
- return array(
319
- 'data' => $export_items,
320
- 'done' => $done,
321
- );
322
- }
323
-
324
-
325
- /**
326
- * Eraser for Popup Maker Optin Form Subscriber Data.
327
- *
328
- * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
329
- *
330
- * @param $email_address
331
- * @param int $page
332
- *
333
- * @return array
334
- */
335
- public static function eraser( $email_address, $page = 1 ) {
336
- if ( empty( $email_address ) ) {
337
- return array(
338
- 'items_removed' => false,
339
- 'items_retained' => false,
340
- 'messages' => array(),
341
- 'done' => true,
342
- );
343
- }
344
-
345
- $messages = array();
346
- $items_removed = false;
347
- $items_retained = false;
348
-
349
- $number = 500; // Limit us to avoid timing out
350
- $page = (int) $page;
351
-
352
- $subscribers = PUM_DB_Subscribers::instance()->query( array(
353
- 's' => $email_address,
354
- 'page' => $page,
355
- 'limit' => $number,
356
- 'orderby' => 'ID',
357
- 'order' => 'ASC',
358
- ), 'ARRAY_A' );
359
-
360
- foreach ( (array) $subscribers as $subscriber ) {
361
- if ( $subscriber['email'] == $email_address ) {
362
-
363
- // Data should not be deleted if the user was left subscribed to a service provider.
364
- $unsubscribed = apply_filters( 'pum_privacy_eraser_subscriber_was_unsubscribed', true, $email_address, $subscriber );
365
-
366
- if ( $unsubscribed ) {
367
-
368
- $deleted = PUM_DB_Subscribers::instance()->delete( $subscriber['ID'] );
369
-
370
- if ( $deleted ) {
371
- $items_removed = true;
372
- } else {
373
- $items_retained = true;
374
- $messages[] = __( 'Subscription information was not removed. A database error may have occurred during deletion.', 'popup-maker' );
375
- }
376
- } else {
377
- $items_retained = true;
378
- $messages[] = __( 'Subscription information was not removed. This may occur when no immediate confirmation is received during our attempt to unsubscribe you from our mailing list.', 'popup-maker' );
379
- }
380
-
381
- }
382
-
383
- }
384
-
385
- // Tell core if we have more comments to work on still
386
- $done = count( $subscribers ) < $number;
387
-
388
- return array(
389
- 'items_removed' => $items_removed,
390
- 'items_retained' => $items_retained,
391
- 'messages' => $messages,
392
- 'done' => $done,
393
- );
394
- }
395
-
396
- /**
397
- * @return array
398
- */
399
- public static function get_all_cookies() {
400
- $cookie_list = get_option( 'pum_privacy_cookie_list' );
401
- $cookies = ! empty( $cookie_list['cookies'] ) ? $cookie_list['cookies'] : array();
402
-
403
- if ( false === $cookie_list || ! isset( $cookie_list['timestamp'] ) || strtotime('-7 days' ) > $cookie_list['timestamp'] ) {
404
- $popups = pum_get_all_popups();
405
-
406
- if ( ! empty( $popups ) ) {
407
-
408
- foreach ( $popups as $popup ) {
409
-
410
- if ( ! pum_is_popup( $popup ) ) {
411
- continue;
412
- }
413
-
414
- // Set this popup as the global $current.
415
- pum()->current_popup = $popup;
416
-
417
- $popup_cookies = $popup->get_setting( 'cookies', array() );
418
-
419
- if ( ! empty( $popup_cookies ) ) {
420
- foreach ( $popup_cookies as $cookie ) {
421
- if ( ! empty ( $cookie['settings']['name'] ) ) {
422
- $current_time = 0;
423
- if ( ! empty( $cookies[ $cookie['settings']['name'] ] ) ) {
424
- $current_time = strtotime( '+' . $cookies[ $cookie['settings']['name'] ]['time'] );
425
- }
426
-
427
- if ( empty( $cookies[ $cookie['settings']['name'] ] ) ) {
428
- $cookies[ $cookie['settings']['name'] ] = array(
429
- 'label' => __( 'Cookie used to prevent popup from displaying repeatedly.', 'popup-maker' ),
430
- 'name' => $cookie['settings']['name'],
431
- 'time' => $cookie['settings']['time'],
432
- );
433
- }
434
-
435
- $new_time = strtotime( '+' . $cookie['settings']['time'] );
436
- if ( $new_time > $current_time ) {
437
- $cookies[ $cookie['settings']['name'] ]['time'] = $cookie['settings']['time'];
438
- }
439
- }
440
- }
441
- }
442
- }
443
-
444
- // Clear the global $current.
445
- pum()->current_popup = null;
446
-
447
- }
448
-
449
- // Update cookie list so we don't have to regenerate it every page load.
450
- update_option( 'pum_privacy_cookie_list', array(
451
- 'cookies' => $cookies,
452
- 'timestamp' => strtotime( 'now' ),
453
- ) );
454
- }
455
-
456
- return apply_filters( 'pum_privacy_get_all_cookies', $cookies );
457
- }
458
  }
1
+ <?php
2
+ /*******************************************************************************
3
+ * Copyright (c) 2018, WP Popup Maker
4
+ ******************************************************************************/
5
+
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+
11
+ /**
12
+ * Class PUM_Privacy
13
+ */
14
+ class PUM_Privacy {
15
+
16
+ public static function init() {
17
+ add_filter( 'wp_privacy_personal_data_exporters', array( __CLASS__, 'register_exporter' ), 10 );
18
+ add_filter( 'wp_privacy_personal_data_erasers', array( __CLASS__, 'register_erasers' ), 10 );
19
+ add_action( 'admin_init', array( __CLASS__, 'privacy_policy_content' ), 20 );
20
+ add_action( 'pum_save_popup', array( __CLASS__, 'clear_cookie_list' ) );
21
+ }
22
+
23
+ public static function clear_cookie_list() {
24
+ delete_option( 'pum_privacy_cookie_list' );
25
+ }
26
+
27
+ /**
28
+ * Add the suggested privacy policy text to the policy postbox.
29
+ */
30
+ public static function privacy_policy_content() {
31
+ if ( function_exists( 'wp_add_privacy_policy_content' ) ) {
32
+ $content = self::default_privacy_policy_content( true );
33
+ wp_add_privacy_policy_content( __( 'Popup Maker', 'popup-maker' ), $content );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Return the default suggested privacy policy content.
39
+ *
40
+ * @param bool $descr Whether to include the descriptions under the section headings. Default false.
41
+ *
42
+ * @return string The default policy content.
43
+ */
44
+ public static function default_privacy_policy_content( $descr = false ) {
45
+ $suggested_text = $descr ? '<strong class="privacy-policy-tutorial">' . __( 'Suggested text:', 'popup-maker' ) . ' </strong>' : '';
46
+ ob_start();
47
+ ?>
48
+ <div class="pum-suggested-text">
49
+ <p class="privacy-policy-tutorial"><?php _e( 'Hello,', 'popup-maker' ); ?></p> <p class="privacy-policy-tutorial"><?php _e( 'This information serves as a guide on what sections need to be modified due to usage of Popup Maker and its extensions.', 'popup-maker' ); ?></p>
50
+ <p class="privacy-policy-tutorial"><?php _e( 'You should include the information below in the correct sections of you privacy policy.', 'popup-maker' ); ?></p>
51
+ <p class="privacy-policy-tutorial"><strong> <?php _e( 'Disclaimer:', 'popup-maker' ); ?></strong> <?php _e( 'This information is only for guidance and not to be considered as legal advice.', 'popup-maker' ); ?></p>
52
+ <p class="privacy-policy-tutorial"><strong> <?php _e( 'Note:', 'popup-maker' ); ?></strong> <?php _e( 'Some of the information below is dynamically generated, such as cookies. If you add or change popups you will see those additions or changes below and will need to update your policy accordingly.', 'popup-maker' ); ?>
53
+ </p>
54
+
55
+ <h2><?php _e( 'What personal data we collect and why we collect it', 'popup-maker' ); ?></h2>
56
+
57
+ <h3><?php _e( 'Subscription forms', 'popup-maker' ); ?></h3>
58
+ <p class="privacy-policy-tutorial"><?php _e( 'Popup Maker subscription forms are not enabled by default.', 'popup-maker' ); ?></p>
59
+ <p class="privacy-policy-tutorial"><?php _e( 'If you have used them in your popups to collect email subscribers, use this subsection to note what personal data is captured when someone submits a subscription form, and how long you keep it.', 'popup-maker' ); ?></p>
60
+ <p class="privacy-policy-tutorial"><?php _e( 'For example, you may note that you keep form submissions for ongoing marketing purposes.', 'popup-maker' ); ?></p>
61
+ <p><?php echo $suggested_text . __( 'If you submit a subscription form on our site you will be opting in for us to save your name, email address and other relevant information.', 'popup-maker' ); ?></p>
62
+ <p><?php _e( 'These subscriptions are used to notify you about related content, discounts & other special offers.', 'popup-maker' ); ?></p> <p><?php _e( 'You can opt our or unsubscribe at any time in the future by clicking link in the bottom of any email.', 'popup-maker' ); ?></p>
63
+
64
+ <h3><?php _e( 'Cookies', 'popup-maker' ); ?></h3>
65
+ <p class="privacy-policy-tutorial"><?php _e( 'Popup Maker uses cookies for most popups. The primary function is to prevent your users from being annoyed by seeing the same popup repeatedly.', 'popup-maker' ); ?></p>
66
+ <p class="privacy-policy-tutorial"><?php _e( 'This may result in cookies being saved for an extended period of time. These are non-tracking cookies used only by our popups.', 'popup-maker' ); ?></p>
67
+
68
+ <?php
69
+ $cookies = self::get_all_cookies();
70
+ if ( ! empty( $cookies ) ) : ?>
71
+ <p class="privacy-policy-tutorial"><?php _e( 'Below is a list of all cookies currently registered within your popup settings. These are here for you to disclose if you are so required.', 'popup-maker' ); ?></p>
72
+ <table class="wp-list-table" style="width: 100%;">
73
+ <thead>
74
+ <tr>
75
+ <th align="left"><?php _e( 'Cookie Name', 'popup-maker' ); ?></th>
76
+ <th align="left"><?php _e( 'Usage', 'popup-maker' ); ?></th>
77
+ <th align="left"><?php _e( 'Time', 'popup-maker' ); ?></th>
78
+ </tr>
79
+ </thead>
80
+ <tbody style="border: 1px solid;"><?php
81
+ foreach ( $cookies as $cookie ) {
82
+ if ( ! is_array( $cookie ) ) {
83
+ continue;
84
+ }
85
+
86
+ $cookie = wp_parse_args( $cookie, array(
87
+ 'name' => '',
88
+ 'label' => '',
89
+ 'time' => '',
90
+ ) );
91
+
92
+ printf( '<tr><td style="border-top: 1px dashed;">%s</td><td style="border-top: 1px dashed;">%s</td><td style="border-top: 1px dashed;">%s</td></tr>', $cookie['name'], $cookie['label'], $cookie['time'] );
93
+ }
94
+ ?>
95
+ </tbody>
96
+ </table>
97
+ <?php
98
+ endif; ?>
99
+
100
+ <p><?php echo $suggested_text . __( 'We use anonymous cookies to prevent users from seeing the same popup repetitively in an attempt to make our users experience more pleasant while still delivering time sensitive messaging.', 'popup-maker' ); ?></p>
101
+
102
+ <h3><?php _e( 'Analytics', 'popup-maker' ); ?></h3>
103
+ <p class="privacy-policy-tutorial"><?php _e( 'Popup Maker anonymously tracks popup views and conversions.', 'popup-maker' ); ?></p>
104
+
105
+ <h2><?php _e( 'How long we retain your data', 'popup-maker' ); ?></h2>
106
+ <p><?php _e( 'Subscriber information is retained in the local database indefinitely for analytic tracking purposes and for future export.', 'popup-maker' ); ?></p>
107
+ <p><?php _e( 'Data will be exported or removed upon users request via the existing Exporter or Eraser.', 'popup-maker' ); ?></p> <p><?php _e( 'If syncing data to a 3rd party service (for example Mailchimp), data is retained there until unsubscribed or deleted.', 'popup-maker' ); ?></p>
108
+
109
+ <h2><?php _e( 'Where we send your data', 'popup-maker' ); ?></h2>
110
+ <p><?php _e( 'Popup Maker does not send any user data outside of your site by default.', 'popup-maker' ); ?></p>
111
+ <p><?php _e( 'If you have extended our subscription forms to send data to a 3rd party service such as Mailchimp, user info may be passed to these external services. These services may be located abroad.', 'popup-maker' ); ?></p>
112
+ </div>
113
+
114
+ <?php
115
+ $content = ob_get_clean();
116
+
117
+ /**
118
+ * Filters the default content suggested for inclusion in a privacy policy.
119
+ *
120
+ * @param $content string The default policy content.
121
+ */
122
+ return apply_filters( 'pum_get_default_privacy_policy_content', $content );
123
+
124
+ }
125
+
126
+ /**
127
+ * Register exporter for Popup Maker Optin Form Subscriber Data.
128
+ *
129
+ * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
130
+ *
131
+ * @param $exporters
132
+ *
133
+ * @return array
134
+ */
135
+ public static function register_exporter( $exporters ) {
136
+ $exporters[] = array(
137
+ 'exporter_friendly_name' => __( 'Popup Maker Subscribe Form' ),
138
+ 'callback' => array( __CLASS__, 'exporter' ),
139
+ );
140
+
141
+ return $exporters;
142
+ }
143
+
144
+ /**
145
+ * Register erasers for Popup Maker Optin Form Subscriber Data.
146
+ *
147
+ * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
148
+ *
149
+ * @param $exporters
150
+ *
151
+ * @return array
152
+ */
153
+ public static function register_erasers( $exporters ) {
154
+ $exporters[] = array(
155
+ 'eraser_friendly_name' => __( 'Popup Maker Subscribe Form' ),
156
+ 'callback' => array( __CLASS__, 'eraser' ),
157
+ );
158
+
159
+ return $exporters;
160
+ }
161
+
162
+ /**
163
+ * Exporter for Popup Maker Optin Form Subscriber Data.
164
+ *
165
+ * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
166
+ *
167
+ * @param $email_address
168
+ * @param int $page
169
+ *
170
+ * @return array
171
+ */
172
+ public static function exporter( $email_address, $page = 1 ) {
173
+ $number = 500; // Limit us to avoid timing out
174
+ $page = (int) $page;
175
+
176
+ $export_items = array();
177
+ $subscribers = PUM_DB_Subscribers::instance()->query( array(
178
+ 's' => $email_address,
179
+ 'page' => $page,
180
+ 'limit' => $number,
181
+ 'orderby' => 'ID',
182
+ 'order' => 'ASC',
183
+ ), 'ARRAY_A' );
184
+
185
+ foreach ( (array) $subscribers as $subscriber ) {
186
+ if ( $subscriber['email'] == $email_address ) {
187
+ // Most item IDs should look like postType-postID
188
+ // If you don't have a post, comment or other ID to work with,
189
+ // use a unique value to avoid having this item's export
190
+ // combined in the final report with other items of the same id
191
+ $item_id = "pum-subscriber-{$subscriber['ID']}";
192
+
193
+ // Core group IDs include 'comments', 'posts', etc.
194
+ // But you can add your own group IDs as needed
195
+ $group_id = 'pum-subscribers';
196
+
197
+ // Optional group label. Core provides these for core groups.
198
+ // If you define your own group, the first exporter to
199
+ // include a label will be used as the group label in the
200
+ // final exported report
201
+ $group_label = __( 'Subscriber Data' );
202
+
203
+ // Plugins can add as many items in the item data array as they want
204
+
205
+ $data = array();
206
+
207
+ foreach ( $subscriber as $field_key => $field_value ) {
208
+ switch ( $field_key ) {
209
+ case 'ID':
210
+ $data[] = array(
211
+ 'name' => __( 'ID', 'popup-maker' ),
212
+ 'value' => $field_value,
213
+ );
214
+ break;
215
+ case 'email':
216
+ $data[] = array(
217
+ 'name' => __( 'Email', 'popup-maker' ),
218
+ 'value' => $field_value,
219
+ );
220
+ break;
221
+ case 'name':
222
+ $data[] = array(
223
+ 'name' => __( 'Name', 'popup-maker' ),
224
+ 'value' => $field_value,
225
+ );
226
+ break;
227
+ case 'fname':
228
+ $data[] = array(
229
+ 'name' => __( 'First Name', 'popup-maker' ),
230
+ 'value' => $field_value,
231
+ );
232
+ break;
233
+ case 'lname':
234
+ $data[] = array(
235
+ 'name' => __( 'Last Name', 'popup-maker' ),
236
+ 'value' => $field_value,
237
+ );
238
+ break;
239
+ case 'consent':
240
+ $data[] = array(
241
+ 'name' => __( 'Provided Consent', 'popup-maker' ),
242
+ 'value' => ucfirst( $field_value ),
243
+ );
244
+ break;
245
+ case 'values':
246
+ case 'consent_args':
247
+ $values = maybe_unserialize( $field_value );
248
+
249
+ foreach ( (array) $values as $key => $value ) {
250
+
251
+ // Empty values don't need to be rendered.
252
+ if ( empty( $value ) ) {
253
+ continue;
254
+ }
255
+
256
+ $label = '';
257
+
258
+ switch ( $key ) {
259
+ case 'provider':
260
+ $providers = PUM_Newsletter_Providers::instance()->get_providers();
261
+
262
+ if ( ! empty( $providers[ $value ] ) ) {
263
+ $label = $providers[ $value ]->name;
264
+ }
265
+ break;
266
+ case 'required':
267
+ $label = __( 'Consent Required', 'popup-maker' );
268
+ break;
269
+ case 'text':
270
+ $label = __( 'Consent Text', 'popup-maker' );
271
+ break;
272
+ case 'name':
273
+ case 'lname':
274
+ case 'email':
275
+ case 'fname':
276
+ case 'list_id':
277
+ case 'popup_id':
278
+ case 'email_hash':
279
+ case 'pum_form_popup_id':
280
+ case 'mc_args':
281
+ // Leave these values out.
282
+ break;
283
+ }
284
+
285
+ $label = apply_filters( 'pum_privacy_subscriber_value_label', $label, $key, $value );
286
+
287
+ if ( ! empty( $label ) ) {
288
+ $data[] = array(
289
+ 'name' => $label,
290
+ 'value' => $value,
291
+ );
292
+ }
293
+ }
294
+
295
+ break;
296
+ case 'created':
297
+ $data[] = array(
298
+ 'name' => __( 'Date Subscribed', 'popup-maker' ),
299
+ 'value' => $field_value,
300
+ );
301
+ break;
302
+ }
303
+ }
304
+
305
+ $export_items[] = array(
306
+ 'group_id' => $group_id,
307
+ 'group_label' => $group_label,
308
+ 'item_id' => $item_id,
309
+ 'data' => $data,
310
+ );
311
+ }
312
+
313
+ }
314
+
315
+ // Tell core if we have more comments to work on still
316
+ $done = count( $subscribers ) < $number;
317
+
318
+ return array(
319
+ 'data' => $export_items,
320
+ 'done' => $done,
321
+ );
322
+ }
323
+
324
+
325
+ /**
326
+ * Eraser for Popup Maker Optin Form Subscriber Data.
327
+ *
328
+ * @see https://github.com/allendav/wp-privacy-requests/blob/master/EXPORT.md
329
+ *
330
+ * @param $email_address
331
+ * @param int $page
332
+ *
333
+ * @return array
334
+ */
335
+ public static function eraser( $email_address, $page = 1 ) {
336
+ if ( empty( $email_address ) ) {
337
+ return array(
338
+ 'items_removed' => false,
339
+ 'items_retained' => false,
340
+ 'messages' => array(),
341
+ 'done' => true,
342
+ );
343
+ }
344
+
345
+ $messages = array();
346
+ $items_removed = false;
347
+ $items_retained = false;
348
+
349
+ $number = 500; // Limit us to avoid timing out
350
+ $page = (int) $page;
351
+
352
+ $subscribers = PUM_DB_Subscribers::instance()->query( array(
353
+ 's' => $email_address,
354
+ 'page' => $page,
355
+ 'limit' => $number,
356
+ 'orderby' => 'ID',
357
+ 'order' => 'ASC',
358
+ ), 'ARRAY_A' );
359
+
360
+ foreach ( (array) $subscribers as $subscriber ) {
361
+ if ( $subscriber['email'] == $email_address ) {
362
+
363
+ // Data should not be deleted if the user was left subscribed to a service provider.
364
+ $unsubscribed = apply_filters( 'pum_privacy_eraser_subscriber_was_unsubscribed', true, $email_address, $subscriber );
365
+
366
+ if ( $unsubscribed ) {
367
+
368
+ $deleted = PUM_DB_Subscribers::instance()->delete( $subscriber['ID'] );
369
+
370
+ if ( $deleted ) {
371
+ $items_removed = true;
372
+ } else {
373
+ $items_retained = true;
374
+ $messages[] = __( 'Subscription information was not removed. A database error may have occurred during deletion.', 'popup-maker' );
375
+ }
376
+ } else {
377
+ $items_retained = true;
378
+ $messages[] = __( 'Subscription information was not removed. This may occur when no immediate confirmation is received during our attempt to unsubscribe you from our mailing list.', 'popup-maker' );
379
+ }
380
+
381
+ }
382
+
383
+ }
384
+
385
+ // Tell core if we have more comments to work on still
386
+ $done = count( $subscribers ) < $number;
387
+
388
+ return array(
389
+ 'items_removed' => $items_removed,
390
+ 'items_retained' => $items_retained,
391
+ 'messages' => $messages,
392
+ 'done' => $done,
393
+ );
394
+ }
395
+
396
+ /**
397
+ * @return array
398
+ */
399
+ public static function get_all_cookies() {
400
+ $cookie_list = get_option( 'pum_privacy_cookie_list' );
401
+ $cookies = ! empty( $cookie_list['cookies'] ) ? $cookie_list['cookies'] : array();
402
+
403
+ if ( false === $cookie_list || ! isset( $cookie_list['timestamp'] ) || strtotime('-7 days' ) > $cookie_list['timestamp'] ) {
404
+ $popups = pum_get_all_popups();
405
+
406
+ if ( ! empty( $popups ) ) {
407
+
408
+ foreach ( $popups as $popup ) {
409
+
410
+ if ( ! pum_is_popup( $popup ) ) {
411
+ continue;
412
+ }
413
+
414
+ // Set this popup as the global $current.
415
+ pum()->current_popup = $popup;
416
+
417
+ $popup_cookies = $popup->get_setting( 'cookies', array() );
418
+
419
+ if ( ! empty( $popup_cookies ) ) {
420
+ foreach ( $popup_cookies as $cookie ) {
421
+ if ( ! empty ( $cookie['settings']['name'] ) ) {
422
+ $current_time = 0;
423
+ if ( ! empty( $cookies[ $cookie['settings']['name'] ] ) ) {
424
+ $current_time = strtotime( '+' . $cookies[ $cookie['settings']['name'] ]['time'] );
425
+ }
426
+
427
+ if ( empty( $cookies[ $cookie['settings']['name'] ] ) ) {
428
+ $cookies[ $cookie['settings']['name'] ] = array(
429
+ 'label' => __( 'Cookie used to prevent popup from displaying repeatedly.', 'popup-maker' ),
430
+ 'name' => $cookie['settings']['name'],
431
+ 'time' => $cookie['settings']['time'],
432
+ );
433
+ }
434
+
435
+ $new_time = strtotime( '+' . $cookie['settings']['time'] );
436
+ if ( $new_time > $current_time ) {
437
+ $cookies[ $cookie['settings']['name'] ]['time'] = $cookie['settings']['time'];
438
+ }
439
+ }
440
+ }
441
+ }
442
+ }
443
+
444
+ // Clear the global $current.
445
+ pum()->current_popup = null;
446
+
447
+ }
448
+
449
+ // Update cookie list so we don't have to regenerate it every page load.
450
+ update_option( 'pum_privacy_cookie_list', array(
451
+ 'cookies' => $cookies,
452
+ 'timestamp' => strtotime( 'now' ),
453
+ ) );
454
+ }
455
+
456
+ return apply_filters( 'pum_privacy_get_all_cookies', $cookies );
457
+ }
458
  }
classes/Utils/Alerts.php CHANGED
@@ -1,485 +1,485 @@
1
- <?php
2
- /*******************************************************************************
3
- * Copyright (c) 2019, WP Popup Maker
4
- ******************************************************************************/
5
-
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit;
8
- }
9
-
10
- /**
11
- * Class PUM_Utils_Alerts
12
- */
13
- class PUM_Utils_Alerts {
14
-
15
- /**
16
- *
17
- */
18
- public static function init() {
19
- add_action( 'admin_init', array( __CLASS__, 'hooks' ) );
20
- add_action( 'wp_ajax_pum_alerts_action', array( __CLASS__, 'ajax_handler' ) );
21
- add_filter( 'pum_alert_list', array( __CLASS__, 'whats_new_alerts' ), 0 );
22
- add_filter( 'pum_alert_list', array( __CLASS__, 'integration_alerts' ), 5 );
23
- add_filter( 'pum_alert_list', array( __CLASS__, 'translation_request' ), 10 );
24
- add_action( 'admin_menu', array( __CLASS__, 'append_alert_count' ), 999 );
25
- }
26
-
27
- /**
28
- * Gets a count of current alerts.
29
- *
30
- * @return int
31
- */
32
- public static function alert_count() {
33
- return count( self::get_alerts() );
34
- }
35
-
36
- /**
37
- * Append alert count to Popup Maker menu item.
38
- */
39
- public static function append_alert_count() {
40
- global $menu;
41
- $count = self::alert_count();
42
- foreach ( $menu as $key => $item ) {
43
- if ( $item[2] == 'edit.php?post_type=popup' ) {
44
- $menu[ $key ][0] .= $count ? ' <span class="update-plugins count-' . $count . '"><span class="plugin-count pum-alert-count" aria-hidden="true">' . $count . '</span></span>' : '';
45
- }
46
- }
47
- }
48
-
49
- /**
50
- * @param array $alerts
51
- *
52
- * @return array
53
- */
54
- public static function translation_request( $alerts = array() ) {
55
-
56
- $version = explode( '.', Popup_Maker::$VER );
57
- // Get only the major.minor version exclude the point releases.
58
- $version = $version[0] . '.' . $version[1];
59
-
60
- $code = 'translation_request_' . $version;
61
-
62
- // Bail Early if they have already dismissed.
63
- if ( self::has_dismissed_alert( $code ) ) {
64
- return $alerts;
65
- }
66
-
67
- // Get locales based on the HTTP accept language header.
68
- $locales_from_header = PUM_Utils_I10n::get_http_locales();
69
-
70
- // Abort early if no locales in header.
71
- if ( empty( $locales_from_header ) ) {
72
- return $alerts;
73
- }
74
-
75
- // Get acceptable non EN WordPress locales based on the HTTP accept language header.
76
- // Used when the current locale is EN only I believe.
77
- $non_en_locales_from_header = PUM_Utils_I10n::get_non_en_accepted_wp_locales_from_header();
78
-
79
- // If no additional languages are supported abort
80
- if ( empty( $non_en_locales_from_header ) ) {
81
- return $alerts;
82
- }
83
-
84
- /**
85
- * Assume all at this point are possible polyglots.
86
- *
87
- * Viewing in English!
88
- * -- Translation available in one additional language!
89
- * ---- Show notice that there other language is available and we need help translating.
90
- * -- Translation available in more than one language!
91
- * ---- Show notice that their other languages are available and need help translating.
92
- * -- Translation not available!
93
- * ---- Show notice that plugin is not translated and we need help.
94
- * Else If translation for their language(s) exists, but isn't up to date!
95
- * -- Show notice that their language is available, but out of date and need help translating.
96
- * Else If translations for their language doesn't exist!
97
- * -- Show notice that plugin is not translated and we need help.
98
- */
99
- $current_locale = function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
100
-
101
- // Get the active language packs of the plugin.
102
- $translation_status = PUM_Utils_I10n::translation_status();
103
- // Retrieve all the WordPress locales in which the plugin is translated.
104
- $locales_with_translations = wp_list_pluck( $translation_status, 'language' );
105
- $locale_translation_versions = wp_list_pluck( $translation_status, 'version' );
106
-
107
- // Suggests existing langpacks
108
- $suggested_locales_with_langpack = array_values( array_intersect( $non_en_locales_from_header, $locales_with_translations ) );
109
- $current_locale_is_suggested = in_array( $current_locale, $suggested_locales_with_langpack );
110
- $current_locale_is_translated = in_array( $current_locale, $locales_with_translations );
111
-
112
- // Last chance to abort early before querying all available languages.
113
- // We abort here if the user is already using a translated language that is up to date!
114
- if ( $current_locale_is_suggested && $current_locale_is_translated && version_compare( $locale_translation_versions[ $current_locale ], Popup_Maker::$VER, '>=' ) ) {
115
- return $alerts;
116
- }
117
-
118
- // Retrieve all the WordPress locales.
119
- $locales_supported_by_wordpress = PUM_Utils_I10n::available_locales();
120
-
121
- // Get the native language names of the locales.
122
- $suggest_translated_locale_names = array();
123
- foreach ( $suggested_locales_with_langpack as $locale ) {
124
- $suggest_translated_locale_names[ $locale ] = $locales_supported_by_wordpress[ $locale ]['native_name'];
125
- }
126
-
127
- $suggest_string = '';
128
-
129
- // If we get this far, they clearly have multiple language available
130
- // If current locale is english but they have others available, they are likely polyglots.
131
- $currently_in_english = strpos( $current_locale, 'en' ) === 0;
132
-
133
- // Currently in English.
134
- if ( $currently_in_english ) {
135
-
136
- // Only one locale suggestion.
137
- if ( 1 === count( $suggest_translated_locale_names ) ) {
138
- $language = current( $suggest_translated_locale_names );
139
-
140
- $suggest_string = sprintf( /* translators: %s: native language name. */
141
- __( 'This plugin is also available in %1$s. <a href="%2$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $language, esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
142
-
143
- // Multiple locale suggestions.
144
- } elseif ( ! empty( $suggest_translated_locale_names ) ) {
145
- $primary_language = current( $suggest_translated_locale_names );
146
- array_shift( $suggest_translated_locale_names );
147
-
148
- $other_suggest = '';
149
- foreach ( $suggest_translated_locale_names as $language ) {
150
- $other_suggest .= $language . ', ';
151
- }
152
-
153
- $suggest_string = sprintf( /* translators: 1: native language name, 2: other native language names, comma separated */
154
- __( 'This plugin is also available in %1$s (also: %2$s). <a href="%3$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $primary_language, trim( $other_suggest, ' ,' ), esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
155
-
156
- // Non-English locale in header, no translations.
157
- } elseif ( ! empty( $non_en_locales_from_header ) ) {
158
-
159
- if ( 1 === count( $non_en_locales_from_header ) ) {
160
- $locale = reset( $non_en_locales_from_header );
161
-
162
- $suggest_string = sprintf( /* translators: 1: native language name, 2: URL to translate.wordpress.org */
163
- __( 'This plugin is not translated into %1$s yet. <a href="%2$s" target="_blank">Help translate it!</a>', 'popup-maker' ), $locales_supported_by_wordpress[ $locale ]['native_name'], esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
164
- } else {
165
- $primary_locale = reset( $non_en_locales_from_header );
166
- $primary_language = $locales_supported_by_wordpress[ $primary_locale ]['native_name'];
167
- array_shift( $non_en_locales_from_header );
168
-
169
- $other_suggest = '';
170
- foreach ( $non_en_locales_from_header as $locale ) {
171
- $other_suggest .= $locales_supported_by_wordpress[ $locale ]['native_name'] . ', ';
172
- }
173
-
174
- $suggest_string = sprintf( /* translators: 1: native language name, 2: other native language names, comma separated */
175
- __( 'This plugin is also available in %1$s (also: %2$s). <a href="%3$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $primary_language, trim( $other_suggest, ' ,' ), esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
176
- }
177
- }
178
-
179
- // The plugin has no translation for the current locale.
180
- } elseif ( ! $current_locale_is_suggested && ! $current_locale_is_translated ) {
181
- $suggest_string = sprintf( __( 'This plugin is not translated into %1$s yet. <a href="%2$s" target="_blank">Help translate it!</a>', 'popup-maker' ), $locales_supported_by_wordpress[ $current_locale ]['native_name'], esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
182
- // The plugin has translations for current locale, but they are out of date.
183
- } elseif ( $current_locale_is_suggested && $current_locale_is_translated && version_compare( $locale_translation_versions[ $current_locale ], Popup_Maker::$VER, '<' ) ) {
184
- $suggest_string = sprintf( /* translators: %s: native language name. */
185
- __( 'This plugin\'s translation for %1$s is out of date. <a href="%2$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $locales_supported_by_wordpress[ $current_locale ]['native_name'], esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
186
- }
187
-
188
-
189
- if ( ! empty( $suggest_string ) ) {
190
- $alerts[] = array(
191
- 'code' => $code,
192
- 'message' => $suggest_string,
193
- 'type' => 'info',
194
- );
195
- }
196
-
197
- return $alerts;
198
- }
199
-
200
- /**
201
- * @param array $alerts
202
- *
203
- * @return array
204
- */
205
- public static function whats_new_alerts( $alerts = array() ) {
206
-
207
- $upgraded_from = PUM_Utils_Upgrades::$upgraded_from;
208
-
209
- if ( version_compare( $upgraded_from, '0.0.0', '>' ) ) {
210
-
211
- if ( version_compare( $upgraded_from, '1.8.0', '<' ) ) {
212
- $alerts[] = array(
213
- 'code' => 'whats_new_1_8_0',
214
- 'type' => 'success',
215
- 'message' => sprintf( '<strong>' . __( 'See whats new in v%s - (%sview all changes%s)', 'popup-maker' ) . '</strong>', '1.8.0', '<a href="' . add_query_arg( array(
216
- 'tab' => 'plugin-information',
217
- 'plugin' => 'popup-maker',
218
- 'section' => 'changelog',
219
- 'TB_iframe' => true,
220
- 'width' => 722,
221
- 'height' => 949,
222
- ), admin_url( 'plugin-install.php' ) ) . '" target="_blank">', '</a>' ),
223
- 'html' => "<ul class='ul-disc'>" . "<li>" . 'New UX for the Popup Theme editor.' . "</li>" . "<li>" . 'New close button positions: top center, bottom center, middle left & middle right.' . "</li>" . "<li>" . 'New option to position close button outside of popup.' . "</li>" . "</ul>",
224
- 'priority' => 100,
225
- );
226
- }
227
-
228
- }
229
-
230
- return $alerts;
231
- }
232
-
233
- /**
234
- * @param array $alerts
235
- *
236
- * @return array
237
- */
238
- public static function integration_alerts( $alerts = array() ) {
239
-
240
- $integrations = array(
241
- 'buddypress' => array(
242
- 'label' => __( 'BuddyPress', 'buddypress' ),
243
- 'learn_more_url' => 'https://wppopupmaker.com/works-with/buddypress/',
244
- 'conditions' => ! class_exists( 'PUM_BuddyPress' ) && ( function_exists( 'buddypress' ) || class_exists( 'BuddyPress' ) ),
245
- 'slug' => 'popup-maker-buddypress-integration',
246
- 'name' => 'Popup Maker - BuddyPress Integration',
247
- 'free' => true,
248
- ),
249
- );
250
-
251
- foreach ( $integrations as $key => $integration ) {
252
-
253
- if ( $integration['conditions'] ) {
254
-
255
- $path = "{$integration['slug']}/{$integration['slug']}.php";
256
- $plugin_data = file_exists( WP_PLUGIN_DIR . '/' . $path ) ? get_plugin_data( WP_PLUGIN_DIR . '/' . $path, false, false ) : false;
257
-
258
- $installed = $plugin_data && ! empty( $plugin_data['Name'] ) && $plugin_data['Name'] === $integration['name'];
259
-
260
- $text = $installed ? __( 'activate it now', 'popup-maker' ) : __( 'install it now', 'popup-maker' );
261
- $url = $installed ? esc_url( wp_nonce_url( admin_url( 'plugins.php?action=activate&plugin=' . $path ), 'activate-plugin_' . $path ) ) : esc_url( wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=popup-maker-buddypress-integration' ), 'install-plugin_popup-maker-buddypress-integration' ) );
262
-
263
- $alerts[] = array(
264
- 'code' => $key . '_integration_available',
265
- 'message' => sprintf( __( '%sDid you know:%s Popup Maker has custom integrations with %s, %slearn more%s or %s%s%s!', 'popup-maker' ), '<strong>', '</strong>', $integration['label'], '<a href="' . $integration['learn_more_url'] . '" target="_blank">', '</a>', '<a href="' . $url . '">', $text, '</a>' ),
266
- 'dismissible' => true,
267
- 'global' => false,
268
- 'type' => $installed ? 'warning' : 'info',
269
- );
270
-
271
- }
272
-
273
- }
274
-
275
- return $alerts;
276
- }
277
-
278
- /**
279
- * Hook into relevant WP actions.
280
- */
281
- public static function hooks() {
282
- if ( is_admin() && current_user_can( 'edit_posts' ) ) {
283
- add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
284
- add_action( 'network_admin_notices', array( __CLASS__, 'admin_notices' ) );
285
- add_action( 'user_admin_notices', array( __CLASS__, 'admin_notices' ) );
286
- }
287
- }
288
-
289
- /**
290
- * @return bool
291
- */
292
- public static function should_show_alerts() {
293
- return in_array( true, array(
294
- pum_is_admin_page(),
295
- count( self::get_global_alerts() ) > 0,
296
- ) );
297
- }
298
-
299
- /**
300
- * Render admin alerts if available.
301
- */
302
- public static function admin_notices() {
303
- if ( ! self::should_show_alerts() ) {
304
- return;
305
- }
306
-
307
- $global_only = ! pum_is_admin_page();
308
-
309
- $alerts = $global_only ? self::get_global_alerts() : self::get_alerts();
310
-
311
- $count = count( $alerts );
312
-
313
- if ( ! $count ) {
314
- return;
315
- }
316
-
317
- wp_enqueue_script( 'pum-admin-general' );
318
- wp_enqueue_style( 'pum-admin-general' );
319
-
320
- ?>
321
-
322
- <script type="text/javascript">
323
- window.pum_alerts_nonce = '<?php echo wp_create_nonce( 'pum_alerts_action' ); ?>';
324
- </script>
325
-
326
- <div class="pum-alerts">
327
-
328
- <h3>
329
- <img alt="" class="logo" width="30" src="<?php echo Popup_Maker::$URL; ?>assets/images/logo.png" /> <?php printf( '%s%s (%s)', ( $global_only ? __( 'Popup Maker', 'popup-maker' ) . ' ' : '' ), __( 'Notifications', 'popup-maker' ), '<span class="pum-alert-count">' . $count . '</span>' ); ?>
330
- </h3>
331
-
332
- <p><?php __( 'Check out the following notifications from Popup Maker.', 'popup-maker' ); ?></p>
333
-
334
- <?php foreach ( $alerts as $alert ) : ?>
335
-
336
- <div class="pum-alert-holder" data-code="<?php echo $alert['code']; ?>" class="<?php echo $alert['dismissible'] ? 'is-dismissible' : ''; ?>" data-dismissible="<?php esc_attr_e( $alert['dismissible'] ); ?>">
337
-
338
- <div class="pum-alert <?php echo $alert['type'] != '' ? 'pum-alert__' . $alert['type'] : ''; ?>">
339
-
340
- <?php if ( ! empty( $alert['message'] ) ) : ?>
341
- <p><?php echo $alert['message']; ?></p>
342
- <?php endif; ?>
343
-
344
- <?php if ( ! empty( $alert['html'] ) ) : ?>
345
- <?php echo wp_encode_emoji( $alert['html'] ); ?>
346
- <?php endif; ?>
347
-
348
- </div>
349
-
350
- <?php if ( $alert['dismissible'] ) : ?>
351
-
352
- <button type="button" class="button dismiss pum-dismiss">
353
- <span class="screen-reader-text"><?php _e( 'Dismiss this item.', 'popup-maker' ); ?></span> <span class="dashicons dashicons-no-alt"></span>
354
- </button>
355
-
356
- <?php endif; ?>
357
-
358
- </div>
359
-
360
- <?php endforeach; ?>
361
-
362
- </div>
363
-
364
- <?php
365
- }
366
-
367
- /**
368
- * @return array
369
- */
370
- public static function get_global_alerts() {
371
- $alerts = self::get_alerts();
372
-
373
- $global_alerts = array();
374
-
375
- foreach ( $alerts as $alert ) {
376
- if ( $alert['global'] ) {
377
- $global_alerts[] = $alert;
378
- }
379
- }
380
-
381
- return $global_alerts;
382
- }
383
-
384
- /**
385
- * @return array
386
- */
387
- public static function get_alerts() {
388
-
389
- static $alert_list;
390
-
391
- if ( ! isset( $alert_list ) ) {
392
- $alert_list = apply_filters( 'pum_alert_list', array() );
393
- }
394
-
395
- $alerts = array();
396
-
397
- foreach ( $alert_list as $alert ) {
398
-
399
- // Ignore dismissed alerts.
400
- if ( self::has_dismissed_alert( $alert['code'] ) ) {
401
- continue;
402
- }
403
-
404
- $alerts[] = wp_parse_args( $alert, array(
405
- 'code' => 'default',
406
- 'priority' => 10,
407
- 'message' => '',
408
- 'type' => 'info',
409
- 'html' => '',
410
- 'dismissible' => true,
411
- 'global' => false,
412
- ) );
413
-
414
- }
415
-
416
- // Sort alerts by priority, highest to lowest.
417
- $alerts = PUM_Utils_Array::sort( $alerts, 'priority', true );
418
-
419
- return $alerts;
420
- }
421
-
422
-
423
- /**
424
- *
425
- */
426
- public static function ajax_handler() {
427
- $args = wp_parse_args( $_REQUEST, array(
428
- 'code' => '',
429
- 'expires' => '',
430
- ) );
431
-
432
- if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'pum_alerts_action' ) ) {
433
- wp_send_json_error();
434
- }
435
-
436
- try {
437
- $dismissed_alerts = self::dismissed_alerts();
438
- $dismissed_alerts[ $args['code'] ] = ! empty( $args['expires'] ) ? strtotime( '+' . $args['expires'] ) : true;
439
-
440
- $user_id = get_current_user_id();
441
- update_user_meta( $user_id, '_pum_dismissed_alerts', $dismissed_alerts );
442
- wp_send_json_success();
443
-
444
- } catch ( Exception $e ) {
445
- wp_send_json_error( $e );
446
- }
447
- }
448
-
449
- /**
450
- * @param string $code
451
- *
452
- * @return bool
453
- */
454
- public static function has_dismissed_alert( $code = '' ) {
455
- $dimissed_alerts = self::dismissed_alerts();
456
-
457
- $alert_dismissed = array_key_exists( $code, $dimissed_alerts );
458
-
459
- // If the alert was dismissed and has a non true type value, it is an expiry time.
460
- if ( $alert_dismissed && true !== $dimissed_alerts[ $code ] ) {
461
- return strtotime( 'now' ) < $dimissed_alerts[ $code ];
462
- }
463
-
464
- return $alert_dismissed;
465
- }
466
-
467
- /**
468
- * Returns an array of dismissed alert groups.
469
- *
470
- * @return array
471
- */
472
- public static function dismissed_alerts() {
473
- $user_id = get_current_user_id();
474
-
475
- $dismissed_alerts = get_user_meta( $user_id, '_pum_dismissed_alerts', true );
476
-
477
- if ( ! is_array( $dismissed_alerts ) ) {
478
- $dismissed_alerts = array();
479
- update_user_meta( $user_id, '_pum_dismissed_alerts', $dismissed_alerts );
480
- }
481
-
482
- return $dismissed_alerts;
483
- }
484
-
485
- }
1
+ <?php
2
+ /*******************************************************************************
3
+ * Copyright (c) 2019, WP Popup Maker
4
+ ******************************************************************************/
5
+
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Class PUM_Utils_Alerts
12
+ */
13
+ class PUM_Utils_Alerts {
14
+
15
+ /**
16
+ *
17
+ */
18
+ public static function init() {
19
+ add_action( 'admin_init', array( __CLASS__, 'hooks' ) );
20
+ add_action( 'wp_ajax_pum_alerts_action', array( __CLASS__, 'ajax_handler' ) );
21
+ add_filter( 'pum_alert_list', array( __CLASS__, 'whats_new_alerts' ), 0 );
22
+ add_filter( 'pum_alert_list', array( __CLASS__, 'integration_alerts' ), 5 );
23
+ add_filter( 'pum_alert_list', array( __CLASS__, 'translation_request' ), 10 );
24
+ add_action( 'admin_menu', array( __CLASS__, 'append_alert_count' ), 999 );
25
+ }
26
+
27
+ /**
28
+ * Gets a count of current alerts.
29
+ *
30
+ * @return int
31
+ */
32
+ public static function alert_count() {
33
+ return count( self::get_alerts() );
34
+ }
35
+
36
+ /**
37
+ * Append alert count to Popup Maker menu item.
38
+ */
39
+ public static function append_alert_count() {
40
+ global $menu;
41
+ $count = self::alert_count();
42
+ foreach ( $menu as $key => $item ) {
43
+ if ( $item[2] == 'edit.php?post_type=popup' ) {
44
+ $menu[ $key ][0] .= $count ? ' <span class="update-plugins count-' . $count . '"><span class="plugin-count pum-alert-count" aria-hidden="true">' . $count . '</span></span>' : '';
45
+ }
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @param array $alerts
51
+ *
52
+ * @return array
53
+ */
54
+ public static function translation_request( $alerts = array() ) {
55
+
56
+ $version = explode( '.', Popup_Maker::$VER );
57
+ // Get only the major.minor version exclude the point releases.
58
+ $version = $version[0] . '.' . $version[1];
59
+
60
+ $code = 'translation_request_' . $version;
61
+
62
+ // Bail Early if they have already dismissed.
63
+ if ( self::has_dismissed_alert( $code ) ) {
64
+ return $alerts;
65
+ }
66
+
67
+ // Get locales based on the HTTP accept language header.
68
+ $locales_from_header = PUM_Utils_I10n::get_http_locales();
69
+
70
+ // Abort early if no locales in header.
71
+ if ( empty( $locales_from_header ) ) {
72
+ return $alerts;
73
+ }
74
+
75
+ // Get acceptable non EN WordPress locales based on the HTTP accept language header.
76
+ // Used when the current locale is EN only I believe.
77
+ $non_en_locales_from_header = PUM_Utils_I10n::get_non_en_accepted_wp_locales_from_header();
78
+
79
+ // If no additional languages are supported abort
80
+ if ( empty( $non_en_locales_from_header ) ) {
81
+ return $alerts;
82
+ }
83
+
84
+ /**
85
+ * Assume all at this point are possible polyglots.
86
+ *
87
+ * Viewing in English!
88
+ * -- Translation available in one additional language!
89
+ * ---- Show notice that there other language is available and we need help translating.
90
+ * -- Translation available in more than one language!
91
+ * ---- Show notice that their other languages are available and need help translating.
92
+ * -- Translation not available!
93
+ * ---- Show notice that plugin is not translated and we need help.
94
+ * Else If translation for their language(s) exists, but isn't up to date!
95
+ * -- Show notice that their language is available, but out of date and need help translating.
96
+ * Else If translations for their language doesn't exist!
97
+ * -- Show notice that plugin is not translated and we need help.
98
+ */
99
+ $current_locale = function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
100
+
101
+ // Get the active language packs of the plugin.
102
+ $translation_status = PUM_Utils_I10n::translation_status();
103
+ // Retrieve all the WordPress locales in which the plugin is translated.
104
+ $locales_with_translations = wp_list_pluck( $translation_status, 'language' );
105
+ $locale_translation_versions = wp_list_pluck( $translation_status, 'version' );
106
+
107
+ // Suggests existing langpacks
108
+ $suggested_locales_with_langpack = array_values( array_intersect( $non_en_locales_from_header, $locales_with_translations ) );
109
+ $current_locale_is_suggested = in_array( $current_locale, $suggested_locales_with_langpack );
110
+ $current_locale_is_translated = in_array( $current_locale, $locales_with_translations );
111
+
112
+ // Last chance to abort early before querying all available languages.
113
+ // We abort here if the user is already using a translated language that is up to date!
114
+ if ( $current_locale_is_suggested && $current_locale_is_translated && version_compare( $locale_translation_versions[ $current_locale ], Popup_Maker::$VER, '>=' ) ) {
115
+ return $alerts;
116
+ }
117
+
118
+ // Retrieve all the WordPress locales.
119
+ $locales_supported_by_wordpress = PUM_Utils_I10n::available_locales();
120
+
121
+ // Get the native language names of the locales.
122
+ $suggest_translated_locale_names = array();
123
+ foreach ( $suggested_locales_with_langpack as $locale ) {
124
+ $suggest_translated_locale_names[ $locale ] = $locales_supported_by_wordpress[ $locale ]['native_name'];
125
+ }
126
+
127
+ $suggest_string = '';
128
+
129
+ // If we get this far, they clearly have multiple language available
130
+ // If current locale is english but they have others available, they are likely polyglots.
131
+ $currently_in_english = strpos( $current_locale, 'en' ) === 0;
132
+
133
+ // Currently in English.
134
+ if ( $currently_in_english ) {
135
+
136
+ // Only one locale suggestion.
137
+ if ( 1 === count( $suggest_translated_locale_names ) ) {
138
+ $language = current( $suggest_translated_locale_names );
139
+
140
+ $suggest_string = sprintf( /* translators: %s: native language name. */
141
+ __( 'This plugin is also available in %1$s. <a href="%2$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $language, esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
142
+
143
+ // Multiple locale suggestions.
144
+ } elseif ( ! empty( $suggest_translated_locale_names ) ) {
145
+ $primary_language = current( $suggest_translated_locale_names );
146
+ array_shift( $suggest_translated_locale_names );
147
+
148
+ $other_suggest = '';
149
+ foreach ( $suggest_translated_locale_names as $language ) {
150
+ $other_suggest .= $language . ', ';
151
+ }
152
+
153
+ $suggest_string = sprintf( /* translators: 1: native language name, 2: other native language names, comma separated */
154
+ __( 'This plugin is also available in %1$s (also: %2$s). <a href="%3$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $primary_language, trim( $other_suggest, ' ,' ), esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
155
+
156
+ // Non-English locale in header, no translations.
157
+ } elseif ( ! empty( $non_en_locales_from_header ) ) {
158
+
159
+ if ( 1 === count( $non_en_locales_from_header ) ) {
160
+ $locale = reset( $non_en_locales_from_header );
161
+
162
+ $suggest_string = sprintf( /* translators: 1: native language name, 2: URL to translate.wordpress.org */
163
+ __( 'This plugin is not translated into %1$s yet. <a href="%2$s" target="_blank">Help translate it!</a>', 'popup-maker' ), $locales_supported_by_wordpress[ $locale ]['native_name'], esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
164
+ } else {
165
+ $primary_locale = reset( $non_en_locales_from_header );
166
+ $primary_language = $locales_supported_by_wordpress[ $primary_locale ]['native_name'];
167
+ array_shift( $non_en_locales_from_header );
168
+
169
+ $other_suggest = '';
170
+ foreach ( $non_en_locales_from_header as $locale ) {
171
+ $other_suggest .= $locales_supported_by_wordpress[ $locale ]['native_name'] . ', ';
172
+ }
173
+
174
+ $suggest_string = sprintf( /* translators: 1: native language name, 2: other native language names, comma separated */
175
+ __( 'This plugin is also available in %1$s (also: %2$s). <a href="%3$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $primary_language, trim( $other_suggest, ' ,' ), esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
176
+ }
177
+ }
178
+
179
+ // The plugin has no translation for the current locale.
180
+ } elseif ( ! $current_locale_is_suggested && ! $current_locale_is_translated ) {
181
+ $suggest_string = sprintf( __( 'This plugin is not translated into %1$s yet. <a href="%2$s" target="_blank">Help translate it!</a>', 'popup-maker' ), $locales_supported_by_wordpress[ $current_locale ]['native_name'], esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
182
+ // The plugin has translations for current locale, but they are out of date.
183
+ } elseif ( $current_locale_is_suggested && $current_locale_is_translated && version_compare( $locale_translation_versions[ $current_locale ], Popup_Maker::$VER, '<' ) ) {
184
+ $suggest_string = sprintf( /* translators: %s: native language name. */
185
+ __( 'This plugin\'s translation for %1$s is out of date. <a href="%2$s" target="_blank">Help improve the translation!</a>', 'popup-maker' ), $locales_supported_by_wordpress[ $current_locale ]['native_name'], esc_url( 'https://translate.wordpress.org/projects/wp-plugins/popup-maker' ) );
186
+ }
187
+
188
+
189
+ if ( ! empty( $suggest_string ) ) {
190
+ $alerts[] = array(
191
+ 'code' => $code,
192
+ 'message' => $suggest_string,
193
+ 'type' => 'info',
194
+ );
195
+ }
196
+
197
+ return $alerts;
198
+ }
199
+
200
+ /**
201
+ * @param array $alerts
202
+ *
203
+ * @return array
204
+ */
205
+ public static function whats_new_alerts( $alerts = array() ) {
206
+
207
+ $upgraded_from = PUM_Utils_Upgrades::$upgraded_from;
208
+
209
+ if ( version_compare( $upgraded_from, '0.0.0', '>' ) ) {
210
+
211
+ if ( version_compare( $upgraded_from, '1.8.0', '<' ) ) {
212
+ $alerts[] = array(
213
+ 'code' => 'whats_new_1_8_0',
214
+ 'type' => 'success',
215
+ 'message' => sprintf( '<strong>' . __( 'See whats new in v%s - (%sview all changes%s)', 'popup-maker' ) . '</strong>', '1.8.0', '<a href="' . add_query_arg( array(
216
+ 'tab' => 'plugin-information',
217
+ 'plugin' => 'popup-maker',
218
+ 'section' => 'changelog',
219
+ 'TB_iframe' => true,
220
+ 'width' => 722,
221
+ 'height' => 949,
222
+ ), admin_url( 'plugin-install.php' ) ) . '" target="_blank">', '</a>' ),
223
+ 'html' => "<ul class='ul-disc'>" . "<li>" . 'New UX for the Popup Theme editor.' . "</li>" . "<li>" . 'New close button positions: top center, bottom center, middle left & middle right.' . "</li>" . "<li>" . 'New option to position close button outside of popup.' . "</li>" . "</ul>",
224
+ 'priority' => 100,
225
+ );
226
+ }
227
+
228
+ }
229
+
230
+ return $alerts;
231
+ }
232
+
233
+ /**
234
+ * @param array $alerts
235
+ *
236
+ * @return array
237
+ */
238
+ public static function integration_alerts( $alerts = array() ) {
239
+
240
+ $integrations = array(
241
+ 'buddypress' => array(
242
+ 'label' => __( 'BuddyPress', 'buddypress' ),
243
+ 'learn_more_url' => 'https://wppopupmaker.com/works-with/buddypress/',
244
+ 'conditions' => ! class_exists( 'PUM_BuddyPress' ) && ( function_exists( 'buddypress' ) || class_exists( 'BuddyPress' ) ),
245
+ 'slug' => 'popup-maker-buddypress-integration',
246
+ 'name' => 'Popup Maker - BuddyPress Integration',
247
+ 'free' => true,
248
+ ),
249
+ );
250
+
251
+ foreach ( $integrations as $key => $integration ) {
252
+
253
+ if ( $integration['conditions'] ) {
254
+
255
+ $path = "{$integration['slug']}/{$integration['slug']}.php";
256
+ $plugin_data = file_exists( WP_PLUGIN_DIR . '/' . $path ) ? get_plugin_data( WP_PLUGIN_DIR . '/' . $path, false, false ) : false;
257
+
258
+ $installed = $plugin_data && ! empty( $plugin_data['Name'] ) && $plugin_data['Name'] === $integration['name'];
259
+
260
+ $text = $installed ? __( 'activate it now', 'popup-maker' ) : __( 'install it now', 'popup-maker' );
261
+ $url = $installed ? esc_url( wp_nonce_url( admin_url( 'plugins.php?action=activate&plugin=' . $path ), 'activate-plugin_' . $path ) ) : esc_url( wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=popup-maker-buddypress-integration' ), 'install-plugin_popup-maker-buddypress-integration' ) );
262
+
263
+ $alerts[] = array(
264
+ 'code' => $key . '_integration_available',
265
+ 'message' => sprintf( __( '%sDid you know:%s Popup Maker has custom integrations with %s, %slearn more%s or %s%s%s!', 'popup-maker' ), '<strong>', '</strong>', $integration['label'], '<a href="' . $integration['learn_more_url'] . '" target="_blank">', '</a>', '<a href="' . $url . '">', $text, '</a>' ),
266
+ 'dismissible' => true,
267
+ 'global' => false,
268
+ 'type' => $installed ? 'warning' : 'info',
269
+ );
270
+
271
+ }
272
+
273
+ }
274
+
275
+ return $alerts;
276
+ }
277
+
278
+ /**
279
+ * Hook into relevant WP actions.
280
+ */
281
+ public static function hooks() {
282
+ if ( is_admin() && current_user_can( 'edit_posts' ) ) {
283
+ add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
284
+ add_action( 'network_admin_notices', array( __CLASS__, 'admin_notices' ) );
285
+ add_action( 'user_admin_notices', array( __CLASS__, 'admin_notices' ) );
286
+ }
287
+ }
288
+
289
+ /**
290
+ * @return bool
291
+ */
292
+ public static function should_show_alerts() {
293
+ return in_array( true, array(
294
+ pum_is_admin_page(),
295
+ count( self::get_global_alerts() ) > 0,
296
+ ) );
297
+ }
298
+
299
+ /**
300
+ * Render admin alerts if available.
301
+ */
302
+ public static function admin_notices() {
303
+ if ( ! self::should_show_alerts() ) {
304
+ return;
305
+ }
306
+
307
+ $global_only = ! pum_is_admin_page();
308
+
309
+ $alerts = $global_only ? self::get_global_alerts() : self::get_alerts();
310
+
311
+ $count = count( $alerts );
312
+
313
+ if ( ! $count ) {
314
+ return;
315
+ }
316
+
317
+ wp_enqueue_script( 'pum-admin-general' );
318
+ wp_enqueue_style( 'pum-admin-general' );
319
+
320
+ ?>
321
+
322
+ <script type="text/javascript">
323
+ window.pum_alerts_nonce = '<?php echo wp_create_nonce( 'pum_alerts_action' ); ?>';
324
+ </script>
325
+
326
+ <div class="pum-alerts">
327
+
328
+ <h3>
329
+ <img alt="" class="logo" width="30" src="<?php echo Popup_Maker::$URL; ?>assets/images/logo.png" /> <?php printf( '%s%s (%s)', ( $global_only ? __( 'Popup Maker', 'popup-maker' ) . ' ' : '' ), __( 'Notifications', 'popup-maker' ), '<span class="pum-alert-count">' . $count . '</span>' ); ?>
330
+ </h3>
331
+
332
+ <p><?php __( 'Check out the following notifications from Popup Maker.', 'popup-maker' ); ?></p>
333
+
334
+ <?php foreach ( $alerts as $alert ) : ?>
335
+
336
+ <div class="pum-alert-holder" data-code="<?php echo $alert['code']; ?>" class="<?php echo $alert['dismissible'] ? 'is-dismissible' : ''; ?>" data-dismissible="<?php esc_attr_e( $alert['dismissible'] ); ?>">
337
+
338
+ <div class="pum-alert <?php echo $alert['type'] != '' ? 'pum-alert__' . $alert['type'] : ''; ?>">
339
+
340
+ <?php if ( ! empty( $alert['message'] ) ) : ?>
341
+ <p><?php echo $alert['message']; ?></p>
342
+ <?php endif; ?>
343
+
344
+ <?php if ( ! empty( $alert['html'] ) ) : ?>
345
+ <?php echo function_exists( 'wp_encode_emoji' ) ? wp_encode_emoji( $alert['html'] ) : $alert['html']; ?>
346
+ <?php endif; ?>
347
+
348
+ </div>
349
+
350
+ <?php if ( $alert['dismissible'] ) : ?>
351
+
352
+ <button type="button" class="button dismiss pum-dismiss">
353
+ <span class="screen-reader-text"><?php _e( 'Dismiss this item.', 'popup-maker' ); ?></span> <span class="dashicons dashicons-no-alt"></span>
354
+ </button>
355
+
356
+ <?php endif; ?>
357
+
358
+ </div>
359
+
360
+ <?php endforeach; ?>
361
+
362
+ </div>
363
+
364
+ <?php
365
+ }
366
+
367
+ /**
368
+ * @return array
369
+ */
370
+ public static function get_global_alerts() {
371
+ $alerts = self::get_alerts();
372
+
373
+ $global_alerts = array();
374
+
375
+ foreach ( $alerts as $alert ) {
376
+ if ( $alert['global'] ) {
377
+ $global_alerts[] = $alert;
378
+ }
379
+ }
380
+
381
+ return $global_alerts;
382
+ }
383
+
384
+ /**
385
+ * @return array
386
+ */
387
+ public static function get_alerts() {
388
+
389
+ static $alert_list;
390
+
391
+ if ( ! isset( $alert_list ) ) {
392
+ $alert_list = apply_filters( 'pum_alert_list', array() );
393
+ }
394
+
395
+ $alerts = array();
396
+
397
+ foreach ( $alert_list as $alert ) {
398
+
399
+ // Ignore dismissed alerts.
400
+ if ( self::has_dismissed_alert( $alert['code'] ) ) {
401
+ continue;
402
+ }
403
+
404
+ $alerts[] = wp_parse_args( $alert, array(
405
+ 'code' => 'default',
406
+ 'priority' => 10,
407
+ 'message' => '',
408
+ 'type' => 'info',
409
+ 'html' => '',
410
+ 'dismissible' => true,
411
+ 'global' => false,
412
+ ) );
413
+
414
+ }
415
+
416
+ // Sort alerts by priority, highest to lowest.
417
+ $alerts = PUM_Utils_Array::sort( $alerts, 'priority', true );
418
+
419
+ return $alerts;
420
+ }
421
+
422
+
423
+ /**
424
+ *
425
+ */
426
+ public static function ajax_handler() {
427
+ $args = wp_parse_args( $_REQUEST, array(
428
+ 'code' => '',
429
+ 'expires' => '',
430
+ ) );
431
+
432
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'pum_alerts_action' ) ) {
433
+ wp_send_json_error();
434
+ }
435
+
436
+ try {
437
+ $dismissed_alerts = self::dismissed_alerts();
438
+ $dismissed_alerts[ $args['code'] ] = ! empty( $args['expires'] ) ? strtotime( '+' . $args['expires'] ) : true;
439
+
440
+ $user_id = get_current_user_id();
441
+ update_user_meta( $user_id, '_pum_dismissed_alerts', $dismissed_alerts );
442
+ wp_send_json_success();
443
+
444
+ } catch ( Exception $e ) {
445
+ wp_send_json_error( $e );
446
+ }
447
+ }
448
+
449
+ /**
450
+ * @param string $code
451
+ *
452
+ * @return bool
453
+ */
454
+ public static function has_dismissed_alert( $code = '' ) {
455
+ $dimissed_alerts = self::dismissed_alerts();
456
+
457
+ $alert_dismissed = array_key_exists( $code, $dimissed_alerts );
458
+
459
+ // If the alert was dismissed and has a non true type value, it is an expiry time.
460
+ if ( $alert_dismissed && true !== $dimissed_alerts[ $code ] ) {
461
+ return strtotime( 'now' ) < $dimissed_alerts[ $code ];
462
+ }
463
+
464
+ return $alert_dismissed;
465
+ }
466
+
467
+ /**
468
+ * Returns an array of dismissed alert groups.
469
+ *
470
+ * @return array
471
+ */
472
+ public static function dismissed_alerts() {
473
+ $user_id = get_current_user_id();
474
+
475
+ $dismissed_alerts = get_user_meta( $user_id, '_pum_dismissed_alerts', true );
476
+
477
+ if ( ! is_array( $dismissed_alerts ) ) {
478
+ $dismissed_alerts = array();
479
+ update_user_meta( $user_id, '_pum_dismissed_alerts', $dismissed_alerts );
480
+ }
481
+
482
+ return $dismissed_alerts;
483
+ }
484
+
485
+ }
popup-maker.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Popup Maker
4
  * Plugin URI: https://wppopupmaker.com/?utm_campaign=PluginInfo&utm_source=plugin-header&utm_medium=plugin-uri
5
  * Description: Easily create & style popups with any content. Theme editor to quickly style your popups. Add forms, social media boxes, videos & more.
6
- * Version: 1.8.5
7
  * Author: WP Popup Maker
8
  * Author URI: https://wppopupmaker.com/?utm_campaign=PluginInfo&utm_source=plugin-header&utm_medium=author-uri
9
  * License: GPL2 or later
@@ -95,7 +95,7 @@ class Popup_Maker {
95
  /**
96
  * @var string Plugin Version
97
  */
98
- public static $VER = '1.8.5';
99
 
100
  /**
101
  * @var int DB Version
3
  * Plugin Name: Popup Maker
4
  * Plugin URI: https://wppopupmaker.com/?utm_campaign=PluginInfo&utm_source=plugin-header&utm_medium=plugin-uri
5
  * Description: Easily create & style popups with any content. Theme editor to quickly style your popups. Add forms, social media boxes, videos & more.
6
+ * Version: 1.8.6
7
  * Author: WP Popup Maker
8
  * Author URI: https://wppopupmaker.com/?utm_campaign=PluginInfo&utm_source=plugin-header&utm_medium=author-uri
9
  * License: GPL2 or later
95
  /**
96
  * @var string Plugin Version
97
  */
98
+ public static $VER = '1.8.6';
99
 
100
  /**
101
  * @var int DB Version
readme.txt CHANGED
@@ -1,4 +1,4 @@
1
- === Popup Maker - Popup Forms, Optins & More ===
2
  Contributors: danieliser, codeatlantic
3
  Author URI: https://wppopupmaker.com/?utm_source=readme-header&utm_campaign=Readme&utm_medium=author-uri
4
  Plugin URI: https://wppopupmaker.com/?utm_capmaign=Readme&utm_source=readme-header&utm_medium=plugin-uri
@@ -7,7 +7,7 @@ Tags: marketing, popup, popups, optin, advertising, conversion, responsive popu
7
  Requires at least: 4.1
8
  Tested up to: 5.2
9
  Requires PHP: 5.2.17
10
- Stable tag: 1.8.5
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
@@ -96,4 +96,8 @@ There are several common causes for this, check [this guide for help](https://do
96
 
97
  == Changelog ==
98
 
99
- View our [changelog](https://plugins.svn.wordpress.org/popup-maker/trunk/CHANGELOG.md) for up-to-date information on what has been going on with the development of Popup Maker.
 
 
 
 
1
+ === Popup Maker - Popup Forms, Optins & More ===
2
  Contributors: danieliser, codeatlantic
3
  Author URI: https://wppopupmaker.com/?utm_source=readme-header&utm_campaign=Readme&utm_medium=author-uri
4
  Plugin URI: https://wppopupmaker.com/?utm_capmaign=Readme&utm_source=readme-header&utm_medium=plugin-uri
7
  Requires at least: 4.1
8
  Tested up to: 5.2
9
  Requires PHP: 5.2.17
10
+ Stable tag: 1.8.6
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
96
 
97
  == Changelog ==
98
 
99
+ View our [complete changelog](https://github.com/PopupMaker/Popup-Maker/blob/master/CHANGELOG.md) for up-to-date information on what has been going on with the development of Popup Maker.
100
+
101
+ = v1.8.6 - 05/05/2019 =
102
+ * Fix: Typo in GDPR eraser that could sometimes result in errors when processing GDPR requests
103
+ * Fix: Added function exists check to prevent errors on WP 4.1